diff --git a/apache-poi-2/pom.xml b/apache-poi-2/pom.xml
index 30270cd7be..af959292fa 100644
--- a/apache-poi-2/pom.xml
+++ b/apache-poi-2/pom.xml
@@ -1,7 +1,7 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
apache-poi-2
0.0.1-SNAPSHOT
@@ -25,5 +25,4 @@
5.2.0
-
-
+
\ No newline at end of file
diff --git a/apache-spark/README.md b/apache-spark/README.md
index 3a2d2f4e15..862626988b 100644
--- a/apache-spark/README.md
+++ b/apache-spark/README.md
@@ -9,3 +9,4 @@ This module contains articles about Apache Spark
- [Machine Learning with Spark MLlib](https://www.baeldung.com/spark-mlib-machine-learning)
- [Introduction to Spark Graph Processing with GraphFrames](https://www.baeldung.com/spark-graph-graphframes)
- [Apache Spark: Differences between Dataframes, Datasets and RDDs](https://www.baeldung.com/java-spark-dataframe-dataset-rdd)
+- [Spark DataFrame](https://www.baeldung.com/spark-dataframes)
diff --git a/apache-spark/src/test/java/com/baeldung/differences/rdd/ActionsUnitTest.java b/apache-spark/src/test/java/com/baeldung/differences/rdd/ActionsUnitTest.java
index a3e1811e6f..b1083021a9 100644
--- a/apache-spark/src/test/java/com/baeldung/differences/rdd/ActionsUnitTest.java
+++ b/apache-spark/src/test/java/com/baeldung/differences/rdd/ActionsUnitTest.java
@@ -12,21 +12,29 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import scala.Tuple2;
public class ActionsUnitTest {
+
+ public static final Logger LOG = LoggerFactory.getLogger(ActionsUnitTest.class);
+
private static JavaRDD tourists;
private static JavaSparkContext sc;
public static final String COMMA_DELIMITER = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)";
-
+
@BeforeClass
public static void init() {
- SparkConf conf = new SparkConf().setAppName("reduce")
- .setMaster("local[*]");
+ SparkConf conf = new SparkConf()
+ .setAppName("reduce")
+ .setMaster("local[*]")
+ .set("spark.driver.allowMultipleContexts", "true");
+
sc = new JavaSparkContext(conf);
tourists = sc.textFile("data/Tourist.csv").filter(line -> !line.startsWith("Region"));
}
-
+
@AfterClass
public static void cleanup() {
sc.close();
@@ -40,11 +48,11 @@ public class ActionsUnitTest {
})
.distinct();
Long numberOfCountries = countries.count();
- System.out.println("Count: " + numberOfCountries);
-
+ LOG.debug("Count: {}", numberOfCountries);
+
assertEquals(Long.valueOf(220), numberOfCountries);
}
-
+
@Test
public void whenReduceByKeySum_thenTotalValuePerKey() {
JavaRDD touristsExpenditure = tourists.filter(line -> line.split(COMMA_DELIMITER)[3].contains("expenditure"));
@@ -53,10 +61,12 @@ public class ActionsUnitTest {
String[] columns = line.split(COMMA_DELIMITER);
return new Tuple2<>(columns[1], Double.valueOf(columns[6]));
});
- List> totalByCountry = expenditurePairRdd.reduceByKey((x, y) -> x + y)
- .collect();
- System.out.println("Total per Country: " + totalByCountry);
-
+ List> totalByCountry = expenditurePairRdd
+ .reduceByKey(Double::sum)
+ .collect();
+
+ LOG.debug("Total per Country: {}", totalByCountry);
+
for(Tuple2 tuple : totalByCountry) {
if (tuple._1.equals("Mexico")) {
assertEquals(Double.valueOf(99164), tuple._2);
diff --git a/apache-spark/src/test/java/com/baeldung/differences/rdd/DataFrameUnitTest.java b/apache-spark/src/test/java/com/baeldung/differences/rdd/DataFrameUnitTest.java
index f294e5bc66..621e589fb6 100644
--- a/apache-spark/src/test/java/com/baeldung/differences/rdd/DataFrameUnitTest.java
+++ b/apache-spark/src/test/java/com/baeldung/differences/rdd/DataFrameUnitTest.java
@@ -39,8 +39,10 @@ public class DataFrameUnitTest {
@Test
public void whenSelectSpecificColumns_thenColumnsFiltered() {
Dataset selectedData = data.select(col("country"), col("year"), col("value"));
- selectedData.show();
-
+
+ // uncomment to see table
+ // selectedData.show();
+
List resultList = Arrays.asList(selectedData.columns());
assertTrue(resultList.contains("country"));
assertTrue(resultList.contains("year"));
@@ -52,22 +54,26 @@ public class DataFrameUnitTest {
@Test
public void whenFilteringByCountry_thenCountryRecordsSelected() {
Dataset filteredData = data.filter(col("country").equalTo("Mexico"));
- filteredData.show();
-
+
+ // uncomment to see table
+ // filteredData.show();
+
filteredData.foreach(record -> {
assertEquals("Mexico", record.get(1));
});
-
+
}
@Test
public void whenGroupCountByCountry_thenContryTotalRecords() {
Dataset recordsPerCountry = data.groupBy(col("country"))
.count();
- recordsPerCountry.show();
-
+
+ // uncomment to see table
+ // recordsPerCountry.show();
+
Dataset filteredData = recordsPerCountry.filter(col("country").equalTo("Sweden"));
- assertEquals(new Long(12), filteredData.first()
+ assertEquals(12L, filteredData.first()
.get(1));
}
diff --git a/apache-spark/src/test/java/com/baeldung/differences/rdd/DatasetUnitTest.java b/apache-spark/src/test/java/com/baeldung/differences/rdd/DatasetUnitTest.java
index 1d83505812..4fde933a3b 100644
--- a/apache-spark/src/test/java/com/baeldung/differences/rdd/DatasetUnitTest.java
+++ b/apache-spark/src/test/java/com/baeldung/differences/rdd/DatasetUnitTest.java
@@ -3,6 +3,7 @@ package com.baeldung.differences.rdd;
import static org.apache.spark.sql.functions.col;
import static org.apache.spark.sql.functions.sum;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import org.apache.spark.api.java.function.FilterFunction;
import org.apache.spark.sql.DataFrameReader;
@@ -29,8 +30,8 @@ public class DatasetUnitTest {
DataFrameReader dataFrameReader = session.read();
Dataset data = dataFrameReader.option("header", "true")
.csv("data/Tourist.csv");
- Dataset responseWithSelectedColumns = data.select(col("region"),
- col("country"), col("year"), col("series"), col("value").cast("double"),
+ Dataset responseWithSelectedColumns = data.select(col("region"),
+ col("country"), col("year"), col("series"), col("value").cast("double"),
col("footnotes"), col("source"));
typedDataset = responseWithSelectedColumns.as(Encoders.bean(TouristData.class));
}
@@ -45,7 +46,9 @@ public class DatasetUnitTest {
Dataset selectedData = typedDataset
.filter((FilterFunction) record -> record.getCountry()
.equals("Norway"));
- selectedData.show();
+
+ // uncomment to see output
+ // selectedData.show();
selectedData.foreach(record -> {
assertEquals("Norway", record.getCountry());
@@ -56,28 +59,41 @@ public class DatasetUnitTest {
public void whenGroupCountByCountry_thenContryTotalRecords() {
Dataset countriesCount = typedDataset.groupBy(typedDataset.col("country"))
.count();
- countriesCount.show();
- assertEquals(Long.valueOf(220), Long.valueOf(countriesCount.count()));
+ // uncomment to see output
+ // countriesCount.show();
+
+ assertEquals(220, countriesCount.count());
}
@Test
public void whenFilteredByPropertyRange_thenRetreiveValidRecords() {
// Filter records with existing data for years between 2010 and 2017
- typedDataset.filter((FilterFunction) record -> record.getYear() != null
- && (Long.valueOf(record.getYear()) > 2010 && Long.valueOf(record.getYear()) < 2017))
- .show();
+ Dataset filteredData = typedDataset.filter(
+ (FilterFunction) record -> record.getYear() != null
+ && (Long.parseLong(record.getYear()) > 2010 && Long.parseLong(record.getYear()) < 2017));
+
+ // uncomment to see output
+ // filteredData.show();
+
+ assertEquals(394, filteredData.count());
+ filteredData.foreach(record -> {
+ assertTrue(Integer.parseInt(record.getYear()) > 2010 && Integer.parseInt(record.getYear()) < 2017);
+ });
}
-
+
@Test
public void whenSumValue_thenRetreiveTotalValue() {
// Total tourist expenditure by country
- typedDataset.filter((FilterFunction) record -> record.getValue() != null
- && record.getSeries()
- .contains("expenditure"))
- .groupBy("country")
- .agg(sum("value"))
- .show();
+ Dataset filteredData = typedDataset.filter((FilterFunction) record -> record.getValue() != null
+ && record.getSeries().contains("expenditure"))
+ .groupBy("country")
+ .agg(sum("value"));
+
+ // uncomment to see output
+ // filteredData.show();
+
+ assertEquals(212, filteredData.count());
}
}
diff --git a/apache-spark/src/test/java/com/baeldung/differences/rdd/TransformationsUnitTest.java b/apache-spark/src/test/java/com/baeldung/differences/rdd/TransformationsUnitTest.java
index 01e7d3adfc..6de407f3b4 100644
--- a/apache-spark/src/test/java/com/baeldung/differences/rdd/TransformationsUnitTest.java
+++ b/apache-spark/src/test/java/com/baeldung/differences/rdd/TransformationsUnitTest.java
@@ -23,8 +23,11 @@ public class TransformationsUnitTest {
@BeforeClass
public static void init() {
- SparkConf conf = new SparkConf().setAppName("uppercaseCountries")
- .setMaster("local[*]");
+ SparkConf conf = new SparkConf()
+ .setAppName("uppercaseCountries")
+ .setMaster("local[*]")
+ .set("spark.driver.allowMultipleContexts", "true");
+
sc = new JavaSparkContext(conf);
tourists = sc.textFile("data/Tourist.csv")
.filter(line -> !line.startsWith("Region")); //filter header row
diff --git a/apache-tapestry/pom.xml b/apache-tapestry/pom.xml
index 7a4c2b53b5..201b807d9f 100644
--- a/apache-tapestry/pom.xml
+++ b/apache-tapestry/pom.xml
@@ -3,12 +3,17 @@
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4.0.0
- com.baeldung
apache-tapestry
0.0.1-SNAPSHOT
apache-tapestry
war
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
-
+
+
diff --git a/core-java-modules/core-java-exceptions-4/pom.xml b/core-java-modules/core-java-exceptions-4/pom.xml
index cc81fdc40b..e9a2d05180 100644
--- a/core-java-modules/core-java-exceptions-4/pom.xml
+++ b/core-java-modules/core-java-exceptions-4/pom.xml
@@ -32,8 +32,8 @@
3.8.1
-
-
+
+
diff --git a/core-java-modules/core-java-httpclient/README.md b/core-java-modules/core-java-httpclient/README.md
new file mode 100644
index 0000000000..712328a123
--- /dev/null
+++ b/core-java-modules/core-java-httpclient/README.md
@@ -0,0 +1,6 @@
+## Java HttpClient
+
+This module contains articles about Java HttpClient
+
+### Relevant articles
+- [Posting with Java HttpClient](https://www.baeldung.com/java-httpclient-post)
diff --git a/core-java-modules/core-java-httpclient/pom.xml b/core-java-modules/core-java-httpclient/pom.xml
new file mode 100644
index 0000000000..57b23e96c1
--- /dev/null
+++ b/core-java-modules/core-java-httpclient/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+ core-java-httpclient
+ 0.1.0-SNAPSHOT
+ core-java-httpclient
+ jar
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+ ../../pom.xml
+
+
+
+
+ org.mock-server
+ mockserver-netty
+ ${mockserver.version}
+
+
+ org.mock-server
+ mockserver-client-java
+ ${mockserver.version}
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${maven.compiler.source.version}
+ ${maven.compiler.target.version}
+
+
+
+
+
+
+ 11
+ 11
+ 3.22.0
+ 5.11.2
+
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-httpclient/src/main/java/com/baeldung/httpclient/HttpClientPost.java b/core-java-modules/core-java-httpclient/src/main/java/com/baeldung/httpclient/HttpClientPost.java
new file mode 100644
index 0000000000..d08a7bf183
--- /dev/null
+++ b/core-java-modules/core-java-httpclient/src/main/java/com/baeldung/httpclient/HttpClientPost.java
@@ -0,0 +1,162 @@
+package com.baeldung.httpclient;
+
+import java.io.IOException;
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+public class HttpClientPost {
+
+ public static HttpResponse sendSynchronousPost(String serviceUrl) throws IOException, InterruptedException {
+ HttpClient client = HttpClient.newHttpClient();
+
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(serviceUrl))
+ .POST(HttpRequest.BodyPublishers.noBody())
+ .build();
+
+ HttpResponse response = client
+ .send(request, HttpResponse.BodyHandlers.ofString());
+
+ return response;
+ }
+
+ public static CompletableFuture> sendAsynchronousPost(String serviceUrl) {
+ HttpClient client = HttpClient.newHttpClient();
+
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(serviceUrl))
+ .POST(HttpRequest.BodyPublishers.noBody())
+ .build();
+
+ CompletableFuture> futureResponse = client
+ .sendAsync(request, HttpResponse.BodyHandlers.ofString());
+
+ return futureResponse;
+ }
+
+ public static List>> sendConcurrentPost(List serviceUrls) {
+ HttpClient client = HttpClient.newHttpClient();
+
+ List>> completableFutures = serviceUrls.stream()
+ .map(URI::create)
+ .map(HttpRequest::newBuilder)
+ .map(builder -> builder.POST(HttpRequest.BodyPublishers.noBody()))
+ .map(HttpRequest.Builder::build)
+ .map(request -> client.sendAsync(request, HttpResponse.BodyHandlers.ofString()))
+ .collect(Collectors.toList());
+
+ return completableFutures;
+ }
+
+ public static HttpResponse sendPostWithAuthHeader(String serviceUrl) throws IOException, InterruptedException {
+ HttpClient client = HttpClient.newHttpClient();
+
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(serviceUrl))
+ .POST(HttpRequest.BodyPublishers.noBody())
+ .header("Authorization", "Basic " + Base64.getEncoder()
+ .encodeToString(("baeldung:123456").getBytes()))
+ .build();
+
+ HttpResponse response = client
+ .send(request, HttpResponse.BodyHandlers.ofString());
+
+ return response;
+ }
+
+ public static HttpResponse sendPostWithAuthClient(String serviceUrl) throws IOException, InterruptedException {
+ HttpClient client = HttpClient.newBuilder()
+ .authenticator(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(
+ "baeldung",
+ "123456".toCharArray());
+ }
+ })
+ .build();
+
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(serviceUrl))
+ .POST(HttpRequest.BodyPublishers.noBody())
+ .build();
+
+ HttpResponse response = client
+ .send(request, HttpResponse.BodyHandlers.ofString());
+
+ return response;
+ }
+
+ public static HttpResponse sendPostWithJsonBody(String serviceUrl) throws IOException, InterruptedException {
+ HttpClient client = HttpClient.newHttpClient();
+
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(serviceUrl))
+ .POST(HttpRequest.BodyPublishers.ofString("{\"action\":\"hello\"}"))
+ .build();
+
+ HttpResponse response = client
+ .send(request, HttpResponse.BodyHandlers.ofString());
+
+ return response;
+ }
+
+ public static HttpResponse sendPostWithFormData(String serviceUrl) throws IOException, InterruptedException {
+ HttpClient client = HttpClient.newHttpClient();
+
+ Map formData = new HashMap<>();
+ formData.put("username", "baeldung");
+ formData.put("message", "hello");
+
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(serviceUrl))
+ .POST(HttpRequest.BodyPublishers.ofString(getFormDataAsString(formData)))
+ .build();
+
+ HttpResponse response = client
+ .send(request, HttpResponse.BodyHandlers.ofString());
+
+ return response;
+ }
+
+ public static HttpResponse sendPostWithFileData(String serviceUrl, Path file) throws IOException, InterruptedException {
+ HttpClient client = HttpClient.newHttpClient();
+
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(serviceUrl))
+ .POST(HttpRequest.BodyPublishers.ofFile(file))
+ .build();
+
+ HttpResponse response = client
+ .send(request, HttpResponse.BodyHandlers.ofString());
+
+ return response;
+ }
+
+ private static String getFormDataAsString(Map formData) {
+ StringBuilder formBodyBuilder = new StringBuilder();
+ for (Map.Entry singleEntry : formData.entrySet()) {
+ if (formBodyBuilder.length() > 0) {
+ formBodyBuilder.append("&");
+ }
+ formBodyBuilder.append(URLEncoder.encode(singleEntry.getKey(), StandardCharsets.UTF_8));
+ formBodyBuilder.append("=");
+ formBodyBuilder.append(URLEncoder.encode(singleEntry.getValue(), StandardCharsets.UTF_8));
+ }
+ return formBodyBuilder.toString();
+ }
+
+}
diff --git a/core-java-modules/core-java-httpclient/src/test/java/com/baeldung/httpclient/HttpClientPostUnitTest.java b/core-java-modules/core-java-httpclient/src/test/java/com/baeldung/httpclient/HttpClientPostUnitTest.java
new file mode 100644
index 0000000000..b43cf08649
--- /dev/null
+++ b/core-java-modules/core-java-httpclient/src/test/java/com/baeldung/httpclient/HttpClientPostUnitTest.java
@@ -0,0 +1,99 @@
+package com.baeldung.httpclient;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import java.io.IOException;
+import java.net.http.HttpResponse;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.*;
+
+class HttpClientPostUnitTest extends PostRequestMockServer {
+
+ @Test
+ void givenSyncPostRequest_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException {
+ HttpResponse response = HttpClientPost.sendSynchronousPost(serviceUrl);
+ assertThat(response.statusCode()).isEqualTo(200);
+ assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
+ }
+
+ @Test
+ void givenAsyncPostRequest_whenServerIsAvailable_thenOkStatusIsReceived() throws ExecutionException, InterruptedException {
+ CompletableFuture> futureResponse = HttpClientPost.sendAsynchronousPost(serviceUrl);
+ HttpResponse response = futureResponse.get();
+
+ assertThat(response.statusCode()).isEqualTo(200);
+ assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
+ }
+
+ @Test
+ void givenConcurrentPostRequests_whenServerIsAvailable_thenOkStatusIsReceived() throws ExecutionException, InterruptedException {
+ List>> completableFutures = HttpClientPost
+ .sendConcurrentPost(List.of(serviceUrl, serviceUrl));
+
+ CompletableFuture>> combinedFutures = CompletableFuture
+ .allOf(completableFutures.toArray(new CompletableFuture[0]))
+ .thenApply(future ->
+ completableFutures.stream()
+ .map(CompletableFuture::join)
+ .collect(Collectors.toList()));
+
+ List> responses = combinedFutures.get();
+ responses.forEach((response) -> {
+ assertThat(response.statusCode()).isEqualTo(200);
+ assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
+ });
+ }
+
+ @Test
+ void givenPostRequestWithAuthClient_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException {
+ HttpResponse response = HttpClientPost.sendPostWithAuthClient(serviceUrl);
+
+ assertThat(response.statusCode()).isEqualTo(200);
+ assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
+ }
+
+ @Test
+ void givenPostRequestWithAuthHeader_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException {
+ HttpResponse response = HttpClientPost.sendPostWithAuthHeader(serviceUrl);
+
+ assertThat(response.statusCode()).isEqualTo(200);
+ assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
+ }
+
+ @Test
+ void givenPostRequestWithJsonBody_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException {
+ HttpResponse response = HttpClientPost.sendPostWithJsonBody(serviceUrl);
+
+ assertThat(response.statusCode()).isEqualTo(200);
+ assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
+ }
+
+ @Test
+ void givenPostRequestWithFormData_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException {
+ HttpResponse response = HttpClientPost.sendPostWithFormData(serviceUrl);
+
+ assertThat(response.statusCode()).isEqualTo(200);
+ assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
+ }
+
+ @Test
+ void givenPostRequestWithFileData_whenServerIsAvailable_thenOkStatusIsReceived(@TempDir Path tempDir) throws IOException, InterruptedException {
+ Path file = tempDir.resolve("temp.txt");
+ List lines = Arrays.asList("1", "2", "3");
+ Files.write(file, lines);
+
+ HttpResponse response = HttpClientPost.sendPostWithFileData(serviceUrl, file);
+
+ assertThat(response.statusCode()).isEqualTo(200);
+ assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
+ }
+
+}
diff --git a/core-java-modules/core-java-httpclient/src/test/java/com/baeldung/httpclient/PostRequestMockServer.java b/core-java-modules/core-java-httpclient/src/test/java/com/baeldung/httpclient/PostRequestMockServer.java
new file mode 100644
index 0000000000..fa594897a3
--- /dev/null
+++ b/core-java-modules/core-java-httpclient/src/test/java/com/baeldung/httpclient/PostRequestMockServer.java
@@ -0,0 +1,61 @@
+package com.baeldung.httpclient;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.mockserver.client.MockServerClient;
+import org.mockserver.integration.ClientAndServer;
+import org.mockserver.model.HttpStatusCode;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.URISyntaxException;
+
+import static org.mockserver.integration.ClientAndServer.startClientAndServer;
+import static org.mockserver.model.HttpRequest.request;
+import static org.mockserver.model.HttpResponse.response;
+
+public abstract class PostRequestMockServer {
+
+ public static ClientAndServer mockServer;
+ public static String serviceUrl;
+
+ private static int serverPort;
+
+ public static final String SERVER_ADDRESS = "127.0.0.1";
+ public static final String PATH = "/test1";
+ public static final String METHOD = "POST";
+
+ @BeforeAll
+ static void startServer() throws IOException, URISyntaxException {
+ serverPort = getFreePort();
+ serviceUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH;
+ mockServer = startClientAndServer(serverPort);
+ mockBasicPostRequest();
+ }
+
+ @AfterAll
+ static void stopServer() {
+ mockServer.stop();
+ }
+
+ private static void mockBasicPostRequest() {
+ new MockServerClient(SERVER_ADDRESS, serverPort)
+ .when(
+ request()
+ .withPath(PATH)
+ .withMethod(METHOD)
+ )
+ .respond(
+ response()
+ .withStatusCode(HttpStatusCode.OK_200.code())
+ .withBody("{\"message\":\"ok\"}")
+ );
+ }
+
+ private static int getFreePort () throws IOException {
+ try (ServerSocket serverSocket = new ServerSocket(0)) {
+ return serverSocket.getLocalPort();
+ }
+ }
+
+}
diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeVO.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeVO.java
index 7a1775f79d..3d2c61aa3d 100644
--- a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeVO.java
+++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/employee/EmployeeVO.java
@@ -28,9 +28,15 @@ public class EmployeeVO {
@Override
public boolean equals(Object obj) {
- return Objects.equals(firstName, this.firstName)
- && Objects.equals(lastName, this.lastName)
- && Objects.equals(startDate, this.startDate);
+
+ if (this == obj) return true;
+ if (obj == null || getClass() != obj.getClass()) return false;
+
+ EmployeeVO emp = (EmployeeVO) obj;
+
+ return Objects.equals(firstName, emp.firstName)
+ && Objects.equals(lastName, emp.lastName)
+ && Objects.equals(startDate, emp.startDate);
}
@Override
diff --git a/core-java-modules/core-java-lang-5/README.md b/core-java-modules/core-java-lang-5/README.md
index 012f4edc51..8920e9c231 100644
--- a/core-java-modules/core-java-lang-5/README.md
+++ b/core-java-modules/core-java-lang-5/README.md
@@ -2,4 +2,6 @@
This module contains articles about core features in the Java language
-## TODO ##
+### Relevant Articles:
+
+- [Difference Between == and equals() in Java](https://www.baeldung.com/java-equals-method-operator-difference)
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 1dd3a3c7e0..3ddaddae39 100644
--- a/core-java-modules/core-java-lang-math-3/README.md
+++ b/core-java-modules/core-java-lang-math-3/README.md
@@ -5,4 +5,5 @@
### Relevant articles:
- [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string)
+- [Swap Two Variables in Java](https://www.baeldung.com/java-swap-two-variables)
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)
diff --git a/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/http/JavaHttpClientTimeout.java b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/http/JavaHttpClientTimeout.java
new file mode 100644
index 0000000000..d7ab002e77
--- /dev/null
+++ b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/http/JavaHttpClientTimeout.java
@@ -0,0 +1,12 @@
+package com.baeldung.http;
+
+import java.net.http.HttpClient;
+import java.time.Duration;
+
+public class JavaHttpClientTimeout {
+ static HttpClient getHttpClientWithTimeout(int seconds) {
+ return HttpClient.newBuilder()
+ .connectTimeout(Duration.ofSeconds(seconds))
+ .build();
+ }
+}
diff --git a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/http/JavaHttpClientTimeoutIntegrationTest.java b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/http/JavaHttpClientTimeoutIntegrationTest.java
new file mode 100644
index 0000000000..df635621ad
--- /dev/null
+++ b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/http/JavaHttpClientTimeoutIntegrationTest.java
@@ -0,0 +1,54 @@
+package com.baeldung.http;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpConnectTimeoutException;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.time.Duration;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import static com.baeldung.http.JavaHttpClientTimeout.getHttpClientWithTimeout;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class JavaHttpClientTimeoutIntegrationTest {
+
+ private HttpClient httpClient;
+ private HttpRequest httpRequest;
+
+ @BeforeEach
+ public void setUp() {
+ httpClient = getHttpClientWithTimeout(3);
+ httpClient.connectTimeout().map(Duration::toSeconds)
+ .ifPresent(sec -> System.out.println("Timeout in seconds: " + sec));
+
+ httpRequest = HttpRequest.newBuilder().uri(URI.create("http://10.255.255.1")).GET().build();
+ }
+
+ @Test
+ void shouldThrowExceptionWhenMakingSyncCall() {
+ HttpConnectTimeoutException thrown = assertThrows(
+ HttpConnectTimeoutException.class,
+ () -> httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()),
+ "Expected doThing() to throw, but it didn't"
+ );
+ assertTrue(thrown.getMessage().contains("timed out"));
+ }
+
+ @Test
+ void shouldThrowExceptionWhenMakingASyncCall() throws ExecutionException, InterruptedException, TimeoutException {
+ CompletableFuture completableFuture =
+ httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofString())
+ .thenApply(HttpResponse::body)
+ .exceptionally(Throwable::getMessage);
+ String response = completableFuture.get(5, TimeUnit.SECONDS);
+ assertTrue(response.contains("timed out"));
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/searchfilesbywildcards/SearchFileByWildcard.java b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/searchfilesbywildcards/SearchFileByWildcard.java
new file mode 100644
index 0000000000..2deaa60ec6
--- /dev/null
+++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/searchfilesbywildcards/SearchFileByWildcard.java
@@ -0,0 +1,37 @@
+package com.baeldung.searchfilesbywildcards;
+
+import java.io.IOException;
+
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SearchFileByWildcard {
+ public static List matchesList = new ArrayList();
+ public List searchWithWc(Path rootDir, String pattern) throws IOException {
+ matchesList.clear();
+ FileVisitor matcherVisitor = new SimpleFileVisitor() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attribs) throws IOException {
+ FileSystem fs = FileSystems.getDefault();
+ PathMatcher matcher = fs.getPathMatcher(pattern);
+ Path name = file.getFileName();
+ if (matcher.matches(name)) {
+ matchesList.add(name.toString());
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ };
+ Files.walkFileTree(rootDir, matcherVisitor);
+ return matchesList;
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/searchfilesbywildcards/SearchFileByWildcardUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/searchfilesbywildcards/SearchFileByWildcardUnitTest.java
new file mode 100644
index 0000000000..71cee036ec
--- /dev/null
+++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/searchfilesbywildcards/SearchFileByWildcardUnitTest.java
@@ -0,0 +1,30 @@
+package com.baeldung.searchfilesbywildcards;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.IOException;
+
+import java.nio.file.Paths;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+public class SearchFileByWildcardUnitTest {
+ @Test
+ public void whenFourFilenameMatch_thenListOfFour() throws IOException {
+ SearchFileByWildcard sfbw = new SearchFileByWildcard();
+ List actual = sfbw.searchWithWc(Paths.get("src/test/resources/sfbw"), "glob:*.{txt,docx}");
+
+ assertEquals(new HashSet<>(Arrays.asList("six.txt", "three.txt", "two.docx", "one.txt")), new HashSet<>(actual));
+ }
+ @Test
+ public void whenOneFilenameMatch_thenListOfOne() throws IOException {
+ SearchFileByWildcard sfbw = new SearchFileByWildcard();
+ List actual = sfbw.searchWithWc(Paths.get("src/test/resources/sfbw"), "glob:????.{csv}");
+
+ assertEquals(new HashSet<>(Arrays.asList("five.csv")), new HashSet<>(actual));
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/five.csv b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/five.csv
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/four.xlsx b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/four.xlsx
new file mode 100644
index 0000000000..1091dafe75
Binary files /dev/null and b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/four.xlsx differ
diff --git a/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/one.txt b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/one.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/test2/six.txt b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/test2/six.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/three.txt b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/three.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/two.docx b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/two.docx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/proxy/AdvancedOperation.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/proxy/AdvancedOperation.java
new file mode 100644
index 0000000000..b3f0dc8ec0
--- /dev/null
+++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/proxy/AdvancedOperation.java
@@ -0,0 +1,7 @@
+package com.baeldung.reflection.proxy;
+
+public interface AdvancedOperation {
+ int multiply(int a, int b);
+
+ int divide(int a, int b);
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/proxy/BasicOperation.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/proxy/BasicOperation.java
new file mode 100644
index 0000000000..168367b690
--- /dev/null
+++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/proxy/BasicOperation.java
@@ -0,0 +1,7 @@
+package com.baeldung.reflection.proxy;
+
+public interface BasicOperation {
+ int add(int a, int b);
+
+ int subtract(int a, int b);
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/proxy/DollarProxyUnitTest.java b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/proxy/DollarProxyUnitTest.java
new file mode 100644
index 0000000000..ef6c481778
--- /dev/null
+++ b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/proxy/DollarProxyUnitTest.java
@@ -0,0 +1,35 @@
+package com.baeldung.reflection.proxy;
+
+import org.junit.Test;
+
+import java.lang.reflect.Proxy;
+import java.util.function.Consumer;
+
+import static org.junit.Assert.assertTrue;
+
+public class DollarProxyUnitTest {
+ @Test
+ public void givenProxy_whenInvokingGetProxyClass_thenGeneratingProxyClass() {
+ // Java 8: -Dsun.misc.ProxyGenerator.saveGeneratedFiles=true
+ // Java 9 or later: -Djdk.proxy.ProxyGenerator.saveGeneratedFiles=true
+ // Note: System.setProperty() doesn't work here
+ // because ProxyGenerator.saveGeneratedFiles read its property only once.
+ // The @Test annotation in this method will generate a $Proxy class.
+
+ ClassLoader classLoader = ClassLoader.getSystemClassLoader();
+ Class>[] interfaces = {BasicOperation.class, AdvancedOperation.class};
+ Class> proxyClass = Proxy.getProxyClass(classLoader, interfaces);
+
+ boolean isProxyClass = Proxy.isProxyClass(proxyClass);
+ assertTrue(isProxyClass);
+ }
+
+ @Test
+ public void givenReflection_whenReadingAnnotation_thenGeneratingProxyClass() {
+ FunctionalInterface instance = Consumer.class.getDeclaredAnnotation(FunctionalInterface.class);
+ Class> clazz = instance.getClass();
+
+ boolean isProxyClass = Proxy.isProxyClass(clazz);
+ assertTrue(isProxyClass);
+ }
+}
diff --git a/core-java-modules/core-java-string-operations-4/pom.xml b/core-java-modules/core-java-string-operations-4/pom.xml
index 7f71ea8da5..0f1e377d18 100644
--- a/core-java-modules/core-java-string-operations-4/pom.xml
+++ b/core-java-modules/core-java-string-operations-4/pom.xml
@@ -30,6 +30,12 @@
commons-lang3
${apache-commons-lang3.version}
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
diff --git a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/checkvowels/CheckVowels.java b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/checkvowels/CheckVowels.java
new file mode 100644
index 0000000000..fd60427a4e
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/checkvowels/CheckVowels.java
@@ -0,0 +1,38 @@
+package com.baeldung.checkvowels;
+
+import java.util.regex.Pattern;
+
+public class CheckVowels {
+ private static final String VOWELS = "aeiouAEIOU";
+ private static final Pattern VOWELS_PATTERN = Pattern.compile("[aeiou]", Pattern.CASE_INSENSITIVE);
+
+ public static boolean isInVowelsString(char c) {
+ return VOWELS.indexOf(c) != -1;
+ }
+
+ public static boolean isInVowelsString(String c) {
+ return VOWELS.contains(c);
+ }
+
+ public static boolean isVowelBySwitch(char c) {
+ switch (c) {
+ case 'a':
+ case 'e':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'A':
+ case 'E':
+ case 'I':
+ case 'O':
+ case 'U':
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public static boolean isVowelByRegex(String c) {
+ return VOWELS_PATTERN.matcher(c).matches();
+ }
+}
diff --git a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/checkvowels/CheckVowelsUnitTest.java b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/checkvowels/CheckVowelsUnitTest.java
new file mode 100644
index 0000000000..52b0e55692
--- /dev/null
+++ b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/checkvowels/CheckVowelsUnitTest.java
@@ -0,0 +1,51 @@
+package com.baeldung.checkvowels;
+
+import org.junit.jupiter.api.Test;
+
+import static com.baeldung.checkvowels.CheckVowels.*;
+import static org.assertj.core.api.Assertions.*;
+
+class CheckVowelsUnitTest {
+
+ @Test
+ void givenAVowelCharacter_thenInVowelString() {
+ assertThat(isInVowelsString('e')).isTrue();
+ }
+
+ @Test
+ void givenAConsonantCharacter_thenNotInVowelString() {
+ assertThat(isInVowelsString('z')).isFalse();
+ }
+
+ @Test
+ void givenAVowelString_thenInVowelString() {
+ assertThat(isInVowelsString("e")).isTrue();
+ }
+
+ @Test
+ void givenAConsonantString_thenNotInVowelString() {
+ assertThat(isInVowelsString("z")).isFalse();
+ }
+
+ @Test
+ void givenAVowelCharacter_thenInVowelSwitch() {
+ assertThat(isVowelBySwitch('e')).isTrue();
+ }
+
+ @Test
+ void givenAConsonantCharacter_thenNotInVowelSwitch() {
+ assertThat(isVowelBySwitch('z')).isFalse();
+ }
+
+ @Test
+ void givenAVowelString_thenInVowelPattern() {
+ assertThat(isVowelByRegex("e")).isTrue();
+ assertThat(isVowelByRegex("E")).isTrue();
+ }
+
+ @Test
+ void givenAVowelCharacter_thenInVowelPattern() {
+ assertThat(isVowelByRegex(Character.toString('e'))).isTrue();
+ assertThat(isVowelByRegex("E")).isTrue();
+ }
+}
diff --git a/core-java-modules/core-java-uuid/pom.xml b/core-java-modules/core-java-uuid/pom.xml
index 28519a1a68..7d851292f5 100644
--- a/core-java-modules/core-java-uuid/pom.xml
+++ b/core-java-modules/core-java-uuid/pom.xml
@@ -35,7 +35,6 @@
true
-
org.apache.maven.plugins
diff --git a/core-java-modules/core-java/pom.xml b/core-java-modules/core-java/pom.xml
index 786ee91192..87abe6c007 100644
--- a/core-java-modules/core-java/pom.xml
+++ b/core-java-modules/core-java/pom.xml
@@ -67,7 +67,7 @@
com.google.gdata
core
- 1.47.1
+ ${gdata.version}
@@ -193,6 +193,7 @@
1.8
1.8
4.3.20.RELEASE
+ 1.47.1
\ No newline at end of file
diff --git a/core-java-modules/java-collections-conversions-2/pom.xml b/core-java-modules/java-collections-conversions-2/pom.xml
index 0f8e80fdbf..510921c35e 100644
--- a/core-java-modules/java-collections-conversions-2/pom.xml
+++ b/core-java-modules/java-collections-conversions-2/pom.xml
@@ -28,7 +28,7 @@
io.vavr
vavr
- 0.10.3
+ ${vavr.version}
@@ -42,4 +42,8 @@
+
+ 0.10.3
+
+
\ No newline at end of file
diff --git a/core-java-modules/java-collections-maps-3/pom.xml b/core-java-modules/java-collections-maps-3/pom.xml
index db56550d10..ab80a9e2fd 100644
--- a/core-java-modules/java-collections-maps-3/pom.xml
+++ b/core-java-modules/java-collections-maps-3/pom.xml
@@ -19,7 +19,7 @@
org.junit.jupiter
junit-jupiter-api
- 5.8.1
+ ${junit-jupiter.version}
org.springframework
diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml
index 04b46e3740..15347d0fe9 100644
--- a/core-java-modules/pom.xml
+++ b/core-java-modules/pom.xml
@@ -35,6 +35,7 @@
core-java-collections-list
core-java-collections-list-2
core-java-collections-list-3
+ core-java-collections-list-4
core-java-collections-maps
core-java-collections-maps-2
core-java-collections-maps-3
diff --git a/docker/docker-caching/multi-module-caching/core/pom.xml b/docker/docker-caching/multi-module-caching/core/pom.xml
index eeeb5a6e5b..bcfc4b5783 100644
--- a/docker/docker-caching/multi-module-caching/core/pom.xml
+++ b/docker/docker-caching/multi-module-caching/core/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
@@ -22,4 +22,5 @@
8
8
+
\ No newline at end of file
diff --git a/docker/docker-caching/multi-module-caching/pom.xml b/docker/docker-caching/multi-module-caching/pom.xml
index 7968114385..7e279dc334 100644
--- a/docker/docker-caching/multi-module-caching/pom.xml
+++ b/docker/docker-caching/multi-module-caching/pom.xml
@@ -1,6 +1,7 @@
-
+
4.0.0
com.baeldung
multi-module-caching
@@ -8,22 +9,24 @@
Multi-module Maven caching example
pom
+
+ runner
+ core
+
+
com.google.guava
guava
- 31.0.1-jre
+ ${guava.version}
1.8
+ 31.0.1-jre
-
- runner
- core
-
-
+
\ No newline at end of file
diff --git a/docker/docker-caching/multi-module-caching/runner/pom.xml b/docker/docker-caching/multi-module-caching/runner/pom.xml
index e3654bff17..e3f234bac0 100644
--- a/docker/docker-caching/multi-module-caching/runner/pom.xml
+++ b/docker/docker-caching/multi-module-caching/runner/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
runner
@@ -53,4 +53,5 @@
8
8
+
\ No newline at end of file
diff --git a/docker/docker-caching/single-module-caching/pom.xml b/docker/docker-caching/single-module-caching/pom.xml
index 386b040138..d7f96e1e7e 100644
--- a/docker/docker-caching/single-module-caching/pom.xml
+++ b/docker/docker-caching/single-module-caching/pom.xml
@@ -1,9 +1,8 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
-
com.baeldung
single-module-caching
1.0-SNAPSHOT
@@ -12,7 +11,7 @@
com.google.guava
guava
- 31.0.1-jre
+ ${guava.version}
@@ -49,5 +48,7 @@
8
8
+ 31.0.1-jre
+
\ No newline at end of file
diff --git a/docker/docker-internal-dto/pom.xml b/docker/docker-internal-dto/pom.xml
index 55cef257fe..09013d2fc3 100644
--- a/docker/docker-internal-dto/pom.xml
+++ b/docker/docker-internal-dto/pom.xml
@@ -3,13 +3,13 @@
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
+ docker-internal-dto
+ docker-internal-dto
+
com.baeldung.docker
docker
0.0.1
- docker-internal-dto
- docker-internal-dto
-
diff --git a/docker/docker-push-to-private-repo/README.md b/docker/docker-push-to-private-repo/README.md
index e320af31b4..61fe00e016 100644
--- a/docker/docker-push-to-private-repo/README.md
+++ b/docker/docker-push-to-private-repo/README.md
@@ -1 +1,3 @@
-### Relevant Articles:
\ No newline at end of file
+### Relevant Articles:
+
+- [Pushing a Docker Image to a Private Repository](https://www.baeldung.com/ops/docker-push-image-to-private-repository)
diff --git a/docker/docker-push-to-private-repo/pom.xml b/docker/docker-push-to-private-repo/pom.xml
index 59a909ff07..19be098794 100644
--- a/docker/docker-push-to-private-repo/pom.xml
+++ b/docker/docker-push-to-private-repo/pom.xml
@@ -1,19 +1,19 @@
-
+
4.0.0
+ docker-push-to-private-repo
+ 0.0.1-SNAPSHOT
+ docker-push-to-private-repo
+ Example application to showcase how to push a docker image to a private repository
+
com.baeldung.docker
docker
0.0.1
- push-to-private-repo
- 0.0.1-SNAPSHOT
- push-to-private-repo
- Example application to showcase how to push a docker image to a private repository
-
- 11
-
+
org.springframework.boot
@@ -40,4 +40,8 @@
-
+
+ 11
+
+
+
\ No newline at end of file
diff --git a/docker/docker-sample-app/pom.xml b/docker/docker-sample-app/pom.xml
index 6841fabcee..24fede56fd 100644
--- a/docker/docker-sample-app/pom.xml
+++ b/docker/docker-sample-app/pom.xml
@@ -1,21 +1,18 @@
-
+
4.0.0
+ docker-sample-app
+ docker-sample-app
+ Demo project for Spring Boot and Docker
+
com.baeldung.docker
docker
0.0.1
- docker-sample-app
- docker-sample-app
- Demo project for Spring Boot and Docker
-
-
- 11
-
-
org.springframework.boot
@@ -42,4 +39,8 @@
-
+
+ 11
+
+
+
\ No newline at end of file
diff --git a/docker/docker-spring-boot-postgres/pom.xml b/docker/docker-spring-boot-postgres/pom.xml
index d08ae130db..7a4ed1db3c 100644
--- a/docker/docker-spring-boot-postgres/pom.xml
+++ b/docker/docker-spring-boot-postgres/pom.xml
@@ -1,13 +1,14 @@
-
- 4.0.0
- com.baeldung.docker
- docker-spring-boot-postgres
- 0.0.1-SNAPSHOT
- docker-spring-boot-postgres
- Demo project showing Spring Boot, PostgreSQL, and Docker
-
+
+ 4.0.0
+ com.baeldung.docker
+ docker-spring-boot-postgres
+ 0.0.1-SNAPSHOT
+ docker-spring-boot-postgres
+ Demo project showing Spring Boot, PostgreSQL, and Docker
+
com.baeldung
parent-boot-2
@@ -15,33 +16,32 @@
../../parent-boot-2
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
-
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.postgresql
+ postgresql
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
-
- org.postgresql
- postgresql
- runtime
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
11
diff --git a/docker/docker-spring-boot/README.md b/docker/docker-spring-boot/README.md
index 4af9378290..0fc9d2b6b5 100644
--- a/docker/docker-spring-boot/README.md
+++ b/docker/docker-spring-boot/README.md
@@ -1,3 +1,4 @@
### Relevant Articles:
- [Creating Docker Images with Spring Boot](https://www.baeldung.com/spring-boot-docker-images)
+- [Starting Spring Boot Application in Docker With Profile](https://www.baeldung.com/spring-boot-docker-start-with-profile)
diff --git a/docker/docker-spring-boot/mvnw b/docker/docker-spring-boot/mvnw
deleted file mode 100755
index a16b5431b4..0000000000
--- a/docker/docker-spring-boot/mvnw
+++ /dev/null
@@ -1,310 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Maven Start Up Batch script
-#
-# Required ENV vars:
-# ------------------
-# JAVA_HOME - location of a JDK home dir
-#
-# Optional ENV vars
-# -----------------
-# M2_HOME - location of maven2's installed home dir
-# MAVEN_OPTS - parameters passed to the Java VM when running Maven
-# e.g. to debug Maven itself, use
-# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-# ----------------------------------------------------------------------------
-
-if [ -z "$MAVEN_SKIP_RC" ] ; then
-
- if [ -f /etc/mavenrc ] ; then
- . /etc/mavenrc
- fi
-
- if [ -f "$HOME/.mavenrc" ] ; then
- . "$HOME/.mavenrc"
- fi
-
-fi
-
-# OS specific support. $var _must_ be set to either true or false.
-cygwin=false;
-darwin=false;
-mingw=false
-case "`uname`" in
- CYGWIN*) cygwin=true ;;
- MINGW*) mingw=true;;
- Darwin*) darwin=true
- # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
- # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
- if [ -z "$JAVA_HOME" ]; then
- if [ -x "/usr/libexec/java_home" ]; then
- export JAVA_HOME="`/usr/libexec/java_home`"
- else
- export JAVA_HOME="/Library/Java/Home"
- fi
- fi
- ;;
-esac
-
-if [ -z "$JAVA_HOME" ] ; then
- if [ -r /etc/gentoo-release ] ; then
- JAVA_HOME=`java-config --jre-home`
- fi
-fi
-
-if [ -z "$M2_HOME" ] ; then
- ## resolve links - $0 may be a link to maven's home
- PRG="$0"
-
- # need this for relative symlinks
- while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG="`dirname "$PRG"`/$link"
- fi
- done
-
- saveddir=`pwd`
-
- M2_HOME=`dirname "$PRG"`/..
-
- # make it fully qualified
- M2_HOME=`cd "$M2_HOME" && pwd`
-
- cd "$saveddir"
- # echo Using m2 at $M2_HOME
-fi
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched
-if $cygwin ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --unix "$M2_HOME"`
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
-fi
-
-# For Mingw, ensure paths are in UNIX format before anything is touched
-if $mingw ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME="`(cd "$M2_HOME"; pwd)`"
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
-fi
-
-if [ -z "$JAVA_HOME" ]; then
- javaExecutable="`which javac`"
- if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
- # readlink(1) is not available as standard on Solaris 10.
- readLink=`which readlink`
- if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
- if $darwin ; then
- javaHome="`dirname \"$javaExecutable\"`"
- javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
- else
- javaExecutable="`readlink -f \"$javaExecutable\"`"
- fi
- javaHome="`dirname \"$javaExecutable\"`"
- javaHome=`expr "$javaHome" : '\(.*\)/bin'`
- JAVA_HOME="$javaHome"
- export JAVA_HOME
- fi
- fi
-fi
-
-if [ -z "$JAVACMD" ] ; then
- if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- else
- JAVACMD="`which java`"
- fi
-fi
-
-if [ ! -x "$JAVACMD" ] ; then
- echo "Error: JAVA_HOME is not defined correctly." >&2
- echo " We cannot execute $JAVACMD" >&2
- exit 1
-fi
-
-if [ -z "$JAVA_HOME" ] ; then
- echo "Warning: JAVA_HOME environment variable is not set."
-fi
-
-CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
-
-# traverses directory structure from process work directory to filesystem root
-# first directory with .mvn subdirectory is considered project base directory
-find_maven_basedir() {
-
- if [ -z "$1" ]
- then
- echo "Path not specified to find_maven_basedir"
- return 1
- fi
-
- basedir="$1"
- wdir="$1"
- while [ "$wdir" != '/' ] ; do
- if [ -d "$wdir"/.mvn ] ; then
- basedir=$wdir
- break
- fi
- # workaround for JBEAP-8937 (on Solaris 10/Sparc)
- if [ -d "${wdir}" ]; then
- wdir=`cd "$wdir/.."; pwd`
- fi
- # end of workaround
- done
- echo "${basedir}"
-}
-
-# concatenates all lines of a file
-concat_lines() {
- if [ -f "$1" ]; then
- echo "$(tr -s '\n' ' ' < "$1")"
- fi
-}
-
-BASE_DIR=`find_maven_basedir "$(pwd)"`
-if [ -z "$BASE_DIR" ]; then
- exit 1;
-fi
-
-##########################################################################################
-# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-# This allows using the maven wrapper in projects that prohibit checking in binary data.
-##########################################################################################
-if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Found .mvn/wrapper/maven-wrapper.jar"
- fi
-else
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
- fi
- if [ -n "$MVNW_REPOURL" ]; then
- jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
- else
- jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
- fi
- while IFS="=" read key value; do
- case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
- esac
- done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Downloading from: $jarUrl"
- fi
- wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
- if $cygwin; then
- wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
- fi
-
- if command -v wget > /dev/null; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Found wget ... using wget"
- fi
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- wget "$jarUrl" -O "$wrapperJarPath"
- else
- wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
- fi
- elif command -v curl > /dev/null; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Found curl ... using curl"
- fi
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- curl -o "$wrapperJarPath" "$jarUrl" -f
- else
- curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
- fi
-
- else
- if [ "$MVNW_VERBOSE" = true ]; then
- echo "Falling back to using Java to download"
- fi
- javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
- # For Cygwin, switch paths to Windows format before running javac
- if $cygwin; then
- javaClass=`cygpath --path --windows "$javaClass"`
- fi
- if [ -e "$javaClass" ]; then
- if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
- if [ "$MVNW_VERBOSE" = true ]; then
- echo " - Compiling MavenWrapperDownloader.java ..."
- fi
- # Compiling the Java class
- ("$JAVA_HOME/bin/javac" "$javaClass")
- fi
- if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
- # Running the downloader
- if [ "$MVNW_VERBOSE" = true ]; then
- echo " - Running MavenWrapperDownloader.java ..."
- fi
- ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
- fi
- fi
- fi
-fi
-##########################################################################################
-# End of extension
-##########################################################################################
-
-export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
-if [ "$MVNW_VERBOSE" = true ]; then
- echo $MAVEN_PROJECTBASEDIR
-fi
-MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --path --windows "$M2_HOME"`
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
- [ -n "$MAVEN_PROJECTBASEDIR" ] &&
- MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
-fi
-
-# Provide a "standardized" way to retrieve the CLI args that will
-# work with both Windows and non-Windows executions.
-MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
-export MAVEN_CMD_LINE_ARGS
-
-WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-exec "$JAVACMD" \
- $MAVEN_OPTS \
- -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
- ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/docker/docker-spring-boot/mvnw.cmd b/docker/docker-spring-boot/mvnw.cmd
deleted file mode 100644
index c8d43372c9..0000000000
--- a/docker/docker-spring-boot/mvnw.cmd
+++ /dev/null
@@ -1,182 +0,0 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM https://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Maven Start Up Batch script
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@REM
-@REM Optional ENV vars
-@REM M2_HOME - location of maven2's installed home dir
-@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
-@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
-@REM e.g. to debug Maven itself, use
-@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-@REM ----------------------------------------------------------------------------
-
-@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
-@echo off
-@REM set title of command window
-title %0
-@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
-@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
-
-@REM set %HOME% to equivalent of $HOME
-if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
-
-@REM Execute a user defined script before this one
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
-@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
-if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
-:skipRcPre
-
-@setlocal
-
-set ERROR_CODE=0
-
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
-@REM ==== START VALIDATION ====
-if not "%JAVA_HOME%" == "" goto OkJHome
-
-echo.
-echo Error: JAVA_HOME not found in your environment. >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-:OkJHome
-if exist "%JAVA_HOME%\bin\java.exe" goto init
-
-echo.
-echo Error: JAVA_HOME is set to an invalid directory. >&2
-echo JAVA_HOME = "%JAVA_HOME%" >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-@REM ==== END VALIDATION ====
-
-:init
-
-@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
-@REM Fallback to current working directory if not found.
-
-set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
-IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
-
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
-:findBaseDir
-IF EXIST "%WDIR%"\.mvn goto baseDirFound
-cd ..
-IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
-goto findBaseDir
-
-:baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
-cd "%EXEC_DIR%"
-goto endDetectBaseDir
-
-:baseDirNotFound
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
-cd "%EXEC_DIR%"
-
-:endDetectBaseDir
-
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
-
-@setlocal EnableExtensions EnableDelayedExpansion
-for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
-@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
-
-:endReadAdditionalConfig
-
-SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
-set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
-
-FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
-)
-
-@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
-if exist %WRAPPER_JAR% (
- if "%MVNW_VERBOSE%" == "true" (
- echo Found %WRAPPER_JAR%
- )
-) else (
- if not "%MVNW_REPOURL%" == "" (
- SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
- )
- if "%MVNW_VERBOSE%" == "true" (
- echo Couldn't find %WRAPPER_JAR%, downloading it ...
- echo Downloading from: %DOWNLOAD_URL%
- )
-
- powershell -Command "&{"^
- "$webclient = new-object System.Net.WebClient;"^
- "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
- "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
- "}"^
- "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
- "}"
- if "%MVNW_VERBOSE%" == "true" (
- echo Finished downloading %WRAPPER_JAR%
- )
-)
-@REM End of extension
-
-@REM Provide a "standardized" way to retrieve the CLI args that will
-@REM work with both Windows and non-Windows executions.
-set MAVEN_CMD_LINE_ARGS=%*
-
-%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
-if ERRORLEVEL 1 goto error
-goto end
-
-:error
-set ERROR_CODE=1
-
-:end
-@endlocal & set ERROR_CODE=%ERROR_CODE%
-
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
-@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
-if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
-:skipRcPost
-
-@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%" == "on" pause
-
-if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
-
-exit /B %ERROR_CODE%
diff --git a/docker/docker-spring-boot/pom.xml b/docker/docker-spring-boot/pom.xml
index 74bd1561cf..c42f7602b4 100644
--- a/docker/docker-spring-boot/pom.xml
+++ b/docker/docker-spring-boot/pom.xml
@@ -3,33 +3,21 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
+ docker-spring-boot
+ docker-spring-boot
+ Demo project showing Spring Boot and Docker
+
com.baeldung.docker
docker
0.0.1
- docker-spring-boot
-
- docker-spring-boot
- Demo project showing Spring Boot and Docker
-
-
- 11
-
-
org.springframework.boot
spring-boot-starter-web
-
-
- com.baeldung.docker
- docker-internal-dto
- 0.0.1
-
-
org.springframework.boot
spring-boot-starter-test
@@ -58,4 +46,8 @@
-
+
+ 11
+
+
+
\ No newline at end of file
diff --git a/docker/heap-sizing/pom.xml b/docker/heap-sizing/pom.xml
index 2cc354f6cf..32c200c1c0 100644
--- a/docker/heap-sizing/pom.xml
+++ b/docker/heap-sizing/pom.xml
@@ -48,7 +48,6 @@
com.google.cloud.tools
jib-maven-plugin
2.7.1
-
heapsizing-demo-jib
@@ -62,4 +61,4 @@
11
-
+
\ No newline at end of file
diff --git a/docker/pom.xml b/docker/pom.xml
index 67f9a5b3bd..f46ceac963 100644
--- a/docker/pom.xml
+++ b/docker/pom.xml
@@ -3,14 +3,13 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
-
com.baeldung.docker
docker
0.0.1
docker
Demo project showing Spring Boot and Docker
pom
-
+
com.baeldung
parent-boot-2
@@ -18,10 +17,6 @@
../parent-boot-2
-
- 11
-
-
docker-internal-dto
docker-spring-boot
@@ -31,4 +26,8 @@
docker-push-to-private-repo
-
+
+ 11
+
+
+
\ No newline at end of file
diff --git a/feign/pom.xml b/feign/pom.xml
index 026afdfc7a..8fa864fa46 100644
--- a/feign/pom.xml
+++ b/feign/pom.xml
@@ -1,5 +1,7 @@
-
+
4.0.0
com.baeldung.feign
feign
@@ -69,6 +71,7 @@
test
+
@@ -92,10 +95,8 @@
src/main/resources/users.xsd
-
-
org.jvnet.jaxb2.maven2
maven-jaxb2-plugin
@@ -111,7 +112,6 @@
*.xsd
-
com.baeldung.feign.soap
target/generated-sources/jaxb
@@ -119,6 +119,6 @@
-
+
\ No newline at end of file
diff --git a/graphql/graphql-error-handling/README.md b/graphql/graphql-error-handling/README.md
new file mode 100644
index 0000000000..06a2957ac1
--- /dev/null
+++ b/graphql/graphql-error-handling/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- [Error Handling in GraphQL With Spring Boot](https://www.baeldung.com/spring-graphql-error-handling)
diff --git a/graphql/graphql-error-handling/pom.xml b/graphql/graphql-error-handling/pom.xml
index ea1cf96a0e..92696d8ed7 100644
--- a/graphql/graphql-error-handling/pom.xml
+++ b/graphql/graphql-error-handling/pom.xml
@@ -1,12 +1,12 @@
+ 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
graphql-error-handling
1.0
- jar
graphql-error-handling
+ jar
com.baeldung.graphql
@@ -19,56 +19,47 @@
org.springframework.boot
spring-boot-starter-data-jpa
-
org.springframework.boot
spring-boot-starter-web
-
com.graphql-java
graphql-spring-boot-starter
${graphql-spring-boot-starter.version}
-
com.graphql-java
graphql-java-tools
${graphql-java-tools.version}
-
org.projectlombok
lombok
${lombok.version}
-
com.h2database
h2
${h2.version}
-
org.springframework.boot
spring-boot-test
test
-
com.graphql-java
graphql-spring-boot-starter-test
test
${graphql-spring-boot-starter.version}
-
org.skyscreamer
jsonassert
${jsonassert.version}
test
-
diff --git a/graphql/graphql-java/pom.xml b/graphql/graphql-java/pom.xml
index 5e5bc8f648..b0b2c15359 100644
--- a/graphql/graphql-java/pom.xml
+++ b/graphql/graphql-java/pom.xml
@@ -85,7 +85,6 @@
httpclient
${httpclient.version}
-
org.mock-server
mockserver-netty
@@ -98,13 +97,11 @@
${mockserver-client-java.version}
test
-
com.graphql-java
graphql-java-extended-scalars
${graphql-java-extended-scalars.version}
-
@@ -155,14 +152,11 @@
1.9.0
0.5.0
4.5.13
-
5.13.2
5.13.2
-
10.0.7
-
1.18
2022-04-06T00-10-27-a70541e
-
+
\ No newline at end of file
diff --git a/graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java b/graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java
index fb5a789428..e72f6a38b9 100644
--- a/graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java
+++ b/graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java
@@ -3,12 +3,13 @@ package com.baeldung.graphql;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.mockserver.client.MockServerClient;
+import org.mockserver.configuration.Configuration;
import org.mockserver.integration.ClientAndServer;
import org.mockserver.model.HttpStatusCode;
+import org.slf4j.event.Level;
import java.io.IOException;
import java.net.ServerSocket;
-import java.net.URISyntaxException;
import static org.mockserver.integration.ClientAndServer.startClientAndServer;
import static org.mockserver.matchers.Times.exactly;
@@ -17,20 +18,22 @@ import static org.mockserver.model.HttpResponse.response;
public class GraphQLMockServer {
- public static ClientAndServer mockServer;
+ private static final String SERVER_ADDRESS = "127.0.0.1";
+ private static final String PATH = "/graphql";
+
public static String serviceUrl;
+ private static ClientAndServer mockServer;
private static int serverPort;
- public static final String SERVER_ADDRESS = "127.0.0.1";
- public static final String HTTP_GET_POST = "GET";
- public static final String PATH = "/graphql";
-
@BeforeAll
- static void startServer() throws IOException, URISyntaxException {
+ static void startServer() throws IOException {
serverPort = getFreePort();
serviceUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH;
- mockServer = startClientAndServer(serverPort);
+
+ Configuration config = Configuration.configuration().logLevel(Level.WARN);
+ mockServer = startClientAndServer(config, serverPort);
+
mockAllBooksTitleRequest();
mockAllBooksTitleAuthorRequest();
}
diff --git a/graphql/graphql-spqr/pom.xml b/graphql/graphql-spqr/pom.xml
index ad040c1557..75a1b5d79b 100644
--- a/graphql/graphql-spqr/pom.xml
+++ b/graphql/graphql-spqr/pom.xml
@@ -28,4 +28,5 @@
0.0.6
+
\ No newline at end of file
diff --git a/grpc/pom.xml b/grpc/pom.xml
index 40284c90fe..40d35183dc 100644
--- a/grpc/pom.xml
+++ b/grpc/pom.xml
@@ -40,7 +40,7 @@
javax.annotation
javax.annotation-api
- 1.2
+ ${annotation-api.version}
@@ -79,6 +79,7 @@
3.17.2
1.6.2
0.6.1
+ 1.2
\ No newline at end of file
diff --git a/jakarta-ee/pom.xml b/jakarta-ee/pom.xml
index dea4437345..afd31d7ece 100644
--- a/jakarta-ee/pom.xml
+++ b/jakarta-ee/pom.xml
@@ -51,25 +51,20 @@
admin
password
-
${local.glassfish.domain}
8080
4848
-
${project.artifactId}
target/${project.build.finalName}.war
-
true
false
true
-
-
diff --git a/java-numbers-4/README.md b/java-numbers-4/README.md
index c18a5ebe6f..2a77992c8f 100644
--- a/java-numbers-4/README.md
+++ b/java-numbers-4/README.md
@@ -8,3 +8,4 @@
- [Convert Byte Size Into a Human-Readable Format in Java](https://www.baeldung.com/java-human-readable-byte-size)
- [Convert boolean to int in Java](https://www.baeldung.com/java-boolean-to-int)
- [Generate a Random Value From an Enum](https://www.baeldung.com/java-enum-random-value)
+- [Reverse a Number in Java](https://www.baeldung.com/java-reverse-number)
diff --git a/java-numbers-4/pom.xml b/java-numbers-4/pom.xml
index 40fe17cc0d..4750b58511 100644
--- a/java-numbers-4/pom.xml
+++ b/java-numbers-4/pom.xml
@@ -23,7 +23,6 @@
org.apache.commons
commons-lang3
${commons-lang3.version}
- test
com.google.guava
diff --git a/java-numbers-4/src/main/java/com/baeldung/booleantoint/BooleanToInt.java b/java-numbers-4/src/main/java/com/baeldung/booleantoint/BooleanToInt.java
new file mode 100644
index 0000000000..3cca1592fb
--- /dev/null
+++ b/java-numbers-4/src/main/java/com/baeldung/booleantoint/BooleanToInt.java
@@ -0,0 +1,42 @@
+package com.baeldung.booleantoint;
+
+import org.apache.commons.lang3.BooleanUtils;
+
+public class BooleanToInt {
+ public static int booleanPrimitiveToInt(boolean foo) {
+ int bar = 0;
+ if (foo) {
+ bar = 1;
+ }
+ return bar;
+ }
+
+ public static int booleanPrimitiveToIntTernary(boolean foo) {
+ return (foo) ? 1 : 0;
+ }
+
+ public static int booleanObjectToInt(boolean foo) {
+ return Boolean.compare(foo, false);
+ }
+
+ public static int booleanObjectToIntInverse(boolean foo) {
+ return Boolean.compare(foo, true) + 1;
+ }
+
+ public static int booleanObjectMethodToInt(Boolean foo) {
+ return foo.compareTo(false);
+ }
+
+ public static int booleanObjectMethodToIntInverse(Boolean foo) {
+ return foo.compareTo(true) + 1;
+ }
+
+ public static int booleanUtilsToInt(Boolean foo) {
+ return BooleanUtils.toInteger(foo);
+ }
+
+ public static int bitwiseBooleanToInt(Boolean foo) {
+ return (Boolean.hashCode(foo) >> 1) & 1;
+ }
+}
+
diff --git a/java-numbers-4/src/main/java/com/baeldung/reversenumber/ReverseNumber.java b/java-numbers-4/src/main/java/com/baeldung/reversenumber/ReverseNumber.java
new file mode 100644
index 0000000000..04865a8d52
--- /dev/null
+++ b/java-numbers-4/src/main/java/com/baeldung/reversenumber/ReverseNumber.java
@@ -0,0 +1,45 @@
+package com.baeldung.reversenumber;
+
+public class ReverseNumber {
+
+ public static int reverseNumberWhileLoop(int number) {
+ int reversedNumber = 0;
+ int numberToReverse = Math.abs(number);
+
+ while (numberToReverse > 0) {
+ int mod = numberToReverse % 10;
+ reversedNumber = reversedNumber * 10 + mod;
+ numberToReverse /= 10;
+ }
+
+ return number < 0 ? reversedNumber * -1 : reversedNumber;
+ }
+
+ public static int reverseNumberForLoop(int number) {
+ int reversedNumber = 0;
+ int numberToReverse = Math.abs(number);
+
+ for (; numberToReverse > 0; numberToReverse /= 10) {
+ int mod = numberToReverse % 10;
+ reversedNumber = reversedNumber * 10 + mod;
+ }
+
+ return number < 0 ? reversedNumber * -1 : reversedNumber;
+ }
+
+ public static int reverseNumberRecWrapper(int number) {
+ int output = reverseNumberRec(Math.abs(number), 0);
+ return number < 0 ? output * -1 : output;
+ }
+ private static int reverseNumberRec(int numberToReverse, int recursiveReversedNumber) {
+
+ if (numberToReverse > 0) {
+ int mod = numberToReverse % 10;
+ recursiveReversedNumber = recursiveReversedNumber * 10 + mod;
+ numberToReverse /= 10;
+ return reverseNumberRec(numberToReverse, recursiveReversedNumber);
+ }
+
+ return recursiveReversedNumber;
+ }
+}
diff --git a/java-numbers-4/src/test/java/com/baeldung/booleantoint/BooleanToIntUnitTest.java b/java-numbers-4/src/test/java/com/baeldung/booleantoint/BooleanToIntUnitTest.java
new file mode 100644
index 0000000000..032eb1d28c
--- /dev/null
+++ b/java-numbers-4/src/test/java/com/baeldung/booleantoint/BooleanToIntUnitTest.java
@@ -0,0 +1,55 @@
+package com.baeldung.booleantoint;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class BooleanToIntUnitTest {
+ @Test
+ void givenBooleanPrimitiveValue_ThenReturnInt() {
+ assertEquals(1, BooleanToInt.booleanPrimitiveToInt(true));
+ assertEquals(0, BooleanToInt.booleanPrimitiveToInt(false));
+ }
+
+ @Test
+ void givenBooleanPrimitiveValue_ThenReturnIntTernary() {
+ assertEquals(1, BooleanToInt.booleanPrimitiveToIntTernary(true));
+ assertEquals(0, BooleanToInt.booleanPrimitiveToIntTernary(false));
+ }
+
+ @Test
+ void givenBooleanObject_ThenReturnInt() {
+ assertEquals(0, BooleanToInt.booleanObjectToInt(false));
+ assertEquals(1, BooleanToInt.booleanObjectToInt(true));
+ }
+
+ @Test
+ void givenBooleanObject_ThenReturnIntInverse() {
+ assertEquals(0, BooleanToInt.booleanObjectToIntInverse(false));
+ assertEquals(1, BooleanToInt.booleanObjectToIntInverse(true));
+ }
+
+ @Test
+ void givenBooleanObject_ThenReturnIntUsingClassMethod() {
+ assertEquals(0, BooleanToInt.booleanObjectMethodToInt(false));
+ assertEquals(1, BooleanToInt.booleanObjectMethodToInt(true));
+ }
+
+ @Test
+ void givenBooleanObject_ThenReturnIntUsingClassMethodInverse() {
+ assertEquals(0, BooleanToInt.booleanObjectMethodToIntInverse(false));
+ assertEquals(1, BooleanToInt.booleanObjectMethodToIntInverse(true));
+ }
+
+ @Test
+ void givenBoolean_ThenReturnIntUsingBooleanUtils() {
+ assertEquals(0, BooleanToInt.booleanUtilsToInt(false));
+ assertEquals(1, BooleanToInt.booleanUtilsToInt(true));
+ }
+
+ @Test
+ void givenBoolean_ThenReturnIntUsingBitwiseOperators() {
+ assertEquals(0, BooleanToInt.bitwiseBooleanToInt(false));
+ assertEquals(1, BooleanToInt.bitwiseBooleanToInt(true));
+ }
+}
diff --git a/java-numbers-4/src/test/java/com/baeldung/reversenumber/ReverseNumberUnitTest.java b/java-numbers-4/src/test/java/com/baeldung/reversenumber/ReverseNumberUnitTest.java
new file mode 100644
index 0000000000..2c55bcc539
--- /dev/null
+++ b/java-numbers-4/src/test/java/com/baeldung/reversenumber/ReverseNumberUnitTest.java
@@ -0,0 +1,34 @@
+package com.baeldung.reversenumber;
+
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ReverseNumberUnitTest {
+
+ private static final int ORIGINAL_NUMBER = 123456789;
+ private static final int REVERSED_NUMBER = 987654321;
+
+ @Test
+ void whenReverseNumberWhileLoop_thenOriginalEqualToReverse() {
+ Assertions.assertThat(ReverseNumber.reverseNumberWhileLoop(ORIGINAL_NUMBER)).isEqualTo(REVERSED_NUMBER);
+ }
+
+ @Test
+ void whenReverseNumberForLoop_thenOriginalEqualToReverse() {
+ Assertions.assertThat(ReverseNumber.reverseNumberForLoop(ORIGINAL_NUMBER)).isEqualTo(REVERSED_NUMBER);
+ }
+
+ @Test
+ void whenReverseNumberRec_thenOriginalEqualToReverse() {
+ Assertions.assertThat(ReverseNumber.reverseNumberRecWrapper(ORIGINAL_NUMBER)).isEqualTo(REVERSED_NUMBER);
+ }
+
+ @Test
+ void whenReverseNegativeNumber_thenNumberShouldReverse() {
+ Assertions.assertThat(ReverseNumber.reverseNumberWhileLoop(ORIGINAL_NUMBER * -1)).isEqualTo(REVERSED_NUMBER * -1);
+ Assertions.assertThat(ReverseNumber.reverseNumberForLoop(ORIGINAL_NUMBER * -1)).isEqualTo(REVERSED_NUMBER * -1);
+ Assertions.assertThat(ReverseNumber.reverseNumberRecWrapper(ORIGINAL_NUMBER * -1)).isEqualTo(REVERSED_NUMBER * -1);
+ }
+}
\ No newline at end of file
diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/Account.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/Account.java
new file mode 100644
index 0000000000..b47a47ec81
--- /dev/null
+++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/Account.java
@@ -0,0 +1,37 @@
+package com.baeldung.javaxval.constraint.composition;
+
+public class Account {
+
+ @ValidAlphanumeric
+ private String username;
+
+ @ValidAlphanumericWithSingleViolation
+ private String password;
+
+ @ValidLengthOrNumericCharacter
+ private String nickname;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+}
diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AccountService.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AccountService.java
new file mode 100644
index 0000000000..f76fed8f04
--- /dev/null
+++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AccountService.java
@@ -0,0 +1,19 @@
+package com.baeldung.javaxval.constraint.composition;
+
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+
+@Component
+@Validated
+public class AccountService {
+
+ @AlphanumericReturnValue
+ public String getAnInvalidAlphanumericValue() {
+ return "john";
+ }
+
+ @AlphanumericReturnValue
+ public String getValidAlphanumericValue() {
+ return "johnDoe1234";
+ }
+}
diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AlphanumericReturnValue.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AlphanumericReturnValue.java
new file mode 100644
index 0000000000..6e3408712b
--- /dev/null
+++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AlphanumericReturnValue.java
@@ -0,0 +1,36 @@
+package com.baeldung.javaxval.constraint.composition;
+
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraintvalidation.SupportedValidationTarget;
+import javax.validation.constraintvalidation.ValidationTarget;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@NotNull
+@Pattern(regexp = ".*\\d.*", message = "must contain at least one numeric character")
+@Length(min = 6, max = 32, message = "must have between 6 and 32 characters")
+@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
+@Retention(RUNTIME)
+@Documented
+@Constraint(validatedBy = {})
+@SupportedValidationTarget(ValidationTarget.ANNOTATED_ELEMENT)
+public @interface AlphanumericReturnValue {
+
+ String message() default "method return value should have a valid length and contain numeric character(s).";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+}
+
diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionConfig.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionConfig.java
new file mode 100644
index 0000000000..ac0ec81ab2
--- /dev/null
+++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionConfig.java
@@ -0,0 +1,21 @@
+package com.baeldung.javaxval.constraint.composition;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
+
+@Configuration
+@ComponentScan({ "com.baeldung.javaxval.constraint.composition" })
+public class ConstraintCompositionConfig {
+
+ @Bean
+ public MethodValidationPostProcessor methodValidationPostProcessor() {
+ return new MethodValidationPostProcessor();
+ }
+
+ @Bean
+ public AccountService accountService() {
+ return new AccountService();
+ }
+}
\ No newline at end of file
diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumeric.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumeric.java
new file mode 100644
index 0000000000..916b4e36a4
--- /dev/null
+++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumeric.java
@@ -0,0 +1,37 @@
+package com.baeldung.javaxval.constraint.composition;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+
+import org.hibernate.validator.constraints.Length;
+
+@NotNull
+@Pattern(regexp = ".*\\d.*", message = "must contain at least one numeric character")
+@Length(min = 6, max = 32, message = "must have between 6 and 32 characters")
+@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
+@Retention(RUNTIME)
+@Documented
+@Constraint(validatedBy = {})
+public @interface ValidAlphanumeric {
+
+ String message() default "field should have a valid length and contain numeric character(s).";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+}
+
diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumericWithSingleViolation.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumericWithSingleViolation.java
new file mode 100644
index 0000000000..edc5b6af3e
--- /dev/null
+++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumericWithSingleViolation.java
@@ -0,0 +1,38 @@
+package com.baeldung.javaxval.constraint.composition;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import javax.validation.ReportAsSingleViolation;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+
+import org.hibernate.validator.constraints.Length;
+
+@NotNull
+@Pattern(regexp = ".*\\d.*", message = "must contain at least one numeric character")
+@Length(min = 6, max = 32, message = "must have between 6 and 32 characters")
+@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
+@Retention(RUNTIME)
+@Documented
+@Constraint(validatedBy = {})
+@ReportAsSingleViolation
+public @interface ValidAlphanumericWithSingleViolation {
+
+ String message() default "field should have a valid length and contain numeric character(s).";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+}
\ No newline at end of file
diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidLengthOrNumericCharacter.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidLengthOrNumericCharacter.java
new file mode 100644
index 0000000000..444cb4a63a
--- /dev/null
+++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidLengthOrNumericCharacter.java
@@ -0,0 +1,34 @@
+package com.baeldung.javaxval.constraint.composition;
+
+import org.hibernate.validator.constraints.CompositionType;
+import org.hibernate.validator.constraints.ConstraintComposition;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import javax.validation.constraints.Pattern;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Pattern(regexp = ".*\\d.*", message = "must contain at least one numeric character")
+@Length(min = 6, max = 32, message = "must have between 6 and 32 characters")
+@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
+@Retention(RUNTIME)
+@Documented
+@Constraint(validatedBy = {})
+@ConstraintComposition(CompositionType.OR)
+public @interface ValidLengthOrNumericCharacter {
+
+ String message() default "field should have a valid length or contain numeric character(s).";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+}
+
diff --git a/javaxval/src/test/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionUnitTest.java b/javaxval/src/test/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionUnitTest.java
new file mode 100644
index 0000000000..6c2b8f801c
--- /dev/null
+++ b/javaxval/src/test/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionUnitTest.java
@@ -0,0 +1,80 @@
+package com.baeldung.javaxval.constraint.composition;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.Set;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { ConstraintCompositionConfig.class }, loader = AnnotationConfigContextLoader.class)
+public class ConstraintCompositionUnitTest {
+
+ @Autowired
+ private AccountService accountService;
+
+ private Validator validator;
+
+ @Before
+ public void setup() {
+ ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
+ validator = factory.getValidator();
+ }
+
+ @Test
+ public void whenUsernameIsInvalid_validationShouldReturnTwoViolations() {
+ Account account = new Account();
+ account.setNickname("valid_nickname123");
+ account.setPassword("valid_password123");
+ account.setUsername("john");
+
+ Set> violations = validator.validate(account);
+
+ assertThat(violations).hasSize(2);
+ }
+
+ @Test
+ public void whenPasswordIsInvalid_validationShouldReturnSingleViolation() {
+ Account account = new Account();
+ account.setUsername("valid_username123");
+ account.setNickname("valid_nickname123");
+ account.setPassword("john");
+
+ Set> violations = validator.validate(account);
+
+ assertThat(violations).hasSize(1);
+ }
+
+ @Test
+ public void whenNicknameIsTooShortButContainsNumericCharacter_validationShouldPass() {
+ Account account = new Account();
+ account.setUsername("valid_username123");
+ account.setPassword("valid_password123");
+ account.setNickname("doe1");
+
+ Set> violations = validator.validate(account);
+
+ assertThat(violations).isEmpty();
+ }
+
+ @Test
+ public void whenMethodReturnValuesIsInvalid_validationShouldFail() {
+ assertThatThrownBy(() -> accountService.getAnInvalidAlphanumericValue()).isInstanceOf(ConstraintViolationException.class)
+ .hasMessageContaining("must contain at least one numeric character")
+ .hasMessageContaining("must have between 6 and 32 characters");
+ }
+
+}
\ No newline at end of file
diff --git a/jhipster-5/bookstore-monolith/pom.xml b/jhipster-5/bookstore-monolith/pom.xml
index 411de0e712..ccf7a3c85e 100644
--- a/jhipster-5/bookstore-monolith/pom.xml
+++ b/jhipster-5/bookstore-monolith/pom.xml
@@ -1090,6 +1090,66 @@
+
+ integration-lite-first
+
+
+
+ com.github.eirslett
+ frontend-maven-plugin
+
+
+
+ install node and npm
+ none
+
+
+ npm install
+ none
+
+
+ webpack build dev
+ none
+
+
+ webpack build test
+ none
+
+
+
+
+
+
+
+ integration-lite-second
+
+
+
+ com.github.eirslett
+ frontend-maven-plugin
+
+
+
+ install node and npm
+ none
+
+
+ npm install
+ none
+
+
+ webpack build dev
+ none
+
+
+ webpack build test
+ none
+
+
+
+
+
+
diff --git a/jib/pom.xml b/jib/pom.xml
index 8208eebdf7..bbc9a3c623 100644
--- a/jib/pom.xml
+++ b/jib/pom.xml
@@ -43,4 +43,5 @@
2.5.0
+
\ No newline at end of file
diff --git a/json-2/pom.xml b/json-2/pom.xml
index 3e12fccc29..6fbdebc953 100644
--- a/json-2/pom.xml
+++ b/json-2/pom.xml
@@ -27,7 +27,7 @@
org.jsonschema2pojo
jsonschema2pojo-core
- 1.1.1
+ ${jsonschema2pojo-core.version}
com.jsoniter
@@ -62,7 +62,7 @@
com.io-informatics.oss
jackson-jsonld
- 0.1.1
+ ${jackson-jsonld.version}
jackson-databind
@@ -85,7 +85,7 @@
de.escalon.hypermedia
hydra-jsonld
- 0.4.2
+ ${hydra-jsonld.version}
jackson-databind
@@ -96,7 +96,7 @@
com.github.jsonld-java
jsonld-java
- 0.13.0
+ ${jsonld-java.version}
jackson-core
@@ -154,6 +154,10 @@
1.9.2
1.2.21
20211205
+ 1.1.1
+ 0.1.1
+ 0.4.2
+ 0.13.0
\ No newline at end of file
diff --git a/kubernetes/k8s-intro/pom.xml b/kubernetes/k8s-intro/pom.xml
index 6d1cec9971..067700bdad 100644
--- a/kubernetes/k8s-intro/pom.xml
+++ b/kubernetes/k8s-intro/pom.xml
@@ -15,7 +15,7 @@
io.kubernetes
client-java
- 11.0.0
+ ${client-java.version}
ch.qos.logback
@@ -39,4 +39,8 @@
+
+ 11.0.0
+
+
\ No newline at end of file
diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml
index c51b264e83..d68a9e0703 100644
--- a/libraries-3/pom.xml
+++ b/libraries-3/pom.xml
@@ -112,7 +112,7 @@
structurizr-plantuml
${structurizr.version}
-
+
org.immutables
value
${immutables.version}
@@ -177,7 +177,7 @@
-
-XepExcludedPaths:(.*)/test/.*|(.*)/jcabi/.*
@@ -190,7 +190,7 @@
plexus-compiler-javac-errorprone
2.8
-
com.google.errorprone
diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml
index dd48453a8c..f0f5338560 100644
--- a/libraries-data/pom.xml
+++ b/libraries-data/pom.xml
@@ -172,7 +172,7 @@
1.0.0
2.4.0
2.8.2
- 1.1.0
+ 1.1.1
1.5.0
3.8.4
0.15.0
diff --git a/libraries-primitive/pom.xml b/libraries-primitive/pom.xml
index ed4982d91c..7d12e9a436 100644
--- a/libraries-primitive/pom.xml
+++ b/libraries-primitive/pom.xml
@@ -8,6 +8,12 @@
1.0-SNAPSHOT
libraries-primitive
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
diff --git a/lightrun/README.md b/lightrun/README.md
new file mode 100644
index 0000000000..18d4ccc12f
--- /dev/null
+++ b/lightrun/README.md
@@ -0,0 +1,36 @@
+# Lightrun Example Application - Tasks Management
+
+This application exists as an example for the Lightrun series of articles.
+
+## Building
+
+This application requires [Apache Maven](https://maven.apache.org/) and [Java 17+](https://www.oracle.com/java/technologies/downloads/).
+
+Building the code is done by executing:
+
+```
+$ mvn install
+```
+
+from the top level.
+
+## Running
+
+The application consists of three services:
+
+* Tasks
+* Users
+* API
+
+These are all Spring Boot applications.
+
+The Tasks and Users services exist as microservices for managing one facet of data. Each uses a database, and utilise a JMS queue between them as well. For convenience this infrastructure is all embedded in the applications.
+
+This does mean that the startup order is important. The JMS queue exists within the Tasks service and is connected to from the Users service. As such, the Tasks service must be started before the others.
+
+Each service can be started either by executing `mvn spring-boot:run` from within the appropriate directory. Alternatively, as Spring Boot applications, the build will produce an executable JAR file within the `target` directory that can be executed as, for
+example:
+
+```
+$ java -jar ./target/tasks-service-0.0.1-SNAPSHOT.jar
+```
diff --git a/lightrun/api-service/.gitignore b/lightrun/api-service/.gitignore
new file mode 100644
index 0000000000..549e00a2a9
--- /dev/null
+++ b/lightrun/api-service/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/lightrun/api-service/pom.xml b/lightrun/api-service/pom.xml
new file mode 100644
index 0000000000..3423c490f1
--- /dev/null
+++ b/lightrun/api-service/pom.xml
@@ -0,0 +1,45 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.7
+
+
+ com.baeldung
+ api-service
+ 0.0.1-SNAPSHOT
+ api-service
+ Aggregator Service for LightRun Article
+
+ 17
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/ApiServiceApplication.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/ApiServiceApplication.java
new file mode 100644
index 0000000000..a9b29cbd4b
--- /dev/null
+++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/ApiServiceApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.apiservice;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ApiServiceApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ApiServiceApplication.class, args);
+ }
+
+}
diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/RequestIdGenerator.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/RequestIdGenerator.java
new file mode 100644
index 0000000000..f15738c1e6
--- /dev/null
+++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/RequestIdGenerator.java
@@ -0,0 +1,33 @@
+package com.baeldung.apiservice;
+
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+@Component
+public class RequestIdGenerator implements HandlerInterceptor {
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+ String requestId = UUID.randomUUID()
+ .toString();
+
+ MDC.put(RequestIdGenerator.class.getCanonicalName(), requestId);
+ response.addHeader("X-Request-Id", requestId);
+
+ return true;
+ }
+
+ @Override
+ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+ MDC.remove(RequestIdGenerator.class.getCanonicalName());
+ }
+
+ public static String getRequestId() {
+ return MDC.get(RequestIdGenerator.class.getCanonicalName());
+ }
+}
diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/RestTemplateConfig.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/RestTemplateConfig.java
new file mode 100644
index 0000000000..1582ba5953
--- /dev/null
+++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/RestTemplateConfig.java
@@ -0,0 +1,20 @@
+package com.baeldung.apiservice;
+
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+ @Bean
+ public RestTemplate restTemplate(RestTemplateBuilder builder) {
+ return builder.additionalInterceptors((request, body, execution) -> {
+ request.getHeaders()
+ .add("X-Request-Id", RequestIdGenerator.getRequestId());
+
+ return execution.execute(request, body);
+ })
+ .build();
+ }
+}
diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/WebConfig.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/WebConfig.java
new file mode 100644
index 0000000000..9edfcff6f6
--- /dev/null
+++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/WebConfig.java
@@ -0,0 +1,17 @@
+package com.baeldung.apiservice;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+ @Autowired
+ private RequestIdGenerator requestIdGenerator;
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(requestIdGenerator);
+ }
+}
diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/TaskResponse.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/TaskResponse.java
new file mode 100644
index 0000000000..875390fdcd
--- /dev/null
+++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/TaskResponse.java
@@ -0,0 +1,6 @@
+package com.baeldung.apiservice.adapters.http;
+
+import java.time.Instant;
+
+public record TaskResponse(String id, String title, Instant created, UserResponse createdBy, UserResponse assignedTo, String status) {
+}
diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/TasksController.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/TasksController.java
new file mode 100644
index 0000000000..55b449f249
--- /dev/null
+++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/TasksController.java
@@ -0,0 +1,56 @@
+package com.baeldung.apiservice.adapters.http;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.apiservice.adapters.tasks.Task;
+import com.baeldung.apiservice.adapters.tasks.TaskRepository;
+import com.baeldung.apiservice.adapters.users.UserRepository;
+
+@RequestMapping("/")
+@RestController
+public class TasksController {
+ @Autowired
+ private TaskRepository taskRepository;
+ @Autowired
+ private UserRepository userRepository;
+
+ @GetMapping("/{id}")
+ public TaskResponse getTaskById(@PathVariable("id") String id) {
+ Task task = taskRepository.getTaskById(id);
+
+ if (task == null) {
+ throw new UnknownTaskException();
+ }
+
+ return buildResponse(task);
+ }
+
+ private TaskResponse buildResponse(Task task) {
+ return new TaskResponse(task.id(), task.title(), task.created(), getUser(task.createdBy()), getUser(task.assignedTo()), task.status());
+ }
+
+ private UserResponse getUser(String userId) {
+ if (userId == null) {
+ return null;
+ }
+
+ var user = userRepository.getUserById(userId);
+ if (user == null) {
+ return null;
+ }
+
+ return new UserResponse(user.id(), user.name());
+ }
+
+ @ExceptionHandler(UnknownTaskException.class)
+ @ResponseStatus(HttpStatus.NOT_FOUND)
+ public void handleUnknownTask() {
+ }
+}
diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/UnknownTaskException.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/UnknownTaskException.java
new file mode 100644
index 0000000000..1635ca8796
--- /dev/null
+++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/UnknownTaskException.java
@@ -0,0 +1,4 @@
+package com.baeldung.apiservice.adapters.http;
+
+public class UnknownTaskException extends RuntimeException {
+}
diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/UserResponse.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/UserResponse.java
new file mode 100644
index 0000000000..f311b895a8
--- /dev/null
+++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/UserResponse.java
@@ -0,0 +1,4 @@
+package com.baeldung.apiservice.adapters.http;
+
+public record UserResponse(String id, String name) {
+}
diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/tasks/Task.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/tasks/Task.java
new file mode 100644
index 0000000000..188d3e951c
--- /dev/null
+++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/tasks/Task.java
@@ -0,0 +1,6 @@
+package com.baeldung.apiservice.adapters.tasks;
+
+import java.time.Instant;
+
+public record Task(String id, String title, Instant created, String createdBy, String assignedTo, String status) {
+}
diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/tasks/TaskRepository.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/tasks/TaskRepository.java
new file mode 100644
index 0000000000..9260a125af
--- /dev/null
+++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/tasks/TaskRepository.java
@@ -0,0 +1,30 @@
+package com.baeldung.apiservice.adapters.tasks;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Repository;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+@Repository
+public class TaskRepository {
+ @Autowired
+ private RestTemplate restTemplate;
+
+ @Value("${tasks-service.url}")
+ private String tasksService;
+
+ public Task getTaskById(String id) {
+ var uri = UriComponentsBuilder.fromUriString(tasksService)
+ .path(id)
+ .build()
+ .toUri();
+
+ try {
+ return restTemplate.getForObject(uri, Task.class);
+ } catch (HttpClientErrorException.NotFound e) {
+ return null;
+ }
+ }
+}
diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/users/User.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/users/User.java
new file mode 100644
index 0000000000..a3a53c0805
--- /dev/null
+++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/users/User.java
@@ -0,0 +1,4 @@
+package com.baeldung.apiservice.adapters.users;
+
+public record User(String id, String name) {
+}
diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/users/UserRepository.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/users/UserRepository.java
new file mode 100644
index 0000000000..d5625f6efc
--- /dev/null
+++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/users/UserRepository.java
@@ -0,0 +1,30 @@
+package com.baeldung.apiservice.adapters.users;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Repository;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+@Repository
+public class UserRepository {
+ @Autowired
+ private RestTemplate restTemplate;
+
+ @Value("${users-service.url}")
+ private String usersService;
+
+ public User getUserById(String id) {
+ var uri = UriComponentsBuilder.fromUriString(usersService)
+ .path(id)
+ .build()
+ .toUri();
+
+ try {
+ return restTemplate.getForObject(uri, User.class);
+ } catch (HttpClientErrorException.NotFound e) {
+ return null;
+ }
+ }
+}
diff --git a/lightrun/api-service/src/main/resources/application.properties b/lightrun/api-service/src/main/resources/application.properties
new file mode 100644
index 0000000000..f3f227f46f
--- /dev/null
+++ b/lightrun/api-service/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+users-service.url=http://localhost:8081
+tasks-service.url=http://localhost:8082
\ No newline at end of file
diff --git a/lightrun/pom.xml b/lightrun/pom.xml
new file mode 100644
index 0000000000..3ce71069a9
--- /dev/null
+++ b/lightrun/pom.xml
@@ -0,0 +1,17 @@
+
+
+ 4.0.0
+ com.baelduung
+ lightrun
+ 0.0.1-SNAPSHOT
+ pom
+ lightrun
+ Services for LightRun Article
+
+
+ tasks-service
+ users-service
+ api-service
+
+
diff --git a/lightrun/tasks-service/.gitignore b/lightrun/tasks-service/.gitignore
new file mode 100644
index 0000000000..549e00a2a9
--- /dev/null
+++ b/lightrun/tasks-service/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/lightrun/tasks-service/pom.xml b/lightrun/tasks-service/pom.xml
new file mode 100644
index 0000000000..441b4d3713
--- /dev/null
+++ b/lightrun/tasks-service/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.7
+
+
+ com.baeldung
+ tasks-service
+ 0.0.1-SNAPSHOT
+ tasks-service
+ Tasks Service for LightRun Article
+
+ 17
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-artemis
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.flywaydb
+ flyway-core
+
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.apache.activemq
+ artemis-jms-server
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/ArtemisConfig.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/ArtemisConfig.java
new file mode 100644
index 0000000000..56ee3bbc93
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/ArtemisConfig.java
@@ -0,0 +1,23 @@
+package com.baeldung.tasksservice;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.jms.artemis.ArtemisConfigurationCustomizer;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class ArtemisConfig implements ArtemisConfigurationCustomizer {
+ @Value("${spring.artemis.host}")
+ private String hostname;
+
+ @Value("${spring.artemis.port}")
+ private int port;
+
+ @Override
+ public void customize(org.apache.activemq.artemis.core.config.Configuration configuration) {
+ try {
+ configuration.addAcceptorConfiguration("remote", "tcp://" + hostname + ":" + port);
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to configure Artemis listener", e);
+ }
+ }
+}
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/TasksServiceApplication.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/TasksServiceApplication.java
new file mode 100644
index 0000000000..dfd9859674
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/TasksServiceApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.tasksservice;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class TasksServiceApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(TasksServiceApplication.class, args);
+ }
+
+}
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/CreateTaskRequest.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/CreateTaskRequest.java
new file mode 100644
index 0000000000..64acea8b1b
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/CreateTaskRequest.java
@@ -0,0 +1,15 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.tasksservice.adapters.http;
+
+public record CreateTaskRequest(String title, String createdBy) {
+}
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/PatchTaskRequest.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/PatchTaskRequest.java
new file mode 100644
index 0000000000..20974b1c1d
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/PatchTaskRequest.java
@@ -0,0 +1,17 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.tasksservice.adapters.http;
+
+import java.util.Optional;
+
+public record PatchTaskRequest(Optional status, Optional assignedTo) {
+}
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/TaskResponse.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/TaskResponse.java
new file mode 100644
index 0000000000..4e01a649b1
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/TaskResponse.java
@@ -0,0 +1,17 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.tasksservice.adapters.http;
+
+import java.time.Instant;
+
+public record TaskResponse(String id, String title, Instant created, String createdBy, String assignedTo, String status) {
+}
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/TasksController.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/TasksController.java
new file mode 100644
index 0000000000..a4145a2243
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/TasksController.java
@@ -0,0 +1,84 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.tasksservice.adapters.http;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.tasksservice.adapters.repository.TaskRecord;
+import com.baeldung.tasksservice.service.TasksService;
+import com.baeldung.tasksservice.service.UnknownTaskException;
+
+@RestController
+@RequestMapping("/")
+class TasksController {
+ @Autowired
+ private TasksService tasksService;
+
+ @PostMapping
+ @ResponseStatus(HttpStatus.CREATED)
+ public TaskResponse createTask(@RequestBody CreateTaskRequest body) {
+ var task = tasksService.createTask(body.title(), body.createdBy());
+ return buildResponse(task);
+ }
+
+ @GetMapping
+ public List searchTasks(@RequestParam("status") Optional status, @RequestParam("createdBy") Optional createdBy) {
+ var tasks = tasksService.search(status, createdBy);
+
+ return tasks.stream()
+ .map(this::buildResponse)
+ .collect(Collectors.toList());
+ }
+
+ @GetMapping("/{id}")
+ public TaskResponse getTask(@PathVariable("id") String id) {
+ var task = tasksService.getTaskById(id);
+ return buildResponse(task);
+ }
+
+ @DeleteMapping("/{id}")
+ public void deleteTask(@PathVariable("id") String id) {
+ tasksService.deleteTaskById(id);
+ }
+
+ @PatchMapping("/{id}")
+ public TaskResponse patchTask(@PathVariable("id") String id, @RequestBody PatchTaskRequest body) {
+ var task = tasksService.updateTask(id, body.status(), body.assignedTo());
+
+ return buildResponse(task);
+ }
+
+ private TaskResponse buildResponse(final TaskRecord task) {
+ return new TaskResponse(task.getId(), task.getTitle(), task.getCreated(), task.getCreatedBy(), task.getAssignedTo(), task.getStatus());
+ }
+
+ @ExceptionHandler(UnknownTaskException.class)
+ @ResponseStatus(HttpStatus.NOT_FOUND)
+ public void handleUnknownTask() {
+ }
+}
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/http-client.env.json b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/http-client.env.json
new file mode 100644
index 0000000000..f27fc4325b
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/http-client.env.json
@@ -0,0 +1,5 @@
+{
+ "local-tasks": {
+ "host": "localhost:8082"
+ }
+}
\ No newline at end of file
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/tasks.http b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/tasks.http
new file mode 100644
index 0000000000..eb7d578ac9
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/tasks.http
@@ -0,0 +1,35 @@
+GET http://{{host}}/createdemoapplication1 HTTP/1.1
+
+###
+GET http://{{host}}/unknown HTTP/1.1
+
+###
+GET http://{{host}}?status=PENDING
+
+###
+GET http://{{host}}?createdBy=baeldung
+
+###
+GET http://{{host}}?createdBy=baeldung&status=COMPLETE
+
+###
+DELETE http://{{host}}/createdemoapplication1 HTTP/1.1
+
+###
+DELETE http://{{host}}/unknown HTTP/1.1
+
+###
+POST http://{{host}} HTTP/1.1
+Content-Type: application/json
+
+{
+ "title": "My Task",
+ "createdBy": "graham"
+}
+###
+PATCH http://{{host}}/createdemoapplication1 HTTP/1.1
+Content-Type: application/json
+
+{
+ "status": "COMPLETE"
+}
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/jms/JmsConsumer.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/jms/JmsConsumer.java
new file mode 100644
index 0000000000..c380a16acc
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/jms/JmsConsumer.java
@@ -0,0 +1,18 @@
+package com.baeldung.tasksservice.adapters.jms;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.tasksservice.service.DeletedUserService;
+
+@Service
+public class JmsConsumer {
+ @Autowired
+ private DeletedUserService deletedUserService;
+
+ @JmsListener(destination = "deleted_user")
+ public void receive(String user) {
+ deletedUserService.handleDeletedUser(user);
+ }
+}
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/repository/TaskRecord.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/repository/TaskRecord.java
new file mode 100644
index 0000000000..dee3017a59
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/repository/TaskRecord.java
@@ -0,0 +1,80 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.tasksservice.adapters.repository;
+
+import java.time.Instant;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "tasks")
+public class TaskRecord {
+ @Id
+ @Column(name = "task_id")
+ private String id;
+ private String title;
+ @Column(name = "created_at")
+ private Instant created;
+ @Column(name = "created_by")
+ private String createdBy;
+ @Column(name = "assigned_to")
+ private String assignedTo;
+ private String status;
+
+ public TaskRecord(final String id, final String title, final Instant created, final String createdBy, final String assignedTo, final String status) {
+ this.id = id;
+ this.title = title;
+ this.created = created;
+ this.createdBy = createdBy;
+ this.assignedTo = assignedTo;
+ this.status = status;
+ }
+
+ private TaskRecord() {
+ // Needed for JPA
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public Instant getCreated() {
+ return created;
+ }
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public String getAssignedTo() {
+ return assignedTo;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setAssignedTo(final String assignedTo) {
+ this.assignedTo = assignedTo;
+ }
+
+ public void setStatus(final String status) {
+ this.status = status;
+ }
+}
\ No newline at end of file
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/repository/TasksRepository.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/repository/TasksRepository.java
new file mode 100644
index 0000000000..9b6f041fd2
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/repository/TasksRepository.java
@@ -0,0 +1,28 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.tasksservice.adapters.repository;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface TasksRepository extends JpaRepository {
+ List findByStatus(String status);
+
+ List findByCreatedBy(String createdBy);
+
+ List findByStatusAndCreatedBy(String status, String createdBy);
+
+ List findByAssignedTo(String assignedTo);
+}
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/DeletedUserService.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/DeletedUserService.java
new file mode 100644
index 0000000000..fa0c3572fb
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/DeletedUserService.java
@@ -0,0 +1,27 @@
+package com.baeldung.tasksservice.service;
+
+import javax.transaction.Transactional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.tasksservice.adapters.repository.TaskRecord;
+import com.baeldung.tasksservice.adapters.repository.TasksRepository;
+
+@Service
+public class DeletedUserService {
+ @Autowired
+ private TasksRepository tasksRepository;
+
+ @Transactional
+ public void handleDeletedUser(String user) {
+ var ownedByUser = tasksRepository.findByCreatedBy(user);
+ tasksRepository.deleteAll(ownedByUser);
+
+ var assignedToUser = tasksRepository.findByAssignedTo(user);
+ for (TaskRecord record : assignedToUser) {
+ record.setAssignedTo(null);
+ record.setStatus("PENDING");
+ }
+ }
+}
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/TasksService.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/TasksService.java
new file mode 100644
index 0000000000..3539dbbc3c
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/TasksService.java
@@ -0,0 +1,73 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.tasksservice.service;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import javax.transaction.Transactional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.tasksservice.adapters.repository.TaskRecord;
+import com.baeldung.tasksservice.adapters.repository.TasksRepository;
+
+@Service
+public class TasksService {
+ @Autowired
+ private TasksRepository tasksRepository;
+
+ public TaskRecord getTaskById(String id) {
+ return tasksRepository.findById(id)
+ .orElseThrow(() -> new UnknownTaskException(id));
+ }
+
+ @Transactional
+ public void deleteTaskById(String id) {
+ var task = tasksRepository.findById(id)
+ .orElseThrow(() -> new UnknownTaskException(id));
+ tasksRepository.delete(task);
+ }
+
+ public List search(Optional createdBy, Optional status) {
+ if (createdBy.isPresent() && status.isPresent()) {
+ return tasksRepository.findByStatusAndCreatedBy(status.get(), createdBy.get());
+ } else if (createdBy.isPresent()) {
+ return tasksRepository.findByCreatedBy(createdBy.get());
+ } else if (status.isPresent()) {
+ return tasksRepository.findByStatus(status.get());
+ } else {
+ return tasksRepository.findAll();
+ }
+ }
+
+ @Transactional
+ public TaskRecord updateTask(String id, Optional newStatus, Optional newAssignedTo) {
+ var task = tasksRepository.findById(id)
+ .orElseThrow(() -> new UnknownTaskException(id));
+
+ newStatus.ifPresent(task::setStatus);
+ newAssignedTo.ifPresent(task::setAssignedTo);
+
+ return task;
+ }
+
+ public TaskRecord createTask(String title, String createdBy) {
+ var task = new TaskRecord(UUID.randomUUID()
+ .toString(), title, Instant.now(), createdBy, null, "PENDING");
+ tasksRepository.save(task);
+ return task;
+ }
+}
diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/UnknownTaskException.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/UnknownTaskException.java
new file mode 100644
index 0000000000..fd9fce4d16
--- /dev/null
+++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/UnknownTaskException.java
@@ -0,0 +1,24 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.tasksservice.service;
+
+public class UnknownTaskException extends RuntimeException {
+ private final String id;
+
+ public UnknownTaskException(final String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+}
diff --git a/lightrun/tasks-service/src/main/resources/application.properties b/lightrun/tasks-service/src/main/resources/application.properties
new file mode 100644
index 0000000000..88326ed10e
--- /dev/null
+++ b/lightrun/tasks-service/src/main/resources/application.properties
@@ -0,0 +1,9 @@
+server.port=8082
+spring.artemis.mode=EMBEDDED
+spring.artemis.host=localhost
+spring.artemis.port=61616
+spring.artemis.embedded.enabled=true
+spring.jms.template.default-destination=my-queue-1
+logging.level.org.apache.activemq.audit.base=WARN
+logging.level.org.apache.activemq.audit.message=WARN
+
diff --git a/lightrun/tasks-service/src/main/resources/db/migration/V1_0_0__create-tasks-table.sql b/lightrun/tasks-service/src/main/resources/db/migration/V1_0_0__create-tasks-table.sql
new file mode 100644
index 0000000000..f2365c2687
--- /dev/null
+++ b/lightrun/tasks-service/src/main/resources/db/migration/V1_0_0__create-tasks-table.sql
@@ -0,0 +1,13 @@
+CREATE TABLE tasks (
+ task_id VARCHAR(36) PRIMARY KEY,
+ title VARCHAR(100) NOT NULL,
+ created_at DATETIME NOT NULL,
+ created_by VARCHAR(36) NOT NULL,
+ assigned_to VARCHAR(36) NULL,
+ status VARCHAR(20) NOT NULL
+);
+
+INSERT INTO tasks(task_id, title, created_at, created_by, assigned_to, status) VALUES
+ ('createdemoapplication1', 'Create demo applications - Tasks', '2022-05-05 12:34:56', 'baeldung', 'coxg', 'IN_PROGRESS'),
+ ('createdemoapplication2', 'Create demo applications - Users', '2022-05-05 12:34:56', 'baeldung', NULL, 'PENDING'),
+ ('createdemoapplication3', 'Create demo applications - API', '2022-05-05 12:34:56', 'baeldung', NULL, 'PENDING');
\ No newline at end of file
diff --git a/lightrun/users-service/.gitignore b/lightrun/users-service/.gitignore
new file mode 100644
index 0000000000..549e00a2a9
--- /dev/null
+++ b/lightrun/users-service/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/lightrun/users-service/README.md b/lightrun/users-service/README.md
new file mode 100644
index 0000000000..e7faae858f
--- /dev/null
+++ b/lightrun/users-service/README.md
@@ -0,0 +1,36 @@
+# Lightrun Example Application - Tasks Management
+
+This application exists as an example for the Lightrun series of articles.
+
+## Building
+
+This application requires [Apache Maven](https://maven.apache.org/) and [Java 17+](https://www.oracle.com/java/technologies/downloads/). It does use the Maven Wrapper, so it can be built with only Java available on the path.
+
+As such, building the code is done by executing:
+
+```
+$ ./mvnw install
+```
+
+from the top level.
+
+## Running
+
+The application consists of three services:
+
+* Tasks
+* Users
+* API
+
+These are all Spring Boot applications.
+
+The Tasks and Users services exist as microservices for managing one facet of data. Each uses a database, and utilise a JMS queue between them as well. For convenience this infrastructure is all embedded in the applications.
+
+This does mean that the startup order is important. The JMS queue exists within the Tasks service and is connected to from the Users service. As such, the Tasks service must be started before the others.
+
+Each service can be started either by executing `mvn spring-boot:run` from within the appropriate directory. Alternatively, as Spring Boot applications, the build will produce an executable JAR file within the `target` directory that can be executed as, for
+example:
+
+```
+$ java -jar ./target/tasks-service-0.0.1-SNAPSHOT.jar
+```
diff --git a/lightrun/users-service/pom.xml b/lightrun/users-service/pom.xml
new file mode 100644
index 0000000000..63596ed67b
--- /dev/null
+++ b/lightrun/users-service/pom.xml
@@ -0,0 +1,63 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.7
+
+
+ com.baeldung
+ users-service
+ 0.0.1-SNAPSHOT
+ users-service
+ Users Service for LightRun Article
+
+ 17
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-artemis
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.flywaydb
+ flyway-core
+
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/JmsConfig.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/JmsConfig.java
new file mode 100644
index 0000000000..c803c9af13
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/JmsConfig.java
@@ -0,0 +1,29 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.usersservice;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
+import org.springframework.jms.support.converter.MessageConverter;
+import org.springframework.jms.support.converter.MessageType;
+
+@Configuration
+public class JmsConfig {
+ @Bean
+ public MessageConverter jacksonJmsMessageConverter() {
+ MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
+ converter.setTargetType(MessageType.TEXT);
+ converter.setTypeIdPropertyName("_type");
+ return converter;
+ }
+}
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/UsersServiceApplication.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/UsersServiceApplication.java
new file mode 100644
index 0000000000..3910960282
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/UsersServiceApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.usersservice;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class UsersServiceApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(UsersServiceApplication.class, args);
+ }
+
+}
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/CreateUserRequest.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/CreateUserRequest.java
new file mode 100644
index 0000000000..c3dfc8d068
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/CreateUserRequest.java
@@ -0,0 +1,15 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.usersservice.adapters.http;
+
+public record CreateUserRequest(String name) {
+}
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/PatchUserRequest.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/PatchUserRequest.java
new file mode 100644
index 0000000000..acaf7e635f
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/PatchUserRequest.java
@@ -0,0 +1,17 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.usersservice.adapters.http;
+
+import java.util.Optional;
+
+public record PatchUserRequest(Optional name) {
+}
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/UserResponse.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/UserResponse.java
new file mode 100644
index 0000000000..e74ede65d5
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/UserResponse.java
@@ -0,0 +1,15 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.usersservice.adapters.http;
+
+public record UserResponse(String id, String name) {
+}
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/UsersController.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/UsersController.java
new file mode 100644
index 0000000000..795d240fe9
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/UsersController.java
@@ -0,0 +1,70 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.usersservice.adapters.http;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.usersservice.adapters.repository.UserRecord;
+import com.baeldung.usersservice.service.UnknownUserException;
+import com.baeldung.usersservice.service.UsersService;
+
+@RestController
+@RequestMapping("/")
+class UsersController {
+ @Autowired
+ private UsersService usersService;
+
+ @GetMapping("/{id}")
+ public UserResponse getUser(@PathVariable("id") String id) {
+ var user = usersService.getUserById(id);
+ return buildResponse(user);
+ }
+
+ @DeleteMapping("/{id}")
+ public void deleteUser(@PathVariable("id") String id) {
+ usersService.deleteUserById(id);
+ }
+
+ @PostMapping
+ @ResponseStatus(HttpStatus.CREATED)
+ public UserResponse createUser(@RequestBody CreateUserRequest body) {
+ var user = usersService.createUser(body.name());
+ return buildResponse(user);
+ }
+
+ @PatchMapping("/{id}")
+ public UserResponse patchUser(@PathVariable("id") String id, @RequestBody PatchUserRequest body) {
+ var user = usersService.updateUser(id, body.name());
+
+ return buildResponse(user);
+ }
+
+ private UserResponse buildResponse(final UserRecord user) {
+ return new UserResponse(user.getId(), user.getName());
+ }
+
+ @ExceptionHandler(UnknownUserException.class)
+ @ResponseStatus(HttpStatus.NOT_FOUND)
+ public void handleUnknownUser() {
+ }
+}
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/http-client.env.json b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/http-client.env.json
new file mode 100644
index 0000000000..3be2f710ff
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/http-client.env.json
@@ -0,0 +1,5 @@
+{
+ "local-users": {
+ "host": "localhost:8081"
+ }
+}
\ No newline at end of file
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/users.http b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/users.http
new file mode 100644
index 0000000000..904c5f1cf1
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/users.http
@@ -0,0 +1,25 @@
+GET http://{{host}}/baeldung HTTP/1.1
+
+###
+GET http://{{host}}/unknown HTTP/1.1
+
+###
+DELETE http://{{host}}/baeldung HTTP/1.1
+
+###
+DELETE http://{{host}}/unknown HTTP/1.1
+
+###
+POST http://{{host}} HTTP/1.1
+Content-Type: application/json
+
+{
+ "name": "Testing"
+}
+###
+PATCH http://{{host}}/coxg HTTP/1.1
+Content-Type: application/json
+
+{
+ "name": "Test Name"
+}
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/jms/JmsSender.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/jms/JmsSender.java
new file mode 100644
index 0000000000..f5d5d7900f
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/jms/JmsSender.java
@@ -0,0 +1,26 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.usersservice.adapters.jms;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jms.core.JmsTemplate;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JmsSender {
+ @Autowired
+ private JmsTemplate jmsTemplate;
+
+ public void sendDeleteUserMessage(String userId) {
+ jmsTemplate.convertAndSend("deleted_user", userId);
+ }
+}
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/repository/UserRecord.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/repository/UserRecord.java
new file mode 100644
index 0000000000..fe87ac3ffe
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/repository/UserRecord.java
@@ -0,0 +1,47 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.usersservice.adapters.repository;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "users")
+public class UserRecord {
+ @Id
+ @Column(name = "user_id")
+ private String id;
+ private String name;
+
+ public UserRecord(final String id, final String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ private UserRecord() {
+ // Needed for JPA
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+}
\ No newline at end of file
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/repository/UsersRepository.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/repository/UsersRepository.java
new file mode 100644
index 0000000000..ed193a4955
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/repository/UsersRepository.java
@@ -0,0 +1,19 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.usersservice.adapters.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface UsersRepository extends JpaRepository {
+}
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/service/UnknownUserException.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/service/UnknownUserException.java
new file mode 100644
index 0000000000..d0ca79850c
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/service/UnknownUserException.java
@@ -0,0 +1,24 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.usersservice.service;
+
+public class UnknownUserException extends RuntimeException {
+ private final String id;
+
+ public UnknownUserException(final String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+}
diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/service/UsersService.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/service/UsersService.java
new file mode 100644
index 0000000000..5115a5a77b
--- /dev/null
+++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/service/UsersService.java
@@ -0,0 +1,64 @@
+/****************************************************************************************************************
+ *
+ * Copyright (c) 2022 OCLC, Inc. All Rights Reserved.
+ *
+ * OCLC proprietary information: the enclosed materials contain
+ * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in
+ * any part to any third party or used by any person for any purpose, without written
+ * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice.
+ *
+ ******************************************************************************************************************/
+
+package com.baeldung.usersservice.service;
+
+import java.util.Optional;
+import java.util.UUID;
+
+import javax.transaction.Transactional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.usersservice.adapters.jms.JmsSender;
+import com.baeldung.usersservice.adapters.repository.UserRecord;
+import com.baeldung.usersservice.adapters.repository.UsersRepository;
+
+@Service
+public class UsersService {
+ @Autowired
+ private UsersRepository usersRepository;
+
+ @Autowired
+ private JmsSender jmsSender;
+
+ public UserRecord getUserById(String id) {
+ return usersRepository.findById(id)
+ .orElseThrow(() -> new UnknownUserException(id));
+ }
+
+ @Transactional
+ public void deleteUserById(String id) {
+ var user = usersRepository.findById(id)
+ .orElseThrow(() -> new UnknownUserException(id));
+ usersRepository.delete(user);
+
+ jmsSender.sendDeleteUserMessage(id);
+ }
+
+ @Transactional
+ public UserRecord updateUser(String id, Optional newName) {
+ var user = usersRepository.findById(id)
+ .orElseThrow(() -> new UnknownUserException(id));
+
+ newName.ifPresent(user::setName);
+
+ return user;
+ }
+
+ public UserRecord createUser(String name) {
+ var user = new UserRecord(UUID.randomUUID()
+ .toString(), name);
+ usersRepository.save(user);
+ return user;
+ }
+}
diff --git a/lightrun/users-service/src/main/resources/application.properties b/lightrun/users-service/src/main/resources/application.properties
new file mode 100644
index 0000000000..616131c42e
--- /dev/null
+++ b/lightrun/users-service/src/main/resources/application.properties
@@ -0,0 +1,7 @@
+server.port=8081
+spring.artemis.host=localhost
+spring.artemis.port=61616
+spring.jms.template.default-destination=my-queue-1
+logging.level.org.apache.activemq.audit.base=WARN
+logging.level.org.apache.activemq.audit.message=WARN
+
diff --git a/lightrun/users-service/src/main/resources/db/migration/V1_0_0__create-users-table.sql b/lightrun/users-service/src/main/resources/db/migration/V1_0_0__create-users-table.sql
new file mode 100644
index 0000000000..d1ec9387e6
--- /dev/null
+++ b/lightrun/users-service/src/main/resources/db/migration/V1_0_0__create-users-table.sql
@@ -0,0 +1,8 @@
+CREATE TABLE users (
+ user_id VARCHAR(36) PRIMARY KEY,
+ name VARCHAR(100) NOT NULL
+);
+
+INSERT INTO users(user_id, name) VALUES
+ ('baeldung', 'Baeldung'),
+ ('coxg', 'Graham');
\ No newline at end of file
diff --git a/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerIntegrationTest.java b/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerIntegrationTest.java
index 80fa0edd96..d3b73637a4 100644
--- a/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerIntegrationTest.java
+++ b/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerIntegrationTest.java
@@ -5,7 +5,6 @@ import com.google.common.flogger.LoggerConfig;
import com.google.common.flogger.StackSize;
import org.junit.Test;
-import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.stream.IntStream;
@@ -25,13 +24,6 @@ public class FloggerIntegrationTest {
});
}
- @Test
- public void givenATimeInterval_shouldLogAfterEveryTimeInterval() {
- IntStream.range(0, 1_000_0000).forEach(value -> {
- logger.atInfo().atMostEvery(10, TimeUnit.SECONDS).log("This log shows [every 10 seconds] => %d", value);
- });
- }
-
@Test
public void givenAnObject_shouldLogTheObject() {
User user = new User();
diff --git a/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerManualTest.java b/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerManualTest.java
new file mode 100644
index 0000000000..a3444e596e
--- /dev/null
+++ b/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerManualTest.java
@@ -0,0 +1,25 @@
+package com.baeldung.flogger;
+
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+
+import org.junit.Test;
+
+import com.google.common.flogger.FluentLogger;
+
+public class FloggerManualTest {
+ static {
+// System.setProperty("flogger.backend_factory", "com.google.common.flogger.backend.log4j.Log4jBackendFactory#getInstance");
+ System.setProperty("flogger.backend_factory",
+ "com.google.common.flogger.backend.slf4j.Slf4jBackendFactory#getInstance");
+ }
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
+ @Test
+ public void givenATimeInterval_shouldLogAfterEveryTimeInterval() {
+ IntStream.range(0, 1_000_0000).forEach(value -> {
+ logger.atInfo().atMostEvery(10, TimeUnit.SECONDS).log("This log shows [every 10 seconds] => %d", value);
+ });
+ }
+
+}
diff --git a/maven-modules/host-maven-repo-example/pom.xml b/maven-modules/host-maven-repo-example/pom.xml
index bd58dddeda..20528853cd 100644
--- a/maven-modules/host-maven-repo-example/pom.xml
+++ b/maven-modules/host-maven-repo-example/pom.xml
@@ -6,11 +6,11 @@
com.baeldung.maven.plugin
host-maven-repo-example
1.0-SNAPSHOT
- https://github.com/sgrverma23/host-maven-repo-example.git
+ https://github.com/${repository-owner}/${repository-name}.git
- https://github.com/sgrverma23/host-maven-repo-example.git
- scm:git:git@github.com:sgrverma23/host-maven-repo-example.git
- scm:git:git@github.com:sgrverma23/host-maven-repo-example.git
+ https://github.com/${repository-owner}/${repository-name}.git
+ scm:git:git@github.com:${repository-owner}/${repository-name}.git
+ scm:git:git@github.com:${repository-owner}/${repository-name}.git
@@ -43,13 +43,13 @@
Maven artifacts for ${project.version}
true
${project.build.directory}
- refs/heads/main
+ refs/heads/${branch-name}
**/*
true
- host-maven-repo-example
- sgrverma23
+ ${repository-name}
+ ${repository-owner}
github
@@ -89,7 +89,7 @@
PROJECT-REPO-URL
- https://github.com/sgrverma23/host-maven-repo-example/main
+ https://github.com/${repository-owner}/${repository-name}/${branch-name}
true
always
@@ -98,9 +98,13 @@
+
+ Put-repo-owner
+ Put-repository-name
+ Put-branch-name
github
8
8
-
\ No newline at end of file
+
diff --git a/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/empty-phase/pom.xml b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/empty-phase/pom.xml
index 28ea8b6359..2dfa34568e 100644
--- a/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/empty-phase/pom.xml
+++ b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/empty-phase/pom.xml
@@ -21,7 +21,7 @@
enforce-file-exists
-
+
diff --git a/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/pom.xml b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/pom.xml
index 2a2e5b00ea..4d16a94838 100644
--- a/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/pom.xml
+++ b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/pom.xml
@@ -13,7 +13,14 @@
maven-parent-pom-resolution
1.0.0-SNAPSHOT
-
+
+
+ plugin-enabled
+ skip-parameter
+ phase-none
+ empty-phase
+
+
@@ -27,26 +34,19 @@
enforce
-
-
-
- ${project.basedir}/src/file-that-must-exist.txt
-
-
-
+
+
+
+ ${project.basedir}/src/file-that-must-exist.txt
+
+
+
-
-
- plugin-enabled
- skip-parameter
- phase-none
- empty-phase
-
UTF-8
diff --git a/maven-modules/maven-simple/parent-project/core/pom.xml b/maven-modules/maven-simple/parent-project/core/pom.xml
index 6553889c24..2e3a6eee7d 100644
--- a/maven-modules/maven-simple/parent-project/core/pom.xml
+++ b/maven-modules/maven-simple/parent-project/core/pom.xml
@@ -23,4 +23,5 @@
4.3.30.RELEASE
+
\ No newline at end of file
diff --git a/maven-modules/maven-simple/parent-project/pom.xml b/maven-modules/maven-simple/parent-project/pom.xml
index bde903b1b5..2f28eff49f 100644
--- a/maven-modules/maven-simple/parent-project/pom.xml
+++ b/maven-modules/maven-simple/parent-project/pom.xml
@@ -33,4 +33,5 @@
5.3.16
+
\ No newline at end of file
diff --git a/maven-modules/maven-simple/parent-project/webapp/pom.xml b/maven-modules/maven-simple/parent-project/webapp/pom.xml
index f6cee60cbf..ce964c222f 100644
--- a/maven-modules/maven-simple/parent-project/webapp/pom.xml
+++ b/maven-modules/maven-simple/parent-project/webapp/pom.xml
@@ -5,7 +5,6 @@
4.0.0
webapp
webapp
-
war
@@ -30,4 +29,5 @@
3.3.2
+
\ No newline at end of file
diff --git a/maven-modules/pom.xml b/maven-modules/pom.xml
index a9fefbbf5d..253f5d9fa0 100644
--- a/maven-modules/pom.xml
+++ b/maven-modules/pom.xml
@@ -15,8 +15,8 @@
- animal-sniffer-mvn-plugin
- maven-archetype
+ animal-sniffer-mvn-plugin
+ maven-archetype
maven-copy-files
maven-custom-plugin
diff --git a/muleesb/pom.xml b/muleesb/pom.xml
index d78cebada2..a2204c15b7 100644
--- a/muleesb/pom.xml
+++ b/muleesb/pom.xml
@@ -1,6 +1,7 @@
-
+
4.0.0
com.mycompany
muleesb
@@ -218,4 +219,4 @@
2.2.1
-
+
\ No newline at end of file
diff --git a/persistence-modules/core-java-persistence-2/example.csv b/persistence-modules/core-java-persistence-2/example.csv
new file mode 100644
index 0000000000..d7715864d1
--- /dev/null
+++ b/persistence-modules/core-java-persistence-2/example.csv
@@ -0,0 +1,4 @@
+Username,Id,First name,Last name
+doe1,7173,John,Doe
+smith3,3722,Dana,Smith
+john22,5490,John,Wang
\ No newline at end of file
diff --git a/persistence-modules/core-java-persistence-2/pom.xml b/persistence-modules/core-java-persistence-2/pom.xml
index 780c1fcfca..c7547e1c46 100644
--- a/persistence-modules/core-java-persistence-2/pom.xml
+++ b/persistence-modules/core-java-persistence-2/pom.xml
@@ -1,7 +1,5 @@
-
+
4.0.0
com.baeldung.core-java-persistence-2
core-java-persistence-2
@@ -41,6 +39,20 @@
mssql-jdbc
${mssql.driver.version}
+
+
+
+ org.jooq
+ jooq
+ 3.11.11
+
+
+
+ org.json
+ json
+ 20220320
+
+
diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultset2json/ResultSet2JSON.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultset2json/ResultSet2JSON.java
new file mode 100755
index 0000000000..bbe3ccf9a0
--- /dev/null
+++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultset2json/ResultSet2JSON.java
@@ -0,0 +1,137 @@
+package com.baeldung.resultset2json;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.jooq.Record;
+import org.jooq.RecordMapper;
+import org.jooq.impl.DSL;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONArray;
+
+public class ResultSet2JSON {
+
+ public static void main(String... args) throws ClassNotFoundException, SQLException {
+
+ ResultSet2JSON testClass = new ResultSet2JSON();
+ testClass.convertWithoutJOOQ();
+ }
+
+ public void convertWithoutJOOQ() throws ClassNotFoundException, SQLException {
+ Class.forName("org.h2.Driver");
+ Connection dbConnection = DriverManager.getConnection("jdbc:h2:mem:rs2jdbc", "user", "password");
+
+ // Create a table
+ Statement stmt = dbConnection.createStatement();
+ stmt.execute("CREATE TABLE words AS SELECT * FROM CSVREAD('./example.csv')");
+ ResultSet resultSet = stmt.executeQuery("SELECT * FROM words");
+
+ JSONArray result1 = resultSet2JdbcWithoutJOOQ(resultSet);
+ System.out.println(result1);
+
+ resultSet.close();
+ }
+
+ public void convertUsingJOOQDefaultApproach() throws ClassNotFoundException, SQLException {
+ Class.forName("org.h2.Driver");
+ Connection dbConnection = DriverManager.getConnection("jdbc:h2:mem:rs2jdbc", "user", "password");
+ // Create a table
+ Statement stmt = dbConnection.createStatement();
+ stmt.execute("CREATE TABLE words AS SELECT * FROM CSVREAD('./example.csv')");
+ ResultSet resultSet = stmt.executeQuery("SELECT * FROM words");
+
+ JSONObject result1 = resultSet2JdbcUsingJOOQDefaultApproach(resultSet, dbConnection);
+ System.out.println(result1);
+
+ resultSet.close();
+ }
+
+ public void convertUsingCustomisedJOOQ() throws ClassNotFoundException, SQLException {
+ Class.forName("org.h2.Driver");
+ Connection dbConnection = DriverManager.getConnection("jdbc:h2:mem:rs2jdbc", "user", "password");
+ // Create a table
+ Statement stmt = dbConnection.createStatement();
+ stmt.execute("CREATE TABLE words AS SELECT * FROM CSVREAD('./example.csv')");
+ ResultSet resultSet = stmt.executeQuery("SELECT * FROM words");
+
+ JSONArray result1 = resultSet2JdbcUsingCustomisedJOOQ(resultSet, dbConnection);
+ System.out.println(result1);
+
+ resultSet.close();
+ }
+
+ public static JSONArray resultSet2JdbcWithoutJOOQ(ResultSet resultSet) throws SQLException {
+ ResultSetMetaData md = resultSet.getMetaData();
+ int numCols = md.getColumnCount();
+ List colNames = IntStream.range(0, numCols)
+ .mapToObj(i -> {
+ try {
+ return md.getColumnName(i + 1);
+ } catch (SQLException e) {
+
+ e.printStackTrace();
+ return "?";
+ }
+ })
+ .collect(Collectors.toList());
+
+ JSONArray result = new JSONArray();
+ while (resultSet.next()) {
+ JSONObject row = new JSONObject();
+ colNames.forEach(cn -> {
+ try {
+ row.put(cn, resultSet.getObject(cn));
+ } catch (JSONException | SQLException e) {
+
+ e.printStackTrace();
+ }
+ });
+ result.put(row);
+ }
+ return result;
+ }
+
+ public static JSONObject resultSet2JdbcUsingJOOQDefaultApproach(ResultSet resultSet, Connection dbConnection) throws SQLException {
+ JSONObject result = new JSONObject(DSL.using(dbConnection)
+ .fetch(resultSet)
+ .formatJSON());
+ return result;
+ }
+
+ public static JSONArray resultSet2JdbcUsingCustomisedJOOQ(ResultSet resultSet, Connection dbConnection) throws SQLException {
+ ResultSetMetaData md = resultSet.getMetaData();
+ int numCols = md.getColumnCount();
+ List colNames = IntStream.range(0, numCols)
+ .mapToObj(i -> {
+ try {
+ return md.getColumnName(i + 1);
+ } catch (SQLException e) {
+
+ e.printStackTrace();
+ return "?";
+ }
+ })
+ .collect(Collectors.toList());
+
+ List json = DSL.using(dbConnection)
+ .fetch(resultSet)
+ .map(new RecordMapper() {
+
+ @Override
+ public JSONObject map(Record r) {
+ JSONObject obj = new JSONObject();
+ colNames.forEach(cn -> obj.put(cn, r.get(cn)));
+ return obj;
+ }
+ });
+ return new JSONArray(json);
+ }
+}
diff --git a/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultset2json/ResultSet2JSONUnitTest.java b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultset2json/ResultSet2JSONUnitTest.java
new file mode 100644
index 0000000000..f3dd8350fa
--- /dev/null
+++ b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultset2json/ResultSet2JSONUnitTest.java
@@ -0,0 +1,75 @@
+package com.baeldung.resultset2json;
+
+import static com.baeldung.resultset2json.ResultSet2JSON.resultSet2JdbcWithoutJOOQ;
+import static com.baeldung.resultset2json.ResultSet2JSON.resultSet2JdbcUsingJOOQDefaultApproach;
+import static com.baeldung.resultset2json.ResultSet2JSON.resultSet2JdbcUsingCustomisedJOOQ;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class ResultSet2JSONUnitTest {
+ JSONObject object = new JSONObject(
+ "{\"records\":[[\"doe1\",\"7173\",\"John\",\"Doe\"],[\"smith3\",\"3722\",\"Dana\",\"Smith\"],[\"john22\",\"5490\",\"John\",\"Wang\"]],\"fields\":[{\"schema\":\"PUBLIC\",\"name\":\"USERNAME\",\"type\":\"VARCHAR\",\"table\":\"WORDS\"},{\"schema\":\"PUBLIC\",\"name\":\"ID\",\"type\":\"VARCHAR\",\"table\":\"WORDS\"},{\"schema\":\"PUBLIC\",\"name\":\"First name\",\"type\":\"VARCHAR\",\"table\":\"WORDS\"},{\"schema\":\"PUBLIC\",\"name\":\"Last name\",\"type\":\"VARCHAR\",\"table\":\"WORDS\"}]}");
+
+ JSONArray array = new JSONArray(
+ "[{\"USERNAME\":\"doe1\",\"First name\":\"John\",\"ID\":\"7173\",\"Last name\":\"Doe\"},{\"USERNAME\":\"smith3\",\"First name\":\"Dana\",\"ID\":\"3722\",\"Last name\":\"Smith\"},{\"USERNAME\":\"john22\",\"First name\":\"John\",\"ID\":\"5490\",\"Last name\":\"Wang\"}]");
+
+ @Test
+ void whenResultSetConvertedWithoutJOOQ_shouldMatchJSON() throws SQLException, ClassNotFoundException {
+ Class.forName("org.h2.Driver");
+ Connection dbConnection = DriverManager.getConnection("jdbc:h2:mem:rs2jdbc1", "user", "password");
+
+ // Create a table
+ Statement stmt = dbConnection.createStatement();
+ stmt.execute("CREATE TABLE words AS SELECT * FROM CSVREAD('./example.csv')");
+ ResultSet resultSet = stmt.executeQuery("SELECT * FROM words");
+
+ JSONArray result1 = resultSet2JdbcWithoutJOOQ(resultSet);
+
+ resultSet.close();
+
+ assertTrue(array.similar(result1));
+ }
+
+ @Test
+ void whenResultSetConvertedUsingJOOQDefaultApproach_shouldMatchJSON() throws SQLException, ClassNotFoundException {
+ Class.forName("org.h2.Driver");
+ Connection dbConnection = DriverManager.getConnection("jdbc:h2:mem:rs2jdbc2", "user", "password");
+ // Create a table
+ Statement stmt = dbConnection.createStatement();
+ stmt.execute("CREATE TABLE words AS SELECT * FROM CSVREAD('./example.csv')");
+ ResultSet resultSet = stmt.executeQuery("SELECT * FROM words");
+
+ JSONObject result2 = resultSet2JdbcUsingJOOQDefaultApproach(resultSet, dbConnection);
+
+ resultSet.close();
+
+ assertTrue(object.similar(result2));
+ }
+
+ @Test
+ void whenResultSetConvertedUsingCustomisedJOOQ_shouldMatchJSON() throws SQLException, ClassNotFoundException {
+ Class.forName("org.h2.Driver");
+ Connection dbConnection = DriverManager.getConnection("jdbc:h2:mem:rs2jdbc3", "user", "password");
+ // Create a table
+ Statement stmt = dbConnection.createStatement();
+ stmt.execute("CREATE TABLE words AS SELECT * FROM CSVREAD('./example.csv')");
+ ResultSet resultSet = stmt.executeQuery("SELECT * FROM words");
+
+ JSONArray result3 = resultSet2JdbcUsingCustomisedJOOQ(resultSet, dbConnection);
+
+ resultSet.close();
+
+ assertTrue(array.similar(result3));
+ }
+
+}
diff --git a/persistence-modules/hibernate-annotations/pom.xml b/persistence-modules/hibernate-annotations/pom.xml
index dc5f245f22..e984078f9a 100644
--- a/persistence-modules/hibernate-annotations/pom.xml
+++ b/persistence-modules/hibernate-annotations/pom.xml
@@ -16,7 +16,7 @@
-
+
org.springframework
spring-context
@@ -32,7 +32,7 @@
hibernate-core
${hibernate-core.version}
-
+
org.hsqldb
hsqldb
${hsqldb.version}
diff --git a/persistence-modules/hibernate-queries/README.md b/persistence-modules/hibernate-queries/README.md
index ac52e73abf..f5cba1aa6f 100644
--- a/persistence-modules/hibernate-queries/README.md
+++ b/persistence-modules/hibernate-queries/README.md
@@ -11,3 +11,4 @@ This module contains articles about use of Queries in Hibernate.
- [Hibernate Query Plan Cache](https://www.baeldung.com/hibernate-query-plan-cache)
- [Hibernate’s addScalar() Method](https://www.baeldung.com/hibernate-addscalar)
- [Distinct Queries in HQL](https://www.baeldung.com/java-hql-distinct)
+- [JPA and Hibernate – Criteria vs. JPQL vs. HQL Query](https://www.baeldung.com/jpql-hql-criteria-query)
diff --git a/persistence-modules/hibernate-queries/pom.xml b/persistence-modules/hibernate-queries/pom.xml
index 4f5de5c06e..ff5a9fe221 100644
--- a/persistence-modules/hibernate-queries/pom.xml
+++ b/persistence-modules/hibernate-queries/pom.xml
@@ -14,7 +14,7 @@
-
+
org.springframework
spring-context
@@ -30,8 +30,7 @@
tomcat-dbcp
${tomcat-dbcp.version}
-
-
+
com.google.guava
@@ -45,7 +44,6 @@
${org.springframework.version}
test
-
org.hibernate
hibernate-core
@@ -81,8 +79,7 @@
jmh-generator-annprocess
${jmh-generator.version}
-
-
+
5.0.2.RELEASE
diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/model/Employee.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/model/Employee.java
index 994d3f3800..8771e02e0b 100644
--- a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/model/Employee.java
+++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/model/Employee.java
@@ -3,74 +3,81 @@ package com.baeldung.hibernate.criteria.model;
import java.io.Serializable;
import javax.persistence.Entity;
-@org.hibernate.annotations.NamedQueries({ @org.hibernate.annotations.NamedQuery(name = "Employee_findByEmployeeId", query = "from Employee where id = :employeeId"),
- @org.hibernate.annotations.NamedQuery(name = "Employee_findAllByEmployeeSalary", query = "from Employee where salary = :employeeSalary")})
-@org.hibernate.annotations.NamedNativeQueries({ @org.hibernate.annotations.NamedNativeQuery(name = "Employee_FindByEmployeeId", query = "select * from employee emp where employeeId=:employeeId", resultClass = Employee.class)})
+@org.hibernate.annotations.NamedQueries({
+ @org.hibernate.annotations.NamedQuery(name = "Employee_findByEmployeeId", query = "from Employee where id = :employeeId"),
+ @org.hibernate.annotations.NamedQuery(name = "Employee_findAllByEmployeeSalary", query = "from Employee where salary = :employeeSalary")})
+@org.hibernate.annotations.NamedNativeQueries({
+ @org.hibernate.annotations.NamedNativeQuery(name = "Employee_FindByEmployeeId", query = "select * from employee emp where employeeId=:employeeId", resultClass = Employee.class)})
@Entity
public class Employee implements Serializable {
- private static final long serialVersionUID = 1L;
- private Integer id;
- private String name;
- private Long salary;
+ private static final long serialVersionUID = 1L;
+ private Integer id;
+ private String name;
+ private Long salary;
- // constructors
- public Employee() {
- }
+ // constructors
+ public Employee() {
+ }
- public Employee(final Integer id, final String name, final Long salary) {
- super();
- this.id = id;
- this.name = name;
- this.salary = salary;
- }
+ public Employee(final Integer id, final String name, final Long salary) {
+ super();
+ this.id = id;
+ this.name = name;
+ this.salary = salary;
+ }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((id == null) ? 0 : id.hashCode());
- return result;
- }
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ return result;
+ }
- @Override
- public boolean equals(final Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final Employee other = (Employee) obj;
- if (id == null) {
- if (other.id != null)
- return false;
- } else if (!id.equals(other.id))
- return false;
- return true;
- }
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Employee other = (Employee) obj;
+ if (id == null) {
+ if (other.id != null) {
+ return false;
+ }
+ } else if (!id.equals(other.id)) {
+ return false;
+ }
+ return true;
+ }
- public Integer getId() {
- return id;
- }
+ public Integer getId() {
+ return id;
+ }
- public void setId(Integer id) {
- this.id = id;
- }
+ public void setId(Integer id) {
+ this.id = id;
+ }
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
- public Long getSalary() {
- return salary;
- }
+ public Long getSalary() {
+ return salary;
+ }
- public void setSalary(Long salary) {
- this.salary = salary;
- }
+ public void setSalary(Long salary) {
+ this.salary = salary;
+ }
}
diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/EmployeeCriteriaQueries.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/EmployeeCriteriaQueries.java
index 04e27d2ec1..f8c525611b 100644
--- a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/EmployeeCriteriaQueries.java
+++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/EmployeeCriteriaQueries.java
@@ -11,35 +11,34 @@ import org.hibernate.query.Query;
public class EmployeeCriteriaQueries {
- public List getAllEmployees() {
- final Session session = HibernateUtil.getHibernateSession();
- final CriteriaBuilder cb = session.getCriteriaBuilder();
- final CriteriaQuery cr = cb.createQuery(Employee.class);
- final Root root = cr.from(Employee.class);
- cr.select(root);
- Query query = session.createQuery(cr);
- List results = query.getResultList();
- session.close();
- return results;
- }
-
- // To get items having salary more than 50000
- public String[] greaterThanCriteria() {
- final Session session = HibernateUtil.getHibernateSession();
- final CriteriaBuilder cb = session.getCriteriaBuilder();
- final CriteriaQuery cr = cb.createQuery(Employee.class);
- final Root root = cr.from(Employee.class);
- cr.select(root)
- .where(cb.gt(root.get("salary"), 50000));
- Query query = session.createQuery(cr);
- final List greaterThanEmployeeList = query.getResultList();
- final String employeeWithGreaterSalary[] = new String[greaterThanEmployeeList.size()];
- for (int i = 0; i < greaterThanEmployeeList.size(); i++) {
- employeeWithGreaterSalary[i] = greaterThanEmployeeList.get(i)
- .getName();
+ public List getAllEmployees() {
+ final Session session = HibernateUtil.getHibernateSession();
+ final CriteriaBuilder cb = session.getCriteriaBuilder();
+ final CriteriaQuery cr = cb.createQuery(Employee.class);
+ final Root root = cr.from(Employee.class);
+ cr.select(root);
+ Query query = session.createQuery(cr);
+ List results = query.getResultList();
+ session.close();
+ return results;
}
- session.close();
- return employeeWithGreaterSalary;
- }
+ // To get items having salary more than 50000
+ public String[] greaterThanCriteria() {
+ final Session session = HibernateUtil.getHibernateSession();
+ final CriteriaBuilder cb = session.getCriteriaBuilder();
+ final CriteriaQuery cr = cb.createQuery(Employee.class);
+ final Root root = cr.from(Employee.class);
+ cr.select(root)
+ .where(cb.gt(root.get("salary"), 50000));
+ Query query = session.createQuery(cr);
+ final List greaterThanEmployeeList = query.getResultList();
+ final String employeeWithGreaterSalary[] = new String[greaterThanEmployeeList.size()];
+ for (int i = 0; i < greaterThanEmployeeList.size(); i++) {
+ employeeWithGreaterSalary[i] = greaterThanEmployeeList.get(i)
+ .getName();
+ }
+ session.close();
+ return employeeWithGreaterSalary;
+ }
}
diff --git a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/EmployeeCriteriaIntegrationTest.java b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/EmployeeCriteriaIntegrationTest.java
index b2ad4240bf..4553bf398c 100644
--- a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/EmployeeCriteriaIntegrationTest.java
+++ b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/EmployeeCriteriaIntegrationTest.java
@@ -11,26 +11,25 @@ import org.junit.Test;
public class EmployeeCriteriaIntegrationTest {
- final private EmployeeCriteriaQueries employeeCriteriaQueries = new EmployeeCriteriaQueries();
+ final private EmployeeCriteriaQueries employeeCriteriaQueries = new EmployeeCriteriaQueries();
- @Test
- public void testGreaterThanCriteriaQuery() {
- final Session session = HibernateUtil.getHibernateSession();
- final List expectedGreaterThanList = session.createQuery("From Employee where salary>50000").list();
- final String expectedGreaterThanEmployees[] = new String[expectedGreaterThanList.size()];
- for (int i = 0; i < expectedGreaterThanList.size(); i++) {
- expectedGreaterThanEmployees[i] = expectedGreaterThanList.get(i).getName();
+ @Test
+ public void testGreaterThanCriteriaQuery() {
+ final Session session = HibernateUtil.getHibernateSession();
+ final List expectedGreaterThanList = session.createQuery("From Employee where salary>50000").list();
+ final String expectedGreaterThanEmployees[] = new String[expectedGreaterThanList.size()];
+ for (int i = 0; i < expectedGreaterThanList.size(); i++) {
+ expectedGreaterThanEmployees[i] = expectedGreaterThanList.get(i).getName();
+ }
+ session.close();
+ assertArrayEquals(expectedGreaterThanEmployees, employeeCriteriaQueries.greaterThanCriteria());
}
- session.close();
- assertArrayEquals(expectedGreaterThanEmployees, employeeCriteriaQueries.greaterThanCriteria());
- }
-
- @Test
- public void testGetAllEmployeesQuery() {
- final Session session = HibernateUtil.getHibernateSession();
- final List expectedSortCritEmployeeList = session.createQuery("From Employee").list();
- session.close();
- assertArrayEquals(expectedSortCritEmployeeList.toArray(), employeeCriteriaQueries.getAllEmployees().toArray());
- }
+ @Test
+ public void testGetAllEmployeesQuery() {
+ final Session session = HibernateUtil.getHibernateSession();
+ final List expectedSortCritEmployeeList = session.createQuery("From Employee").list();
+ session.close();
+ assertArrayEquals(expectedSortCritEmployeeList.toArray(), employeeCriteriaQueries.getAllEmployees().toArray());
+ }
}
diff --git a/persistence-modules/hibernate-queries/src/test/resources/com/baeldung/hibernate/criteria/model/Employee.hbm.xml b/persistence-modules/hibernate-queries/src/test/resources/com/baeldung/hibernate/criteria/model/Employee.hbm.xml
index 90e1c2fefd..0cc1c54680 100644
--- a/persistence-modules/hibernate-queries/src/test/resources/com/baeldung/hibernate/criteria/model/Employee.hbm.xml
+++ b/persistence-modules/hibernate-queries/src/test/resources/com/baeldung/hibernate/criteria/model/Employee.hbm.xml
@@ -1,19 +1,19 @@
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/java-mongodb-2/pom.xml b/persistence-modules/java-mongodb-2/pom.xml
index ffc8da0b64..9475a86bee 100644
--- a/persistence-modules/java-mongodb-2/pom.xml
+++ b/persistence-modules/java-mongodb-2/pom.xml
@@ -50,4 +50,4 @@
1.5.3
-
+
\ No newline at end of file
diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml
index 3f4e906348..7be71ad215 100644
--- a/persistence-modules/pom.xml
+++ b/persistence-modules/pom.xml
@@ -60,6 +60,7 @@
spring-boot-persistence
spring-boot-persistence-h2
spring-boot-persistence-mongodb
+ spring-boot-persistence-mongodb-2
spring-data-arangodb
spring-data-cassandra
spring-data-cassandra-test
@@ -108,4 +109,4 @@
42.2.20
-
+
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-mysql/pom.xml b/persistence-modules/spring-boot-mysql/pom.xml
index ed3f7d9279..239378c7b1 100644
--- a/persistence-modules/spring-boot-mysql/pom.xml
+++ b/persistence-modules/spring-boot-mysql/pom.xml
@@ -39,7 +39,7 @@
- 8.0.12
+ 8.0.23
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-mysql/src/main/resources/application.yml b/persistence-modules/spring-boot-mysql/src/main/resources/application.yml
index 5404555d49..f660ab4759 100644
--- a/persistence-modules/spring-boot-mysql/src/main/resources/application.yml
+++ b/persistence-modules/spring-boot-mysql/src/main/resources/application.yml
@@ -1,6 +1,6 @@
spring:
datasource:
- url: jdbc:mysql://localhost:3306/test?useLegacyDatetimeCode=false
+ url: jdbc:mysql://localhost:3306/test?
username: root
password:
@@ -9,6 +9,6 @@ spring:
ddl-auto: update
properties:
hibernate:
- dialect: org.hibernate.dialect.MySQL5Dialect
+ dialect: org.hibernate.dialect.MySQL8Dialect
jdbc:
time_zone: UTC
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/.gitignore b/persistence-modules/spring-boot-persistence-mongodb-2/.gitignore
new file mode 100644
index 0000000000..2d513a0101
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/.gitignore
@@ -0,0 +1,2 @@
+/.idea/
+/target/
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/README.md b/persistence-modules/spring-boot-persistence-mongodb-2/README.md
new file mode 100644
index 0000000000..9169e09813
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/README.md
@@ -0,0 +1,4 @@
+# Relevant Articles
+
+- [Logging MongoDB Queries with Spring Boot](https://www.baeldung.com/spring-boot-mongodb-logging)
+- More articles: [[<--prev]](../spring-boot-persistence-mongodb)
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/pom.xml b/persistence-modules/spring-boot-persistence-mongodb-2/pom.xml
new file mode 100644
index 0000000000..a172c28a80
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/pom.xml
@@ -0,0 +1,39 @@
+
+
+ 4.0.0
+ spring-boot-persistence-mongodb-2
+ spring-boot-persistence-mongodb-2
+ war
+ This is simple boot application for Spring boot persistence mongodb test
+
+
+ com.baeldung
+ parent-boot-2
+ 0.0.1-SNAPSHOT
+ ../../parent-boot-2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+ de.flapdoodle.embed
+ de.flapdoodle.embed.mongo
+ ${embed.mongo.version}
+ test
+
+
+
+
+ 3.2.6
+
+
+
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/SpringBootPersistenceApplication.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/SpringBootPersistenceApplication.java
new file mode 100644
index 0000000000..2dff3f37df
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/SpringBootPersistenceApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringBootPersistenceApplication {
+
+ public static void main(String ... args) {
+ SpringApplication.run(SpringBootPersistenceApplication.class, args);
+ }
+
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/Naming.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/Naming.java
new file mode 100644
index 0000000000..9808ecccb6
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/Naming.java
@@ -0,0 +1,35 @@
+package com.baeldung.boot.collection.name;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.data.util.ParsingUtils;
+import org.springframework.util.StringUtils;
+
+public class Naming {
+ public static void main(String[] args) {
+ String r = new Naming().fix(args[0]);
+ System.out.println(r);
+ }
+
+ public String fix(String name) {
+ List parts = ParsingUtils.splitCamelCaseToLower(name);
+ List result = new ArrayList<>();
+
+ for (String part : parts) {
+ if (StringUtils.hasText(part)) {
+ result.add(part);
+ }
+ }
+
+ return StringUtils.collectionToDelimitedString(result, "_");
+ }
+
+ public String convert(Class> type) {
+ return fix(type.getSimpleName());
+ }
+
+ public String convert(Object instance) {
+ return convert(instance.getClass());
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/SpringBootCollectionNameApplication.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/SpringBootCollectionNameApplication.java
new file mode 100644
index 0000000000..e4157b6a53
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/SpringBootCollectionNameApplication.java
@@ -0,0 +1,21 @@
+package com.baeldung.boot.collection.name;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+
+@SpringBootApplication
+@PropertySource("classpath:boot.collection.name/app.properties")
+@EnableMongoRepositories(basePackages = { "com.baeldung.boot.collection.name" })
+public class SpringBootCollectionNameApplication {
+ public static void main(String... args) {
+ SpringApplication.run(SpringBootCollectionNameApplication.class, args);
+ }
+
+ @Bean
+ public Naming naming() {
+ return new Naming();
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/CompilationRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/CompilationRepository.java
new file mode 100644
index 0000000000..3f83ad4548
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/CompilationRepository.java
@@ -0,0 +1,9 @@
+package com.baeldung.boot.collection.name.dao;
+
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+import com.baeldung.boot.collection.name.data.Compilation;
+
+public interface CompilationRepository extends MongoRepository {
+
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/MusicAlbumRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/MusicAlbumRepository.java
new file mode 100644
index 0000000000..98709361d7
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/MusicAlbumRepository.java
@@ -0,0 +1,9 @@
+package com.baeldung.boot.collection.name.dao;
+
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+import com.baeldung.boot.collection.name.data.MusicAlbum;
+
+public interface MusicAlbumRepository extends MongoRepository {
+
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/MusicTrackRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/MusicTrackRepository.java
new file mode 100644
index 0000000000..0964a8de00
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/MusicTrackRepository.java
@@ -0,0 +1,9 @@
+package com.baeldung.boot.collection.name.dao;
+
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+import com.baeldung.boot.collection.name.data.MusicTrack;
+
+public interface MusicTrackRepository extends MongoRepository {
+
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/StoreRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/StoreRepository.java
new file mode 100644
index 0000000000..b446a7d98d
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/StoreRepository.java
@@ -0,0 +1,9 @@
+package com.baeldung.boot.collection.name.dao;
+
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+import com.baeldung.boot.collection.name.data.Store;
+
+public interface StoreRepository extends MongoRepository {
+
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/Compilation.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/Compilation.java
new file mode 100644
index 0000000000..ce081acf25
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/Compilation.java
@@ -0,0 +1,36 @@
+package com.baeldung.boot.collection.name.data;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document
+public class Compilation {
+ @Id
+ private String id;
+
+ private String name;
+
+ public Compilation() {
+ }
+
+ public Compilation(String name) {
+ super();
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/MusicAlbum.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/MusicAlbum.java
new file mode 100644
index 0000000000..ce2e084504
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/MusicAlbum.java
@@ -0,0 +1,48 @@
+package com.baeldung.boot.collection.name.data;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document("albums")
+public class MusicAlbum {
+ @Id
+ private String id;
+
+ private String name;
+
+ private String artist;
+
+ public MusicAlbum() {
+
+ }
+
+ public MusicAlbum(String name, String artist) {
+ super();
+ this.name = name;
+ this.artist = artist;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getArtist() {
+ return artist;
+ }
+
+ public void setArtist(String artist) {
+ this.artist = artist;
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/MusicTrack.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/MusicTrack.java
new file mode 100644
index 0000000000..39ce3994bb
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/MusicTrack.java
@@ -0,0 +1,50 @@
+package com.baeldung.boot.collection.name.data;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document("#{@naming.fix('MusicTrack')}")
+public class MusicTrack {
+ @Id
+ private String id;
+
+ private String name;
+
+ private String artist;
+
+ public MusicTrack() {
+ }
+
+ public MusicTrack(String name, String artist) {
+ this.name = name;
+ this.artist = artist;
+ }
+
+ public MusicTrack(String name) {
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getArtist() {
+ return artist;
+ }
+
+ public void setArtist(String artist) {
+ this.artist = artist;
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/Store.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/Store.java
new file mode 100644
index 0000000000..83f5017a13
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/Store.java
@@ -0,0 +1,36 @@
+package com.baeldung.boot.collection.name.data;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document("store-#{@environment.getProperty('collection.suffix')}")
+public class Store {
+ @Id
+ private String id;
+
+ private String name;
+
+ public Store() {
+ }
+
+ public Store(String name) {
+ super();
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/service/MusicStoreService.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/service/MusicStoreService.java
new file mode 100644
index 0000000000..6083e3d0c3
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/service/MusicStoreService.java
@@ -0,0 +1,62 @@
+package com.baeldung.boot.collection.name.service;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.boot.collection.name.dao.CompilationRepository;
+import com.baeldung.boot.collection.name.dao.MusicAlbumRepository;
+import com.baeldung.boot.collection.name.dao.MusicTrackRepository;
+import com.baeldung.boot.collection.name.dao.StoreRepository;
+import com.baeldung.boot.collection.name.data.Compilation;
+import com.baeldung.boot.collection.name.data.MusicAlbum;
+import com.baeldung.boot.collection.name.data.MusicTrack;
+import com.baeldung.boot.collection.name.data.Store;
+
+@Service
+public class MusicStoreService {
+ @Autowired
+ private MusicAlbumRepository albumRepository;
+
+ @Autowired
+ private CompilationRepository compilationRepository;
+
+ @Autowired
+ private StoreRepository storeRepository;
+
+ @Autowired
+ private MusicTrackRepository trackRepository;
+
+ public MusicAlbum add(MusicAlbum item) {
+ return albumRepository.save(item);
+ }
+
+ public List getAlbumList() {
+ return albumRepository.findAll();
+ }
+
+ public Compilation add(Compilation item) {
+ return compilationRepository.save(item);
+ }
+
+ public List getCompilationList() {
+ return compilationRepository.findAll();
+ }
+
+ public Store add(Store item) {
+ return storeRepository.save(item);
+ }
+
+ public List getStoreList() {
+ return storeRepository.findAll();
+ }
+
+ public MusicTrack add(MusicTrack item) {
+ return trackRepository.save(item);
+ }
+
+ public List getTrackList() {
+ return trackRepository.findAll();
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/web/CollectionController.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/web/CollectionController.java
new file mode 100644
index 0000000000..2efca361b9
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/web/CollectionController.java
@@ -0,0 +1,24 @@
+package com.baeldung.boot.collection.name.web;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.mongodb.DBObject;
+
+@RestController
+@RequestMapping("/collection")
+public class CollectionController {
+ @Autowired
+ private MongoTemplate mongo;
+
+ @GetMapping("/{name}")
+ public List get(@PathVariable String name) {
+ return mongo.findAll(DBObject.class, name);
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/web/MusicStoreController.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/web/MusicStoreController.java
new file mode 100644
index 0000000000..8c510121c2
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/web/MusicStoreController.java
@@ -0,0 +1,63 @@
+package com.baeldung.boot.collection.name.web;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.boot.collection.name.data.Compilation;
+import com.baeldung.boot.collection.name.data.MusicAlbum;
+import com.baeldung.boot.collection.name.data.MusicTrack;
+import com.baeldung.boot.collection.name.data.Store;
+import com.baeldung.boot.collection.name.service.MusicStoreService;
+
+@RestController
+@RequestMapping("/music")
+public class MusicStoreController {
+ @Autowired
+ private MusicStoreService service;
+
+ @PostMapping("/album")
+ public MusicAlbum post(@RequestBody MusicAlbum item) {
+ return service.add(item);
+ }
+
+ @GetMapping("/album")
+ public List getAlbumList() {
+ return service.getAlbumList();
+ }
+
+ @PostMapping("/compilation")
+ public Compilation post(@RequestBody Compilation item) {
+ return service.add(item);
+ }
+
+ @GetMapping("/compilation")
+ public List getCompilationList() {
+ return service.getCompilationList();
+ }
+
+ @PostMapping("/store")
+ public Store post(@RequestBody Store item) {
+ return service.add(item);
+ }
+
+ @GetMapping("/store")
+ public List getStoreList() {
+ return service.getStoreList();
+ }
+
+ @PostMapping("/track")
+ public MusicTrack post(@RequestBody MusicTrack item) {
+ return service.add(item);
+ }
+
+ @GetMapping("/track")
+ public List getTrackList() {
+ return service.getTrackList();
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/logging/model/Book.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/logging/model/Book.java
similarity index 100%
rename from persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/logging/model/Book.java
rename to persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/logging/model/Book.java
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/application.properties b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/application.properties
new file mode 100644
index 0000000000..9dbc261896
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/application.properties
@@ -0,0 +1 @@
+spring.application.name=spring-boot-persistence-mongodb-2
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.collection.name/app.properties b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.collection.name/app.properties
new file mode 100644
index 0000000000..98945a76e1
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.collection.name/app.properties
@@ -0,0 +1 @@
+collection.suffix=db
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/collection/name/service/MusicStoreServiceIntegrationTest.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/collection/name/service/MusicStoreServiceIntegrationTest.java
new file mode 100644
index 0000000000..eda8b8aafb
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/collection/name/service/MusicStoreServiceIntegrationTest.java
@@ -0,0 +1,81 @@
+package com.baeldung.boot.collection.name.service;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.baeldung.boot.collection.name.data.Compilation;
+import com.baeldung.boot.collection.name.data.MusicAlbum;
+import com.baeldung.boot.collection.name.data.MusicTrack;
+import com.baeldung.boot.collection.name.data.Store;
+
+@SpringBootTest
+@DirtiesContext
+@RunWith(SpringRunner.class)
+public class MusicStoreServiceIntegrationTest {
+ @Autowired
+ private MusicStoreService service;
+
+ @Autowired
+ private MongoTemplate mongoDb;
+
+ @Test
+ public void givenAnnotation_whenSearchingByCollectionName_thenFound() {
+ List list = service.getCompilationList();
+ int sizeBefore = list.size();
+
+ service.add(new Compilation("Spring Hits"));
+
+ list = mongoDb.findAll(Compilation.class, "compilation");
+ int sizeAfter = list.size();
+
+ assertThat(sizeAfter - sizeBefore).isEqualTo(1);
+ }
+
+ @Test
+ public void givenAnnotationWithValue_whenSearchingByCollectionName_thenFound() {
+ List list = service.getAlbumList();
+ int sizeBefore = list.size();
+
+ service.add(new MusicAlbum("Album 1", "Artist A"));
+
+ list = mongoDb.findAll(MusicAlbum.class, "albums");
+ int sizeAfter = list.size();
+
+ assertThat(sizeAfter - sizeBefore).isEqualTo(1);
+ }
+
+ @Test
+ public void givenAnnotationWithSpELEnvironment_whenSearchingByCollectionName_thenFound() {
+ List list = service.getStoreList();
+ int sizeBefore = list.size();
+
+ service.add(new Store("Store A"));
+
+ list = mongoDb.findAll(Store.class, "store-db");
+ int sizeAfter = list.size();
+
+ assertThat(sizeAfter - sizeBefore).isEqualTo(1);
+ }
+
+ @Test
+ public void givenAnnotationWithSpELBean_whenSearchingByCollectionName_thenFound() {
+ List list = service.getTrackList();
+ int sizeBefore = list.size();
+
+ service.add(new MusicTrack("Track 1"));
+
+ list = mongoDb.findAll(MusicTrack.class, "music_track");
+ int sizeAfter = list.size();
+
+ assertThat(sizeAfter - sizeBefore).isEqualTo(1);
+ }
+}
diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/GroupByAuthor.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/logging/GroupByAuthor.java
similarity index 100%
rename from persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/GroupByAuthor.java
rename to persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/logging/GroupByAuthor.java
diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/LoggingUnitTest.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/logging/LoggingUnitTest.java
similarity index 97%
rename from persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/LoggingUnitTest.java
rename to persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/logging/LoggingUnitTest.java
index 1c59dcb5ac..00def53566 100644
--- a/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/LoggingUnitTest.java
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/logging/LoggingUnitTest.java
@@ -35,7 +35,7 @@ import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.process.runtime.Network;
@SpringBootTest
-@TestPropertySource(properties = { "logging.level.org.springframework.data.mongodb.core.MongoTemplate=DEBUG" })
+@TestPropertySource(properties = { "logging.level.org.springframework.data.mongodb.core.MongoTemplate=INFO" })
public class LoggingUnitTest {
private static final String CONNECTION_STRING = "mongodb://%s:%d";
@@ -51,7 +51,7 @@ public class LoggingUnitTest {
@BeforeEach
void setup() throws Exception {
String ip = "localhost";
- int port = SocketUtils.findAvailableTcpPort();
+ int port = Network.freeServerPort(Network.getLocalHost());
ImmutableMongodConfig mongodConfig = MongodConfig.builder()
.version(Version.Main.PRODUCTION)
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/resources/application.properties b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/resources/application.properties
new file mode 100644
index 0000000000..a5b5fb9804
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/resources/application.properties
@@ -0,0 +1 @@
+spring.mongodb.embedded.version=4.4.9
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/resources/logback-test.xml b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8d4771e308
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-mongodb/README.md b/persistence-modules/spring-boot-persistence-mongodb/README.md
index 6659e82677..8e9399f076 100644
--- a/persistence-modules/spring-boot-persistence-mongodb/README.md
+++ b/persistence-modules/spring-boot-persistence-mongodb/README.md
@@ -7,5 +7,4 @@
- [ZonedDateTime with Spring Data MongoDB](https://www.baeldung.com/spring-data-mongodb-zoneddatetime)
- [A Guide to @DBRef in MongoDB](https://www.baeldung.com/spring-mongodb-dbref-annotation)
- [Import Data to MongoDB From JSON File Using Java](https://www.baeldung.com/java-import-json-mongodb)
-- [Logging MongoDB Queries with Spring Boot](https://www.baeldung.com/spring-boot-mongodb-logging)
-- [Return Only Specific Fields for a Query in Spring Data MongoDB](https://www.baeldung.com/mongodb-return-specific-fields)
+- More articles: [[next-->]](../spring-boot-persistence-mongodb-2)
diff --git a/persistence-modules/spring-data-jpa-query-3/README.md b/persistence-modules/spring-data-jpa-query-3/README.md
index 246b6ebf3d..920ec40965 100644
--- a/persistence-modules/spring-data-jpa-query-3/README.md
+++ b/persistence-modules/spring-data-jpa-query-3/README.md
@@ -4,6 +4,7 @@ This module contains articles about querying data using Spring Data JPA.
### Relevant Articles:
- [Query Entities by Dates and Times with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-query-by-date)
+- [JPA and Hibernate – Criteria vs. JPQL vs. HQL Query](https://www.baeldung.com/jpql-hql-criteria-query)
- More articles: [[<-- prev]](../spring-data-jpa-query-2)
### Eclipse Config
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/entity/Employee.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/entity/Employee.java
index 214cb09e57..a511686f1b 100644
--- a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/entity/Employee.java
+++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/entity/Employee.java
@@ -7,12 +7,12 @@ import javax.persistence.Id;
@Entity
public class Employee {
- @Id
- @GeneratedValue
- private Integer id;
+ @Id
+ @GeneratedValue
+ private Integer id;
- private String name;
+ private String name;
- private Long salary;
+ private Long salary;
}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Author.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Author.java
new file mode 100644
index 0000000000..70e699ebeb
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Author.java
@@ -0,0 +1,57 @@
+package com.baeldung.spring.data.jpa.query.specifications.join;
+
+import javax.persistence.*;
+
+import java.util.List;
+
+@Entity
+public class Author {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String firstName;
+
+ private String lastName;
+
+ @OneToMany(cascade = CascadeType.ALL)
+ private List books;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public List getBooks() {
+ return books;
+ }
+
+ public void setBooks(List books) {
+ this.books = books;
+ }
+
+ @Override
+ public String toString() {
+ return "Author{" + "id=" + id + ", firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + ", books=" + books + '}';
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorSpecifications.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorSpecifications.java
new file mode 100644
index 0000000000..73d0cd6c01
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorSpecifications.java
@@ -0,0 +1,24 @@
+package com.baeldung.spring.data.jpa.query.specifications.join;
+
+import org.springframework.data.jpa.domain.Specification;
+
+import javax.persistence.criteria.*;
+
+public class AuthorSpecifications {
+
+ public static Specification hasFirstNameLike(String name) {
+ return (root, query, criteriaBuilder) -> criteriaBuilder.like(root.get("firstName"), "%" + name + "%");
+ }
+
+ public static Specification hasLastName(String name) {
+ return (root, query, cb) -> cb.equal(root.get("lastName"), name);
+ }
+
+ public static Specification hasBookWithTitle(String bookTitle) {
+ return (root, query, criteriaBuilder) -> {
+ Join authorsBook = root.join("books");
+ return criteriaBuilder.equal(authorsBook.get("title"), bookTitle);
+ };
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorsRepository.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorsRepository.java
new file mode 100644
index 0000000000..67fe86b8b3
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorsRepository.java
@@ -0,0 +1,9 @@
+package com.baeldung.spring.data.jpa.query.specifications.join;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface AuthorsRepository extends JpaRepository, JpaSpecificationExecutor {
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Book.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Book.java
new file mode 100644
index 0000000000..3d658ca107
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Book.java
@@ -0,0 +1,37 @@
+package com.baeldung.spring.data.jpa.query.specifications.join;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Book {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String title;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ @Override
+ public String toString() {
+ return "Book{" + "id=" + id + ", title='" + title + '\'' + '}';
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/repository/EmployeeRepository.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/repository/EmployeeRepository.java
index 652b7b93d2..85d1a1b324 100644
--- a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/repository/EmployeeRepository.java
+++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/repository/EmployeeRepository.java
@@ -9,29 +9,32 @@ import org.springframework.data.repository.query.Param;
public interface EmployeeRepository extends JpaRepository {
- @Query(value = "SELECT e FROM Employee e")
- List findAllEmployees(Sort sort);
+ @Query(value = "SELECT e FROM Employee e")
+ List findAllEmployees(Sort sort);
- @Query("SELECT e FROM Employee e WHERE e.salary = ?1")
- Employee findAllEmployeesWithSalary(Long salary);
+ @Query("SELECT e FROM Employee e WHERE e.salary = ?1")
+ Employee findAllEmployeesWithSalary(Long salary);
- @Query("SELECT e FROM Employee e WHERE e.name = ?1 and e.salary = ?2")
- Employee findUserByNameAndSalary(String name, Long salary);
+ @Query("SELECT e FROM Employee e WHERE e.name = ?1 and e.salary = ?2")
+ Employee findUserByNameAndSalary(String name, Long salary);
- @Query(
- value = "SELECT * FROM Employee e WHERE e.salary = ?1",
- nativeQuery = true)
- Employee findUserBySalaryNative(Long salary);
+ @Query(
+ value = "SELECT * FROM Employee e WHERE e.salary = ?1",
+ nativeQuery = true
+ )
+ Employee findUserBySalaryNative(Long salary);
- @Query("SELECT e FROM Employee e WHERE e.name = :name and e.salary = :salary")
- Employee findUserByEmployeeNameAndSalaryNamedParameters(
- @Param("name") String employeeName,
- @Param("salary") Long employeeSalary);
+ @Query("SELECT e FROM Employee e WHERE e.name = :name and e.salary = :salary")
+ Employee findUserByEmployeeNameAndSalaryNamedParameters(
+ @Param("name") String employeeName,
+ @Param("salary") Long employeeSalary);
- @Query(value = "SELECT * FROM Employee e WHERE e.name = :name and e.salary = :salary",
- nativeQuery = true)
- Employee findUserByNameAndSalaryNamedParamsNative(
- @Param("name") String employeeName,
- @Param("salary") Long employeeSalary);
+ @Query(
+ value = "SELECT * FROM Employee e WHERE e.name = :name and e.salary = :salary",
+ nativeQuery = true
+ )
+ Employee findUserByNameAndSalaryNamedParamsNative(
+ @Param("name") String employeeName,
+ @Param("salary") Long employeeSalary);
}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/query/specifications/join/SpecificationsJoinIntegrationTest.java b/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/query/specifications/join/SpecificationsJoinIntegrationTest.java
new file mode 100644
index 0000000000..27db09d11c
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/query/specifications/join/SpecificationsJoinIntegrationTest.java
@@ -0,0 +1,80 @@
+package com.baeldung.spring.data.jpa.query.specifications.join;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static com.baeldung.spring.data.jpa.query.specifications.join.AuthorSpecifications.*;
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+public class SpecificationsJoinIntegrationTest {
+
+ @Autowired
+ private AuthorsRepository repository;
+
+ @Before
+ public void beforeEach() {
+ saveTestData();
+ }
+
+ @Test
+ public void whenSearchingByLastName_thenOneAuthorIsReturned() {
+
+ List authors = repository.findAll(hasLastName("Martin"));
+
+ assertThat(authors).hasSize(1);
+ }
+
+ @Test
+ public void whenSearchingByLastNameAndFirstNameLike_thenOneAuthorIsReturned() {
+
+ Specification specification = hasLastName("Martin").and(hasFirstNameLike("Robert"));
+
+ List authors = repository.findAll(specification);
+
+ assertThat(authors).hasSize(1);
+ }
+
+ @Test
+ public void whenSearchingByBookTitle_thenOneAuthorIsReturned() {
+
+ Specification specification = hasBookWithTitle("Clean Code");
+
+ List authors = repository.findAll(specification);
+
+ assertThat(authors).hasSize(1);
+ }
+
+ @Test
+ public void whenSearchingByBookTitleAndAuthorName_thenOneAuthorIsReturned() {
+
+ Specification specification = hasLastName("Martin").and(hasBookWithTitle("Clean Code"));
+
+ List authors = repository.findAll(specification);
+
+ assertThat(authors).hasSize(1);
+ }
+
+ private void saveTestData() {
+ Author uncleBob = new Author();
+ uncleBob.setFirstName("Robert");
+ uncleBob.setLastName("Martin");
+
+ Book book1 = new Book();
+ book1.setTitle("Clean Code");
+ Book book2 = new Book();
+ book2.setTitle("Clean Architecture");
+
+ uncleBob.setBooks(Arrays.asList(book1, book2));
+ repository.save(uncleBob);
+ }
+}
diff --git a/persistence-modules/spring-data-mongodb/README.md b/persistence-modules/spring-data-mongodb/README.md
index acc978c68e..7dd0a82def 100644
--- a/persistence-modules/spring-data-mongodb/README.md
+++ b/persistence-modules/spring-data-mongodb/README.md
@@ -11,6 +11,7 @@
- [Spring Data MongoDB: Projections and Aggregations](http://www.baeldung.com/spring-data-mongodb-projections-aggregations)
- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
- [Spring Data MongoDB Transactions](https://www.baeldung.com/spring-data-mongodb-transactions)
+- [Return Only Specific Fields for a Query in Spring Data MongoDB](https://www.baeldung.com/mongodb-return-specific-fields)
## Spring Data MongoDB Live Testing
diff --git a/persistence-modules/spring-jooq/pom.xml b/persistence-modules/spring-jooq/pom.xml
index c842922fe5..6a9fb0ef06 100644
--- a/persistence-modules/spring-jooq/pom.xml
+++ b/persistence-modules/spring-jooq/pom.xml
@@ -195,7 +195,7 @@
- 3.12.4
+ 3.14.15
1.0.0
1.5
1.0.0
diff --git a/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/CountQueryIntegrationTest.java b/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/CountQueryIntegrationTest.java
index 7edcc2cd4b..9765a26a2b 100644
--- a/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/CountQueryIntegrationTest.java
+++ b/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/CountQueryIntegrationTest.java
@@ -76,7 +76,14 @@ public class CountQueryIntegrationTest {
int count = dsl.fetchCount(AUTHOR, conditions);
Assert.assertEquals(1, count);
}
-
+
+
+ @Test
+ public void givenValidData_whenFetchCountWithMultipleConditionsUsingAndOperator_thenSucceed() {
+ int count = dsl.fetchCount(AUTHOR, AUTHOR.FIRST_NAME.equalIgnoreCase("Bryan").and(AUTHOR.ID.notEqual(1)));
+ Assert.assertEquals(1, count);
+ }
+
@Test
public void givenValidData_whenFetchCountWithConditionsInVarargs_thenSucceed() {
Condition firstCond = AUTHOR.FIRST_NAME.equalIgnoreCase("Bryan");
diff --git a/pom.xml b/pom.xml
index f06c75b3be..a8bd79f3f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -366,7 +366,7 @@
atomix
aws-modules
-
+
axon
azure
@@ -620,7 +620,6 @@
spring-bom
spring-boot-modules
spring-boot-rest
- spring-boot-rest-2
spring-caching
spring-caching-2
@@ -837,7 +836,7 @@
atomix
aws-modules
-
+
axon
azure
@@ -896,7 +895,7 @@
helidon
apache-httpclient
httpclient-simple
- hystrix
+ hystrix
jackson-modules
jackson-simple
@@ -1085,7 +1084,6 @@
spring-bom
spring-boot-modules
spring-boot-rest
- spring-boot-rest-2
spring-caching
spring-caching-2
@@ -1211,6 +1209,7 @@
jenkins/plugins
jhipster
+ jhipster-5
jws
libraries
@@ -1318,6 +1317,7 @@
core-java-modules/core-java-networking-3
core-java-modules/multimodulemavenproject
core-java-modules/core-java-strings
+ core-java-modules/core-java-httpclient
ddd-modules
docker
apache-httpclient-2
@@ -1327,9 +1327,10 @@
quarkus-vs-springboot
quarkus-jandex
spring-boot-modules/spring-boot-cassandre
- spring-boot-modules/spring-boot-camel
+ spring-boot-modules/spring-boot-camel
testing-modules/testing-assertions
persistence-modules/fauna
+ lightrun
@@ -1397,6 +1398,7 @@
spring-boot-modules/spring-boot-camel
testing-modules/testing-assertions
persistence-modules/fauna
+ lightrun
diff --git a/reactive-systems/README.md b/reactive-systems/README.md
index b23f4e4dc4..65d4b0a919 100644
--- a/reactive-systems/README.md
+++ b/reactive-systems/README.md
@@ -1,6 +1,6 @@
## Reactive Systems in Java
-This module contains services for article about reactive systems in Java. Please note that these secrives comprise parts of a full stack application to demonstrate the capabilities of a reactive system. Unless there is an article which extends on this concept, this is probably not a suitable module to add other code.
+This module contains services for article about reactive systems in Java. Please note that these services comprise parts of a full stack application to demonstrate the capabilities of a reactive system. Unless there is an article which extends on this concept, this is probably not a suitable module to add other code.
### Relevant Articles
diff --git a/resteasy/pom.xml b/resteasy/pom.xml
index d35fc852ba..a8c1f2815c 100644
--- a/resteasy/pom.xml
+++ b/resteasy/pom.xml
@@ -20,12 +20,6 @@
org.jboss.resteasy
resteasy-servlet-initializer
${resteasy.version}
-
-
- commons-logging
- commons-logging
-
-
org.jboss.resteasy
@@ -40,14 +34,15 @@
org.jboss.resteasy
- resteasy-jackson-provider
+ resteasy-jackson2-provider
${resteasy.version}
- commons-io
- commons-io
- ${commons-io.version}
+ javax.servlet
+ javax.servlet-api
+ 4.0.1
+
@@ -134,7 +129,7 @@
- 3.0.19.Final
+ 4.7.2.Final
1.6.1
diff --git a/resteasy/src/test/java/com/baeldung/server/RestEasyClientLiveTest.java b/resteasy/src/test/java/com/baeldung/server/RestEasyClientLiveTest.java
index 7e709edb96..ba2878cc21 100644
--- a/resteasy/src/test/java/com/baeldung/server/RestEasyClientLiveTest.java
+++ b/resteasy/src/test/java/com/baeldung/server/RestEasyClientLiveTest.java
@@ -7,6 +7,7 @@ import java.util.List;
import java.util.Locale;
import javax.naming.NamingException;
+import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
@@ -14,21 +15,21 @@ import org.apache.commons.io.IOUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
-import org.codehaus.jackson.map.DeserializationConfig;
-import org.codehaus.jackson.map.ObjectMapper;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
-import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
+import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine;
import org.junit.Before;
import org.junit.Test;
import com.baeldung.client.ServicesInterface;
import com.baeldung.model.Movie;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
public class RestEasyClientLiveTest {
- public static final UriBuilder FULL_PATH = UriBuilder.fromPath("http://127.0.0.1:8082/RestEasyTutorial/rest");
+ public static final UriBuilder FULL_PATH = UriBuilder.fromPath("http://127.0.0.1:8082/resteasy/rest");
Movie transformerMovie = null;
Movie batmanMovie = null;
ObjectMapper jsonMapper = null;
@@ -36,8 +37,8 @@ public class RestEasyClientLiveTest {
@Before
public void setup() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NamingException {
- jsonMapper = new ObjectMapper().configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- jsonMapper.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
+ jsonMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ jsonMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
final SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);
jsonMapper.setDateFormat(sdf);
@@ -60,8 +61,8 @@ public class RestEasyClientLiveTest {
@Test
public void testListAllMovies() {
-
- final ResteasyClient client = new ResteasyClientBuilder().build();
+
+ final ResteasyClient client = (ResteasyClient)ClientBuilder.newClient();
final ResteasyWebTarget target = client.target(FULL_PATH);
final ServicesInterface proxy = target.proxy(ServicesInterface.class);
@@ -79,7 +80,7 @@ public class RestEasyClientLiveTest {
final String transformerImdbId = "tt0418279";
- final ResteasyClient client = new ResteasyClientBuilder().build();
+ final ResteasyClient client = (ResteasyClient) ClientBuilder.newClient();
final ResteasyWebTarget target = client.target(FULL_PATH);
final ServicesInterface proxy = target.proxy(ServicesInterface.class);
@@ -93,7 +94,7 @@ public class RestEasyClientLiveTest {
@Test
public void testAddMovie() {
- final ResteasyClient client = new ResteasyClientBuilder().build();
+ final ResteasyClient client = (ResteasyClient) ClientBuilder.newClient();
final ResteasyWebTarget target = client.target(FULL_PATH);
final ServicesInterface proxy = target.proxy(ServicesInterface.class);
@@ -114,8 +115,8 @@ public class RestEasyClientLiveTest {
final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
final CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build();
- final ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);
- final ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
+ final ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine(httpClient);
+ final ResteasyClient client = ((ResteasyClientBuilder) ClientBuilder.newBuilder()).httpEngine(engine).build();
final ResteasyWebTarget target = client.target(FULL_PATH);
final ServicesInterface proxy = target.proxy(ServicesInterface.class);
@@ -138,7 +139,7 @@ public class RestEasyClientLiveTest {
@Test
public void testDeleteMovie() {
- final ResteasyClient client = new ResteasyClientBuilder().build();
+ final ResteasyClient client = (ResteasyClient) ClientBuilder.newClient();
final ResteasyWebTarget target = client.target(FULL_PATH);
final ServicesInterface proxy = target.proxy(ServicesInterface.class);
@@ -158,7 +159,7 @@ public class RestEasyClientLiveTest {
@Test
public void testUpdateMovie() {
- final ResteasyClient client = new ResteasyClientBuilder().build();
+ final ResteasyClient client = (ResteasyClient) ClientBuilder.newClient();
final ResteasyWebTarget target = client.target(FULL_PATH);
final ServicesInterface proxy = target.proxy(ServicesInterface.class);
diff --git a/restx/src/main/resources/restx/demo/settings.properties b/restx/src/main/resources/restx/demo/settings.properties
index a03c2eea97..3b2b591922 100644
--- a/restx/src/main/resources/restx/demo/settings.properties
+++ b/restx/src/main/resources/restx/demo/settings.properties
@@ -1 +1,2 @@
-app.name=restx-demo
\ No newline at end of file
+app.name=restx-demo
+restx.stats.share.enable=false
\ No newline at end of file
diff --git a/spring-5/src/test/java/com/baeldung/Example1IntegrationTest.java b/spring-5/src/test/java/com/baeldung/Example1ManualTest.java
similarity index 93%
rename from spring-5/src/test/java/com/baeldung/Example1IntegrationTest.java
rename to spring-5/src/test/java/com/baeldung/Example1ManualTest.java
index 8b9e66213f..c3330b4213 100644
--- a/spring-5/src/test/java/com/baeldung/Example1IntegrationTest.java
+++ b/spring-5/src/test/java/com/baeldung/Example1ManualTest.java
@@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
-public class Example1IntegrationTest {
+public class Example1ManualTest {
@Test
public void test1a() {
diff --git a/spring-5/src/test/java/com/baeldung/Example2IntegrationTest.java b/spring-5/src/test/java/com/baeldung/Example2ManualTest.java
similarity index 93%
rename from spring-5/src/test/java/com/baeldung/Example2IntegrationTest.java
rename to spring-5/src/test/java/com/baeldung/Example2ManualTest.java
index 6ed53ca4e9..9c47b17fdb 100644
--- a/spring-5/src/test/java/com/baeldung/Example2IntegrationTest.java
+++ b/spring-5/src/test/java/com/baeldung/Example2ManualTest.java
@@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
-public class Example2IntegrationTest {
+public class Example2ManualTest {
@Test
public void test1a() {
diff --git a/spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java b/spring-5/src/test/java/com/baeldung/ParallelManualTest.java
similarity index 62%
rename from spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java
rename to spring-5/src/test/java/com/baeldung/ParallelManualTest.java
index 1ce96de4ef..5c3a111c62 100644
--- a/spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java
+++ b/spring-5/src/test/java/com/baeldung/ParallelManualTest.java
@@ -5,18 +5,18 @@ import org.junit.experimental.ParallelComputer;
import org.junit.runner.Computer;
import org.junit.runner.JUnitCore;
-public class ParallelIntegrationTest {
+public class ParallelManualTest {
@Test
public void runTests() {
- final Class>[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class };
+ final Class>[] classes = { Example1ManualTest.class, Example2ManualTest.class };
JUnitCore.runClasses(new Computer(), classes);
}
@Test
public void runTestsInParallel() {
- final Class>[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class };
+ final Class>[] classes = { Example1ManualTest.class, Example2ManualTest.class };
JUnitCore.runClasses(new ParallelComputer(true, true), classes);
}
diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelManualTest.java
similarity index 60%
rename from spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java
rename to spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelManualTest.java
index 55b0fcf267..b9ed87ed73 100644
--- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java
+++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelManualTest.java
@@ -1,24 +1,24 @@
package com.baeldung.jupiter;
-import com.baeldung.Example1IntegrationTest;
-import com.baeldung.Example2IntegrationTest;
+import com.baeldung.Example1ManualTest;
+import com.baeldung.Example2ManualTest;
import org.junit.experimental.ParallelComputer;
import org.junit.jupiter.api.Test;
import org.junit.runner.Computer;
import org.junit.runner.JUnitCore;
-class Spring5JUnit5ParallelIntegrationTest {
+class Spring5JUnit5ParallelManualTest {
@Test
void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingParallel() {
- final Class>[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class };
+ final Class>[] classes = { Example1ManualTest.class, Example2ManualTest.class };
JUnitCore.runClasses(new ParallelComputer(true, true), classes);
}
@Test
void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingLinear() {
- final Class>[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class };
+ final Class>[] classes = { Example1ManualTest.class, Example2ManualTest.class };
JUnitCore.runClasses(new Computer(), classes);
}
diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml
index dd81072ad1..63f11a4a76 100644
--- a/spring-boot-modules/pom.xml
+++ b/spring-boot-modules/pom.xml
@@ -6,8 +6,8 @@
com.baeldung.spring-boot-modules
spring-boot-modules
1.0.0-SNAPSHOT
- pom
spring-boot-modules
+ pom
com.baeldung
@@ -16,7 +16,7 @@
../parent-boot-2
-
+
spring-boot-admin
spring-boot-angular
spring-boot-annotations
@@ -98,4 +98,4 @@
-
+
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-artifacts/pom.xml b/spring-boot-modules/spring-boot-artifacts/pom.xml
index 0292dc95cf..7709c6a316 100644
--- a/spring-boot-modules/spring-boot-artifacts/pom.xml
+++ b/spring-boot-modules/spring-boot-artifacts/pom.xml
@@ -101,7 +101,7 @@
maven-failsafe-plugin
2.18
-
integration-tests
@@ -110,7 +110,7 @@
verify
-
**/ExternalPropertyFileLoaderIntegrationTest.java
@@ -195,4 +195,4 @@
4.5.8
-
+
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java
index 50d5f4ea71..9ef1fcbc8e 100644
--- a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java
+++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java
@@ -27,8 +27,8 @@ public class UserController {
LOG.info("Fetching all the users");
return Arrays.asList(
new User(UUID.randomUUID().toString(), "User1", "user1@test.com"),
- new User(UUID.randomUUID().toString(), "User1", "user1@test.com"),
- new User(UUID.randomUUID().toString(), "User1", "user1@test.com"));
+ new User(UUID.randomUUID().toString(), "User2", "user2@test.com"),
+ new User(UUID.randomUUID().toString(), "User3", "user3@test.com"));
}
}
diff --git a/spring-boot-modules/spring-boot-data-2/README.md b/spring-boot-modules/spring-boot-data-2/README.md
index e7d39a78e9..9ff2b2caf8 100644
--- a/spring-boot-modules/spring-boot-data-2/README.md
+++ b/spring-boot-modules/spring-boot-data-2/README.md
@@ -5,6 +5,6 @@
- [“HttpMessageNotWritableException: No converter found for return value of type”](https://www.baeldung.com/spring-no-converter-found)
- [Creating a Read-Only Repository with Spring Data](https://www.baeldung.com/spring-data-read-only-repository)
- [Using JaVers for Data Model Auditing in Spring Data](https://www.baeldung.com/spring-data-javers-audit)
-- [BootstrapMode for JPA Repositories](https://github.com/eugenp/tutorials/tree/master/spring-boot-modules/spring-boot-data-2)
+- [BootstrapMode for JPA Repositories](https://www.baeldung.com/jpa-bootstrap-mode)
- [Dynamic DTO Validation Config Retrieved from the Database](https://www.baeldung.com/spring-dynamic-dto-validation)
diff --git a/spring-boot-modules/spring-boot-deployment/pom.xml b/spring-boot-modules/spring-boot-deployment/pom.xml
index 7a9c2096f1..47b1a0f0d5 100644
--- a/spring-boot-modules/spring-boot-deployment/pom.xml
+++ b/spring-boot-modules/spring-boot-deployment/pom.xml
@@ -41,6 +41,11 @@
org.springframework.boot
spring-boot-starter-actuator
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+ provided
+
com.h2database
h2
diff --git a/spring-boot-modules/spring-boot-di/src/main/java/com/baeldung/componentscan/springapp/SpringComponentScanApp.java b/spring-boot-modules/spring-boot-di/src/main/java/com/baeldung/componentscan/springapp/SpringComponentScanApp.java
index 8873f1214c..5d3cbe35cb 100644
--- a/spring-boot-modules/spring-boot-di/src/main/java/com/baeldung/componentscan/springapp/SpringComponentScanApp.java
+++ b/spring-boot-modules/spring-boot-di/src/main/java/com/baeldung/componentscan/springapp/SpringComponentScanApp.java
@@ -13,6 +13,10 @@ import org.springframework.context.annotation.Configuration;
// @ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Rose.class))
// @ComponentScan(basePackages = "com.baeldung.componentscan.springapp")
// @ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals")
+// @ComponentScan(basePackages = {"com.baeldung.componentscan.springapp.animals","com.baeldung.componentscan.springapp.flowers"})
+// @ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals;com.baeldung.componentscan.springapp.flowers")
+// @ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals,com.baeldung.componentscan.springapp.flowers")
+// @ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals com.baeldung.componentscan.springapp.flowers")
// @ComponentScan (excludeFilters = @ComponentScan.Filter(type=FilterType.REGEX,pattern="com\\.baeldung\\.componentscan\\.springapp\\.flowers\\..*"))
public class SpringComponentScanApp {
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/CustomUserAttrController.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/CustomUserAttrController.java
index 1959590e5a..5b267ae19e 100644
--- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/CustomUserAttrController.java
+++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/CustomUserAttrController.java
@@ -24,6 +24,8 @@ public class CustomUserAttrController {
final Principal principal = (Principal) authentication.getPrincipal();
String dob = "";
+ String userIdByToken = "";
+ String userIdByMapper = "";
if (principal instanceof KeycloakPrincipal) {
@@ -31,6 +33,9 @@ public class CustomUserAttrController {
IDToken token = kPrincipal.getKeycloakSecurityContext()
.getIdToken();
+ userIdByToken = token.getSubject();
+ userIdByMapper = token.getOtherClaims().get("user_id").toString();
+
Map customClaims = token.getOtherClaims();
if (customClaims.containsKey("DOB")) {
@@ -39,6 +44,8 @@ public class CustomUserAttrController {
}
model.addAttribute("username", principal.getName());
+ model.addAttribute("userIDByToken", userIdByToken);
+ model.addAttribute("userIDByMapper", userIdByMapper);
model.addAttribute("dob", dob);
return "userInfo";
}
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-embedded.properties b/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-embedded.properties
new file mode 100644
index 0000000000..7e1985f0ad
--- /dev/null
+++ b/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-embedded.properties
@@ -0,0 +1,9 @@
+### server port
+server.port=8080
+
+#Keycloak Configuration
+keycloak.auth-server-url=http://localhost:8083/auth
+keycloak.realm=baeldung
+keycloak.resource=customerClient
+keycloak.public-client=true
+keycloak.principal-attribute=preferred_username
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/resources/templates/userInfo.html b/spring-boot-modules/spring-boot-keycloak/src/main/resources/templates/userInfo.html
index 1446fe2124..7f772398c1 100644
--- a/spring-boot-modules/spring-boot-keycloak/src/main/resources/templates/userInfo.html
+++ b/spring-boot-modules/spring-boot-keycloak/src/main/resources/templates/userInfo.html
@@ -7,6 +7,12 @@
Hello, --name--.
+
+ User ID By Token: --userID--.
+
+
+ User ID By Mapper: --userID--.
+
Your Date of Birth as per our records is .
diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapIntegrationTest.java b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapLiveTest.java
similarity index 96%
rename from spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapIntegrationTest.java
rename to spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapLiveTest.java
index e0de897044..0327915399 100644
--- a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapIntegrationTest.java
+++ b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapLiveTest.java
@@ -26,29 +26,35 @@ import java.util.Objects;
import static org.assertj.core.api.Assertions.assertThat;
/**
- * The class contains Live/Integration tests.
+ * The class contains Live tests.
* These tests expect that the Keycloak server is up and running on port 8080.
- * The tests may fail without a Keycloak server.
*/
-@DisplayName("Keycloak SOAP Webservice Unit Tests")
+@DisplayName("Keycloak SOAP Webservice Live Tests")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
@AutoConfigureMockMvc
-class KeycloakSoapIntegrationTest {
+class KeycloakSoapLiveTest {
+
+ private static final Logger logger = LoggerFactory.getLogger(KeycloakSoapLiveTest.class);
- private static final Logger logger = LoggerFactory.getLogger(KeycloakSoapIntegrationTest.class);
@LocalServerPort
private int port;
+
@Autowired
private TestRestTemplate restTemplate;
+
@Autowired
private ObjectMapper objectMapper;
+
@Value("${grant.type}")
private String grantType;
+
@Value("${client.id}")
private String clientId;
+
@Value("${client.secret}")
private String clientSecret;
+
@Value("${url}")
private String keycloakUrl;
diff --git a/spring-boot-modules/spring-boot-libraries/src/test/resources/GraphQL collection.postman_collection.json b/spring-boot-modules/spring-boot-libraries/src/test/resources/GraphQL collection.postman_collection.json
new file mode 100644
index 0000000000..8245152bdd
--- /dev/null
+++ b/spring-boot-modules/spring-boot-libraries/src/test/resources/GraphQL collection.postman_collection.json
@@ -0,0 +1,169 @@
+{
+ "info": {
+ "_postman_id": "910d9690-f629-4491-bbbd-adb30982a386",
+ "name": "GraphQL collection",
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
+ },
+ "item": [
+ {
+ "name": "mutations",
+ "item": [
+ {
+ "name": "writePost",
+ "request": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "graphql",
+ "graphql": {
+ "query": "mutation writePost ($title: String!, $text: String!, $category: String) {\n writePost (title: $title, text: $text, category: $category) {\n id\n title\n text\n category\n }\n}",
+ "variables": "{\n \"title\": \"\",\n \"text\": \"\",\n \"category\": \"\"\n}"
+ },
+ "options": {
+ "graphql": {}
+ }
+ },
+ "url": {
+ "raw": "http://localhost:9090/springbootapp/graphql",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "9090",
+ "path": [
+ "springbootapp",
+ "graphql"
+ ]
+ }
+ },
+ "response": []
+ }
+ ],
+ "protocolProfileBehavior": {}
+ },
+ {
+ "name": "queries",
+ "item": [
+ {
+ "name": "get recent posts",
+ "request": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "graphql",
+ "graphql": {
+ "query": "{\r\n recentPosts(count: 10, offset: 0) {\r\n id\r\n title\r\n category\r\n text\r\n author {\r\n id\r\n name\r\n thumbnail\r\n }\r\n }\r\n}",
+ "variables": ""
+ }
+ },
+ "url": {
+ "raw": "http://localhost:9090/springbootapp/graphql",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "9090",
+ "path": [
+ "springbootapp",
+ "graphql"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "recentPosts - variables",
+ "request": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "graphql",
+ "graphql": {
+ "query": "query recentPosts ($count: Int, $offset: Int) {\n recentPosts (count: $count, offset: $offset) {\n id\n title\n text\n category\n }\n}",
+ "variables": "{\n \"count\": 1,\n \"offset\": 0\n}"
+ },
+ "options": {
+ "graphql": {}
+ }
+ },
+ "url": {
+ "raw": "http://localhost:9090/springbootapp/graphql",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "9090",
+ "path": [
+ "springbootapp",
+ "graphql"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "get recent posts - raw",
+ "request": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/graphql",
+ "type": "text"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "query {\r\n recentPosts(count: 10, offset: 0) {\r\n id\r\n title\r\n category\r\n author {\r\n id\r\n name\r\n thumbnail\r\n }\r\n }\r\n}"
+ },
+ "url": {
+ "raw": "http://localhost:9090/springbootapp/graphql",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "9090",
+ "path": [
+ "springbootapp",
+ "graphql"
+ ]
+ }
+ },
+ "response": []
+ }
+ ],
+ "protocolProfileBehavior": {}
+ }
+ ],
+ "event": [
+ {
+ "listen": "prerequest",
+ "script": {
+ "id": "b54f267b-c450-4f2d-8105-2f23bab4c922",
+ "type": "text/javascript",
+ "exec": [
+ ""
+ ]
+ }
+ },
+ {
+ "listen": "test",
+ "script": {
+ "id": "00b575be-03d4-4b29-b137-733ead139638",
+ "type": "text/javascript",
+ "exec": [
+ ""
+ ]
+ }
+ }
+ ],
+ "variable": [
+ {
+ "id": "20a274e5-6d51-40d6-81cb-af9eb115b21b",
+ "key": "url",
+ "value": "",
+ "type": "string"
+ }
+ ],
+ "protocolProfileBehavior": {}
+}
diff --git a/spring-boot-modules/spring-boot-mvc-2/README.md b/spring-boot-modules/spring-boot-mvc-2/README.md
index 0d0e05daf0..30e6d71a30 100644
--- a/spring-boot-modules/spring-boot-mvc-2/README.md
+++ b/spring-boot-modules/spring-boot-mvc-2/README.md
@@ -11,4 +11,5 @@ This module contains articles about Spring Web MVC in Spring Boot projects.
- [Testing Web APIs with Postman Collections](https://www.baeldung.com/postman-testing-collections)
- [Spring Boot Consuming and Producing JSON](https://www.baeldung.com/spring-boot-json)
- [Serve Static Resources with Spring](https://www.baeldung.com/spring-mvc-static-resources)
+- [Add Header to Every Request in Postman](https://www.baeldung.com/postman-add-headers-pre-request)
- More articles: [[prev -->]](/spring-boot-modules/spring-boot-mvc)
diff --git a/spring-boot-modules/spring-boot-mvc-4/README.md b/spring-boot-modules/spring-boot-mvc-4/README.md
index d215525ab5..a7a341deee 100644
--- a/spring-boot-modules/spring-boot-mvc-4/README.md
+++ b/spring-boot-modules/spring-boot-mvc-4/README.md
@@ -9,3 +9,4 @@ This module contains articles about Spring Web MVC in Spring Boot projects.
- [Configure a Spring Boot Web Application](https://www.baeldung.com/spring-boot-application-configuration)
- [A Quick Intro to the SpringBootServletInitializer](https://www.baeldung.com/spring-boot-servlet-initializer)
- [A Guide to Spring in Eclipse STS](https://www.baeldung.com/eclipse-sts-spring)
+- [Hide a Request Field in Swagger API](https://www.baeldung.com/spring-swagger-hide-field)
diff --git a/spring-boot-modules/spring-boot-mvc-4/pom.xml b/spring-boot-modules/spring-boot-mvc-4/pom.xml
index 5b58b326ab..b1c079b715 100644
--- a/spring-boot-modules/spring-boot-mvc-4/pom.xml
+++ b/spring-boot-modules/spring-boot-mvc-4/pom.xml
@@ -1,14 +1,13 @@
-
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
spring-boot-mvc-4
spring-boot-mvc-4
jar
Module For Spring Boot MVC Web
-
+
com.baeldung.spring-boot-modules
spring-boot-modules
@@ -70,7 +69,6 @@
-
3.0.0
com.baeldung.springboot.swagger.ArticleApplication
diff --git a/spring-boot-modules/spring-boot-mvc/README.md b/spring-boot-modules/spring-boot-mvc/README.md
index cdb2bd0fce..fdd7c70af2 100644
--- a/spring-boot-modules/spring-boot-mvc/README.md
+++ b/spring-boot-modules/spring-boot-mvc/README.md
@@ -7,7 +7,7 @@ This module contains articles about Spring Web MVC in Spring Boot projects.
- [Custom Validation MessageSource in Spring Boot](https://www.baeldung.com/spring-custom-validation-message-source)
- [Display RSS Feed with Spring MVC](https://www.baeldung.com/spring-mvc-rss-feed)
- [A Controller, Service and DAO Example with Spring Boot and JSF](https://www.baeldung.com/jsf-spring-boot-controller-service-dao)
-- [Setting Up Swagger 2 with a Spring REST API](https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api)
+- [Setting Up Swagger 2 with a Spring REST API Using Springfox](https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api)
- [Using Spring ResponseEntity to Manipulate the HTTP Response](https://www.baeldung.com/spring-response-entity)
- [The @ServletComponentScan Annotation in Spring Boot](https://www.baeldung.com/spring-servletcomponentscan)
- [Guide to Internationalization in Spring Boot](https://www.baeldung.com/spring-boot-internationalization)
diff --git a/spring-boot-modules/spring-boot-properties-migrator-demo/pom.xml b/spring-boot-modules/spring-boot-properties-migrator-demo/pom.xml
index d44a8ce6f1..95dc06b155 100644
--- a/spring-boot-modules/spring-boot-properties-migrator-demo/pom.xml
+++ b/spring-boot-modules/spring-boot-properties-migrator-demo/pom.xml
@@ -1,9 +1,8 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
-
spring-boot-properties-migrator-demo
1.0-SNAPSHOT
@@ -13,18 +12,13 @@
1.0.0-SNAPSHOT
../pom.xml
-
-
-
-
-
-
-
-
-
- 8
- 8
-
+
+
+
+
+
+
+
@@ -54,4 +48,9 @@
-
+
+ 8
+ 8
+
+
+
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadIntegrationTest.java b/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadManualTest.java
similarity index 99%
rename from spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadIntegrationTest.java
rename to spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadManualTest.java
index 0c28cb085b..88e22af4ba 100644
--- a/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadIntegrationTest.java
+++ b/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadManualTest.java
@@ -24,7 +24,7 @@ import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SpringBootPropertiesTestApplication.class)
-public class PropertiesReloadIntegrationTest {
+public class PropertiesReloadManualTest {
protected MockMvc mvc;
diff --git a/spring-boot-modules/spring-boot-springdoc/README.md b/spring-boot-modules/spring-boot-springdoc/README.md
index 4ac4147da6..5daca79bd2 100644
--- a/spring-boot-modules/spring-boot-springdoc/README.md
+++ b/spring-boot-modules/spring-boot-springdoc/README.md
@@ -4,3 +4,4 @@
- [Spring REST Docs vs OpenAPI](https://www.baeldung.com/spring-rest-docs-vs-openapi)
- [Hiding Endpoints From Swagger Documentation in Spring Boot](https://www.baeldung.com/spring-swagger-hiding-endpoints)
- [Swagger @Api Description Is Deprecated](https://www.baeldung.com/java-swagger-api-description-deprecated)
+- [Set List of Objects in Swagger API Response](https://www.baeldung.com/java-swagger-set-list-response)
diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/README.md b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/README.md
deleted file mode 100644
index a7ff3285ee..0000000000
--- a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### Relevant Articles:
-
-- [Set List of Objects in Swagger API Response](https://www.baeldung.com/java-swagger-set-list-response)
diff --git a/spring-boot-modules/spring-boot-validation/pom.xml b/spring-boot-modules/spring-boot-validation/pom.xml
index 639a62059d..1412a57e2a 100644
--- a/spring-boot-modules/spring-boot-validation/pom.xml
+++ b/spring-boot-modules/spring-boot-validation/pom.xml
@@ -22,7 +22,7 @@
org.hibernate.validator
hibernate-validator
-
+
org.springframework.boot
spring-boot-starter-data-jpa
diff --git a/spring-boot-rest-2/README.md b/spring-boot-rest-2/README.md
deleted file mode 100644
index 985aa97a86..0000000000
--- a/spring-boot-rest-2/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-### Relevant Article:
-
-- [Get All Endpoints in Spring Boot](https://www.baeldung.com/spring-boot-get-all-endpoints)
-- [HTTP PUT vs. POST in REST API](https://www.baeldung.com/rest-http-put-vs-post)
-- [415 Unsupported MediaType in Spring Application](https://www.baeldung.com/spring-415-unsupported-mediatype)
diff --git a/spring-boot-rest-2/pom.xml b/spring-boot-rest-2/pom.xml
deleted file mode 100644
index b75e93577a..0000000000
--- a/spring-boot-rest-2/pom.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
- 4.0.0
- com.baeldung.web
- spring-boot-rest-2
- spring-boot-rest-2
- war
- Spring Boot Rest Module
-
-
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../parent-boot-2
-
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-actuator
-
-
- io.springfox
- springfox-boot-starter
- ${springfox.version}
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
-
-
- com.h2database
- h2
- runtime
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
-
- 3.0.0
-
-
-
\ No newline at end of file
diff --git a/spring-boot-rest-2/src/main/resources/application.properties b/spring-boot-rest-2/src/main/resources/application.properties
deleted file mode 100644
index 5046c9660f..0000000000
--- a/spring-boot-rest-2/src/main/resources/application.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-
-management.endpoints.web.exposure.include=mappings
diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml
index 9205416cd5..f58e1aec5c 100644
--- a/spring-cloud/pom.xml
+++ b/spring-cloud/pom.xml
@@ -92,4 +92,4 @@
3.1.3
-
+
\ No newline at end of file
diff --git a/spring-di-3/README.md b/spring-di-3/README.md
index 4246069616..3ddd720af5 100644
--- a/spring-di-3/README.md
+++ b/spring-di-3/README.md
@@ -6,4 +6,5 @@ This module contains articles about dependency injection with Spring
- [@Lookup Annotation in Spring](https://www.baeldung.com/spring-lookup)
- [Spring @Autowired Field Null – Common Causes and Solutions](https://www.baeldung.com/spring-autowired-field-null)
+- [Finding All Beans with a Custom Annotation](https://www.baeldung.com/spring-injecting-all-annotated-beans)
- More articles: [[<-- prev]](../spring-di-2)
diff --git a/spring-reactive/pom.xml b/spring-reactive/pom.xml
index 37df1a820d..396fa3ee4a 100644
--- a/spring-reactive/pom.xml
+++ b/spring-reactive/pom.xml
@@ -59,7 +59,6 @@
integration-lite-first
-
@@ -76,7 +75,6 @@
integration-lite-second
-
diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsUnitTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsUnitTest.java
deleted file mode 100644
index ff59f12391..0000000000
--- a/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsUnitTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package com.baeldung.reactive.webclientrequests;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.web.reactive.function.client.ClientRequest;
-import org.springframework.web.reactive.function.client.ClientResponse;
-import org.springframework.web.reactive.function.client.ExchangeFunction;
-import org.springframework.web.reactive.function.client.WebClient;
-import org.springframework.web.util.DefaultUriBuilderFactory;
-import reactor.core.publisher.Mono;
-
-import java.time.Duration;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-@RunWith(SpringRunner.class)
-@WebFluxTest
-public class WebClientRequestsUnitTest {
-
- private static final String BASE_URL = "https://example.com";
-
- private WebClient webClient;
-
- @Captor
- private ArgumentCaptor argumentCaptor;
-
- private ExchangeFunction exchangeFunction;
-
- @Before
- public void init() {
- MockitoAnnotations.initMocks(this);
- this.exchangeFunction = mock(ExchangeFunction.class);
- ClientResponse mockResponse = mock(ClientResponse.class);
- when(this.exchangeFunction.exchange(this.argumentCaptor.capture())).thenReturn(Mono.just(mockResponse));
- this.webClient = WebClient
- .builder()
- .baseUrl(BASE_URL)
- .exchangeFunction(exchangeFunction)
- .build();
- }
-
- @Test
- public void whenCallSimpleURI_thenURIMatched() {
- this.webClient.get()
- .uri("/products")
- .exchange()
- .block(Duration.ofSeconds(1));
- verifyCalledUrl("/products");
- }
-
- @Test
- public void whenCallSinglePathSegmentUri_thenURIMatched() {
- this.webClient.get()
- .uri(uriBuilder -> uriBuilder
- .path("/products/{id}")
- .build(2))
- .exchange()
- .block(Duration.ofSeconds(1));
- verifyCalledUrl("/products/2");
- }
-
- @Test
- public void whenCallMultiplePathSegmentsUri_thenURIMatched() {
- this.webClient.get()
- .uri(uriBuilder -> uriBuilder
- .path("/products/{id}/attributes/{attributeId}")
- .build(2, 13))
- .exchange()
- .block(Duration.ofSeconds(1));
- verifyCalledUrl("/products/2/attributes/13");
- }
-
- @Test
- public void whenCallSingleQueryParams_thenURIMatched() {
- this.webClient.get()
- .uri(uriBuilder -> uriBuilder
- .path("/products/")
- .queryParam("name", "AndroidPhone")
- .queryParam("color", "black")
- .queryParam("deliveryDate", "13/04/2019")
- .build())
- .exchange()
- .block(Duration.ofSeconds(1));
- verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019");
- }
-
- @Test
- public void whenCallSingleQueryParamsPlaceholders_thenURIMatched() {
- this.webClient.get()
- .uri(uriBuilder -> uriBuilder
- .path("/products/")
- .queryParam("name", "{title}")
- .queryParam("color", "{authorId}")
- .queryParam("deliveryDate", "{date}")
- .build("AndroidPhone", "black", "13/04/2019"))
- .exchange()
- .block(Duration.ofSeconds(1));
- verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13%2F04%2F2019");
- }
-
- @Test
- public void whenCallArrayQueryParamsBrackets_thenURIMatched() {
- this.webClient.get()
- .uri(uriBuilder -> uriBuilder
- .path("/products/")
- .queryParam("tag[]", "Snapdragon", "NFC")
- .build())
- .exchange()
- .block(Duration.ofSeconds(1));
- verifyCalledUrl("/products/?tag%5B%5D=Snapdragon&tag%5B%5D=NFC");
- }
-
-
- @Test
- public void whenCallArrayQueryParams_thenURIMatched() {
- this.webClient.get()
- .uri(uriBuilder -> uriBuilder
- .path("/products/")
- .queryParam("category", "Phones", "Tablets")
- .build())
- .exchange()
- .block(Duration.ofSeconds(1));
- verifyCalledUrl("/products/?category=Phones&category=Tablets");
- }
-
- @Test
- public void whenCallArrayQueryParamsComma_thenURIMatched() {
- this.webClient.get()
- .uri(uriBuilder -> uriBuilder
- .path("/products/")
- .queryParam("category", String.join(",", "Phones", "Tablets"))
- .build())
- .exchange()
- .block(Duration.ofSeconds(1));
- verifyCalledUrl("/products/?category=Phones,Tablets");
- }
-
- @Test
- public void whenUriComponentEncoding_thenQueryParamsNotEscaped() {
- DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(BASE_URL);
- factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.URI_COMPONENT);
- this.webClient = WebClient
- .builder()
- .uriBuilderFactory(factory)
- .baseUrl(BASE_URL)
- .exchangeFunction(exchangeFunction)
- .build();
- this.webClient.get()
- .uri(uriBuilder -> uriBuilder
- .path("/products/")
- .queryParam("name", "AndroidPhone")
- .queryParam("color", "black")
- .queryParam("deliveryDate", "13/04/2019")
- .build())
- .exchange()
- .block(Duration.ofSeconds(1));
- verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019");
- }
-
- private void verifyCalledUrl(String relativeUrl) {
- ClientRequest request = this.argumentCaptor.getValue();
- Assert.assertEquals(String.format("%s%s", BASE_URL, relativeUrl), request.url().toString());
- Mockito.verify(this.exchangeFunction).exchange(request);
- verifyNoMoreInteractions(this.exchangeFunction);
- }
-}
diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsWithParametersUnitTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsWithParametersUnitTest.java
new file mode 100644
index 0000000000..eefde078e1
--- /dev/null
+++ b/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsWithParametersUnitTest.java
@@ -0,0 +1,194 @@
+package com.baeldung.reactive.webclientrequests;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.web.reactive.function.client.ClientRequest;
+import org.springframework.web.reactive.function.client.ClientResponse;
+import org.springframework.web.reactive.function.client.ExchangeFunction;
+import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.util.DefaultUriBuilderFactory;
+import reactor.core.publisher.Mono;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+@RunWith(SpringRunner.class)
+@WebFluxTest
+public class WebClientRequestsWithParametersUnitTest {
+
+ private static final String BASE_URL = "https://example.com";
+
+ private WebClient webClient;
+
+ @Captor
+ private ArgumentCaptor argumentCaptor;
+
+ @Mock
+ private ExchangeFunction exchangeFunction;
+
+ @Before
+ public void init() {
+ ClientResponse mockResponse = mock(ClientResponse.class);
+ when(mockResponse.bodyToMono(String.class)).thenReturn(Mono.just("test"));
+ when(exchangeFunction.exchange(argumentCaptor.capture())).thenReturn(Mono.just(mockResponse));
+
+ webClient = WebClient
+ .builder()
+ .baseUrl(BASE_URL)
+ .exchangeFunction(exchangeFunction)
+ .build();
+ }
+
+ @Test
+ public void whenCallSimpleURI_thenURIMatched() {
+ webClient.get()
+ .uri("/products")
+ .retrieve()
+ .bodyToMono(String.class)
+ .block();
+
+ verifyCalledUrl("/products");
+ }
+
+ @Test
+ public void whenCallSinglePathSegmentUri_thenURIMatched() {
+ webClient.get()
+ .uri(uriBuilder -> uriBuilder
+ .path("/products/{id}")
+ .build(2))
+ .retrieve()
+ .bodyToMono(String.class)
+ .block();
+
+ verifyCalledUrl("/products/2");
+ }
+
+ @Test
+ public void whenCallMultiplePathSegmentsUri_thenURIMatched() {
+ webClient.get()
+ .uri(uriBuilder -> uriBuilder
+ .path("/products/{id}/attributes/{attributeId}")
+ .build(2, 13))
+ .retrieve()
+ .bodyToMono(String.class)
+ .block();
+
+ verifyCalledUrl("/products/2/attributes/13");
+ }
+
+ @Test
+ public void whenCallSingleQueryParams_thenURIMatched() {
+ webClient.get()
+ .uri(uriBuilder -> uriBuilder
+ .path("/products/")
+ .queryParam("name", "AndroidPhone")
+ .queryParam("color", "black")
+ .queryParam("deliveryDate", "13/04/2019")
+ .build())
+ .retrieve()
+ .bodyToMono(String.class)
+ .block();
+
+ verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019");
+ }
+
+ @Test
+ public void whenCallSingleQueryParamsPlaceholders_thenURIMatched() {
+ webClient.get()
+ .uri(uriBuilder -> uriBuilder
+ .path("/products/")
+ .queryParam("name", "{title}")
+ .queryParam("color", "{authorId}")
+ .queryParam("deliveryDate", "{date}")
+ .build("AndroidPhone", "black", "13/04/2019"))
+ .retrieve()
+ .bodyToMono(String.class)
+ .block();
+
+ verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13%2F04%2F2019");
+ }
+
+ @Test
+ public void whenCallArrayQueryParamsBrackets_thenURIMatched() {
+ webClient.get()
+ .uri(uriBuilder -> uriBuilder
+ .path("/products/")
+ .queryParam("tag[]", "Snapdragon", "NFC")
+ .build())
+ .retrieve()
+ .bodyToMono(String.class)
+ .block();
+
+ verifyCalledUrl("/products/?tag%5B%5D=Snapdragon&tag%5B%5D=NFC");
+ }
+
+ @Test
+ public void whenCallArrayQueryParams_thenURIMatched() {
+ webClient.get()
+ .uri(uriBuilder -> uriBuilder
+ .path("/products/")
+ .queryParam("category", "Phones", "Tablets")
+ .build())
+ .retrieve()
+ .bodyToMono(String.class)
+ .block();
+
+ verifyCalledUrl("/products/?category=Phones&category=Tablets");
+ }
+
+ @Test
+ public void whenCallArrayQueryParamsComma_thenURIMatched() {
+ webClient.get()
+ .uri(uriBuilder -> uriBuilder
+ .path("/products/")
+ .queryParam("category", String.join(",", "Phones", "Tablets"))
+ .build())
+ .retrieve()
+ .bodyToMono(String.class)
+ .block();
+
+ verifyCalledUrl("/products/?category=Phones,Tablets");
+ }
+
+ @Test
+ public void whenUriComponentEncoding_thenQueryParamsNotEscaped() {
+ DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(BASE_URL);
+ factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.URI_COMPONENT);
+ webClient = WebClient
+ .builder()
+ .uriBuilderFactory(factory)
+ .baseUrl(BASE_URL)
+ .exchangeFunction(exchangeFunction)
+ .build();
+
+ webClient.get()
+ .uri(uriBuilder -> uriBuilder
+ .path("/products/")
+ .queryParam("name", "AndroidPhone")
+ .queryParam("color", "black")
+ .queryParam("deliveryDate", "13/04/2019")
+ .build())
+ .retrieve()
+ .bodyToMono(String.class)
+ .block();
+
+ verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019");
+ }
+
+ private void verifyCalledUrl(String relativeUrl) {
+ ClientRequest request = argumentCaptor.getValue();
+ assertEquals(String.format("%s%s", BASE_URL, relativeUrl), request.url().toString());
+
+ verify(exchangeFunction).exchange(request);
+ verifyNoMoreInteractions(exchangeFunction);
+ }
+}
diff --git a/spring-roo/pom.xml b/spring-roo/pom.xml
index ea42095d92..fa84ec9558 100644
--- a/spring-roo/pom.xml
+++ b/spring-roo/pom.xml
@@ -18,6 +18,190 @@
+
+
+
+
+ org.springframework.roo
+ org.springframework.roo.annotations
+ ${roo.version}
+ pom
+ provided
+
+
+ io.springlets
+ springlets-data-jpa
+ ${springlets.version}
+
+
+ io.springlets
+ springlets-data-commons
+ ${springlets.version}
+
+
+ io.springlets
+ springlets-context
+ ${springlets.version}
+
+
+ org.springframework.roo
+ org.springframework.roo.querydsl.processor
+ ${querydsl-processor.version}
+
+
+ io.tracee.binding
+ tracee-springmvc
+ ${tracee.version}
+
+
+ io.springlets
+ springlets-boot-starter-web
+ ${springlets.version}
+
+
+ com.github.mxab.thymeleaf.extras
+ thymeleaf-extras-data-attribute
+ ${thymeleaf-data-dialect.version}
+
+
+ ar.com.fdvs
+ DynamicJasper
+ ${dynamicjasper.version}
+
+
+ ar.com.fdvs
+ DynamicJasper-core-fonts
+ ${dynamicjasper-fonts.version}
+
+
+ org.webjars.bower
+ bootstrap
+ ${bootstrap.version}
+
+
+ org.webjars.bower
+ datatables
+ ${datatables.version}
+
+
+ org.webjars.bower
+ datatables.net-bs
+ ${datatables-bs.version}
+
+
+ org.webjars.bower
+ datatables.net-buttons
+ ${datatables-buttons.version}
+
+
+ org.webjars.bower
+ datatables.net-buttons-bs
+ ${datatables-buttons-bs.version}
+
+
+ org.webjars.bower
+ datatables.net-responsive
+ ${datatables-responsive.version}
+
+
+ org.webjars.bower
+ datatables.net-responsive-bs
+ ${datatables-responsive-bs.version}
+
+
+ org.webjars.bower
+ datatables.net-select
+ ${datatables-select.version}
+
+
+ org.webjars.bower
+ datatables.net-select-bs
+ ${datatables-select-bs.version}
+
+
+ org.webjars.npm
+ jquery-datatables-checkboxes
+ ${datatables-checkboxes.version}
+
+
+ org.webjars.npm
+ jquery
+
+
+ org.webjars.npm
+ datatables.net
+
+
+
+
+ org.webjars.bower
+ github-com-julmot-datatables-mark-js
+ ${datatables-mark.version}
+
+
+ org.webjars.bower
+ datetimepicker
+ ${datetimepicker.version}
+
+
+ org.webjars.bower
+ font-awesome
+ ${fontawesome.version}
+
+
+ org.webjars.bower
+ jquery
+ ${jquery.version}
+
+
+ org.webjars
+ jquery.inputmask
+ ${jquery-inputmask.version}
+
+
+ org.webjars
+ jquery
+
+
+
+
+ org.webjars.bower
+ jquery-validation
+ ${jquery-validation.version}
+
+
+ org.webjars.bower
+ momentjs
+ ${momentjs.version}
+
+
+ org.webjars.bower
+ select2
+ ${select2.version}
+
+
+ org.webjars.bower
+ select2-bootstrap-theme
+ ${select2-bootstrap-theme.version}
+
+
+ org.webjars
+ respond
+ ${respond.version}
+
+
+ org.webjars
+ html5shiv
+ ${html5shiv.version}
+
+
+ org.webjars.bower
+ ie10-viewport-bug-workaround
+ ${bootstrap.ie10-viewport-bug-workaround.version}
+
+
+
+
@@ -404,190 +588,6 @@
-
-
-
-
- org.springframework.roo
- org.springframework.roo.annotations
- ${roo.version}
- pom
- provided
-
-
- io.springlets
- springlets-data-jpa
- ${springlets.version}
-
-
- io.springlets
- springlets-data-commons
- ${springlets.version}
-
-
- io.springlets
- springlets-context
- ${springlets.version}
-
-
- org.springframework.roo
- org.springframework.roo.querydsl.processor
- ${querydsl-processor.version}
-
-
- io.tracee.binding
- tracee-springmvc
- ${tracee.version}
-
-
- io.springlets
- springlets-boot-starter-web
- ${springlets.version}
-
-
- com.github.mxab.thymeleaf.extras
- thymeleaf-extras-data-attribute
- ${thymeleaf-data-dialect.version}
-
-
- ar.com.fdvs
- DynamicJasper
- ${dynamicjasper.version}
-
-
- ar.com.fdvs
- DynamicJasper-core-fonts
- ${dynamicjasper-fonts.version}
-
-
- org.webjars.bower
- bootstrap
- ${bootstrap.version}
-
-
- org.webjars.bower
- datatables
- ${datatables.version}
-
-
- org.webjars.bower
- datatables.net-bs
- ${datatables-bs.version}
-
-
- org.webjars.bower
- datatables.net-buttons
- ${datatables-buttons.version}
-
-
- org.webjars.bower
- datatables.net-buttons-bs
- ${datatables-buttons-bs.version}
-
-
- org.webjars.bower
- datatables.net-responsive
- ${datatables-responsive.version}
-
-
- org.webjars.bower
- datatables.net-responsive-bs
- ${datatables-responsive-bs.version}
-
-
- org.webjars.bower
- datatables.net-select
- ${datatables-select.version}
-
-
- org.webjars.bower
- datatables.net-select-bs
- ${datatables-select-bs.version}
-
-
- org.webjars.npm
- jquery-datatables-checkboxes
- ${datatables-checkboxes.version}
-
-
- org.webjars.npm
- jquery
-
-
- org.webjars.npm
- datatables.net
-
-
-
-
- org.webjars.bower
- github-com-julmot-datatables-mark-js
- ${datatables-mark.version}
-
-
- org.webjars.bower
- datetimepicker
- ${datetimepicker.version}
-
-
- org.webjars.bower
- font-awesome
- ${fontawesome.version}
-
-
- org.webjars.bower
- jquery
- ${jquery.version}
-
-
- org.webjars
- jquery.inputmask
- ${jquery-inputmask.version}
-
-
- org.webjars
- jquery
-
-
-
-
- org.webjars.bower
- jquery-validation
- ${jquery-validation.version}
-
-
- org.webjars.bower
- momentjs
- ${momentjs.version}
-
-
- org.webjars.bower
- select2
- ${select2.version}
-
-
- org.webjars.bower
- select2-bootstrap-theme
- ${select2-bootstrap-theme.version}
-
-
- org.webjars
- respond
- ${respond.version}
-
-
- org.webjars
- html5shiv
- ${html5shiv.version}
-
-
- org.webjars.bower
- ie10-viewport-bug-workaround
- ${bootstrap.ie10-viewport-bug-workaround.version}
-
-
-
-
2.0.0.RELEASE
8
diff --git a/spring-security-modules/pom.xml b/spring-security-modules/pom.xml
index bb36909c79..eb643c78c7 100644
--- a/spring-security-modules/pom.xml
+++ b/spring-security-modules/pom.xml
@@ -22,6 +22,7 @@
spring-security-acl
spring-security-auth0
spring-security-core
+ spring-security-core-2
spring-security-ldap
spring-security-legacy-oidc
spring-security-oauth2-sso
diff --git a/spring-security-modules/spring-security-core-2/.gitignore b/spring-security-modules/spring-security-core-2/.gitignore
new file mode 100644
index 0000000000..9f970225ad
--- /dev/null
+++ b/spring-security-modules/spring-security-core-2/.gitignore
@@ -0,0 +1 @@
+target/
\ No newline at end of file
diff --git a/spring-security-modules/spring-security-core-2/README.md b/spring-security-modules/spring-security-core-2/README.md
new file mode 100644
index 0000000000..9ce12af8ef
--- /dev/null
+++ b/spring-security-modules/spring-security-core-2/README.md
@@ -0,0 +1,10 @@
+## Spring Security Core
+
+This module contains articles about core Spring Security
+
+### Relevant Articles:
+- [Handle Spring Security Exceptions](https://www.baeldung.com/spring-security-exceptions)
+
+### Build the Project
+
+`mvn clean install`
diff --git a/spring-security-modules/spring-security-core-2/pom.xml b/spring-security-modules/spring-security-core-2/pom.xml
new file mode 100644
index 0000000000..cf150bfd42
--- /dev/null
+++ b/spring-security-modules/spring-security-core-2/pom.xml
@@ -0,0 +1,103 @@
+
+
+ 4.0.0
+ spring-security-core-2
+ 0.1-SNAPSHOT
+ spring-security-core-2
+ war
+
+
+ com.baeldung
+ parent-boot-2
+ 0.0.1-SNAPSHOT
+ ../../parent-boot-2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-devtools
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.springframework.security
+ spring-security-test
+
+
+
+
+ spring-security-core
+
+
+ src/main/resources
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+
+
+
+
+
+ live
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ integration-test
+
+ test
+
+
+
+ none
+
+
+ **/*LiveTest.java
+
+
+ cargo
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/AppInitializer.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/AppInitializer.java
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/AppInitializer.java
rename to spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/AppInitializer.java
diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/AccessDeniedController.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/AccessDeniedController.java
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/AccessDeniedController.java
rename to spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/AccessDeniedController.java
diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/CustomErrorController.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/CustomErrorController.java
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/CustomErrorController.java
rename to spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/CustomErrorController.java
diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/HomeController.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/HomeController.java
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/HomeController.java
rename to spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/HomeController.java
diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/SecuredResourceController.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/SecuredResourceController.java
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/SecuredResourceController.java
rename to spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/SecuredResourceController.java
diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAccessDeniedHandler.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAccessDeniedHandler.java
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAccessDeniedHandler.java
rename to spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAccessDeniedHandler.java
diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationFailureHandler.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationFailureHandler.java
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationFailureHandler.java
rename to spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationFailureHandler.java
diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationSuccessHandler.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationSuccessHandler.java
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationSuccessHandler.java
rename to spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationSuccessHandler.java
diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/SecurityConfig.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/SecurityConfig.java
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/SecurityConfig.java
rename to spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/SecurityConfig.java
diff --git a/spring-security-modules/spring-security-core/src/main/resources/application.properties b/spring-security-modules/spring-security-core-2/src/main/resources/application.properties
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/resources/application.properties
rename to spring-security-modules/spring-security-core-2/src/main/resources/application.properties
diff --git a/spring-security-modules/spring-security-core/src/main/resources/templates/admin.html b/spring-security-modules/spring-security-core-2/src/main/resources/templates/admin.html
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/resources/templates/admin.html
rename to spring-security-modules/spring-security-core-2/src/main/resources/templates/admin.html
diff --git a/spring-security-modules/spring-security-core/src/main/resources/templates/denied.html b/spring-security-modules/spring-security-core-2/src/main/resources/templates/denied.html
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/resources/templates/denied.html
rename to spring-security-modules/spring-security-core-2/src/main/resources/templates/denied.html
diff --git a/spring-security-modules/spring-security-core/src/main/resources/templates/error.html b/spring-security-modules/spring-security-core-2/src/main/resources/templates/error.html
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/resources/templates/error.html
rename to spring-security-modules/spring-security-core-2/src/main/resources/templates/error.html
diff --git a/spring-security-modules/spring-security-core/src/main/resources/templates/index.html b/spring-security-modules/spring-security-core-2/src/main/resources/templates/index.html
similarity index 100%
rename from spring-security-modules/spring-security-core/src/main/resources/templates/index.html
rename to spring-security-modules/spring-security-core-2/src/main/resources/templates/index.html
diff --git a/spring-security-modules/spring-security-core/src/test/java/com/baeldung/exceptionhandler/SecurityConfigUnitTest.java b/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/exceptionhandler/SecurityConfigUnitTest.java
similarity index 100%
rename from spring-security-modules/spring-security-core/src/test/java/com/baeldung/exceptionhandler/SecurityConfigUnitTest.java
rename to spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/exceptionhandler/SecurityConfigUnitTest.java
diff --git a/spring-security-modules/spring-security-opa/README.md b/spring-security-modules/spring-security-opa/README.md
new file mode 100644
index 0000000000..d2c1652edb
--- /dev/null
+++ b/spring-security-modules/spring-security-opa/README.md
@@ -0,0 +1,4 @@
+
+### Relevant Articles:
+
+- [Spring Security Authorization with OPA](https://www.baeldung.com/spring-security-authorization-opa)
diff --git a/spring-security-modules/spring-security-opa/pom.xml b/spring-security-modules/spring-security-opa/pom.xml
index 6665c33db3..72b0574253 100644
--- a/spring-security-modules/spring-security-opa/pom.xml
+++ b/spring-security-modules/spring-security-opa/pom.xml
@@ -1,49 +1,48 @@
-
- 4.0.0
-
- com.baeldung
- parent-boot-2
- 0.0.1-SNAPSHOT
- ../../parent-boot-2
-
- spring-security-opa
- Spring Security with OPA authorization
+
+ 4.0.0
+ spring-security-opa
+ Spring Security with OPA authorization
+
+
+ com.baeldung
+ parent-boot-2
+ 0.0.1-SNAPSHOT
+ ../../parent-boot-2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.projectlombok
+ lombok
+
+
+ com.google.guava
+ guava
+ 31.0.1-jre
+
+
+ org.springframework.boot
+ spring-boot-devtools
+
+
+ org.springframework.security
+ spring-security-test
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
-
-
- org.springframework.boot
- spring-boot-starter-webflux
-
-
-
- org.springframework.boot
- spring-boot-starter-security
-
-
-
- org.projectlombok
- lombok
-
-
-
- com.google.guava
- guava
- 31.0.1-jre
-
-
-
- org.springframework.boot
- spring-boot-devtools
-
-
-
- org.springframework.security
- spring-security-test
-
-
- org.springframework.boot
- spring-boot-configuration-processor
- true
-
-
\ No newline at end of file
diff --git a/spring-security-modules/spring-security-saml/src/main/resources/application.properties b/spring-security-modules/spring-security-saml/src/main/resources/application.properties
index 1d93a12737..fd7798dda9 100644
--- a/spring-security-modules/spring-security-saml/src/main/resources/application.properties
+++ b/spring-security-modules/spring-security-saml/src/main/resources/application.properties
@@ -1,8 +1,9 @@
-saml.keystore.location=classpath:/saml/samlKeystore.jks
+saml.keystore.location=classpath:/saml/saml-keystore
# Password for Java keystore and item therein
saml.keystore.password=
saml.keystore.alias=
# SAML Entity ID extracted from top of SAML metadata file
saml.idp=
-saml.sp=http://localhost:8080/saml/metadata
\ No newline at end of file
+saml.sp=http://localhost:8080/saml/metadata
+spring.main.allow-circular-references=true
\ No newline at end of file
diff --git a/spring-security-modules/spring-security-web-boot-3/pom.xml b/spring-security-modules/spring-security-web-boot-3/pom.xml
index 5da993acd9..0984c25e07 100644
--- a/spring-security-modules/spring-security-web-boot-3/pom.xml
+++ b/spring-security-modules/spring-security-web-boot-3/pom.xml
@@ -1,6 +1,7 @@
-
+
4.0.0
spring-security-web-boot-3
0.0.1-SNAPSHOT
@@ -73,5 +74,4 @@
3.6.0
-
\ No newline at end of file
diff --git a/spring-security-modules/spring-security-web-login/pom.xml b/spring-security-modules/spring-security-web-login/pom.xml
index 346338cbcd..c2369abc14 100644
--- a/spring-security-modules/spring-security-web-login/pom.xml
+++ b/spring-security-modules/spring-security-web-login/pom.xml
@@ -118,7 +118,7 @@
runtime
-
+
org.springframework.boot
spring-boot-starter-test
${spring-boot.version}
@@ -136,11 +136,11 @@
${spring-security.version}
test
-
- org.apache.commons
- commons-lang3
- ${commons-lang3.version}
-
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+
diff --git a/spring-security-modules/spring-security-web-rest/README.md b/spring-security-modules/spring-security-web-rest/README.md
index fd1f86f6b8..5a94504762 100644
--- a/spring-security-modules/spring-security-web-rest/README.md
+++ b/spring-security-modules/spring-security-web-rest/README.md
@@ -9,7 +9,7 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com
### Relevant Articles:
-- [Setting Up Swagger 2 with a Spring REST API](https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api)
+- [Setting Up Swagger 2 with a Spring REST API Using Springfox](https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api)
- [Custom Error Message Handling for REST API](https://www.baeldung.com/global-error-handler-in-a-spring-rest-api)
- [Spring Security Context Propagation with @Async](https://www.baeldung.com/spring-security-async-principal-propagation)
- [Servlet 3 Async Support with Spring MVC and Spring Security](https://www.baeldung.com/spring-mvc-async-security)
diff --git a/spring-security-modules/spring-security-web-x509/spring-security-web-x509-basic-auth/pom.xml b/spring-security-modules/spring-security-web-x509/spring-security-web-x509-basic-auth/pom.xml
index 9598843b63..12153c91f2 100644
--- a/spring-security-modules/spring-security-web-x509/spring-security-web-x509-basic-auth/pom.xml
+++ b/spring-security-modules/spring-security-web-x509/spring-security-web-x509-basic-auth/pom.xml
@@ -21,7 +21,6 @@
org.springframework.boot
spring-boot-maven-plugin
-
org.apache.maven.plugins
maven-surefire-plugin
diff --git a/spring-security-modules/spring-security-web-x509/spring-security-web-x509-client-auth/pom.xml b/spring-security-modules/spring-security-web-x509/spring-security-web-x509-client-auth/pom.xml
index f310ab1e5c..f3ea2728f2 100644
--- a/spring-security-modules/spring-security-web-x509/spring-security-web-x509-client-auth/pom.xml
+++ b/spring-security-modules/spring-security-web-x509/spring-security-web-x509-client-auth/pom.xml
@@ -21,7 +21,6 @@
org.springframework.boot
spring-boot-maven-plugin
-
org.apache.maven.plugins
maven-surefire-plugin
diff --git a/spring-state-machine/pom.xml b/spring-state-machine/pom.xml
index bc2b67cc38..741361b3fa 100644
--- a/spring-state-machine/pom.xml
+++ b/spring-state-machine/pom.xml
@@ -18,6 +18,11 @@
spring-statemachine-core
${spring-statemachine-core.version}
+
+ org.springframework
+ spring-context
+ ${spring-context.version}
+
org.springframework
spring-test
@@ -32,7 +37,8 @@
- 1.2.3.RELEASE
+ 3.2.0
+ 5.3.19
4.3.7.RELEASE
1.7.0
diff --git a/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml b/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml
index 2afde0b07d..f125018fb0 100644
--- a/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml
+++ b/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml
@@ -9,13 +9,11 @@
jar
https://github.com/openapitools/openapi-generator
OpenAPI Java
-
scm:git:git@github.com:openapitools/openapi-generator.git
scm:git:git@github.com:openapitools/openapi-generator.git
https://github.com/openapitools/openapi-generator
-
Unlicense
@@ -23,7 +21,6 @@
repo
-
OpenAPI-Generator Contributors
diff --git a/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml b/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml
index 66e9d1dda2..c9ba912feb 100644
--- a/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml
+++ b/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml
@@ -8,13 +8,11 @@
jar
https://github.com/swagger-api/swagger-codegen
Swagger Java
-
scm:git:git@github.com:swagger-api/swagger-codegen.git
scm:git:git@github.com:swagger-api/swagger-codegen.git
https://github.com/swagger-api/swagger-codegen
-
Unlicense
@@ -22,7 +20,6 @@
repo
-
Swagger
diff --git a/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestmappingvalue/WelcomeController.java b/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestmappingvalue/WelcomeController.java
new file mode 100644
index 0000000000..bbc978ccd4
--- /dev/null
+++ b/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestmappingvalue/WelcomeController.java
@@ -0,0 +1,15 @@
+package com.baeldung.requestmappingvalue;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/${request.value}")
+public class WelcomeController {
+
+ @GetMapping
+ public String getWelcomeMessage() {
+ return "Welcome to Baeldung!";
+ }
+}
diff --git a/spring-web-modules/spring-mvc-basics-5/src/main/resources/application.properties b/spring-web-modules/spring-mvc-basics-5/src/main/resources/application.properties
index 935f91554b..61a0755b93 100644
--- a/spring-web-modules/spring-mvc-basics-5/src/main/resources/application.properties
+++ b/spring-web-modules/spring-mvc-basics-5/src/main/resources/application.properties
@@ -1 +1,2 @@
server.servlet.context-path=/spring-mvc-basics
+request.value=welcome
diff --git a/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestmappingvalue/WelcomeControllerUnitTest.java b/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestmappingvalue/WelcomeControllerUnitTest.java
new file mode 100644
index 0000000000..ac5140733b
--- /dev/null
+++ b/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestmappingvalue/WelcomeControllerUnitTest.java
@@ -0,0 +1,25 @@
+package com.baeldung.requestmappingvalue;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.web.servlet.MockMvc;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class WelcomeControllerUnitTest {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Test
+ public void whenUserAccessToWelcome_thenReturnOK() throws Exception {
+ this.mockMvc.perform(get("/welcome"))
+ .andExpect(status().isOk());
+ }
+
+}
\ No newline at end of file
diff --git a/spring-web-modules/spring-rest-http-2/README.md b/spring-web-modules/spring-rest-http-2/README.md
index bb9175db8c..2c1b1f76f7 100644
--- a/spring-web-modules/spring-rest-http-2/README.md
+++ b/spring-web-modules/spring-rest-http-2/README.md
@@ -11,4 +11,7 @@ The "REST With Spring 2" Classes: http://bit.ly/restwithspring
- [Setting a Request Timeout for a Spring REST API](https://www.baeldung.com/spring-rest-timeout)
- [Long Polling in Spring MVC](https://www.baeldung.com/spring-mvc-long-polling)
- [Guide to UriComponentsBuilder in Spring](https://www.baeldung.com/spring-uricomponentsbuilder)
+- [Get All Endpoints in Spring Boot](https://www.baeldung.com/spring-boot-get-all-endpoints)
+- [HTTP PUT vs. POST in REST API](https://www.baeldung.com/rest-http-put-vs-post)
+- [415 Unsupported MediaType in Spring Application](https://www.baeldung.com/spring-415-unsupported-mediatype)
- More articles: [[<-- prev]](../spring-rest-http)
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java
similarity index 100%
rename from spring-boot-rest-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java
similarity index 100%
rename from spring-boot-rest-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java
similarity index 100%
rename from spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java
similarity index 100%
rename from spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java
similarity index 100%
rename from spring-boot-rest-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/putvspost/Address.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/Address.java
similarity index 100%
rename from spring-boot-rest-2/src/main/java/com/baeldung/putvspost/Address.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/Address.java
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/putvspost/AddressController.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/AddressController.java
similarity index 100%
rename from spring-boot-rest-2/src/main/java/com/baeldung/putvspost/AddressController.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/AddressController.java
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/putvspost/AddressRepository.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/AddressRepository.java
similarity index 100%
rename from spring-boot-rest-2/src/main/java/com/baeldung/putvspost/AddressRepository.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/AddressRepository.java
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/putvspost/PutVsPostApplication.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/PutVsPostApplication.java
similarity index 100%
rename from spring-boot-rest-2/src/main/java/com/baeldung/putvspost/PutVsPostApplication.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/PutVsPostApplication.java
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java
similarity index 100%
rename from spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/unsupportedmediatype/User.java
similarity index 100%
rename from spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/unsupportedmediatype/User.java
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UserController.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/unsupportedmediatype/UserController.java
similarity index 100%
rename from spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UserController.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/unsupportedmediatype/UserController.java
diff --git a/spring-web-modules/spring-rest-http-2/src/main/resources/application.properties b/spring-web-modules/spring-rest-http-2/src/main/resources/application.properties
index ff4af943ec..3119ad188a 100644
--- a/spring-web-modules/spring-rest-http-2/src/main/resources/application.properties
+++ b/spring-web-modules/spring-rest-http-2/src/main/resources/application.properties
@@ -1 +1,2 @@
-spring.mvc.async.request-timeout=750
\ No newline at end of file
+spring.mvc.async.request-timeout=750
+management.endpoints.web.exposure.include=mappings
\ No newline at end of file
diff --git a/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java b/spring-web-modules/spring-rest-http-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java
similarity index 100%
rename from spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java
rename to spring-web-modules/spring-rest-http-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java
diff --git a/spring-web-modules/spring-rest-http-2/src/test/resources/application.properties b/spring-web-modules/spring-rest-http-2/src/test/resources/application.properties
index ff4af943ec..10ac1ab5fa 100644
--- a/spring-web-modules/spring-rest-http-2/src/test/resources/application.properties
+++ b/spring-web-modules/spring-rest-http-2/src/test/resources/application.properties
@@ -1 +1,2 @@
-spring.mvc.async.request-timeout=750
\ No newline at end of file
+spring.mvc.async.request-timeout=750
+spring.main.allow-bean-definition-overriding=true
diff --git a/spring-web-modules/spring-resttemplate/pom.xml b/spring-web-modules/spring-resttemplate/pom.xml
index e5a8ba5ea9..4abaac5628 100644
--- a/spring-web-modules/spring-resttemplate/pom.xml
+++ b/spring-web-modules/spring-resttemplate/pom.xml
@@ -37,12 +37,12 @@
org.springframework.boot
spring-boot-starter-test
-
+
au.com.dius
pact-jvm-provider-junit5_2.12
${pact.version}
-
-
+
+
au.com.dius
pact-jvm-consumer-junit5_2.12
${pact.version}
@@ -119,10 +119,10 @@
spring-test
- org.mockito
- mockito-junit-jupiter
- ${mockito.version}
- test
+ org.mockito
+ mockito-junit-jupiter
+ ${mockito.version}
+ test
diff --git a/testing-modules/junit-5-basics/pom.xml b/testing-modules/junit-5-basics/pom.xml
index e240efe514..a758d79069 100644
--- a/testing-modules/junit-5-basics/pom.xml
+++ b/testing-modules/junit-5-basics/pom.xml
@@ -15,12 +15,12 @@
-
- org.junit.platform
- junit-platform-suite
- ${junit-platform.version}
+
+ org.junit.platform
+ junit-platform-suite
+ ${junit-platform.version}
test
-
+
org.junit.jupiter
junit-jupiter-migrationsupport
diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml
index f794c3990f..047eddcbcb 100644
--- a/testing-modules/junit-5/pom.xml
+++ b/testing-modules/junit-5/pom.xml
@@ -32,12 +32,6 @@
junit-platform-engine
${junit-platform.version}
-
- org.junit.platform
- junit-platform-runner
- ${junit-platform.version}
- test
-
org.junit.platform
junit-platform-console-standalone
diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java
index e13b4e24be..6aa3dd4a7f 100644
--- a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java
+++ b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java
@@ -3,14 +3,15 @@ package com.baeldung.junit5.mockito;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.junit.platform.runner.JUnitPlatform;
-import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
@@ -25,7 +26,6 @@ import com.baeldung.junit5.mockito.service.Errors;
import com.baeldung.junit5.mockito.service.UserService;
@ExtendWith(MockitoExtension.class)
-@RunWith(JUnitPlatform.class)
public class UserServiceUnitTest {
UserService userService;
diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/param/PersonValidatorUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/param/PersonValidatorUnitTest.java
index 3db44c9d63..ce9b188afa 100644
--- a/testing-modules/junit-5/src/test/java/com/baeldung/param/PersonValidatorUnitTest.java
+++ b/testing-modules/junit-5/src/test/java/com/baeldung/param/PersonValidatorUnitTest.java
@@ -8,10 +8,7 @@ import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.junit.platform.runner.JUnitPlatform;
-import org.junit.runner.RunWith;
-@RunWith(JUnitPlatform.class)
@DisplayName("Testing PersonValidator")
public class PersonValidatorUnitTest {
diff --git a/testing-modules/testng-command-line/pom.xml b/testing-modules/testng-command-line/pom.xml
index efc49b187d..a71238f4fb 100644
--- a/testing-modules/testng-command-line/pom.xml
+++ b/testing-modules/testng-command-line/pom.xml
@@ -78,7 +78,6 @@
-
ExecuteTestSuite
@@ -101,6 +100,7 @@
+
UTF-8
1.8
@@ -112,4 +112,5 @@
3.8.0
2.22.1
-
+
+
\ No newline at end of file