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[] 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[] 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[] 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[] 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