diff --git a/.gitignore b/.gitignore index 7f1bab3751..7725bf202e 100644 --- a/.gitignore +++ b/.gitignore @@ -69,6 +69,7 @@ jmeter/src/main/resources/*-Basic*.csv jmeter/src/main/resources/*-JMeter*.csv jmeter/src/main/resources/*ReportsDashboard*.csv jmeter/src/main/resources/dashboard/*ReportsDashboard*.csv +jmeter/src/main/resources/*FileExtractionExample.csv ninja/devDb.mv.db @@ -88,6 +89,7 @@ spring-soap/src/main/java/com/baeldung/springsoap/gen/ /report-*.json transaction.log *-shell.log +customers.xml apache-cxf/cxf-aegis/baeldung.xml testing-modules/report-*.json @@ -102,6 +104,7 @@ spring-boot-modules/spring-boot-react/frontend/build spring-boot-modules/spring-boot-react/frontend/node spring-boot-modules/spring-boot-react/frontend/yarn.lock spring-boot-modules/spring-boot-properties-3/*.log +spring-boot-modules/spring-boot-properties-3/*.gz # SDKMan .sdkmanrc @@ -114,4 +117,7 @@ libraries-2/employee* libraries-2/src/test/resources/crawler4j/** #web-modules/ninja -devDb*.db \ No newline at end of file +devDb*.db + +#jaxb +*.xjb \ No newline at end of file diff --git a/akka-modules/akka-http/pom.xml b/akka-modules/akka-http/pom.xml index 3af7c492ca..9372107fc9 100644 --- a/akka-modules/akka-http/pom.xml +++ b/akka-modules/akka-http/pom.xml @@ -36,7 +36,6 @@ - 10.0.11 2.5.11 diff --git a/algorithms-modules/algorithms-miscellaneous-7/README.md b/algorithms-modules/algorithms-miscellaneous-7/README.md index 918fcd21dd..ab07d655f9 100644 --- a/algorithms-modules/algorithms-miscellaneous-7/README.md +++ b/algorithms-modules/algorithms-miscellaneous-7/README.md @@ -1,4 +1,6 @@ ### Relevant Articles: - [Algorithm to Identify and Validate a Credit Card Number](https://www.baeldung.com/java-validate-cc-number) +- [Find the N Most Frequent Elements in a Java Array](https://www.baeldung.com/java-n-most-frequent-elements-array) +- [Getting Pixel Array From Image in Java](https://www.baeldung.com/java-getting-pixel-array-from-image) - More articles: [[<-- prev]](/algorithms-miscellaneous-6) diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/pixelarray/GetPixelArray.java b/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/pixelarray/GetPixelArray.java new file mode 100644 index 0000000000..ba7fe44808 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/pixelarray/GetPixelArray.java @@ -0,0 +1,65 @@ +package com.baeldung.algorithms.pixelarray; + +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferByte; +public class GetPixelArray { + + public static int[][] get2DPixelArraySlow(BufferedImage sampleImage) { + int width = sampleImage.getWidth(); + int height = sampleImage.getHeight(); + int[][] result = new int[height][width]; + + for (int row = 0; row < height; row++) { + for (int col = 0; col < width; col++) { + result[row][col] = sampleImage.getRGB(col, row); + } + } + + return result; + } + + public static int[][] get2DPixelArrayFast(BufferedImage image) { + final byte[] pixelData = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); + final int width = image.getWidth(); + final int height = image.getHeight(); + final boolean hasAlphaChannel = image.getAlphaRaster() != null; + + int[][] result = new int[height][width]; + if (hasAlphaChannel) { + final int numberOfValues = 4; + for (int valueIndex = 0, row = 0, col = 0; valueIndex + numberOfValues - 1 < pixelData.length; valueIndex += numberOfValues) { + // Getting the values for each pixel from the pixelData array. + int argb = 0; + argb += (((int) pixelData[valueIndex] & 0xff) << 24); // alpha value + argb += ((int) pixelData[valueIndex + 1] & 0xff); // blue value + argb += (((int) pixelData[valueIndex + 2] & 0xff) << 8); // green value + argb += (((int) pixelData[valueIndex + 3] & 0xff) << 16); // red value + result[row][col] = argb; + + col++; + if (col == width) { + col = 0; + row++; + } + } + } else { + final int numberOfValues = 3; + for (int valueIndex = 0, row = 0, col = 0; valueIndex + numberOfValues - 1 < pixelData.length; valueIndex += numberOfValues) { + int argb = 0; + argb += -16777216; // 255 alpha value (fully opaque) + argb += ((int) pixelData[valueIndex] & 0xff); // blue value + argb += (((int) pixelData[valueIndex + 1] & 0xff) << 8); // green value + argb += (((int) pixelData[valueIndex + 2] & 0xff) << 16); // red value + result[row][col] = argb; + + col++; + if (col == width) { + col = 0; + row++; + } + } + } + + return result; + } +} \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/pixelarray/GetPixelArrayUnitTest.java b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/pixelarray/GetPixelArrayUnitTest.java new file mode 100644 index 0000000000..b7bbb462dd --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/pixelarray/GetPixelArrayUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.algorithms.pixelarray; + +import static com.baeldung.algorithms.pixelarray.GetPixelArray.get2DPixelArrayFast; +import static com.baeldung.algorithms.pixelarray.GetPixelArray.get2DPixelArraySlow; +import static org.junit.Assert.*; + +import org.junit.Test; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.Arrays; + +public class GetPixelArrayUnitTest { + @Test + public void givenImage_whenGetPixelArray_thenBothMethodsReturnEqualValues() { + BufferedImage sampleImage = null; + try { + sampleImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg")); + } catch (IOException e) { + throw new RuntimeException(e); + } + + int[][] firstResult = get2DPixelArraySlow(sampleImage); + int[][] secondResult = get2DPixelArrayFast(sampleImage); + + assertTrue(Arrays.deepEquals(firstResult, secondResult)); + } +} diff --git a/annotations/annotation-processing/pom.xml b/annotations/annotation-processing/pom.xml index 2a17242ee5..14bbc409e5 100644 --- a/annotations/annotation-processing/pom.xml +++ b/annotations/annotation-processing/pom.xml @@ -21,7 +21,6 @@ - 1.0-rc2 diff --git a/apache-httpclient-2/README.md b/apache-httpclient-2/README.md index 45f1e41637..a19112476b 100644 --- a/apache-httpclient-2/README.md +++ b/apache-httpclient-2/README.md @@ -12,6 +12,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Reading an HTTP Response Body as a String in Java](https://www.baeldung.com/java-http-response-body-as-string) - [How To Get Cookies From the Apache HttpClient Response](https://www.baeldung.com/java-apache-httpclient-cookies) - [Enabling Logging for Apache HttpClient](https://www.baeldung.com/apache-httpclient-enable-logging) -- [Expand Shortened URLs with Apache HttpClient](https://www.baeldung.com/apache-httpclient-expand-url) - [Apache HttpClient vs. CloseableHttpClient](https://www.baeldung.com/apache-httpclient-vs-closeablehttpclient) +- [Expand Shortened URLs with Apache HttpClient](https://www.baeldung.com/apache-httpclient-expand-url) - More articles: [[<-- prev]](../apache-httpclient) diff --git a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/expandUrl/HttpClientExpandUrlLiveTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/expandUrl/HttpClientExpandUrlLiveTest.java new file mode 100644 index 0000000000..c1bb5bdddb --- /dev/null +++ b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/expandUrl/HttpClientExpandUrlLiveTest.java @@ -0,0 +1,126 @@ +package com.baeldung.httpclient.expandUrl; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + +import java.io.IOException; +import java.util.List; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; + +import org.apache.hc.client5.http.classic.methods.HttpHead; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; + +import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HttpHeaders; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class HttpClientExpandUrlLiveTest { + + private static CloseableHttpClient httpClient; + + @BeforeAll + static void setup() { + httpClient = HttpClientBuilder.create() + .disableRedirectHandling() + .build(); + } + + @AfterAll + static void tearDown() throws IOException { + if (httpClient != null) { + httpClient.close(); + } + } + + @Test + void givenShortenedOnce_whenUrlIsExpanded_thenCorrectResult() throws IOException { + final String expectedResult = "https://www.baeldung.com/rest-versioning"; + final String actualResult = expandSingleLevel("http://bit.ly/3LScTri"); + assertThat(actualResult, equalTo(expectedResult)); + } + + @Test + void givenShortenedMultiple_whenUrlIsExpanded_thenCorrectResult() throws IOException { + final String expectedResult = "https://www.baeldung.com/rest-versioning"; + final String actualResult = expand("http://t.co/e4rDDbnzmk"); + assertThat(actualResult, equalTo(expectedResult)); + } + + private String expand(final String urlArg) throws IOException { + String originalUrl = urlArg; + String newUrl = expandSingleLevel(originalUrl); + while (!originalUrl.equals(newUrl)) { + originalUrl = newUrl; + newUrl = expandSingleLevel(originalUrl); + } + + return newUrl; + } + + final String expandSafe(final String urlArg) throws IOException { + String originalUrl = urlArg; + String newUrl = expandSingleLevelSafe(originalUrl).getRight(); + final List alreadyVisited = Lists.newArrayList(originalUrl, newUrl); + while (!originalUrl.equals(newUrl)) { + originalUrl = newUrl; + final Pair statusAndUrl = expandSingleLevelSafe(originalUrl); + newUrl = statusAndUrl.getRight(); + final boolean isRedirect = statusAndUrl.getLeft() == 301 || statusAndUrl.getLeft() == 302; + if (isRedirect && alreadyVisited.contains(newUrl)) { + throw new IllegalStateException("Likely a redirect loop"); + } + alreadyVisited.add(newUrl); + } + + return newUrl; + } + + private Pair expandSingleLevelSafe(final String url) throws IOException { + try { + HttpHead request = new HttpHead(url); + Pair resp = httpClient.execute(request, response -> { + final int statusCode = response.getCode(); + if (statusCode != 301 && statusCode != 302) { + return new ImmutablePair<>(statusCode, url); + } + final Header[] headers = response.getHeaders(HttpHeaders.LOCATION); + Preconditions.checkState(headers.length == 1); + final String newUrl = headers[0].getValue(); + + return new ImmutablePair<>(statusCode, newUrl); + }); + return resp; + } catch (final IllegalArgumentException uriEx) { + return new ImmutablePair<>(500, url); + } + } + + private String expandSingleLevel(final String url) throws IOException { + try { + HttpHead request = new HttpHead(url); + String expandedUrl = httpClient.execute(request, response -> { + final int statusCode = response.getCode(); + if (statusCode != 301 && statusCode != 302) { + return url; + } + final Header[] headers = response.getHeaders(HttpHeaders.LOCATION); + Preconditions.checkState(headers.length == 1); + + return headers[0].getValue(); + }); + return expandedUrl; + } catch (final IllegalArgumentException uriEx) { + return url; + } + } + +} diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientCancelRequestLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientCancelRequestLiveTest.java new file mode 100644 index 0000000000..d19e0e1d86 --- /dev/null +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientCancelRequestLiveTest.java @@ -0,0 +1,40 @@ +package com.baeldung.httpclient; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; + +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.HttpStatus; +import org.junit.jupiter.api.Test; + +class HttpClientCancelRequestLiveTest { + + private static final String SAMPLE_URL = "http://www.github.com"; + + @Test + void whenRequestIsCanceled_thenCorrect() throws IOException { + HttpGet request = new HttpGet(SAMPLE_URL); + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + httpClient.execute(request, response -> { + HttpEntity entity = response.getEntity(); + + System.out.println("----------------------------------------"); + System.out.println(response.getCode()); + if (entity != null) { + System.out.println("Response content length: " + entity.getContentLength()); + } + System.out.println("----------------------------------------"); + // Do not feel like reading the response body + // Call abort on the request object + request.abort(); + + assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK); + return response; + }); + } + } +} diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientLiveTest.java index ef12c37412..4173909f7d 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientLiveTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientLiveTest.java @@ -1,8 +1,8 @@ package com.baeldung.httpclient.base; import com.baeldung.httpclient.ResponseUtil; + import org.apache.http.Header; -import org.apache.http.HttpEntity; import org.apache.http.HttpHeaders; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; @@ -10,7 +10,6 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.BasicHttpClientConnectionManager; import org.junit.After; import org.junit.Before; @@ -73,30 +72,4 @@ public class HttpClientLiveTest { assertThat(headers, not(emptyArray())); } - // tests - cancel request - - @Test - public final void whenRequestIsCanceled_thenCorrect() throws IOException { - instance = HttpClients.custom().build(); - final HttpGet request = new HttpGet(SAMPLE_URL); - response = instance.execute(request); - - try { - final HttpEntity entity = response.getEntity(); - - System.out.println("----------------------------------------"); - System.out.println(response.getStatusLine()); - if (entity != null) { - System.out.println("Response content length: " + entity.getContentLength()); - } - System.out.println("----------------------------------------"); - - // Do not feel like reading the response body - // Call abort on the request object - request.abort(); - } finally { - response.close(); - } - } - } diff --git a/apache-httpclient4/README.md b/apache-httpclient4/README.md index dff63a5cc1..22b0391e6b 100644 --- a/apache-httpclient4/README.md +++ b/apache-httpclient4/README.md @@ -4,11 +4,13 @@ This module contains articles about Apache HttpClient 4.5 ### Relevant Articles +- [Apache HttpClient – Cancel Request](https://www.baeldung.com/httpclient-cancel-request) - [Apache HttpClient with SSL](https://www.baeldung.com/httpclient-ssl) - [Apache HttpClient Timeout](https://www.baeldung.com/httpclient-timeout) - [Custom HTTP Header with the Apache HttpClient](https://www.baeldung.com/httpclient-custom-http-header) - [Apache HttpClient vs. CloseableHttpClient](https://www.baeldung.com/apache-httpclient-vs-closeablehttpclient) - [Expand Shortened URLs with Apache HttpClient](https://www.baeldung.com/apache-httpclient-expand-url) +- [Retrying Requests using Apache HttpClient](https://www.baeldung.com/java-retrying-requests-using-apache-httpclient) ### Running the Tests To run the live tests, use the command: mvn clean install -Plive diff --git a/apache-httpclient4/pom.xml b/apache-httpclient4/pom.xml index 1485c94c8c..e0bf9dd5f6 100644 --- a/apache-httpclient4/pom.xml +++ b/apache-httpclient4/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-httpclient4 0.1-SNAPSHOT diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCancelRequestV4LiveTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCancelRequestV4LiveTest.java new file mode 100644 index 0000000000..226a7b8cf7 --- /dev/null +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCancelRequestV4LiveTest.java @@ -0,0 +1,57 @@ +package com.baeldung.httpclient; + +import java.io.IOException; + +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class HttpClientCancelRequestV4LiveTest { + + private static final String SAMPLE_URL = "http://www.github.com"; + + private CloseableHttpClient instance; + + private CloseableHttpResponse response; + + @Before + public final void before() { + instance = HttpClientBuilder.create().build(); + } + + @After + public final void after() throws IllegalStateException, IOException { + ResponseUtil.closeResponse(response); + } + + @Test + public final void whenRequestIsCanceled_thenCorrect() throws IOException { + instance = HttpClients.custom().build(); + final HttpGet request = new HttpGet(SAMPLE_URL); + response = instance.execute(request); + + try { + final HttpEntity entity = response.getEntity(); + + System.out.println("----------------------------------------"); + System.out.println(response.getStatusLine()); + if (entity != null) { + System.out.println("Response content length: " + entity.getContentLength()); + } + System.out.println("----------------------------------------"); + + // Do not feel like reading the response body + // Call abort on the request object + request.abort(); + } finally { + response.close(); + } + } +} diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/retry/ApacheHttpClientRetryLiveTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/retry/ApacheHttpClientRetryLiveTest.java new file mode 100644 index 0000000000..3a8ff252c2 --- /dev/null +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/retry/ApacheHttpClientRetryLiveTest.java @@ -0,0 +1,168 @@ +package com.baeldung.httpclient.retry; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.IOException; +import java.net.URI; +import java.net.UnknownHostException; +import java.util.Objects; + +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPatch; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; +import org.apache.http.impl.client.HttpClientBuilder; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class ApacheHttpClientRetryLiveTest { + + private Integer requestCounter; + private CloseableHttpClient httpClient; + + @BeforeEach + void setUp() { + requestCounter = 0; + } + + @AfterEach + void tearDown() throws IOException { + if (httpClient != null) { + httpClient.close(); + } + } + + private void createDefaultApacheHttpClient() { + this.httpClient = HttpClientBuilder + .create() + .addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> { + requestCounter++; + }).build(); + } + + private void createFailingHttpClient() { + this.httpClient = HttpClientBuilder + .create() + .addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> requestCounter++) + .addInterceptorLast((HttpResponseInterceptor) (httpResponse, httpContext) -> { + throw new IOException(); + }) + .build(); + } + + private void createHttpClientWithRetryHandler() { + this.httpClient = HttpClientBuilder + .create() + .addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> requestCounter++) + .addInterceptorLast((HttpResponseInterceptor) (httpRequest, httpContext) -> { throw new IOException(); }) + .setRetryHandler(new DefaultHttpRequestRetryHandler(6, true)) + .build(); + } + + private void createHttpClientWithCustomRetryHandler() { + this.httpClient = HttpClientBuilder + .create() + .addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> requestCounter++) + .addInterceptorLast((HttpResponseInterceptor) (httpRequest, httpContext) -> { throw new IOException(); }) + .setRetryHandler((exception, executionCount, context) -> { + if (executionCount < 5 && Objects.equals("GET", ((HttpClientContext) context).getRequest().getRequestLine().getMethod())) { + return true; + } else { + return false; + } + }) + .build(); + } + + private void createHttpClientWithRetriesDisabled() { + this.httpClient = HttpClientBuilder + .create() + .addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> requestCounter++) + .addInterceptorLast((HttpResponseInterceptor) (httpRequest, httpContext) -> { throw new IOException(); }) + .disableAutomaticRetries() + .build(); + } + + @Test + public void givenDefaultConfiguration_whenReceivedIOException_thenRetriesPerformed() { + createFailingHttpClient(); + assertThrows(IOException.class, () -> httpClient.execute(new HttpGet("https://httpstat.us/200"))); + assertThat(requestCounter).isEqualTo(4); + } + + @Test + public void givenDefaultConfiguration_whenDomainNameNotResolved_thenNoRetryApplied() { + createDefaultApacheHttpClient(); + HttpGet request = new HttpGet(URI.create("http://domain.that.does.not.exist:80/api/v1")); + + assertThrows(UnknownHostException.class, () -> httpClient.execute(request)); + assertThat(requestCounter).isEqualTo(1); + } + + @Test + public void givenDefaultConfiguration_whenGotInternalServerError_thenNoRetryLogicApplied() throws IOException { + createDefaultApacheHttpClient(); + HttpGet request = new HttpGet(URI.create("https://httpstat.us/500")); + + CloseableHttpResponse response = assertDoesNotThrow(() -> httpClient.execute(request)); + assertThat(response.getStatusLine().getStatusCode()).isEqualTo(500); + assertThat(requestCounter).isEqualTo(1); + response.close(); + } + + @Test + public void givenDefaultConfiguration_whenHttpPatchRequest_thenRetryIsNotApplied() { + createFailingHttpClient(); + HttpPatch request = new HttpPatch(URI.create("https://httpstat.us/500")); + + assertThrows(IOException.class, () -> httpClient.execute(request)); + assertThat(requestCounter).isEqualTo(1); + } + + @Test + public void givenDefaultConfiguration_whenHttpPutRequest_thenRetryIsNotApplied() { + createFailingHttpClient(); + HttpPut request = new HttpPut(URI.create("https://httpstat.us/500")); + + assertThrows(IOException.class, () -> httpClient.execute(request)); + assertThat(requestCounter).isEqualTo(1); + } + + @Test + public void givenConfiguredRetryHandler_whenHttpPostRequest_thenRetriesPerformed() { + createHttpClientWithRetryHandler(); + + HttpPost request = new HttpPost(URI.create("https://httpstat.us/200")); + + assertThrows(IOException.class, () -> httpClient.execute(request)); + assertThat(requestCounter).isEqualTo(7); + } + + @Test + public void givenCustomRetryHandler_whenUnknownHostException_thenRetryAnyway() { + createHttpClientWithCustomRetryHandler(); + + HttpGet request = new HttpGet(URI.create("https://domain.that.does.not.exist/200")); + + assertThrows(IOException.class, () -> httpClient.execute(request)); + assertThat(requestCounter).isEqualTo(5); + } + + @Test + public void givenDisabledRetries_whenExecutedHttpRequestEndUpWithIOException_thenRetryIsNotApplied() { + createHttpClientWithRetriesDisabled(); + HttpGet request = new HttpGet(URI.create("https://httpstat.us/200")); + + assertThrows(IOException.class, () -> httpClient.execute(request)); + assertThat(requestCounter).isEqualTo(1); + } +} diff --git a/apache-kafka-2/README.md b/apache-kafka-2/README.md index ec9e8e2adc..157078f023 100644 --- a/apache-kafka-2/README.md +++ b/apache-kafka-2/README.md @@ -7,3 +7,4 @@ You can build the project from the command line using: *mvn clean install*, or i ### Relevant Articles: - [Guide to Check if Apache Kafka Server Is Running](https://www.baeldung.com/apache-kafka-check-server-is-running) +- [Add Custom Headers to a Kafka Message](https://www.baeldung.com/java-kafka-custom-headers) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/headers/KafkaMessageHeaders.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/headers/KafkaMessageHeaders.java new file mode 100644 index 0000000000..2c8c14bfc5 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/headers/KafkaMessageHeaders.java @@ -0,0 +1,88 @@ +package com.baeldung.kafka.headers; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.header.Header; +import org.apache.kafka.common.header.Headers; +import org.apache.kafka.common.header.internals.RecordHeader; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class KafkaMessageHeaders { + + private static Logger logger = LoggerFactory.getLogger(KafkaMessageHeaders.class); + + private static String TOPIC = "baeldung"; + private static String MESSAGE_KEY = "message"; + private static String MESSAGE_VALUE = "Hello World"; + private static String HEADER_KEY = "website"; + private static String HEADER_VALUE = "baeldung.com"; + + private static KafkaProducer producer; + private static KafkaConsumer consumer; + + public static void main(String[] args) { + setup(); + + publishMessageWithCustomHeaders(); + + consumeMessageWithCustomHeaders(); + } + + private static void consumeMessageWithCustomHeaders() { + consumer.subscribe(Arrays.asList(TOPIC)); + + ConsumerRecords records = consumer.poll(Duration.ofMinutes(1)); + for (ConsumerRecord record : records) { + logger.info(record.key()); + logger.info(record.value()); + + Headers headers = record.headers(); + for (Header header : headers) { + logger.info(header.key()); + logger.info(new String(header.value())); + } + } + } + + private static void publishMessageWithCustomHeaders() { + List
headers = new ArrayList<>(); + headers.add(new RecordHeader(HEADER_KEY, HEADER_VALUE.getBytes())); + + ProducerRecord record1 = new ProducerRecord<>(TOPIC, null, MESSAGE_KEY, MESSAGE_VALUE, headers); + producer.send(record1); + + ProducerRecord record2 = new ProducerRecord<>(TOPIC, null, System.currentTimeMillis(), MESSAGE_KEY, MESSAGE_VALUE, headers); + producer.send(record2); + } + + private static void setup() { + Properties producerProperties = new Properties(); + producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + + Properties consumerProperties = new Properties(); + consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "ConsumerGroup1"); + + producer = new KafkaProducer<>(producerProperties); + consumer = new KafkaConsumer<>(consumerProperties); + } + +} diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/KafaConsumeLastNMessages.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/KafaConsumeLastNMessages.java new file mode 100644 index 0000000000..94f5907525 --- /dev/null +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/KafaConsumeLastNMessages.java @@ -0,0 +1,138 @@ +package com.baeldung.kafka; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.TopicPartition; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.ExecutionException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Testcontainers +public class KafaConsumeLastNMessages { + + private static String TOPIC1 = "baeldung-github"; + private static String TOPIC2 = "baeldung-blog"; + private static String MESSAGE_KEY = "message"; + private static KafkaProducer producer; + private static KafkaConsumer consumer; + private static KafkaProducer transactionalProducer; + + @Container + private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + + @BeforeAll + static void setup() { + KAFKA_CONTAINER.addExposedPort(9092); + + Properties producerProperties = new Properties(); + producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + + Properties consumerProperties = new Properties(); + consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "ConsumerGroup1"); + + Properties transactionalProducerProprieties = new Properties(); + transactionalProducerProprieties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + transactionalProducerProprieties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + transactionalProducerProprieties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + transactionalProducerProprieties.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true"); + transactionalProducerProprieties.put(ProducerConfig.TRANSACTIONAL_ID_CONFIG, "prod-0"); + + producer = new KafkaProducer<>(producerProperties); + consumer = new KafkaConsumer<>(consumerProperties); + transactionalProducer = new KafkaProducer<>(transactionalProducerProprieties); + } + + @AfterAll + static void destroy() { + KAFKA_CONTAINER.stop(); + } + + @Test + void whenSeekingKafkaTopicCursorToEnd_consumerRetrievesOnlyDesiredNumberOfMessages() throws ExecutionException, InterruptedException { + int messagesInTopic = 100; + int messagesToRetrieve = 20; + + for (int i = 0; i < messagesInTopic; i++) { + producer.send(new ProducerRecord<>(TOPIC1, null, MESSAGE_KEY, String.valueOf(i))) + .get(); + } + + TopicPartition partition = new TopicPartition(TOPIC1, 0); + List partitions = new ArrayList<>(); + partitions.add(partition); + consumer.assign(partitions); + + consumer.seekToEnd(partitions); + long startIndex = consumer.position(partition) - messagesToRetrieve; + consumer.seek(partition, startIndex); + + ConsumerRecords records = consumer.poll(Duration.ofMinutes(1)); + int recordsReceived = 0; + for (ConsumerRecord record : records) { + assertEquals(MESSAGE_KEY, record.key()); + assertTrue(Integer.parseInt(record.value()) >= (messagesInTopic - messagesToRetrieve)); + recordsReceived++; + } + + assertEquals(messagesToRetrieve, recordsReceived); + } + + @Test + void havingTransactionalProducer_whenSeekingKafkaTopicCursorToEnd_consumerRetrievesLessMessages() throws ExecutionException, InterruptedException { + int messagesInTopic = 100; + int messagesToRetrieve = 20; + + transactionalProducer.initTransactions(); + for (int i = 0; i < messagesInTopic; i++) { + transactionalProducer.beginTransaction(); + transactionalProducer.send(new ProducerRecord<>(TOPIC2, null, MESSAGE_KEY, String.valueOf(i))) + .get(); + transactionalProducer.commitTransaction(); + } + + TopicPartition partition = new TopicPartition(TOPIC2, 0); + List partitions = new ArrayList<>(); + partitions.add(partition); + consumer.assign(partitions); + + consumer.seekToEnd(partitions); + long startIndex = consumer.position(partition) - messagesToRetrieve; + consumer.seek(partition, startIndex); + + ConsumerRecords records = consumer.poll(Duration.ofMinutes(1)); + int recordsReceived = 0; + for (ConsumerRecord record : records) { + assertEquals(MESSAGE_KEY, record.key()); + assertTrue(Integer.parseInt(record.value()) >= (messagesInTopic - messagesToRetrieve)); + recordsReceived++; + } + + assertTrue(messagesToRetrieve > recordsReceived); + } + +} diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/headers/KafkaMessageHeadersLiveTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/headers/KafkaMessageHeadersLiveTest.java new file mode 100644 index 0000000000..42cc572e07 --- /dev/null +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/headers/KafkaMessageHeadersLiveTest.java @@ -0,0 +1,104 @@ +package com.baeldung.kafka.headers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.apache.kafka.common.header.Header; +import org.apache.kafka.common.header.Headers; +import org.apache.kafka.common.header.internals.RecordHeader; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +// This live test needs a Docker Daemon running so that a kafka container can be created + +@Testcontainers +public class KafkaMessageHeadersLiveTest { + + private static String TOPIC = "baeldung"; + private static String MESSAGE_KEY = "message"; + private static String MESSAGE_VALUE = "Hello World"; + private static String HEADER_KEY = "website"; + private static String HEADER_VALUE = "baeldung.com"; + + private static KafkaProducer producer; + private static KafkaConsumer consumer; + + @Container + private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + + @BeforeAll + static void setup() { + KAFKA_CONTAINER.addExposedPort(9092); + + Properties producerProperties = new Properties(); + producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + + Properties consumerProperties = new Properties(); + consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "ConsumerGroup1"); + + producer = new KafkaProducer<>(producerProperties); + consumer = new KafkaConsumer<>(consumerProperties); + } + + @AfterAll + static void destroy() { + KAFKA_CONTAINER.stop(); + } + + @Test + void givenAMessageWithCustomHeaders_whenPublishedToKafkaAndConsumed_thenCheckForCustomHeaders() throws ExecutionException, InterruptedException { + List
headers = new ArrayList<>(); + headers.add(new RecordHeader(HEADER_KEY, HEADER_VALUE.getBytes())); + + ProducerRecord record1 = new ProducerRecord<>(TOPIC, null, MESSAGE_KEY, MESSAGE_VALUE, headers); + Future future = producer.send(record1); + + RecordMetadata metadata = future.get(); + + assertNotNull(metadata); + + consumer.subscribe(Arrays.asList(TOPIC)); + + ConsumerRecords records = consumer.poll(Duration.ofMinutes(1)); + for (ConsumerRecord record : records) { + assertEquals(MESSAGE_KEY, record.key()); + assertEquals(MESSAGE_VALUE, record.value()); + + Headers consumedHeaders = record.headers(); + assertNotNull(consumedHeaders); + + for (Header header : consumedHeaders) { + assertEquals(HEADER_KEY, header.key()); + assertEquals(HEADER_VALUE, new String(header.value())); + } + } + } +} diff --git a/apache-kafka/pom.xml b/apache-kafka/pom.xml index 915583fed8..494bc94961 100644 --- a/apache-kafka/pom.xml +++ b/apache-kafka/pom.xml @@ -171,7 +171,8 @@ --add-opens java.base/java.time=ALL-UNNAMED - --add-opens java.base/java.nio=ALL-UNNAMED + --add-opens + java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED @@ -179,8 +180,6 @@ - - 3.4.0 1.15.3 diff --git a/apache-libraries/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java b/apache-libraries/src/test/java/com/baeldung/apache/beam/intro/WordCountIntegrationTest.java similarity index 91% rename from apache-libraries/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java rename to apache-libraries/src/test/java/com/baeldung/apache/beam/intro/WordCountIntegrationTest.java index 77287066ac..5d51d8e5fa 100644 --- a/apache-libraries/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java +++ b/apache-libraries/src/test/java/com/baeldung/apache/beam/intro/WordCountIntegrationTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import com.baeldung.apache.beam.intro.WordCount; -public class WordCountUnitTest { +public class WordCountIntegrationTest { @Test public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() { diff --git a/apache-poi/pom.xml b/apache-poi/pom.xml index 546eedec5b..78781cf215 100644 --- a/apache-poi/pom.xml +++ b/apache-poi/pom.xml @@ -30,6 +30,16 @@ + + org.dhatim + fastexcel + ${fastexcel.version} + + + org.dhatim + fastexcel-reader + ${fastexcel.version} + @@ -52,6 +62,7 @@ 5.2.0 1.0.6 + 0.15.3 3.2.0 diff --git a/apache-poi/src/main/java/com/baeldung/fastexcel/FastexcelHelper.java b/apache-poi/src/main/java/com/baeldung/fastexcel/FastexcelHelper.java new file mode 100644 index 0000000000..9d6041b66e --- /dev/null +++ b/apache-poi/src/main/java/com/baeldung/fastexcel/FastexcelHelper.java @@ -0,0 +1,63 @@ +package com.baeldung.fastexcel; + +import org.dhatim.fastexcel.Workbook; +import org.dhatim.fastexcel.Worksheet; +import org.dhatim.fastexcel.reader.Cell; +import org.dhatim.fastexcel.reader.ReadableWorkbook; +import org.dhatim.fastexcel.reader.Row; +import org.dhatim.fastexcel.reader.Sheet; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +public class FastexcelHelper { + + public Map> readExcel(String fileLocation) throws IOException { + Map> data = new HashMap<>(); + + try (FileInputStream file = new FileInputStream(fileLocation); ReadableWorkbook wb = new ReadableWorkbook(file)) { + Sheet sheet = wb.getFirstSheet(); + try (Stream rows = sheet.openStream()) { + rows.forEach(r -> { + data.put(r.getRowNum(), new ArrayList<>()); + + for (Cell cell : r) { + data.get(r.getRowNum()).add(cell.getRawValue()); + } + }); + } + } + + return data; + } + + public void writeExcel() throws IOException { + File currDir = new File("."); + String path = currDir.getAbsolutePath(); + String fileLocation = path.substring(0, path.length() - 1) + "fastexcel.xlsx"; + + try (OutputStream os = Files.newOutputStream(Paths.get(fileLocation)); Workbook wb = new Workbook(os, "MyApplication", "1.0")) { + Worksheet ws = wb.newWorksheet("Sheet 1"); + + ws.width(0, 25); + ws.width(1, 15); + + ws.range(0, 0, 0, 1).style().fontName("Arial").fontSize(16).bold().fillColor("3366FF").set(); + ws.value(0, 0, "Name"); + ws.value(0, 1, "Age"); + + ws.range(2, 0, 2, 1).style().wrapText(true).set(); + ws.value(2, 0, "John Smith"); + ws.value(2, 1, 20L); + } + } +} diff --git a/apache-poi/src/test/java/com/baeldung/fastexcel/FastexcelIntegrationTest.java b/apache-poi/src/test/java/com/baeldung/fastexcel/FastexcelIntegrationTest.java new file mode 100644 index 0000000000..a36c06e41f --- /dev/null +++ b/apache-poi/src/test/java/com/baeldung/fastexcel/FastexcelIntegrationTest.java @@ -0,0 +1,49 @@ +package com.baeldung.fastexcel; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class FastexcelIntegrationTest { + + private FastexcelHelper fastexcelHelper; + private static String FILE_NAME = "fastexcel.xlsx"; + private String fileLocation; + + @Before + public void generateExcelFile() throws IOException { + + File currDir = new File("."); + String path = currDir.getAbsolutePath(); + fileLocation = path.substring(0, path.length() - 1) + FILE_NAME; + + fastexcelHelper = new FastexcelHelper(); + fastexcelHelper.writeExcel(); + } + + @Test + public void whenParsingExcelFile_thenCorrect() throws IOException { + Map> data = fastexcelHelper.readExcel(fileLocation); + + assertEquals("Name", data.get(1).get(0)); + assertEquals("Age", data.get(1).get(1)); + + assertEquals("John Smith", data.get(3).get(0)); + assertEquals("20", data.get(3).get(1)); + } + + @After + public void cleanup() { + File testFile = new File(fileLocation); + if (testFile.exists()) { + testFile.delete(); + } + } +} diff --git a/apache-spark/pom.xml b/apache-spark/pom.xml index 9e61e1340d..b5e97ee03d 100644 --- a/apache-spark/pom.xml +++ b/apache-spark/pom.xml @@ -7,7 +7,6 @@ 1.0-SNAPSHOT apache-spark jar - http://maven.apache.org com.baeldung diff --git a/aws-modules/aws-lambda/.gitignore b/aws-modules/aws-lambda-modules/.gitignore similarity index 100% rename from aws-modules/aws-lambda/.gitignore rename to aws-modules/aws-lambda-modules/.gitignore diff --git a/aws-modules/aws-lambda/README.md b/aws-modules/aws-lambda-modules/README.md similarity index 100% rename from aws-modules/aws-lambda/README.md rename to aws-modules/aws-lambda-modules/README.md diff --git a/aws-modules/aws-lambda/lambda/pom.xml b/aws-modules/aws-lambda-modules/lambda-function/pom.xml similarity index 96% rename from aws-modules/aws-lambda/lambda/pom.xml rename to aws-modules/aws-lambda-modules/lambda-function/pom.xml index 8e47bab4be..9fff7d1d9a 100644 --- a/aws-modules/aws-lambda/lambda/pom.xml +++ b/aws-modules/aws-lambda-modules/lambda-function/pom.xml @@ -3,14 +3,14 @@ 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 - lambda + lambda-function 0.1.0-SNAPSHOT - lambda + lambda-function jar com.baeldung - aws-lambda + aws-lambda-modules 1.0.0-SNAPSHOT diff --git a/aws-modules/aws-lambda/lambda/sam-templates/template-implicit.yaml b/aws-modules/aws-lambda-modules/lambda-function/sam-templates/template-implicit.yaml similarity index 100% rename from aws-modules/aws-lambda/lambda/sam-templates/template-implicit.yaml rename to aws-modules/aws-lambda-modules/lambda-function/sam-templates/template-implicit.yaml diff --git a/aws-modules/aws-lambda/lambda/sam-templates/template-inline-swagger.yaml b/aws-modules/aws-lambda-modules/lambda-function/sam-templates/template-inline-swagger.yaml similarity index 100% rename from aws-modules/aws-lambda/lambda/sam-templates/template-inline-swagger.yaml rename to aws-modules/aws-lambda-modules/lambda-function/sam-templates/template-inline-swagger.yaml diff --git a/aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/LambdaMethodHandler.java b/aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/LambdaMethodHandler.java similarity index 100% rename from aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/LambdaMethodHandler.java rename to aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/LambdaMethodHandler.java diff --git a/aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/LambdaRequestHandler.java b/aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/LambdaRequestHandler.java similarity index 100% rename from aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/LambdaRequestHandler.java rename to aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/LambdaRequestHandler.java diff --git a/aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/LambdaRequestStreamHandler.java b/aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/LambdaRequestStreamHandler.java similarity index 100% rename from aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/LambdaRequestStreamHandler.java rename to aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/LambdaRequestStreamHandler.java diff --git a/aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/apigateway/APIDemoHandler.java b/aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/apigateway/APIDemoHandler.java similarity index 100% rename from aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/apigateway/APIDemoHandler.java rename to aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/apigateway/APIDemoHandler.java diff --git a/aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/apigateway/model/Person.java b/aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/apigateway/model/Person.java similarity index 100% rename from aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/apigateway/model/Person.java rename to aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/apigateway/model/Person.java diff --git a/aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/dynamodb/SavePersonHandler.java b/aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/dynamodb/SavePersonHandler.java similarity index 100% rename from aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/dynamodb/SavePersonHandler.java rename to aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/dynamodb/SavePersonHandler.java diff --git a/aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonRequest.java b/aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonRequest.java similarity index 100% rename from aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonRequest.java rename to aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonRequest.java diff --git a/aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonResponse.java b/aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonResponse.java similarity index 100% rename from aws-modules/aws-lambda/lambda/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonResponse.java rename to aws-modules/aws-lambda-modules/lambda-function/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonResponse.java diff --git a/aws-modules/aws-lambda/lambda/src/main/resources/logback.xml b/aws-modules/aws-lambda-modules/lambda-function/src/main/resources/logback.xml similarity index 100% rename from aws-modules/aws-lambda/lambda/src/main/resources/logback.xml rename to aws-modules/aws-lambda-modules/lambda-function/src/main/resources/logback.xml diff --git a/aws-modules/aws-lambda/pom.xml b/aws-modules/aws-lambda-modules/pom.xml similarity index 66% rename from aws-modules/aws-lambda/pom.xml rename to aws-modules/aws-lambda-modules/pom.xml index bdd295c007..9886ff58d2 100644 --- a/aws-modules/aws-lambda/pom.xml +++ b/aws-modules/aws-lambda-modules/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - aws-lambda - aws-lambda + aws-lambda-modules + aws-lambda-modules pom @@ -14,9 +14,9 @@ - lambda - shipping-tracker/ShippingFunction - todo-reminder/ToDoFunction + lambda-function + shipping-tracker-lambda/ShippingFunction + todo-reminder-lambda/ToDoFunction \ No newline at end of file diff --git a/aws-modules/aws-lambda/shipping-tracker/.gitignore b/aws-modules/aws-lambda-modules/shipping-tracker-lambda/.gitignore similarity index 100% rename from aws-modules/aws-lambda/shipping-tracker/.gitignore rename to aws-modules/aws-lambda-modules/shipping-tracker-lambda/.gitignore diff --git a/aws-modules/aws-lambda/shipping-tracker/ShippingFunction/pom.xml b/aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/pom.xml similarity index 96% rename from aws-modules/aws-lambda/shipping-tracker/ShippingFunction/pom.xml rename to aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/pom.xml index 24f2a76912..abd22ea50c 100644 --- a/aws-modules/aws-lambda/shipping-tracker/ShippingFunction/pom.xml +++ b/aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/pom.xml @@ -2,7 +2,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - com.baeldung ShippingFunction 1.0 ShippingFunction @@ -10,7 +9,7 @@ com.baeldung - aws-lambda + aws-lambda-modules 1.0.0-SNAPSHOT ../../ diff --git a/aws-modules/aws-lambda/shipping-tracker/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/App.java b/aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/App.java similarity index 100% rename from aws-modules/aws-lambda/shipping-tracker/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/App.java rename to aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/App.java diff --git a/aws-modules/aws-lambda/shipping-tracker/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/Checkin.java b/aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/Checkin.java similarity index 100% rename from aws-modules/aws-lambda/shipping-tracker/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/Checkin.java rename to aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/Checkin.java diff --git a/aws-modules/aws-lambda/shipping-tracker/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/Consignment.java b/aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/Consignment.java similarity index 100% rename from aws-modules/aws-lambda/shipping-tracker/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/Consignment.java rename to aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/Consignment.java diff --git a/aws-modules/aws-lambda/shipping-tracker/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/Item.java b/aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/Item.java similarity index 100% rename from aws-modules/aws-lambda/shipping-tracker/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/Item.java rename to aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/Item.java diff --git a/aws-modules/aws-lambda/shipping-tracker/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/ShippingDao.java b/aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/ShippingDao.java similarity index 100% rename from aws-modules/aws-lambda/shipping-tracker/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/ShippingDao.java rename to aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/ShippingDao.java diff --git a/aws-modules/aws-lambda/shipping-tracker/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/ShippingService.java b/aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/ShippingService.java similarity index 100% rename from aws-modules/aws-lambda/shipping-tracker/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/ShippingService.java rename to aws-modules/aws-lambda-modules/shipping-tracker-lambda/ShippingFunction/src/main/java/com/baeldung/lambda/shipping/ShippingService.java diff --git a/aws-modules/aws-lambda/shipping-tracker/template.yaml b/aws-modules/aws-lambda-modules/shipping-tracker-lambda/template.yaml similarity index 100% rename from aws-modules/aws-lambda/shipping-tracker/template.yaml rename to aws-modules/aws-lambda-modules/shipping-tracker-lambda/template.yaml diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/pom.xml b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml similarity index 92% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/pom.xml rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml index 0dd2e4d14a..04295e1ab1 100644 --- a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/pom.xml +++ b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml @@ -1,6 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 helloworld ToDoFunction @@ -8,6 +8,13 @@ ToDoFunction jar + + com.baeldung + aws-lambda-modules + 1.0.0-SNAPSHOT + ../../ + + com.amazonaws diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/App.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/App.java similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/App.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/App.java diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/PostApi.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/PostApi.java similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/PostApi.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/PostApi.java diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/PostItem.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/PostItem.java similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/PostItem.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/PostItem.java diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/ToDoApi.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/ToDoApi.java similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/ToDoApi.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/ToDoApi.java diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/ToDoItem.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/ToDoItem.java similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/ToDoItem.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/api/ToDoItem.java diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/Config.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/Config.java similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/Config.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/Config.java diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/Credentials.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/Credentials.java similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/Credentials.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/Credentials.java diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/ExecutionContext.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/ExecutionContext.java similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/ExecutionContext.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/ExecutionContext.java diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/Services.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/Services.java similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/Services.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/config/Services.java diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/service/PostService.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/service/PostService.java similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/service/PostService.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/service/PostService.java diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/service/ToDoReaderService.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/service/ToDoReaderService.java similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/java/com/baeldung/lambda/todo/service/ToDoReaderService.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/java/com/baeldung/lambda/todo/service/ToDoReaderService.java diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/resources/configuration.yml b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/resources/configuration.yml similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/resources/configuration.yml rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/resources/configuration.yml diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/resources/log4j2.xml b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/resources/log4j2.xml similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/main/resources/log4j2.xml rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/main/resources/log4j2.xml diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/test/java/com/baeldung/lambda/todo/AppTest.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/test/java/com/baeldung/lambda/todo/AppUnitTest.java similarity index 98% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/test/java/com/baeldung/lambda/todo/AppTest.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/test/java/com/baeldung/lambda/todo/AppUnitTest.java index cbdc8c22cb..952a773f69 100644 --- a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/test/java/com/baeldung/lambda/todo/AppTest.java +++ b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/test/java/com/baeldung/lambda/todo/AppUnitTest.java @@ -21,7 +21,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) -public class AppTest { +public class AppUnitTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mockContext; diff --git a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/test/java/com/baeldung/lambda/todo/service/ToDoReaderServiceTest.java b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/test/java/com/baeldung/lambda/todo/service/ToDoReaderServiceUnitTest.java similarity index 94% rename from aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/test/java/com/baeldung/lambda/todo/service/ToDoReaderServiceTest.java rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/test/java/com/baeldung/lambda/todo/service/ToDoReaderServiceUnitTest.java index 634c5257ff..dd5b52d073 100644 --- a/aws-modules/aws-lambda/todo-reminder/ToDoFunction/src/test/java/com/baeldung/lambda/todo/service/ToDoReaderServiceTest.java +++ b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/src/test/java/com/baeldung/lambda/todo/service/ToDoReaderServiceUnitTest.java @@ -7,7 +7,7 @@ import uk.org.webcompere.systemstubs.rules.SystemOutRule; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; -public class ToDoReaderServiceTest { +public class ToDoReaderServiceUnitTest { @Rule public SystemOutRule systemOutRule = new SystemOutRule(); diff --git a/aws-modules/aws-lambda/todo-reminder/template.yaml b/aws-modules/aws-lambda-modules/todo-reminder-lambda/template.yaml similarity index 100% rename from aws-modules/aws-lambda/todo-reminder/template.yaml rename to aws-modules/aws-lambda-modules/todo-reminder-lambda/template.yaml diff --git a/aws-modules/aws-s3/README.md b/aws-modules/aws-s3/README.md index efebf7d933..109a898405 100644 --- a/aws-modules/aws-s3/README.md +++ b/aws-modules/aws-s3/README.md @@ -6,4 +6,5 @@ This module contains articles about Simple Storage Service (S3) on AWS - [AWS S3 with Java](https://www.baeldung.com/aws-s3-java) - [Multipart Uploads in Amazon S3 with Java](https://www.baeldung.com/aws-s3-multipart-upload) -- [Using the JetS3t Java Client With Amazon S3](https://www.baeldung.com/jets3t-amazon-s3) \ No newline at end of file +- [Using the JetS3t Java Client With Amazon S3](https://www.baeldung.com/jets3t-amazon-s3) +- [Check if a Specified Key Exists in a Given S3 Bucket Using Java](https://www.baeldung.com/java-aws-s3-check-specified-key-exists) diff --git a/aws-modules/aws-s3/src/main/java/com/baeldung/s3/AWSS3ObjectUtils.java b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/AWSS3ObjectUtils.java new file mode 100644 index 0000000000..1c31218ff9 --- /dev/null +++ b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/AWSS3ObjectUtils.java @@ -0,0 +1,42 @@ +package com.baeldung.s3; + +import org.apache.http.HttpStatus; + +import com.amazonaws.AmazonServiceException; +import com.amazonaws.services.s3.AmazonS3; + +public class AWSS3ObjectUtils { + + private AmazonS3 s3Client; + + public AWSS3ObjectUtils(AmazonS3 s3client) { + this.s3Client = s3client; + } + + public boolean doesObjectExistByDefaultMethod(String bucket, String key) { + return s3Client.doesObjectExist(bucket, key); + } + + public boolean doesObjectExistByListObjects(String bucket, String key) { + return s3Client.listObjects(bucket) + .getObjectSummaries() + .stream() + .filter(s3ObjectSummary -> s3ObjectSummary.getKey() + .equals(key)) + .findFirst() + .isPresent(); + } + + public boolean doesObjectExistByMetaData(String bucket, String key) { + try { + s3Client.getObjectMetadata(bucket, key); + return true; + } catch (AmazonServiceException e) { + if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) { + return false; + } else { + throw e; + } + } + } +} \ No newline at end of file diff --git a/aws-modules/aws-s3/src/test/java/com/baeldung/s3/AWSS3ObjectManualTest.java b/aws-modules/aws-s3/src/test/java/com/baeldung/s3/AWSS3ObjectManualTest.java new file mode 100644 index 0000000000..02cc22367a --- /dev/null +++ b/aws-modules/aws-s3/src/test/java/com/baeldung/s3/AWSS3ObjectManualTest.java @@ -0,0 +1,49 @@ +package com.baeldung.s3; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.Before; +import org.junit.Test; + +import com.amazonaws.auth.EnvironmentVariableCredentialsProvider; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; + +/** + * Required defined environment variables AWS_ACCESS_KEY_ID & AWS_ACCESS_KEY to access S3. + * Required S3 bucket and key that exist. + */ + +public class AWSS3ObjectManualTest { + + private static final String BUCKET = "your-bucket"; + private static final String KEY_THAT_EXIST = "your-key-that-exist"; + private AWSS3ObjectUtils s3ObjectUtils; + + @Before + public void setUp() { + AmazonS3 client = AmazonS3ClientBuilder.standard() + .withRegion(Regions.DEFAULT_REGION) + .withCredentials(new EnvironmentVariableCredentialsProvider()) + .build(); + + s3ObjectUtils = new AWSS3ObjectUtils(client); + } + + @Test + public void whenVerifyIfObjectExistByDefaultMethod_thenCorrect() { + assertTrue(s3ObjectUtils.doesObjectExistByDefaultMethod(BUCKET, KEY_THAT_EXIST), "Key: " + KEY_THAT_EXIST + " doesn't exist"); + + } + + @Test + public void whenVerifyIfObjectExistByListObjects_thenCorrect() { + assertTrue(s3ObjectUtils.doesObjectExistByListObjects(BUCKET, KEY_THAT_EXIST), "Key: " + KEY_THAT_EXIST + " doesn't exist"); + } + + @Test + public void whenVerifyIfObjectExistByMetaData_thenCorrect() { + assertTrue(s3ObjectUtils.doesObjectExistByMetaData(BUCKET, KEY_THAT_EXIST), "Key: " + KEY_THAT_EXIST + " doesn't exist"); + } +} diff --git a/aws-modules/pom.xml b/aws-modules/pom.xml index 72c5017c32..02473815b5 100644 --- a/aws-modules/pom.xml +++ b/aws-modules/pom.xml @@ -15,7 +15,7 @@ aws-app-sync - aws-lambda + aws-lambda-modules aws-miscellaneous aws-reactive aws-s3 diff --git a/axon/pom.xml b/axon/pom.xml index 5c8f1d7a6c..5eed742aab 100644 --- a/axon/pom.xml +++ b/axon/pom.xml @@ -103,7 +103,8 @@ --add-opens java.base/java.util=ALL-UNNAMED - --add-opens java.base/java.util.concurrent=ALL-UNNAMED + --add-opens + java.base/java.util.concurrent=ALL-UNNAMED diff --git a/checker-plugin/README.md b/checker-framework/README.md similarity index 100% rename from checker-plugin/README.md rename to checker-framework/README.md diff --git a/checker-plugin/pom.xml b/checker-framework/pom.xml similarity index 97% rename from checker-plugin/pom.xml rename to checker-framework/pom.xml index 28958db89d..a348745343 100644 --- a/checker-plugin/pom.xml +++ b/checker-framework/pom.xml @@ -3,11 +3,10 @@ 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 - checker-plugin + checker-framework 1.0-SNAPSHOT - checker-plugin + checker-framework jar - http://maven.apache.org com.baeldung diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/FakeNumExample.java b/checker-framework/src/main/java/com/baeldung/typechecker/FakeNumExample.java similarity index 100% rename from checker-plugin/src/main/java/com/baeldung/typechecker/FakeNumExample.java rename to checker-framework/src/main/java/com/baeldung/typechecker/FakeNumExample.java diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/FormatExample.java b/checker-framework/src/main/java/com/baeldung/typechecker/FormatExample.java similarity index 100% rename from checker-plugin/src/main/java/com/baeldung/typechecker/FormatExample.java rename to checker-framework/src/main/java/com/baeldung/typechecker/FormatExample.java diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/KeyForExample.java b/checker-framework/src/main/java/com/baeldung/typechecker/KeyForExample.java similarity index 100% rename from checker-plugin/src/main/java/com/baeldung/typechecker/KeyForExample.java rename to checker-framework/src/main/java/com/baeldung/typechecker/KeyForExample.java diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/MonotonicNotNullExample.java b/checker-framework/src/main/java/com/baeldung/typechecker/MonotonicNotNullExample.java similarity index 100% rename from checker-plugin/src/main/java/com/baeldung/typechecker/MonotonicNotNullExample.java rename to checker-framework/src/main/java/com/baeldung/typechecker/MonotonicNotNullExample.java diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/NonNullExample.java b/checker-framework/src/main/java/com/baeldung/typechecker/NonNullExample.java similarity index 100% rename from checker-plugin/src/main/java/com/baeldung/typechecker/NonNullExample.java rename to checker-framework/src/main/java/com/baeldung/typechecker/NonNullExample.java diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/RegexExample.java b/checker-framework/src/main/java/com/baeldung/typechecker/RegexExample.java similarity index 100% rename from checker-plugin/src/main/java/com/baeldung/typechecker/RegexExample.java rename to checker-framework/src/main/java/com/baeldung/typechecker/RegexExample.java diff --git a/checker-plugin/src/main/resources/logback.xml b/checker-framework/src/main/resources/logback.xml similarity index 100% rename from checker-plugin/src/main/resources/logback.xml rename to checker-framework/src/main/resources/logback.xml diff --git a/clojure/ring/.gitignore b/clojure-modules/clojure-ring/.gitignore similarity index 100% rename from clojure/ring/.gitignore rename to clojure-modules/clojure-ring/.gitignore diff --git a/clojure/ring/README.md b/clojure-modules/clojure-ring/README.md similarity index 100% rename from clojure/ring/README.md rename to clojure-modules/clojure-ring/README.md diff --git a/clojure/ring/project.clj b/clojure-modules/clojure-ring/project.clj similarity index 100% rename from clojure/ring/project.clj rename to clojure-modules/clojure-ring/project.clj diff --git a/clojure/ring/src/ring/core.clj b/clojure-modules/clojure-ring/src/ring/core.clj similarity index 100% rename from clojure/ring/src/ring/core.clj rename to clojure-modules/clojure-ring/src/ring/core.clj diff --git a/core-groovy-modules/core-groovy-2/pom.xml b/core-groovy-modules/core-groovy-2/pom.xml index ca6a9a62c7..de750daf0f 100644 --- a/core-groovy-modules/core-groovy-2/pom.xml +++ b/core-groovy-modules/core-groovy-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-groovy-2 - 1.0-SNAPSHOT core-groovy-2 jar @@ -153,14 +152,6 @@ - - - maven_central - Maven Central - https://repo.maven.apache.org/maven2/ - - - 1.1.3 3.4.2 diff --git a/core-groovy-modules/core-groovy-collections/pom.xml b/core-groovy-modules/core-groovy-collections/pom.xml index 6d43ce7d18..08589f54e3 100644 --- a/core-groovy-modules/core-groovy-collections/pom.xml +++ b/core-groovy-modules/core-groovy-collections/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-groovy-collections - 1.0-SNAPSHOT core-groovy-collections jar @@ -111,13 +110,4 @@ - - - maven_central - Maven Central - https://repo.maven.apache.org/maven2/ - - - - diff --git a/core-groovy-modules/core-groovy-strings/pom.xml b/core-groovy-modules/core-groovy-strings/pom.xml index fac0f25219..ac68849431 100644 --- a/core-groovy-modules/core-groovy-strings/pom.xml +++ b/core-groovy-modules/core-groovy-strings/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-groovy-strings - 1.0-SNAPSHOT core-groovy-strings jar @@ -101,12 +100,4 @@ - - - maven_central - Maven Central - https://repo.maven.apache.org/maven2/ - - - diff --git a/core-groovy-modules/core-groovy/pom.xml b/core-groovy-modules/core-groovy/pom.xml index cf6cca9e18..6668f62235 100644 --- a/core-groovy-modules/core-groovy/pom.xml +++ b/core-groovy-modules/core-groovy/pom.xml @@ -3,9 +3,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-groovy - 1.0-SNAPSHOT core-groovy jar @@ -102,12 +100,4 @@ - - - maven_central - Maven Central - https://repo.maven.apache.org/maven2/ - - - diff --git a/core-java-modules/core-java-10/pom.xml b/core-java-modules/core-java-10/pom.xml index e2ac8db919..7eccb098a0 100644 --- a/core-java-modules/core-java-10/pom.xml +++ b/core-java-modules/core-java-10/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-10 - 0.1.0-SNAPSHOT core-java-10 jar diff --git a/core-java-modules/core-java-11-2/pom.xml b/core-java-modules/core-java-11-2/pom.xml index 64a486b5c4..4647814048 100644 --- a/core-java-modules/core-java-11-2/pom.xml +++ b/core-java-modules/core-java-11-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-11-2 - 0.1.0-SNAPSHOT core-java-11-2 jar diff --git a/core-java-modules/core-java-11-3/pom.xml b/core-java-modules/core-java-11-3/pom.xml index ccccae5ba1..22db9e62ab 100644 --- a/core-java-modules/core-java-11-3/pom.xml +++ b/core-java-modules/core-java-11-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-11-3 - 0.1.0-SNAPSHOT core-java-11-3 jar @@ -14,7 +13,7 @@ 1.0.0-SNAPSHOT ../../pom.xml - + com.google.code.gson diff --git a/core-java-modules/core-java-11/pom.xml b/core-java-modules/core-java-11/pom.xml index 28a218c400..d0c2c0acaa 100644 --- a/core-java-modules/core-java-11/pom.xml +++ b/core-java-modules/core-java-11/pom.xml @@ -4,10 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-11 - 0.1.0-SNAPSHOT core-java-11 jar - http://maven.apache.org com.baeldung diff --git a/core-java-modules/core-java-12/pom.xml b/core-java-modules/core-java-12/pom.xml index 9f95b1bc3f..ba6dfc62bc 100644 --- a/core-java-modules/core-java-12/pom.xml +++ b/core-java-modules/core-java-12/pom.xml @@ -4,10 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-12 - 0.1.0-SNAPSHOT core-java-12 jar - http://maven.apache.org com.baeldung diff --git a/core-java-modules/core-java-13/pom.xml b/core-java-modules/core-java-13/pom.xml index 9e42838971..11d6ee7007 100644 --- a/core-java-modules/core-java-13/pom.xml +++ b/core-java-modules/core-java-13/pom.xml @@ -3,12 +3,9 @@ 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 core-java-13 - 0.1.0-SNAPSHOT core-java-13 jar - http://maven.apache.org com.baeldung diff --git a/core-java-modules/core-java-14/pom.xml b/core-java-modules/core-java-14/pom.xml index f78edd622a..9f48c0b8b2 100644 --- a/core-java-modules/core-java-14/pom.xml +++ b/core-java-modules/core-java-14/pom.xml @@ -6,7 +6,6 @@ core-java-14 core-java-14 jar - http://maven.apache.org com.baeldung diff --git a/core-java-modules/core-java-15/pom.xml b/core-java-modules/core-java-15/pom.xml index a4923054ac..059e2cc8f3 100644 --- a/core-java-modules/core-java-15/pom.xml +++ b/core-java-modules/core-java-15/pom.xml @@ -6,7 +6,6 @@ core-java-15 core-java-15 jar - http://maven.apache.org com.baeldung diff --git a/core-java-modules/core-java-16/pom.xml b/core-java-modules/core-java-16/pom.xml index a2c0d4855b..f8d287880a 100644 --- a/core-java-modules/core-java-16/pom.xml +++ b/core-java-modules/core-java-16/pom.xml @@ -4,10 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-16 - 0.1.0-SNAPSHOT core-java-16 jar - http://maven.apache.org com.baeldung diff --git a/core-java-modules/core-java-17/pom.xml b/core-java-modules/core-java-17/pom.xml index bc949d9050..e2d854be44 100644 --- a/core-java-modules/core-java-17/pom.xml +++ b/core-java-modules/core-java-17/pom.xml @@ -4,10 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-17 - 0.1.0-SNAPSHOT core-java-17 jar - http://maven.apache.org com.baeldung diff --git a/core-java-modules/core-java-19/README.md b/core-java-modules/core-java-19/README.md index 6a9c6c7fdd..68244d9f91 100644 --- a/core-java-modules/core-java-19/README.md +++ b/core-java-modules/core-java-19/README.md @@ -1,3 +1,4 @@ ## Relevant Articles - [Record Patterns in Java 19](https://www.baeldung.com/java-19-record-patterns) - [Structured Concurrency in Java 19](https://www.baeldung.com/java-structured-concurrency) +- [Possible Root Causes for High CPU Usage in Java](https://www.baeldung.com/java-high-cpu-usage-causes) diff --git a/core-java-modules/core-java-19/pom.xml b/core-java-modules/core-java-19/pom.xml index 096b13e679..930b37391c 100644 --- a/core-java-modules/core-java-19/pom.xml +++ b/core-java-modules/core-java-19/pom.xml @@ -1,21 +1,17 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + core-java-19 + core-java-19 + com.baeldung.core-java-modules core-java-modules 0.0.1-SNAPSHOT - core-java-19 - - - 19 - 19 - UTF-8 - @@ -30,4 +26,10 @@ + + 19 + 19 + UTF-8 + + \ No newline at end of file diff --git a/core-java-modules/core-java-19/src/main/java/com/baeldung/highcpu/Application.java b/core-java-modules/core-java-19/src/main/java/com/baeldung/highcpu/Application.java new file mode 100644 index 0000000000..82162406b3 --- /dev/null +++ b/core-java-modules/core-java-19/src/main/java/com/baeldung/highcpu/Application.java @@ -0,0 +1,20 @@ +package com.baeldung.highcpu; + +import java.util.LinkedList; +import java.util.List; +import java.util.function.IntUnaryOperator; +import java.util.stream.IntStream; + +public class Application { + + static List generateList() { + return IntStream.range(0, 10000000).parallel().map(IntUnaryOperator.identity()).collect(LinkedList::new, List::add, List::addAll); + } + + public static void main(String[] args) { + List list = generateList(); + long start = System.nanoTime(); + int value = list.get(9500000); + System.out.printf("Found value %d in %d nanos\n", value, (System.nanoTime() - start)); + } +} diff --git a/core-java-modules/core-java-20/README.md b/core-java-modules/core-java-20/README.md new file mode 100644 index 0000000000..aba4e9e240 --- /dev/null +++ b/core-java-modules/core-java-20/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Scoped Values in Java 20](https://www.baeldung.com/java-20-scoped-values) diff --git a/core-java-modules/core-java-20/pom.xml b/core-java-modules/core-java-20/pom.xml new file mode 100644 index 0000000000..9562a41b1c --- /dev/null +++ b/core-java-modules/core-java-20/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + core-java-20 + + + 20 + 20 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 20 + 20 + + --enable-preview + --add-modules=jdk.incubator.concurrent + + + + + org.apache.maven.plugins + maven-surefire-plugin + + --enable-preview --add-modules=jdk.incubator.concurrent + + + + + + + + jakarta.servlet + jakarta.servlet-api + 6.0.0 + provided + + + org.assertj + assertj-core + 3.24.2 + test + + + org.mockito + mockito-junit-jupiter + 5.2.0 + test + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/classic/Controller.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/classic/Controller.java new file mode 100644 index 0000000000..92edc57e48 --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/classic/Controller.java @@ -0,0 +1,33 @@ +package com.baeldung.scopedvalues.classic; + +import com.baeldung.scopedvalues.data.Data; +import com.baeldung.scopedvalues.data.User; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Optional; + +public class Controller { + + private final Service service = new Service(); + + public void processRequest(HttpServletRequest request, HttpServletResponse response, User loggedInUser) { + Optional data = service.getData(request, loggedInUser); + if (data.isPresent()) { + try { + PrintWriter out = response.getWriter(); + response.setContentType("application/json"); + out.print(data.get()); + out.flush(); + response.setStatus(200); + } catch (IOException e) { + response.setStatus(500); + } + } else { + response.setStatus(400); + } + } + +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/classic/Repository.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/classic/Repository.java new file mode 100644 index 0000000000..3085b3be58 --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/classic/Repository.java @@ -0,0 +1,16 @@ +package com.baeldung.scopedvalues.classic; + +import com.baeldung.scopedvalues.data.Data; +import com.baeldung.scopedvalues.data.User; + +import java.util.Optional; + +public class Repository { + + public Optional getData(String id, User user) { + return user.isAdmin() + ? Optional.of(new Data(id, "Title 1", "Description 1")) + : Optional.empty(); + } + +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/classic/Server.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/classic/Server.java new file mode 100644 index 0000000000..71afa9e675 --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/classic/Server.java @@ -0,0 +1,42 @@ +package com.baeldung.scopedvalues.classic; + +import com.baeldung.scopedvalues.data.User; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.util.List; +import java.util.Optional; +import java.util.concurrent.*; + +public class Server { + + private static final List AUTHENTICATED_USERS = List.of( + new User("1", "admin", "123456", true), + new User("2", "user", "123456", false) + ); + private final Controller controller = new Controller(); + private final ExecutorService executor = Executors.newFixedThreadPool(5); + + public void serve(HttpServletRequest request, HttpServletResponse response) throws InterruptedException, ExecutionException { + Optional user = authenticateUser(request); + if (user.isPresent()) { + Future future = executor.submit(() -> + controller.processRequest(request, response, user.get())); + future.get(); + } else { + response.setStatus(401); + } + } + + private Optional authenticateUser(HttpServletRequest request) { + return AUTHENTICATED_USERS.stream() + .filter(user -> checkUserPassword(user, request)) + .findFirst(); + } + + private boolean checkUserPassword(User user, HttpServletRequest request) { + return user.name().equals(request.getParameter("user_name")) + && user.password().equals(request.getParameter("user_pw")); + } + +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/classic/Service.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/classic/Service.java new file mode 100644 index 0000000000..011f793001 --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/classic/Service.java @@ -0,0 +1,18 @@ +package com.baeldung.scopedvalues.classic; + +import com.baeldung.scopedvalues.data.Data; +import com.baeldung.scopedvalues.data.User; +import jakarta.servlet.http.HttpServletRequest; + +import java.util.Optional; + +public class Service { + + private final Repository repository = new Repository(); + + public Optional getData(HttpServletRequest request, User loggedInUser) { + String id = request.getParameter("data_id"); + return repository.getData(id, loggedInUser); + } + +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/data/Data.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/data/Data.java new file mode 100644 index 0000000000..70be41c1ac --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/data/Data.java @@ -0,0 +1,3 @@ +package com.baeldung.scopedvalues.data; + +public record Data(String id, String title, String description) {} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/data/User.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/data/User.java new file mode 100644 index 0000000000..22e0a4243f --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/data/User.java @@ -0,0 +1,3 @@ +package com.baeldung.scopedvalues.data; + +public record User(String id, String name, String password, boolean isAdmin) {} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/Controller.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/Controller.java new file mode 100644 index 0000000000..239ee88f19 --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/Controller.java @@ -0,0 +1,37 @@ +package com.baeldung.scopedvalues.scoped; + +import com.baeldung.scopedvalues.data.Data; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jdk.incubator.concurrent.ScopedValue; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Optional; + +public class Controller { + + private final Service internalService = new Service(); + + public void processRequest(HttpServletRequest request, HttpServletResponse response) { + Optional data = internalService.getData(request); + + ScopedValue.where(Server.LOGGED_IN_USER, null) + .run(internalService::extractData); + + if (data.isPresent()) { + try { + PrintWriter out = response.getWriter(); + response.setContentType("application/json"); + out.print(data.get()); + out.flush(); + response.setStatus(200); + } catch (IOException e) { + response.setStatus(500); + } + } else { + response.setStatus(400); + } + } + +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/Repository.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/Repository.java new file mode 100644 index 0000000000..a40191eb3c --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/Repository.java @@ -0,0 +1,17 @@ +package com.baeldung.scopedvalues.scoped; + +import com.baeldung.scopedvalues.data.Data; +import com.baeldung.scopedvalues.data.User; + +import java.util.Optional; + +public class Repository { + + public Optional getData(String id) { + User loggedInUser = Server.LOGGED_IN_USER.get(); + return loggedInUser.isAdmin() + ? Optional.of(new Data(id, "Title 1", "Description 1")) + : Optional.empty(); + } + +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/Server.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/Server.java new file mode 100644 index 0000000000..559e4efd56 --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/Server.java @@ -0,0 +1,41 @@ +package com.baeldung.scopedvalues.scoped; + +import com.baeldung.scopedvalues.data.User; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jdk.incubator.concurrent.ScopedValue; + +import java.util.List; +import java.util.Optional; + +public class Server { + + private static final List AUTHENTICATED_USERS = List.of( + new User("1", "admin", "123456", true), + new User("2", "user", "123456", false) + ); + public final static ScopedValue LOGGED_IN_USER = ScopedValue.newInstance(); + private final Controller controller = new Controller(); + + public void serve(HttpServletRequest request, HttpServletResponse response) { + Optional user = authenticateUser(request); + if (user.isPresent()) { + ScopedValue.where(LOGGED_IN_USER, user.get()) + .run(() -> controller.processRequest(request, response)); + } else { + response.setStatus(401); + } + } + + private Optional authenticateUser(HttpServletRequest request) { + return AUTHENTICATED_USERS.stream() + .filter(user -> checkUserPassword(user, request)) + .findFirst(); + } + + private boolean checkUserPassword(User user, HttpServletRequest request) { + return user.name().equals(request.getParameter("user_name")) + && user.password().equals(request.getParameter("user_pw")); + } + +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/Service.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/Service.java new file mode 100644 index 0000000000..e35d98cae5 --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/Service.java @@ -0,0 +1,23 @@ +package com.baeldung.scopedvalues.scoped; + +import com.baeldung.scopedvalues.data.Data; +import com.baeldung.scopedvalues.data.User; +import jakarta.servlet.http.HttpServletRequest; + +import java.util.Optional; + +public class Service { + + private final Repository repository = new Repository(); + + public Optional getData(HttpServletRequest request) { + String id = request.getParameter("data_id"); + return repository.getData(id); + } + + public void extractData() { + User loggedInUser = Server.LOGGED_IN_USER.get(); + assert loggedInUser == null; + } + +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/Controller.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/Controller.java new file mode 100644 index 0000000000..e4742c0998 --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/Controller.java @@ -0,0 +1,44 @@ +package com.baeldung.scopedvalues.scoped.inheriting; + +import com.baeldung.scopedvalues.data.Data; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jdk.incubator.concurrent.StructuredTaskScope; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class Controller { + + private final InternalService internalService = new InternalService(); + private final ExternalService externalService = new ExternalService(); + + public void processRequest(HttpServletRequest request, HttpServletResponse response) { + try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { + Future> internalData = scope.fork(() -> internalService.getData(request)); + Future externalData = scope.fork(externalService::getData); + try { + scope.join(); + scope.throwIfFailed(); + + Optional data = internalData.resultNow(); + if (data.isPresent()) { + PrintWriter out = response.getWriter(); + response.setContentType("application/json"); + out.println(data.get()); + out.print(externalData.resultNow()); + out.flush(); + response.setStatus(200); + } else { + response.setStatus(400); + } + } catch (InterruptedException | ExecutionException | IOException e) { + response.setStatus(500); + } + } + } + +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/ExternalService.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/ExternalService.java new file mode 100644 index 0000000000..88fa4dfb74 --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/ExternalService.java @@ -0,0 +1,9 @@ +package com.baeldung.scopedvalues.scoped.inheriting; + +public class ExternalService { + + public String getData() { + return "External data"; + } + +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/InternalService.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/InternalService.java new file mode 100644 index 0000000000..ace46b254c --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/InternalService.java @@ -0,0 +1,17 @@ +package com.baeldung.scopedvalues.scoped.inheriting; + +import com.baeldung.scopedvalues.data.Data; +import jakarta.servlet.http.HttpServletRequest; + +import java.util.Optional; + +public class InternalService { + + private final Repository repository = new Repository(); + + public Optional getData(HttpServletRequest request) { + String id = request.getParameter("data_id"); + return repository.getData(id); + } + +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/Repository.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/Repository.java new file mode 100644 index 0000000000..22d18b2fac --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/Repository.java @@ -0,0 +1,17 @@ +package com.baeldung.scopedvalues.scoped.inheriting; + +import com.baeldung.scopedvalues.data.Data; +import com.baeldung.scopedvalues.data.User; + +import java.util.Optional; + +public class Repository { + + public Optional getData(String id) { + User loggedInUser = Server.LOGGED_IN_USER.get(); + return loggedInUser.isAdmin() + ? Optional.of(new Data(id, "Title 1", "Description 1")) + : Optional.empty(); + } + +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/Server.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/Server.java new file mode 100644 index 0000000000..5f04a1eedd --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/scopedvalues/scoped/inheriting/Server.java @@ -0,0 +1,41 @@ +package com.baeldung.scopedvalues.scoped.inheriting; + +import com.baeldung.scopedvalues.data.User; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jdk.incubator.concurrent.ScopedValue; + +import java.util.List; +import java.util.Optional; + +public class Server { + + private static final List AUTHENTICATED_USERS = List.of( + new User("1", "admin", "123456", true), + new User("2", "user", "123456", false) + ); + public final static ScopedValue LOGGED_IN_USER = ScopedValue.newInstance(); + private final Controller controller = new Controller(); + + public void serve(HttpServletRequest request, HttpServletResponse response) { + Optional user = authenticateUser(request); + if (user.isPresent()) { + ScopedValue.where(LOGGED_IN_USER, user.get()) + .run(() -> controller.processRequest(request, response)); + } else { + response.setStatus(401); + } + } + + private Optional authenticateUser(HttpServletRequest request) { + return AUTHENTICATED_USERS.stream() + .filter(user -> checkUserPassword(user, request)) + .findFirst(); + } + + private boolean checkUserPassword(User user, HttpServletRequest request) { + return user.name().equals(request.getParameter("user_name")) + && user.password().equals(request.getParameter("user_pw")); + } + +} diff --git a/core-java-modules/core-java-20/src/test/java/com/baeldung/scopedvalues/classic/ServerUnitTest.java b/core-java-modules/core-java-20/src/test/java/com/baeldung/scopedvalues/classic/ServerUnitTest.java new file mode 100644 index 0000000000..e0b9366c22 --- /dev/null +++ b/core-java-modules/core-java-20/src/test/java/com/baeldung/scopedvalues/classic/ServerUnitTest.java @@ -0,0 +1,52 @@ +package com.baeldung.scopedvalues.classic; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.concurrent.ExecutionException; + +import static org.mockito.Mockito.*; +import static org.assertj.core.api.Assertions.*; +@ExtendWith(MockitoExtension.class) +public class ServerUnitTest { + + @Mock + private HttpServletRequest request; + + @Mock + private HttpServletResponse response; + + private final StringWriter writer = new StringWriter(); + + private final Server server = new Server(); + + @Test + void givenMockedRequestWithAdminCredentials_whenServeMethodIsCalled_thenDataIsReturned() throws InterruptedException, IOException, ExecutionException { + when(request.getParameter("user_name")).thenReturn("admin"); + when(request.getParameter("user_pw")).thenReturn("123456"); + when(request.getParameter("data_id")).thenReturn("1"); + when(response.getWriter()).thenReturn(new PrintWriter(writer)); + + server.serve(request, response); + + assertThat(writer.toString()).isEqualTo("Data[id=1, title=Title 1, description=Description 1]"); + } + + @Test + void givenMockedRequestWithUserCredentials_whenServeMethodIsCalled_thenNoDataIsReturned() throws InterruptedException, ExecutionException { + when(request.getParameter("user_name")).thenReturn("user"); + when(request.getParameter("user_pw")).thenReturn("123456"); + + server.serve(request, response); + + assertThat(writer.toString()).isEqualTo(""); + } + +} diff --git a/core-java-modules/core-java-20/src/test/java/com/baeldung/scopedvalues/scoped/ServerUnitTest.java b/core-java-modules/core-java-20/src/test/java/com/baeldung/scopedvalues/scoped/ServerUnitTest.java new file mode 100644 index 0000000000..034e6683e3 --- /dev/null +++ b/core-java-modules/core-java-20/src/test/java/com/baeldung/scopedvalues/scoped/ServerUnitTest.java @@ -0,0 +1,52 @@ +package com.baeldung.scopedvalues.scoped; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class ServerUnitTest { + + @Mock + private HttpServletRequest request; + + @Mock + private HttpServletResponse response; + + private final StringWriter writer = new StringWriter(); + + private final Server server = new Server(); + + @Test + void givenMockedRequestWithAdminCredentials_whenServeMethodIsCalled_thenDataIsReturned() throws IOException { + when(request.getParameter("user_name")).thenReturn("admin"); + when(request.getParameter("user_pw")).thenReturn("123456"); + when(request.getParameter("data_id")).thenReturn("1"); + when(response.getWriter()).thenReturn(new PrintWriter(writer)); + + server.serve(request, response); + + assertThat(writer.toString()).isEqualTo("Data[id=1, title=Title 1, description=Description 1]"); + } + + @Test + void givenMockedRequestWithUserCredentials_whenServeMethodIsCalled_thenNoDataIsReturned() throws IOException { + when(request.getParameter("user_name")).thenReturn("user"); + when(request.getParameter("user_pw")).thenReturn("123456"); + + server.serve(request, response); + + assertThat(writer.toString()).isEqualTo(""); + } + +} diff --git a/core-java-modules/core-java-20/src/test/java/com/baeldung/scopedvalues/scoped/inheriting/ServerUnitTest.java b/core-java-modules/core-java-20/src/test/java/com/baeldung/scopedvalues/scoped/inheriting/ServerUnitTest.java new file mode 100644 index 0000000000..230b017c18 --- /dev/null +++ b/core-java-modules/core-java-20/src/test/java/com/baeldung/scopedvalues/scoped/inheriting/ServerUnitTest.java @@ -0,0 +1,52 @@ +package com.baeldung.scopedvalues.scoped.inheriting; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class ServerUnitTest { + + @Mock + private HttpServletRequest request; + + @Mock + private HttpServletResponse response; + + private final StringWriter writer = new StringWriter(); + + private final Server server = new Server(); + + @Test + void givenMockedRequestWithAdminCredentials_whenServeMethodIsCalled_thenDataIsReturned() throws IOException { + when(request.getParameter("user_name")).thenReturn("admin"); + when(request.getParameter("user_pw")).thenReturn("123456"); + when(request.getParameter("data_id")).thenReturn("1"); + when(response.getWriter()).thenReturn(new PrintWriter(writer)); + + server.serve(request, response); + + assertThat(writer.toString()).isEqualTo("Data[id=1, title=Title 1, description=Description 1]\nExternal data"); + } + + @Test + void givenMockedRequestWithUserCredentials_whenServeMethodIsCalled_thenNoDataIsReturned() throws IOException { + when(request.getParameter("user_name")).thenReturn("user"); + when(request.getParameter("user_pw")).thenReturn("123456"); + + server.serve(request, response); + + assertThat(writer.toString()).isEqualTo(""); + } + +} diff --git a/core-java-modules/core-java-8-2/README.md b/core-java-modules/core-java-8-2/README.md index cad4a4f1fa..c723a827b1 100644 --- a/core-java-modules/core-java-8-2/README.md +++ b/core-java-modules/core-java-8-2/README.md @@ -11,4 +11,6 @@ This module contains articles about Java 8 core features - [Convert Between Byte Array and UUID in Java](https://www.baeldung.com/java-byte-array-to-uuid) - [Create a Simple “Rock-Paper-Scissors” Game in Java](https://www.baeldung.com/java-rock-paper-scissors) - [VarArgs vs Array Input Parameters in Java](https://www.baeldung.com/varargs-vs-array) +- [Lambda Expression vs. Anonymous Inner Class](https://www.baeldung.com/java-lambdas-vs-anonymous-class) +- [Java Helper vs. Utility Classes](https://www.baeldung.com/java-helper-vs-utility-classes) - [[<-- Prev]](/core-java-modules/core-java-8) diff --git a/core-java-modules/core-java-8-2/pom.xml b/core-java-modules/core-java-8-2/pom.xml index 7db1e1ed4e..589e384613 100644 --- a/core-java-modules/core-java-8-2/pom.xml +++ b/core-java-modules/core-java-8-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-8-2 - 0.1.0-SNAPSHOT core-java-8-2 jar diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/anonymousclass/AnonymousClassExample.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/anonymousclass/AnonymousClassExample.java similarity index 100% rename from core-java-modules/core-java-lambdas/src/main/java/com/baeldung/anonymousclass/AnonymousClassExample.java rename to core-java-modules/core-java-8-2/src/main/java/com/baeldung/anonymousclass/AnonymousClassExample.java diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/helpervsutilityclasses/MyHelperClass.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/helpervsutilityclasses/MyHelperClass.java new file mode 100644 index 0000000000..40b58bf200 --- /dev/null +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/helpervsutilityclasses/MyHelperClass.java @@ -0,0 +1,40 @@ +package com.baeldung.helpervsutilityclasses; + +class MyHelperClass { + public double discount; + public MyHelperClass(double discount) { + if (discount > 0 && discount < 1) { + this.discount = discount; + } + } + public double discountedPrice(double price) { + return price - (price * discount); + } + + public static int getMaxNumber(int[] numbers) { + if (numbers.length == 0) { + throw new IllegalArgumentException("Ensure array is not empty"); + } + int max = numbers[0]; + for (int i = 1; i < numbers.length; i++) { + if (numbers[i] > max) { + max = numbers[i]; + } + } + return max; + } + + public static int getMinNumber(int[] numbers) { + if (numbers.length == 0) { + throw new IllegalArgumentException("Ensure array is not empty"); + } + int min = numbers[0]; + for (int i = 1; i < numbers.length; i++) { + if (numbers[i] < min) { + min = numbers[i]; + } + } + return min; + } + +} diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/helpervsutilityclasses/MyUtilityClass.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/helpervsutilityclasses/MyUtilityClass.java new file mode 100644 index 0000000000..1f0075995c --- /dev/null +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/helpervsutilityclasses/MyUtilityClass.java @@ -0,0 +1,19 @@ +package com.baeldung.helpervsutilityclasses; + +public final class MyUtilityClass { + + private MyUtilityClass(){} + + public static String returnUpperCase(String stringInput) { + return stringInput.toUpperCase(); + } + + public static String returnLowerCase(String stringInput) { + return stringInput.toLowerCase(); + } + + public static String[] splitStringInput(String stringInput, String delimiter) { + return stringInput.split(delimiter); + } + +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/lambdaexpression/LambdaExpressionExample.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/lambdaexpression/LambdaExpressionExample.java similarity index 100% rename from core-java-modules/core-java-lambdas/src/main/java/com/baeldung/lambdaexpression/LambdaExpressionExample.java rename to core-java-modules/core-java-8-2/src/main/java/com/baeldung/lambdaexpression/LambdaExpressionExample.java diff --git a/core-java-modules/core-java-8-2/src/test/java/com/baeldung/helpervsutilityclasses/MyHelperClassUnitTest.java b/core-java-modules/core-java-8-2/src/test/java/com/baeldung/helpervsutilityclasses/MyHelperClassUnitTest.java new file mode 100644 index 0000000000..a0c1afea52 --- /dev/null +++ b/core-java-modules/core-java-8-2/src/test/java/com/baeldung/helpervsutilityclasses/MyHelperClassUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.helpervsutilityclasses; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class MyHelperClassUnitTest { + + @Test + void whenCreatingHelperObject_thenHelperObjectShouldBeCreated() { + MyHelperClass myHelperClassObject = new MyHelperClass(0.10); + int[] numberArray = {15, 23, 66, 3, 51, 79}; + + assertNotNull(myHelperClassObject); + + assertEquals(90, myHelperClassObject.discountedPrice(100.00)); + assertEquals( 79, MyHelperClass.getMaxNumber(numberArray)); + assertEquals(3, MyHelperClass.getMinNumber(numberArray)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-8-2/src/test/java/com/baeldung/helpervsutilityclasses/MyUtilityClassUnitTest.java b/core-java-modules/core-java-8-2/src/test/java/com/baeldung/helpervsutilityclasses/MyUtilityClassUnitTest.java new file mode 100644 index 0000000000..8b29f51959 --- /dev/null +++ b/core-java-modules/core-java-8-2/src/test/java/com/baeldung/helpervsutilityclasses/MyUtilityClassUnitTest.java @@ -0,0 +1,15 @@ +package com.baeldung.helpervsutilityclasses; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class MyUtilityClassUnitTest { + + @Test + void whenUsingUtilityMethods_thenAccessMethodsViaClassName(){ + assertEquals( "INIUBONG", MyUtilityClass.returnUpperCase("iniubong")); + assertEquals("accra", MyUtilityClass.returnLowerCase("AcCrA")); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-8-datetime-2/README.md b/core-java-modules/core-java-8-datetime-2/README.md index f16563aacc..56f66c10fb 100644 --- a/core-java-modules/core-java-8-datetime-2/README.md +++ b/core-java-modules/core-java-8-datetime-2/README.md @@ -2,4 +2,5 @@ - [Generating Random Dates in Java](https://www.baeldung.com/java-random-dates) - [Creating a LocalDate with Values in Java](https://www.baeldung.com/java-creating-localdate-with-values) -- [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) \ No newline at end of file +- [Parsing Date Strings with Varying Formats](https://www.baeldung.com/java-parsing-dates-many-formats) +- [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) diff --git a/core-java-modules/core-java-8-datetime-2/pom.xml b/core-java-modules/core-java-8-datetime-2/pom.xml index 9e54b0ee12..ce349d9dc3 100644 --- a/core-java-modules/core-java-8-datetime-2/pom.xml +++ b/core-java-modules/core-java-8-datetime-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-8-datetime-2 - ${project.parent.version} core-java-8-datetime-2 jar diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleDateTimeFormat.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleDateTimeFormat.java new file mode 100644 index 0000000000..a82f3bce2b --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleDateTimeFormat.java @@ -0,0 +1,20 @@ +package com.baeldung.parsingDates; + +import java.util.Arrays; +import java.util.List; +import org.joda.time.LocalDate; +import org.joda.time.format.DateTimeFormat; + +public class SimpleDateTimeFormat { + + public static LocalDate parseDate(String date) { + List patternList = Arrays.asList("MM/dd/yyyy", "dd.MM.yyyy", "yyyy-MM-dd"); + for (String pattern : patternList) { + try { + return DateTimeFormat.forPattern(pattern).parseLocalDate(date); + } catch (IllegalArgumentException e) { + } + } + return null; + } +} diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleDateTimeFormater.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleDateTimeFormater.java new file mode 100644 index 0000000000..aa12038032 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleDateTimeFormater.java @@ -0,0 +1,17 @@ +package com.baeldung.parsingDates; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; + +public class SimpleDateTimeFormater { + + public static LocalDate parseDate(String date) { + DateTimeFormatterBuilder dateTimeFormatterBuilder = new DateTimeFormatterBuilder() + .append(DateTimeFormatter.ofPattern("[MM/dd/yyyy]" + "[dd-MM-yyyy]" + "[yyyy-MM-dd]")); + + DateTimeFormatter dateTimeFormatter = dateTimeFormatterBuilder.toFormatter(); + + return LocalDate.parse(date, dateTimeFormatter); + } +} diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleDateUtils.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleDateUtils.java new file mode 100644 index 0000000000..8a154d3cd8 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleDateUtils.java @@ -0,0 +1,18 @@ +package com.baeldung.parsingDates; + +import java.text.ParseException; +import java.util.Date; +import org.apache.commons.lang3.time.DateUtils; + +public class SimpleDateUtils { + + public static Date parseDate(String date) { + try { + return DateUtils.parseDateStrictly(date, + new String[]{"yyyy/MM/dd", "dd/MM/yyyy", "yyyy-MM-dd"}); + } catch (ParseException ex) { + return null; + } + } + +} diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleParseDate.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleParseDate.java new file mode 100644 index 0000000000..cb024eea53 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleParseDate.java @@ -0,0 +1,19 @@ +package com.baeldung.parsingDates; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +public class SimpleParseDate { + + public Date parseDate(String dateString, List formatStrings) { + for (String formatString : formatStrings) { + try { + return new SimpleDateFormat(formatString).parse(dateString); + } catch (ParseException e) { + } + } + return null; + } +} diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/parsingDates/SimpleParseDateUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/parsingDates/SimpleParseDateUnitTest.java new file mode 100644 index 0000000000..d7cbb6a834 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/parsingDates/SimpleParseDateUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.parsingDates; + +import com.baeldung.parsingDates.SimpleDateTimeFormat; +import com.baeldung.parsingDates.SimpleDateTimeFormater; +import com.baeldung.parsingDates.SimpleDateUtils; +import com.baeldung.parsingDates.SimpleParseDate; +import java.time.format.DateTimeParseException; +import java.util.Arrays; +import org.junit.*; +import static org.junit.Assert.*; +import org.joda.time.LocalDate; + +public class SimpleParseDateUnitTest { + + @Test + public void whenInvalidInput_thenGettingUnexpectedResult() { + SimpleParseDate simpleParseDate = new SimpleParseDate(); + String date = "2022-40-40"; + assertEquals("Sat May 10 00:00:00 UTC 2025", simpleParseDate.parseDate(date, Arrays.asList("MM/dd/yyyy", "dd.MM.yyyy", "yyyy-MM-dd")).toString()); + } + + @Test + public void whenInvalidDate_thenAssertThrows() { + SimpleDateTimeFormater simpleDateTimeFormater = new SimpleDateTimeFormater(); + assertEquals(java.time.LocalDate.parse("2022-12-04"), simpleDateTimeFormater.parseDate("2022-12-04")); + assertThrows(DateTimeParseException.class, () -> simpleDateTimeFormater.parseDate("2022-13-04")); + } + + @Test + public void whenDateIsCorrect_thenParseCorrect() { + SimpleDateUtils simpleDateUtils = new SimpleDateUtils(); + assertNull(simpleDateUtils.parseDate("53/10/2014")); + assertEquals("Wed Sep 10 00:00:00 UTC 2014", simpleDateUtils.parseDate("10/09/2014").toString()); + } + + @Test + public void whenDateIsCorrect_thenResultCorrect() { + SimpleDateTimeFormat simpleDateTimeFormat = new SimpleDateTimeFormat(); + assertNull(simpleDateTimeFormat.parseDate("53/10/2014")); + assertEquals(LocalDate.parse("2014-10-10"), simpleDateTimeFormat.parseDate("2014-10-10")); + } + +} diff --git a/core-java-modules/core-java-8-datetime/pom.xml b/core-java-modules/core-java-8-datetime/pom.xml index 01ec6c0b76..481b1a6a69 100644 --- a/core-java-modules/core-java-8-datetime/pom.xml +++ b/core-java-modules/core-java-8-datetime/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-8-datetime - ${project.parent.version} core-java-8-datetime jar diff --git a/core-java-modules/core-java-8/pom.xml b/core-java-modules/core-java-8/pom.xml index 89925bdbbb..fff7b7f2f9 100644 --- a/core-java-modules/core-java-8/pom.xml +++ b/core-java-modules/core-java-8/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-8 - 0.1.0-SNAPSHOT core-java-8 jar diff --git a/core-java-modules/core-java-9-improvements/pom.xml b/core-java-modules/core-java-9-improvements/pom.xml index 56d4ccff9f..f6f13ff409 100644 --- a/core-java-modules/core-java-9-improvements/pom.xml +++ b/core-java-modules/core-java-9-improvements/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-9-improvements - 0.2-SNAPSHOT core-java-9-improvements diff --git a/core-java-modules/core-java-9-jigsaw/README.md b/core-java-modules/core-java-9-jigsaw/README.md index cfffb86588..73905e6033 100644 --- a/core-java-modules/core-java-9-jigsaw/README.md +++ b/core-java-modules/core-java-9-jigsaw/README.md @@ -8,5 +8,5 @@ This module contains articles about Project Jigsaw and the Java Platform Module - [A Guide to Java 9 Modularity](https://www.baeldung.com/java-9-modularity) - [Java 9 java.lang.Module API](https://www.baeldung.com/java-9-module-api) - [Java 9 Illegal Reflective Access Warning](https://www.baeldung.com/java-illegal-reflective-access) - +- [Java Modularity and Unit Testing](https://www.baeldung.com/java-modularity-unit-testing) diff --git a/core-java-modules/core-java-9-jigsaw/compile-library-core-module.sh b/core-java-modules/core-java-9-jigsaw/compile-library-core-module.sh new file mode 100644 index 0000000000..fa0d4d5f14 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/compile-library-core-module.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +javac -d mods/com.baeldung.library.core $(find library-core/src/main -name "*.java") \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/compile-library-core-tests.sh b/core-java-modules/core-java-9-jigsaw/compile-library-core-tests.sh new file mode 100644 index 0000000000..751906103b --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/compile-library-core-tests.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +javac --class-path outDir/library-core/:\ +libs/junit-jupiter-engine-5.9.2.jar:\ +libs/junit-platform-engine-1.9.2.jar:\ +libs/apiguardian-api-1.1.2.jar:\ +libs/junit-jupiter-params-5.9.2.jar:\ +libs/junit-jupiter-api-5.9.2.jar:\ +libs/opentest4j-1.2.0.jar:\ +libs/junit-platform-commons-1.9.2.jar \ +-d outDir/library-test library-core/src/test/java/com/baeldung/library/core/LibraryUnitTest.java \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/compile-library-core-with-tests.sh b/core-java-modules/core-java-9-jigsaw/compile-library-core-with-tests.sh new file mode 100644 index 0000000000..c873a9003c --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/compile-library-core-with-tests.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +javac --class-path libs/junit-jupiter-engine-5.9.2.jar:\ +libs/junit-platform-engine-1.9.2.jar:\ +libs/apiguardian-api-1.1.2.jar:\ +libs/junit-jupiter-params-5.9.2.jar:\ +libs/junit-jupiter-api-5.9.2.jar:\ +libs/opentest4j-1.2.0.jar:\ +libs/junit-platform-commons-1.9.2.jar \ +-d outDir/library-core \ +library-core/src/main/java/com/baeldung/library/core/Book.java \ +library-core/src/main/java/com/baeldung/library/core/Library.java \ +library-core/src/main/java/com/baeldung/library/core/Main.java \ +library-core/src/test/java/com/baeldung/library/core/LibraryUnitTest.java \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/compile-library-core.sh b/core-java-modules/core-java-9-jigsaw/compile-library-core.sh new file mode 100644 index 0000000000..7531148d0f --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/compile-library-core.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +javac --class-path libs/junit-jupiter-engine-5.9.2.jar:\ +libs/junit-platform-engine-1.9.2.jar:\ +libs/apiguardian-api-1.1.2.jar:\ +libs/junit-jupiter-params-5.9.2.jar:\ +libs/junit-jupiter-api-5.9.2.jar:\ +libs/opentest4j-1.2.0.jar:\ +libs/junit-platform-commons-1.9.2.jar \ +-d outDir/library-core \ +library-core/src/main/java/com/baeldung/library/core/Book.java \ +library-core/src/main/java/com/baeldung/library/core/Library.java \ +library-core/src/main/java/com/baeldung/library/core/Main.java \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/compile-library-test-module.sh b/core-java-modules/core-java-9-jigsaw/compile-library-test-module.sh new file mode 100644 index 0000000000..c6fd614fd0 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/compile-library-test-module.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +javac --module-path mods:libs -d mods/com.baeldung.library.test $(find library-test/src/test -name "*.java") \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/download-junit-dependencies.sh b/core-java-modules/core-java-9-jigsaw/download-junit-dependencies.sh new file mode 100644 index 0000000000..64c72a5429 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/download-junit-dependencies.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +wget -P libs/ https://repo1.maven.org/maven2/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar / +wget -P libs/ https://repo1.maven.org/maven2/org/opentest4j/opentest4j/1.2.0/opentest4j-1.2.0.jar / +wget -P libs/ https://repo1.maven.org/maven2/org/junit/platform/junit-platform-commons/1.9.2/junit-platform-commons-1.9.2.jar / +wget -P libs/ https://repo1.maven.org/maven2/org/junit/platform/junit-platform-engine/1.9.2/junit-platform-engine-1.9.2.jar / +wget -P libs/ https://repo1.maven.org/maven2/org/junit/platform/junit-platform-reporting/1.9.2/junit-platform-reporting-1.9.2.jar / +wget -P libs/ https://repo1.maven.org/maven2/org/junit/platform/junit-platform-console/1.9.2/junit-platform-console-1.9.2.jar / +wget -P libs/ https://repo1.maven.org/maven2/org/junit/platform/junit-platform-launcher/1.9.2/junit-platform-launcher-1.9.2.jar / +wget -P libs/ https://repo1.maven.org/maven2/org/junit/jupiter/junit-jupiter-engine/5.9.2/junit-jupiter-engine-5.9.2.jar / +wget -P libs/ https://repo1.maven.org/maven2/org/junit/jupiter/junit-jupiter-params/5.9.2/junit-jupiter-params-5.9.2.jar \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/library-core/pom.xml b/core-java-modules/core-java-9-jigsaw/library-core/pom.xml new file mode 100644 index 0000000000..b860d89932 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/library-core/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + + com.baeldung + core-java-9-jigsaw + 0.2-SNAPSHOT + + + library-core + + + 19 + 19 + UTF-8 + + + + + org.junit.jupiter + junit-jupiter-api + 5.9.2 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.9.2 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 9 + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + false + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/library-core/src/main/java/com/baeldung/library/core/Book.java b/core-java-modules/core-java-9-jigsaw/library-core/src/main/java/com/baeldung/library/core/Book.java new file mode 100644 index 0000000000..782de8fa10 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/library-core/src/main/java/com/baeldung/library/core/Book.java @@ -0,0 +1,52 @@ +package com.baeldung.library.core; + +import java.util.Objects; + +public class Book { + + private String title; + private String author; + + public Book(String title, String author) { + this.title = title; + this.author = author; + } + + public String getTitle() { + return title; + } + + public String getAuthor() { + return author; + } + + + @Override + public String toString() { + return "Book [title=" + title + ", author=" + author + "]"; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final Book book = (Book) o; + + if (!Objects.equals(title, book.title)) { + return false; + } + return Objects.equals(author, book.author); + } + + @Override + public int hashCode() { + int result = title != null ? title.hashCode() : 0; + result = 31 * result + (author != null ? author.hashCode() : 0); + return result; + } +} diff --git a/core-java-modules/core-java-9-jigsaw/library-core/src/main/java/com/baeldung/library/core/Library.java b/core-java-modules/core-java-9-jigsaw/library-core/src/main/java/com/baeldung/library/core/Library.java new file mode 100644 index 0000000000..ee2225810d --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/library-core/src/main/java/com/baeldung/library/core/Library.java @@ -0,0 +1,25 @@ +package com.baeldung.library.core; + +import java.util.ArrayList; +import java.util.List; + +public class Library { + + private List books = new ArrayList<>(); + + public void addBook(Book book) { + books.add(book); + } + + public List getBooks() { + return books; + } + + void removeBook(Book book) { + books.remove(book); + } + + protected void removeBookByAuthor(String author) { + books.removeIf(book -> book.getAuthor().equals(author)); + } +} diff --git a/core-java-modules/core-java-9-jigsaw/library-core/src/main/java/com/baeldung/library/core/Main.java b/core-java-modules/core-java-9-jigsaw/library-core/src/main/java/com/baeldung/library/core/Main.java new file mode 100644 index 0000000000..18839602c2 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/library-core/src/main/java/com/baeldung/library/core/Main.java @@ -0,0 +1,16 @@ +package com.baeldung.library.core; + +public class Main { + + public static void main(String[] args) { + Library library = new Library(); + library.addBook(new Book("The Lord of the Rings", "J.R.R. Tolkien")); + library.addBook(new Book("The Hobbit", "J.R.R. Tolkien")); + library.addBook(new Book("The Silmarillion", "J.R.R. Tolkien")); + library.addBook(new Book("The Chronicles of Narnia", "C.S. Lewis")); + library.addBook(new Book("The Lion, the Witch and the Wardrobe", "C.S. Lewis")); + System.out.println("Welcome to our library!"); + System.out.println("We have the following books:"); + library.getBooks().forEach(System.out::println); + } +} diff --git a/core-java-modules/core-java-9-jigsaw/library-core/src/main/java/module-info.java b/core-java-modules/core-java-9-jigsaw/library-core/src/main/java/module-info.java new file mode 100644 index 0000000000..bdf88d8bc9 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/library-core/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module com.baeldung.library.core { + exports com.baeldung.library.core; +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/library-core/src/test/java/com/baeldung/library/core/LibraryUnitTest.java b/core-java-modules/core-java-9-jigsaw/library-core/src/test/java/com/baeldung/library/core/LibraryUnitTest.java new file mode 100644 index 0000000000..20a4889e8c --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/library-core/src/test/java/com/baeldung/library/core/LibraryUnitTest.java @@ -0,0 +1,47 @@ +package com.baeldung.library.core; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class LibraryUnitTest { + + @Test + void givenEmptyLibrary_whenAddABook_thenLibraryHasOneBook() { + Library library = new Library(); + Book theLordOfTheRings = new Book("The Lord of the Rings", "J.R.R. Tolkien"); + library.addBook(theLordOfTheRings); + int expected = 1; + int actual = library.getBooks().size(); + assertEquals(expected, actual); + } + + @Test + void givenTheLibraryWithABook_whenRemoveABook_thenLibraryIsEmpty() { + Library library = new Library(); + Book theLordOfTheRings = new Book("The Lord of the Rings", "J.R.R. Tolkien"); + library.addBook(theLordOfTheRings); + library.removeBook(theLordOfTheRings); + int expected = 0; + int actual = library.getBooks().size(); + assertEquals(expected, actual); + } + + @Test + void givenTheLibraryWithSeveralBook_whenRemoveABookByAuthor_thenLibraryHasNoBooksByTheAuthor() { + Library library = new Library(); + Book theLordOfTheRings = new Book("The Lord of the Rings", "J.R.R. Tolkien"); + Book theHobbit = new Book("The Hobbit", "J.R.R. Tolkien"); + Book theSilmarillion = new Book("The Silmarillion", "J.R.R. Tolkien"); + Book theHungerGames = new Book("The Hunger Games", "Suzanne Collins"); + library.addBook(theLordOfTheRings); + library.addBook(theHobbit); + library.addBook(theSilmarillion); + library.addBook(theHungerGames); + library.removeBookByAuthor("J.R.R. Tolkien"); + int expected = 1; + int actual = library.getBooks().size(); + assertEquals(expected, actual); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/library-test/src/test/java/com/baeldung/library/test/LibraryUnitTest.java b/core-java-modules/core-java-9-jigsaw/library-test/src/test/java/com/baeldung/library/test/LibraryUnitTest.java new file mode 100644 index 0000000000..31eae89bba --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/library-test/src/test/java/com/baeldung/library/test/LibraryUnitTest.java @@ -0,0 +1,53 @@ +package com.baeldung.library.test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.baeldung.library.core.Book; +import com.baeldung.library.core.Library; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import org.junit.jupiter.api.Test; + +class LibraryUnitTest { + + @Test + void givenEmptyLibrary_whenAddABook_thenLibraryHasOneBook() { + Library library = new Library(); + Book theLordOfTheRings = new Book("The Lord of the Rings", "J.R.R. Tolkien"); + library.addBook(theLordOfTheRings); + int expected = 1; + int actual = library.getBooks().size(); + assertEquals(expected, actual); + } + + @Test + void givenTheLibraryWithABook_whenRemoveABook_thenLibraryIsEmpty() + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Library library = new Library(); + Book theLordOfTheRings = new Book("The Lord of the Rings", "J.R.R. Tolkien"); + library.addBook(theLordOfTheRings); + Method removeBook = Library.class.getDeclaredMethod("removeBook", Book.class); + removeBook.setAccessible(true); + removeBook.invoke(library, theLordOfTheRings); + int expected = 0; + int actual = library.getBooks().size(); + assertEquals(expected, actual); + } +@Test +void givenTheLibraryWithSeveralBook_whenRemoveABookByAuthor_thenLibraryHasNoBooksByTheAuthor() { + TestLibrary library = new TestLibrary(); + Book theLordOfTheRings = new Book("The Lord of the Rings", "J.R.R. Tolkien"); + Book theHobbit = new Book("The Hobbit", "J.R.R. Tolkien"); + Book theSilmarillion = new Book("The Silmarillion", "J.R.R. Tolkien"); + Book theHungerGames = new Book("The Hunger Games", "Suzanne Collins"); + library.addBook(theLordOfTheRings); + library.addBook(theHobbit); + library.addBook(theSilmarillion); + library.addBook(theHungerGames); + library.removeBookByAuthor("J.R.R. Tolkien"); + int expected = 1; + int actual = library.getBooks().size(); + assertEquals(expected, actual); +} + +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/library-test/src/test/java/com/baeldung/library/test/TestLibrary.java b/core-java-modules/core-java-9-jigsaw/library-test/src/test/java/com/baeldung/library/test/TestLibrary.java new file mode 100644 index 0000000000..8ee3b0e3fe --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/library-test/src/test/java/com/baeldung/library/test/TestLibrary.java @@ -0,0 +1,10 @@ +package com.baeldung.library.test; + +import com.baeldung.library.core.Library; + +public class TestLibrary extends Library { + @Override + public void removeBookByAuthor(final String author) { + super.removeBookByAuthor(author); + } +} diff --git a/core-java-modules/core-java-9-jigsaw/library-test/src/test/java/module-info.java b/core-java-modules/core-java-9-jigsaw/library-test/src/test/java/module-info.java new file mode 100644 index 0000000000..8d60b574f2 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/library-test/src/test/java/module-info.java @@ -0,0 +1,5 @@ +module com.baeldung.library.test { + requires com.baeldung.library.core; + requires org.junit.jupiter.api; + opens com.baeldung.library.test to org.junit.platform.commons; +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/pom.xml b/core-java-modules/core-java-9-jigsaw/pom.xml index a26a88f4b0..288254b9cf 100644 --- a/core-java-modules/core-java-9-jigsaw/pom.xml +++ b/core-java-modules/core-java-9-jigsaw/pom.xml @@ -4,8 +4,11 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-9-jigsaw - 0.2-SNAPSHOT core-java-9-jigsaw + pom + + library-core + com.baeldung diff --git a/core-java-modules/core-java-9-jigsaw/run-library-core-module-with-patch.sh b/core-java-modules/core-java-9-jigsaw/run-library-core-module-with-patch.sh new file mode 100644 index 0000000000..70772a3589 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/run-library-core-module-with-patch.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +java --module-path mods:libs \ +--add-modules com.baeldung.library.core \ +--add-opens com.baeldung.library.core/com.baeldung.library.core=org.junit.platform.commons \ +--add-reads com.baeldung.library.core=org.junit.jupiter.api \ +--patch-module com.baeldung.library.core=outDir/library-test \ +--module org.junit.platform.console --select-class com.baeldung.library.core.LibraryUnitTest \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/run-library-core-module.sh b/core-java-modules/core-java-9-jigsaw/run-library-core-module.sh new file mode 100644 index 0000000000..f2bb976512 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/run-library-core-module.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +java --module-path mods --module com.baeldung.library.core/com.baeldung.library.core.Main \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/run-library-test-class-path.sh b/core-java-modules/core-java-9-jigsaw/run-library-test-class-path.sh new file mode 100644 index 0000000000..73e3d504bf --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/run-library-test-class-path.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +java --module-path libs \ +org.junit.platform.console.ConsoleLauncher \ +--classpath ./outDir/library-core \ +--select-class com.baeldung.library.core.LibraryUnitTest \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/run-library-test-module-path.sh b/core-java-modules/core-java-9-jigsaw/run-library-test-module-path.sh new file mode 100644 index 0000000000..08d149dbd7 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/run-library-test-module-path.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +java --module-path mods:libs \ +--add-modules com.baeldung.library.test \ +--add-opens com.baeldung.library.core/com.baeldung.library.core=com.baeldung.library.test \ +org.junit.platform.console.ConsoleLauncher --select-class com.baeldung.library.test.LibraryUnitTest \ No newline at end of file diff --git a/core-java-modules/core-java-9-new-features/pom.xml b/core-java-modules/core-java-9-new-features/pom.xml index 78ffaff010..6821c9c340 100644 --- a/core-java-modules/core-java-9-new-features/pom.xml +++ b/core-java-modules/core-java-9-new-features/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-9-new-features - 0.2-SNAPSHOT core-java-9-new-features diff --git a/core-java-modules/core-java-9-streams/pom.xml b/core-java-modules/core-java-9-streams/pom.xml index d3f81780d1..903194b3b3 100644 --- a/core-java-modules/core-java-9-streams/pom.xml +++ b/core-java-modules/core-java-9-streams/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-9-streams - 0.1.0-SNAPSHOT core-java-9-streams jar diff --git a/core-java-modules/core-java-9/README.md b/core-java-modules/core-java-9/README.md index 38965d88f1..bd7df0c8a6 100644 --- a/core-java-modules/core-java-9/README.md +++ b/core-java-modules/core-java-9/README.md @@ -5,7 +5,6 @@ This module contains articles about Java 9 core features ### Relevant Articles: - [Method Handles in Java](https://www.baeldung.com/java-method-handles) -- [Introduction to Chronicle Queue](https://www.baeldung.com/java-chronicle-queue) - [Iterate Through a Range of Dates in Java](https://www.baeldung.com/java-iterate-date-range) - [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) - [Immutable ArrayList in Java](https://www.baeldung.com/java-immutable-list) diff --git a/core-java-modules/core-java-9/pom.xml b/core-java-modules/core-java-9/pom.xml index 272af327cb..bcfdacdf1d 100644 --- a/core-java-modules/core-java-9/pom.xml +++ b/core-java-modules/core-java-9/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-9 - 0.2-SNAPSHOT core-java-9 diff --git a/core-java-modules/core-java-annotations/pom.xml b/core-java-modules/core-java-annotations/pom.xml index a1f84ab563..6b1b9d802f 100644 --- a/core-java-modules/core-java-annotations/pom.xml +++ b/core-java-modules/core-java-annotations/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-annotations - 0.1.0-SNAPSHOT core-java-annotations jar @@ -24,4 +23,12 @@ + + + javax.annotation + javax.annotation-api + 1.3.2 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-operations-basic/README.md b/core-java-modules/core-java-arrays-operations-basic/README.md index 2e1268e00c..76f4044355 100644 --- a/core-java-modules/core-java-arrays-operations-basic/README.md +++ b/core-java-modules/core-java-arrays-operations-basic/README.md @@ -11,3 +11,5 @@ This module contains articles about Java array fundamentals. They assume no prev - [Removing the First Element of an Array](https://www.baeldung.com/java-array-remove-first-element) - [Extending an Array’s Length](https://www.baeldung.com/java-array-add-element-at-the-end) - [Initializing a Boolean Array in Java](https://www.baeldung.com/java-initializing-boolean-array) +- [Find the Index of an Element in a Java Array](https://www.baeldung.com/java-array-find-index) +- [Comparing Two Byte Arrays in Java](https://www.baeldung.com/java-comparing-byte-arrays) diff --git a/core-java-modules/core-java-arrays-operations-basic/src/main/java/com/baeldung/arrayindex/ArrayIndex.java b/core-java-modules/core-java-arrays-operations-basic/src/main/java/com/baeldung/arrayindex/ArrayIndex.java new file mode 100644 index 0000000000..596e0d424f --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-basic/src/main/java/com/baeldung/arrayindex/ArrayIndex.java @@ -0,0 +1,28 @@ +package com.baeldung.arrayindex; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.IntStream; + +class ArrayIndex { + static int forLoop(int[] numbers, int target) { + for (int index = 0; index < numbers.length; index++) { + if (numbers[index] == target) { + return index; + } + } + return -1; + } + + static int listIndexOf(Integer[] numbers, int target) { + List list = Arrays.asList(numbers); + return list.indexOf(target); + } + + static int intStream(int[] numbers, int target) { + return IntStream.range(0, numbers.length) + .filter(i -> numbers[i] == target) + .findFirst() + .orElse(-1); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-operations-basic/src/test/java/com/baeldung/array/compare/CompareByteArraysUnitTest.java b/core-java-modules/core-java-arrays-operations-basic/src/test/java/com/baeldung/array/compare/CompareByteArraysUnitTest.java new file mode 100644 index 0000000000..4274acf83d --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-basic/src/test/java/com/baeldung/array/compare/CompareByteArraysUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.array.compare; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +public class CompareByteArraysUnitTest { + private final static String INPUT = "I am a magic string."; + private final static byte[] ARRAY1 = INPUT.getBytes(); + private final static byte[] ARRAY2 = INPUT.getBytes(); + + @Test + void whenUsingEqualsSign_thenTwoArraysAreNotEqual() { + assertFalse(ARRAY1 == ARRAY2); + } + + @Test + void whenUsingEquals_thenTwoArraysAreNotEqual() { + assertFalse(ARRAY1.equals(ARRAY2)); + } + + @Test + void whenUsingArrayEquals_thenTwoArraysAreEqual() { + assertTrue(Arrays.equals(ARRAY1, ARRAY2)); + } + + @Test + void whenComparingStringArrays_thenGetExpectedResult() { + String[] strArray1 = new String[] { "Java", "is", "great" }; + String[] strArray2 = new String[] { "Java", "is", "great" }; + + assertFalse(strArray1 == strArray2); + assertFalse(strArray1.equals(strArray2)); + assertTrue(Arrays.equals(strArray1, strArray2)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-operations-basic/src/test/java/com/baeldung/arrayindex/ArrayIndexUnitTest.java b/core-java-modules/core-java-arrays-operations-basic/src/test/java/com/baeldung/arrayindex/ArrayIndexUnitTest.java new file mode 100644 index 0000000000..84c868d5e0 --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-basic/src/test/java/com/baeldung/arrayindex/ArrayIndexUnitTest.java @@ -0,0 +1,106 @@ +package com.baeldung.arrayindex; + +import static com.baeldung.arrayindex.ArrayIndex.forLoop; +import static com.baeldung.arrayindex.ArrayIndex.intStream; +import static com.baeldung.arrayindex.ArrayIndex.listIndexOf; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; + +import org.apache.commons.lang3.ArrayUtils; +import org.junit.jupiter.api.Test; + +import com.google.common.primitives.Ints; + +class ArrayIndexUnitTest { + + @Test + void givenIntegerArray_whenUseForLoop_thenWillGetElementIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(2, forLoop(numbers, 30)); + } + + @Test + void givenIntegerArray_whenUseForLoop_thenWillGetElementMinusOneIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(-1, forLoop(numbers, 100)); + } + + @Test + void givenIntegerArray_whenUseIndexOf_thenWillGetElementIndex() { + Integer[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(2, listIndexOf(numbers, 30)); + } + + @Test + void givenIntegerArray_whenUseIndexOf_thenWillGetElementMinusOneIndex() { + Integer[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(-1, listIndexOf(numbers, 100)); + } + + @Test + void givenIntegerArray_whenUseIntStream_thenWillGetElementIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(2, intStream(numbers, 30)); + } + + @Test + void givenIntegerArray_whenUseIntStream_thenWillGetElementMinusOneIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(-1, intStream(numbers, 100)); + } + + @Test + void givenIntegerArray_whenUseBinarySearch_thenWillGetElementIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(2, Arrays.binarySearch(numbers, 30)); + } + + @Test + void givenIntegerArray_whenUseBinarySearch_thenWillGetUpperBoundMinusIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(-6, Arrays.binarySearch(numbers, 100)); + } + + @Test + void givenIntegerArray_whenUseBinarySearch_thenWillGetInArrayMinusIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(-2, Arrays.binarySearch(numbers, 15)); + } + + @Test + void givenIntegerArray_whenUseBinarySearch_thenWillGetLowerBoundMinusIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(-1, Arrays.binarySearch(numbers, -15)); + } + + @Test + void givenIntegerArray_whenUseApacheCommons_thenWillGetElementIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(2, ArrayUtils.indexOf(numbers, 30)); + } + + @Test + void givenIntegerArray_whenUseApacheCommonsStartingFromIndex_thenWillGetNegativeIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(-1, ArrayUtils.indexOf(numbers, 30, 3)); + } + + @Test + void givenIntegerArray_whenUseApacheCommons_thenWillGetElementMinusOneIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(-1, ArrayUtils.indexOf(numbers, 100)); + } + + @Test + void givenIntegerArray_whenUseGuavaInts_thenWillGetElementIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(2, Ints.indexOf(numbers, 30)); + } + + @Test + void givenIntegerArray_whenUseGuavaInts_thenWillGetElementMinusOneIndex() { + int[] numbers = { 10, 20, 30, 40, 50 }; + assertEquals(-1, Ints.indexOf(numbers, 100)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-booleans/README.md b/core-java-modules/core-java-booleans/README.md new file mode 100644 index 0000000000..fe7068c6f4 --- /dev/null +++ b/core-java-modules/core-java-booleans/README.md @@ -0,0 +1,6 @@ +## Core Java Booleans + +This module contains articles about Java Booleans. + +### Relevant Articles: +- [Convert Boolean to String in Java](https://www.baeldung.com/java-convert-boolean-to-string) diff --git a/core-java-modules/core-java-booleans/pom.xml b/core-java-modules/core-java-booleans/pom.xml new file mode 100644 index 0000000000..3b0c28208f --- /dev/null +++ b/core-java-modules/core-java-booleans/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + core-java-booleans + core-java-booleans + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + \ No newline at end of file diff --git a/core-java-modules/core-java-booleans/src/test/java/com/baeldung/booleans/BooleanToStringUnitTest.java b/core-java-modules/core-java-booleans/src/test/java/com/baeldung/booleans/BooleanToStringUnitTest.java new file mode 100644 index 0000000000..e20cc3508f --- /dev/null +++ b/core-java-modules/core-java-booleans/src/test/java/com/baeldung/booleans/BooleanToStringUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.booleans; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class BooleanToStringUnitTest { + String optionToString(String optionName, boolean optionValue) { + return String.format("The option '%s' is %s.", optionName, optionValue ? "Enabled" : "Disabled"); + } + + @Test + void givenPrimitiveBoolean_whenConvertingUsingTernaryOperator_thenSuccess() { + boolean primitiveBoolean = true; + assertEquals("true", primitiveBoolean ? "true" : "false"); + + primitiveBoolean = false; + assertEquals("false", primitiveBoolean ? "true" : "false"); + + assertEquals("The option 'IgnoreWarnings' is Enabled.", optionToString("IgnoreWarnings", true)); + } + + + @Test + void givenBooleanObject_whenConvertingUsingBooleanToString_thenSuccess() { + Boolean myBoolean = Boolean.TRUE; + assertEquals("true", myBoolean.toString()); + + myBoolean = Boolean.FALSE; + assertEquals("false", myBoolean.toString()); + + Boolean nullBoolean = null; + assertThrows(NullPointerException.class, () -> nullBoolean.toString()); + } + + @Test + void givenBooleanObject_whenConvertingUsingStringValueOf_thenSuccess() { + Boolean myBoolean = Boolean.TRUE; + assertEquals("true", String.valueOf(myBoolean)); + + myBoolean = Boolean.FALSE; + assertEquals("false", String.valueOf(myBoolean)); + + Boolean nullBoolean = null; + assertEquals("null", String.valueOf(nullBoolean)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-char/README.md b/core-java-modules/core-java-char/README.md index 5f33aa6914..e4af3121c5 100644 --- a/core-java-modules/core-java-char/README.md +++ b/core-java-modules/core-java-char/README.md @@ -4,3 +4,4 @@ This module contains articles about Java Character Class ### Relevant Articles: - [Character#isAlphabetic vs. Character#isLetter](https://www.baeldung.com/java-character-isletter-isalphabetic) +- [Difference Between Java’s “char” and “String”](https://www.baeldung.com/java-char-vs-string) diff --git a/core-java-modules/core-java-char/pom.xml b/core-java-modules/core-java-char/pom.xml index 7dc0923fb5..eb6cbee952 100644 --- a/core-java-modules/core-java-char/pom.xml +++ b/core-java-modules/core-java-char/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-char - 0.1.0-SNAPSHOT core-java-char jar diff --git a/core-java-modules/core-java-char/src/test/java/com/baeldung/charandstring/DifferenceBetweenCharAndStringUnitTest.java b/core-java-modules/core-java-char/src/test/java/com/baeldung/charandstring/DifferenceBetweenCharAndStringUnitTest.java new file mode 100644 index 0000000000..b4e1da6d71 --- /dev/null +++ b/core-java-modules/core-java-char/src/test/java/com/baeldung/charandstring/DifferenceBetweenCharAndStringUnitTest.java @@ -0,0 +1,56 @@ +package com.baeldung.charandstring; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + +import org.junit.jupiter.api.Test; + +public class DifferenceBetweenCharAndStringUnitTest { + + @Test + void whenPlusTwoChars_thenGetSumAsInteger() { + char h = 'H'; // the value is 72 + char i = 'i'; // the value is 105 + assertEquals(177, h + i); + assertInstanceOf(Integer.class, h + i); + } + + @Test + void whenPlusTwoStrings_thenConcatenateThem() { + String i = "i"; + String h = "H"; + assertEquals("Hi", h + i); + } + + @Test + void whenPlusCharsAndStrings_thenGetExpectedValues() { + char c = 'C'; + assertEquals("C", "" + c); + + char h = 'H'; // the value is 72 + char i = 'i'; // the value is 105 + assertEquals("Hi", "" + h + i); + assertEquals("Hi", h + "" + i); + assertEquals("177", h + i + ""); + } + + @Test + void whenStringChars_thenGetCharArray() { + char h = 'h'; + char e = 'e'; + char l = 'l'; + char o = 'o'; + + String hello = "hello"; + assertEquals(h, hello.charAt(0)); + assertEquals(e, hello.charAt(1)); + assertEquals(l, hello.charAt(2)); + assertEquals(l, hello.charAt(3)); + assertEquals(o, hello.charAt(4)); + + char[] chars = new char[] { h, e, l, l, o }; + char[] charsFromString = hello.toCharArray(); + assertArrayEquals(chars, charsFromString); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-3/pom.xml b/core-java-modules/core-java-collections-3/pom.xml index 6ef8e3c81a..373dc9db14 100644 --- a/core-java-modules/core-java-collections-3/pom.xml +++ b/core-java-modules/core-java-collections-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-3 - 0.1.0-SNAPSHOT core-java-collections-3 jar diff --git a/core-java-modules/core-java-collections-4/pom.xml b/core-java-modules/core-java-collections-4/pom.xml index e88d5a6740..1a59411ecb 100644 --- a/core-java-modules/core-java-collections-4/pom.xml +++ b/core-java-modules/core-java-collections-4/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-4 - 0.1.0-SNAPSHOT core-java-collections-4 jar diff --git a/core-java-modules/core-java-collections-5/pom.xml b/core-java-modules/core-java-collections-5/pom.xml index 67c9f7120c..84f62c696d 100644 --- a/core-java-modules/core-java-collections-5/pom.xml +++ b/core-java-modules/core-java-collections-5/pom.xml @@ -1,11 +1,22 @@ - 4.0.0 core-java-collections-5 - 0.0.1-SNAPSHOT core-java-collections-5 + + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + jar @@ -55,4 +66,5 @@ 0.9.38 1.36 + diff --git a/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/arrayandlistperformance/ArrayAndArrayListPerformance.java b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/arrayandlistperformance/ArrayAndArrayListPerformance.java new file mode 100644 index 0000000000..f8a113ff69 --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/arrayandlistperformance/ArrayAndArrayListPerformance.java @@ -0,0 +1,77 @@ +package com.baeldung.arrayandlistperformance; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.concurrent.TimeUnit; + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +public class ArrayAndArrayListPerformance { + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.runner.Runner runner = new org.openjdk.jmh.runner.Runner(new OptionsBuilder().include(ArrayAndArrayListPerformance.class.getSimpleName()).forks(1).build()); + runner.run(); + } + public static Integer[] array = Collections.nCopies(1000000, 1).toArray(new Integer[0]); + public static ArrayList list = new ArrayList( + Arrays.asList(array)); + @Benchmark + public Integer[] arrayCreation() { + return new Integer[1000000]; + } + + @Benchmark + public ArrayList arrayListCreation() { + return new ArrayList<>(1000000); + } + + @Benchmark + public Integer[] arrayItemsSetting() { + for (int i = 0; i < 1000000; i++) { + array[i] = i; + } + return array; + } + + @Benchmark + public ArrayList arrayListItemsSetting() { + for (int i = 0; i < 1000000; i++) { + list.add(i); + } + return list; + } + + @Benchmark + public void arrayItemsRetrieval(Blackhole blackhole) { + for (int i = 0; i < 1000000; i++) { + int item = array[i]; + blackhole.consume(item); + } + } + + @Benchmark + public void arrayListItemsRetrieval(Blackhole blackhole) { + for (int i = 0; i < 1000000; i++) { + int item = list.get(i); + blackhole.consume(item); + } + } + + @Benchmark + public void arrayCloning(Blackhole blackhole) { + Integer[] newArray = array.clone(); + blackhole.consume(newArray); + } + + @Benchmark + public void arrayListCloning(Blackhole blackhole) { + ArrayList newList = new ArrayList<>(list); + blackhole.consume(newList); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/customiterators/CustomMovieIterator.java b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/customiterators/CustomMovieIterator.java new file mode 100644 index 0000000000..a1e34dd4c5 --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/customiterators/CustomMovieIterator.java @@ -0,0 +1,39 @@ +package com.baeldung.customiterators; + +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +public class CustomMovieIterator implements Iterator { + private int currentIndex; + private final List list; + + public CustomMovieIterator(List list) { + this.list = list; + this.currentIndex = 0; + } + + @Override + public boolean hasNext() { + while (currentIndex < list.size()) { + Movie currentMovie = list.get(currentIndex); + if (isMovieEligible(currentMovie)) { + return true; + } + currentIndex++; + } + return false; + } + + @Override + public Movie next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return list.get(currentIndex++); + } + + private boolean isMovieEligible(Movie movie) { + return movie.getRating() >= 8; + } +} diff --git a/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/customiterators/Movie.java b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/customiterators/Movie.java new file mode 100644 index 0000000000..e1188e69bf --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/customiterators/Movie.java @@ -0,0 +1,37 @@ +package com.baeldung.customiterators; + +public class Movie { + private String name; + private String director; + private float rating; + + public Movie(String name, String director, float rating) { + this.name = name; + this.director = director; + this.rating = rating; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDirector() { + return director; + } + + public void setDirector(String director) { + this.director = director; + } + + public float getRating() { + return rating; + } + + public void setRating(float rating) { + this.rating = rating; + } +} diff --git a/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/customiterators/MyList.java b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/customiterators/MyList.java new file mode 100644 index 0000000000..a0b2f4a943 --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/customiterators/MyList.java @@ -0,0 +1,139 @@ +package com.baeldung.customiterators; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +/** + * Please note that this class has been added for representation purposes of how a custom collection and its iterator would be. + * This does not have working code. + */ +public class MyList implements List { + @Override + public int size() { + return 0; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean contains(Object o) { + return false; + } + + @Override + public boolean add(E e) { + return false; + } + + @Override + public boolean remove(Object o) { + return false; + } + + @Override + public Iterator iterator() { + return new MyListIterator(); + } + + private class MyListIterator implements Iterator { + @Override + public boolean hasNext() { + return false; + } + + @Override + public E next() { + return null; + } + } + + @Override + public Object[] toArray() { + return new Object[0]; + } + + @Override + public T[] toArray(T[] a) { + return null; + } + + @Override + public boolean containsAll(Collection c) { + return false; + } + + @Override + public boolean addAll(Collection c) { + return false; + } + + @Override + public boolean addAll(int index, Collection c) { + return false; + } + + @Override + public boolean removeAll(Collection c) { + return false; + } + + @Override + public boolean retainAll(Collection c) { + return false; + } + + @Override + public void clear() { + + } + + @Override + public E get(int index) { + return null; + } + + @Override + public E set(int index, E element) { + return null; + } + + @Override + public void add(int index, E element) { + + } + + @Override + public E remove(int index) { + return null; + } + + @Override + public int indexOf(Object o) { + return 0; + } + + @Override + public int lastIndexOf(Object o) { + return 0; + } + + @Override + public ListIterator listIterator() { + return null; + } + + @Override + public ListIterator listIterator(int index) { + return null; + } + + @Override + public List subList(int fromIndex, int toIndex) { + return null; + } +} diff --git a/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/customiterators/PalindromIterator.java b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/customiterators/PalindromIterator.java new file mode 100644 index 0000000000..50263f52ec --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/customiterators/PalindromIterator.java @@ -0,0 +1,44 @@ +package com.baeldung.customiterators; + +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +public class PalindromIterator implements Iterator { + private final List list; + private int currentIndex; + + public PalindromIterator(List list) { + this.list = list; + this.currentIndex = 0; + } + + @Override + public boolean hasNext() { + while (currentIndex < list.size()) { + String currString = list.get(currentIndex); + if (isPalindrome(currString)) { + return true; + } + currentIndex++; + } + return false; + } + + @Override + public String next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return list.get(currentIndex++); + } + + private boolean isPalindrome(String input) { + for (int i = 0; i < input.length() / 2; i++) { + if (input.charAt(i) != input.charAt(input.length() - i - 1)) { + return false; + } + } + return true; + } +} diff --git a/core-java-modules/core-java-collections-5/src/test/java/com/baeldung/customiterators/IteratorsUnitTest.java b/core-java-modules/core-java-collections-5/src/test/java/com/baeldung/customiterators/IteratorsUnitTest.java new file mode 100644 index 0000000000..04389eb1d2 --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/test/java/com/baeldung/customiterators/IteratorsUnitTest.java @@ -0,0 +1,53 @@ +package com.baeldung.customiterators; + +import static org.junit.Assert.assertEquals; + +import java.util.Iterator; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +public class IteratorsUnitTest { + @Test + public void givenListOfStrings_whenIteratedWithDefaultIterator() { + List listOfStrings = List.of("hello", "world", "this", "is", "a", "test"); + Iterator iterator = listOfStrings.iterator(); + Assert.assertTrue(iterator.hasNext()); + assertEquals(iterator.next(), "hello"); + } + + @Test + public void givenListOfStrings_whenPalindromIterator_thenOnlyPalindromes() { + List listOfStrings = List.of("oslo", "madam", "car", "deed", "wow", "test"); + PalindromIterator palindromIterator = new PalindromIterator(listOfStrings); + int count = 0; + while (palindromIterator.hasNext()) { + palindromIterator.next(); + count++; + } + assertEquals(count, 3); + } + + @Test + public void givenMovieList_whenMovieIteratorUsed_thenOnlyHighRatedMovies() { + List movies = getMovies(); + CustomMovieIterator movieIterator = new CustomMovieIterator(movies); + int count = 0; + while (movieIterator.hasNext()) { + movieIterator.next(); + count++; + } + assertEquals(4, movies.size()); + assertEquals(2, count); + } + + private List getMovies() { + Movie movie1 = new Movie("The Dark Knight", "Nolan", 10); + Movie movie2 = new Movie("Avatar", "Cameron", 9); + Movie movie3 = new Movie("Tenet", "Nolan", 7); + Movie movie4 = new Movie("Extraction", "Hargrave", 5); + return List.of(movie1, movie2, movie3, movie4); + } + +} diff --git a/core-java-modules/core-java-collections-array-list/pom.xml b/core-java-modules/core-java-collections-array-list/pom.xml index e3a115854c..ee0b102bb0 100644 --- a/core-java-modules/core-java-collections-array-list/pom.xml +++ b/core-java-modules/core-java-collections-array-list/pom.xml @@ -4,34 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-array-list - 0.1.0-SNAPSHOT - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${maven-compiler-plugin.source} - ${maven-compiler-plugin.target} - - - - org.apache.maven.plugins - maven-surefire-plugin - ${surefire.plugin.version} - - - --add-opens java.base/java.util=ALL-UNNAMED - - - - - - - 16 - 16 - 3.0.0-M3 - core-java-collections-array-list jar @@ -55,4 +27,33 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${maven-compiler-plugin.source} + ${maven-compiler-plugin.target} + + + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire.plugin.version} + + + --add-opens java.base/java.util=ALL-UNNAMED + + + + + + + + 16 + 16 + 3.0.0-M3 + + \ No newline at end of file diff --git a/core-java-modules/core-java-collections-conversions-2/pom.xml b/core-java-modules/core-java-collections-conversions-2/pom.xml index f6775a7a42..8cd0a6932b 100644 --- a/core-java-modules/core-java-collections-conversions-2/pom.xml +++ b/core-java-modules/core-java-collections-conversions-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-conversions-2 - 0.1.0-SNAPSHOT core-java-collections-conversions-2 jar diff --git a/core-java-modules/core-java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserList.java b/core-java-modules/core-java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserList.java index 7b6bed807b..5907c159cb 100644 --- a/core-java-modules/core-java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserList.java +++ b/core-java-modules/core-java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserList.java @@ -9,6 +9,7 @@ import java.util.Collection; */ public class UserList { + public UserList() {} private Collection users; public Collection getUsers() { diff --git a/core-java-modules/core-java-collections-conversions/pom.xml b/core-java-modules/core-java-collections-conversions/pom.xml index 08a452da51..78e9847c0a 100644 --- a/core-java-modules/core-java-collections-conversions/pom.xml +++ b/core-java-modules/core-java-collections-conversions/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-conversions - 0.1.0-SNAPSHOT core-java-collections-conversions jar diff --git a/core-java-modules/core-java-collections-list-2/pom.xml b/core-java-modules/core-java-collections-list-2/pom.xml index 59ab8c5f27..a305cdffc8 100644 --- a/core-java-modules/core-java-collections-list-2/pom.xml +++ b/core-java-modules/core-java-collections-list-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-list-2 - 0.1.0-SNAPSHOT core-java-collections-list-2 jar diff --git a/core-java-modules/core-java-collections-list-3/pom.xml b/core-java-modules/core-java-collections-list-3/pom.xml index 912204bcc6..f01fe1f3b9 100644 --- a/core-java-modules/core-java-collections-list-3/pom.xml +++ b/core-java-modules/core-java-collections-list-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-list-3 - 0.1.0-SNAPSHOT core-java-collections-list-3 jar diff --git a/core-java-modules/core-java-collections-list-4/pom.xml b/core-java-modules/core-java-collections-list-4/pom.xml index 964ea4f5a1..6d068298ec 100644 --- a/core-java-modules/core-java-collections-list-4/pom.xml +++ b/core-java-modules/core-java-collections-list-4/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-list-4 - 0.1.0-SNAPSHOT core-java-collections-list-4 jar diff --git a/core-java-modules/core-java-collections-list-5/pom.xml b/core-java-modules/core-java-collections-list-5/pom.xml index 0807f7612c..2269cce9fd 100644 --- a/core-java-modules/core-java-collections-list-5/pom.xml +++ b/core-java-modules/core-java-collections-list-5/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-list-5 - 0.1.0-SNAPSHOT core-java-collections-list-5 jar @@ -15,6 +14,11 @@ + + org.openjdk.jmh + jmh-core + 1.36 + commons-lang commons-lang @@ -25,11 +29,24 @@ commons-lang3 ${commons-lang3.version} + + + org.apache.commons + commons-collections4 + 4.4 + + + + org.projectlombok + lombok + 1.18.26 + provided + + 1.21 2.2 3.12.0 - \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list-5/src/main/java/com/baeldung/arrayandlistperformance/ArrayAndArrayListPerformance.java b/core-java-modules/core-java-collections-list-5/src/main/java/com/baeldung/arrayandlistperformance/ArrayAndArrayListPerformance.java new file mode 100644 index 0000000000..3b8fa8c9f3 --- /dev/null +++ b/core-java-modules/core-java-collections-list-5/src/main/java/com/baeldung/arrayandlistperformance/ArrayAndArrayListPerformance.java @@ -0,0 +1,65 @@ +package com.baeldung.arrayandlistperformance; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import java.util.ArrayList; +import java.util.concurrent.TimeUnit; +@State(Scope.Benchmark) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +public class ArrayAndArrayListPerformance { + + @Benchmark + public void arrayCreation() { + int[] array = new int[1000000]; + } + + @Benchmark + public void arrayListCreation() { + ArrayList list = new ArrayList<>(1000000); + } + + @Benchmark + public void arrayItemSetting() { + int[] array = new int[1000000]; + array[0] = 10; + } + + @Benchmark + public void arrayListItemSetting() { + ArrayList list = new ArrayList<>(1000000); + list.add(0, 10); + } + + @Benchmark + public void arrayItemRetrieval() { + int[] array = new int[1000000]; + array[0] = 10; + int item = array[0]; + } + + @Benchmark + public void arrayListItemRetrieval() { + ArrayList list = new ArrayList<>(1000000); + list.add(0, 10); + int item2 = list.get(0); + } + + @Benchmark + public void arrayCloning() { + int[] array = new int[1000000]; + int[] newArray = array.clone(); + } + + @Benchmark + public void arrayListCloning() { + ArrayList list = new ArrayList<>(1000000); + ArrayList newList = new ArrayList<>(list); + } + public static void main(String[] args) throws Exception { + org.openjdk.jmh.runner.Runner runner = new org.openjdk.jmh.runner.Runner(new OptionsBuilder() + .include(ArrayAndArrayListPerformance.class.getSimpleName()) + .forks(1) + .build()); + runner.run(); + } + } \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list-5/src/main/java/com/baeldung/list/Country.java b/core-java-modules/core-java-collections-list-5/src/main/java/com/baeldung/list/Country.java new file mode 100644 index 0000000000..354aeca2d3 --- /dev/null +++ b/core-java-modules/core-java-collections-list-5/src/main/java/com/baeldung/list/Country.java @@ -0,0 +1,11 @@ +package com.baeldung.list; + +import lombok.Data; + +@Data +public class Country { + + private final String name; + private final String capital; + +} diff --git a/core-java-modules/core-java-collections-list-5/src/test/java/com/baeldung/java/list/ListContainsElementFromOtherListTest.java b/core-java-modules/core-java-collections-list-5/src/test/java/com/baeldung/java/list/ListContainsElementFromOtherListTest.java new file mode 100644 index 0000000000..0f47f7713a --- /dev/null +++ b/core-java-modules/core-java-collections-list-5/src/test/java/com/baeldung/java/list/ListContainsElementFromOtherListTest.java @@ -0,0 +1,68 @@ +package com.baeldung.java.list; + +import static java.util.stream.Collectors.toSet; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.collections4.CollectionUtils; +import org.junit.Test; + +import com.baeldung.list.Country; + +public class ListContainsElementFromOtherListTest { + + final private List listOfLetters = Arrays.asList("a", "b", "c", "d"); + final private List listOfLettersWithOverlap = Arrays.asList("d", "e", "f", "g"); + final private List listOfCities = Arrays.asList("London", "Berlin", "Paris", "Brussels"); + + @Test + public void givenValuesToCompare_whenUsingCollectionsDisjoint_thenDetectElementsInTwoLists() { + boolean shouldBeTrue = !Collections.disjoint(listOfLetters, listOfLettersWithOverlap); + assertTrue(shouldBeTrue); + + boolean shouldBeFalse = !Collections.disjoint(listOfLetters, listOfCities); + assertFalse(shouldBeFalse); + } + + @Test + public void givenValuesToCompare_whenUsingStreams_thenDetectElementsInTwoLists() { + boolean shouldBeTrue = listOfLetters.stream() + .anyMatch(listOfLettersWithOverlap::contains); + assertTrue(shouldBeTrue); + + boolean shouldBeFalse = listOfLetters.stream() + .anyMatch(listOfCities::contains); + assertFalse(shouldBeFalse); + } + + @Test + public void givenValuesToCompare_whenUsingApacheCollectionUtils_thenDetectElementsInTwoLists() { + boolean shouldBeTrue = CollectionUtils.containsAny(listOfLetters, listOfLettersWithOverlap); + assertTrue(shouldBeTrue); + + boolean shouldBeFalse = CollectionUtils.containsAny(listOfLetters, listOfCities); + assertFalse(shouldBeFalse); + } + + @Test + public void givenPropertiesInObjectsToCompare_whenUsingStreams_thenDetectElementsInTwoLists() { + Country france = new Country("France", "Paris"); + Country belgium = new Country("Belgium", "Brussels"); + Country spain = new Country("Spain", "Madrid"); + List franceAndBelgium = Arrays.asList(france, belgium); + List belgiumAndSpain = Arrays.asList(belgium, spain); + + boolean shouldBeTrue = franceAndBelgium.stream() + .map(Country::getCapital) + .anyMatch(belgiumAndSpain.stream() + .map(Country::getCapital) + .collect(toSet())::contains); + + assertTrue(shouldBeTrue); + } + +} diff --git a/core-java-modules/core-java-collections-list/pom.xml b/core-java-modules/core-java-collections-list/pom.xml index 0cc8828a0d..94abb334e0 100644 --- a/core-java-modules/core-java-collections-list/pom.xml +++ b/core-java-modules/core-java-collections-list/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-list - 0.1.0-SNAPSHOT core-java-collections-list jar diff --git a/core-java-modules/core-java-collections-list/src/test/java/com/baeldung/java8/Java8MaxMinUnitTest.java b/core-java-modules/core-java-collections-list/src/test/java/com/baeldung/java8/Java8MaxMinUnitTest.java index c2cc39c685..e634fddab8 100644 --- a/core-java-modules/core-java-collections-list/src/test/java/com/baeldung/java8/Java8MaxMinUnitTest.java +++ b/core-java-modules/core-java-collections-list/src/test/java/com/baeldung/java8/Java8MaxMinUnitTest.java @@ -6,6 +6,7 @@ import com.baeldung.java_8_features.Person; import org.junit.Test; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.NoSuchElementException; @@ -71,4 +72,17 @@ public class Java8MaxMinUnitTest { assertEquals(bugatti, maxBySpeed); } + + @Test + public void givenIntegerList_whenGetMinAndIndex_thenSuccess() { + final List listOfIntegers = Arrays.asList(11, 13, 9, 20, 7, 3, 30); + final Integer expectedMinValue = 3; + final Integer expectedMinIndex = 5; + + Integer minValue = Collections.min(listOfIntegers); + Integer minIndex = listOfIntegers.indexOf(minValue); + + assertEquals(minValue, expectedMinValue); + assertEquals(minIndex, expectedMinIndex); + } } diff --git a/core-java-modules/core-java-collections-maps-2/pom.xml b/core-java-modules/core-java-collections-maps-2/pom.xml index 1e526ef892..15ca688ad2 100644 --- a/core-java-modules/core-java-collections-maps-2/pom.xml +++ b/core-java-modules/core-java-collections-maps-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-maps-2 - 0.1.0-SNAPSHOT core-java-collections-maps-2 jar diff --git a/core-java-modules/core-java-collections-maps-3/pom.xml b/core-java-modules/core-java-collections-maps-3/pom.xml index a5bb6dc338..98a0d18fe9 100644 --- a/core-java-modules/core-java-collections-maps-3/pom.xml +++ b/core-java-modules/core-java-collections-maps-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-maps-3 - 0.1.0-SNAPSHOT core-java-collections-maps-3 jar diff --git a/core-java-modules/core-java-collections-maps-4/pom.xml b/core-java-modules/core-java-collections-maps-4/pom.xml index a85e2cde2a..f1734b7379 100644 --- a/core-java-modules/core-java-collections-maps-4/pom.xml +++ b/core-java-modules/core-java-collections-maps-4/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-maps-4 - 0.1.0-SNAPSHOT core-java-collections-maps-4 jar diff --git a/core-java-modules/core-java-collections-maps-5/pom.xml b/core-java-modules/core-java-collections-maps-5/pom.xml index f12e044b23..593ec5a8f6 100644 --- a/core-java-modules/core-java-collections-maps-5/pom.xml +++ b/core-java-modules/core-java-collections-maps-5/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-maps-5 - 0.1.0-SNAPSHOT core-java-collections-maps-5 jar diff --git a/core-java-modules/core-java-collections-maps-6/pom.xml b/core-java-modules/core-java-collections-maps-6/pom.xml index 9910d08691..8c35dcee6e 100644 --- a/core-java-modules/core-java-collections-maps-6/pom.xml +++ b/core-java-modules/core-java-collections-maps-6/pom.xml @@ -1,20 +1,54 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 core-java-collections-maps-6 - 0.1.0-SNAPSHOT core-java-collections-maps-6 jar + core-java-modules com.baeldung.core-java-modules 0.0.1-SNAPSHOT - 4.0.0 5.2.5.RELEASE + + + com.fasterxml.jackson.core + jackson-databind + 2.13.1 + + + org.openjdk.jmh + jmh-core + 1.36 + + + com.google.code.gson + gson + 2.8.9 + + + org.json + json + 20230227 + + + junit + junit + 4.13.1 + test + + + org.junit.jupiter + junit-jupiter + 5.8.1 + test + + \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-6/src/test/java/com/baeldung/maptojson/MapToJsonUnitTest.java b/core-java-modules/core-java-collections-maps-6/src/test/java/com/baeldung/maptojson/MapToJsonUnitTest.java new file mode 100644 index 0000000000..7a9f046a94 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-6/src/test/java/com/baeldung/maptojson/MapToJsonUnitTest.java @@ -0,0 +1,65 @@ +package com.baeldung.maptojson; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonSyntaxException; +import com.google.gson.TypeAdapter; +import com.google.gson.reflect.TypeToken; +import org.json.JSONObject; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +public class MapToJsonUnitTest { + final TypeAdapter strictAdapter = new Gson().getAdapter(JsonElement.class); + + public boolean isValid(String json) { + try { + strictAdapter.fromJson(json); + } catch (JsonSyntaxException | IOException e) { + return false; + } + return true; + } + + @Test + public void given_HashMapData_whenUsingJackson_thenConvertToJson() throws JsonProcessingException { + Map data = new HashMap(); + data.put("CS", "Post1"); + data.put("Linux", "Post1"); + data.put("Kotlin", "Post1"); + ObjectMapper objectMapper = new ObjectMapper(); + String jacksonData = objectMapper.writeValueAsString(data); + Assertions.assertTrue(isValid(jacksonData)); + } + + @Test + public void given_HashMapData_whenUsingGson_thenConvertToJson() { + Map data = new HashMap<>(); + data.put("CS", "Post1"); + data.put("Linux", "Post1"); + data.put("Kotlin", "Post1"); + Gson gson = new Gson(); + Type typeObject = new TypeToken() { + }.getType(); + String gsonData = gson.toJson(data, typeObject); + Assertions.assertTrue(isValid(gsonData)); + } + + @Test + public void given_HashMapData_whenOrgJson_thenConvertToJsonUsing() { + Map data = new HashMap<>(); + data.put("CS", "Post1"); + data.put("Linux", "Post1"); + data.put("Kotlin", "Post1"); + JSONObject jsonObject = new JSONObject(data); + String orgJsonData = jsonObject.toString(); + Assertions.assertTrue(isValid(orgJsonData)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps/pom.xml b/core-java-modules/core-java-collections-maps/pom.xml index 3a1bf0d8a1..5e19117e08 100644 --- a/core-java-modules/core-java-collections-maps/pom.xml +++ b/core-java-modules/core-java-collections-maps/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-maps - 0.1.0-SNAPSHOT core-java-collections-maps jar diff --git a/core-java-modules/core-java-collections-maps/src/test/java/com/baeldung/map/ImmutableMapUnitTest.java b/core-java-modules/core-java-collections-maps/src/test/java/com/baeldung/map/ImmutableMapUnitTest.java index d308aac7eb..4ac562ef04 100644 --- a/core-java-modules/core-java-collections-maps/src/test/java/com/baeldung/map/ImmutableMapUnitTest.java +++ b/core-java-modules/core-java-collections-maps/src/test/java/com/baeldung/map/ImmutableMapUnitTest.java @@ -1,84 +1,126 @@ package com.baeldung.map; -import com.google.common.collect.ImmutableMap; -import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.AbstractMap; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import static org.junit.jupiter.api.Assertions.*; +import org.hamcrest.collection.IsMapContaining; +import org.junit.jupiter.api.Test; +import com.google.common.collect.ImmutableMap; -public class ImmutableMapUnitTest { +class ImmutableMapUnitTest { - @Test - public void whenCollectionsUnModifiableMapMethod_thenOriginalCollectionChangesReflectInUnmodifiableMap() { + @Test + void whenCollectionsUnModifiableMapMethod_thenOriginalCollectionChangesReflectInUnmodifiableMap() { - Map mutableMap = new HashMap<>(); - mutableMap.put("USA", "North America"); + Map mutableMap = new HashMap<>(); + mutableMap.put("USA", "North America"); - Map unmodifiableMap = Collections.unmodifiableMap(mutableMap); - assertThrows(UnsupportedOperationException.class, () -> unmodifiableMap.put("Canada", "North America")); - - mutableMap.remove("USA"); - assertFalse(unmodifiableMap.containsKey("USA")); - - mutableMap.put("Mexico", "North America"); - assertTrue(unmodifiableMap.containsKey("Mexico")); - } - - @Test - @SuppressWarnings("deprecation") - public void whenGuavaImmutableMapFromCopyOfMethod_thenOriginalCollectionChangesDoNotReflectInImmutableMap() { + Map unmodifiableMap = Collections.unmodifiableMap(mutableMap); + assertThrows(UnsupportedOperationException.class, () -> unmodifiableMap.put("Canada", "North America")); - Map mutableMap = new HashMap<>(); - mutableMap.put("USA", "North America"); + mutableMap.remove("USA"); + assertFalse(unmodifiableMap.containsKey("USA")); - ImmutableMap immutableMap = ImmutableMap.copyOf(mutableMap); - assertTrue(immutableMap.containsKey("USA")); - - assertThrows(UnsupportedOperationException.class, () -> immutableMap.put("Canada", "North America")); - - mutableMap.remove("USA"); - assertTrue(immutableMap.containsKey("USA")); - - mutableMap.put("Mexico", "North America"); - assertFalse(immutableMap.containsKey("Mexico")); - } - - @Test - @SuppressWarnings("deprecation") - public void whenGuavaImmutableMapFromBuilderMethod_thenOriginalCollectionChangesDoNotReflectInImmutableMap() { + mutableMap.put("Mexico", "North America"); + assertTrue(unmodifiableMap.containsKey("Mexico")); + } - Map mutableMap = new HashMap<>(); - mutableMap.put("USA", "North America"); + @Test + @SuppressWarnings("deprecation") + void whenGuavaImmutableMapFromCopyOfMethod_thenOriginalCollectionChangesDoNotReflectInImmutableMap() { - ImmutableMap immutableMap = ImmutableMap.builder() - .putAll(mutableMap) - .put("Costa Rica", "North America") - .build(); - assertTrue(immutableMap.containsKey("USA")); - assertTrue(immutableMap.containsKey("Costa Rica")); - - assertThrows(UnsupportedOperationException.class, () -> immutableMap.put("Canada", "North America")); - - mutableMap.remove("USA"); - assertTrue(immutableMap.containsKey("USA")); - - mutableMap.put("Mexico", "North America"); - assertFalse(immutableMap.containsKey("Mexico")); - } - - @Test - @SuppressWarnings("deprecation") - public void whenGuavaImmutableMapFromOfMethod_thenOriginalCollectionChangesDoNotReflectInImmutableMap() { + Map mutableMap = new HashMap<>(); + mutableMap.put("USA", "North America"); - ImmutableMap immutableMap = ImmutableMap.of("USA", "North America", "Costa Rica", "North America"); - assertTrue(immutableMap.containsKey("USA")); - assertTrue(immutableMap.containsKey("Costa Rica")); + ImmutableMap immutableMap = ImmutableMap.copyOf(mutableMap); + assertTrue(immutableMap.containsKey("USA")); + + assertThrows(UnsupportedOperationException.class, () -> immutableMap.put("Canada", "North America")); + + mutableMap.remove("USA"); + assertTrue(immutableMap.containsKey("USA")); + + mutableMap.put("Mexico", "North America"); + assertFalse(immutableMap.containsKey("Mexico")); + } + + @Test + @SuppressWarnings("deprecation") + void whenGuavaImmutableMapFromBuilderMethod_thenOriginalCollectionChangesDoNotReflectInImmutableMap() { + + Map mutableMap = new HashMap<>(); + mutableMap.put("USA", "North America"); + + ImmutableMap immutableMap = ImmutableMap.builder() + .putAll(mutableMap) + .put("Costa Rica", "North America") + .build(); + assertTrue(immutableMap.containsKey("USA")); + assertTrue(immutableMap.containsKey("Costa Rica")); + + assertThrows(UnsupportedOperationException.class, () -> immutableMap.put("Canada", "North America")); + + mutableMap.remove("USA"); + assertTrue(immutableMap.containsKey("USA")); + + mutableMap.put("Mexico", "North America"); + assertFalse(immutableMap.containsKey("Mexico")); + } + + @Test + @SuppressWarnings("deprecation") + void whenGuavaImmutableMapFromOfMethod_thenOriginalCollectionChangesDoNotReflectInImmutableMap() { + + ImmutableMap immutableMap = ImmutableMap.of("USA", "North America", "Costa Rica", "North America"); + assertTrue(immutableMap.containsKey("USA")); + assertTrue(immutableMap.containsKey("Costa Rica")); + + assertThrows(UnsupportedOperationException.class, () -> immutableMap.put("Canada", "North America")); + } + + @Test + @SuppressWarnings("deprecation") + void givenGuavaImmutableMapFromOfEntriesMethodwhenModifyEntry_thenThrowUnsupportedOperationException() { + + ImmutableMap immutableMap = ImmutableMap.ofEntries(new AbstractMap.SimpleEntry<>(1, "USA"), new AbstractMap.SimpleEntry<>(2, "Canada")); + + assertThrows(UnsupportedOperationException.class, () -> immutableMap.put(2, "Mexico")); + } + + @Test + void givenEntrieswhenCreatingGuavaImmutableMapFromOfEntriesMethod_thenCorrect() { + + ImmutableMap immutableMap = ImmutableMap.ofEntries(new AbstractMap.SimpleEntry<>(1, "USA")); + + assertEquals(1, immutableMap.size()); + assertThat(immutableMap, IsMapContaining.hasEntry(1, "USA")); + } + + @Test + void givenGuavaImmutableMapFromOfEntriesMethodwhenEntryKeyExists_thenThrowIllegalArgumentException() { + + assertThrows(IllegalArgumentException.class, () -> ImmutableMap.ofEntries(new AbstractMap.SimpleEntry<>(1, "USA"), new AbstractMap.SimpleEntry<>(1, "Canada"))); + } + + @Test + void givenGuavaImmutableMapFromOfEntriesMethodwhenEntryKeyIsNull_thenThrowNullPointerException() { + + assertThrows(NullPointerException.class, () -> ImmutableMap.ofEntries(new AbstractMap.SimpleEntry<>(null, "USA"))); + } + + @Test + void givenGuavaImmutableMapFromOfEntriesMethodwhenEntryValueIsNull_thenThrowNullPointerException() { + + assertThrows(NullPointerException.class, () -> ImmutableMap.ofEntries(new AbstractMap.SimpleEntry<>(1, null))); + } - assertThrows(UnsupportedOperationException.class, () -> immutableMap.put("Canada", "North America")); - } - } diff --git a/core-java-modules/core-java-collections-set-2/pom.xml b/core-java-modules/core-java-collections-set-2/pom.xml index b1aadb0c22..680c01d8ca 100644 --- a/core-java-modules/core-java-collections-set-2/pom.xml +++ b/core-java-modules/core-java-collections-set-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-set-2 - 0.0.1-SNAPSHOT core-java-collections-set-2 jar diff --git a/core-java-modules/core-java-collections-set/pom.xml b/core-java-modules/core-java-collections-set/pom.xml index 0b6e324c78..e130837f1c 100644 --- a/core-java-modules/core-java-collections-set/pom.xml +++ b/core-java-modules/core-java-collections-set/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-set - 0.1.0-SNAPSHOT core-java-collections-set jar diff --git a/core-java-modules/core-java-collections/pom.xml b/core-java-modules/core-java-collections/pom.xml index eab7a35584..be91492d06 100644 --- a/core-java-modules/core-java-collections/pom.xml +++ b/core-java-modules/core-java-collections/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections - 0.1.0-SNAPSHOT core-java-collections jar diff --git a/core-java-modules/core-java-compiler/README.md b/core-java-modules/core-java-compiler/README.md new file mode 100644 index 0000000000..2a1e609194 --- /dev/null +++ b/core-java-modules/core-java-compiler/README.md @@ -0,0 +1,6 @@ +## Core Java Compiler + +### Relevant Articles: + +- [Compiling Java *.class Files with javac](http://www.baeldung.com/javac) +- [Illegal Character Compilation Error](https://www.baeldung.com/java-illegal-character-error) diff --git a/core-java-modules/core-java-compiler/pom.xml b/core-java-modules/core-java-compiler/pom.xml new file mode 100644 index 0000000000..8f2be3f142 --- /dev/null +++ b/core-java-modules/core-java-compiler/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + core-java-compiler + 0.1.0-SNAPSHOT + core-java-compiler + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + com.google.gdata + core + ${gdata.version} + + + + + 1.47.1 + + + \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/javac/Data.java b/core-java-modules/core-java-compiler/src/main/java/com/baeldung/javac/Data.java similarity index 100% rename from core-java-modules/core-java/src/main/java/com/baeldung/javac/Data.java rename to core-java-modules/core-java-compiler/src/main/java/com/baeldung/javac/Data.java diff --git a/core-java-modules/core-java/src/main/java/javac-args/arguments b/core-java-modules/core-java-compiler/src/main/java/javac-args/arguments similarity index 100% rename from core-java-modules/core-java/src/main/java/javac-args/arguments rename to core-java-modules/core-java-compiler/src/main/java/javac-args/arguments diff --git a/core-java-modules/core-java/src/main/java/javac-args/options b/core-java-modules/core-java-compiler/src/main/java/javac-args/options similarity index 100% rename from core-java-modules/core-java/src/main/java/javac-args/options rename to core-java-modules/core-java-compiler/src/main/java/javac-args/options diff --git a/core-java-modules/core-java/src/main/java/javac-args/types b/core-java-modules/core-java-compiler/src/main/java/javac-args/types similarity index 100% rename from core-java-modules/core-java/src/main/java/javac-args/types rename to core-java-modules/core-java-compiler/src/main/java/javac-args/types diff --git a/core-java-modules/core-java/src/main/java/javac-args/xlint-ops b/core-java-modules/core-java-compiler/src/main/java/javac-args/xlint-ops similarity index 100% rename from core-java-modules/core-java/src/main/java/javac-args/xlint-ops rename to core-java-modules/core-java-compiler/src/main/java/javac-args/xlint-ops diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/illegalcharacter/IllegalCharacterUnitTest.java b/core-java-modules/core-java-compiler/src/test/java/com/baeldung/illegalcharacter/IllegalCharacterUnitTest.java similarity index 100% rename from core-java-modules/core-java/src/test/java/com/baeldung/illegalcharacter/IllegalCharacterUnitTest.java rename to core-java-modules/core-java-compiler/src/test/java/com/baeldung/illegalcharacter/IllegalCharacterUnitTest.java diff --git a/core-java-modules/core-java/src/test/resources/bom-file.txt b/core-java-modules/core-java-compiler/src/test/resources/bom-file.txt similarity index 100% rename from core-java-modules/core-java/src/test/resources/bom-file.txt rename to core-java-modules/core-java-compiler/src/test/resources/bom-file.txt diff --git a/core-java-modules/core-java-concurrency-2/pom.xml b/core-java-modules/core-java-concurrency-2/pom.xml index c61f28a6b3..e373c829cc 100644 --- a/core-java-modules/core-java-concurrency-2/pom.xml +++ b/core-java-modules/core-java-concurrency-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-concurrency-2 - 0.1.0-SNAPSHOT core-java-concurrency-2 jar diff --git a/core-java-modules/core-java-concurrency-advanced-2/pom.xml b/core-java-modules/core-java-concurrency-advanced-2/pom.xml index 1f19dc8cca..5c96684311 100644 --- a/core-java-modules/core-java-concurrency-advanced-2/pom.xml +++ b/core-java-modules/core-java-concurrency-advanced-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-concurrency-advanced-2 - 0.1.0-SNAPSHOT core-java-concurrency-advanced-2 jar diff --git a/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java b/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerManualTest.java similarity index 93% rename from core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java rename to core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerManualTest.java index 20e6a5ef5b..bd71cfc263 100644 --- a/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java +++ b/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerManualTest.java @@ -2,7 +2,8 @@ package com.baeldung.concurrent.prioritytaskexecution; import org.junit.Test; -public class PriorityJobSchedulerUnitTest { +//Converted to ManualTest due to thread sleep +public class PriorityJobSchedulerManualTest { private static final int POOL_SIZE = 1; private static final int QUEUE_SIZE = 10; diff --git a/core-java-modules/core-java-concurrency-advanced-3/pom.xml b/core-java-modules/core-java-concurrency-advanced-3/pom.xml index 49a72112b4..7fa859c2d5 100644 --- a/core-java-modules/core-java-concurrency-advanced-3/pom.xml +++ b/core-java-modules/core-java-concurrency-advanced-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-concurrency-advanced-3 - 0.1.0-SNAPSHOT core-java-concurrency-advanced-3 jar diff --git a/core-java-modules/core-java-concurrency-advanced-4/pom.xml b/core-java-modules/core-java-concurrency-advanced-4/pom.xml index 5bd7ccfa07..2ffe19b13c 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/pom.xml +++ b/core-java-modules/core-java-concurrency-advanced-4/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-concurrency-advanced-4 - 0.1.0-SNAPSHOT core-java-concurrency-advanced-4 jar @@ -14,9 +13,6 @@ 0.0.1-SNAPSHOT - - - core-java-concurrency-advanced-4 diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java index 9bbcbb923c..933a1b5f52 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java @@ -1,6 +1,9 @@ package com.baeldung.producerconsumer; +import java.util.logging.Logger; + public class Consumer implements Runnable { + private static final Logger log = Logger.getLogger(Consumer.class.getCanonicalName()); private final DataQueue dataQueue; public Consumer(DataQueue dataQueue) { @@ -14,7 +17,7 @@ public class Consumer implements Runnable { public void consume() { while (dataQueue.runFlag) { - synchronized (this) { + synchronized (dataQueue) { while (dataQueue.isEmpty() && dataQueue.runFlag) { try { dataQueue.waitOnEmpty(); @@ -31,12 +34,13 @@ public class Consumer implements Runnable { useMessage(message); } } - System.out.println("Consumer Stopped"); + log.info("Consumer Stopped"); } private void useMessage(Message message) { if (message != null) { - System.out.printf("[%s] Consuming Message. Id: %d, Data: %f\n", Thread.currentThread().getName(), message.getId(), message.getData()); + log.info(String.format("[%s] Consuming Message. Id: %d, Data: %f%n", + Thread.currentThread().getName(), message.getId(), message.getData())); //Sleeping on random time to make it realistic ThreadUtil.sleep((long) (message.getData() * 100)); diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java index 04ad39f26e..ca89d0c866 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java @@ -1,6 +1,9 @@ package com.baeldung.producerconsumer; +import java.util.logging.Logger; + public class Producer implements Runnable { + private static final Logger log = Logger.getLogger(Producer.class.getCanonicalName()); private final DataQueue dataQueue; private static int idSequence = 0; @@ -16,7 +19,7 @@ public class Producer implements Runnable { public void produce() { while (dataQueue.runFlag) { - synchronized (this) { + synchronized (dataQueue) { while (dataQueue.isFull() && dataQueue.runFlag) { try { dataQueue.waitOnFull(); @@ -33,12 +36,13 @@ public class Producer implements Runnable { dataQueue.notifyAllForEmpty(); } } - System.out.println("Producer Stopped"); + log.info("Producer Stopped"); } private Message generateMessage() { - Message message = new Message(++idSequence, Math.random()); - System.out.printf("[%s] Generated Message. Id: %d, Data: %f\n", Thread.currentThread().getName(), message.getId(), message.getData()); + Message message = new Message(incrementAndGetId(), Math.random()); + log.info(String.format("[%s] Generated Message. Id: %d, Data: %f%n", + Thread.currentThread().getName(), message.getId(), message.getData())); //Sleeping on random time to make it realistic ThreadUtil.sleep((long) (message.getData() * 100)); @@ -46,6 +50,10 @@ public class Producer implements Runnable { return message; } + private static int incrementAndGetId() { + return ++idSequence; + } + public void stop() { dataQueue.runFlag = false; dataQueue.notifyAllForFull(); diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/SimpleProducerConsumerDemonstrator.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/SimpleProducerConsumerDemonstrator.java index f1f6e1cc9c..500dc9ca07 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/SimpleProducerConsumerDemonstrator.java +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/SimpleProducerConsumerDemonstrator.java @@ -2,10 +2,12 @@ package com.baeldung.producerconsumer; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; +import java.util.logging.Logger; import static com.baeldung.producerconsumer.ThreadUtil.sleep; public class SimpleProducerConsumerDemonstrator { + private static final Logger log = Logger.getLogger(SimpleProducerConsumerDemonstrator.class.getCanonicalName()); BlockingQueue blockingQueue = new LinkedBlockingDeque<>(5); private void produce() { @@ -17,7 +19,7 @@ public class SimpleProducerConsumerDemonstrator { e.printStackTrace(); break; } - System.out.printf("[%s] Value produced: %f\n", Thread.currentThread().getName(), value); + log.info(String.format("[%s] Value produced: %f%n", Thread.currentThread().getName(), value)); } } @@ -31,7 +33,7 @@ public class SimpleProducerConsumerDemonstrator { break; } // Consume value - System.out.printf("[%s] Value consumed: %f\n", Thread.currentThread().getName(), value); + log.info(String.format("[%s] Value consumed: %f%n", Thread.currentThread().getName(), value)); } } diff --git a/core-java-modules/core-java-concurrency-advanced/pom.xml b/core-java-modules/core-java-concurrency-advanced/pom.xml index 3c726e1284..18cfc5371c 100644 --- a/core-java-modules/core-java-concurrency-advanced/pom.xml +++ b/core-java-modules/core-java-concurrency-advanced/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-concurrency-advanced - 0.1.0-SNAPSHOT core-java-concurrency-advanced jar diff --git a/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/countdownlatch/Worker.java b/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/countdownlatch/Worker.java index 389e25719b..d23f1faa69 100644 --- a/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/countdownlatch/Worker.java +++ b/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/countdownlatch/Worker.java @@ -1,9 +1,14 @@ package com.baeldung.concurrent.countdownlatch; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.List; import java.util.concurrent.CountDownLatch; public class Worker implements Runnable { + + private static Logger log = LoggerFactory.getLogger(Worker.class); private final List outputScraper; private final CountDownLatch countDownLatch; @@ -15,7 +20,7 @@ public class Worker implements Runnable { @Override public void run() { // Do some work - System.out.println("Doing some logic"); + log.debug("Doing some logic"); outputScraper.add("Counted down"); countDownLatch.countDown(); } diff --git a/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/phaser/LongRunningAction.java b/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/phaser/LongRunningAction.java index c022c02085..44f84ad77c 100644 --- a/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/phaser/LongRunningAction.java +++ b/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/phaser/LongRunningAction.java @@ -1,8 +1,13 @@ package com.baeldung.concurrent.phaser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.concurrent.Phaser; class LongRunningAction implements Runnable { + + private static Logger log = LoggerFactory.getLogger(LongRunningAction.class); private String threadName; private Phaser ph; @@ -14,18 +19,18 @@ class LongRunningAction implements Runnable { @Override public void run() { - System.out.println("This is phase " + ph.getPhase()); - System.out.println("Thread " + threadName + " before long running action"); + log.info("This is phase {}", ph.getPhase()); + log.info("Thread {} before long running action", threadName); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } - - System.out.println("Thread " + threadName + " action completed and waiting for others"); + + log.debug("Thread {} action completed and waiting for others", threadName); ph.arriveAndAwaitAdvance(); - System.out.println("Thread " + threadName + " proceeding in phase " + ph.getPhase()); + log.debug("Thread {} proceeding in phase {}", threadName, ph.getPhase()); ph.arriveAndDeregister(); } diff --git a/core-java-modules/core-java-concurrency-advanced/src/test/java/com/baeldung/concurrent/phaser/PhaserUnitTest.java b/core-java-modules/core-java-concurrency-advanced/src/test/java/com/baeldung/concurrent/phaser/PhaserUnitTest.java index 88c18b5149..384a1837c1 100644 --- a/core-java-modules/core-java-concurrency-advanced/src/test/java/com/baeldung/concurrent/phaser/PhaserUnitTest.java +++ b/core-java-modules/core-java-concurrency-advanced/src/test/java/com/baeldung/concurrent/phaser/PhaserUnitTest.java @@ -4,6 +4,9 @@ import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Phaser; @@ -13,6 +16,8 @@ import static junit.framework.TestCase.assertEquals; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class PhaserUnitTest { + private static Logger log = LoggerFactory.getLogger(PhaserUnitTest.class); + @Test public void givenPhaser_whenCoordinateWorksBetweenThreads_thenShouldCoordinateBetweenMultiplePhases() { //given @@ -26,19 +31,19 @@ public class PhaserUnitTest { executorService.submit(new LongRunningAction("thread-3", ph)); //then - System.out.println("Thread " + Thread.currentThread().getName() + " waiting for others"); + log.debug("Thread {} waiting for others", Thread.currentThread().getName()); ph.arriveAndAwaitAdvance(); - System.out.println("Thread " + Thread.currentThread().getName() + " proceeding in phase " + ph.getPhase()); + log.debug("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase()); assertEquals(1, ph.getPhase()); //and executorService.submit(new LongRunningAction("thread-4", ph)); executorService.submit(new LongRunningAction("thread-5", ph)); - - System.out.println("Thread " + Thread.currentThread().getName() + " waiting for others"); + + log.debug("Thread {} waiting for others", Thread.currentThread().getName()); ph.arriveAndAwaitAdvance(); - System.out.println("Thread " + Thread.currentThread().getName() + " proceeding in phase " + ph.getPhase()); + log.debug("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase()); assertEquals(2, ph.getPhase()); diff --git a/core-java-modules/core-java/src/main/resources/logback.xml b/core-java-modules/core-java-concurrency-advanced/src/test/resources/logback-test.xml similarity index 100% rename from core-java-modules/core-java/src/main/resources/logback.xml rename to core-java-modules/core-java-concurrency-advanced/src/test/resources/logback-test.xml diff --git a/core-java-modules/core-java-concurrency-basic-2/pom.xml b/core-java-modules/core-java-concurrency-basic-2/pom.xml index 9ca12da7fb..0cdfd68f03 100644 --- a/core-java-modules/core-java-concurrency-basic-2/pom.xml +++ b/core-java-modules/core-java-concurrency-basic-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-concurrency-basic-2 - 0.1.0-SNAPSHOT core-java-concurrency-basic-2 jar diff --git a/core-java-modules/core-java-concurrency-basic-3/README.md b/core-java-modules/core-java-concurrency-basic-3/README.md index 46480c6b01..da148599b0 100644 --- a/core-java-modules/core-java-concurrency-basic-3/README.md +++ b/core-java-modules/core-java-concurrency-basic-3/README.md @@ -6,4 +6,5 @@ This module contains articles about basic Java concurrency. - [How to Handle InterruptedException in Java](https://www.baeldung.com/java-interrupted-exception) - [Thread.sleep() vs Awaitility.await()](https://www.baeldung.com/java-thread-sleep-vs-awaitility-await) +- [Is CompletableFuture Non-blocking?](https://www.baeldung.com/java-completablefuture-non-blocking) - [[<-- Prev]](../core-java-concurrency-basic-2) diff --git a/core-java-modules/core-java-concurrency-basic-3/pom.xml b/core-java-modules/core-java-concurrency-basic-3/pom.xml index 7289877550..1983d3c163 100644 --- a/core-java-modules/core-java-concurrency-basic-3/pom.xml +++ b/core-java-modules/core-java-concurrency-basic-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-concurrency-basic-3 - 0.1.0-SNAPSHOT core-java-concurrency-basic-3 jar @@ -14,6 +13,15 @@ 0.0.1-SNAPSHOT + + + org.awaitility + awaitility + ${awaitility.version} + test + + + core-java-concurrency-basic-3 @@ -28,12 +36,4 @@ 4.2.0 - - - org.awaitility - awaitility - ${awaitility.version} - test - - \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/NonBlockingExample.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/NonBlockingExample.java new file mode 100644 index 0000000000..b97f7d0dee --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/NonBlockingExample.java @@ -0,0 +1,17 @@ +package com.baeldung.concurrent.completablefuture; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.CompletableFuture; + +public class NonBlockingExample { + + private static final Logger logger = LoggerFactory.getLogger(NonBlockingExample.class); + + public static void main(String[] args) { + CompletableFuture.supplyAsync(() -> "Baeldung") + .thenApply(String::length) + .thenAccept(s -> logger.info(String.valueOf(s))); + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/RequestProcessorUnitTest.java b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/RequestProcessorUnitTest.java index c437b08b34..4a400f7beb 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/RequestProcessorUnitTest.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/RequestProcessorUnitTest.java @@ -20,7 +20,8 @@ public class RequestProcessorUnitTest { void whenWaitingWithThreadSleep_thenStatusIsDone() throws InterruptedException { String requestId = requestProcessor.processRequest(); - Thread.sleep(2000); + //The sleep value should be greater than the maximum time the request takes to complete + Thread.sleep(2010); assertEquals("DONE", requestProcessor.getStatus(requestId)); } @@ -31,7 +32,8 @@ public class RequestProcessorUnitTest { String requestId = requestProcessor.processRequest(); Awaitility.await() - .atMost(2, TimeUnit.SECONDS) + //The timeout value should exceed the maximum time the request takes to complete, for the time amount of a poll (500 ms) + .atMost(2501, TimeUnit.MILLISECONDS) .pollDelay(500, TimeUnit.MILLISECONDS) .until(() -> requestProcessor.getStatus(requestId), not(equalTo("PROCESSING"))); diff --git a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/completablefuture/BlockingUnitTest.java b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/completablefuture/BlockingUnitTest.java new file mode 100644 index 0000000000..75d8d73c2f --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/completablefuture/BlockingUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.concurrent.completablefuture; + +import org.junit.jupiter.api.Test; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class BlockingUnitTest { + + @Test + void givenCompletableFuture_whenGet_thenReturnResult() + throws ExecutionException, InterruptedException { + CompletableFuture completableFuture = CompletableFuture + .supplyAsync(() -> "Baeldung") + .thenApply(String::toUpperCase); + + assertEquals("BAELDUNG", completableFuture.get()); + } + + @Test + void givenCompletableFuture_whenJoin_thenReturnResult() { + CompletableFuture completableFuture = CompletableFuture + .supplyAsync(() -> "Blocking") + .thenApply(s -> s + " Operation") + .thenApply(String::toLowerCase); + + assertEquals("blocking operation", completableFuture.join()); + } +} diff --git a/core-java-modules/core-java-concurrency-basic/pom.xml b/core-java-modules/core-java-concurrency-basic/pom.xml index 1e3157291a..36d59f254c 100644 --- a/core-java-modules/core-java-concurrency-basic/pom.xml +++ b/core-java-modules/core-java-concurrency-basic/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-concurrency-basic - 0.1.0-SNAPSHOT core-java-concurrency-basic jar diff --git a/core-java-modules/core-java-concurrency-collections-2/README.md b/core-java-modules/core-java-concurrency-collections-2/README.md index c812ed4284..2d65cf88e7 100644 --- a/core-java-modules/core-java-concurrency-collections-2/README.md +++ b/core-java-modules/core-java-concurrency-collections-2/README.md @@ -4,4 +4,5 @@ - [Guide to the Java TransferQueue](http://www.baeldung.com/java-transfer-queue) - [Java Concurrent HashSet Equivalent to ConcurrentHashMap](https://www.baeldung.com/java-concurrent-hashset-concurrenthashmap) - [Reading and Writing With a ConcurrentHashMap](https://www.baeldung.com/concurrenthashmap-reading-and-writing) +- [ArrayBlockingQueue vs. LinkedBlockingQueue](https://www.baeldung.com/java-arrayblockingqueue-vs-linkedblockingqueue) - [[<-- Prev]](/core-java-modules/core-java-concurrency-collections) diff --git a/core-java-modules/core-java-concurrency-collections-2/pom.xml b/core-java-modules/core-java-concurrency-collections-2/pom.xml index 9a95662fae..a85721e474 100644 --- a/core-java-modules/core-java-concurrency-collections-2/pom.xml +++ b/core-java-modules/core-java-concurrency-collections-2/pom.xml @@ -3,7 +3,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-concurrency-collections-2 - 0.1.0-SNAPSHOT core-java-concurrency-collections-2 jar diff --git a/core-java-modules/core-java-concurrency-collections-2/src/test/java/com/baeldung/concurrent/queue/BlockingQueueUnitTest.java b/core-java-modules/core-java-concurrency-collections-2/src/test/java/com/baeldung/concurrent/queue/BlockingQueueUnitTest.java new file mode 100644 index 0000000000..e913747f2d --- /dev/null +++ b/core-java-modules/core-java-concurrency-collections-2/src/test/java/com/baeldung/concurrent/queue/BlockingQueueUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.concurrent.queue; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; + +public class BlockingQueueUnitTest { + + @Test + public void givenArrayBlockingQueue_whenAddedElements_thenReturnQueueRemainingCapacity() { + BlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(10); + arrayBlockingQueue.add("TestString1"); + arrayBlockingQueue.add("TestString2"); + assertEquals(8, arrayBlockingQueue.remainingCapacity()); + } + + @Test + public void givenLinkedBlockingQueue_whenAddedElements_thenReturnQueueRemainingCapacity() { + BlockingQueue linkedBlockingQueue = new LinkedBlockingQueue<>(10); + linkedBlockingQueue.add("TestString1"); + assertEquals(9, linkedBlockingQueue.remainingCapacity()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-collections/pom.xml b/core-java-modules/core-java-concurrency-collections/pom.xml index 8b8d2fe03b..a35da4ce49 100644 --- a/core-java-modules/core-java-concurrency-collections/pom.xml +++ b/core-java-modules/core-java-concurrency-collections/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-concurrency-collections - 0.1.0-SNAPSHOT core-java-concurrency-collections jar diff --git a/core-java-modules/core-java-concurrency-simple/pom.xml b/core-java-modules/core-java-concurrency-simple/pom.xml index 159a105035..a16df4fc97 100644 --- a/core-java-modules/core-java-concurrency-simple/pom.xml +++ b/core-java-modules/core-java-concurrency-simple/pom.xml @@ -3,7 +3,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-concurrency-simple - 0.1.0-SNAPSHOT core-java-concurrency-simple jar diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/sandbox/SandboxJavaManualTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/sandbox/SandboxJavaManualTest.java similarity index 100% rename from core-java-modules/core-java/src/test/java/com/baeldung/sandbox/SandboxJavaManualTest.java rename to core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/sandbox/SandboxJavaManualTest.java diff --git a/core-java-modules/core-java-console/pom.xml b/core-java-modules/core-java-console/pom.xml index 200e2707dd..4debf9388b 100644 --- a/core-java-modules/core-java-console/pom.xml +++ b/core-java-modules/core-java-console/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-console - 0.1.0-SNAPSHOT core-java-console jar diff --git a/core-java-modules/core-java-date-operations-1/pom.xml b/core-java-modules/core-java-date-operations-1/pom.xml index c5d46723d8..5bfbb5bab0 100644 --- a/core-java-modules/core-java-date-operations-1/pom.xml +++ b/core-java-modules/core-java-date-operations-1/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-date-operations-1 - ${project.parent.version} core-java-date-operations-1 jar diff --git a/core-java-modules/core-java-date-operations-2/pom.xml b/core-java-modules/core-java-date-operations-2/pom.xml index 461ba70b62..c6a22a4166 100644 --- a/core-java-modules/core-java-date-operations-2/pom.xml +++ b/core-java-modules/core-java-date-operations-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-date-operations-2 - ${project.parent.version} core-java-date-operations-2 jar diff --git a/core-java-modules/core-java-date-operations-3/README.md b/core-java-modules/core-java-date-operations-3/README.md index 944ab4bd1b..0d36f9c8a2 100644 --- a/core-java-modules/core-java-date-operations-3/README.md +++ b/core-java-modules/core-java-date-operations-3/README.md @@ -5,4 +5,5 @@ This module contains articles about date operations in Java. - [Create Date From Unix Timestamp in Java](https://www.baeldung.com/java-date-unix-timestamp) - [Convert java.util.Date to java.sql.Date](https://www.baeldung.com/java-convert-util-date-to-sql) +- [How to Determine Date of the First Day of the Week Using LocalDate in Java](https://www.baeldung.com/java-first-day-of-the-week) - [[<-- Prev]](/core-java-modules/core-java-date-operations-2) diff --git a/core-java-modules/core-java-date-operations-3/pom.xml b/core-java-modules/core-java-date-operations-3/pom.xml index 8713139ba8..89c21a31c1 100644 --- a/core-java-modules/core-java-date-operations-3/pom.xml +++ b/core-java-modules/core-java-date-operations-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-date-operations-3 - ${project.parent.version} core-java-date-operations-3 jar @@ -14,10 +13,4 @@ 0.0.1-SNAPSHOT - - - - - - \ No newline at end of file diff --git a/core-java-modules/core-java-datetime-string-2/pom.xml b/core-java-modules/core-java-datetime-string-2/pom.xml index 3ec9ccaac4..458fba25a2 100644 --- a/core-java-modules/core-java-datetime-string-2/pom.xml +++ b/core-java-modules/core-java-datetime-string-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-datetime-string-2 - ${project.parent.version} core-java-datetime-string-2 jar diff --git a/core-java-modules/core-java-datetime-string/pom.xml b/core-java-modules/core-java-datetime-string/pom.xml index 2b3c2edb02..3efb2fe728 100644 --- a/core-java-modules/core-java-datetime-string/pom.xml +++ b/core-java-modules/core-java-datetime-string/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-datetime-string - ${project.parent.version} core-java-datetime-string jar @@ -20,7 +19,6 @@ commons-lang3 ${commons-lang3.version} - commons-validator commons-validator diff --git a/core-java-modules/core-java-documentation/README.md b/core-java-modules/core-java-documentation/README.md new file mode 100644 index 0000000000..b66b9e8c05 --- /dev/null +++ b/core-java-modules/core-java-documentation/README.md @@ -0,0 +1,6 @@ +## Core Java Documentation + +### Relevant Articles: + +- [Introduction to Javadoc](http://www.baeldung.com/javadoc) + diff --git a/core-java-modules/core-java-documentation/pom.xml b/core-java-modules/core-java-documentation/pom.xml new file mode 100644 index 0000000000..be18af1b10 --- /dev/null +++ b/core-java-modules/core-java-documentation/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + core-java-documentation + 0.1.0-SNAPSHOT + core-java-documentation + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + ${source.version} + ${target.version} + + + + + + + + 3.0.0-M1 + 1.8 + 1.8 + + + \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/javadoc/CodeSnippetFormatting.java b/core-java-modules/core-java-documentation/src/main/java/com/baeldung/javadoc/CodeSnippetFormatting.java similarity index 100% rename from core-java-modules/core-java/src/main/java/com/baeldung/javadoc/CodeSnippetFormatting.java rename to core-java-modules/core-java-documentation/src/main/java/com/baeldung/javadoc/CodeSnippetFormatting.java diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/javadoc/Person.java b/core-java-modules/core-java-documentation/src/main/java/com/baeldung/javadoc/Person.java similarity index 100% rename from core-java-modules/core-java/src/main/java/com/baeldung/javadoc/Person.java rename to core-java-modules/core-java-documentation/src/main/java/com/baeldung/javadoc/Person.java diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/javadoc/SuperHero.java b/core-java-modules/core-java-documentation/src/main/java/com/baeldung/javadoc/SuperHero.java similarity index 100% rename from core-java-modules/core-java/src/main/java/com/baeldung/javadoc/SuperHero.java rename to core-java-modules/core-java-documentation/src/main/java/com/baeldung/javadoc/SuperHero.java diff --git a/core-java-modules/core-java-exceptions-2/pom.xml b/core-java-modules/core-java-exceptions-2/pom.xml index 9103672cd4..8bf5605f09 100644 --- a/core-java-modules/core-java-exceptions-2/pom.xml +++ b/core-java-modules/core-java-exceptions-2/pom.xml @@ -5,8 +5,6 @@ core-java-exceptions-2 core-java-exceptions-2 jar - - http://maven.apache.org com.baeldung.core-java-modules diff --git a/core-java-modules/core-java-exceptions-3/pom.xml b/core-java-modules/core-java-exceptions-3/pom.xml index 7eaa57edf1..6ef979b54a 100644 --- a/core-java-modules/core-java-exceptions-3/pom.xml +++ b/core-java-modules/core-java-exceptions-3/pom.xml @@ -3,9 +3,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 - com.baeldung.exceptions core-java-exceptions-3 - 0.1.0-SNAPSHOT core-java-exceptions-3 jar diff --git a/core-java-modules/core-java-exceptions-4/pom.xml b/core-java-modules/core-java-exceptions-4/pom.xml index e9eb1bf379..c41c782fcc 100644 --- a/core-java-modules/core-java-exceptions-4/pom.xml +++ b/core-java-modules/core-java-exceptions-4/pom.xml @@ -3,9 +3,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 - com.baeldung.exceptions core-java-exceptions-4 - 0.1.0-SNAPSHOT core-java-exceptions-4 jar diff --git a/core-java-modules/core-java-exceptions/pom.xml b/core-java-modules/core-java-exceptions/pom.xml index 866248b416..0bb6e86c76 100644 --- a/core-java-modules/core-java-exceptions/pom.xml +++ b/core-java-modules/core-java-exceptions/pom.xml @@ -3,9 +3,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 - com.baeldung.exceptions core-java-exceptions - 0.1.0-SNAPSHOT core-java-exceptions jar diff --git a/core-java-modules/core-java-function/pom.xml b/core-java-modules/core-java-function/pom.xml index ebc34aaf4b..e8b538ad24 100644 --- a/core-java-modules/core-java-function/pom.xml +++ b/core-java-modules/core-java-function/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-function - 0.1.0-SNAPSHOT core-java-function jar diff --git a/core-java-modules/core-java-functional/pom.xml b/core-java-modules/core-java-functional/pom.xml index 9ad47f8133..4b0bf9f730 100644 --- a/core-java-modules/core-java-functional/pom.xml +++ b/core-java-modules/core-java-functional/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-functional - 0.1.0-SNAPSHOT core-java-functional jar diff --git a/core-java-modules/core-java-hex/pom.xml b/core-java-modules/core-java-hex/pom.xml index afac1c4d66..71e6b15b2e 100644 --- a/core-java-modules/core-java-hex/pom.xml +++ b/core-java-modules/core-java-hex/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-hex - 0.1.0-SNAPSHOT core-java-hex jar @@ -14,12 +13,4 @@ 0.0.1-SNAPSHOT - - - - - - - - \ No newline at end of file diff --git a/core-java-modules/core-java-httpclient/pom.xml b/core-java-modules/core-java-httpclient/pom.xml index 3df0447ff0..f3730d1b45 100644 --- a/core-java-modules/core-java-httpclient/pom.xml +++ b/core-java-modules/core-java-httpclient/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-httpclient - 0.1.0-SNAPSHOT core-java-httpclient jar diff --git a/core-java-modules/core-java-io-2/pom.xml b/core-java-modules/core-java-io-2/pom.xml index b5f43d5a94..8f4f2518fe 100644 --- a/core-java-modules/core-java-io-2/pom.xml +++ b/core-java-modules/core-java-io-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-io-2 - 0.1.0-SNAPSHOT core-java-io-2 jar diff --git a/core-java-modules/core-java-io-3/pom.xml b/core-java-modules/core-java-io-3/pom.xml index 4901133854..26ea301837 100644 --- a/core-java-modules/core-java-io-3/pom.xml +++ b/core-java-modules/core-java-io-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-io-3 - 0.1.0-SNAPSHOT core-java-io-3 jar diff --git a/core-java-modules/core-java-io-4/pom.xml b/core-java-modules/core-java-io-4/pom.xml index 2cc05698fc..30177e5c09 100644 --- a/core-java-modules/core-java-io-4/pom.xml +++ b/core-java-modules/core-java-io-4/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-io-4 - 0.1.0-SNAPSHOT core-java-io-4 jar diff --git a/core-java-modules/core-java-io-4/src/main/java/com/baeldung/iostreams/DataStream.java b/core-java-modules/core-java-io-4/src/main/java/com/baeldung/iostreams/DataStream.java index 71c55d31b9..84d6c1ad80 100644 --- a/core-java-modules/core-java-io-4/src/main/java/com/baeldung/iostreams/DataStream.java +++ b/core-java-modules/core-java-io-4/src/main/java/com/baeldung/iostreams/DataStream.java @@ -7,12 +7,14 @@ public class DataStream { PrintStream out = new PrintStream(fileName); out.print(content); out.flush(); + out.close(); } public static void textDataProcessingCharStream(String fileName, String content) throws IOException { PrintWriter out = new PrintWriter(fileName); out.print(content); out.flush(); + out.close(); } public static void nonTextDataProcessing(String fileName, String streamOutputFile, String writerOutputFile) throws IOException { @@ -33,5 +35,6 @@ public class DataStream { writer.write(c); } writer.close(); + inputStream.close(); } } \ No newline at end of file diff --git a/core-java-modules/core-java-io-4/src/test/java/com/baeldung/iostreams/DataStreamUnitTest.java b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/iostreams/DataStreamUnitTest.java index a5a53d5a08..7d697171ce 100644 --- a/core-java-modules/core-java-io-4/src/test/java/com/baeldung/iostreams/DataStreamUnitTest.java +++ b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/iostreams/DataStreamUnitTest.java @@ -23,32 +23,29 @@ public class DataStreamUnitTest { @Test public void whenUsingByteStream_thenWriteTextToFile() throws IOException { - DataStream dataStream = new DataStream(); - dataStream.textDataProcessingByteStream(dataProcessingTextFile, textFileContent); + DataStream.textDataProcessingByteStream(dataProcessingTextFile, textFileContent); File file = new File(dataProcessingTextFile); assertTrue(file.exists()); assertEquals(textFileContent, FileUtils.readFileToString(file, "utf-8")); - Files.delete(Paths.get(dataProcessingTextFile)); + Files.deleteIfExists(Paths.get(dataProcessingTextFile)); } @Test public void whenUsingCharStream_thenWriteTextToFile() throws IOException { - DataStream dataStream = new DataStream(); - dataStream.textDataProcessingCharStream(dataProcessingTextFile, textFileContent); + DataStream.textDataProcessingCharStream(dataProcessingTextFile, textFileContent); File file = new File(dataProcessingTextFile); assertTrue(file.exists()); assertEquals(textFileContent, FileUtils.readFileToString(file, "utf-8")); - Files.delete(Paths.get(dataProcessingTextFile)); + Files.deleteIfExists(Paths.get(dataProcessingTextFile)); } @Test public void whenUsingStreams_thenWriteNonTextData() throws IOException { - DataStream dataStream = new DataStream(); - dataStream.nonTextDataProcessing(dataProcessingImageFile, dataProcessingByteStreamFile, dataProcessingCharStreamFile); + DataStream.nonTextDataProcessing(dataProcessingImageFile, dataProcessingByteStreamFile, dataProcessingCharStreamFile); File file = new File(dataProcessingImageFile); File byteStreamOutputFile = new File(dataProcessingByteStreamFile); @@ -60,7 +57,7 @@ public class DataStreamUnitTest { assertTrue(FileUtils.contentEquals(file, byteStreamOutputFile)); assertFalse(FileUtils.contentEquals(file, charStreamOutputFile)); - Files.delete(Paths.get(dataProcessingByteStreamFile)); - Files.delete(Paths.get(dataProcessingCharStreamFile)); + Files.deleteIfExists(Paths.get(dataProcessingByteStreamFile)); + Files.deleteIfExists(Paths.get(dataProcessingCharStreamFile)); } } diff --git a/core-java-modules/core-java-io-4/src/test/resources/iostreams/TestFile.txt b/core-java-modules/core-java-io-4/src/test/resources/iostreams/TestFile.txt new file mode 100644 index 0000000000..5dd01c177f --- /dev/null +++ b/core-java-modules/core-java-io-4/src/test/resources/iostreams/TestFile.txt @@ -0,0 +1 @@ +Hello, world! \ No newline at end of file diff --git a/core-java-modules/core-java-io-apis-2/README.md b/core-java-modules/core-java-io-apis-2/README.md index f3d72fe8b5..a4ea869946 100644 --- a/core-java-modules/core-java-io-apis-2/README.md +++ b/core-java-modules/core-java-io-apis-2/README.md @@ -5,3 +5,8 @@ This module contains articles about core Java input/output(IO) APIs. ### Relevant Articles: - [Constructing a Relative Path From Two Absolute Paths in Java](https://www.baeldung.com/java-relative-path-absolute) - [Java Scanner Taking a Character Input](https://www.baeldung.com/java-scanner-character-input) +- [Get the Desktop Path in Java](https://www.baeldung.com/java-desktop-path) +- [Integer.parseInt(scanner.nextLine()) and scanner.nextInt() in Java](https://www.baeldung.com/java-scanner-integer) +- [Difference Between FileReader and BufferedReader in Java](https://www.baeldung.com/java-filereader-vs-bufferedreader) +- [Java: Read Multiple Inputs on Same Line](https://www.baeldung.com/java-read-multiple-inputs-same-line) +- [Storing Java Scanner Input in an Array](https://www.baeldung.com/java-store-scanner-input-in-array) diff --git a/core-java-modules/core-java-io-apis-2/pom.xml b/core-java-modules/core-java-io-apis-2/pom.xml index 70c3a87da2..22c04cdc58 100644 --- a/core-java-modules/core-java-io-apis-2/pom.xml +++ b/core-java-modules/core-java-io-apis-2/pom.xml @@ -1,47 +1,115 @@ - - - 4.0.0 - core-java-io-apis-2 - 0.1.0-SNAPSHOT - core-java-io-apis-2 - jar - - - com.baeldung.core-java-modules - core-java-modules - 0.0.1-SNAPSHOT - - - - - - log4j - log4j - ${log4j.version} - - - org.slf4j - log4j-over-slf4j - ${org.slf4j.version} - - - org.projectlombok - lombok - ${lombok.version} - provided - - - - - core-java-io-apis-2 - - - src/main/resources - true - - - - + + + 4.0.0 + core-java-io-apis-2 + core-java-io-apis-2 + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + + log4j + log4j + ${log4j.version} + + + org.slf4j + log4j-over-slf4j + ${org.slf4j.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + org.junit.jupiter + junit-jupiter-engine + 5.7.2 + test + + + org.junit.jupiter + junit-jupiter + + + org.junit.jupiter + junit-jupiter + + + org.junit.jupiter + junit-jupiter + + + org.junit.jupiter + junit-jupiter + + + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter-version} + test + + + + org.junit.jupiter + junit-jupiter-params + ${junit-jupiter-version} + test + + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter-version} + test + + + org.junit.jupiter + junit-jupiter + + + org.junit.jupiter + junit-jupiter + + + org.junit.jupiter + junit-jupiter + + + org.testng + testng + 7.1.0 + test + + + org.testng + testng + 7.5 + compile + + + + 5.2.0 + + + core-java-io-apis-2 + + + src/main/resources + true + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-io-apis-2/src/main/java/com/baeldung/multinput/MultiInputs.java b/core-java-modules/core-java-io-apis-2/src/main/java/com/baeldung/multinput/MultiInputs.java new file mode 100644 index 0000000000..df799b2511 --- /dev/null +++ b/core-java-modules/core-java-io-apis-2/src/main/java/com/baeldung/multinput/MultiInputs.java @@ -0,0 +1,36 @@ +package com.baeldung.multinput; + +import java.util.InputMismatchException; +import java.util.Scanner; + +public class MultiInputs { + public void UsingSpaceDelimiter(){ + Scanner scanner = new Scanner(System.in); + System.out.print("Enter two numbers: "); + int num1 = scanner.nextInt(); + int num2 = scanner.nextInt(); + System.out.println("You entered " + num1 + " and " + num2); + + } + public void UsingREDelimiter(){ + Scanner scanner = new Scanner(System.in); + scanner.useDelimiter("[\\s,]+"); + System.out.print("Enter two numbers separated by a space or a comma: "); + int num1 = scanner.nextInt(); + int num2 = scanner.nextInt(); + System.out.println("You entered " + num1 + " and " + num2); + + } + public void UsingCustomDelimiter(){ + Scanner scanner = new Scanner(System.in); + scanner.useDelimiter(";"); + System.out.print("Enter two numbers separated by a semicolon: "); + try { int num1 = scanner.nextInt(); + int num2 = scanner.nextInt(); + System.out.println("You entered " + num1 + " and " + num2); } + catch (InputMismatchException e) + { System.out.println("Invalid input. Please enter two integers separated by a semicolon."); } + + } +} + diff --git a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/absolutetorelative/AbsoluteToRelativeUnitTest.java b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/absolutetorelative/AbsoluteToRelativeUnitTest.java index 0830b0808a..9b3f424a30 100644 --- a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/absolutetorelative/AbsoluteToRelativeUnitTest.java +++ b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/absolutetorelative/AbsoluteToRelativeUnitTest.java @@ -1,93 +1,92 @@ -package com.baeldung.absolutetorelative; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.net.URI; -import java.nio.file.Path; -import java.nio.file.Paths; - -public class AbsoluteToRelativeUnitTest { - - // given - until using Paths, no need to create physical files - private final Path pathOne = Paths.get("/baeldung/bar/one.txt"); - private final Path pathTwo = Paths.get("/baeldung/bar/two.txt"); - private final Path pathThree = Paths.get("/baeldung/foo/three.txt"); - - private final URI uriOne = pathOne.toUri(); - private final URI uriTwo = pathTwo.toUri(); - private final URI uriThree = pathThree.toUri(); - - @Test - public void givenAbsolutePaths_whenRelativizePathOneToPathTwo_thenRelativeIsReturned() { - Path result = pathOne.relativize(pathTwo); - - Assertions.assertThat(result) - .isRelative() - .isEqualTo(Paths.get("../two.txt")); - } - - @Test - public void givenAbsolutePaths_whenRelativizePathTwoToPathOne_thenRelativeIsReturned() { - Path result = pathTwo.relativize(pathOne); - - Assertions.assertThat(result) - .isRelative() - .isEqualTo(Paths.get("../one.txt")); - } - - @Test - public void givenAbsolutePaths_whenRelativizePathOneParentToPathTwo_thenRelativeIsReturned() { - Path result = pathOne.getParent().relativize(pathTwo); - - Assertions.assertThat(result) - .isRelative() - .isEqualTo(Paths.get("two.txt")); - } - - @Test - public void givenAbsolutePaths_whenRelativizePathOneToPathThree_thenRelativeIsReturned() { - Path result = pathOne.relativize(pathThree); - - Assertions.assertThat(result) - .isRelative() - .isEqualTo(Paths.get("../../foo/three.txt")); - } - - @Test - public void givenAbsolutePaths_whenRelativizePathThreeToPathOne_thenRelativeIsReturned() { - Path result = pathThree.relativize(pathOne); - - Assertions.assertThat(result) - .isRelative() - .isEqualTo(Paths.get("../../bar/one.txt")); - } - - @Test - public void givenAbsoluteURIs_whenRelativizeUriOneToUriTwo_thenAbsoluteIsReturned() { - URI result = uriOne.relativize(uriTwo); - - Assertions.assertThat(result) - .asString() - .contains("/baeldung/bar/two.txt"); - } - - @Test - public void givenAbsoluteURIs_whenRelativizeUriOneParentToUriTwo_thenRelativeIsReturned() { - URI result = pathOne.getParent().toUri().relativize(uriTwo); - - Assertions.assertThat(result) - .asString() - .contains("two.txt"); - } - - @Test - public void givenAbsoluteURIs_whenRelativizeUriOneParentToUriThree_thenAbsoluteIsReturned() { - URI result = pathOne.getParent().toUri().relativize(uriThree); - - Assertions.assertThat(result) - .asString() - .contains("/baeldung/foo/three.txt"); - } - -} +package com.baeldung.absolutetorelative; + +import java.net.URI; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class AbsoluteToRelativeUnitTest { + + // given - until using Paths, no need to create physical files + private final Path pathOne = Paths.get("/baeldung/bar/one.txt"); + private final Path pathTwo = Paths.get("/baeldung/bar/two.txt"); + private final Path pathThree = Paths.get("/baeldung/foo/three.txt"); + + private final URI uriOne = pathOne.toUri(); + private final URI uriTwo = pathTwo.toUri(); + private final URI uriThree = pathThree.toUri(); + + @Test + public void givenAbsolutePaths_whenRelativizePathOneToPathTwo_thenRelativeIsReturned() { + Path result = pathOne.relativize(pathTwo); + + org.assertj.core.api.Assertions.assertThat(result) + .isRelative() + .isEqualTo(Paths.get("../two.txt")); + } + + @Test + public void givenAbsolutePaths_whenRelativizePathTwoToPathOne_thenRelativeIsReturned() { + Path result = pathTwo.relativize(pathOne); + + org.assertj.core.api.Assertions.assertThat(result) + .isRelative() + .isEqualTo(Paths.get("../one.txt")); + } + + @Test + public void givenAbsolutePaths_whenRelativizePathOneParentToPathTwo_thenRelativeIsReturned() { + Path result = pathOne.getParent().relativize(pathTwo); + + org.assertj.core.api.Assertions.assertThat(result) + .isRelative() + .isEqualTo(Paths.get("two.txt")); + } + + @Test + public void givenAbsolutePaths_whenRelativizePathOneToPathThree_thenRelativeIsReturned() { + Path result = pathOne.relativize(pathThree); + + org.assertj.core.api.Assertions.assertThat(result) + .isRelative() + .isEqualTo(Paths.get("../../foo/three.txt")); + } + + @Test + public void givenAbsolutePaths_whenRelativizePathThreeToPathOne_thenRelativeIsReturned() { + Path result = pathThree.relativize(pathOne); + + org.assertj.core.api.Assertions.assertThat(result) + .isRelative() + .isEqualTo(Paths.get("../../bar/one.txt")); + } + + @Test + public void givenAbsoluteURIs_whenRelativizeUriOneToUriTwo_thenAbsoluteIsReturned() { + URI result = uriOne.relativize(uriTwo); + + org.assertj.core.api.Assertions.assertThat(result) + .asString() + .contains("/baeldung/bar/two.txt"); + } + + @Test + public void givenAbsoluteURIs_whenRelativizeUriOneParentToUriTwo_thenRelativeIsReturned() { + URI result = pathOne.getParent().toUri().relativize(uriTwo); + + org.assertj.core.api.Assertions.assertThat(result) + .asString() + .contains("two.txt"); + } + + @Test + public void givenAbsoluteURIs_whenRelativizeUriOneParentToUriThree_thenAbsoluteIsReturned() { + URI result = pathOne.getParent().toUri().relativize(uriThree); + + org.assertj.core.api.Assertions.assertThat(result) + .asString() + .contains("/baeldung/foo/three.txt"); + } + +} diff --git a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/BufferedReaderUnitTest.java b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/BufferedReaderUnitTest.java new file mode 100644 index 0000000000..06b7d38821 --- /dev/null +++ b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/BufferedReaderUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.bufferedreadervsfilereader; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +import org.junit.jupiter.api.Assertions; +import org.testng.annotations.Test; +public class BufferedReaderUnitTest { + + @Test + public void whenReadingAFile_thenReadsLineByLine() { + StringBuilder result = new StringBuilder(); + + try (BufferedReader br = new BufferedReader(new FileReader("src/test/resources/sampleText1.txt"))) { + String line; + + while((line = br.readLine()) != null) { + result.append(line); + result.append('\n'); + } + } catch (IOException e) { + e.printStackTrace(); + } + + assertEquals("first line\nsecond line\nthird line\n", result.toString()); + } + +} diff --git a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/FileReaderUnitTest.java b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/FileReaderUnitTest.java new file mode 100644 index 0000000000..5df870e7b5 --- /dev/null +++ b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/FileReaderUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.bufferedreadervsfilereader; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.FileReader; +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +public class FileReaderUnitTest { + + @Test + public void whenReadingAFile_thenReadsCharByChar() { + StringBuilder result = new StringBuilder(); + + try (FileReader fr = new FileReader("src/test/resources/sampleText2.txt")) { + int i = fr.read(); + + while(i != -1) { + result.append((char)i); + + i = fr.read(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + assertEquals("qwerty", result.toString()); + } +} diff --git a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/multinput/TestMultipleInputsUnitTest.java b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/multinput/TestMultipleInputsUnitTest.java new file mode 100644 index 0000000000..317d9e817e --- /dev/null +++ b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/multinput/TestMultipleInputsUnitTest.java @@ -0,0 +1,47 @@ +package com.baeldung.multinput; + import java.io.ByteArrayInputStream; + import java.io.InputStream; + import java.util.InputMismatchException; + import org.junit.jupiter.api.Assertions; + import org.testng.annotations.Test; +import com.baeldung.multinput.MultiInputs; +public class TestMultipleInputsUnitTest { + @Test + public void givenMultipleInputs_whenUsingSpaceDelimiter_thenExpectPrintingOutputs() { + String input = "10 20\n"; + InputStream in = new ByteArrayInputStream(input.getBytes()); + System.setIn(in); + MultiInputs mi = new MultiInputs(); + mi.UsingSpaceDelimiter(); + // You can add assertions here to verify the behavior of the method + } + + @Test + public void givenMultipleInputs_whenUsingREDelimiter_thenExpectPrintingOutputs() { + String input = "30, 40\n"; + InputStream in = new ByteArrayInputStream(input.getBytes()); + System.setIn(in); + MultiInputs mi = new MultiInputs(); + mi.UsingREDelimiter(); + // You can add assertions here to verify the behavior of the method + } + + @Test + public void givenMultipleInputs_whenUsingCustomDelimiter_thenExpectPrintingOutputs() { + String input = "50; 60\n"; + InputStream in = new ByteArrayInputStream(input.getBytes()); + System.setIn(in); + MultiInputs mi = new MultiInputs(); + mi.UsingCustomDelimiter(); + // You can add assertions here to verify the behavior of the method + } + + @Test + public void givenInvalidInput_whenUsingSpaceDelimiter_thenExpectInputMismatchException() { + String input = "abc\n"; + InputStream in = new ByteArrayInputStream(input.getBytes()); + System.setIn(in); + MultiInputs mi = new MultiInputs(); + Assertions.assertThrows(InputMismatchException.class, mi::UsingSpaceDelimiter); + } +} diff --git a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/path/DesktopPathUnitTest.java b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/path/DesktopPathUnitTest.java index fe21d0a72f..1b71512c5c 100644 --- a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/path/DesktopPathUnitTest.java +++ b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/path/DesktopPathUnitTest.java @@ -1,29 +1,27 @@ -package com.baeldung.path; - -import org.junit.jupiter.api.Test; - -import java.io.File; - -import static org.junit.Assert.assertEquals; - -import javax.swing.filechooser.FileSystemView; - -public class DesktopPathUnitTest { - // Adapt DESKTOP_PATH variable to your own system path - // private static final String DESKTOP_PATH = "C:\\Users\\HRAF\\Desktop"; - - @Test - public void whenUsingGetUserHomeProperty_thenShouldEqualDesktopPath() { - String desktopPath = System.getProperty("user.home") + File.separator + "Desktop"; - // assertEquals(DESKTOP_PATH, desktopPath); - } - - @Test - public void whenUsingFileSystemViewGetHomeDirectory_thenShouldEqualDesktopPath() { - FileSystemView view = FileSystemView.getFileSystemView(); - File file = view.getHomeDirectory(); - String path = file.getPath(); - // assertEquals(DESKTOP_PATH, path); - } - -} +package com.baeldung.path; + +import java.io.File; + +import javax.swing.filechooser.FileSystemView; + +import org.junit.jupiter.api.Test; + +public class DesktopPathUnitTest { + // Adapt DESKTOP_PATH variable to your own system path + // private static final String DESKTOP_PATH = "C:\\Users\\HRAF\\Desktop"; + + @Test + public void whenUsingGetUserHomeProperty_thenShouldEqualDesktopPath() { + String desktopPath = System.getProperty("user.home") + File.separator + "Desktop"; + // assertEquals(DESKTOP_PATH, desktopPath); + } + + @Test + public void whenUsingFileSystemViewGetHomeDirectory_thenShouldEqualDesktopPath() { + FileSystemView view = FileSystemView.getFileSystemView(); + File file = view.getHomeDirectory(); + String path = file.getPath(); + // assertEquals(DESKTOP_PATH, path); + } + +} diff --git a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/scanner/NextLineVsNextIntUnitTest.java b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/scanner/NextLineVsNextIntUnitTest.java new file mode 100644 index 0000000000..3aae0469d0 --- /dev/null +++ b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/scanner/NextLineVsNextIntUnitTest.java @@ -0,0 +1,85 @@ +package com.baeldung.scanner; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.InputMismatchException; +import java.util.Scanner; + +import org.junit.jupiter.api.Test; + +public class NextLineVsNextIntUnitTest { + + @Test + void whenInputLineIsNumber_thenNextLineAndNextIntBothWork() { + String input = "42\n"; + + //nextLine() + Scanner sc1 = new Scanner(input); + int num1 = Integer.parseInt(sc1.nextLine()); + assertEquals(42, num1); + + //nextInt() + Scanner sc2 = new Scanner(input); + int num2 = sc2.nextInt(); + assertEquals(42, num2); + + } + + @Test + void whenInputIsNotValidNumber_thenNextLineAndNextIntThrowDifferentException() { + String input = "Nan\n"; + + //nextLine() -> NumberFormatException + Scanner sc1 = new Scanner(input); + assertThrows(NumberFormatException.class, () -> Integer.parseInt(sc1.nextLine())); + + //nextInt() -> InputMismatchException + Scanner sc2 = new Scanner(input); + assertThrows(InputMismatchException.class, sc2::nextInt); + } + + @Test + void whenUsingNextInt_thenTheNextTokenAfterItFailsToParseIsNotConsumed() { + String input = "42 is a magic number\n"; + + //nextInt() to read '42' + Scanner sc2 = new Scanner(input); + int num2 = sc2.nextInt(); + assertEquals(42, num2); + + // call nextInt() again on "is" + assertThrows(InputMismatchException.class, sc2::nextInt); + + String theNextToken = sc2.next(); + assertEquals("is", theNextToken); + + theNextToken = sc2.next(); + assertEquals("a", theNextToken); + } + + @Test + void whenReadingTwoInputLines_thenNextLineAndNextIntBehaveDifferently() { + + String input = new StringBuilder().append("42\n") + .append("It is a magic number.\n") + .toString(); + + //nextLine() + Scanner sc1 = new Scanner(input); + int num1 = Integer.parseInt(sc1.nextLine()); + String nextLineText1 = sc1.nextLine(); + assertEquals(42, num1); + assertEquals("It is a magic number.", nextLineText1); + + //nextInt() + Scanner sc2 = new Scanner(input); + int num2 = sc2.nextInt(); + assertEquals(42, num2); + + // nextInt() leaves the newline character (\n) behind + String nextLineText2 = sc2.nextLine(); + assertEquals("", nextLineText2); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/scanner/ScanACharacterUnitTest.java b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/scanner/ScanACharacterUnitTest.java index 1a70c6e3af..340b58bbf6 100644 --- a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/scanner/ScanACharacterUnitTest.java +++ b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/scanner/ScanACharacterUnitTest.java @@ -1,38 +1,38 @@ -package com.baeldung.scanner; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Scanner; - -import org.junit.jupiter.api.Test; - -public class ScanACharacterUnitTest { - - // given - input scanner source, no need to scan from console - String input = new StringBuilder().append("abc\n") - .append("mno\n") - .append("xyz\n") - .toString(); - - @Test - public void givenInputSource_whenScanCharUsingNext_thenOneCharIsRead() { - Scanner sc = new Scanner(input); - char c = sc.next().charAt(0); - assertEquals('a', c); - } - - @Test - public void givenInputSource_whenScanCharUsingFindInLine_thenOneCharIsRead() { - Scanner sc = new Scanner(input); - char c = sc.findInLine(".").charAt(0); - assertEquals('a', c); - } - - @Test - public void givenInputSource_whenScanCharUsingUseDelimiter_thenOneCharIsRead() { - Scanner sc = new Scanner(input); - char c = sc.useDelimiter("").next().charAt(0); - assertEquals('a', c); - } - -} +package com.baeldung.scanner; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Scanner; + +import org.junit.jupiter.api.Test; + +public class ScanACharacterUnitTest { + + // given - input scanner source, no need to scan from console + String input = new StringBuilder().append("abc\n") + .append("mno\n") + .append("xyz\n") + .toString(); + + @Test + public void givenInputSource_whenScanCharUsingNext_thenOneCharIsRead() { + Scanner sc = new Scanner(input); + char c = sc.next().charAt(0); + assertEquals('a', c); + } + + @Test + public void givenInputSource_whenScanCharUsingFindInLine_thenOneCharIsRead() { + Scanner sc = new Scanner(input); + char c = sc.findInLine(".").charAt(0); + assertEquals('a', c); + } + + @Test + public void givenInputSource_whenScanCharUsingUseDelimiter_thenOneCharIsRead() { + Scanner sc = new Scanner(input); + char c = sc.useDelimiter("").next().charAt(0); + assertEquals('a', c); + } + +} diff --git a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/scanner/ScannerToArrayUnitTest.java b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/scanner/ScannerToArrayUnitTest.java new file mode 100644 index 0000000000..f64bd7b1fc --- /dev/null +++ b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/scanner/ScannerToArrayUnitTest.java @@ -0,0 +1,107 @@ +package com.baeldung.scanner; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +import org.junit.jupiter.api.Test; + +import com.google.common.collect.Lists; +import com.google.common.collect.ObjectArrays; + +public class ScannerToArrayUnitTest { + + @Test + void whenMultipleElementsInOneLine_thenGetExpectedArray() { + String input = "Java Kotlin Ruby Python Go\n"; + String[] expected = new String[] { "Java", "Kotlin", "Ruby", "Python", "Go" }; + + // scanner.next() + Scanner scanner1 = new Scanner(input); + String[] result1 = new String[5]; + int i = 0; + while (i < result1.length) { + result1[i] = scanner1.next(); + i++; + } + assertArrayEquals(expected, result1); + + //split() + Scanner scanner2 = new Scanner(input); + String[] result2 = scanner2.nextLine() + .split("\\s+"); + assertArrayEquals(expected, result2); + } + + @Test + void whenOneElementPerLine_thenGetExpectedArray() { + String input = new StringBuilder().append("Baeldung Java\n") + .append("Baeldung Kotlin\n") + .append("Baeldung Linux\n") + .toString(); + + String[] expected = new String[] { "Baeldung Java", "Baeldung Kotlin", "Baeldung Linux" }; + + String[] result = new String[3]; + Scanner scanner = new Scanner(input); + int i = 0; + while (i < result.length) { + result[i] = scanner.nextLine(); + i++; + } + assertArrayEquals(expected, result); + } + + @Test + void whenOneElementPerLine_thenGetExpectedList() { + String input = new StringBuilder().append("Baeldung Java\n") + .append("Baeldung Kotlin\n") + .append("Baeldung Linux\n") + .toString(); + + List expected = Lists.newArrayList("Baeldung Java", "Baeldung Kotlin", "Baeldung Linux"); + + List result = new ArrayList<>(); + Scanner scanner = new Scanner(input); + while (scanner.hasNextLine()) { + result.add(scanner.nextLine()); + } + assertEquals(expected, result); + } + + @Test + void whenEveryTokenIsAnElement_thenGetExpectedList() { + String input = new StringBuilder().append("Linux Windows MacOS\n") + .append("Java Kotlin Python Go\n") + .toString(); + + List expected = Lists.newArrayList("Linux", "Windows", "MacOS", "Java", "Kotlin", "Python", "Go"); + List result = new ArrayList<>(); + Scanner scanner = new Scanner(input); + while (scanner.hasNext()) { + result.add(scanner.next()); + } + assertEquals(expected, result); + } + + @Test + void whenEveryTokenIsAnElement_thenGetExpectedArray() { + String input = new StringBuilder().append("Linux Windows MacOS\n") + .append("Java Kotlin Python Go\n") + .toString(); + + String[] expected = new String[] { "Linux", "Windows", "MacOS", "Java", "Kotlin", "Python", "Go" }; + String[] result = new String[] {}; + + Scanner scanner = new Scanner(input); + while (scanner.hasNextLine()) { + String[] lineInArray = scanner.nextLine() + .split("\\s+"); + result = ObjectArrays.concat(result, lineInArray, String.class); + } + assertArrayEquals(expected, result); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-io-apis-2/src/test/resources/sampleText1.txt b/core-java-modules/core-java-io-apis-2/src/test/resources/sampleText1.txt new file mode 100644 index 0000000000..ea0584cfe0 --- /dev/null +++ b/core-java-modules/core-java-io-apis-2/src/test/resources/sampleText1.txt @@ -0,0 +1,3 @@ +first line +second line +third line diff --git a/core-java-modules/core-java-io-apis-2/src/test/resources/sampleText2.txt b/core-java-modules/core-java-io-apis-2/src/test/resources/sampleText2.txt new file mode 100644 index 0000000000..f2289097d4 --- /dev/null +++ b/core-java-modules/core-java-io-apis-2/src/test/resources/sampleText2.txt @@ -0,0 +1 @@ +qwerty \ No newline at end of file diff --git a/core-java-modules/core-java-io-apis/pom.xml b/core-java-modules/core-java-io-apis/pom.xml index fab2bff959..f9d404cd5b 100644 --- a/core-java-modules/core-java-io-apis/pom.xml +++ b/core-java-modules/core-java-io-apis/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-io-apis - 0.1.0-SNAPSHOT core-java-io-apis jar diff --git a/core-java-modules/core-java-io-conversions-2/README.md b/core-java-modules/core-java-io-conversions-2/README.md index c83a3fb1d7..4e179a84d2 100644 --- a/core-java-modules/core-java-io-conversions-2/README.md +++ b/core-java-modules/core-java-io-conversions-2/README.md @@ -10,4 +10,6 @@ This module contains articles about core Java input/output(IO) conversions. - [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array) - [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv) - [How to Convert InputStream to Base64 String](https://www.baeldung.com/java-inputstream-to-base64-string) +- [Convert an OutputStream to an InputStream](https://www.baeldung.com/java-convert-outputstream-to-inputstream) +- [Java PrintStream to String](https://www.baeldung.com/java-printstream-to-string) - More articles: [[<-- prev]](/core-java-modules/core-java-io-conversions) diff --git a/core-java-modules/core-java-io-conversions-2/pom.xml b/core-java-modules/core-java-io-conversions-2/pom.xml index 24708ad967..2c49bbfd81 100644 --- a/core-java-modules/core-java-io-conversions-2/pom.xml +++ b/core-java-modules/core-java-io-conversions-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-io-conversions-2 - 0.1.0-SNAPSHOT core-java-io-conversions-2 jar diff --git a/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/printstreamtostring/PrintStreamToStringUtil.java b/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/printstreamtostring/PrintStreamToStringUtil.java new file mode 100644 index 0000000000..72bba78db0 --- /dev/null +++ b/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/printstreamtostring/PrintStreamToStringUtil.java @@ -0,0 +1,68 @@ +package com.baeldung.printstreamtostring; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; + +public class PrintStreamToStringUtil { + + public static String usingByteArrayOutputStreamClass(String input) throws IOException { + if (input == null) { + return null; + } + + String output; + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PrintStream printStream = new PrintStream(outputStream)) { + printStream.print(input); + + output = outputStream.toString(); + } + + return output; + } + + public static String usingApacheCommonsIO(String input) { + if (input == null) { + return null; + } + + org.apache.commons.io.output.ByteArrayOutputStream outputStream = new org.apache.commons.io.output.ByteArrayOutputStream(); + try (PrintStream printStream = new PrintStream(outputStream)) { + printStream.print(input); + } + + return new String(outputStream.toByteArray()); + } + + public static String usingCustomOutputStream(String input) throws IOException { + if (input == null) { + return null; + } + + String output; + try (CustomOutputStream outputStream = new CustomOutputStream(); PrintStream printStream = new PrintStream(outputStream)) { + printStream.print(input); + + output = outputStream.toString(); + } + + return output; + } + + private static class CustomOutputStream extends OutputStream { + + private StringBuilder stringBuilder = new StringBuilder(); + + @Override + public void write(int b) throws IOException { + this.stringBuilder.append((char) b); + } + + @Override + public String toString() { + return this.stringBuilder.toString(); + } + } + +} diff --git a/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/inputstreamtostring/JavaInputStreamToXUnitTest.java b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/inputstreamtostring/JavaInputStreamToXUnitTest.java index 03f528766b..341a820b01 100644 --- a/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/inputstreamtostring/JavaInputStreamToXUnitTest.java +++ b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/inputstreamtostring/JavaInputStreamToXUnitTest.java @@ -49,7 +49,7 @@ public class JavaInputStreamToXUnitTest { final InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); final StringBuilder textBuilder = new StringBuilder(); - try (Reader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName(StandardCharsets.UTF_8.name())))) { + try (Reader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { int c; while ((c = reader.read()) != -1) { textBuilder.append((char) c); @@ -63,7 +63,7 @@ public class JavaInputStreamToXUnitTest { final String originalString = randomAlphabetic(DEFAULT_SIZE); final InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); - final String text = new BufferedReader(new InputStreamReader(inputStream, Charset.forName(StandardCharsets.UTF_8.name()))) + final String text = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)) .lines() .collect(Collectors.joining("\n")); diff --git a/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/outputstreamtoinputstream/ConvertOutputStreamToInputStreamUnitTest.java b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/outputstreamtoinputstream/ConvertOutputStreamToInputStreamUnitTest.java new file mode 100644 index 0000000000..53e9da6dbb --- /dev/null +++ b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/outputstreamtoinputstream/ConvertOutputStreamToInputStreamUnitTest.java @@ -0,0 +1,53 @@ +package com.baeldung.outputstreamtoinputstream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; + +import org.junit.jupiter.api.Test; + +public class ConvertOutputStreamToInputStreamUnitTest { + + @Test + void whenUsingByteArray_thenGetExpectedInputStream() throws IOException { + String content = "I'm an important message."; + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + out.write(content.getBytes()); + try (ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray())) { + String inContent = new String(in.readAllBytes()); + + assertEquals(content, inContent); + } + } + } + + @Test + void whenUsingPipeStream_thenGetExpectedInputStream() throws IOException { + String content = "I'm going through the pipe."; + + ByteArrayOutputStream originOut = new ByteArrayOutputStream(); + originOut.write(content.getBytes()); + + //connect the pipe + PipedInputStream in = new PipedInputStream(); + PipedOutputStream out = new PipedOutputStream(in); + + try (in) { + new Thread(() -> { + try (out) { + originOut.writeTo(out); + } catch (IOException iox) { + // handle IOExceptions + } + }).start(); + + String inContent = new String(in.readAllBytes()); + assertEquals(content, inContent); + } + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/printstreamtostring/PrintStreamToStringUtilUnitTest.java b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/printstreamtostring/PrintStreamToStringUtilUnitTest.java new file mode 100644 index 0000000000..4db60b604e --- /dev/null +++ b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/printstreamtostring/PrintStreamToStringUtilUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.printstreamtostring; + +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; + +import org.junit.Test; + +public class PrintStreamToStringUtilUnitTest { + + @Test + public void whenUsingByteArrayOutputStreamClass_thenConvert() throws IOException { + assertEquals("test", PrintStreamToStringUtil.usingByteArrayOutputStreamClass("test")); + assertEquals("", PrintStreamToStringUtil.usingByteArrayOutputStreamClass("")); + assertNull(PrintStreamToStringUtil.usingByteArrayOutputStreamClass(null)); + } + + @Test + public void whenCustomOutputStream_thenConvert() throws IOException { + assertEquals("world", PrintStreamToStringUtil.usingCustomOutputStream("world")); + assertEquals("", PrintStreamToStringUtil.usingCustomOutputStream("")); + assertNull(PrintStreamToStringUtil.usingCustomOutputStream(null)); + } + + @Test + public void whenUsingApacheCommonsIO_thenConvert() { + assertEquals("hello", PrintStreamToStringUtil.usingApacheCommonsIO("hello")); + assertEquals("", PrintStreamToStringUtil.usingApacheCommonsIO("")); + assertNull(PrintStreamToStringUtil.usingApacheCommonsIO(null)); + } +} diff --git a/core-java-modules/core-java-io-conversions/pom.xml b/core-java-modules/core-java-io-conversions/pom.xml index 8d5a47a1ac..a44c352df2 100644 --- a/core-java-modules/core-java-io-conversions/pom.xml +++ b/core-java-modules/core-java-io-conversions/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-io-conversions - 0.1.0-SNAPSHOT core-java-io-conversions jar diff --git a/core-java-modules/core-java-io/pom.xml b/core-java-modules/core-java-io/pom.xml index e645534b46..ce072e6875 100644 --- a/core-java-modules/core-java-io/pom.xml +++ b/core-java-modules/core-java-io/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-io - 0.1.0-SNAPSHOT core-java-io jar diff --git a/core-java-modules/core-java-jar/pom.xml b/core-java-modules/core-java-jar/pom.xml index 0ce2414f1e..e4a43bdf1f 100644 --- a/core-java-modules/core-java-jar/pom.xml +++ b/core-java-modules/core-java-jar/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-jar - 0.1.0-SNAPSHOT core-java-jar jar diff --git a/core-java-modules/core-java-jndi/pom.xml b/core-java-modules/core-java-jndi/pom.xml index 752700c390..e48bec6622 100644 --- a/core-java-modules/core-java-jndi/pom.xml +++ b/core-java-modules/core-java-jndi/pom.xml @@ -3,9 +3,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 - com.baeldung.jndi core-java-jndi - 1.0-SNAPSHOT core-java-jndi diff --git a/core-java-modules/core-java-jpms/pom.xml b/core-java-modules/core-java-jpms/pom.xml index 62aa49f299..3cfa0e3f45 100644 --- a/core-java-modules/core-java-jpms/pom.xml +++ b/core-java-modules/core-java-jpms/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-jpms - 0.0.1-SNAPSHOT core-java-jpms pom @@ -15,8 +14,8 @@ - decoupling-pattern1 - decoupling-pattern2 + service-provider-factory-pattern + service-loader-api-pattern diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule2/pom.xml b/core-java-modules/core-java-jpms/service-loader-api-pattern/consumermodule2/pom.xml similarity index 91% rename from core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule2/pom.xml rename to core-java-modules/core-java-jpms/service-loader-api-pattern/consumermodule2/pom.xml index 13d0b2d201..f928912ffd 100644 --- a/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule2/pom.xml +++ b/core-java-modules/core-java-jpms/service-loader-api-pattern/consumermodule2/pom.xml @@ -8,8 +8,8 @@ 1.0 - com.baeldung.decoupling-pattern2 - decoupling-pattern2 + com.baeldung.service-loader-api-pattern + service-loader-api-pattern 1.0-SNAPSHOT diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule2/src/main/java/com/baeldung/consumermodule/Application.java b/core-java-modules/core-java-jpms/service-loader-api-pattern/consumermodule2/src/main/java/com/baeldung/consumermodule/Application.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule2/src/main/java/com/baeldung/consumermodule/Application.java rename to core-java-modules/core-java-jpms/service-loader-api-pattern/consumermodule2/src/main/java/com/baeldung/consumermodule/Application.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule2/src/main/java/module-info.java b/core-java-modules/core-java-jpms/service-loader-api-pattern/consumermodule2/src/main/java/module-info.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule2/src/main/java/module-info.java rename to core-java-modules/core-java-jpms/service-loader-api-pattern/consumermodule2/src/main/java/module-info.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/pom.xml b/core-java-modules/core-java-jpms/service-loader-api-pattern/pom.xml similarity index 91% rename from core-java-modules/core-java-jpms/decoupling-pattern2/pom.xml rename to core-java-modules/core-java-jpms/service-loader-api-pattern/pom.xml index 5b2e4cfc82..13a443eab5 100644 --- a/core-java-modules/core-java-jpms/decoupling-pattern2/pom.xml +++ b/core-java-modules/core-java-jpms/service-loader-api-pattern/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung.decoupling-pattern2 - decoupling-pattern2 + com.baeldung.service-loader-api-pattern + service-loader-api-pattern 1.0-SNAPSHOT pom diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/pom.xml b/core-java-modules/core-java-jpms/service-loader-api-pattern/providermodule/pom.xml similarity index 90% rename from core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/pom.xml rename to core-java-modules/core-java-jpms/service-loader-api-pattern/providermodule/pom.xml index ddb8aeccd1..bcee01f631 100644 --- a/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/pom.xml +++ b/core-java-modules/core-java-jpms/service-loader-api-pattern/providermodule/pom.xml @@ -8,8 +8,8 @@ 1.0 - com.baeldung.decoupling-pattern2 - decoupling-pattern2 + com.baeldung.service-loader-api-pattern + service-loader-api-pattern 1.0-SNAPSHOT diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/com/baeldung/providermodule/LowercaseTextService.java b/core-java-modules/core-java-jpms/service-loader-api-pattern/providermodule/src/main/java/com/baeldung/providermodule/LowercaseTextService.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/com/baeldung/providermodule/LowercaseTextService.java rename to core-java-modules/core-java-jpms/service-loader-api-pattern/providermodule/src/main/java/com/baeldung/providermodule/LowercaseTextService.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/module-info.java b/core-java-modules/core-java-jpms/service-loader-api-pattern/providermodule/src/main/java/module-info.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/module-info.java rename to core-java-modules/core-java-jpms/service-loader-api-pattern/providermodule/src/main/java/module-info.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule2/pom.xml b/core-java-modules/core-java-jpms/service-loader-api-pattern/servicemodule2/pom.xml similarity index 87% rename from core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule2/pom.xml rename to core-java-modules/core-java-jpms/service-loader-api-pattern/servicemodule2/pom.xml index 06ef900092..f40745541b 100644 --- a/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule2/pom.xml +++ b/core-java-modules/core-java-jpms/service-loader-api-pattern/servicemodule2/pom.xml @@ -8,8 +8,8 @@ 1.0 - com.baeldung.decoupling-pattern2 - decoupling-pattern2 + com.baeldung.service-loader-api-pattern + service-loader-api-pattern 1.0-SNAPSHOT diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule2/src/main/java/com/baeldung/servicemodule/TextService.java b/core-java-modules/core-java-jpms/service-loader-api-pattern/servicemodule2/src/main/java/com/baeldung/servicemodule/TextService.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule2/src/main/java/com/baeldung/servicemodule/TextService.java rename to core-java-modules/core-java-jpms/service-loader-api-pattern/servicemodule2/src/main/java/com/baeldung/servicemodule/TextService.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule2/src/main/java/module-info.java b/core-java-modules/core-java-jpms/service-loader-api-pattern/servicemodule2/src/main/java/module-info.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule2/src/main/java/module-info.java rename to core-java-modules/core-java-jpms/service-loader-api-pattern/servicemodule2/src/main/java/module-info.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule1/pom.xml b/core-java-modules/core-java-jpms/service-provider-factory-pattern/consumermodule1/pom.xml similarity index 89% rename from core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule1/pom.xml rename to core-java-modules/core-java-jpms/service-provider-factory-pattern/consumermodule1/pom.xml index f82e72b85d..ba92733f34 100644 --- a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule1/pom.xml +++ b/core-java-modules/core-java-jpms/service-provider-factory-pattern/consumermodule1/pom.xml @@ -8,8 +8,8 @@ jar - com.baeldung.decoupling-pattern1 - decoupling-pattern1 + com.baeldung.service-provider-factory-pattern + service-provider-factory-pattern 1.0-SNAPSHOT diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule1/src/main/java/com/baeldung/consumermodule/Application.java b/core-java-modules/core-java-jpms/service-provider-factory-pattern/consumermodule1/src/main/java/com/baeldung/consumermodule/Application.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule1/src/main/java/com/baeldung/consumermodule/Application.java rename to core-java-modules/core-java-jpms/service-provider-factory-pattern/consumermodule1/src/main/java/com/baeldung/consumermodule/Application.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule1/src/main/java/module-info.java b/core-java-modules/core-java-jpms/service-provider-factory-pattern/consumermodule1/src/main/java/module-info.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule1/src/main/java/module-info.java rename to core-java-modules/core-java-jpms/service-provider-factory-pattern/consumermodule1/src/main/java/module-info.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/pom.xml b/core-java-modules/core-java-jpms/service-provider-factory-pattern/pom.xml similarity index 91% rename from core-java-modules/core-java-jpms/decoupling-pattern1/pom.xml rename to core-java-modules/core-java-jpms/service-provider-factory-pattern/pom.xml index 2121b46b82..35a9912312 100644 --- a/core-java-modules/core-java-jpms/decoupling-pattern1/pom.xml +++ b/core-java-modules/core-java-jpms/service-provider-factory-pattern/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung.decoupling-pattern1 - decoupling-pattern1 + com.baeldung.service-provider-factory-pattern + service-provider-factory-pattern 1.0-SNAPSHOT pom diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/pom.xml b/core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/pom.xml similarity index 86% rename from core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/pom.xml rename to core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/pom.xml index fc4b5854f9..d6e50ee9ff 100644 --- a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/pom.xml +++ b/core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/pom.xml @@ -9,8 +9,8 @@ jar - com.baeldung.decoupling-pattern1 - decoupling-pattern1 + com.baeldung.service-provider-factory-pattern + service-provider-factory-pattern 1.0-SNAPSHOT diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/src/main/java/com/baeldung/servicemodule/external/TextService.java b/core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/src/main/java/com/baeldung/servicemodule/external/TextService.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/src/main/java/com/baeldung/servicemodule/external/TextService.java rename to core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/src/main/java/com/baeldung/servicemodule/external/TextService.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/src/main/java/com/baeldung/servicemodule/external/TextServiceFactory.java b/core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/src/main/java/com/baeldung/servicemodule/external/TextServiceFactory.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/src/main/java/com/baeldung/servicemodule/external/TextServiceFactory.java rename to core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/src/main/java/com/baeldung/servicemodule/external/TextServiceFactory.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/src/main/java/com/baeldung/servicemodule/internal/LowercaseTextService.java b/core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/src/main/java/com/baeldung/servicemodule/internal/LowercaseTextService.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/src/main/java/com/baeldung/servicemodule/internal/LowercaseTextService.java rename to core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/src/main/java/com/baeldung/servicemodule/internal/LowercaseTextService.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/src/main/java/com/baeldung/servicemodule/internal/UppercaseTextService.java b/core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/src/main/java/com/baeldung/servicemodule/internal/UppercaseTextService.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/src/main/java/com/baeldung/servicemodule/internal/UppercaseTextService.java rename to core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/src/main/java/com/baeldung/servicemodule/internal/UppercaseTextService.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/src/main/java/module-info.java b/core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/src/main/java/module-info.java similarity index 100% rename from core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule1/src/main/java/module-info.java rename to core-java-modules/core-java-jpms/service-provider-factory-pattern/servicemodule1/src/main/java/module-info.java diff --git a/core-java-modules/core-java-jvm-2/pom.xml b/core-java-modules/core-java-jvm-2/pom.xml index 01628b0908..2ccc847a6f 100644 --- a/core-java-modules/core-java-jvm-2/pom.xml +++ b/core-java-modules/core-java-jvm-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-jvm-2 - 0.1.0-SNAPSHOT core-java-jvm-2 jar @@ -27,9 +26,28 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + --add-exports=java.base/jdk.internal.vm.annotation=ALL-UNNAMED + + + + + + 0.10 0.10.2 + 11 + 11 \ No newline at end of file diff --git a/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/memlayout/MemoryLayoutUnitTest.java b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/memlayout/MemoryLayoutUnitTest.java index 2f226d7657..760115877e 100644 --- a/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/memlayout/MemoryLayoutUnitTest.java +++ b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/memlayout/MemoryLayoutUnitTest.java @@ -3,7 +3,8 @@ package com.baeldung.memlayout; import org.junit.Test; import org.openjdk.jol.info.ClassLayout; import org.openjdk.jol.vm.VM; -import sun.misc.Contended; + +import jdk.internal.vm.annotation.Contended; public class MemoryLayoutUnitTest { diff --git a/core-java-modules/core-java-jvm-3/pom.xml b/core-java-modules/core-java-jvm-3/pom.xml index cb2d8b0b85..78f4201c94 100644 --- a/core-java-modules/core-java-jvm-3/pom.xml +++ b/core-java-modules/core-java-jvm-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-jvm-3 - 0.1.0-SNAPSHOT core-java-jvm-3 jar @@ -14,7 +13,4 @@ 0.0.1-SNAPSHOT - - - \ No newline at end of file diff --git a/core-java-modules/core-java-jvm/pom.xml b/core-java-modules/core-java-jvm/pom.xml index d26c72323f..52bdf8bc5d 100644 --- a/core-java-modules/core-java-jvm/pom.xml +++ b/core-java-modules/core-java-jvm/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-jvm - 0.1.0-SNAPSHOT core-java-jvm jar @@ -30,13 +29,6 @@ esapi ${esapi.version} - - com.sun - tools - ${sun.tools.version} - system - ${java.home}/../lib/tools.jar - org.ow2.asm asm @@ -176,9 +168,8 @@ 3.27.0-GA - 1.8.0 0.10 - 8.0.1 + 9.4 6.5.0 diff --git a/core-java-modules/core-java-jvm/src/main/java/com/baeldung/classloader/PrintClassLoader.java b/core-java-modules/core-java-jvm/src/main/java/com/baeldung/classloader/PrintClassLoader.java index 09ee68bf6e..cd7000b419 100644 --- a/core-java-modules/core-java-jvm/src/main/java/com/baeldung/classloader/PrintClassLoader.java +++ b/core-java-modules/core-java-jvm/src/main/java/com/baeldung/classloader/PrintClassLoader.java @@ -1,13 +1,7 @@ package com.baeldung.classloader; -import com.sun.javafx.util.Logging; +import java.sql.DriverManager; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; import java.util.ArrayList; public class PrintClassLoader { @@ -15,7 +9,7 @@ public class PrintClassLoader { public void printClassLoaders() throws ClassNotFoundException { System.out.println("Classloader of this class:" + PrintClassLoader.class.getClassLoader()); - System.out.println("Classloader of Logging:" + Logging.class.getClassLoader()); + System.out.println("Classloader of DriverManager:" + DriverManager.class.getClassLoader()); System.out.println("Classloader of ArrayList:" + ArrayList.class.getClassLoader()); } diff --git a/core-java-modules/core-java-jvm/src/test/java/com/baeldung/bytecode/ViewBytecodeUnitTest.java b/core-java-modules/core-java-jvm/src/test/java/com/baeldung/bytecode/ViewBytecodeUnitTest.java index 5b0fdf26d4..2a7366c322 100644 --- a/core-java-modules/core-java-jvm/src/test/java/com/baeldung/bytecode/ViewBytecodeUnitTest.java +++ b/core-java-modules/core-java-jvm/src/test/java/com/baeldung/bytecode/ViewBytecodeUnitTest.java @@ -33,7 +33,7 @@ public class ViewBytecodeUnitTest { JavaClass objectClazz = Repository.lookupClass("java.lang.Object"); assertEquals(objectClazz.getClassName(), "java.lang.Object"); - assertEquals(objectClazz.getMethods().length, 14); + assertEquals(objectClazz.getMethods().length, 12); assertTrue(objectClazz.toString().contains("public class java.lang.Object")); } @@ -43,7 +43,7 @@ public class ViewBytecodeUnitTest { ClassFile cf = cp.get("java.lang.Object").getClassFile(); assertEquals(cf.getName(), "java.lang.Object"); - assertEquals(cf.getMethods().size(), 14); + assertEquals(cf.getMethods().size(), 12); } } diff --git a/core-java-modules/core-java-lambdas/README.md b/core-java-modules/core-java-lambdas/README.md index 56b2a79e7e..cad2097673 100644 --- a/core-java-modules/core-java-lambdas/README.md +++ b/core-java-modules/core-java-lambdas/README.md @@ -10,4 +10,3 @@ - [Serialize a Lambda in Java](https://www.baeldung.com/java-serialize-lambda) - [Convert Anonymous Class into Lambda in Java](https://www.baeldung.com/java-from-anonymous-class-to-lambda) - [When to Use Callable and Supplier in Java](https://www.baeldung.com/java-callable-vs-supplier) -- [Lambda Expression vs. Anonymous Inner Class](https://www.baeldung.com/java-lambdas-vs-anonymous-class) diff --git a/core-java-modules/core-java-lambdas/pom.xml b/core-java-modules/core-java-lambdas/pom.xml index f1e61ab8bf..a7fc5355d7 100644 --- a/core-java-modules/core-java-lambdas/pom.xml +++ b/core-java-modules/core-java-lambdas/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lambdas - 0.1.0-SNAPSHOT core-java-lambdas jar diff --git a/core-java-modules/core-java-lang-2/pom.xml b/core-java-modules/core-java-lang-2/pom.xml index 4a89a22577..22055cf252 100644 --- a/core-java-modules/core-java-lang-2/pom.xml +++ b/core-java-modules/core-java-lang-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lang-2 - 0.1.0-SNAPSHOT core-java-lang-2 jar diff --git a/core-java-modules/core-java-lang-2/src/test/java/com/baeldung/headlessmode/HeadlessModeUnitTest.java b/core-java-modules/core-java-lang-2/src/test/java/com/baeldung/headlessmode/HeadlessModeUnitTest.java index a17c1600f3..d64d8c16da 100644 --- a/core-java-modules/core-java-lang-2/src/test/java/com/baeldung/headlessmode/HeadlessModeUnitTest.java +++ b/core-java-modules/core-java-lang-2/src/test/java/com/baeldung/headlessmode/HeadlessModeUnitTest.java @@ -3,13 +3,12 @@ package com.baeldung.headlessmode; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import java.awt.Canvas; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Frame; -import java.awt.GraphicsEnvironment; -import java.awt.HeadlessException; +import java.awt.*; import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.WritableRaster; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -58,7 +57,7 @@ public class HeadlessModeUnitTest { boolean result = false; try (InputStream inStream = HeadlessModeUnitTest.class.getResourceAsStream(IN_FILE); FileOutputStream outStream = new FileOutputStream(OUT_FILE)) { BufferedImage inputImage = ImageIO.read(inStream); - result = ImageIO.write(inputImage, FORMAT, outStream); + result = ImageIO.write(removeAlphaChannel(inputImage), FORMAT, outStream); } assertThat(result).isTrue(); @@ -84,4 +83,10 @@ public class HeadlessModeUnitTest { assertThat(FlexibleApp.iAmFlexible()).isEqualTo(FlexibleApp.HEADED); } + private BufferedImage removeAlphaChannel(BufferedImage inputImage) { + final WritableRaster raster = inputImage.getRaster(); + final WritableRaster newRaster = raster.createWritableChild(0, 0, inputImage.getWidth(), inputImage.getHeight(), 0, 0, new int[]{0, 1, 2}); + ColorModel newCM = new ComponentColorModel(inputImage.getColorModel().getColorSpace(), false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); + return new BufferedImage(newCM, newRaster, false, null); + } } diff --git a/core-java-modules/core-java-lang-3/pom.xml b/core-java-modules/core-java-lang-3/pom.xml index 331d91dff6..f29fa6494a 100644 --- a/core-java-modules/core-java-lang-3/pom.xml +++ b/core-java-modules/core-java-lang-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lang-3 - 0.1.0-SNAPSHOT core-java-lang-3 jar diff --git a/core-java-modules/core-java-lang-4/pom.xml b/core-java-modules/core-java-lang-4/pom.xml index de67ddf55a..6977621a0e 100644 --- a/core-java-modules/core-java-lang-4/pom.xml +++ b/core-java-modules/core-java-lang-4/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lang-4 - 0.1.0-SNAPSHOT core-java-lang-4 jar diff --git a/core-java-modules/core-java-lang-5/pom.xml b/core-java-modules/core-java-lang-5/pom.xml index e3130632fb..8e95fc4405 100644 --- a/core-java-modules/core-java-lang-5/pom.xml +++ b/core-java-modules/core-java-lang-5/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lang-5 - 0.1.0-SNAPSHOT core-java-lang-5 jar @@ -13,12 +12,6 @@ core-java-modules 0.0.1-SNAPSHOT - - - 3.12.0 - 0.10.2 - - core-java-lang-5 @@ -29,4 +22,10 @@ + + + 3.12.0 + 0.10.2 + + \ No newline at end of file diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/rawtypes/RawTypesUnitTest.java b/core-java-modules/core-java-lang-5/src/test/java/com/baeldung/rawtypes/RawTypesUnitTest.java similarity index 100% rename from core-java-modules/core-java/src/test/java/com/baeldung/rawtypes/RawTypesUnitTest.java rename to core-java-modules/core-java-lang-5/src/test/java/com/baeldung/rawtypes/RawTypesUnitTest.java diff --git a/core-java-modules/core-java-lang-math-2/pom.xml b/core-java-modules/core-java-lang-math-2/pom.xml index e6ead53350..223c791d35 100644 --- a/core-java-modules/core-java-lang-math-2/pom.xml +++ b/core-java-modules/core-java-lang-math-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lang-math-2 - 0.0.1-SNAPSHOT core-java-lang-math-2 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 89adc23100..847bd314a7 100644 --- a/core-java-modules/core-java-lang-math-3/README.md +++ b/core-java-modules/core-java-lang-math-3/README.md @@ -10,4 +10,5 @@ - [Create a BMI Calculator in Java](https://www.baeldung.com/java-body-mass-index-calculator) - [Java Program to Calculate the Standard Deviation](https://www.baeldung.com/java-calculate-standard-deviation) - [Java Program to Print Pascal’s Triangle](https://www.baeldung.com/java-pascal-triangle) +- [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency) - More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2) diff --git a/core-java-modules/core-java-lang-math-3/pom.xml b/core-java-modules/core-java-lang-math-3/pom.xml index 38cb6dfa17..7860f57735 100644 --- a/core-java-modules/core-java-lang-math-3/pom.xml +++ b/core-java-modules/core-java-lang-math-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lang-math-3 - 0.0.1-SNAPSHOT core-java-lang-math-3 @@ -24,11 +23,17 @@ javaluator ${javaluator.version} + + org.javamoney + moneta + ${javamoney.moneta.version} + 0.4.8 3.0.3 + 1.1 \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/money/JavaMoney.java b/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/money/JavaMoney.java similarity index 100% rename from core-java-modules/core-java/src/main/java/com/baeldung/money/JavaMoney.java rename to core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/money/JavaMoney.java diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/money/JavaMoneyUnitManualTest.java b/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/money/JavaMoneyUnitManualTest.java similarity index 100% rename from core-java-modules/core-java/src/test/java/com/baeldung/money/JavaMoneyUnitManualTest.java rename to core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/money/JavaMoneyUnitManualTest.java diff --git a/core-java-modules/core-java-lang-math/pom.xml b/core-java-modules/core-java-lang-math/pom.xml index 37550b67d8..551e5db1d5 100644 --- a/core-java-modules/core-java-lang-math/pom.xml +++ b/core-java-modules/core-java-lang-math/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lang-math - 0.1.0-SNAPSHOT core-java-lang-math jar diff --git a/core-java-modules/core-java-lang-oop-constructors-2/README.md b/core-java-modules/core-java-lang-oop-constructors-2/README.md new file mode 100644 index 0000000000..d9b162c7a6 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-constructors-2/README.md @@ -0,0 +1,7 @@ +## Core Java Lang OOP - Constructors - Part 2 + +This module contains article about constructors in Java + +### Relevant Articles: +- [Different Ways to Create an Object in Java](https://www.baeldung.com/java-different-ways-to-create-objects) +- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-oop-constructors) \ No newline at end of file diff --git a/core-java-modules/core-java-lang-oop-constructors-2/pom.xml b/core-java-modules/core-java-lang-oop-constructors-2/pom.xml new file mode 100644 index 0000000000..c6d9d84774 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-constructors-2/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + core-java-lang-oop-constructors-2 + core-java-lang-oop-constructors-2 + jar + + + core-java-modules + com.baeldung.core-java-modules + 0.0.1-SNAPSHOT + + + \ No newline at end of file diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/objectcreation/objects/ClonableRabbit.java b/core-java-modules/core-java-lang-oop-constructors-2/src/main/java/com/baeldung/objectcreation/objects/ClonableRabbit.java similarity index 100% rename from core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/objectcreation/objects/ClonableRabbit.java rename to core-java-modules/core-java-lang-oop-constructors-2/src/main/java/com/baeldung/objectcreation/objects/ClonableRabbit.java diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/objectcreation/objects/Rabbit.java b/core-java-modules/core-java-lang-oop-constructors-2/src/main/java/com/baeldung/objectcreation/objects/Rabbit.java similarity index 100% rename from core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/objectcreation/objects/Rabbit.java rename to core-java-modules/core-java-lang-oop-constructors-2/src/main/java/com/baeldung/objectcreation/objects/Rabbit.java diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/objectcreation/objects/RabbitType.java b/core-java-modules/core-java-lang-oop-constructors-2/src/main/java/com/baeldung/objectcreation/objects/RabbitType.java similarity index 100% rename from core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/objectcreation/objects/RabbitType.java rename to core-java-modules/core-java-lang-oop-constructors-2/src/main/java/com/baeldung/objectcreation/objects/RabbitType.java diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/objectcreation/objects/SerializableRabbit.java b/core-java-modules/core-java-lang-oop-constructors-2/src/main/java/com/baeldung/objectcreation/objects/SerializableRabbit.java similarity index 100% rename from core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/objectcreation/objects/SerializableRabbit.java rename to core-java-modules/core-java-lang-oop-constructors-2/src/main/java/com/baeldung/objectcreation/objects/SerializableRabbit.java diff --git a/core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/objectcreation/utils/CreateRabbits.java b/core-java-modules/core-java-lang-oop-constructors-2/src/main/java/com/baeldung/objectcreation/utils/CreateRabbits.java similarity index 100% rename from core-java-modules/core-java-lang-oop-constructors/src/main/java/com/baeldung/objectcreation/utils/CreateRabbits.java rename to core-java-modules/core-java-lang-oop-constructors-2/src/main/java/com/baeldung/objectcreation/utils/CreateRabbits.java diff --git a/core-java-modules/core-java-lang-oop-constructors/src/test/java/com/baeldung/objectcreation/CreateRabbitsUnitTest.java b/core-java-modules/core-java-lang-oop-constructors-2/src/test/java/com/baeldung/objectcreation/CreateRabbitsUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-oop-constructors/src/test/java/com/baeldung/objectcreation/CreateRabbitsUnitTest.java rename to core-java-modules/core-java-lang-oop-constructors-2/src/test/java/com/baeldung/objectcreation/CreateRabbitsUnitTest.java diff --git a/core-java-modules/core-java-lang-oop-constructors/README.md b/core-java-modules/core-java-lang-oop-constructors/README.md index 4ac9224bb1..c35cb836a5 100644 --- a/core-java-modules/core-java-lang-oop-constructors/README.md +++ b/core-java-modules/core-java-lang-oop-constructors/README.md @@ -13,4 +13,4 @@ This module contains article about constructors in Java - [Constructor Specification in Java](https://www.baeldung.com/java-constructor-specification) - [Static vs. Instance Initializer Block in Java](https://www.baeldung.com/java-static-instance-initializer-blocks) - [Accessing Private Constructor in Java](https://www.baeldung.com/java-private-constructor-access) -- [Different Ways to Create an Object in Java](https://www.baeldung.com/java-different-ways-to-create-objects) +- More articles: [[next -->]](/core-java-modules/core-java-lang-oop-constructors-2) \ No newline at end of file diff --git a/core-java-modules/core-java-lang-oop-methods/README.md b/core-java-modules/core-java-lang-oop-methods/README.md index f34606f26a..053cafac3e 100644 --- a/core-java-modules/core-java-lang-oop-methods/README.md +++ b/core-java-modules/core-java-lang-oop-methods/README.md @@ -11,3 +11,4 @@ This module contains articles about methods in Java - [The Covariant Return Type in Java](https://www.baeldung.com/java-covariant-return-type) - [Does a Method’s Signature Include the Return Type in Java?](https://www.baeldung.com/java-method-signature-return-type) - [Solving the Hide Utility Class Public Constructor Sonar Warning](https://www.baeldung.com/java-sonar-hide-implicit-constructor) +- [Best Practices for Passing Many Arguments to a Method in Java](https://www.baeldung.com/java-best-practices-many-parameters-method) diff --git a/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/methods/Car.java b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/methods/Car.java new file mode 100644 index 0000000000..a72d7dd0f1 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/methods/Car.java @@ -0,0 +1,98 @@ +package com.baeldung.methods; + +public class Car { + + private final String make; + private final String model; + private final int year; + private final String color; + private final boolean automatic; + private final int numDoors; + private final String features; + + private Car(CarBuilder carBuilder) { + this.make = carBuilder.make; + this.model = carBuilder.model; + this.year = carBuilder.year; + this.color = carBuilder.color; + this.automatic = carBuilder.automatic; + this.numDoors = carBuilder.numDoors; + this.features = carBuilder.features; + } + + public String getMake() { + return make; + } + + public String getModel() { + return model; + } + + public int getYear() { + return year; + } + + public String getColor() { + return color; + } + + public boolean isAutomatic() { + return automatic; + } + + public int getNumDoors() { + return numDoors; + } + + public String getFeatures() { + return features; + } + + public static class CarBuilder { + + private final String make; + private final String model; + private final int year; + + private String color = "unknown"; + private boolean automatic = false; + private int numDoors = 4; + private String features = ""; + + public CarBuilder(String make, String model, int year) { + this.make = make; + this.model = model; + this.year = year; + } + + public CarBuilder color(String color) { + this.color = color; + return this; + } + + public CarBuilder automatic(boolean automatic) { + this.automatic = automatic; + return this; + } + + public CarBuilder numDoors(int numDoors) { + this.numDoors = numDoors; + return this; + } + + public CarBuilder features(String features) { + this.features = features; + return this; + } + + public Car build() { + return new Car(this); + } + } + + @Override + public String toString() { + return "Car [make=" + make + ", model=" + model + ", year=" + year + ", color=" + color + ", automatic=" + automatic + ", numDoors=" + numDoors + ", features=" + features + "]"; + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/methods/Motorcycle.java b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/methods/Motorcycle.java new file mode 100644 index 0000000000..8a1fce4a5d --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/methods/Motorcycle.java @@ -0,0 +1,52 @@ +package com.baeldung.methods; + +import java.io.Serializable; + +public class Motorcycle extends Vehicle implements Serializable { + + private static final long serialVersionUID = 5973661295933599929L; + + private int year; + private String features = ""; + + public Motorcycle() { + super(); + } + + public Motorcycle(String make, String model, String color, int weight, boolean statusNew, int year) { + super(make, model, color, weight, statusNew); + this.year = year; + } + + public Motorcycle(Vehicle vehicle, int year) { + super(vehicle); + this.year = year; + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public void setFeatures(String features) { + this.features = features; + } + + public String getFeatures() { + return features; + } + + public void addMotorcycleFeatures(String... features) { + StringBuilder str = new StringBuilder(this.getFeatures()); + for (String feature : features) { + if (!str.toString().isEmpty()) + str.append(", "); + str.append(feature); + } + this.setFeatures(str.toString()); + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/methods/Vehicle.java b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/methods/Vehicle.java new file mode 100644 index 0000000000..0c6964d255 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/methods/Vehicle.java @@ -0,0 +1,33 @@ +package com.baeldung.methods; + +public class Vehicle { + + static String defaultValue = "DEFAULT"; + private String make = defaultValue; + private String model = defaultValue; + private String color = defaultValue; + private int weight = 0; + private boolean statusNew = true; + + public Vehicle() { + super(); + } + + public Vehicle(String make, String model, String color, int weight, boolean statusNew) { + this.make = make; + this.model = model; + this.color = color; + this.weight = weight; + this.statusNew = statusNew; + } + + public Vehicle(Vehicle vehicle) { + this(vehicle.make, vehicle.model, vehicle.color, vehicle.weight, vehicle.statusNew); + } + + @Override + public String toString() { + return "Vehicle [make=" + make + ", model=" + model + ", color=" + color + ", weight=" + weight + ", statusNew=" + statusNew + "]"; + } + +} diff --git a/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/methods/VehicleProcessor.java b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/methods/VehicleProcessor.java new file mode 100644 index 0000000000..a7d5975813 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/methods/VehicleProcessor.java @@ -0,0 +1,20 @@ +package com.baeldung.methods; + +public class VehicleProcessor { + + Vehicle processVehicle(String make, String model, String color, int weight, boolean status) { + return new Vehicle(make, model, color, weight, status); + } + + Vehicle processVehicle(Vehicle vehicle) { + return new Vehicle(vehicle); + } + + Car processCar(Car car) { + return new Car.CarBuilder(car.getMake(), car.getModel(), car.getYear()).color(car.getColor()) + .automatic(car.isAutomatic()) + .features(car.getFeatures()) + .build(); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/methods/VehicleProcessorUnitTest.java b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/methods/VehicleProcessorUnitTest.java new file mode 100644 index 0000000000..928fbcb426 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/methods/VehicleProcessorUnitTest.java @@ -0,0 +1,58 @@ +package com.baeldung.methods; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class VehicleProcessorUnitTest { + + VehicleProcessor vehicleProcessor = new VehicleProcessor(); + Vehicle vehicle = new Vehicle("Ford", "Focus", "red", 2200, true); + + @Test + void givenAllArguments_whenMethodCall_thenVerifyCallIsDoneCorrectly() { + Vehicle veh = vehicleProcessor.processVehicle("Ford", "Focus", "red", 2200, true); + assertThat(veh.toString()).hasToString(vehicle.toString()); + } + + @Test + void givenParameterObject_whenMethodCall_thenVerifyCallIsDoneCorrectly() { + Vehicle veh = vehicleProcessor.processVehicle(vehicle); + assertThat(veh.toString()).hasToString(vehicle.toString()); + } + + @Test + void givenJavaBeanPattern_whenMethodCall_thenVerifyCallIsDoneCorrectly() { + Motorcycle motorcycle = new Motorcycle("Ducati", "Monster", "yellow", 235, true, 2023); + motorcycle.setFeatures("GPS"); + + vehicleProcessor.processVehicle(motorcycle); + assertThat(motorcycle.getFeatures()).isEqualToIgnoringCase("GPS"); + } + + @Test + void givenJavaVarargs_whenMethodCall_thenAssertTheReturnedConcatenatedString() { + Motorcycle motorcycle = new Motorcycle("Ducati", "Monster", "red", 350, true, 2023); + motorcycle.addMotorcycleFeatures("abs"); + assertThat(motorcycle.getFeatures()).isEqualToIgnoringCase("abs"); + + motorcycle.addMotorcycleFeatures("navi", "charger"); + assertThat(motorcycle.getFeatures()).isEqualToIgnoringCase("abs, navi, charger"); + + motorcycle.addMotorcycleFeatures("wifi", "phone", "satellite"); + assertThat(motorcycle.getFeatures()).isEqualToIgnoringCase("abs, navi, charger, wifi, phone, satellite"); + } + + @Test + void givenJavaBuilderPattern_whenMethodCall_thenVerifyCallIsDoneCorrectly() { + Car car = new Car.CarBuilder("Ford", "Focus", 2023).color("blue") + .automatic(true) + .features("abs, navi, charger, wifi, phone, satellite") + .build(); + + Car result = vehicleProcessor.processCar(car); + + assertThat(result.toString()).hasToString(car.toString()); + } + +} diff --git a/core-java-modules/core-java-lang-oop-modifiers/pom.xml b/core-java-modules/core-java-lang-oop-modifiers/pom.xml index c193073a0e..459aa21721 100644 --- a/core-java-modules/core-java-lang-oop-modifiers/pom.xml +++ b/core-java-modules/core-java-lang-oop-modifiers/pom.xml @@ -23,7 +23,7 @@ - 1.4.197 + 2.1.214 \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/staticclass/Pizza.java b/core-java-modules/core-java-lang-oop-modifiers/src/main/java/com/baeldung/staticclass/Pizza.java similarity index 100% rename from core-java-modules/core-java/src/main/java/com/baeldung/staticclass/Pizza.java rename to core-java-modules/core-java-lang-oop-modifiers/src/main/java/com/baeldung/staticclass/Pizza.java diff --git a/core-java-modules/core-java-lang-oop-modifiers/src/main/java/com/baeldung/staticmodifier/Car.java b/core-java-modules/core-java-lang-oop-modifiers/src/main/java/com/baeldung/staticmodifier/Car.java index 950f008dcd..1158851fbd 100644 --- a/core-java-modules/core-java-lang-oop-modifiers/src/main/java/com/baeldung/staticmodifier/Car.java +++ b/core-java-modules/core-java-lang-oop-modifiers/src/main/java/com/baeldung/staticmodifier/Car.java @@ -42,6 +42,10 @@ public class Car { this.engine = engine; } + public static String getCarsInformation(Car car) { + return car.getName() + "-" + car.getEngine(); + } + public static void setNumberOfCars(int numberOfCars) { Car.numberOfCars = numberOfCars; } diff --git a/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmethod/CallNonStaticMethodUnitTest.java b/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmethod/CallNonStaticMethodUnitTest.java new file mode 100644 index 0000000000..1171cb2e7a --- /dev/null +++ b/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmethod/CallNonStaticMethodUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.staticmethod; + +import static org.junit.Assert.assertEquals; + +import org.junit.AfterClass; +import org.junit.Test; + +import com.baeldung.staticmodifier.Car; + +public class CallNonStaticMethodUnitTest { + @AfterClass + public static void setUpCarInstance() { + Car.setNumberOfCars(0); + } + @Test + public void whenCallingNonStaticMethodInStaticMethodWithInstanceClass_thenSuccess() { + Car car = new Car("Jaguar", "V8"); + assertEquals("Jaguar-V8", Car.getCarsInformation(car)); + } + +} diff --git a/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmodifier/CarUnitTest.java b/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmodifier/CarUnitTest.java index f55955caa8..68bbe8f0a2 100644 --- a/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmodifier/CarUnitTest.java +++ b/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmodifier/CarUnitTest.java @@ -2,9 +2,16 @@ package com.baeldung.staticmodifier; import static org.junit.Assert.*; +import org.junit.AfterClass; import org.junit.Test; public class CarUnitTest { + + @AfterClass + public static void setUpCarInstance() { + Car.setNumberOfCars(0); + } + @Test public void whenNumberOfCarObjectsInitialized_thenStaticCounterIncreases() { new Car("Jaguar", "V8"); diff --git a/core-java-modules/core-java-lang-oop-patterns/README.md b/core-java-modules/core-java-lang-oop-patterns/README.md index df68a1413a..ea3309dc0a 100644 --- a/core-java-modules/core-java-lang-oop-patterns/README.md +++ b/core-java-modules/core-java-lang-oop-patterns/README.md @@ -8,3 +8,4 @@ This module contains articles about Object-oriented programming (OOP) patterns i - [Immutable Objects in Java](https://www.baeldung.com/java-immutable-object) - [How to Make a Deep Copy of an Object in Java](https://www.baeldung.com/java-deep-copy) - [Using an Interface vs. Abstract Class in Java](https://www.baeldung.com/java-interface-vs-abstract-class) +- [Should We Create an Interface for Only One Implementation?](https://www.baeldung.com/java-interface-single-implementation) diff --git a/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/interfacesingleimpl/Animal.java b/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/interfacesingleimpl/Animal.java new file mode 100644 index 0000000000..b20c01cac9 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/interfacesingleimpl/Animal.java @@ -0,0 +1,5 @@ +package com.baeldung.interfacesingleimpl; + +public interface Animal { + String makeSound(); +} diff --git a/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/interfacesingleimpl/AnimalCare.java b/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/interfacesingleimpl/AnimalCare.java new file mode 100644 index 0000000000..0d7b732056 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/interfacesingleimpl/AnimalCare.java @@ -0,0 +1,13 @@ +package com.baeldung.interfacesingleimpl; + +public class AnimalCare { + private Animal animal; + + public AnimalCare(Animal animal) { + this.animal = animal; + } + + public String animalSound() { + return animal.makeSound(); + } +} diff --git a/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/interfacesingleimpl/Cat.java b/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/interfacesingleimpl/Cat.java new file mode 100644 index 0000000000..7540e0823b --- /dev/null +++ b/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/interfacesingleimpl/Cat.java @@ -0,0 +1,21 @@ +package com.baeldung.interfacesingleimpl; + +public class Cat { + private String name; + + public Cat(String name) { + this.name = name; + } + + public String makeSound() { + return "Meow! My name is " + name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/interfacesingleimpl/Dog.java b/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/interfacesingleimpl/Dog.java new file mode 100644 index 0000000000..1dfd3bea0d --- /dev/null +++ b/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/interfacesingleimpl/Dog.java @@ -0,0 +1,22 @@ +package com.baeldung.interfacesingleimpl; + +public class Dog implements Animal { + private String name; + + public Dog(String name) { + this.name = name; + } + + @Override + public String makeSound() { + return "Woof! My name is " + name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/core-java-modules/core-java-lang-oop-patterns/src/test/java/com/baeldung/interfacesingleimpl/InterfaceSingleImplUnitTest.java b/core-java-modules/core-java-lang-oop-patterns/src/test/java/com/baeldung/interfacesingleimpl/InterfaceSingleImplUnitTest.java new file mode 100644 index 0000000000..4044a554a3 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-patterns/src/test/java/com/baeldung/interfacesingleimpl/InterfaceSingleImplUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.interfacesingleimpl; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +public class InterfaceSingleImplUnitTest { + @Test + public void whenUsingMockAnimal_thenAnimalSoundIsCorrect() { + MockAnimal mockAnimal = new MockAnimal(); + String expected = "Mock animal sound!"; + AnimalCare animalCare = new AnimalCare(mockAnimal); + assertThat(animalCare.animalSound()).isEqualTo(expected); + } + + @Test + public void whenCreatingDog_thenDogMakesWoofSound() { + Dog dog = new Dog("Buddy"); + String expected = "Woof! My name is Buddy"; + assertThat(dog.makeSound()).isEqualTo(expected); + } + + @Test + public void whenCreatingCat_thenCatMakesMeowSound() { + Cat cat = new Cat("FuzzBall"); + String expected = "Meow! My name is FuzzBall"; + assertThat(cat.makeSound()).isEqualTo(expected); + } + + @Test + public void whenCreatingAnimalCareWithDog_thenDogMakesWoofSound() { + Animal dog = new Dog("Ham"); + AnimalCare animalCare = new AnimalCare(dog); + String expected = "Woof! My name is Ham"; + assertThat(animalCare.animalSound()).isEqualTo(expected); + } + + @Test + public void whenCreatingCatCareWithCat_thenCatMakesMeowSound() { + Cat cat = new Cat("Grumpy"); + String expected = "Meow! My name is Grumpy"; + assertThat(cat.makeSound()).isEqualTo(expected); + } + + @Test + public void whenCreatingMockAnimal_thenMockAnimalMakesMockAnimalSound() { + MockAnimal mockAnimal = new MockAnimal(); + String expected = "Mock animal sound!"; + assertThat(mockAnimal.makeSound()).isEqualTo(expected); + } +} diff --git a/core-java-modules/core-java-lang-oop-patterns/src/test/java/com/baeldung/interfacesingleimpl/MockAnimal.java b/core-java-modules/core-java-lang-oop-patterns/src/test/java/com/baeldung/interfacesingleimpl/MockAnimal.java new file mode 100644 index 0000000000..1d3b264f45 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-patterns/src/test/java/com/baeldung/interfacesingleimpl/MockAnimal.java @@ -0,0 +1,8 @@ +package com.baeldung.interfacesingleimpl; + +public class MockAnimal implements Animal { + @Override + public String makeSound() { + return "Mock animal sound!"; + } +} diff --git a/core-java-modules/core-java-lang-operators-2/pom.xml b/core-java-modules/core-java-lang-operators-2/pom.xml index 9d925c553a..4170f9f6a0 100644 --- a/core-java-modules/core-java-lang-operators-2/pom.xml +++ b/core-java-modules/core-java-lang-operators-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lang-operators-2 - 0.1.0-SNAPSHOT core-java-lang-operators-2 jar diff --git a/core-java-modules/core-java-lang-operators/pom.xml b/core-java-modules/core-java-lang-operators/pom.xml index c61fb81354..1815d01dcc 100644 --- a/core-java-modules/core-java-lang-operators/pom.xml +++ b/core-java-modules/core-java-lang-operators/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lang-operators - 0.1.0-SNAPSHOT core-java-lang-operators jar diff --git a/core-java-modules/core-java-lang-syntax-2/pom.xml b/core-java-modules/core-java-lang-syntax-2/pom.xml index fdb0503174..bae5f0b6bd 100644 --- a/core-java-modules/core-java-lang-syntax-2/pom.xml +++ b/core-java-modules/core-java-lang-syntax-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lang-syntax-2 - 0.1.0-SNAPSHOT core-java-lang-syntax-2 jar diff --git a/core-java-modules/core-java-lang-syntax/pom.xml b/core-java-modules/core-java-lang-syntax/pom.xml index 7cdbc40fbc..005bdc73cc 100644 --- a/core-java-modules/core-java-lang-syntax/pom.xml +++ b/core-java-modules/core-java-lang-syntax/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lang-syntax - 0.1.0-SNAPSHOT core-java-lang-syntax jar diff --git a/core-java-modules/core-java-lang/pom.xml b/core-java-modules/core-java-lang/pom.xml index 4989c6a5a7..27cf0ac276 100644 --- a/core-java-modules/core-java-lang/pom.xml +++ b/core-java-modules/core-java-lang/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-lang - 0.1.0-SNAPSHOT core-java-lang jar diff --git a/core-java-modules/core-java-locale/README.md b/core-java-modules/core-java-locale/README.md new file mode 100644 index 0000000000..744b5e760f --- /dev/null +++ b/core-java-modules/core-java-locale/README.md @@ -0,0 +1,6 @@ + Core Java Locale + +### Relevant Articles: + +- [A Guide to the ResourceBundle](http://www.baeldung.com/java-resourcebundle) + diff --git a/core-java-modules/core-java-locale/pom.xml b/core-java-modules/core-java-locale/pom.xml new file mode 100644 index 0000000000..f493d572a1 --- /dev/null +++ b/core-java-modules/core-java-locale/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + core-java-locale + 0.1.0-SNAPSHOT + core-java-locale + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/resourcebundle/ExampleControl.java b/core-java-modules/core-java-locale/src/main/java/com/baeldung/resourcebundle/ExampleControl.java similarity index 100% rename from core-java-modules/core-java/src/main/java/com/baeldung/resourcebundle/ExampleControl.java rename to core-java-modules/core-java-locale/src/main/java/com/baeldung/resourcebundle/ExampleControl.java diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource.java b/core-java-modules/core-java-locale/src/main/java/com/baeldung/resourcebundle/ExampleResource.java similarity index 100% rename from core-java-modules/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource.java rename to core-java-modules/core-java-locale/src/main/java/com/baeldung/resourcebundle/ExampleResource.java diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl.java b/core-java-modules/core-java-locale/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl.java similarity index 100% rename from core-java-modules/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl.java rename to core-java-modules/core-java-locale/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl.java diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl_PL.java b/core-java-modules/core-java-locale/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl_PL.java similarity index 100% rename from core-java-modules/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl_PL.java rename to core-java-modules/core-java-locale/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl_PL.java diff --git a/core-java-modules/core-java/src/main/resources/resourcebundle/resource.properties b/core-java-modules/core-java-locale/src/main/resources/resourcebundle/resource.properties similarity index 100% rename from core-java-modules/core-java/src/main/resources/resourcebundle/resource.properties rename to core-java-modules/core-java-locale/src/main/resources/resourcebundle/resource.properties diff --git a/core-java-modules/core-java/src/main/resources/resourcebundle/resource_en.properties b/core-java-modules/core-java-locale/src/main/resources/resourcebundle/resource_en.properties similarity index 100% rename from core-java-modules/core-java/src/main/resources/resourcebundle/resource_en.properties rename to core-java-modules/core-java-locale/src/main/resources/resourcebundle/resource_en.properties diff --git a/core-java-modules/core-java/src/main/resources/resourcebundle/resource_pl_PL.properties b/core-java-modules/core-java-locale/src/main/resources/resourcebundle/resource_pl_PL.properties similarity index 100% rename from core-java-modules/core-java/src/main/resources/resourcebundle/resource_pl_PL.properties rename to core-java-modules/core-java-locale/src/main/resources/resourcebundle/resource_pl_PL.properties diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/resourcebundle/ExampleResourceUnitTest.java b/core-java-modules/core-java-locale/src/test/java/com/baeldung/resourcebundle/ExampleResourceUnitTest.java similarity index 100% rename from core-java-modules/core-java/src/test/java/com/baeldung/resourcebundle/ExampleResourceUnitTest.java rename to core-java-modules/core-java-locale/src/test/java/com/baeldung/resourcebundle/ExampleResourceUnitTest.java diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/resourcebundle/PropertyResourceUnitTest.java b/core-java-modules/core-java-locale/src/test/java/com/baeldung/resourcebundle/PropertyResourceUnitTest.java similarity index 100% rename from core-java-modules/core-java/src/test/java/com/baeldung/resourcebundle/PropertyResourceUnitTest.java rename to core-java-modules/core-java-locale/src/test/java/com/baeldung/resourcebundle/PropertyResourceUnitTest.java diff --git a/core-java-modules/core-java-methods/README.md b/core-java-modules/core-java-methods/README.md new file mode 100644 index 0000000000..b2208778e7 --- /dev/null +++ b/core-java-modules/core-java-methods/README.md @@ -0,0 +1,6 @@ +========= + +## Core Java Methods + +### Relevant Articles: +- [Execute a Method Only Once in Java](https://www.baeldung.com/execute-a-method-only-once-in-java) \ No newline at end of file diff --git a/core-java-modules/core-java-methods/pom.xml b/core-java-modules/core-java-methods/pom.xml new file mode 100644 index 0000000000..5502cc6733 --- /dev/null +++ b/core-java-modules/core-java-methods/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + core-java-methods + 0.1.0-SNAPSHOT + core-java-methods + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + core-java-methods + + + src/main/resources + true + + + + + + 3.22.0 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-methods/src/main/java/com/baeldung/executeonce/AtomicBooleanInitializer.java b/core-java-modules/core-java-methods/src/main/java/com/baeldung/executeonce/AtomicBooleanInitializer.java new file mode 100644 index 0000000000..72ffc42711 --- /dev/null +++ b/core-java-modules/core-java-methods/src/main/java/com/baeldung/executeonce/AtomicBooleanInitializer.java @@ -0,0 +1,19 @@ +package com.baeldung.executeonce; + +import java.util.concurrent.atomic.AtomicBoolean; + +final class AtomicBooleanInitializer { + + private final AtomicBoolean isInitialized = new AtomicBoolean(false); + int callCount = 0; + + void initialize() { + if (isInitialized.compareAndSet(false, true)) { + initializationLogic(); + } + } + + private void initializationLogic() { + callCount++; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-methods/src/main/java/com/baeldung/executeonce/StaticInitializer.java b/core-java-modules/core-java-methods/src/main/java/com/baeldung/executeonce/StaticInitializer.java new file mode 100644 index 0000000000..2896578a8c --- /dev/null +++ b/core-java-modules/core-java-methods/src/main/java/com/baeldung/executeonce/StaticInitializer.java @@ -0,0 +1,14 @@ +package com.baeldung.executeonce; + +final class StaticInitializer { + + static int CALL_COUNT = 0; + + static { + initializationLogic(); + } + + private static void initializationLogic() { + CALL_COUNT++; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-methods/src/main/java/com/baeldung/executeonce/SynchronizedInitializer.java b/core-java-modules/core-java-methods/src/main/java/com/baeldung/executeonce/SynchronizedInitializer.java new file mode 100644 index 0000000000..79c5fb9c3c --- /dev/null +++ b/core-java-modules/core-java-methods/src/main/java/com/baeldung/executeonce/SynchronizedInitializer.java @@ -0,0 +1,18 @@ +package com.baeldung.executeonce; + +final class SynchronizedInitializer { + + private static volatile boolean isInitialized = false; + int callCount = 0; + + synchronized void initialize() { + if (!isInitialized) { + initializationLogic(); + isInitialized = true; + } + } + + private void initializationLogic() { + callCount++; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-methods/src/test/java/com/baeldung/executeonce/AtomicBooleanInitializerUnitTest.java b/core-java-modules/core-java-methods/src/test/java/com/baeldung/executeonce/AtomicBooleanInitializerUnitTest.java new file mode 100644 index 0000000000..8d72ded2cb --- /dev/null +++ b/core-java-modules/core-java-methods/src/test/java/com/baeldung/executeonce/AtomicBooleanInitializerUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.executeonce; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +final class AtomicBooleanInitializerUnitTest { + + @Test + void givenAtomicBooleanInitializer_whenRepeatedlyCallingInitialize_thenCallCountIsOne() { + AtomicBooleanInitializer atomicBooleanInitializer = new AtomicBooleanInitializer(); + assertEquals(0, atomicBooleanInitializer.callCount); + + atomicBooleanInitializer.initialize(); + atomicBooleanInitializer.initialize(); + atomicBooleanInitializer.initialize(); + + assertEquals(1, atomicBooleanInitializer.callCount); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-methods/src/test/java/com/baeldung/executeonce/StaticInitializerUnitTest.java b/core-java-modules/core-java-methods/src/test/java/com/baeldung/executeonce/StaticInitializerUnitTest.java new file mode 100644 index 0000000000..a1620069ee --- /dev/null +++ b/core-java-modules/core-java-methods/src/test/java/com/baeldung/executeonce/StaticInitializerUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.executeonce; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +final class StaticInitializerUnitTest { + + @Test + void whenLoadingStaticInitializer_thenCallCountIsOne() { + assertEquals(1, StaticInitializer.CALL_COUNT); + } + + @Test + void whenInitializingStaticInitializer_thenCallCountStaysOne() { + StaticInitializer staticInitializer = new StaticInitializer(); + assertEquals(1, StaticInitializer.CALL_COUNT); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-methods/src/test/java/com/baeldung/executeonce/SynchronizedInitializerUnitTest.java b/core-java-modules/core-java-methods/src/test/java/com/baeldung/executeonce/SynchronizedInitializerUnitTest.java new file mode 100644 index 0000000000..50eca7c5b7 --- /dev/null +++ b/core-java-modules/core-java-methods/src/test/java/com/baeldung/executeonce/SynchronizedInitializerUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.executeonce; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +final class SynchronizedInitializerUnitTest { + + @Test + void givenSynchronizedInitializer_whenRepeatedlyCallingInitialize_thenCallCountIsOne() { + SynchronizedInitializer synchronizedInitializer = new SynchronizedInitializer(); + assertEquals(0, synchronizedInitializer.callCount); + + synchronizedInitializer.initialize(); + synchronizedInitializer.initialize(); + synchronizedInitializer.initialize(); + + assertEquals(1, synchronizedInitializer.callCount); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-networking-2/pom.xml b/core-java-modules/core-java-networking-2/pom.xml index 982f4fa346..34f16a9938 100644 --- a/core-java-modules/core-java-networking-2/pom.xml +++ b/core-java-modules/core-java-networking-2/pom.xml @@ -15,9 +15,9 @@ - org.apache.httpcomponents - httpclient - ${httpclient.version} + commons-codec + commons-codec + ${commons-codec.version} org.apache.commons @@ -52,11 +52,11 @@ - 4.5.9 2.0.1 2.4.5 2.3.3 2.0.0-alpha-3 + 1.15 \ No newline at end of file diff --git a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/url/auth/HttpClient.java b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/url/auth/HttpClient.java index 779f8aa898..f9d747a133 100644 --- a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/url/auth/HttpClient.java +++ b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/url/auth/HttpClient.java @@ -21,7 +21,7 @@ public class HttpClient { this.password = password; } - public int sendRquestWithAuthHeader(String url) throws IOException { + public int sendRequestWithAuthHeader(String url) throws IOException { HttpURLConnection connection = null; try { connection = createConnection(url); @@ -34,7 +34,7 @@ public class HttpClient { } } - public int sendRquestWithAuthenticator(String url) throws IOException { + public int sendRequestWithAuthenticator(String url) throws IOException { setAuthenticator(); HttpURLConnection connection = null; diff --git a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/url/auth/HttpClientLiveTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/url/auth/HttpClientLiveTest.java index 01d580bc65..387b228953 100644 --- a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/url/auth/HttpClientLiveTest.java +++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/url/auth/HttpClientLiveTest.java @@ -7,28 +7,28 @@ import org.junit.Test; public class HttpClientLiveTest { @Test - public void sendRquestWithAuthHeader() throws Exception { + public void sendRequestWithAuthHeader() throws Exception { HttpClient httpClient = new HttpClient("user1", "pass1"); - int status = httpClient.sendRquestWithAuthHeader("https://httpbin.org/basic-auth/user1/pass1"); + int status = httpClient.sendRequestWithAuthHeader("https://httpbin.org/basic-auth/user1/pass1"); assertTrue(isSuccess(status)); } @Test - public void sendRquestWithAuthHeader_whenIncorrectCredentials_thenNotSuccessful() throws Exception { + public void sendRequestWithAuthHeader_whenIncorrectCredentials_thenNotSuccessful() throws Exception { HttpClient httpClient = new HttpClient("John", "Smith"); - int status = httpClient.sendRquestWithAuthHeader("https://httpbin.org/basic-auth/user1/pass1"); + int status = httpClient.sendRequestWithAuthHeader("https://httpbin.org/basic-auth/user1/pass1"); assertTrue(isUnauthorized(status)); } @Test - public void sendRquestWithAuthenticator() throws Exception { + public void sendRequestWithAuthenticator() throws Exception { HttpClient httpClient = new HttpClient("user2", "pass2"); - int status = httpClient.sendRquestWithAuthenticator("https://httpbin.org/basic-auth/user2/pass2"); + int status = httpClient.sendRequestWithAuthenticator("https://httpbin.org/basic-auth/user2/pass2"); assertTrue(isSuccess(status)); } @@ -37,7 +37,7 @@ public class HttpClientLiveTest { public void sendRquestWithAuthenticator_whenIncorrectCredentials_thenNotSuccessful() throws Exception { HttpClient httpClient = new HttpClient("John", "Smith"); - int status = httpClient.sendRquestWithAuthenticator("https://httpbin.org/basic-auth/user2/pass2"); + int status = httpClient.sendRequestWithAuthenticator("https://httpbin.org/basic-auth/user2/pass2"); assertTrue(isUnauthorized(status)); } diff --git a/core-java-modules/core-java-networking-4/README.md b/core-java-modules/core-java-networking-4/README.md index e614801468..10ca7caf41 100644 --- a/core-java-modules/core-java-networking-4/README.md +++ b/core-java-modules/core-java-networking-4/README.md @@ -3,3 +3,4 @@ - [Validating URL in Java](https://www.baeldung.com/java-validate-url) - [Validating IPv4 Address in Java](https://www.baeldung.com/java-validate-ipv4-address) - [Download a Webpage in Java](https://www.baeldung.com/java-download-webpage) +- [URL Query Manipulation in Java](https://www.baeldung.com/java-url-query-manipulation) diff --git a/core-java-modules/core-java-networking-4/pom.xml b/core-java-modules/core-java-networking-4/pom.xml index a3694cfea8..cbe6356d0f 100644 --- a/core-java-modules/core-java-networking-4/pom.xml +++ b/core-java-modules/core-java-networking-4/pom.xml @@ -14,7 +14,6 @@ - commons-validator commons-validator @@ -25,7 +24,30 @@ jsoup ${jsoup.version} - + + + org.apache.httpcomponents + httpclient + 4.5.2 + + + + javax.ws.rs + javax.ws.rs-api + 2.1.1 + + + org.glassfish.jersey.core + jersey-common + 2.22.2 + test + + + + org.springframework + spring-web + 6.0.6 + diff --git a/core-java-modules/core-java-networking-4/src/test/java/com/baeldung/urlquerymanipulation/UrlQueryManipulationUnitTest.java b/core-java-modules/core-java-networking-4/src/test/java/com/baeldung/urlquerymanipulation/UrlQueryManipulationUnitTest.java new file mode 100644 index 0000000000..cc53a3e3a8 --- /dev/null +++ b/core-java-modules/core-java-networking-4/src/test/java/com/baeldung/urlquerymanipulation/UrlQueryManipulationUnitTest.java @@ -0,0 +1,53 @@ +package com.baeldung.urlquerymanipulation; + +import static junit.framework.TestCase.assertEquals; + +import java.net.URI; +import java.net.URISyntaxException; + +import javax.ws.rs.core.UriBuilder; + +import org.apache.http.client.utils.URIBuilder; + +import org.junit.Test; +import org.springframework.web.util.UriComponentsBuilder; + +public class UrlQueryManipulationUnitTest { + + @Test + public void whenUsingApacheUriBuilder_thenParametersAreCorrectlyAdded() throws URISyntaxException { + String url = "baeldung.com"; + String key = "article"; + String value = "alpha"; + URI uri = new URIBuilder(url).addParameter(key, value) + .build(); + + assertEquals("baeldung.com?article=alpha", uri.toString()); + } + + @Test + public void whenUsingJavaUriBuilder_thenParametersAreCorrectlyAdded() { + String url = "baeldung.com"; + String key = "article"; + String value = "beta"; + URI uri = UriBuilder.fromUri(url) + .queryParam(key, value) + .build(); + + assertEquals("baeldung.com?article=beta", uri.toString()); + } + + @Test + public void whenUsingSpringUriComponentsBuilder_thenParametersAreCorrectlyAdded() { + String url = "baeldung.com"; + String key = "article"; + String value = "charlie"; + URI uri = UriComponentsBuilder.fromUriString(url) + .queryParam(key, value) + .build() + .toUri(); + + assertEquals("baeldung.com?article=charlie", uri.toString()); + } + +} diff --git a/core-java-modules/core-java-networking/pom.xml b/core-java-modules/core-java-networking/pom.xml index 9974134eae..59aadbd1ed 100644 --- a/core-java-modules/core-java-networking/pom.xml +++ b/core-java-modules/core-java-networking/pom.xml @@ -1,10 +1,9 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-networking - 0.1.0-SNAPSHOT core-java-networking jar @@ -20,6 +19,11 @@ spring-web ${springframework.spring-web.version} + + org.apache.httpcomponents + httpclient + ${apache.httpclient.version} + @@ -28,6 +32,7 @@ 4.3.4.RELEASE + 4.5.14 \ No newline at end of file diff --git a/core-java-modules/core-java-networking/src/test/java/com/baeldung/networking/url/UrlUnitTest.java b/core-java-modules/core-java-networking/src/test/java/com/baeldung/networking/url/UrlUnitTest.java index 112f2cf53f..87d9d7a620 100644 --- a/core-java-modules/core-java-networking/src/test/java/com/baeldung/networking/url/UrlUnitTest.java +++ b/core-java-modules/core-java-networking/src/test/java/com/baeldung/networking/url/UrlUnitTest.java @@ -1,11 +1,19 @@ package com.baeldung.networking.url; +import static java.util.stream.Collectors.toList; import static org.junit.Assert.assertEquals; import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; +import java.util.Map; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.message.BasicNameValuePair; import org.junit.Test; +import org.springframework.web.util.UriComponentsBuilder; + +import com.google.common.collect.ImmutableMap; public class UrlUnitTest { @@ -101,4 +109,44 @@ public class UrlUnitTest { assertEquals("http://baeldung.com:9000/guidelines.txt", url.toString()); } -} + @Test + public void givenUrlParameters_whenBuildUrlWithURIBuilder_thenSuccess() throws URISyntaxException, MalformedURLException { + URIBuilder uriBuilder = new URIBuilder("http://baeldung.com/articles"); + uriBuilder.setPort(9090); + uriBuilder.addParameter("topic", "java"); + uriBuilder.addParameter("version", "8"); + URL url = uriBuilder.build().toURL(); + assertEquals("http://baeldung.com:9090/articles?topic=java&version=8", url.toString()); + } + + @Test + public void givenUrlParametersInMap_whenBuildUrlWithURIBuilder_thenSuccess() throws URISyntaxException, MalformedURLException { + Map paramMap = ImmutableMap.of("topic", "java", "version", "8"); + URIBuilder uriBuilder = new URIBuilder("http://baeldung.com/articles"); + uriBuilder.setPort(9090); + uriBuilder.addParameters(paramMap.entrySet() + .stream() + .map(entry -> new BasicNameValuePair(entry.getKey(), entry.getValue())) + .collect(toList())); + + URL url = uriBuilder.build().toURL(); + assertEquals("http://baeldung.com:9090/articles?topic=java&version=8", url.toString()); + } + + @Test + public void givenUrlParameters_whenBuildUrlWithSpringUriComponentsBuilder_thenSuccess() throws MalformedURLException { + URL url = UriComponentsBuilder.newInstance() + .scheme("http") + .host("baeldung.com") + .port(9090) + .path("articles") + .queryParam("topic", "java") + .queryParam("version", "8") + .build() + .toUri() + .toURL(); + + assertEquals("http://baeldung.com:9090/articles?topic=java&version=8", url.toString()); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-nio-2/README.md b/core-java-modules/core-java-nio-2/README.md index 308356cf8b..527600779a 100644 --- a/core-java-modules/core-java-nio-2/README.md +++ b/core-java-modules/core-java-nio-2/README.md @@ -14,5 +14,4 @@ This module contains articles about core Java non-blocking input and output (IO) - [What Is the Difference Between NIO and NIO.2?](https://www.baeldung.com/java-nio-vs-nio-2) - [Guide to ByteBuffer](https://www.baeldung.com/java-bytebuffer) - [Find Files that Match Wildcard Strings in Java](https://www.baeldung.com/java-files-match-wildcard-strings) -- [Get the Desktop Path in Java](https://www.baeldung.com/java-desktop-path) - [[<-- Prev]](/core-java-modules/core-java-nio) diff --git a/core-java-modules/core-java-nio-2/pom.xml b/core-java-modules/core-java-nio-2/pom.xml index eb56c2bf68..e35b70cfc7 100644 --- a/core-java-modules/core-java-nio-2/pom.xml +++ b/core-java-modules/core-java-nio-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-nio-2 - 0.1.0-SNAPSHOT core-java-nio-2 jar diff --git a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/selector/EchoServer.java b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/selector/EchoServer.java index 9e9edcd0ba..c8b638dc04 100644 --- a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/selector/EchoServer.java +++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/selector/EchoServer.java @@ -45,8 +45,9 @@ public class EchoServer { private static void answerWithEcho(ByteBuffer buffer, SelectionKey key) throws IOException { SocketChannel client = (SocketChannel) key.channel(); - client.read(buffer); - if (new String(buffer.array()).trim().equals(POISON_PILL)) { + int r = client.read(buffer); + if (r == -1 || new String(buffer.array()).trim() + .equals(POISON_PILL)) { client.close(); System.out.println("Not accepting client messages anymore"); } else { diff --git a/core-java-modules/core-java-nio/pom.xml b/core-java-modules/core-java-nio/pom.xml index 9e1c529a65..35fef82df5 100644 --- a/core-java-modules/core-java-nio/pom.xml +++ b/core-java-modules/core-java-nio/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-nio - 0.1.0-SNAPSHOT core-java-nio jar diff --git a/core-java-modules/core-java-nio/src/main/java/com/baeldung/lines/NumberOfLineFinder.java b/core-java-modules/core-java-nio/src/main/java/com/baeldung/lines/NumberOfLineFinder.java index b355295dab..f5d5fb2b4f 100644 --- a/core-java-modules/core-java-nio/src/main/java/com/baeldung/lines/NumberOfLineFinder.java +++ b/core-java-modules/core-java-nio/src/main/java/com/baeldung/lines/NumberOfLineFinder.java @@ -37,7 +37,7 @@ public class NumberOfLineFinder { int lines = 0; try (LineNumberReader reader = new LineNumberReader(new FileReader(fileName))) { reader.skip(Integer.MAX_VALUE); - lines = reader.getLineNumber() + 1; + lines = reader.getLineNumber(); } catch (IOException ioe) { ioe.printStackTrace(); } diff --git a/core-java-modules/core-java-nio/src/test/java/com/baeldung/creationdate/CreationDateResolverUnitTest.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/creationdate/CreationDateResolverUnitTest.java index 5402852c74..5e7929859d 100644 --- a/core-java-modules/core-java-nio/src/test/java/com/baeldung/creationdate/CreationDateResolverUnitTest.java +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/creationdate/CreationDateResolverUnitTest.java @@ -21,9 +21,11 @@ public class CreationDateResolverUnitTest { final Instant response = creationDateResolver.resolveCreationTimeWithBasicAttributes(path); - assertTrue(Instant - .now() - .isAfter(response)); + Optional.of(response).ifPresent((value) -> { + assertTrue(Instant + .now() + .isAfter(value)); + }); } diff --git a/core-java-modules/core-java-numbers-2/pom.xml b/core-java-modules/core-java-numbers-2/pom.xml index ac3843607e..46e0fa47b4 100644 --- a/core-java-modules/core-java-numbers-2/pom.xml +++ b/core-java-modules/core-java-numbers-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-numbers-2 - 0.1.0-SNAPSHOT core-java-numbers-2 jar diff --git a/core-java-modules/core-java-numbers-3/src/test/java/com/baeldung/formatNumber/FormatNumberUnitTest.java b/core-java-modules/core-java-numbers-3/src/test/java/com/baeldung/formatNumber/FormatNumberUnitTest.java index 4f0358c6a2..6d78426a56 100644 --- a/core-java-modules/core-java-numbers-3/src/test/java/com/baeldung/formatNumber/FormatNumberUnitTest.java +++ b/core-java-modules/core-java-numbers-3/src/test/java/com/baeldung/formatNumber/FormatNumberUnitTest.java @@ -75,8 +75,8 @@ public class FormatNumberUnitTest { public void givenCurrency_whenFormatNumberCurrencyWithChosenLocalisation_thenGetExpectedResult() { double value = 23_500; assertThat(currencyWithChosenLocalisation(value, new Locale("en", "US"))).isEqualTo("$23,500.00"); - assertThat(currencyWithChosenLocalisation(value, new Locale("zh", "CN"))).isEqualTo("¥23,500.00"); - assertThat(currencyWithChosenLocalisation(value, new Locale("pl", "PL"))).isEqualTo("23 500 zł"); + assertThat(currencyWithChosenLocalisation(value, new Locale("zh", "CN"))).isEqualTo("¥23,500.00"); + assertThat(currencyWithChosenLocalisation(value, new Locale("pl", "PL"))).isEqualTo("23 500,00 zł"); } } diff --git a/core-java-modules/core-java-numbers-6/README.md b/core-java-modules/core-java-numbers-6/README.md new file mode 100644 index 0000000000..97e4e2ca28 --- /dev/null +++ b/core-java-modules/core-java-numbers-6/README.md @@ -0,0 +1,4 @@ +### Relevant Articles: +- [Java Program to Calculate Pi](https://www.baeldung.com/java-monte-carlo-compute-pi) +- [Convert Integer to Hexadecimal in Java](https://www.baeldung.com/java-convert-int-to-hex) +- More articles: [[<-- prev]](../core-java-numbers-5) diff --git a/core-java-modules/core-java-numbers-6/pom.xml b/core-java-modules/core-java-numbers-6/pom.xml new file mode 100644 index 0000000000..531f1293d1 --- /dev/null +++ b/core-java-modules/core-java-numbers-6/pom.xml @@ -0,0 +1,43 @@ + + 4.0.0 + core-java-numbers-6 + core-java-numbers-6 + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + test + + + commons-codec + commons-codec + ${commons-codec} + test + + + + + core-java-numbers-6 + + + src/main/resources + true + + + + + + 1.15 + + \ No newline at end of file diff --git a/core-java-modules/core-java-numbers-6/src/main/java/com/baeldung/integertohex/IntegerToHex.java b/core-java-modules/core-java-numbers-6/src/main/java/com/baeldung/integertohex/IntegerToHex.java new file mode 100644 index 0000000000..9f75b9a145 --- /dev/null +++ b/core-java-modules/core-java-numbers-6/src/main/java/com/baeldung/integertohex/IntegerToHex.java @@ -0,0 +1,16 @@ +package com.baeldung.integertohex; + +class IntegerToHex { + static final String digits = "0123456789ABCDEF"; + static String integerToHex(int input) { + if (input <= 0) + return "0"; + StringBuilder hex = new StringBuilder(); + while (input > 0) { + int digit = input % 16; + hex.insert(0, digits.charAt(digit)); + input = input / 16; + } + return hex.toString(); + } +} diff --git a/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/integertohex/IntegerToHexUnitTest.java b/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/integertohex/IntegerToHexUnitTest.java new file mode 100644 index 0000000000..6073c2d347 --- /dev/null +++ b/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/integertohex/IntegerToHexUnitTest.java @@ -0,0 +1,75 @@ +package com.baeldung.integertohex; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.apache.commons.codec.binary.Hex; +import org.junit.jupiter.api.Test; + +class IntegerToHexUnitTest { + + @Test + void givenIntegerValue_whenUseRawMethod_thenWillGetHexValue() { + String result = IntegerToHex.integerToHex(1055); + assertEquals("41F", result); + } + + @Test + void givenIntegerNegativeValue_whenUseRawMethod_thenZeroValue() { + String result = IntegerToHex.integerToHex(-1055); + assertEquals("0", result); + } + + @Test + void givenIntegerPositiveValue_whenUseStringFormat_thenWillGetHexValue() { + String result = String.format("%02x", 255); + assertEquals("ff", result); + } + + @Test + void givenIntegerPositiveValue_whenUseStringFormat_thenWillGetHexValueWithLeftZeros() { + String result = String.format("%04x", 255); + assertEquals("00ff", result); + } + + @Test + void givenIntegerPositiveValue_whenUseStringFormat_thenWillGetHexValueWithLeftZerosAndUpperLetter() { + String result = String.format("%04X", 255); + assertEquals("00FF", result); + } + + @Test + void givenIntegerValue_whenUseIntegerToHexString_thenWillGetHexValue() { + String result = Integer.toHexString(1000); + assertEquals("3e8", result); + } + + @Test + void givenIntegerValue_whenUseLongToHexString_thenWillGetHexValue() { + String result = Long.toHexString(255L); + assertEquals("ff", result); + } + + @Test + public void givenNegativeIntegerValue_whenUseIntegerToString_thenWillGetHexValue() { + String result = Integer.toString(-1458, 16); + assertEquals("-5b2", result); + } + + @Test + public void givenIntegerValue_whenUseIntegerToString_thenWillGetHexValue() { + String result = Integer.toString(1458, 16); + assertEquals("5b2", result); + } + + @Test + public void givenLongValue_whenUseLongToString_thenWillGetHexValue() { + String result = Long.toString(158, 16); + assertEquals("9e", result); + } + + @Test + public void givenIntegerValue_whenUseApacheCommons_thenWillGetHexSignedValue() { + String result = Hex.encodeHexString(new byte[] { (byte) 254 }); + assertEquals("fe", result); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/pi/PiProgramUnitTest.java b/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/pi/PiProgramUnitTest.java new file mode 100644 index 0000000000..d47942a517 --- /dev/null +++ b/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/pi/PiProgramUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.pi; + +import static org.junit.Assert.*; + +import java.util.Random; +import org.junit.Test; + +public class PiProgramUnitTest { + + @Test + public void givenPiCalculator_whenCalculatePiWithOneMillionPoints_thenEstimatedPiIsWithinTolerance() { + int totalPoints = 1000000; + int insideCircle = 0; + + Random random = new Random(); + + for (long i = 0; i < totalPoints; i++) { + double x = random.nextDouble() * 2 - 1; + double y = random.nextDouble() * 2 - 1; + + if (x * x + y * y <= 1) { + insideCircle++; + } + + } + double pi = 4.0 * insideCircle / totalPoints; + + assertEquals(Math.PI, pi, 0.01); + } + +} diff --git a/core-java-modules/core-java-numbers-conversions/README.md b/core-java-modules/core-java-numbers-conversions/README.md index e320af31b4..21810834bd 100644 --- a/core-java-modules/core-java-numbers-conversions/README.md +++ b/core-java-modules/core-java-numbers-conversions/README.md @@ -1 +1,2 @@ -### Relevant Articles: \ No newline at end of file +### Relevant Articles: +- [Convert a Number to a Letter in Java](https://www.baeldung.com/java-convert-number-to-letter) diff --git a/core-java-modules/core-java-numbers/pom.xml b/core-java-modules/core-java-numbers/pom.xml index 4b2cae8ee9..38def238e8 100644 --- a/core-java-modules/core-java-numbers/pom.xml +++ b/core-java-modules/core-java-numbers/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-numbers - 0.1.0-SNAPSHOT core-java-numbers jar diff --git a/core-java-modules/core-java-optional/pom.xml b/core-java-modules/core-java-optional/pom.xml index 08441f6cee..eeefed867e 100644 --- a/core-java-modules/core-java-optional/pom.xml +++ b/core-java-modules/core-java-optional/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-optional - 0.1.0-SNAPSHOT core-java-optional jar diff --git a/core-java-modules/core-java-os/pom.xml b/core-java-modules/core-java-os/pom.xml index ef29e435a5..d4ee34b8b7 100644 --- a/core-java-modules/core-java-os/pom.xml +++ b/core-java-modules/core-java-os/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-os - 0.1.0-SNAPSHOT core-java-os jar diff --git a/core-java-modules/core-java-perf-2/README.md b/core-java-modules/core-java-perf-2/README.md new file mode 100644 index 0000000000..8911c687a0 --- /dev/null +++ b/core-java-modules/core-java-perf-2/README.md @@ -0,0 +1,8 @@ +## Core Java Performance + +This module contains articles about performance of Java applications + +### Relevant Articles: +- [Possible Root Causes for High CPU Usage in Java](https://www.baeldung.com/java-high-cpu-usage-causes) +- [External Debugging With JMXTerm](https://www.baeldung.com/java-jmxterm-external-debugging) +- [Create and Detect Memory Leaks in Java](https://www.baeldung.com/java-create-detect-memory-leaks) diff --git a/core-java-modules/core-java-perf-2/pom.xml b/core-java-modules/core-java-perf-2/pom.xml new file mode 100644 index 0000000000..a44f6aa8c1 --- /dev/null +++ b/core-java-modules/core-java-perf-2/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + core-java-perf-2 + core-java-perf-2 + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + net.datafaker + datafaker + 1.6.0 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/highcpu/Application.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/highcpu/Application.java new file mode 100644 index 0000000000..82162406b3 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/highcpu/Application.java @@ -0,0 +1,20 @@ +package com.baeldung.highcpu; + +import java.util.LinkedList; +import java.util.List; +import java.util.function.IntUnaryOperator; +import java.util.stream.IntStream; + +public class Application { + + static List generateList() { + return IntStream.range(0, 10000000).parallel().map(IntUnaryOperator.identity()).collect(LinkedList::new, List::add, List::addAll); + } + + public static void main(String[] args) { + List list = generateList(); + long start = System.nanoTime(); + int value = list.get(9500000); + System.out.printf("Found value %d in %d nanos\n", value, (System.nanoTime() - start)); + } +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/AbstractPlayerMBean.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/AbstractPlayerMBean.java new file mode 100644 index 0000000000..698d107c51 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/AbstractPlayerMBean.java @@ -0,0 +1,16 @@ +package com.baeldung.jmxterm; + +import java.util.UUID; + +public abstract class AbstractPlayerMBean implements PlayerMBean{ + + private final UUID id; + + protected AbstractPlayerMBean() { + this.id = UUID.randomUUID(); + } + + String getId() { + return getName() + id.toString(); + } +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/BroadcastingGuessGame.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/BroadcastingGuessGame.java new file mode 100644 index 0000000000..921d87c4d7 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/BroadcastingGuessGame.java @@ -0,0 +1,42 @@ +package com.baeldung.jmxterm; + +import javax.management.ListenerNotFoundException; +import javax.management.MBeanNotificationInfo; +import javax.management.Notification; +import javax.management.NotificationBroadcaster; +import javax.management.NotificationBroadcasterSupport; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; + +public abstract class BroadcastingGuessGame implements NotificationBroadcaster, GuessGameMBean { + private final NotificationBroadcasterSupport broadcaster = + new NotificationBroadcasterSupport(); + + private long notificationSequence = 0; + + private final MBeanNotificationInfo[] notificationInfo; + + protected BroadcastingGuessGame() { + this.notificationInfo = new MBeanNotificationInfo[]{ + new MBeanNotificationInfo(new String[]{"game"}, Notification.class.getName(), "Game notification") + }; + } + + protected void notifyAboutWinner(Player winner) { + String message = "Winner is " + winner.getName() + " with score " + winner.getScore(); + Notification notification = new Notification("game.winner", this, notificationSequence++, message); + broadcaster.sendNotification(notification); + } + + public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) { + broadcaster.addNotificationListener(listener, filter, handback); + } + + public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException { + broadcaster.removeNotificationListener(listener); + } + + public MBeanNotificationInfo[] getNotificationInfo() { + return notificationInfo; + } +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/GameRunner.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/GameRunner.java new file mode 100644 index 0000000000..3955d37504 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/GameRunner.java @@ -0,0 +1,19 @@ +package com.baeldung.jmxterm; + +import java.util.Arrays; +import java.util.List; + +public class GameRunner { + + public static void main(String[] args) { + MBeanGameServer mBeanGameServer = new MBeanGameServer(); + Player bob = new Player("Bob"); + Player alice = new Player("Alice"); + Player john = new Player("John"); + List players = Arrays.asList(bob, alice, john); + GuessGame guessGame = new GuessGame(players); + mBeanGameServer.registerGame(guessGame); + guessGame.start(); + } + +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/GuessGame.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/GuessGame.java new file mode 100644 index 0000000000..c9d680880f --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/GuessGame.java @@ -0,0 +1,80 @@ +package com.baeldung.jmxterm; + +import static com.baeldung.jmxterm.RandomNumbergenerator.generateRandomNumber; + +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class GuessGame extends BroadcastingGuessGame { + + + public static final int SECOND = 1000; + private static final Logger log = Logger.getLogger(GuessGame.class.getCanonicalName()); + private final List players; + private volatile boolean isFinished = false; + private volatile boolean isPaused = false; + + + public GuessGame(List players) { + this.players = players; + log.setLevel(Level.WARNING); + } + + public void start() { + int randomNumber = generateRandomNumber(); + while (!isFinished) { + waitASecond(); + while (!isPaused && !isFinished) { + log.info("Current random number is " + randomNumber); + waitASecond(); + for (Player player : players) { + int guess = player.guessNumber(); + if (guess == randomNumber) { + log.info("Players " + player.getName() + " " + guess + " is correct"); + player.incrementScore(); + notifyAboutWinner(player); + randomNumber = generateRandomNumber(); + break; + } + log.info("Player " + player.getName() + " guessed incorrectly with " + guess); + } + log.info("\n"); + } + if (isPaused) { + log.info("Game is paused"); + } + if (isFinished) { + log.info("Game is finished"); + } + } + } + + @Override + public void finishGame() { + isFinished = true; + } + + @Override + public void pauseGame() { + isPaused = true; + } + + @Override + public void unpauseGame() { + isPaused = false; + } + + public List getPlayers() { + return players; + } + + private void waitASecond() { + try { + Thread.sleep(SECOND); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/GuessGameMBean.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/GuessGameMBean.java new file mode 100644 index 0000000000..fdf8149f71 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/GuessGameMBean.java @@ -0,0 +1,8 @@ +package com.baeldung.jmxterm; + +public interface GuessGameMBean { + + void finishGame(); + void pauseGame(); + void unpauseGame(); +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/MBeanGameServer.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/MBeanGameServer.java new file mode 100644 index 0000000000..922a0baf76 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/MBeanGameServer.java @@ -0,0 +1,37 @@ +package com.baeldung.jmxterm; + +import java.lang.management.ManagementFactory; +import javax.management.InstanceAlreadyExistsException; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; + +public class MBeanGameServer { + + public static final String ID_FORMAT = "com.baeldung.jmxterm:type=%s,id=%s"; + private final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); + + public void registerPlayer(AbstractPlayerMBean player) { + registerBean(player, "player", player.getId()); + } + + public void registerGame(GuessGame guessGame) { + registerBean(guessGame, "game", "singlegame"); + guessGame.getPlayers().forEach(this::registerPlayer); + } + + private void registerBean(Object bean, String type, String id) { + try { + ObjectName name = new ObjectName(String.format(ID_FORMAT, type, id)); + server.registerMBean(bean, name); + } catch (InstanceAlreadyExistsException | + MBeanRegistrationException | + NotCompliantMBeanException | + MalformedObjectNameException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/Player.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/Player.java new file mode 100644 index 0000000000..4961400f2f --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/Player.java @@ -0,0 +1,33 @@ +package com.baeldung.jmxterm; + +import static com.baeldung.jmxterm.RandomNumbergenerator.generateRandomNumber; + +public class Player extends AbstractPlayerMBean { + private final String name; + private int score = 0; + + public Player(String name) { + super(); + this.name = name; + } + + @Override + public int guessNumber() { + return generateRandomNumber(); + } + + public void incrementScore() { + score++; + } + + @Override + public int getScore() { + return score; + } + + @Override + public String getName() { + return name; + } + +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/PlayerMBean.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/PlayerMBean.java new file mode 100644 index 0000000000..78b73ff578 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/PlayerMBean.java @@ -0,0 +1,10 @@ +package com.baeldung.jmxterm; + +public interface PlayerMBean { + + int guessNumber(); + + int getScore(); + + String getName(); +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/RandomNumbergenerator.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/RandomNumbergenerator.java new file mode 100644 index 0000000000..1418f502c6 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/jmxterm/RandomNumbergenerator.java @@ -0,0 +1,18 @@ +package com.baeldung.jmxterm; + +import java.util.concurrent.ThreadLocalRandom; + +public class RandomNumbergenerator { + + private static final int MIN = 0; + private static final int MAX = 10; + + private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current(); + + private RandomNumbergenerator() { + } + public static int generateRandomNumber() { + return RANDOM.nextInt(MIN, MAX + 1); + } + +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/LapsedListenerRunner.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/LapsedListenerRunner.java new file mode 100644 index 0000000000..50da98e6c4 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/LapsedListenerRunner.java @@ -0,0 +1,35 @@ +package com.baeldung.lapsedlistener; + +import static com.baeldung.lapsedlistener.UserGenerator.generateUser; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LapsedListenerRunner { + + private static final Logger logger = LoggerFactory.getLogger(LapsedListenerRunner.class); + private static final MovieQuoteService movieQuoteService = new MovieQuoteService(); + + static { + movieQuoteService.start(); + } + +public static void main(String[] args) { + while (true) { + User user = generateUser(); + logger.debug("{} logged in", user.getName()); + user.subscribe(movieQuoteService); + userUsingService(); + logger.debug("{} logged out", user.getName()); + } +} + + private static void userUsingService() { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/MovieQuoteService.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/MovieQuoteService.java new file mode 100644 index 0000000000..95240bbbd5 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/MovieQuoteService.java @@ -0,0 +1,47 @@ +package com.baeldung.lapsedlistener; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import net.datafaker.Faker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MovieQuoteService implements Subject { + + private static final Logger logger = LoggerFactory.getLogger(MovieQuoteService.class); + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + private final List observers = new ArrayList<>(); + private final Faker faker = new Faker(); + + @Override + public void attach(Observer observer) { + logger.debug("Current number of subscribed users: {}", observers.size()); + observers.add(observer); + } + + @Override + public void detach(Observer observer) { + observers.remove(observer); + } + + @Override + public void notifyObservers() { + String quote = faker.movie().quote(); + logger.debug("New quote: {}", quote); + for (Observer observer : observers) { + logger.debug("Notifying user: {}", observer); + observer.update(quote); + } + } + + public void start() { + scheduler.scheduleAtFixedRate(this::notifyObservers, 0, 1, TimeUnit.SECONDS); + } + + public int numberOfSubscribers() { + return observers.size(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/Observer.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/Observer.java new file mode 100644 index 0000000000..2c4ccf9e06 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/Observer.java @@ -0,0 +1,9 @@ +package com.baeldung.lapsedlistener; + +public interface Observer { + void update(String latestNews); + + void subscribe(Subject subject); + + void unsubscribe(Subject subject); +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/Subject.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/Subject.java new file mode 100644 index 0000000000..141a7662a7 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/Subject.java @@ -0,0 +1,9 @@ +package com.baeldung.lapsedlistener; + +public interface Subject { + void attach(Observer observer); + + void detach(Observer observer); + + void notifyObservers(); +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/User.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/User.java new file mode 100644 index 0000000000..0ed0a32a01 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/User.java @@ -0,0 +1,70 @@ +package com.baeldung.lapsedlistener; + +public class User implements Observer { + + private final String name; + private final String email; + private final String phone; + private final String street; + private final String city; + private final String state; + private final String zipCode; + + public User(String name, String email, String phone, String street, String city, String state, String zipCode) { + this.name = name; + this.email = email; + this.phone = phone; + this.street = street; + this.city = city; + this.state = state; + this.zipCode = zipCode; + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } + + public String getPhone() { + return phone; + } + + public String getStreet() { + return street; + } + + public String getCity() { + return city; + } + + public String getState() { + return state; + } + + public String getZipCode() { + return zipCode; + } + + @Override + public void update(final String quote) { + // user got updated with a new quote + } + + @Override + public void subscribe(final Subject subject) { + subject.attach(this); + } + + @Override + public void unsubscribe(final Subject subject) { + subject.detach(this); + } + + @Override + public String toString() { + return "User [name=" + name + "]"; + } +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/UserGenerator.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/UserGenerator.java new file mode 100644 index 0000000000..acdb7d7af7 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/UserGenerator.java @@ -0,0 +1,23 @@ +package com.baeldung.lapsedlistener; + +import net.datafaker.Faker; + +public class UserGenerator { + + private UserGenerator() { + } + + private static final Faker faker = new Faker(); + + public static User generateUser() { + String name = faker.name().fullName(); + String email = faker.internet().emailAddress(); + String phone = faker.phoneNumber().cellPhone(); + String street = faker.address().streetAddress(); + String city = faker.address().city(); + String state = faker.address().state(); + String zipCode = faker.address().zipCode(); + return new User(name, email, phone, street, city, state, zipCode); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/jmxterm/PlayerUnitTest.java b/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/jmxterm/PlayerUnitTest.java new file mode 100644 index 0000000000..668c7195d7 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/jmxterm/PlayerUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.jmxterm; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class PlayerUnitTest { + + @Test + void givenNewPlayer_thenScoreIsZero() { + Player player = new Player("John"); + assertEquals(0, player.getScore()); + } + + @Test + void givenNewPlayer_whenIncrementScore_thenScoreIsOne() { + Player player = new Player("John"); + player.incrementScore(); + assertEquals(1, player.getScore()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/lapsedlistener/MovieQuoteServiceTest.java b/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/lapsedlistener/MovieQuoteServiceTest.java new file mode 100644 index 0000000000..90c96cba1b --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/lapsedlistener/MovieQuoteServiceTest.java @@ -0,0 +1,24 @@ +package com.baeldung.lapsedlistener; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class MovieQuoteServiceTest { + + @Test + void whenSubscribeToService_thenServiceHasOneSubscriber() { + MovieQuoteService service = new MovieQuoteService(); + service.attach(UserGenerator.generateUser()); + assertEquals(1, service.numberOfSubscribers()); + } + + @Test + void whenUnsubscribeFromService_thenServiceHasNoSubscribers() { + MovieQuoteService service = new MovieQuoteService(); + User user = UserGenerator.generateUser(); + service.attach(user); + service.detach(user); + assertEquals(0, service.numberOfSubscribers()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-perf/README.md b/core-java-modules/core-java-perf/README.md index c018ec9927..c400f1d196 100644 --- a/core-java-modules/core-java-perf/README.md +++ b/core-java-modules/core-java-perf/README.md @@ -13,3 +13,5 @@ This module contains articles about performance of Java applications - [Capturing a Java Thread Dump](https://www.baeldung.com/java-thread-dump) - [JMX Ports](https://www.baeldung.com/jmx-ports) - [Calling JMX MBean Method From a Shell Script](https://www.baeldung.com/jmx-mbean-shell-access) +- [External Debugging With JMXTerm](https://www.baeldung.com/java-jmxterm-external-debugging) +- [Create and Detect Memory Leaks in Java](https://www.baeldung.com/java-create-detect-memory-leaks) diff --git a/core-java-modules/core-java-perf/pom.xml b/core-java-modules/core-java-perf/pom.xml index f6f3ef795c..c21fc94ec1 100644 --- a/core-java-modules/core-java-perf/pom.xml +++ b/core-java-modules/core-java-perf/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-perf - 0.1.0-SNAPSHOT core-java-perf jar diff --git a/core-java-modules/core-java-properties/README.md b/core-java-modules/core-java-properties/README.md new file mode 100644 index 0000000000..73991634df --- /dev/null +++ b/core-java-modules/core-java-properties/README.md @@ -0,0 +1,6 @@ +## Core Java Properties + +### Relevant Articles: + +- [Getting Started with Java Properties](http://www.baeldung.com/java-properties) +- [Merging java.util.Properties Objects](https://www.baeldung.com/java-merging-properties) diff --git a/core-java-modules/core-java-properties/pom.xml b/core-java-modules/core-java-properties/pom.xml new file mode 100644 index 0000000000..9beacabdd5 --- /dev/null +++ b/core-java-modules/core-java-properties/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + core-java-properties + 0.1.0-SNAPSHOT + core-java-properties + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/util/PropertiesLoader.java b/core-java-modules/core-java-properties/src/main/java/com/baeldung/util/PropertiesLoader.java similarity index 100% rename from core-java-modules/core-java/src/main/java/com/baeldung/util/PropertiesLoader.java rename to core-java-modules/core-java-properties/src/main/java/com/baeldung/util/PropertiesLoader.java diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/java/properties/PropertiesUnitTest.java b/core-java-modules/core-java-properties/src/test/java/com/baeldung/java/properties/PropertiesUnitTest.java similarity index 100% rename from core-java-modules/core-java/src/test/java/com/baeldung/java/properties/PropertiesUnitTest.java rename to core-java-modules/core-java-properties/src/test/java/com/baeldung/java/properties/PropertiesUnitTest.java diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/properties/MergePropertiesUnitTest.java b/core-java-modules/core-java-properties/src/test/java/com/baeldung/properties/MergePropertiesUnitTest.java similarity index 100% rename from core-java-modules/core-java/src/test/java/com/baeldung/properties/MergePropertiesUnitTest.java rename to core-java-modules/core-java-properties/src/test/java/com/baeldung/properties/MergePropertiesUnitTest.java diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/util/PropertiesLoaderUnitTest.java b/core-java-modules/core-java-properties/src/test/java/com/baeldung/util/PropertiesLoaderUnitTest.java similarity index 100% rename from core-java-modules/core-java/src/test/java/com/baeldung/util/PropertiesLoaderUnitTest.java rename to core-java-modules/core-java-properties/src/test/java/com/baeldung/util/PropertiesLoaderUnitTest.java diff --git a/core-java-modules/core-java/src/test/resources/app.properties b/core-java-modules/core-java-properties/src/test/resources/app.properties similarity index 100% rename from core-java-modules/core-java/src/test/resources/app.properties rename to core-java-modules/core-java-properties/src/test/resources/app.properties diff --git a/core-java-modules/core-java/src/test/resources/catalog b/core-java-modules/core-java-properties/src/test/resources/catalog similarity index 100% rename from core-java-modules/core-java/src/test/resources/catalog rename to core-java-modules/core-java-properties/src/test/resources/catalog diff --git a/core-java-modules/core-java/src/test/resources/configuration.properties b/core-java-modules/core-java-properties/src/test/resources/configuration.properties similarity index 100% rename from core-java-modules/core-java/src/test/resources/configuration.properties rename to core-java-modules/core-java-properties/src/test/resources/configuration.properties diff --git a/core-java-modules/core-java/src/test/resources/default.properties b/core-java-modules/core-java-properties/src/test/resources/default.properties similarity index 100% rename from core-java-modules/core-java/src/test/resources/default.properties rename to core-java-modules/core-java-properties/src/test/resources/default.properties diff --git a/core-java-modules/core-java/src/test/resources/icons.xml b/core-java-modules/core-java-properties/src/test/resources/icons.xml similarity index 100% rename from core-java-modules/core-java/src/test/resources/icons.xml rename to core-java-modules/core-java-properties/src/test/resources/icons.xml diff --git a/core-java-modules/core-java-records/README.md b/core-java-modules/core-java-records/README.md new file mode 100644 index 0000000000..2e7ad00cd3 --- /dev/null +++ b/core-java-modules/core-java-records/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Overridding hashCode() And equals() For Records](https://www.baeldung.com/java-override-hashcode-equals-records) diff --git a/core-java-modules/core-java-records/pom.xml b/core-java-modules/core-java-records/pom.xml new file mode 100644 index 0000000000..ed9a36fc14 --- /dev/null +++ b/core-java-modules/core-java-records/pom.xml @@ -0,0 +1,32 @@ + + + + core-java-modules + com.baeldung.core-java-modules + 0.0.1-SNAPSHOT + + 4.0.0 + + core-java-records + + + + org.apache.maven.plugins + maven-compiler-plugin + + 16 + 16 + + + + + + + 19 + 19 + UTF-8 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Movie.java b/core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Movie.java new file mode 100644 index 0000000000..e94638e8b5 --- /dev/null +++ b/core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Movie.java @@ -0,0 +1,26 @@ +package com.baeldung.equalshashcoderecords; + +import java.util.Objects; + +record Movie(String name, Integer yearOfRelease, String distributor) { + +@Override +public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other == null) { + return false; + } + Movie movie = (Movie) other; + if (movie.name.equals(this.name) && movie.yearOfRelease.equals(this.yearOfRelease)) { + return true; + } + return false; +} + + @Override + public int hashCode() { + return Objects.hash(name, yearOfRelease); + } +} diff --git a/core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Person.java b/core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Person.java new file mode 100644 index 0000000000..7bfd8ae741 --- /dev/null +++ b/core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Person.java @@ -0,0 +1,5 @@ +package com.baeldung.equalshashcoderecords; + +public record Person(String firstName, String lastName, String SSN, String dateOfBirth) { +}; + diff --git a/core-java-modules/core-java-records/src/test/java/com/baeldung/equalshashcoderecords/CustomRecordEqualsHashCode.java b/core-java-modules/core-java-records/src/test/java/com/baeldung/equalshashcoderecords/CustomRecordEqualsHashCode.java new file mode 100644 index 0000000000..074886304f --- /dev/null +++ b/core-java-modules/core-java-records/src/test/java/com/baeldung/equalshashcoderecords/CustomRecordEqualsHashCode.java @@ -0,0 +1,30 @@ +package com.baeldung.equalshashcoderecords; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.Test; + +public class CustomRecordEqualsHashCode { + @Test + public void givenTwoRecords_whenDefaultEquals_thenCompareEquality() { + Person robert = new Person("Robert", "Frost", "HDHDB223", "2000-01-02"); + Person mike = new Person("Mike", "Adams", "ABJDJ2883", "2001-01-02"); + assertNotEquals(robert, mike); + } + + @Test + public void givenTwoRecords_hashCodesShouldBeSame() { + Person robert = new Person("Robert", "Frost", "HDHDB223", "2000-01-02"); + Person robertCopy = new Person("Robert", "Frost", "HDHDB223", "2000-01-02"); + assertEquals(robert.hashCode(), robertCopy.hashCode()); + } + + @Test + public void givenTwoRecords_whenCustomImplementation_thenCompareEquality() { + Movie movie1 = new Movie("The Batman", 2022, "WB"); + Movie movie2 = new Movie("The Batman", 2022, "Dreamworks"); + assertEquals(movie1, movie2); + assertEquals(movie1.hashCode(), movie2.hashCode()); + } +} diff --git a/core-java-modules/core-java-reflection-2/pom.xml b/core-java-modules/core-java-reflection-2/pom.xml index ee3eeee734..c7a4981533 100644 --- a/core-java-modules/core-java-reflection-2/pom.xml +++ b/core-java-modules/core-java-reflection-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-reflection-2 - 0.1.0-SNAPSHOT core-java-reflection-2 jar diff --git a/core-java-modules/core-java-reflection-private-constructor/pom.xml b/core-java-modules/core-java-reflection-private-constructor/pom.xml index b53aa2c61b..aee7815e23 100644 --- a/core-java-modules/core-java-reflection-private-constructor/pom.xml +++ b/core-java-modules/core-java-reflection-private-constructor/pom.xml @@ -1,10 +1,9 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-reflection-private-constructor - 0.1.0-SNAPSHOT core-java-reflection-private-constructor jar diff --git a/core-java-modules/core-java-reflection/pom.xml b/core-java-modules/core-java-reflection/pom.xml index f6ee08dbda..a836ee4a22 100644 --- a/core-java-modules/core-java-reflection/pom.xml +++ b/core-java-modules/core-java-reflection/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-reflection - 0.1.0-SNAPSHOT core-java-reflection jar diff --git a/core-java-modules/core-java-regex-2/README.md b/core-java-modules/core-java-regex-2/README.md index 453e2cc419..ccf60f56d9 100644 --- a/core-java-modules/core-java-regex-2/README.md +++ b/core-java-modules/core-java-regex-2/README.md @@ -5,4 +5,6 @@ - [Converting Camel Case and Title Case to Words in Java](https://www.baeldung.com/java-camel-case-title-case-to-words) - [How to Use Regular Expressions to Replace Tokens in Strings in Java](https://www.baeldung.com/java-regex-token-replacement) - [Creating a Java Array from Regular Expression Matches](https://www.baeldung.com/java-array-regex-matches) +- [Getting the Text That Follows After the Regex Match in Java](https://www.baeldung.com/java-regex-text-after-match) +- [Regular Expression: \z vs \Z Anchors in Java](https://www.baeldung.com/java-regular-expression-z-vs-z-anchors) - More articles: [[<-- prev]](/core-java-modules/core-java-regex) diff --git a/core-java-modules/core-java-regex-2/pom.xml b/core-java-modules/core-java-regex-2/pom.xml index ae9385e63c..ddfba35cb2 100644 --- a/core-java-modules/core-java-regex-2/pom.xml +++ b/core-java-modules/core-java-regex-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-regex-2 - 0.1.0-SNAPSHOT core-java-regex-2 jar diff --git a/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/aftermatch/GetTextAfterTheRegexMatchUnitTest.java b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/aftermatch/GetTextAfterTheRegexMatchUnitTest.java new file mode 100644 index 0000000000..04650a0c02 --- /dev/null +++ b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/aftermatch/GetTextAfterTheRegexMatchUnitTest.java @@ -0,0 +1,83 @@ +package com.baeldung.regex.aftermatch; + +import org.junit.jupiter.api.Test; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class GetTextAfterTheRegexMatchUnitTest { + private static final String INPUT1 = "Some text, targetValue=Regex is cool"; + private static final String INPUT2 = "Some text. targetValue=Java is cool. some other text"; + + @Test + void whenUsingSplit_thenGetExpectedString() { + String result1 = INPUT1.split("targetValue=")[1]; + assertEquals("Regex is cool", result1); + + String afterFirstSplit = INPUT2.split("targetValue=")[1]; + assertEquals("Java is cool. some other text", afterFirstSplit); + String result2 = afterFirstSplit.split("[.]")[0]; + assertEquals("Java is cool", result2); + + // if use the dot as the regex for splitting, the result array is empty + String[] splitByDot = INPUT2.split("targetValue=")[1].split("."); + assertEquals(0, splitByDot.length); + } + + @Test + void whenUsingReplaceAll_thenGetExpectedString() { + String result1 = INPUT1.replaceAll(".*targetValue=", ""); + assertEquals("Regex is cool", result1); + + String afterFirstReplace = INPUT2.replaceAll(".*targetValue=", ""); + assertEquals("Java is cool. some other text", afterFirstReplace); + String result2 = afterFirstReplace.replaceAll("[.].*", ""); + assertEquals("Java is cool", result2); + + } + + @Test + void whenUsingRegexGrouping_thenGetExpectedString() { + Pattern p1 = Pattern.compile("targetValue=(.*)"); + Matcher m1 = p1.matcher(INPUT1); + assertTrue(m1.find()); + String result1 = m1.group(1); + assertEquals("Regex is cool", result1); + + Pattern p2 = Pattern.compile("targetValue=([^.]*)"); + Matcher m2 = p2.matcher(INPUT2); + assertTrue(m2.find()); + String result2 = m2.group(1); + assertEquals("Java is cool", result2); + + Pattern p3 = Pattern.compile("targetValue=(.*?)[.]"); + Matcher m3 = p3.matcher(INPUT2); + assertTrue(m3.find()); + String result3 = m3.group(1); + assertEquals("Java is cool", result3); + } + + @Test + void whenUsingLookaround_thenGetExpectedString() { + Pattern p1 = Pattern.compile("(?<=targetValue=).*"); + Matcher m1 = p1.matcher(INPUT1); + assertTrue(m1.find()); + String result1 = m1.group(); + assertEquals("Regex is cool", result1); + + Pattern p2 = Pattern.compile("(?<=targetValue=)[^.]*"); + Matcher m2 = p2.matcher(INPUT2); + assertTrue(m2.find()); + String result2 = m2.group(); + assertEquals("Java is cool", result2); + + Pattern p3 = Pattern.compile("(?<=targetValue=).*(?=[.])"); + Matcher m3 = p3.matcher(INPUT2); + assertTrue(m3.find()); + String result3 = m3.group(); + assertEquals("Java is cool", result3); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/z_regexp/ZRegularExpressionUnitTest.java b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/z_regexp/ZRegularExpressionUnitTest.java new file mode 100644 index 0000000000..90bbbb6540 --- /dev/null +++ b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/z_regexp/ZRegularExpressionUnitTest.java @@ -0,0 +1,35 @@ +package com.baeldung.regex.z_regexp; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ZRegularExpressionUnitTest { + @Test + public void givenCreditCardNumber_thenReturnIfMatched() { + String creditCardNumber = "1234567890123456"; + String pattern = "\\d{16}\\z"; + Assertions.assertTrue(creditCardNumber.matches(pattern)); + } + + @Test + public void givenLogOutput_thenReturnIfMatched() { + String logLine = "2022-05-01 14:30:00,123 INFO Some log message"; + String pattern = ".*message\\z"; + Assertions.assertTrue(logLine.matches(pattern)); + } + + @Test + public void givenEmailMessage_thenReturnIfMatched() { + String myMessage = "Hello HR, I hope i can write to Baeldung\n"; + String pattern = ".*Baeldung\\s*\\Z"; + Assertions.assertTrue(myMessage.matches(pattern)); + } + + @Test + public void givenFileExtension_thenReturnIfMatched() { + String fileName = "image.jpeg"; + String pattern = ".*\\.jpeg\\Z"; + Assertions.assertTrue(fileName.matches(pattern)); + } + +} diff --git a/core-java-modules/core-java-regex/pom.xml b/core-java-modules/core-java-regex/pom.xml index 93f3ae3cdb..00b8107c57 100644 --- a/core-java-modules/core-java-regex/pom.xml +++ b/core-java-modules/core-java-regex/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-regex - 0.1.0-SNAPSHOT core-java-regex jar diff --git a/core-java-modules/core-java-security-2/pom.xml b/core-java-modules/core-java-security-2/pom.xml index 7a354ee9e2..0fc121c070 100644 --- a/core-java-modules/core-java-security-2/pom.xml +++ b/core-java-modules/core-java-security-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-security-2 - 0.1.0-SNAPSHOT core-java-security-2 jar diff --git a/core-java-modules/core-java-security-3/pom.xml b/core-java-modules/core-java-security-3/pom.xml index 3cd546e697..a4f60b4db5 100644 --- a/core-java-modules/core-java-security-3/pom.xml +++ b/core-java-modules/core-java-security-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-security-3 - 0.1.0-SNAPSHOT core-java-security-3 jar @@ -31,12 +30,18 @@ jaxb-api ${jaxb-api.version} + + org.springframework.security + spring-security-crypto + ${spring-security-crypto.version} + - 1.60 + 1.70 1.11 2.3.1 + 6.0.3 \ No newline at end of file diff --git a/core-java-modules/core-java-security-3/src/test/java/com/baeldung/hash/argon/HashPasswordUnitTest.java b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/hash/argon/HashPasswordUnitTest.java new file mode 100644 index 0000000000..6e0e326821 --- /dev/null +++ b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/hash/argon/HashPasswordUnitTest.java @@ -0,0 +1,65 @@ +package com.baeldung.hash.argon; + +import static org.junit.jupiter.api.Assertions.*; + +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; + +import org.bouncycastle.crypto.generators.Argon2BytesGenerator; +import org.bouncycastle.crypto.params.Argon2Parameters; +import org.bouncycastle.util.encoders.Hex; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.security.crypto.argon2.Argon2PasswordEncoder; + +import java.util.Arrays; +import java.util.Base64; + +public class HashPasswordUnitTest { + + @Test + public void givenRawPassword_whenEncodedWithArgon2_thenMatchesEncodedPassword() { + String rawPassword = "Baeldung"; + + Argon2PasswordEncoder arg2SpringSecurity = new Argon2PasswordEncoder(16, 32, 1, 60000, 10); + String hashPassword = arg2SpringSecurity.encode(rawPassword); + + assertTrue(arg2SpringSecurity.matches(rawPassword, hashPassword)); + } + + @Test + public void givenRawPasswordAndSalt_whenArgon2AlgorithmIsUsed_thenHashIsCorrect() { + byte[] salt = generateSalt16Byte(); + String password = "Baeldung"; + + int iterations = 2; + int memLimit = 66536; + int hashLength = 32; + int parallelism = 1; + Argon2Parameters.Builder builder = new Argon2Parameters.Builder(Argon2Parameters.ARGON2_id).withVersion(Argon2Parameters.ARGON2_VERSION_13) + .withIterations(iterations) + .withMemoryAsKB(memLimit) + .withParallelism(parallelism) + .withSalt(salt); + + Argon2BytesGenerator generate = new Argon2BytesGenerator(); + generate.init(builder.build()); + byte[] result = new byte[hashLength]; + generate.generateBytes(password.getBytes(StandardCharsets.UTF_8), result, 0, result.length); + + Argon2BytesGenerator verifier = new Argon2BytesGenerator(); + verifier.init(builder.build()); + byte[] testHash = new byte[hashLength]; + verifier.generateBytes(password.getBytes(StandardCharsets.UTF_8), testHash, 0, testHash.length); + + assertTrue(Arrays.equals(result, testHash)); + } + + private static byte[] generateSalt16Byte() { + SecureRandom secureRandom = new SecureRandom(); + byte[] salt = new byte[16]; + secureRandom.nextBytes(salt); + return salt; + } + +} diff --git a/core-java-modules/core-java/src/main/resources/META-INF/BenchmarkList b/core-java-modules/core-java-security-algorithms/classpath similarity index 100% rename from core-java-modules/core-java/src/main/resources/META-INF/BenchmarkList rename to core-java-modules/core-java-security-algorithms/classpath diff --git a/core-java-modules/core-java-security-algorithms/pom.xml b/core-java-modules/core-java-security-algorithms/pom.xml index 967ddc103e..0dde9f861a 100644 --- a/core-java-modules/core-java-security-algorithms/pom.xml +++ b/core-java-modules/core-java-security-algorithms/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-security-algorithms - 0.1.0-SNAPSHOT core-java-security-algorithms jar @@ -25,7 +24,6 @@ bcprov-jdk15on ${bouncycastle.version} - javax.xml.bind jaxb-api diff --git a/core-java-modules/core-java-security/pom.xml b/core-java-modules/core-java-security/pom.xml index b36de5ac4c..921017b080 100644 --- a/core-java-modules/core-java-security/pom.xml +++ b/core-java-modules/core-java-security/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-security - 0.1.0-SNAPSHOT core-java-security jar diff --git a/core-java-modules/core-java-serialization/pom.xml b/core-java-modules/core-java-serialization/pom.xml index c82ae9d1d6..04144fb27f 100644 --- a/core-java-modules/core-java-serialization/pom.xml +++ b/core-java-modules/core-java-serialization/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-serialization - 0.1.0-SNAPSHOT core-java-serialization jar diff --git a/core-java-modules/core-java-streams-2/pom.xml b/core-java-modules/core-java-streams-2/pom.xml index c8fa83c55a..9725497b04 100644 --- a/core-java-modules/core-java-streams-2/pom.xml +++ b/core-java-modules/core-java-streams-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-streams-2 - 1.0 core-java-streams-2 jar diff --git a/core-java-modules/core-java-streams-3/pom.xml b/core-java-modules/core-java-streams-3/pom.xml index 3074a647ff..9c657119b5 100644 --- a/core-java-modules/core-java-streams-3/pom.xml +++ b/core-java-modules/core-java-streams-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-streams-3 - 0.1.0-SNAPSHOT core-java-streams-3 jar diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/java8/Java8MapAndFlatMap.java b/core-java-modules/core-java-streams-3/src/test/java/com/baeldung/streams/flatmap/map/Java8MapAndFlatMapUnitTest.java similarity index 94% rename from core-java-modules/core-java/src/test/java/com/baeldung/java8/Java8MapAndFlatMap.java rename to core-java-modules/core-java-streams-3/src/test/java/com/baeldung/streams/flatmap/map/Java8MapAndFlatMapUnitTest.java index a0bd1cf093..1b09ea25c6 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/java8/Java8MapAndFlatMap.java +++ b/core-java-modules/core-java-streams-3/src/test/java/com/baeldung/streams/flatmap/map/Java8MapAndFlatMapUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.java8; +package com.baeldung.streams.flatmap.map; import org.junit.Test; @@ -12,7 +12,7 @@ import java.util.stream.Stream; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; -public class Java8MapAndFlatMap { +public class Java8MapAndFlatMapUnitTest { @Test public void givenStream_whenCalledMap_thenProduceList() { diff --git a/core-java-modules/core-java-streams-4/pom.xml b/core-java-modules/core-java-streams-4/pom.xml index 46c0f3f7e1..fe791ebd42 100644 --- a/core-java-modules/core-java-streams-4/pom.xml +++ b/core-java-modules/core-java-streams-4/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-streams-4 - 0.1.0-SNAPSHOT core-java-streams-4 jar diff --git a/core-java-modules/core-java-streams-5/README.md b/core-java-modules/core-java-streams-5/README.md new file mode 100644 index 0000000000..4f367799f2 --- /dev/null +++ b/core-java-modules/core-java-streams-5/README.md @@ -0,0 +1 @@ +- [Difference Between parallelStream() and stream().parallel() in Java](https://www.baeldung.com/java-parallelstream-vs-stream-parallel) diff --git a/core-java-modules/core-java-streams-5/pom.xml b/core-java-modules/core-java-streams-5/pom.xml new file mode 100644 index 0000000000..d1f8af6461 --- /dev/null +++ b/core-java-modules/core-java-streams-5/pom.xml @@ -0,0 +1,72 @@ + + + 4.0.0 + core-java-streams-5 + core-java-streams-5 + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + log4j + log4j + ${log4j.version} + + + org.junit + junit-bom + ${junit-jupiter.version} + pom + import + + + org.assertj + assertj-core + 3.23.1 + test + + + org.apache.commons + commons-lang3 + 3.12.0 + test + + + + + core-java-streams-4 + + + ../core-java-streams-4/src/main + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + -parameters + + + + + + + + 3.1 + 12 + 12 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/emptystreams/EmptyStreams.java b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/emptystreams/EmptyStreams.java new file mode 100644 index 0000000000..e561cfc8c1 --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/emptystreams/EmptyStreams.java @@ -0,0 +1,49 @@ +package com.baeldung.streams.emptystreams; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +public class EmptyStreams { + + public static void main(String[] args) { + + createEmptyStreams(); + checkForEmptyStreamUsingSupplier(); + } + + private static void createEmptyStreams() { + + // Using Stream.empty() + Stream emptyStream = Stream.empty(); + System.out.println(emptyStream.findAny().isEmpty()); + + // Using Stream.of() + emptyStream = Stream.of(); + System.out.println(emptyStream.findAny().isEmpty()); + + // Empty Stream of primitive type + IntStream emptyIntStream = IntStream.of(new int[] {}); + System.out.println(emptyIntStream.findAny().isEmpty()); + + // Using Arrays.stream() + emptyIntStream = Arrays.stream(new int[] {}); + System.out.println(emptyIntStream.findAny().isEmpty()); + + // Using list.stream() + Stream collectionStream = new ArrayList().stream(); + System.out.println(collectionStream.findAny().isEmpty()); + } + + private static void checkForEmptyStreamUsingSupplier() { + Supplier> streamSupplier = () -> Stream.of(1, 2, 3, 4, 5).filter(number -> number > 5); + + Optional result1 = streamSupplier.get().findAny(); + System.out.println(result1.isEmpty()); + Optional result2 = streamSupplier.get().findFirst(); + System.out.println(result2.isEmpty()); + } +} diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/parallelstream/Book.java b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/parallelstream/Book.java new file mode 100644 index 0000000000..d52a31aac9 --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/parallelstream/Book.java @@ -0,0 +1,37 @@ +package com.baeldung.streams.parallelstream; + +public class Book { + private String name; + private String author; + private int yearPublished; + + public Book(String name, String author, int yearPublished) { + this.name = name; + this.author = author; + this.yearPublished = yearPublished; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public int getYearPublished() { + return yearPublished; + } + + public void setYearPublished(int yearPublished) { + this.yearPublished = yearPublished; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/parallelstream/BookSpliterator.java b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/parallelstream/BookSpliterator.java new file mode 100644 index 0000000000..7460e1372b --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/parallelstream/BookSpliterator.java @@ -0,0 +1,40 @@ +package com.baeldung.streams.parallelstream; + +import java.util.Spliterator; +import java.util.function.Consumer; + +public class BookSpliterator implements Spliterator { + private final Object[] books; + private int startIndex; + public BookSpliterator(Object[] books, int startIndex) { + this.books = books; + this.startIndex = startIndex; + } + + @Override + public Spliterator trySplit() { + // Always Assuming that the source is too small to split, returning null + return null; + } + + // Other overridden methods such as tryAdvance(), estimateSize() etc + + @Override + public boolean tryAdvance(Consumer action) { + if (startIndex < books.length) { + startIndex += 2; + return true; + } + return false; + } + + @Override + public long estimateSize() { + return books.length - startIndex; + } + + @Override + public int characteristics() { + return CONCURRENT; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/parallelstream/MyBookContainer.java b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/parallelstream/MyBookContainer.java new file mode 100644 index 0000000000..d7e3adc5f1 --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/parallelstream/MyBookContainer.java @@ -0,0 +1,93 @@ +package com.baeldung.streams.parallelstream; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Spliterator; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class MyBookContainer implements Collection { + private static final long serialVersionUID = 1L; + private T[] elements; + + public MyBookContainer(T[] elements) { + this.elements = elements; + } + + @Override + public Spliterator spliterator() { + return new BookSpliterator(elements, 0); + } + + @Override + public Stream parallelStream() { + return StreamSupport.stream(spliterator(), false); + } + + // standard overridden methods of Collection Interface + + @Override + public int size() { + return elements.length; + } + + @Override + public boolean isEmpty() { + return elements.length == 0; + } + + @Override + public boolean contains(Object o) { + return false; + } + + @Override + public Iterator iterator() { + return null; + } + + @Override + public Object[] toArray() { + return new Object[0]; + } + + @Override + public T1[] toArray(T1[] a) { + return null; + } + + @Override + public boolean add(T t) { + return false; + } + + @Override + public boolean remove(Object o) { + return false; + } + + @Override + public boolean containsAll(Collection c) { + return false; + } + + @Override + public boolean addAll(Collection c) { + return false; + } + + @Override + public boolean removeAll(Collection c) { + return false; + } + + @Override + public boolean retainAll(Collection c) { + return false; + } + + @Override + public void clear() { + + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/parallelstream/ParallelStreamApplication.java b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/parallelstream/ParallelStreamApplication.java new file mode 100644 index 0000000000..4297bdd3ed --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/parallelstream/ParallelStreamApplication.java @@ -0,0 +1,41 @@ +package com.baeldung.streams.parallelstream; + +import java.util.Collection; +import java.util.concurrent.atomic.AtomicLong; + +public class ParallelStreamApplication { + + public long usingCollectionsParallel(Collection listOfbooks, int year) { + AtomicLong countOfBooks = new AtomicLong(); + listOfbooks.parallelStream() + .forEach(book -> { + if (book.getYearPublished() == year) { + countOfBooks.getAndIncrement(); + } + }); + return countOfBooks.get(); + } + + public long usingStreamParallel(Collection listOfBooks, int year) { + AtomicLong countOfBooks = new AtomicLong(); + listOfBooks.stream() + .parallel() + .forEach(book -> { + if (book.getYearPublished() == year) { + countOfBooks.getAndIncrement(); + } + }); + return countOfBooks.get(); + } + + public long usingWithCustomSpliterator(MyBookContainer listOfBooks, int year) { + AtomicLong countOfBooks = new AtomicLong(); + listOfBooks.parallelStream() + .forEach(book -> { + if (book.getYearPublished() == year) { + countOfBooks.getAndIncrement(); + } + }); + return countOfBooks.get(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/parallelstream/ParallelStreamUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/parallelstream/ParallelStreamUnitTest.java new file mode 100644 index 0000000000..af8172a10d --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/parallelstream/ParallelStreamUnitTest.java @@ -0,0 +1,46 @@ +package com.baeldung.parallelstream; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import com.baeldung.streams.parallelstream.Book; +import com.baeldung.streams.parallelstream.MyBookContainer; +import com.baeldung.streams.parallelstream.ParallelStreamApplication; + +public class ParallelStreamUnitTest { + + @Test + public void givenCollectionWhenCollectionsParallelIsUsedThenReturnCount() { + ParallelStreamApplication parallelStreamApplication = new ParallelStreamApplication(); + Assert.assertEquals(parallelStreamApplication.usingCollectionsParallel(generateListOfBooks(), 1974), 2); + } + + @Test + public void givenCollectionWhenStreamParallelIsUsedThenReturnCount() { + ParallelStreamApplication parallelStreamApplication = new ParallelStreamApplication(); + Assert.assertEquals(parallelStreamApplication.usingStreamParallel(generateListOfBooks(), 1974), 2); + } + + @Test + public void givenBookContainerWhenParallelStreamIsUsedThenReturnIncorrectCount() { + ParallelStreamApplication parallelStreamApplication = new ParallelStreamApplication(); + Assert.assertNotEquals(parallelStreamApplication.usingWithCustomSpliterator(getBookContainer(), 1974), 2); + } + + private List generateListOfBooks() { + Book book1 = new Book("The Blue Umbrella", "Ruskin Bond", 1974); + Book book2 = new Book("Carrie", "Stephen King", 1974); + Book book3 = new Book("The Psychology of money", "Morgan Housel", 2020); + List books = List.of(book1, book2, book3); + return books; + } + + private MyBookContainer getBookContainer() { + MyBookContainer listOfBooks = new MyBookContainer<>(new Book[] { new Book("The Blue Umbrella", "Ruskin Bond", 1974), + new Book("Carrie", "Stephen King", 1974), + new Book("The Psychology of money", "Morgan Housel", 2020)}); + return listOfBooks; + } +} diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streams/emptystreams/EmptyStreamsUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streams/emptystreams/EmptyStreamsUnitTest.java new file mode 100644 index 0000000000..a05eca1fcb --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streams/emptystreams/EmptyStreamsUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.streams.emptystreams; + +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import org.junit.Test; + +public class EmptyStreamsUnitTest { + + @Test + public void givenEmptyStreams_findAnyReturnsAnEmptyOptional() { + + Stream emptyStream = Stream.empty(); + assertTrue(emptyStream.findAny().isEmpty()); + + emptyStream = Stream.of(); + assertTrue(emptyStream.findAny().isEmpty()); + + IntStream emptyIntStream = IntStream.of(new int[] {}); + assertTrue(emptyIntStream.findAny().isEmpty()); + + emptyIntStream = Arrays.stream(new int[] {}); + assertTrue(emptyIntStream.findAny().isEmpty()); + + Stream collectionStream = new ArrayList().stream(); + assertTrue(collectionStream.findAny().isEmpty()); + } + + @Test + public void givenAStreamToSupplier_NewInstanceOfTheStreamIsReturnedForEveryGetCall() { + Supplier> streamSupplier = () -> Stream.of(1, 2, 3, 4, 5).filter(number -> number > 5); + + Optional result1 = streamSupplier.get().findAny(); + assertTrue(result1.isEmpty()); + Optional result2 = streamSupplier.get().findFirst(); + assertTrue(result2.isEmpty()); + } +} diff --git a/core-java-modules/core-java-streams-collect/pom.xml b/core-java-modules/core-java-streams-collect/pom.xml index c60cf2ab93..e81598017c 100644 --- a/core-java-modules/core-java-streams-collect/pom.xml +++ b/core-java-modules/core-java-streams-collect/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-streams-4 - 0.1.0-SNAPSHOT core-java-streams-collect jar @@ -35,7 +34,6 @@ - 3.23.1 diff --git a/core-java-modules/core-java-streams-maps/pom.xml b/core-java-modules/core-java-streams-maps/pom.xml index 06cc9ceef6..66e1fedd87 100644 --- a/core-java-modules/core-java-streams-maps/pom.xml +++ b/core-java-modules/core-java-streams-maps/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-streams-maps - 0.1.0-SNAPSHOT core-java-streams-maps jar diff --git a/core-java-modules/core-java-streams/pom.xml b/core-java-modules/core-java-streams/pom.xml index a6bb827e77..b0794829c2 100644 --- a/core-java-modules/core-java-streams/pom.xml +++ b/core-java-modules/core-java-streams/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-streams - 0.1.0-SNAPSHOT core-java-streams jar @@ -15,7 +14,6 @@ - org.openjdk.jmh jmh-core diff --git a/core-java-modules/core-java-string-algorithms-2/pom.xml b/core-java-modules/core-java-string-algorithms-2/pom.xml index 5af187abc2..3fdb022a4b 100644 --- a/core-java-modules/core-java-string-algorithms-2/pom.xml +++ b/core-java-modules/core-java-string-algorithms-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-algorithms-2 - 0.1.0-SNAPSHOT core-java-string-algorithms-2 jar diff --git a/core-java-modules/core-java-string-algorithms-3/README.md b/core-java-modules/core-java-string-algorithms-3/README.md index d2863be8e5..c9e7e7d7d4 100644 --- a/core-java-modules/core-java-string-algorithms-3/README.md +++ b/core-java-modules/core-java-string-algorithms-3/README.md @@ -10,3 +10,4 @@ This module contains articles about string-related algorithms. - [Check if the First Letter of a String is Uppercase](https://www.baeldung.com/java-check-first-letter-uppercase) - [Find the First Non Repeating Character in a String in Java](https://www.baeldung.com/java-find-the-first-non-repeating-character) - [Find the First Embedded Occurrence of an Integer in a Java String](https://www.baeldung.com/java-string-find-embedded-integer) +- [Find the Most Frequent Characters in a String](https://www.baeldung.com/java-string-find-most-frequent-characters) diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index 147ea22375..7d4adeba92 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -3,7 +3,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-algorithms-3 - 0.1.0-SNAPSHOT core-java-string-algorithms-3 jar @@ -40,8 +39,8 @@ maven-compiler-plugin ${maven-compiler-plugin.version} - ${java.version} - ${java.version} + ${maven.compiler.source} + ${maven.compiler.target} -parameters diff --git a/core-java-modules/core-java-string-algorithms-3/src/main/java/com/baeldung/charfreq/CharacterWithHighestFrequency.java b/core-java-modules/core-java-string-algorithms-3/src/main/java/com/baeldung/charfreq/CharacterWithHighestFrequency.java new file mode 100644 index 0000000000..938ad1edf3 --- /dev/null +++ b/core-java-modules/core-java-string-algorithms-3/src/main/java/com/baeldung/charfreq/CharacterWithHighestFrequency.java @@ -0,0 +1,58 @@ +package com.baeldung.charfreq; + +import static java.util.Map.Entry.comparingByValue; +import static java.util.stream.Collectors.counting; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toSet; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class CharacterWithHighestFrequency { + public static Character byStream(String input) { + return input.chars() + .mapToObj(x -> (char) x) + .collect(groupingBy(x -> x, counting())) + .entrySet() + .stream() + .max(comparingByValue()) + .get() + .getKey(); + } + + public static Set byMap(String input) { + Map map = new HashMap<>(); + for (char c : input.toCharArray()) { + map.compute(c, (character, count) -> count == null ? 1 : ++count); + } + int maxCount = map.values() + .stream() + .mapToInt(Integer::intValue) + .max() + .getAsInt(); + + return map.keySet() + .stream() + .filter(c -> map.get(c) == maxCount) + .collect(toSet()); + } + + public static Set byBucket(String input) { + int[] buckets = new int[128]; + + int maxCount = 0; + for (char c : input.toCharArray()) { + buckets[c]++; + maxCount = Math.max(buckets[c], maxCount); + } + + int finalMaxCount = maxCount; + return IntStream.range(0, 128) + .filter(c -> buckets[c] == finalMaxCount) + .mapToObj(i -> (char) i) + .collect(Collectors.toSet()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/charfreq/CharacterWithHighestFrequencyUnitTest.java b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/charfreq/CharacterWithHighestFrequencyUnitTest.java new file mode 100644 index 0000000000..978752f3d4 --- /dev/null +++ b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/charfreq/CharacterWithHighestFrequencyUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.charfreq; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Collections; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import com.google.common.collect.ImmutableSet; + +class CharacterWithHighestFrequencyUnitTest { + private static final String INPUT1 = "aaaaaaaaaa(10) bbbbbbb ccccc dddd eee ff"; + private static final Set EXPECTED1 = Collections.singleton('a'); + + private static final String INPUT2 = "YYYYYYY(7) bbbbb -------(7) dddd eee kkkkkkk(7) ff"; + private static final Set EXPECTED2 = ImmutableSet.of('Y', '-', 'k'); + + @Test + void whenGettingSingleCharWithHighestFrequencyByStream_shouldSuccess() { + char result1 = CharacterWithHighestFrequency.byStream(INPUT1); + assertEquals('a', result1); + } + + @Test + void whenGettingCharWithHighestFrequencyByMap_shouldSuccess() { + Set result1 = CharacterWithHighestFrequency.byMap(INPUT1); + assertEquals(EXPECTED1, result1); + + Set result2 = CharacterWithHighestFrequency.byMap(INPUT2); + assertEquals(EXPECTED2, result2); + + } + + @Test + void whenGettingCharWithHighestFrequencyByBucket_shouldSuccess() { + Set result1 = CharacterWithHighestFrequency.byBucket(INPUT1); + assertEquals(EXPECTED1, result1); + + Set result2 = CharacterWithHighestFrequency.byBucket(INPUT2); + assertEquals(EXPECTED2, result2); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-algorithms/pom.xml b/core-java-modules/core-java-string-algorithms/pom.xml index 84f3b61f84..10d28feb2f 100644 --- a/core-java-modules/core-java-string-algorithms/pom.xml +++ b/core-java-modules/core-java-string-algorithms/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-algorithms - 0.1.0-SNAPSHOT core-java-string-algorithms jar diff --git a/core-java-modules/core-java-string-algorithms/src/main/java/com/baeldung/reverse/ReverseStringExamples.java b/core-java-modules/core-java-string-algorithms/src/main/java/com/baeldung/reverse/ReverseStringExamples.java index 5236f14ccd..07663ab7d1 100644 --- a/core-java-modules/core-java-string-algorithms/src/main/java/com/baeldung/reverse/ReverseStringExamples.java +++ b/core-java-modules/core-java-string-algorithms/src/main/java/com/baeldung/reverse/ReverseStringExamples.java @@ -1,5 +1,9 @@ package com.baeldung.reverse; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + import org.apache.commons.lang3.StringUtils; public class ReverseStringExamples { @@ -46,11 +50,43 @@ public class ReverseStringExamples { } return output.toString() - .trim(); + .trim(); } public static String reverseTheOrderOfWordsUsingApacheCommons(String sentence) { return StringUtils.reverseDelimited(sentence, ' '); } + public static String reverseUsingIntStreamRangeMethod(String str) { + if (str == null) { + return null; + } + + char[] charArray = str.toCharArray(); + return IntStream.range(0, str.length()) + .mapToObj(i -> charArray[str.length() - i - 1]) + .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) + .toString(); + } + + public static String reverseUsingStreamOfMethod(String str) { + if (str == null) { + return null; + } + + return Stream.of(str) + .map(string -> new StringBuilder(string).reverse()) + .collect(Collectors.joining()); + } + + public static String reverseUsingCharsMethod(String str) { + if (str == null) { + return null; + } + + return str.chars() + .mapToObj(c -> (char) c) + .reduce("", (a, b) -> b + a, (a2, b2) -> b2 + a2); + } + } diff --git a/core-java-modules/core-java-string-algorithms/src/test/java/com/baeldung/reverse/ReverseStringExamplesUnitTest.java b/core-java-modules/core-java-string-algorithms/src/test/java/com/baeldung/reverse/ReverseStringExamplesUnitTest.java index c122163174..b3685a49da 100644 --- a/core-java-modules/core-java-string-algorithms/src/test/java/com/baeldung/reverse/ReverseStringExamplesUnitTest.java +++ b/core-java-modules/core-java-string-algorithms/src/test/java/com/baeldung/reverse/ReverseStringExamplesUnitTest.java @@ -1,10 +1,11 @@ package com.baeldung.reverse; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + import org.apache.commons.lang3.StringUtils; import org.junit.Test; -import static org.junit.Assert.assertEquals; - public class ReverseStringExamplesUnitTest { private static final String STRING_INPUT = "cat"; @@ -19,7 +20,7 @@ public class ReverseStringExamplesUnitTest { String reversedEmpty = ReverseStringExamples.reverse(StringUtils.EMPTY); assertEquals(STRING_INPUT_REVERSED, reversed); - assertEquals(null, reversedNull); + assertNull(reversedNull); assertEquals(StringUtils.EMPTY, reversedEmpty); } @@ -30,7 +31,7 @@ public class ReverseStringExamplesUnitTest { String reversedEmpty = ReverseStringExamples.reverseUsingStringBuilder(StringUtils.EMPTY); assertEquals(STRING_INPUT_REVERSED, reversed); - assertEquals(null, reversedNull); + assertNull(reversedNull); assertEquals(StringUtils.EMPTY, reversedEmpty); } @@ -41,7 +42,7 @@ public class ReverseStringExamplesUnitTest { String reversedEmpty = ReverseStringExamples.reverseUsingApacheCommons(StringUtils.EMPTY); assertEquals(STRING_INPUT_REVERSED, reversed); - assertEquals(null, reversedNull); + assertNull(reversedNull); assertEquals(StringUtils.EMPTY, reversedEmpty); } @@ -52,7 +53,7 @@ public class ReverseStringExamplesUnitTest { String reversedEmpty = ReverseStringExamples.reverseTheOrderOfWords(StringUtils.EMPTY); assertEquals(REVERSED_WORDS_SENTENCE, reversed); - assertEquals(null, reversedNull); + assertNull(reversedNull); assertEquals(StringUtils.EMPTY, reversedEmpty); } @@ -63,7 +64,40 @@ public class ReverseStringExamplesUnitTest { String reversedEmpty = ReverseStringExamples.reverseTheOrderOfWordsUsingApacheCommons(StringUtils.EMPTY); assertEquals(REVERSED_WORDS_SENTENCE, reversed); - assertEquals(null, reversedNull); + assertNull(reversedNull); + assertEquals(StringUtils.EMPTY, reversedEmpty); + } + + @Test + public void whenReverseStringUsingIntStreamRangeMethod_ThenCorrectStringIsReturned() { + String reversed = ReverseStringExamples.reverseUsingIntStreamRangeMethod(STRING_INPUT); + String reversedNull = ReverseStringExamples.reverseUsingIntStreamRangeMethod(null); + String reversedEmpty = ReverseStringExamples.reverseUsingIntStreamRangeMethod(StringUtils.EMPTY); + + assertEquals(STRING_INPUT_REVERSED, reversed); + assertNull(reversedNull); + assertEquals(StringUtils.EMPTY, reversedEmpty); + } + + @Test + public void whenReverseStringUsingCharsMethod_ThenCorrectStringIsReturned() { + String reversed = ReverseStringExamples.reverseUsingCharsMethod(STRING_INPUT); + String reversedNull = ReverseStringExamples.reverseUsingCharsMethod(null); + String reversedEmpty = ReverseStringExamples.reverseUsingCharsMethod(StringUtils.EMPTY); + + assertEquals(STRING_INPUT_REVERSED, reversed); + assertNull(reversedNull); + assertEquals(StringUtils.EMPTY, reversedEmpty); + } + + @Test + public void whenReverseStringUsingStreamOfMethod_ThenCorrectStringIsReturned() { + String reversed = ReverseStringExamples.reverseUsingStreamOfMethod(STRING_INPUT); + String reversedNull = ReverseStringExamples.reverseUsingStreamOfMethod(null); + String reversedEmpty = ReverseStringExamples.reverseUsingStreamOfMethod(StringUtils.EMPTY); + + assertEquals(STRING_INPUT_REVERSED, reversed); + assertNull(reversedNull); assertEquals(StringUtils.EMPTY, reversedEmpty); } diff --git a/core-java-modules/core-java-string-apis-2/README.md b/core-java-modules/core-java-string-apis-2/README.md index 5476e91169..d1ec0d8388 100644 --- a/core-java-modules/core-java-string-apis-2/README.md +++ b/core-java-modules/core-java-string-apis-2/README.md @@ -4,3 +4,4 @@ This module contains articles about string APIs. ### Relevant Articles: - [Retain Only Digits and Decimal Separator in String](https://www.baeldung.com/java-string-retain-digits-decimal) +- [Difference Between null and Empty String in Java](https://www.baeldung.com/java-string-null-vs-empty) diff --git a/core-java-modules/core-java-string-apis-2/pom.xml b/core-java-modules/core-java-string-apis-2/pom.xml index ba983d7593..db97b85748 100644 --- a/core-java-modules/core-java-string-apis-2/pom.xml +++ b/core-java-modules/core-java-string-apis-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-apis-2 - 0.0.1-SNAPSHOT core-java-string-apis-2 jar diff --git a/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/nullandempty/NullAndEmptyStringUnitTest.java b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/nullandempty/NullAndEmptyStringUnitTest.java new file mode 100644 index 0000000000..332a16fd84 --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/nullandempty/NullAndEmptyStringUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.nullandempty; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.Test; + +public class NullAndEmptyStringUnitTest { + + @Test + void givenANullAndEmptyString_whenUsingStringMethods_thenShouldGetExpectedResult() { + String nullString = null; + String emptyString = ""; + assertTrue(emptyString.equals("")); + assertThrows(NullPointerException.class, () -> nullString.length()); + } + + @Test + void givenANullAndEmptyString_whenCheckingEquality_thenShouldGetExpectedResult() { + String nullString = null; + String emptyString = ""; + assertFalse(emptyString.equals(nullString)); + assertFalse(emptyString == nullString); + } + +} diff --git a/core-java-modules/core-java-string-apis/pom.xml b/core-java-modules/core-java-string-apis/pom.xml index 6a382c3c57..5d7737228c 100644 --- a/core-java-modules/core-java-string-apis/pom.xml +++ b/core-java-modules/core-java-string-apis/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-apis - 0.1.0-SNAPSHOT core-java-string-apis jar diff --git a/core-java-modules/core-java-string-conversions-2/pom.xml b/core-java-modules/core-java-string-conversions-2/pom.xml index e424ef3083..90463271b8 100644 --- a/core-java-modules/core-java-string-conversions-2/pom.xml +++ b/core-java-modules/core-java-string-conversions-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-conversions-2 - 0.1.0-SNAPSHOT core-java-string-conversions-2 jar diff --git a/core-java-modules/core-java-string-conversions/pom.xml b/core-java-modules/core-java-string-conversions/pom.xml index f10ae401b3..b87431cd0b 100644 --- a/core-java-modules/core-java-string-conversions/pom.xml +++ b/core-java-modules/core-java-string-conversions/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-conversions - 0.1.0-SNAPSHOT core-java-string-conversions jar @@ -44,6 +43,7 @@ 61.1 + -Djava.locale.providers=COMPAT \ No newline at end of file diff --git a/core-java-modules/core-java-string-conversions/src/test/java/com/baeldung/datetostring/DateToStringFormatterUnitTest.java b/core-java-modules/core-java-string-conversions/src/test/java/com/baeldung/datetostring/DateToStringFormatterUnitTest.java index 221900fb0e..c4fb84713c 100644 --- a/core-java-modules/core-java-string-conversions/src/test/java/com/baeldung/datetostring/DateToStringFormatterUnitTest.java +++ b/core-java-modules/core-java-string-conversions/src/test/java/com/baeldung/datetostring/DateToStringFormatterUnitTest.java @@ -1,7 +1,6 @@ package com.baeldung.datetostring; -import org.junit.BeforeClass; -import org.junit.Test; +import static org.junit.Assert.assertEquals; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -14,7 +13,8 @@ import java.util.Date; import java.util.Locale; import java.util.TimeZone; -import static org.junit.Assert.assertEquals; +import org.junit.BeforeClass; +import org.junit.Test; public class DateToStringFormatterUnitTest { diff --git a/core-java-modules/core-java-string-operations-2/pom.xml b/core-java-modules/core-java-string-operations-2/pom.xml index 92bfa6b2d8..c6debc4f71 100644 --- a/core-java-modules/core-java-string-operations-2/pom.xml +++ b/core-java-modules/core-java-string-operations-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-operations-2 - 0.1.0-SNAPSHOT core-java-string-operations-2 jar diff --git a/core-java-modules/core-java-string-operations-3/pom.xml b/core-java-modules/core-java-string-operations-3/pom.xml index 19b3d57ffd..39167271fa 100644 --- a/core-java-modules/core-java-string-operations-3/pom.xml +++ b/core-java-modules/core-java-string-operations-3/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-operations-3 - 0.1.0-SNAPSHOT core-java-string-operations-3 jar 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 0f1e377d18..cc755cf470 100644 --- a/core-java-modules/core-java-string-operations-4/pom.xml +++ b/core-java-modules/core-java-string-operations-4/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-operations-4 - 0.1.0-SNAPSHOT core-java-string-operations-4 jar diff --git a/core-java-modules/core-java-string-operations-5/README.md b/core-java-modules/core-java-string-operations-5/README.md index 94fb7e855e..3a09c8a585 100644 --- a/core-java-modules/core-java-string-operations-5/README.md +++ b/core-java-modules/core-java-string-operations-5/README.md @@ -8,3 +8,7 @@ - [Convert String to String Array](https://www.baeldung.com/java-convert-string-to-string-array) - [String Interpolation in Java](https://www.baeldung.com/java-string-interpolation) - [Guide to Splitting a String by Whitespace in Java](https://www.baeldung.com/java-splitting-a-string-by-whitespace) +- [Check if the First Letter of a String Is a Number](https://www.baeldung.com/java-check-if-string-starts-with-number) +- [Print “” Quotes Around a String in Java](https://www.baeldung.com/java-string-print-quotes) +- [Remove Punctuation From a String in Java](https://www.baeldung.com/java-remove-punctuation-from-string) +- [Find the Longest Word in a Given String in Java](https://www.baeldung.com/java-longest-word-string) diff --git a/core-java-modules/core-java-string-operations-5/pom.xml b/core-java-modules/core-java-string-operations-5/pom.xml index efb32c73b9..2a2a353984 100644 --- a/core-java-modules/core-java-string-operations-5/pom.xml +++ b/core-java-modules/core-java-string-operations-5/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-operations-5 - 0.1.0-SNAPSHOT core-java-string-operations-5 jar diff --git a/core-java-modules/core-java-string-operations-5/src/main/java/com/baeldung/firstchardigit/FirstCharDigit.java b/core-java-modules/core-java-string-operations-5/src/main/java/com/baeldung/firstchardigit/FirstCharDigit.java new file mode 100644 index 0000000000..a43127af1a --- /dev/null +++ b/core-java-modules/core-java-string-operations-5/src/main/java/com/baeldung/firstchardigit/FirstCharDigit.java @@ -0,0 +1,62 @@ +package com.baeldung.firstchardigit; + +import java.util.regex.Pattern; + +import com.google.common.base.CharMatcher; + +public class FirstCharDigit { + + public static boolean checkUsingCharAtMethod(String str) { + if (str == null || str.length() == 0) { + return false; + } + + char c = str.charAt(0); + return c >= '0' && c <= '9'; + } + + public static boolean checkUsingIsDigitMethod(String str) { + if (str == null || str.length() == 0) { + return false; + } + + return Character.isDigit(str.charAt(0)); + } + + public static boolean checkUsingPatternClass(String str) { + if (str == null || str.length() == 0) { + return false; + } + + return Pattern.compile("^[0-9].*") + .matcher(str) + .matches(); + } + + public static boolean checkUsingMatchesMethod(String str) { + if (str == null || str.length() == 0) { + return false; + } + + return str.matches("^[0-9].*"); + } + + public static boolean checkUsingCharMatcherInRangeMethod(String str) { + if (str == null || str.length() == 0) { + return false; + } + + return CharMatcher.inRange('0', '9') + .matches(str.charAt(0)); + } + + public static boolean checkUsingCharMatcherForPredicateMethod(String str) { + if (str == null || str.length() == 0) { + return false; + } + + return CharMatcher.forPredicate(Character::isDigit) + .matches(str.charAt(0)); + } + +} diff --git a/core-java-modules/core-java-string-operations-5/src/main/java/com/baeldung/longestword/LongestWordFinder.java b/core-java-modules/core-java-string-operations-5/src/main/java/com/baeldung/longestword/LongestWordFinder.java new file mode 100644 index 0000000000..770984ac29 --- /dev/null +++ b/core-java-modules/core-java-string-operations-5/src/main/java/com/baeldung/longestword/LongestWordFinder.java @@ -0,0 +1,36 @@ +package com.baeldung.longestword; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class LongestWordFinder { + + public Optional findLongestWord(String sentence) { + return Optional.ofNullable(sentence) + .filter(string -> !string.trim() + .isEmpty()) + .map(string -> string.split("\\s")) + .map(Arrays::asList) + .map(list -> Collections.max(list, Comparator.comparingInt(String::length))); + } + + public List findLongestWords(String sentence) { + if (sentence == null || sentence.trim() + .isEmpty()) { + return Collections.emptyList(); + } + String[] words = sentence.split("\\s"); + int maxWordLength = Arrays.stream(words) + .mapToInt(String::length) + .max() + .orElseThrow(); + return Arrays.stream(words) + .filter(word -> word.length() == maxWordLength) + .collect(Collectors.toList()); + } + +} diff --git a/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/delpunctuation/RemovePunctuationUnitTest.java b/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/delpunctuation/RemovePunctuationUnitTest.java new file mode 100644 index 0000000000..751ae0f4bc --- /dev/null +++ b/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/delpunctuation/RemovePunctuationUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.delpunctuation; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.jupiter.api.Test; + +public class RemovePunctuationUnitTest { + private static final String INPUT = "Its 1 W o r d (!@#$%^&*{}[];':\")<>,."; + private static final String EXPECTED = "Its 1 W o r d "; + + private static final String UNICODE_INPUT = "3 March März 三月 březen маршировать (!@#$%^&*{}[];':\")<>,."; + private static final String UNICODE_EXPECTED = "3 March März 三月 březen маршировать "; + + @Test + void whenUsingCharClassRange_thenGetExceptedResult() { + String result = INPUT.replaceAll("[^\\sa-zA-Z0-9]", ""); + assertEquals(EXPECTED, result); + } + + @Test + void whenUsingPunctuationCharClass_thenGetExceptedResult() { + String result = INPUT.replaceAll("\\p{Punct}", ""); + assertEquals(EXPECTED, result); + } + + @Test + void whenInputContainsUnicodeChars_thenGetExceptedResult() { + String result1 = UNICODE_INPUT.replaceAll("[^\\sa-zA-Z0-9]", ""); + assertNotEquals(UNICODE_EXPECTED, result1); + + String actualResult1 = "3 March Mrz bezen "; + assertEquals(actualResult1, result1); + + + String result2 = UNICODE_INPUT.replaceAll("\\p{Punct}", ""); + assertEquals(UNICODE_EXPECTED, result2); + + String result3 = UNICODE_INPUT.replaceAll("[^\\s\\p{L}0-9]", ""); + assertEquals(UNICODE_EXPECTED, result3); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/firstchardigit/FirstCharDigitUnitTest.java b/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/firstchardigit/FirstCharDigitUnitTest.java new file mode 100644 index 0000000000..0095ebcaf3 --- /dev/null +++ b/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/firstchardigit/FirstCharDigitUnitTest.java @@ -0,0 +1,58 @@ +package com.baeldung.firstchardigit; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class FirstCharDigitUnitTest { + + @Test + void givenString_whenUsingCharAtMethod_thenSuccess() { + assertTrue(FirstCharDigit.checkUsingCharAtMethod("12 years")); + assertFalse(FirstCharDigit.checkUsingCharAtMethod("years")); + assertFalse(FirstCharDigit.checkUsingCharAtMethod("")); + assertFalse(FirstCharDigit.checkUsingCharAtMethod(null)); + } + + @Test + void givenString_whenUsingIsDigitMethod_thenSuccess() { + assertTrue(FirstCharDigit.checkUsingIsDigitMethod("10 cm")); + assertFalse(FirstCharDigit.checkUsingIsDigitMethod("cm")); + assertFalse(FirstCharDigit.checkUsingIsDigitMethod("")); + assertFalse(FirstCharDigit.checkUsingIsDigitMethod(null)); + } + + @Test + void givenString_whenUsingPatternClass_thenSuccess() { + assertTrue(FirstCharDigit.checkUsingPatternClass("1 kg")); + assertFalse(FirstCharDigit.checkUsingPatternClass("kg")); + assertFalse(FirstCharDigit.checkUsingPatternClass("")); + assertFalse(FirstCharDigit.checkUsingPatternClass(null)); + } + + @Test + void givenString_whenUsingMatchesMethod_thenSuccess() { + assertTrue(FirstCharDigit.checkUsingMatchesMethod("123")); + assertFalse(FirstCharDigit.checkUsingMatchesMethod("ABC")); + assertFalse(FirstCharDigit.checkUsingMatchesMethod("")); + assertFalse(FirstCharDigit.checkUsingMatchesMethod(null)); + } + + @Test + void givenString_whenUsingCharMatcherInRangeMethod_thenSuccess() { + assertTrue(FirstCharDigit.checkUsingCharMatcherInRangeMethod("2023")); + assertFalse(FirstCharDigit.checkUsingCharMatcherInRangeMethod("abc")); + assertFalse(FirstCharDigit.checkUsingCharMatcherInRangeMethod("")); + assertFalse(FirstCharDigit.checkUsingCharMatcherInRangeMethod(null)); + } + + @Test + void givenString_whenUsingCharMatcherForPredicateMethod_thenSuccess() { + assertTrue(FirstCharDigit.checkUsingCharMatcherForPredicateMethod("100")); + assertFalse(FirstCharDigit.checkUsingCharMatcherForPredicateMethod("abdo")); + assertFalse(FirstCharDigit.checkUsingCharMatcherForPredicateMethod("")); + assertFalse(FirstCharDigit.checkUsingCharMatcherForPredicateMethod(null)); + } + +} diff --git a/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/longestword/LongestWordFinderUnitTest.java b/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/longestword/LongestWordFinderUnitTest.java new file mode 100644 index 0000000000..9d5f82d493 --- /dev/null +++ b/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/longestword/LongestWordFinderUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.longestword; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class LongestWordFinderUnitTest { + + LongestWordFinder longestWordFinder = new LongestWordFinder(); + + @Test + void givenNull_whenFindLongestWord_thenEmpty() { + assertThat(longestWordFinder.findLongestWord(null)).isEmpty(); + } + + @Test + void givenEmptyString_whenFindLongestWord_thenEmpty() { + assertThat(longestWordFinder.findLongestWord("")).isEmpty(); + } + + @Test + void givenStringWithOnlySpaces_whenFindLongestWord_thenEmpty() { + assertThat(longestWordFinder.findLongestWord(" ")).isEmpty(); + } + + @Test + void givenAPhraseWithALongestWord_whenFindLongestWord_thenLongestWordOfThePhrase() { + assertThat(longestWordFinder.findLongestWord("This is a phrase with words")).hasValue("phrase"); + } + + @Test + void givenAPhraseWithVariousWordsOfMaxLength_whenFindLongestWord_thenAnyOfTheLongestsWordsOfThePhrase() { + assertThat(longestWordFinder.findLongestWord("Baeldung is another word of size eight in this sentence") + .get()).isIn("Baeldung", "sentence"); + } + + @Test + void givenNull_whenFindLongestWords_thenEmpty() { + assertThat(longestWordFinder.findLongestWords(null)).isEmpty(); + } + + @Test + void givenEmptyString_whenFindLongestWords_thenEmpty() { + assertThat(longestWordFinder.findLongestWords("")).isEmpty(); + } + + @Test + void givenStringWithOnlySpaces_whenFindLongestWords_thenEmpty() { + assertThat(longestWordFinder.findLongestWords(" ")).isEmpty(); + } + + @Test + void givenAPhraseWithALongestWord_whenFindLongestWords_thenLongestWordOfThePhrase() { + assertThat(longestWordFinder.findLongestWords("This is a phrase with words")).containsExactly("phrase"); + } + + @Test + void givenAPhraseWithVariousWordsOfMaxLength_whenFindLongestWords_thenAllLongestsWords() { + assertThat(longestWordFinder.findLongestWords("Baeldung is another word of size eight in this sentence")).containsExactly("Baeldung", "sentence"); + } + +} diff --git a/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/stringwithquotes/PrintQuotesAroundAStringUnitTest.java b/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/stringwithquotes/PrintQuotesAroundAStringUnitTest.java new file mode 100644 index 0000000000..fd4ade1ef3 --- /dev/null +++ b/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/stringwithquotes/PrintQuotesAroundAStringUnitTest.java @@ -0,0 +1,60 @@ +package com.baeldung.stringwithquotes; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class PrintQuotesAroundAStringUnitTest { + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final PrintStream originalOut = System.out; + + @BeforeEach + void replaceOut() { + System.setOut(new PrintStream(outContent)); + } + + @AfterEach + void restoreOut() { + System.setOut(originalOut); + } + + @Test + void whenWrappingAStringWithEscapedQuote_thenGetExpectedResult() { + String theySay = "All Java programmers are cute!"; + String quoted = "\"" + theySay + "\""; + + System.out.println(quoted); + + //assertion + String expected = "\"All Java programmers are cute!\"\n"; + assertEquals(expected, outContent.toString()); + } + + @Test + void whenCallingReplaceAll_thenGetExpectedResult() { + String theySay = "Can you write Java code?"; + String quoted = theySay.replaceAll("^|$", "\""); + + System.out.println(quoted); + + //assertion + String expected = "\"Can you write Java code?\"\n"; + assertEquals(expected, outContent.toString()); + } + + @Test + void whenWrappingAStringWithQuoteChar_thenGetExpectedResult() { + String weSay = "Yes, we can write beautiful Java codes!"; + String quoted = '"' + weSay + '"'; + System.out.println(quoted); + + //assertion + String expected = "\"Yes, we can write beautiful Java codes!\"\n"; + assertEquals(expected, outContent.toString()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations/pom.xml b/core-java-modules/core-java-string-operations/pom.xml index 20e4df3ba3..577736a324 100644 --- a/core-java-modules/core-java-string-operations/pom.xml +++ b/core-java-modules/core-java-string-operations/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-operations - 0.1.0-SNAPSHOT core-java-string-operations jar @@ -15,6 +14,11 @@ + + javax.xml.bind + jaxb-api + 2.4.0-b180725.0427 + org.apache.commons commons-lang3 diff --git a/core-java-modules/core-java-strings/README.md b/core-java-modules/core-java-strings/README.md index 835e9ec582..84cf31e8bd 100644 --- a/core-java-modules/core-java-strings/README.md +++ b/core-java-modules/core-java-strings/README.md @@ -13,3 +13,4 @@ This module contains articles about strings in Java. - [Java Multi-line String](https://www.baeldung.com/java-multiline-string) - [Guide to Java String Pool](https://www.baeldung.com/java-string-pool) - [Fixing “constant string too long” Build Error](https://www.baeldung.com/java-constant-string-too-long-error) +- [Reuse StringBuilder for Efficiency](https://www.baeldung.com/java-reuse-stringbuilder-for-efficiency) diff --git a/core-java-modules/core-java-strings/pom.xml b/core-java-modules/core-java-strings/pom.xml index 2cc35dad5f..e3cdb3c666 100644 --- a/core-java-modules/core-java-strings/pom.xml +++ b/core-java-modules/core-java-strings/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-strings - 0.1.0-SNAPSHOT core-java-strings jar diff --git a/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringbuilder/ReuseStringBuilderPerformance.java b/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringbuilder/ReuseStringBuilderPerformance.java new file mode 100644 index 0000000000..b403f859bc --- /dev/null +++ b/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringbuilder/ReuseStringBuilderPerformance.java @@ -0,0 +1,55 @@ +package com.baeldung.stringbuilder; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.SingleShotTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Measurement(batchSize = 100000, iterations = 10) +@Warmup(batchSize = 100000, iterations = 10) +@State(Scope.Thread) +public class ReuseStringBuilderPerformance { + + @Benchmark + public void benchmarkStringBuilder() { + for (int i = 0; i < 100; i++) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("baeldung"); + stringBuilder.toString(); + } + } + + @Benchmark + public void benchmarkStringBuilderReuseWithSetLength() { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < 100; i++) { + stringBuilder.append("baeldung"); + stringBuilder.toString(); + stringBuilder.setLength(0); + } + } + + @Benchmark() + public void benchmarkStringBuilderReuseWithDelete() { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < 100; i++) { + stringBuilder.append("baeldung"); + stringBuilder.toString(); + stringBuilder.delete(0, stringBuilder.length()); + } + } + + public static void main(String[] args) throws Exception { + Options options = new OptionsBuilder() + .include(ReuseStringBuilderPerformance.class.getSimpleName()).threads(1) + .forks(1).shouldFailOnError(true) + .shouldDoGC(true) + .jvmArgs("-server").build(); + new Runner(options).run(); + } + +} diff --git a/core-java-modules/core-java-sun/pom.xml b/core-java-modules/core-java-sun/pom.xml index e959932235..c9427f66a3 100644 --- a/core-java-modules/core-java-sun/pom.xml +++ b/core-java-modules/core-java-sun/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-sun - 0.1.0-SNAPSHOT core-java-sun jar diff --git a/core-java-modules/core-java-time-measurements/pom.xml b/core-java-modules/core-java-time-measurements/pom.xml index ac5fb3a5e6..7b2bc31ebb 100644 --- a/core-java-modules/core-java-time-measurements/pom.xml +++ b/core-java-modules/core-java-time-measurements/pom.xml @@ -3,9 +3,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 - com.baeldung.exception.numberformat core-java-time-measurements - 0.0.1-SNAPSHOT core-java-time-measurements jar diff --git a/core-java-modules/core-java-uuid/README.md b/core-java-modules/core-java-uuid/README.md index 0a77c36acd..bd7bd9d9da 100644 --- a/core-java-modules/core-java-uuid/README.md +++ b/core-java-modules/core-java-uuid/README.md @@ -4,3 +4,5 @@ - [Generating Alphanumeric UUID String in Java](https://www.baeldung.com/java-generate-alphanumeric-uuid) - [Guide to UUID in Java](http://www.baeldung.com/java-uuid) - [Validate UUID String in Java](https://www.baeldung.com/java-validate-uuid-string) +- [Generate the Same UUID From a String in Java](https://www.baeldung.com/java-generate-same-uuid-from-string) +- [Generating Time Based UUIDs](https://www.baeldung.com/java-generating-time-based-uuids) diff --git a/core-java-modules/core-java-uuid/pom.xml b/core-java-modules/core-java-uuid/pom.xml index 7d851292f5..c0e93c1d32 100644 --- a/core-java-modules/core-java-uuid/pom.xml +++ b/core-java-modules/core-java-uuid/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-uuid - 0.1.0-SNAPSHOT core-java-uuid jar @@ -25,6 +24,21 @@ log4j-over-slf4j ${org.slf4j.version} + + com.github.f4b6a3 + uuid-creator + 5.2.0 + + + com.fasterxml.uuid + java-uuid-generator + 4.1.0 + + + com.github.f4b6a3 + tsid-creator + 5.2.3 + @@ -143,4 +157,4 @@ 3.0.0-M1 - \ No newline at end of file + diff --git a/core-java-modules/core-java-uuid/src/main/java/com/baeldung/timebaseduuid/JavaUUIDCreatorBenchmark.java b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/timebaseduuid/JavaUUIDCreatorBenchmark.java new file mode 100644 index 0000000000..20b2c127bd --- /dev/null +++ b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/timebaseduuid/JavaUUIDCreatorBenchmark.java @@ -0,0 +1,42 @@ +package com.baeldung.timebaseduuid; + +import com.fasterxml.uuid.Generators; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +public class JavaUUIDCreatorBenchmark { + +public static void main(String[] args) throws InterruptedException { + + int threadCount = 128; + int iterationCount = 100_000; + Map uuidMap = new ConcurrentHashMap<>(); + AtomicLong collisionCount = new AtomicLong(); + long startNanos = System.nanoTime(); + CountDownLatch endLatch = new CountDownLatch(threadCount); + + for (long i = 0; i < threadCount; i++) { + long threadId = i; + new Thread(() -> { + for (long j = 0; j < iterationCount; j++) { + UUID uuid = Generators.timeBasedGenerator().generate(); + Long existingUUID = uuidMap.put(uuid, (threadId * iterationCount) + j); + if(existingUUID != null) { + collisionCount.incrementAndGet(); + } + } + endLatch.countDown(); + }).start(); + } + + endLatch.await(); + System.out.println(threadCount * iterationCount + " UUIDs generated, " + collisionCount + " collisions in " + + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos) + "ms"); +} +} + diff --git a/core-java-modules/core-java-uuid/src/main/java/com/baeldung/timebaseduuid/JavaUUIDCreatorExample.java b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/timebaseduuid/JavaUUIDCreatorExample.java new file mode 100644 index 0000000000..b59d7e236a --- /dev/null +++ b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/timebaseduuid/JavaUUIDCreatorExample.java @@ -0,0 +1,13 @@ +package com.baeldung.timebaseduuid; + +import com.fasterxml.uuid.Generators; + +public class JavaUUIDCreatorExample { + + public static void main(String[] args) { + System.out.println("UUID Version 1: " + Generators.timeBasedGenerator().generate()); + System.out.println("UUID Version 6: " + Generators.timeBasedReorderedGenerator().generate()); + System.out.println("UUID Version 7: " + Generators.timeBasedEpochGenerator().generate()); + + } +} diff --git a/core-java-modules/core-java-uuid/src/main/java/com/baeldung/timebaseduuid/UUIDCreatorBenchmark.java b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/timebaseduuid/UUIDCreatorBenchmark.java new file mode 100644 index 0000000000..d93cd73a25 --- /dev/null +++ b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/timebaseduuid/UUIDCreatorBenchmark.java @@ -0,0 +1,42 @@ +package com.baeldung.timebaseduuid; + +import com.github.f4b6a3.uuid.UuidCreator; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +public class UUIDCreatorBenchmark { + + public static void main(String[] args) throws InterruptedException { + + int threadCount = 128; + int iterationCount = 100_000; + Map uuidMap = new ConcurrentHashMap<>(); + AtomicLong collisionCount = new AtomicLong(); + long startNanos = System.nanoTime(); + CountDownLatch endLatch = new CountDownLatch(threadCount); + + for (long i = 0; i < threadCount; i++) { + long threadId = i; + new Thread(() -> { + for (long j = 0; j < iterationCount; j++) { + UUID uuid = UuidCreator.getTimeBased(); + Long existingUUID = uuidMap.put(uuid, (threadId * iterationCount) + j); + if(existingUUID != null) { + collisionCount.incrementAndGet(); + } + } + endLatch.countDown(); + }).start(); + } + + endLatch.await(); + System.out.println(threadCount * iterationCount + " UUIDs generated, " + collisionCount + " collisions in " + + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos) + "ms"); + } +} diff --git a/core-java-modules/core-java-uuid/src/main/java/com/baeldung/timebaseduuid/UUIDCreatorExample.java b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/timebaseduuid/UUIDCreatorExample.java new file mode 100644 index 0000000000..fad2f55c93 --- /dev/null +++ b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/timebaseduuid/UUIDCreatorExample.java @@ -0,0 +1,13 @@ +package com.baeldung.timebaseduuid; + +import com.github.f4b6a3.uuid.UuidCreator; + +public class UUIDCreatorExample { + + public static void main(String[] args) { + System.out.println("UUID Version 1: " + UuidCreator.getTimeBased()); + System.out.println("UUID Version 6: " + UuidCreator.getTimeOrdered()); + System.out.println("UUID Version 7: " + UuidCreator.getTimeOrderedEpoch()); + } +} + diff --git a/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDFromStringUnitTest.java b/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDFromStringUnitTest.java new file mode 100644 index 0000000000..381d8715d5 --- /dev/null +++ b/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDFromStringUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.uuid; + +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.*; + +public class UUIDFromStringUnitTest { + @Test + void whenStringInUUIDFormat_thenFromStringWorks() { + String inputStr = "bbcc4621-d88f-4a94-ae2f-b38072bf5087"; + + UUID uuid = UUID.fromString(inputStr); + UUID uuid2 = UUID.fromString(inputStr); + UUID uuid3 = UUID.fromString(inputStr); + + assertEquals(inputStr, uuid.toString()); + + assertEquals(uuid, uuid2); + assertEquals(uuid, uuid3); + + } + + @Test + void whenStringNotInUUIDFormat_thenFromStringRaisesException() { + String inputStr = "I am not a standard UUID representation."; + assertThrows(IllegalArgumentException.class, () -> UUID.fromString(inputStr)); + } + + @Test + void whenStringInFreeFormat_thenNameUUIDFromBytesWorks() { + String inputStr = "I am not a standard UUID representation."; + + UUID uuid = UUID.nameUUIDFromBytes(inputStr.getBytes()); + UUID uuid2 = UUID.nameUUIDFromBytes(inputStr.getBytes()); + UUID uuid3 = UUID.nameUUIDFromBytes(inputStr.getBytes()); + + assertTrue(uuid != null); + + assertEquals(uuid, uuid2); + assertEquals(uuid, uuid3); + + assertEquals(3, uuid.version()); + } + + @Test + void whenStringInFreeFormat_thenGenerateVer5UUIDWorks() { + String inputStr = "I am not a standard UUID representation."; + + UUID uuid = UUIDGenerator.generateType5UUID(inputStr); + UUID uuid2 = UUIDGenerator.generateType5UUID(inputStr); + UUID uuid3 = UUIDGenerator.generateType5UUID(inputStr); + + assertEquals(5, uuid.version()); + + assertTrue(uuid != null); + + assertEquals(uuid, uuid2); + assertEquals(uuid, uuid3); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java/.gitignore b/core-java-modules/core-java/.gitignore deleted file mode 100644 index 374c8bf907..0000000000 --- a/core-java-modules/core-java/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -*.class - -0.* - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* -.resourceCache - -# Packaged files # -*.jar -*.war -*.ear - -# Files generated by integration tests -backup-pom.xml -/bin/ -/temp - -#IntelliJ specific -.idea/ -*.iml \ No newline at end of file diff --git a/core-java-modules/core-java/README.md b/core-java-modules/core-java/README.md deleted file mode 100644 index 087c5d356e..0000000000 --- a/core-java-modules/core-java/README.md +++ /dev/null @@ -1,11 +0,0 @@ -## Core Java Cookbooks and Examples - -### Relevant Articles: - -- [Getting Started with Java Properties](http://www.baeldung.com/java-properties) -- [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency) -- [Compiling Java *.class Files with javac](http://www.baeldung.com/javac) -- [Introduction to Javadoc](http://www.baeldung.com/javadoc) -- [A Guide to the ResourceBundle](http://www.baeldung.com/java-resourcebundle) -- [Merging java.util.Properties Objects](https://www.baeldung.com/java-merging-properties) -- [Illegal Character Compilation Error](https://www.baeldung.com/java-illegal-character-error) diff --git a/core-java-modules/core-java/customers.xml b/core-java-modules/core-java/customers.xml deleted file mode 100644 index b52dc27633..0000000000 --- a/core-java-modules/core-java/customers.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - SELECT * FROM customers - 1008 - - true - 1000 - 0 - 2 - - - - - 0 - 0 - 0 - true - ResultSet.TYPE_SCROLL_INSENSITIVE - false - customers - jdbc:h2:mem:testdb - - com.sun.rowset.providers.RIOptimisticProvider - Oracle Corporation - 1.0 - 2 - 1 - - - - 2 - - 1 - false - true - false - 0 - true - true - 11 - ID - ID - PUBLIC - 10 - 0 - CUSTOMERS - TESTDB - 4 - INTEGER - - - 2 - false - true - false - 0 - true - true - 50 - NAME - NAME - PUBLIC - 50 - 0 - CUSTOMERS - TESTDB - 12 - VARCHAR - - - - - 1 - Customer1 - - - 2 - Customer2 - - - 3 - Customer3 - - - 4 - Customer4 - - - 5 - Customer5 - - - diff --git a/core-java-modules/core-java/externalizable.txt b/core-java-modules/core-java/externalizable.txt deleted file mode 100644 index ddd3e143a8..0000000000 Binary files a/core-java-modules/core-java/externalizable.txt and /dev/null differ diff --git a/core-java-modules/core-java/pom.xml b/core-java-modules/core-java/pom.xml deleted file mode 100644 index 87abe6c007..0000000000 --- a/core-java-modules/core-java/pom.xml +++ /dev/null @@ -1,199 +0,0 @@ - - - 4.0.0 - core-java - 0.1.0-SNAPSHOT - core-java - jar - - - com.baeldung.core-java-modules - core-java-modules - 0.0.1-SNAPSHOT - - - - - org.unix4j - unix4j-command - ${unix4j.version} - - - com.googlecode.grep4j - grep4j - ${grep4j.version} - - - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - - - log4j - log4j - ${log4j.version} - - - org.slf4j - log4j-over-slf4j - ${org.slf4j.version} - - - org.projectlombok - lombok - ${lombok.version} - provided - - - org.javamoney - moneta - ${javamoney.moneta.version} - - - org.springframework - spring-core - ${spring.core.version} - - - commons-io - commons-io - ${commons-io.version} - - - com.google.gdata - core - ${gdata.version} - - - - - core-java - - - src/main/resources - true - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - - - org.codehaus.mojo - exec-maven-plugin - - java - com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed - - -Xmx300m - -XX:+UseParallelGC - -classpath - - com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed - - - - - org.apache.maven.plugins - maven-javadoc-plugin - ${maven-javadoc-plugin.version} - - ${source.version} - ${target.version} - - - - - - - - integration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*ManualTest.java - - - **/*IntegrationTest.java - **/*IntTest.java - - - - - - - json - - - - - org.codehaus.mojo - exec-maven-plugin - - - run-benchmarks - - none - - exec - - - test - java - - -classpath - - org.openjdk.jmh.Main - .* - - - - - - - - - - - - - 0.4 - 1.8.7 - - 1.1 - 3.0.0-M1 - 1.8 - 1.8 - 4.3.20.RELEASE - 1.47.1 - - - \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/.gitignore b/core-java-modules/core-java/src/main/java/com/baeldung/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/core-java-modules/core-java/src/main/java/com/baeldung/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/executable/ExecutableMavenJar.java b/core-java-modules/core-java/src/main/java/com/baeldung/executable/ExecutableMavenJar.java deleted file mode 100644 index 6c79e89717..0000000000 --- a/core-java-modules/core-java/src/main/java/com/baeldung/executable/ExecutableMavenJar.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.baeldung.executable; - -import javax.swing.JOptionPane; - -public class ExecutableMavenJar { - - public static void main(String[] args) { - JOptionPane.showMessageDialog(null, "It worked!", "Executable Jar with Maven", 1); - } - -} diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/filesystem/jndi/LookupFSJNDI.java b/core-java-modules/core-java/src/main/java/com/baeldung/filesystem/jndi/LookupFSJNDI.java deleted file mode 100644 index 7e6bb5d3b2..0000000000 --- a/core-java-modules/core-java/src/main/java/com/baeldung/filesystem/jndi/LookupFSJNDI.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.baeldung.filesystem.jndi; - -import java.io.File; -import java.util.Hashtable; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; - -public class LookupFSJNDI { - private InitialContext ctx = null; - - public LookupFSJNDI() throws NamingException { - super(); - init(); - } - - private void init() throws NamingException { - Hashtable env = new Hashtable(); - - env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory"); - // URI to namespace (actual directory) - env.put(Context.PROVIDER_URL, "file:./src/test/resources"); - - ctx = new InitialContext(env); - } - - public InitialContext getCtx() { - return ctx; - } - - public File getFile(String fileName) { - File file; - try { - file = (File) getCtx().lookup(fileName); - } catch (NamingException e) { - file = null; - } - return file; - } - -} diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/jsonposturlconnection/PostJSONWithHttpURLConnection.java b/core-java-modules/core-java/src/main/java/com/baeldung/jsonposturlconnection/PostJSONWithHttpURLConnection.java deleted file mode 100644 index b2469ac984..0000000000 --- a/core-java-modules/core-java/src/main/java/com/baeldung/jsonposturlconnection/PostJSONWithHttpURLConnection.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.baeldung.jsonposturlconnection; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; - -public class PostJSONWithHttpURLConnection { - - public static void main (String []args) throws IOException{ - //Change the URL with any other publicly accessible POST resource, which accepts JSON request body - URL url = new URL ("https://reqres.in/api/users"); - - HttpURLConnection con = (HttpURLConnection)url.openConnection(); - con.setRequestMethod("POST"); - - con.setRequestProperty("Content-Type", "application/json; utf-8"); - con.setRequestProperty("Accept", "application/json"); - - con.setDoOutput(true); - - //JSON String need to be constructed for the specific resource. - //We may construct complex JSON using any third-party JSON libraries such as jackson or org.json - String jsonInputString = "{\"name\": \"Upendra\", \"job\": \"Programmer\"}"; - - try(OutputStream os = con.getOutputStream()){ - byte[] input = jsonInputString.getBytes("utf-8"); - os.write(input, 0, input.length); - } - - int code = con.getResponseCode(); - System.out.println(code); - - try(BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"))){ - StringBuilder response = new StringBuilder(); - String responseLine = null; - while ((responseLine = br.readLine()) != null) { - response.append(responseLine.trim()); - } - System.out.println(response.toString()); - } - } - -} diff --git a/core-java-modules/core-java/src/main/java/log4j.properties b/core-java-modules/core-java/src/main/java/log4j.properties deleted file mode 100644 index 5fe42d854c..0000000000 --- a/core-java-modules/core-java/src/main/java/log4j.properties +++ /dev/null @@ -1,9 +0,0 @@ -# Set root logger level to DEBUG and its only appender to A1. -log4j.rootLogger=DEBUG, A1 - -# A1 is set to be a ConsoleAppender. -log4j.appender.A1=org.apache.log4j.ConsoleAppender - -# A1 uses PatternLayout. -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n diff --git a/core-java-modules/core-java/src/main/resources/META-INF/MANIFEST.MF b/core-java-modules/core-java/src/main/resources/META-INF/MANIFEST.MF deleted file mode 100644 index 988de3193d..0000000000 --- a/core-java-modules/core-java/src/main/resources/META-INF/MANIFEST.MF +++ /dev/null @@ -1,5 +0,0 @@ -Agent-Class: com.baeldung.instrumentation.agent.MyInstrumentationAgent -Can-Redefine-Classes: true -Can-Retransform-Classes: true -Premain-Class: com.baeldung.instrumentation.agent.MyInstrumentationAgent -Main-Class: com.baeldung.instrumentation.application.Launcher diff --git a/core-java-modules/core-java/src/main/resources/META-INF/persistence.xml b/core-java-modules/core-java/src/main/resources/META-INF/persistence.xml deleted file mode 100644 index 3966afdcda..0000000000 --- a/core-java-modules/core-java/src/main/resources/META-INF/persistence.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/core-java-modules/core-java/src/main/resources/countries.properties b/core-java-modules/core-java/src/main/resources/countries.properties deleted file mode 100644 index 50b5e85653..0000000000 --- a/core-java-modules/core-java/src/main/resources/countries.properties +++ /dev/null @@ -1,3 +0,0 @@ -UK -US -Germany \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/resources/datasource.properties b/core-java-modules/core-java/src/main/resources/datasource.properties deleted file mode 100644 index 61df0d45f7..0000000000 --- a/core-java-modules/core-java/src/main/resources/datasource.properties +++ /dev/null @@ -1,6 +0,0 @@ -dataSourceClassName=//TBD -dataSource.user=//TBD -dataSource.password=//TBD -dataSource.databaseName=//TBD -dataSource.portNumber=//TBD -dataSource.serverName=//TBD \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/resources/log4j.properties b/core-java-modules/core-java/src/main/resources/log4j.properties deleted file mode 100644 index 621cf01735..0000000000 --- a/core-java-modules/core-java/src/main/resources/log4j.properties +++ /dev/null @@ -1,6 +0,0 @@ -log4j.rootLogger=DEBUG, A1 - -log4j.appender.A1=org.apache.log4j.ConsoleAppender - -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/resources/log4j2.xml b/core-java-modules/core-java/src/main/resources/log4j2.xml deleted file mode 100644 index a824bef9b0..0000000000 --- a/core-java-modules/core-java/src/main/resources/log4j2.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/resources/log4jstructuraldp.properties b/core-java-modules/core-java/src/main/resources/log4jstructuraldp.properties deleted file mode 100644 index 5bc2bfe4b9..0000000000 --- a/core-java-modules/core-java/src/main/resources/log4jstructuraldp.properties +++ /dev/null @@ -1,9 +0,0 @@ - -# Root logger -log4j.rootLogger=INFO, file, stdout - -# Write to console -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.Target=System.out -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/resources/product.png b/core-java-modules/core-java/src/main/resources/product.png deleted file mode 100644 index 4edd01c0a1..0000000000 Binary files a/core-java-modules/core-java/src/main/resources/product.png and /dev/null differ diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/arrays/ArraysJoinAndSplitJUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/arrays/ArraysJoinAndSplitJUnitTest.java deleted file mode 100644 index b31a829f34..0000000000 --- a/core-java-modules/core-java/src/test/java/com/baeldung/arrays/ArraysJoinAndSplitJUnitTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.baeldung.arrays; - -import java.util.Arrays; - -import org.junit.Assert; -import org.junit.Test; - -public class ArraysJoinAndSplitJUnitTest { - - private final String[] sauces = { "Marinara", "Olive Oil" }; - private final String[] cheeses = { "Mozzarella", "Feta", "Parmesan" }; - private final String[] vegetables = { "Olives", "Spinach", "Green Peppers" }; - - private final String[] customers = { "Jay", "Harry", "Ronnie", "Gary", "Ross" }; - - @Test - public void givenThreeStringArrays_whenJoiningIntoOneStringArray_shouldSucceed() { - String[] toppings = new String[sauces.length + cheeses.length + vegetables.length]; - - System.arraycopy(sauces, 0, toppings, 0, sauces.length); - int AddedSoFar = sauces.length; - - System.arraycopy(cheeses, 0, toppings, AddedSoFar, cheeses.length); - AddedSoFar += cheeses.length; - - System.arraycopy(vegetables, 0, toppings, AddedSoFar, vegetables.length); - - Assert.assertArrayEquals(toppings, new String[] { "Marinara", "Olive Oil", "Mozzarella", "Feta", "Parmesan", "Olives", "Spinach", "Green Peppers" }); - } - - @Test - public void givenOneStringArray_whenSplittingInHalfTwoStringArrays_shouldSucceed() { - int ordersHalved = (customers.length / 2) + (customers.length % 2); - - String[] driverOne = Arrays.copyOf(customers, ordersHalved); - String[] driverTwo = Arrays.copyOfRange(customers, ordersHalved, customers.length); - - Assert.assertArrayEquals(driverOne, new String[] { "Jay", "Harry", "Ronnie" }); - Assert.assertArrayEquals(driverTwo, new String[] { "Gary", "Ross" }); - } -} diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/stringisnumeric.zip b/core-java-modules/core-java/src/test/java/com/baeldung/stringisnumeric.zip deleted file mode 100644 index b8a7b9b35a..0000000000 Binary files a/core-java-modules/core-java/src/test/java/com/baeldung/stringisnumeric.zip and /dev/null differ diff --git a/core-java-modules/core-java/src/test/resources/.gitignore b/core-java-modules/core-java/src/test/resources/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/core-java-modules/core-java/src/test/resources/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/core-java-modules/core-java/src/test/resources/newFile3.txt b/core-java-modules/core-java/src/test/resources/newFile3.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/core-java-modules/core-java/src/test/resources/original.txt b/core-java-modules/core-java/src/test/resources/original.txt deleted file mode 100644 index 8511f56bef..0000000000 --- a/core-java-modules/core-java/src/test/resources/original.txt +++ /dev/null @@ -1,2 +0,0 @@ -#Copy a File with Java (www.Baeldung.com) -Copying Files with Java is Fun! \ No newline at end of file diff --git a/core-java-modules/core-java/src/test/resources/sourceFile.txt b/core-java-modules/core-java/src/test/resources/sourceFile.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/core-java-modules/core-java/src/test/resources/test.find b/core-java-modules/core-java/src/test/resources/test.find deleted file mode 100644 index 0cb7d51df1..0000000000 --- a/core-java-modules/core-java/src/test/resources/test.find +++ /dev/null @@ -1 +0,0 @@ -Test of JNDI on file. \ No newline at end of file diff --git a/core-java-modules/core-java/src/test/resources/test_read.in b/core-java-modules/core-java/src/test/resources/test_read.in deleted file mode 100644 index 70c379b63f..0000000000 --- a/core-java-modules/core-java/src/test/resources/test_read.in +++ /dev/null @@ -1 +0,0 @@ -Hello world \ No newline at end of file diff --git a/core-java-modules/core-java/src/test/resources/test_read1.in b/core-java-modules/core-java/src/test/resources/test_read1.in deleted file mode 100644 index 1e46242993..0000000000 --- a/core-java-modules/core-java/src/test/resources/test_read1.in +++ /dev/null @@ -1 +0,0 @@ -Hello world 1 \ No newline at end of file diff --git a/core-java-modules/core-java/src/test/resources/test_read2.in b/core-java-modules/core-java/src/test/resources/test_read2.in deleted file mode 100644 index fe47dc003b..0000000000 --- a/core-java-modules/core-java/src/test/resources/test_read2.in +++ /dev/null @@ -1 +0,0 @@ -2,3 4 \ No newline at end of file diff --git a/core-java-modules/core-java/src/test/resources/test_read3.in b/core-java-modules/core-java/src/test/resources/test_read3.in deleted file mode 100644 index db9f25a672..0000000000 --- a/core-java-modules/core-java/src/test/resources/test_read3.in +++ /dev/null @@ -1 +0,0 @@ -Hello 1 \ No newline at end of file diff --git a/core-java-modules/core-java/src/test/resources/test_read4.in b/core-java-modules/core-java/src/test/resources/test_read4.in deleted file mode 100644 index 5727d54bfc..0000000000 Binary files a/core-java-modules/core-java/src/test/resources/test_read4.in and /dev/null differ diff --git a/core-java-modules/core-java/src/test/resources/test_read7.in b/core-java-modules/core-java/src/test/resources/test_read7.in deleted file mode 100644 index 28d4d45d43..0000000000 --- a/core-java-modules/core-java/src/test/resources/test_read7.in +++ /dev/null @@ -1 +0,0 @@ -青空 \ No newline at end of file diff --git a/core-java-modules/core-java/src/test/resources/test_read8.in b/core-java-modules/core-java/src/test/resources/test_read8.in deleted file mode 100644 index 10fc1aac8a..0000000000 --- a/core-java-modules/core-java/src/test/resources/test_read8.in +++ /dev/null @@ -1,2 +0,0 @@ -Hello world - Test line diff --git a/core-java-modules/core-java/src/test/resources/test_read_d.in b/core-java-modules/core-java/src/test/resources/test_read_d.in deleted file mode 100644 index 82bbb4071f..0000000000 --- a/core-java-modules/core-java/src/test/resources/test_read_d.in +++ /dev/null @@ -1 +0,0 @@ -John,Adam-Tom \ No newline at end of file diff --git a/core-java-modules/core-java/src/test/resources/test_read_multiple.in b/core-java-modules/core-java/src/test/resources/test_read_multiple.in deleted file mode 100644 index 7d64000a76..0000000000 --- a/core-java-modules/core-java/src/test/resources/test_read_multiple.in +++ /dev/null @@ -1,2 +0,0 @@ -Hello world -Hi, John \ No newline at end of file diff --git a/core-java-modules/core-java/yofile.txt b/core-java-modules/core-java/yofile.txt deleted file mode 100644 index ad56bf35f7..0000000000 Binary files a/core-java-modules/core-java/yofile.txt and /dev/null differ diff --git a/core-java-modules/core-java/yofile2.txt b/core-java-modules/core-java/yofile2.txt deleted file mode 100644 index 8393b6e98b..0000000000 Binary files a/core-java-modules/core-java/yofile2.txt and /dev/null differ diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index f2db98dbfb..91f0dbfc28 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -16,9 +16,20 @@ - core-java - core-java-8 - core-java-8-2 + + + + + + + + + + + + + + core-java-annotations core-java-arrays-sorting core-java-arrays-guides @@ -26,6 +37,7 @@ core-java-arrays-convert core-java-arrays-operations-basic core-java-arrays-operations-advanced + core-java-booleans core-java-char core-java-collections core-java-collections-2 @@ -33,7 +45,6 @@ core-java-collections-4 core-java-collections-5 core-java-collections-conversions - core-java-collections-conversions-2 core-java-collections-set-2 core-java-collections-list core-java-collections-list-2 @@ -41,6 +52,7 @@ core-java-collections-maps core-java-collections-maps-2 core-java-collections-maps-3 + core-java-compiler core-java-concurrency-2 core-java-concurrency-advanced core-java-concurrency-advanced-2 @@ -52,11 +64,10 @@ core-java-concurrency-collections core-java-concurrency-collections-2 core-java-console - core-java-8-datetime-2 core-java-datetime-string-2 core-java-date-operations-2 core-java-date-operations-3 - core-java-8-datetime + core-java-documentation core-java-exceptions core-java-exceptions-2 core-java-exceptions-3 @@ -77,14 +88,12 @@ core-java-jvm-2 core-java-jvm-3 core-java-lambdas - core-java-lang core-java-lang-2 core-java-lang-3 core-java-lang-4 core-java-lang-5 core-java-lang-math core-java-lang-math-2 - core-java-lang-math-3 core-java-lang-oop-constructors core-java-lang-oop-patterns core-java-lang-oop-generics @@ -98,31 +107,27 @@ core-java-lang-operators-2 core-java-lang-syntax core-java-lang-syntax-2 + core-java-locale core-java-networking core-java-networking-2 core-java-networking-4 core-java-nio - core-java-nio-2 core-java-numbers core-java-numbers-2 core-java-numbers-3 core-java-numbers-4 core-java-numbers-5 - core-java-numbers-conversions + core-java-numbers-6 core-java-optional core-java-perf + core-java-properties core-java-reflection core-java-reflection-2 - core-java-security core-java-security-2 core-java-security-3 - core-java-serialization core-java-security-algorithms core-java-streams - core-java-streams-2 core-java-streams-3 - core-java-streams-maps - core-java-streams-collect core-java-string-algorithms core-java-string-algorithms-2 core-java-string-apis @@ -131,12 +136,12 @@ core-java-string-conversions-2 core-java-string-operations core-java-string-operations-2 - core-java-sun core-java-regex core-java-regex-2 core-java-uuid pre-jpms core-java-collections-maps-6 + core-java-records diff --git a/core-java-modules/pre-jpms/pom.xml b/core-java-modules/pre-jpms/pom.xml index cd4bd0faa3..67bc913767 100644 --- a/core-java-modules/pre-jpms/pom.xml +++ b/core-java-modules/pre-jpms/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 pre-jpms - 0.0.1-SNAPSHOT pre-jpms jar @@ -15,6 +14,11 @@ + + javax.xml.bind + jaxb-api + 2.4.0-b180725.0427 + org.slf4j slf4j-api @@ -32,6 +36,9 @@ ${source.version} ${target.version} + + --add-exports=java.base/com.sun.crypto.provider=ALL-UNNAMED + @@ -72,8 +79,8 @@ 3.1.1 3.8.0 - 1.8 - 1.8 + 11 + 11 \ No newline at end of file diff --git a/core-java-modules/pre-jpms/src/main/java/com/baeldung/prejpms/App.java b/core-java-modules/pre-jpms/src/main/java/com/baeldung/prejpms/App.java index 1afaae30e4..a69e0555c6 100644 --- a/core-java-modules/pre-jpms/src/main/java/com/baeldung/prejpms/App.java +++ b/core-java-modules/pre-jpms/src/main/java/com/baeldung/prejpms/App.java @@ -1,19 +1,18 @@ package com.baeldung.prejpms; import java.io.StringWriter; +import java.lang.StackWalker.Option; +import java.lang.StackWalker.StackFrame; +import com.sun.crypto.provider.SunJCE; +import java.util.Base64; +import java.util.concurrent.atomic.AtomicInteger; import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.sun.crypto.provider.SunJCE; - -import sun.misc.BASE64Encoder; -import sun.reflect.Reflection; - public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); @@ -37,14 +36,14 @@ public class App { private static void getCallStackClassNames() { try { StringBuffer sbStack = new StringBuffer(); - int i = 0; - Class caller = Reflection.getCallerClass(i++); - do { - sbStack.append(i + ".") - .append(caller.getName()) - .append("\n"); - caller = Reflection.getCallerClass(i++); - } while (caller != null); + AtomicInteger i = new AtomicInteger(0); + StackWalker.getInstance((Option.RETAIN_CLASS_REFERENCE)) + .walk(s -> s.map(StackFrame::getDeclaringClass) + .map(e -> { + i.getAndIncrement(); + return e.getName(); + })) + .forEach(name -> sbStack.append(String.format("%d. %s \n", i.get(), name))); LOGGER.info("2. Call Stack:\n{}", sbStack); } catch (Throwable e) { LOGGER.error(e.toString()); @@ -54,7 +53,7 @@ public class App { private static void getXmlFromObject(Book book) { try { Marshaller marshallerObj = JAXBContext.newInstance(Book.class) - .createMarshaller(); + .createMarshaller(); marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); StringWriter sw = new StringWriter(); @@ -68,7 +67,8 @@ public class App { private static void getBase64EncodedString(String inputString) { try { - String encodedString = new BASE64Encoder().encode(inputString.getBytes()); + String encodedString = new String(Base64.getEncoder() + .encode(inputString.getBytes())); LOGGER.info("4. Base Encoded String: {}", encodedString); } catch (Throwable e) { LOGGER.error(e.toString()); diff --git a/couchbase/pom.xml b/couchbase/pom.xml index 095bda3610..823b33ee29 100644 --- a/couchbase/pom.xml +++ b/couchbase/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 couchbase - 0.1-SNAPSHOT couchbase jar Couchbase Tutorials diff --git a/custom-pmd/pom.xml b/custom-pmd/pom.xml index 38a5e30404..8097d4fefa 100644 --- a/custom-pmd/pom.xml +++ b/custom-pmd/pom.xml @@ -8,7 +8,6 @@ 0.0.1 custom-pmd jar - http://maven.apache.org com.baeldung diff --git a/data-structures/pom.xml b/data-structures/pom.xml index cba602878f..aeadfcefc3 100644 --- a/data-structures/pom.xml +++ b/data-structures/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 data-structures - 0.0.1-SNAPSHOT data-structures @@ -13,13 +12,6 @@ 1.0.0-SNAPSHOT - - - github.release.repo - https://raw.github.com/bulldog2011/bulldog-repo/master/repo/releases/ - - - com.leansoft @@ -39,6 +31,13 @@ + + + github.release.repo + https://raw.github.com/bulldog2011/bulldog-repo/master/repo/releases/ + + + 0.7.0 diff --git a/ddd/pom.xml b/ddd/pom.xml index 6128bb1cd9..443b2b5148 100644 --- a/ddd/pom.xml +++ b/ddd/pom.xml @@ -3,7 +3,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung.ddd ddd ddd jar diff --git a/deeplearning4j/pom.xml b/deeplearning4j/pom.xml index 01bac93214..875d8cdf85 100644 --- a/deeplearning4j/pom.xml +++ b/deeplearning4j/pom.xml @@ -3,9 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - com.baeldung.deeplearning4j deeplearning4j - 1.0-SNAPSHOT deeplearning4j jar diff --git a/dependency-exclusion/core-java-exclusions/pom.xml b/dependency-exclusion/core-java-exclusions/pom.xml deleted file mode 100644 index cf1b36656d..0000000000 --- a/dependency-exclusion/core-java-exclusions/pom.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - 4.0.0 - core-java-exclusions - 0.0.0-SNAPSHOT - core-java-exclusions - jar - - - com.baeldung.dependency-exclusion - dependency-exclusion - 0.0.1-SNAPSHOT - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${surefire-version} - - alphabetical - 1 - - - junit - false - - - - - - - org.apache.maven.surefire - surefire-junit47 - dummy - - - - - - - - - junit - junit - test - - - - diff --git a/dependency-exclusion/dummy-surefire-junit47/pom.xml b/dependency-exclusion/dummy-surefire-junit47/pom.xml deleted file mode 100644 index 5859ddbe72..0000000000 --- a/dependency-exclusion/dummy-surefire-junit47/pom.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - 4.0.0 - org.apache.maven.surefire - surefire-junit47 - dummy - diff --git a/dependeny-exclusion/core-java-exclusions/src/test/java/com/sample/project/tests/ExcludeDirectDependencyUnitTest.java b/dependeny-exclusion/core-java-exclusions/src/test/java/com/sample/project/tests/ExcludeDirectDependencyUnitTest.java deleted file mode 100644 index ed2400f9ac..0000000000 --- a/dependeny-exclusion/core-java-exclusions/src/test/java/com/sample/project/tests/ExcludeDirectDependencyUnitTest.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.sample.project.tests; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -public class ExcludeDirectDependencyUnitTest { - @Test - public void basicUnitTest() { - assertTrue(true); - } -} diff --git a/dependeny-exclusion/dummy-surefire-junit47/pom.xml b/dependeny-exclusion/dummy-surefire-junit47/pom.xml deleted file mode 100644 index 5859ddbe72..0000000000 --- a/dependeny-exclusion/dummy-surefire-junit47/pom.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - 4.0.0 - org.apache.maven.surefire - surefire-junit47 - dummy - diff --git a/dependeny-exclusion/pom.xml b/dependeny-exclusion/pom.xml deleted file mode 100644 index ac83cc161a..0000000000 --- a/dependeny-exclusion/pom.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - 4.0.0 - com.baeldung.dependency-exclusion - dependency-exclusion - dependency-exclusion - pom - - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../parent-java - - - - 2.22.2 - - - - dummy-surefire-junit47 - core-java-exclusions - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.7.0 - - 1.8 - 1.8 - - -parameters - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${surefire-version} - - 1 - - - - org.apache.maven.surefire - surefire-junit-platform - ${surefire-version} - - - - - - - - - - - junit - junit - 4.13 - - - - - diff --git a/di-modules/guice/pom.xml b/di-modules/guice/pom.xml index a28dbe5297..d0d2876fc8 100644 --- a/di-modules/guice/pom.xml +++ b/di-modules/guice/pom.xml @@ -3,7 +3,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung.examples.guice guice guice jar diff --git a/disruptor/pom.xml b/disruptor/pom.xml index c2f9cf34b0..75e783e935 100644 --- a/disruptor/pom.xml +++ b/disruptor/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 disruptor - 0.1.0-SNAPSHOT disruptor jar diff --git a/docker-modules/docker-caching/multi-module-caching/core/pom.xml b/docker-modules/docker-caching/multi-module-caching/core-module/pom.xml similarity index 93% rename from docker-modules/docker-caching/multi-module-caching/core/pom.xml rename to docker-modules/docker-caching/multi-module-caching/core-module/pom.xml index bcfc4b5783..159d76830b 100644 --- a/docker-modules/docker-caching/multi-module-caching/core/pom.xml +++ b/docker-modules/docker-caching/multi-module-caching/core-module/pom.xml @@ -3,7 +3,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 + core-module multi-module-caching diff --git a/docker-modules/docker-caching/multi-module-caching/core/src/main/java/com/baeldung/maven_caching/CoreClass.java b/docker-modules/docker-caching/multi-module-caching/core-module/src/main/java/com/baeldung/maven_caching/CoreClass.java similarity index 100% rename from docker-modules/docker-caching/multi-module-caching/core/src/main/java/com/baeldung/maven_caching/CoreClass.java rename to docker-modules/docker-caching/multi-module-caching/core-module/src/main/java/com/baeldung/maven_caching/CoreClass.java diff --git a/docker-modules/docker-caching/multi-module-caching/pom.xml b/docker-modules/docker-caching/multi-module-caching/pom.xml index 94a370453c..b64cf1a8b8 100644 --- a/docker-modules/docker-caching/multi-module-caching/pom.xml +++ b/docker-modules/docker-caching/multi-module-caching/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung multi-module-caching @@ -10,8 +10,8 @@ pom - runner - core + runner-module + core-module diff --git a/docker-modules/docker-caching/multi-module-caching/runner/pom.xml b/docker-modules/docker-caching/multi-module-caching/runner-module/pom.xml similarity index 94% rename from docker-modules/docker-caching/multi-module-caching/runner/pom.xml rename to docker-modules/docker-caching/multi-module-caching/runner-module/pom.xml index e3f234bac0..e608706864 100644 --- a/docker-modules/docker-caching/multi-module-caching/runner/pom.xml +++ b/docker-modules/docker-caching/multi-module-caching/runner-module/pom.xml @@ -3,7 +3,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 + runner-module multi-module-caching @@ -14,7 +14,7 @@ com.baeldung - core + core-module 0.0.1-SNAPSHOT diff --git a/docker-modules/docker-caching/multi-module-caching/runner/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java b/docker-modules/docker-caching/multi-module-caching/runner-module/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java similarity index 100% rename from docker-modules/docker-caching/multi-module-caching/runner/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java rename to docker-modules/docker-caching/multi-module-caching/runner-module/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java diff --git a/docker-modules/docker-caching/single-module-caching/pom.xml b/docker-modules/docker-caching/single-module-caching/pom.xml index 4a4e53f1d3..a388c7563f 100644 --- a/docker-modules/docker-caching/single-module-caching/pom.xml +++ b/docker-modules/docker-caching/single-module-caching/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 com.baeldung single-module-caching diff --git a/docker-modules/docker-compose-2/pom.xml b/docker-modules/docker-compose-2/pom.xml index 851742309d..3a94ee3901 100644 --- a/docker-modules/docker-compose-2/pom.xml +++ b/docker-modules/docker-compose-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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 docker-compose-2 Demo project for Spring Boot and Docker - Module docker-compose-2 diff --git a/docker-modules/docker-containers/pom.xml b/docker-modules/docker-containers/pom.xml index 42c2d403e4..79bf0aee72 100644 --- a/docker-modules/docker-containers/pom.xml +++ b/docker-modules/docker-containers/pom.xml @@ -5,7 +5,6 @@ 4.0.0 com.baeldung.docker docker-containers - 0.0.1-SNAPSHOT Demo project for Spring Boot diff --git a/docker-modules/pom.xml b/docker-modules/pom.xml index 1a87fa5d1c..b4c5240718 100644 --- a/docker-modules/pom.xml +++ b/docker-modules/pom.xml @@ -3,9 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung docker-modules - 1.0.0-SNAPSHOT docker-modules pom diff --git a/dozer/pom.xml b/dozer/pom.xml index 840763445c..66f4ee8227 100644 --- a/dozer/pom.xml +++ b/dozer/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 dozer - 1.0 dozer diff --git a/ethereum/pom.xml b/ethereum/pom.xml index 6c1a0e900f..8dc25427d9 100644 --- a/ethereum/pom.xml +++ b/ethereum/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 com.baeldung.ethereum ethereum @@ -113,7 +113,8 @@ test ${spring.boot.version} - + junit junit @@ -195,4 +196,5 @@ 2.0.4.RELEASE 3.1 + \ No newline at end of file diff --git a/feign/README.md b/feign/README.md index 3e733448fb..074ce1cbd2 100644 --- a/feign/README.md +++ b/feign/README.md @@ -6,10 +6,4 @@ This module contains articles about Feign - [Intro to Feign](https://www.baeldung.com/intro-to-feign) - [Retrying Feign Calls](https://www.baeldung.com/feign-retry) -- [Setting Request Headers Using Feign](https://www.baeldung.com/java-feign-request-headers) -- [File Upload With Open Feign](https://www.baeldung.com/java-feign-file-upload) -- [Feign Logging Configuration](https://www.baeldung.com/java-feign-logging) -- [Retrieve Original Message From Feign ErrorDecoder](https://www.baeldung.com/feign-retrieve-original-message) -- [RequestLine with Feign Client](https://www.baeldung.com/feign-requestline) -- [Propagating Exceptions With OpenFeign and Spring](https://www.baeldung.com/spring-openfeign-propagate-exception) -- [Post form-url-encoded Data with Spring Cloud Feign](https://www.baeldung.com/spring-cloud-post-form-url-encoded-data) +- [Setting Request Headers Using Feign](https://www.baeldung.com/java-feign-request-headers) \ No newline at end of file diff --git a/feign/pom.xml b/feign/pom.xml index f39adec607..edb55e7da5 100644 --- a/feign/pom.xml +++ b/feign/pom.xml @@ -3,7 +3,6 @@ xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung.feign feign feign @@ -69,11 +68,6 @@ feign-form-spring ${feign.form.spring.version} - - org.springframework.cloud - spring-cloud-starter-openfeign - ${spring.cloud.openfeign.version} - com.github.tomakehurst wiremock-jre8 diff --git a/feign/src/main/java/com/baeldung/core/ExampleApplication.java b/feign/src/main/java/com/baeldung/core/ExampleApplication.java index 391e808ede..881265d5ba 100644 --- a/feign/src/main/java/com/baeldung/core/ExampleApplication.java +++ b/feign/src/main/java/com/baeldung/core/ExampleApplication.java @@ -2,10 +2,8 @@ package com.baeldung.core; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication -@EnableFeignClients public class ExampleApplication { public static void main(String[] args) { diff --git a/feign/src/main/java/com/baeldung/core/fileupload/config/ExceptionMessage.java b/feign/src/main/java/com/baeldung/core/fileupload/config/ExceptionMessage.java deleted file mode 100644 index 8301705ca6..0000000000 --- a/feign/src/main/java/com/baeldung/core/fileupload/config/ExceptionMessage.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.baeldung.core.fileupload.config; - -public class ExceptionMessage { - private String timestamp; - private int status; - private String error; - private String message; - private String path; - - public String getTimestamp() { - return timestamp; - } - - public void setTimestamp(String timestamp) { - this.timestamp = timestamp; - } - - public int getStatus() { - return status; - } - - public void setStatus(int status) { - this.status = status; - } - - public String getError() { - return error; - } - - public void setError(String error) { - this.error = error; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - @Override - public String toString() { - return "ExceptionMessage [timestamp=" + timestamp + ", status=" + status + ", error=" + error + ", message=" + message + ", path=" + path + "]"; - } - -} diff --git a/feign/src/main/java/com/baeldung/core/fileupload/config/FeignSupportConfig.java b/feign/src/main/java/com/baeldung/core/fileupload/config/FeignSupportConfig.java deleted file mode 100644 index c8c9eb1acc..0000000000 --- a/feign/src/main/java/com/baeldung/core/fileupload/config/FeignSupportConfig.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.baeldung.core.fileupload.config; - -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.cloud.openfeign.support.SpringEncoder; -import org.springframework.context.annotation.Bean; -import org.springframework.web.client.RestTemplate; - -import feign.codec.Encoder; -import feign.codec.ErrorDecoder; -import feign.form.spring.SpringFormEncoder; - -public class FeignSupportConfig { - @Bean - public Encoder multipartFormEncoder() { - return new SpringFormEncoder(new SpringEncoder(() -> new HttpMessageConverters(new RestTemplate().getMessageConverters()))); - } - - @Bean - public ErrorDecoder errorDecoder() { - return new RetreiveMessageErrorDecoder(); - } -} diff --git a/feign/src/main/java/com/baeldung/core/fileupload/config/RetreiveMessageErrorDecoder.java b/feign/src/main/java/com/baeldung/core/fileupload/config/RetreiveMessageErrorDecoder.java deleted file mode 100644 index fc2c8da0ed..0000000000 --- a/feign/src/main/java/com/baeldung/core/fileupload/config/RetreiveMessageErrorDecoder.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.baeldung.core.fileupload.config; - -import java.io.IOException; -import java.io.InputStream; - -import com.baeldung.core.exception.BadRequestException; -import com.baeldung.core.exception.NotFoundException; -import com.fasterxml.jackson.databind.ObjectMapper; - -import feign.Response; -import feign.codec.ErrorDecoder; - -public class RetreiveMessageErrorDecoder implements ErrorDecoder { - private final ErrorDecoder errorDecoder = new Default(); - - @Override - public Exception decode(String methodKey, Response response) { - ExceptionMessage message; - try (InputStream bodyIs = response.body() - .asInputStream()) { - ObjectMapper mapper = new ObjectMapper(); - message = mapper.readValue(bodyIs, ExceptionMessage.class); - } catch (IOException e) { - return new Exception(e.getMessage()); - } - switch (response.status()) { - case 400: - return new BadRequestException(message.getMessage() != null ? message.getMessage() : "Bad Request"); - case 404: - return new NotFoundException(message.getMessage() != null ? message.getMessage() : "Not found"); - default: - return errorDecoder.decode(methodKey, response); - } - } -} diff --git a/feign/src/main/java/com/baeldung/core/fileupload/service/UploadResource.java b/feign/src/main/java/com/baeldung/core/fileupload/service/UploadResource.java deleted file mode 100644 index 9d3d173cd4..0000000000 --- a/feign/src/main/java/com/baeldung/core/fileupload/service/UploadResource.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.baeldung.core.fileupload.service; - -import org.springframework.web.multipart.MultipartFile; - -import feign.Headers; -import feign.Param; -import feign.RequestLine; -import feign.Response; - -public interface UploadResource { - - @RequestLine("POST /upload-file") - @Headers("Content-Type: multipart/form-data") - Response uploadFile(@Param("file") MultipartFile file); - -} \ No newline at end of file diff --git a/feign/src/main/java/com/baeldung/core/fileupload/service/UploadService.java b/feign/src/main/java/com/baeldung/core/fileupload/service/UploadService.java deleted file mode 100644 index 5176ddf0fa..0000000000 --- a/feign/src/main/java/com/baeldung/core/fileupload/service/UploadService.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.baeldung.core.fileupload.service; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - -import feign.Feign; -import feign.Response; -import feign.form.spring.SpringFormEncoder; - -@Service -public class UploadService { - private static final String HTTP_FILE_UPLOAD_URL = "http://localhost:8081"; - - @Autowired - private UploadClient client; - - public boolean uploadFileWithManualClient(MultipartFile file) { - UploadResource fileUploadResource = Feign.builder().encoder(new SpringFormEncoder()) - .target(UploadResource.class, HTTP_FILE_UPLOAD_URL); - Response response = fileUploadResource.uploadFile(file); - return response.status() == 200; - } - - public String uploadFile(MultipartFile file) { - return client.fileUpload(file); - } - - public String uploadFileError(MultipartFile file) { - return client.fileUpload(file); - } -} \ No newline at end of file diff --git a/feign/src/test/java/com/baeldung/core/OpenFeignFileUploadLiveTest.java b/feign/src/test/java/com/baeldung/core/OpenFeignFileUploadLiveTest.java deleted file mode 100644 index f9dc8b13ed..0000000000 --- a/feign/src/test/java/com/baeldung/core/OpenFeignFileUploadLiveTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.baeldung.core; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; -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.mock.web.MockMultipartFile; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.multipart.MultipartFile; - -import com.baeldung.core.fileupload.service.UploadService; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = ExampleApplication.class) -public class OpenFeignFileUploadLiveTest { - - @Autowired - private UploadService uploadService; - - private static String FILE_NAME = "fileupload.txt"; - - @Test - public void whenFeignBuilder_thenFileUploadSuccess() throws IOException { - ClassLoader classloader = Thread.currentThread().getContextClassLoader(); - File file = new File(classloader.getResource(FILE_NAME).getFile()); - Assert.assertTrue(file.exists()); - FileInputStream input = new FileInputStream(file); - MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", - IOUtils.toByteArray(input)); - Assert.assertTrue(uploadService.uploadFileWithManualClient(multipartFile)); - } - - @Test - public void whenAnnotatedFeignClient_thenFileUploadSuccess() throws IOException { - ClassLoader classloader = Thread.currentThread().getContextClassLoader(); - File file = new File(classloader.getResource(FILE_NAME).getFile()); - Assert.assertTrue(file.exists()); - FileInputStream input = new FileInputStream(file); - MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", - IOUtils.toByteArray(input)); - String uploadFile = uploadService.uploadFile(multipartFile); - Assert.assertNotNull(uploadFile); - } -} diff --git a/gcp-firebase/pom.xml b/gcp-firebase/pom.xml index c563099ad6..10a899f370 100644 --- a/gcp-firebase/pom.xml +++ b/gcp-firebase/pom.xml @@ -1,48 +1,51 @@ - - 4.0.0 + + 4.0.0 + gcp-firebase + com.baeldung parent-boot-2 0.0.1-SNAPSHOT ../parent-boot-2 - gcp-firebase - - - 9.1.1 - - - - com.google.firebase - firebase-admin - ${firebase-admin.version} - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + + com.google.firebase + firebase-admin + ${firebase-admin.version} + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + 9.1.1 + + \ No newline at end of file diff --git a/gcp-firebase/src/main/resources/firebase-service-account.json b/gcp-firebase/src/main/resources/firebase-service-account.json index ed5afa9f13..cd87ff6bda 100644 --- a/gcp-firebase/src/main/resources/firebase-service-account.json +++ b/gcp-firebase/src/main/resources/firebase-service-account.json @@ -1,10 +1,10 @@ { "type": "service_account", - "project_id": "tutorials-2cdfb", - "private_key_id": "d9f6a684d6814f85ed2d0490585eb7bf590f983a", - "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDdJWTeGT2eBFo+\nXxzT9xFJYPtyawTAj0K1rVUNlWNUwj3zszK6P2sAsrpI2Rz1klwQ9aDz9i3+Opxv\n7UZ3pOzur6S58JnoswtNs6BZ9P7oeggLJJC6MPjioxwh8jLLIGMgdVtC2/iPYW3r\nGzurWlwkM8M8DyCgNq7KKJcx44pGcyy16ZGCYiijuTEmK6R+WHJTTyICzRFu3Org\nuHGlZUs/G4E76p10HanoFX2AIS/fDEEMP2DXBB73yoCal5GuvMY9yZWxnvV65Y5z\nGveY3NDB9EESbO2AAhDvHekWT17uWhymtO5N3gM8da48J9d51tVzi0D/NIPZnF0u\nTS64uxK3AgMBAAECggEAYuEQa7oPcfLyQscWRbRH1250n2E4e7zSkBcTW4J7Km+7\ncZajTOGEP4iqgF4Lc8XgQnkBYXOmdvDP97+47VAh3EtOtRDeUEyV9kUlonNH8rx1\nkj3kNEwnTHav4oG/slEl4WJ3zro6NinTEvdXQ7OgVVOLrPP6m4g3uQ5TJCxgLEUI\nTd3Hs3cg3P71mzEqfBF4NmGVmC1ea5lXFELd6giJJMvL7g+O2w22/fquGWOrreAM\ncj/G2Xv9/vmzeb9yzbgGxqCJyY6vspmd90fQLUu7bxkEY5/PPc6Zk8qay4AdEn47\nkL6hnJiR8H1wMCzV2RTUKE7ospriNVdBilXgxm9IMQKBgQD1TmF0Bg85zvXmEKBa\nLBhbc3xTtM7DOgKs+pI12sYDKwgL/QKEI/TKkYXua0aVGiQWc2Bk2/0sYhO6aB2f\n6AN1ZUrf4PRM8c53jebChc7beVLSjWI8Tx+kE+0t8864OwvELYZUzP35oSx3RdJD\nE/CvqBM7NQfJwx2Mw2VJK/YRGQKBgQDmyWLm/IWitehkITw6xMQpkkFs2m4Joq3A\nJvAyri58TRkw/7rqWaIxb5Wcy/7BOvjDN8PZNTHh4ZvhQiHpn7NGUks2/ULnWxUB\nWAA9YbeO9PNHJfZ6PjD2FSvwOXHj+vVkWt2GCXT8pDGYM2ImqXon85Oe3OH/h+N5\nktO9taesTwKBgQCSdPGKK/P7N61oZpTWQW1pbFHWSCUKOiBO1mtk6/E9AvwS7EQM\nUMteBfRInJPPgYP6Q3hRv2YwkX3l1TOavRMTjB5f/BbfuZ7jkj0r9mfCcXUZcIAu\nMa9abus0fFP3eolT3zpMdvdLiwbZTz5x/f29YkPZHZhAxdVmrWJThYOsQQKBgBDu\nZVsc25D8V3hBF/IXzWxfVn1t6PS8ApM+SBDvxmlIHrkBiez3dna6APfn32C9utJX\nnP6qcGZp7s2v1F0XYkeecfYuzmG6xOe8VQgryxOp1M87ccG2HlFvbDHLhRd8qdQa\n9nWG7BY81Yac/m5nsJaNwB6/hbUBeybIJtCcKxjxAoGBAJ3y+QSFb4AYmxLFtmMA\nklOvlT+r70w4RV/z4SEO1gjWEh9IozNSXknl5Q/8Zh9IVm3+/qYap//IzEv9JUc3\nv4+HlpZu0trxTpvRWWjPqVr3ssxRdiFLC0LCLEk4rzqWLBVyzJm8uHVIF9Inv8PE\naudInvdbnfAWi60+1Wi8u0Co\n-----END PRIVATE KEY-----\n", - "client_email": "firebase-adminsdk-2afzd@tutorials-2cdfb.iam.gserviceaccount.com", - "client_id": "111111112074248894669", + "project_id": "REPLACE WITH VALID PROJECT ID", + "private_key_id": "REPLACE WITH VALID PRIVATE KEY ID", + "private_key": "REPLACE WITH VALID PRIVATE KEY", + "client_email": "REPLACE WITH VALID CLIENT EMAIL", + "client_id": "REPLACE WITH VALID CLIENT ID", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", diff --git a/geotools/pom.xml b/geotools/pom.xml index f17b4cc5da..61682ae0f5 100644 --- a/geotools/pom.xml +++ b/geotools/pom.xml @@ -4,10 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 geotools - 0.0.1-SNAPSHOT geotools jar - http://maven.apache.org com.baeldung @@ -15,14 +13,6 @@ 1.0.0-SNAPSHOT - - - osgeo-release - OSGeo Repository - https://repo.osgeo.org/repository/release/ - - - org.geotools @@ -41,6 +31,14 @@ + + + osgeo-release + OSGeo Repository + https://repo.osgeo.org/repository/release/ + + + 28.1 28.1 diff --git a/code-generation/README.md b/google-auto-project/README.md similarity index 100% rename from code-generation/README.md rename to google-auto-project/README.md diff --git a/code-generation/pom.xml b/google-auto-project/pom.xml similarity index 95% rename from code-generation/pom.xml rename to google-auto-project/pom.xml index ed8890e1dd..839ccabc5f 100644 --- a/code-generation/pom.xml +++ b/google-auto-project/pom.xml @@ -3,9 +3,9 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - code-generation + google-auto-project 1.0 - code-generation + google-auto-project com.baeldung diff --git a/code-generation/src/main/java/com/baeldung/autofactory/App.java b/google-auto-project/src/main/java/com/baeldung/autofactory/App.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autofactory/App.java rename to google-auto-project/src/main/java/com/baeldung/autofactory/App.java diff --git a/code-generation/src/main/java/com/baeldung/autofactory/CustomStorage.java b/google-auto-project/src/main/java/com/baeldung/autofactory/CustomStorage.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autofactory/CustomStorage.java rename to google-auto-project/src/main/java/com/baeldung/autofactory/CustomStorage.java diff --git a/code-generation/src/main/java/com/baeldung/autofactory/custom/AbstractFactory.java b/google-auto-project/src/main/java/com/baeldung/autofactory/custom/AbstractFactory.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autofactory/custom/AbstractFactory.java rename to google-auto-project/src/main/java/com/baeldung/autofactory/custom/AbstractFactory.java diff --git a/code-generation/src/main/java/com/baeldung/autofactory/custom/CustomPhone.java b/google-auto-project/src/main/java/com/baeldung/autofactory/custom/CustomPhone.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autofactory/custom/CustomPhone.java rename to google-auto-project/src/main/java/com/baeldung/autofactory/custom/CustomPhone.java diff --git a/code-generation/src/main/java/com/baeldung/autofactory/custom/SmartPhone.java b/google-auto-project/src/main/java/com/baeldung/autofactory/custom/SmartPhone.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autofactory/custom/SmartPhone.java rename to google-auto-project/src/main/java/com/baeldung/autofactory/custom/SmartPhone.java diff --git a/code-generation/src/main/java/com/baeldung/autofactory/model/Camera.java b/google-auto-project/src/main/java/com/baeldung/autofactory/model/Camera.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autofactory/model/Camera.java rename to google-auto-project/src/main/java/com/baeldung/autofactory/model/Camera.java diff --git a/code-generation/src/main/java/com/baeldung/autofactory/model/ClassicPhone.java b/google-auto-project/src/main/java/com/baeldung/autofactory/model/ClassicPhone.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autofactory/model/ClassicPhone.java rename to google-auto-project/src/main/java/com/baeldung/autofactory/model/ClassicPhone.java diff --git a/code-generation/src/main/java/com/baeldung/autofactory/model/Phone.java b/google-auto-project/src/main/java/com/baeldung/autofactory/model/Phone.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autofactory/model/Phone.java rename to google-auto-project/src/main/java/com/baeldung/autofactory/model/Phone.java diff --git a/code-generation/src/main/java/com/baeldung/autofactory/modules/SonyCameraModule.java b/google-auto-project/src/main/java/com/baeldung/autofactory/modules/SonyCameraModule.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autofactory/modules/SonyCameraModule.java rename to google-auto-project/src/main/java/com/baeldung/autofactory/modules/SonyCameraModule.java diff --git a/code-generation/src/main/java/com/baeldung/autofactory/provided/IntermediateAssembler.java b/google-auto-project/src/main/java/com/baeldung/autofactory/provided/IntermediateAssembler.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autofactory/provided/IntermediateAssembler.java rename to google-auto-project/src/main/java/com/baeldung/autofactory/provided/IntermediateAssembler.java diff --git a/code-generation/src/main/java/com/baeldung/autofactory/provider/SonyCameraProvider.java b/google-auto-project/src/main/java/com/baeldung/autofactory/provider/SonyCameraProvider.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autofactory/provider/SonyCameraProvider.java rename to google-auto-project/src/main/java/com/baeldung/autofactory/provider/SonyCameraProvider.java diff --git a/code-generation/src/main/java/com/baeldung/autoservice/BingTranslationServiceProvider.java b/google-auto-project/src/main/java/com/baeldung/autoservice/BingTranslationServiceProvider.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autoservice/BingTranslationServiceProvider.java rename to google-auto-project/src/main/java/com/baeldung/autoservice/BingTranslationServiceProvider.java diff --git a/code-generation/src/main/java/com/baeldung/autoservice/GoogleTranslationServiceProvider.java b/google-auto-project/src/main/java/com/baeldung/autoservice/GoogleTranslationServiceProvider.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autoservice/GoogleTranslationServiceProvider.java rename to google-auto-project/src/main/java/com/baeldung/autoservice/GoogleTranslationServiceProvider.java diff --git a/code-generation/src/main/java/com/baeldung/autoservice/TranslationService.java b/google-auto-project/src/main/java/com/baeldung/autoservice/TranslationService.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autoservice/TranslationService.java rename to google-auto-project/src/main/java/com/baeldung/autoservice/TranslationService.java diff --git a/code-generation/src/main/java/com/baeldung/autovalue/AutoValueMoney.java b/google-auto-project/src/main/java/com/baeldung/autovalue/AutoValueMoney.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autovalue/AutoValueMoney.java rename to google-auto-project/src/main/java/com/baeldung/autovalue/AutoValueMoney.java diff --git a/code-generation/src/main/java/com/baeldung/autovalue/AutoValueMoneyWithBuilder.java b/google-auto-project/src/main/java/com/baeldung/autovalue/AutoValueMoneyWithBuilder.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autovalue/AutoValueMoneyWithBuilder.java rename to google-auto-project/src/main/java/com/baeldung/autovalue/AutoValueMoneyWithBuilder.java diff --git a/code-generation/src/main/java/com/baeldung/autovalue/Foo.java b/google-auto-project/src/main/java/com/baeldung/autovalue/Foo.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autovalue/Foo.java rename to google-auto-project/src/main/java/com/baeldung/autovalue/Foo.java diff --git a/code-generation/src/main/java/com/baeldung/autovalue/ImmutableMoney.java b/google-auto-project/src/main/java/com/baeldung/autovalue/ImmutableMoney.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autovalue/ImmutableMoney.java rename to google-auto-project/src/main/java/com/baeldung/autovalue/ImmutableMoney.java diff --git a/code-generation/src/main/java/com/baeldung/autovalue/MutableMoney.java b/google-auto-project/src/main/java/com/baeldung/autovalue/MutableMoney.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autovalue/MutableMoney.java rename to google-auto-project/src/main/java/com/baeldung/autovalue/MutableMoney.java diff --git a/code-generation/src/main/java/com/baeldung/autovalue/Person.java b/google-auto-project/src/main/java/com/baeldung/autovalue/Person.java similarity index 100% rename from code-generation/src/main/java/com/baeldung/autovalue/Person.java rename to google-auto-project/src/main/java/com/baeldung/autovalue/Person.java diff --git a/code-generation/src/main/resources/logback.xml b/google-auto-project/src/main/resources/logback.xml similarity index 100% rename from code-generation/src/main/resources/logback.xml rename to google-auto-project/src/main/resources/logback.xml diff --git a/code-generation/src/test/java/com/baeldung/autoservice/TranslationServiceUnitTest.java b/google-auto-project/src/test/java/com/baeldung/autoservice/TranslationServiceUnitTest.java similarity index 100% rename from code-generation/src/test/java/com/baeldung/autoservice/TranslationServiceUnitTest.java rename to google-auto-project/src/test/java/com/baeldung/autoservice/TranslationServiceUnitTest.java diff --git a/code-generation/src/test/java/com/baeldung/autovalue/MoneyUnitTest.java b/google-auto-project/src/test/java/com/baeldung/autovalue/MoneyUnitTest.java similarity index 100% rename from code-generation/src/test/java/com/baeldung/autovalue/MoneyUnitTest.java rename to google-auto-project/src/test/java/com/baeldung/autovalue/MoneyUnitTest.java diff --git a/code-generation/src/test/java/com/baeldung/autovalue/PersonUnitTest.java b/google-auto-project/src/test/java/com/baeldung/autovalue/PersonUnitTest.java similarity index 100% rename from code-generation/src/test/java/com/baeldung/autovalue/PersonUnitTest.java rename to google-auto-project/src/test/java/com/baeldung/autovalue/PersonUnitTest.java diff --git a/google-cloud/pom.xml b/google-cloud/pom.xml index 72b9647bc8..8bb535f12a 100644 --- a/google-cloud/pom.xml +++ b/google-cloud/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 google-cloud - 0.1-SNAPSHOT google-cloud jar Google Cloud Tutorials @@ -24,7 +23,6 @@ org.projectlombok lombok - ${lombok.version} provided diff --git a/gradle-modules/gradle-7/dependency-version/.gitattributes b/gradle-modules/gradle-7/dependency-version/.gitattributes new file mode 100644 index 0000000000..097f9f98d9 --- /dev/null +++ b/gradle-modules/gradle-7/dependency-version/.gitattributes @@ -0,0 +1,9 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# Linux start script should use lf +/gradlew text eol=lf + +# These are Windows script files and should use crlf +*.bat text eol=crlf + diff --git a/gradle-modules/gradle-7/dependency-version/.gitignore b/gradle-modules/gradle-7/dependency-version/.gitignore new file mode 100644 index 0000000000..1b6985c009 --- /dev/null +++ b/gradle-modules/gradle-7/dependency-version/.gitignore @@ -0,0 +1,5 @@ +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build diff --git a/gradle-modules/gradle-7/dependency-version/build.gradle b/gradle-modules/gradle-7/dependency-version/build.gradle new file mode 100644 index 0000000000..7a8b51f5cc --- /dev/null +++ b/gradle-modules/gradle-7/dependency-version/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group = "com.baeldung.gradle" +version = "1.0.0-SNAPSHOT" +sourceCompatibility = JavaVersion.VERSION_17 + +repositories { + mavenLocal() + mavenCentral() +} + +dependencies { + implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0' + implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.+' + implementation group: 'org.apache.commons', name: 'commons-math3', version: '[3.4, 3.5)' + implementation group: 'org.apache.commons', name: 'commons-text', version: 'latest.release' +} \ No newline at end of file diff --git a/gradle-modules/gradle-7/dependency-version/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-7/dependency-version/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..bdc9a83b1e --- /dev/null +++ b/gradle-modules/gradle-7/dependency-version/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/dependency-version/gradlew b/gradle-modules/gradle-7/dependency-version/gradlew new file mode 100755 index 0000000000..79a61d421c --- /dev/null +++ b/gradle-modules/gradle-7/dependency-version/gradlew @@ -0,0 +1,244 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradle-modules/gradle-7/dependency-version/gradlew.bat b/gradle-modules/gradle-7/dependency-version/gradlew.bat new file mode 100644 index 0000000000..93e3f59f13 --- /dev/null +++ b/gradle-modules/gradle-7/dependency-version/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/gradle-modules/gradle-7/dependency-version/settings.gradle b/gradle-modules/gradle-7/dependency-version/settings.gradle new file mode 100644 index 0000000000..a2e76e5b21 --- /dev/null +++ b/gradle-modules/gradle-7/dependency-version/settings.gradle @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/8.0.2/userguide/multi_project_builds.html + */ + +rootProject.name = 'dependency-version' diff --git a/gradle-modules/gradle-customization/protobuf/README.md b/gradle-modules/gradle-customization/protobuf/README.md new file mode 100644 index 0000000000..4e94aa3557 --- /dev/null +++ b/gradle-modules/gradle-customization/protobuf/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Configuring Protobuf Compilation with Custom Source Directories](https://www.baeldung.com/java-configure-protobuf-compilation-custom-source-directories) diff --git a/gradle-modules/gradle-customization/protobuf/build.gradle b/gradle-modules/gradle-customization/protobuf/build.gradle new file mode 100644 index 0000000000..3cac57fb03 --- /dev/null +++ b/gradle-modules/gradle-customization/protobuf/build.gradle @@ -0,0 +1,45 @@ +plugins { + id 'java' + id "com.google.protobuf" version "0.8.18" +} + +group = 'com.baeldung' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '17' + +repositories { + mavenCentral() +} + +dependencies { + implementation group: 'com.google.protobuf', name: 'protobuf-java', version: '3.15.0' + implementation group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' +} + +tasks.named('test') { + useJUnitPlatform() +} + +protobuf { + protoc { + artifact = 'com.google.protobuf:protoc:3.15.0' + } +} + +sourceSets { + main { + proto { + srcDir 'src/sample_protofiles' + } + java { + srcDirs 'build/generated/source/proto/main/java' + } + } + test { + proto { + srcDir 'src/sample_protofiles' + } + } +} \ No newline at end of file diff --git a/gradle-modules/gradle-customization/protobuf/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-customization/protobuf/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..774fae8767 --- /dev/null +++ b/gradle-modules/gradle-customization/protobuf/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-customization/protobuf/gradlew b/gradle-modules/gradle-customization/protobuf/gradlew new file mode 100755 index 0000000000..a69d9cb6c2 --- /dev/null +++ b/gradle-modules/gradle-customization/protobuf/gradlew @@ -0,0 +1,240 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradle-modules/gradle-customization/protobuf/gradlew.bat b/gradle-modules/gradle-customization/protobuf/gradlew.bat new file mode 100644 index 0000000000..f127cfd49d --- /dev/null +++ b/gradle-modules/gradle-customization/protobuf/gradlew.bat @@ -0,0 +1,91 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/gradle-modules/gradle-customization/protobuf/settings.gradle b/gradle-modules/gradle-customization/protobuf/settings.gradle new file mode 100644 index 0000000000..63483bae11 --- /dev/null +++ b/gradle-modules/gradle-customization/protobuf/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'protobuf' diff --git a/gradle-modules/gradle-customization/protobuf/src/main/resources/application.properties b/gradle-modules/gradle-customization/protobuf/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/gradle-modules/gradle-customization/protobuf/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/gradle-modules/gradle-customization/protobuf/src/sample_protofiles/user_message.proto b/gradle-modules/gradle-customization/protobuf/src/sample_protofiles/user_message.proto new file mode 100644 index 0000000000..60e06c2016 --- /dev/null +++ b/gradle-modules/gradle-customization/protobuf/src/sample_protofiles/user_message.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package com.baeldung.protobuf; + +option java_multiple_files = true; +option java_package = "com.baeldung.protobuf.service"; + +message User { + string firstName = 1; + optional string middleName = 2; + string lastName = 3; + optional uint32 age = 4; +} \ No newline at end of file diff --git a/gradle-modules/gradle-customization/protobuf/src/test/java/com/baeldung/protobuf/ProtobufCodeGenerationUnitTest.java b/gradle-modules/gradle-customization/protobuf/src/test/java/com/baeldung/protobuf/ProtobufCodeGenerationUnitTest.java new file mode 100644 index 0000000000..12187e3efb --- /dev/null +++ b/gradle-modules/gradle-customization/protobuf/src/test/java/com/baeldung/protobuf/ProtobufCodeGenerationUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.protobuf; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +import com.baeldung.protobuf.service.User; + +class ProtobufCodeGenerationUnitTest { + + @Test + void givenUserData_whenObjectCreated_thenDataShouldMatch() { + final String firstName = "John"; + final String lastName = "Doe"; + final int age = 28; + + User user = User.newBuilder() + .setFirstName(firstName) + .setLastName(lastName) + .setAge(age) + .build(); + + assertEquals(firstName, user.getFirstName()); + assertEquals(lastName, user.getLastName()); + assertEquals(age, user.getAge()); + } + +} diff --git a/graphql-modules/graphql-dgs/pom.xml b/graphql-modules/graphql-dgs/pom.xml index 051785b4b8..313e598130 100644 --- a/graphql-modules/graphql-dgs/pom.xml +++ b/graphql-modules/graphql-dgs/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 graphql-dgs - 1.0 graphql-dgs diff --git a/graphql-modules/graphql-java/pom.xml b/graphql-modules/graphql-java/pom.xml index 01b7a4fbc3..88f2beb574 100644 --- a/graphql-modules/graphql-java/pom.xml +++ b/graphql-modules/graphql-java/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 graphql-java - 1.0 graphql-java @@ -13,21 +12,6 @@ 1.0.0-SNAPSHOT - - - jitpack.io - https://jitpack.io - - - - false - - central - Central Repository - https://repo.maven.apache.org/maven2 - - - com.graphql-java @@ -143,6 +127,13 @@ + + + jitpack.io + https://jitpack.io + + + 11.0 5.2.4 diff --git a/graphql-modules/graphql-spqr-boot-starter/pom.xml b/graphql-modules/graphql-spqr-boot-starter/pom.xml index 6cb1d74329..fd9ebc0224 100644 --- a/graphql-modules/graphql-spqr-boot-starter/pom.xml +++ b/graphql-modules/graphql-spqr-boot-starter/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 graphql-spqr-boot-starter - 1.0 graphql-spqr-boot-starter diff --git a/graphql-modules/graphql-spqr/pom.xml b/graphql-modules/graphql-spqr/pom.xml index d845d1ac8a..756930f2ac 100644 --- a/graphql-modules/graphql-spqr/pom.xml +++ b/graphql-modules/graphql-spqr/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 graphql-spqr - 1.0 graphql-spqr diff --git a/graphql-modules/pom.xml b/graphql-modules/pom.xml index a42400b7cc..4b43cbffde 100644 --- a/graphql-modules/pom.xml +++ b/graphql-modules/pom.xml @@ -5,7 +5,6 @@ 4.0.0 com.baeldung.graphql graphql-modules - 1.0.0-SNAPSHOT graphql-modules pom diff --git a/grpc/pom.xml b/grpc/pom.xml index 40d35183dc..fed1e801f2 100644 --- a/grpc/pom.xml +++ b/grpc/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 grpc - 0.0.1-SNAPSHOT grpc jar diff --git a/guava-modules/guava-18/pom.xml b/guava-modules/guava-18/pom.xml index 8f5108bff1..873555bf24 100644 --- a/guava-modules/guava-18/pom.xml +++ b/guava-modules/guava-18/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 guava-18 - 0.1.0-SNAPSHOT guava-18 diff --git a/guava-modules/guava-19/pom.xml b/guava-modules/guava-19/pom.xml index ba85fe0ae8..9a40677e08 100644 --- a/guava-modules/guava-19/pom.xml +++ b/guava-modules/guava-19/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 guava-19 - 0.1.0-SNAPSHOT guava-19 diff --git a/guava-modules/guava-21/pom.xml b/guava-modules/guava-21/pom.xml index 9e791bfe23..a26176ba0b 100644 --- a/guava-modules/guava-21/pom.xml +++ b/guava-modules/guava-21/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 guava-21 - 1.0-SNAPSHOT guava-21 diff --git a/guava-modules/guava-collections-list/pom.xml b/guava-modules/guava-collections-list/pom.xml index 6863b4011c..a07f34e56c 100644 --- a/guava-modules/guava-collections-list/pom.xml +++ b/guava-modules/guava-collections-list/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 guava-collections-list - 0.1.0-SNAPSHOT guava-collections-list diff --git a/guava-modules/guava-collections-map/pom.xml b/guava-modules/guava-collections-map/pom.xml index 04beaa13a1..6b73e8c29a 100644 --- a/guava-modules/guava-collections-map/pom.xml +++ b/guava-modules/guava-collections-map/pom.xml @@ -5,7 +5,6 @@ 4.0.0 com.baeldung.guava guava-collections-map - 0.1.0-SNAPSHOT guava-collections-map diff --git a/guava-modules/guava-collections-set/pom.xml b/guava-modules/guava-collections-set/pom.xml index 49bfc46ee2..ffd6c80a3e 100644 --- a/guava-modules/guava-collections-set/pom.xml +++ b/guava-modules/guava-collections-set/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 guava-collections-set - 0.1.0-SNAPSHOT guava-collections-set diff --git a/guava-modules/guava-collections/pom.xml b/guava-modules/guava-collections/pom.xml index 8dc052db75..e016b1c547 100644 --- a/guava-modules/guava-collections/pom.xml +++ b/guava-modules/guava-collections/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 guava-collections - 0.1.0-SNAPSHOT guava-collections diff --git a/guava-modules/guava-core/pom.xml b/guava-modules/guava-core/pom.xml index dd68fef43a..6c4f76356f 100644 --- a/guava-modules/guava-core/pom.xml +++ b/guava-modules/guava-core/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 guava-core - 0.1.0-SNAPSHOT guava-core diff --git a/guava-modules/guava-io/pom.xml b/guava-modules/guava-io/pom.xml index 2ea91c5e4f..367533139e 100644 --- a/guava-modules/guava-io/pom.xml +++ b/guava-modules/guava-io/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 guava-io - 0.1.0-SNAPSHOT guava-io diff --git a/guava-modules/guava-utilities/pom.xml b/guava-modules/guava-utilities/pom.xml index ab849072a5..407a44587e 100644 --- a/guava-modules/guava-utilities/pom.xml +++ b/guava-modules/guava-utilities/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 guava-utilities - 0.1.0-SNAPSHOT guava-utilities diff --git a/hazelcast/pom.xml b/hazelcast/pom.xml index 694563790f..4742f213e5 100644 --- a/hazelcast/pom.xml +++ b/hazelcast/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 hazelcast - 0.0.1-SNAPSHOT hazelcast diff --git a/httpclient-simple/pom.xml b/httpclient-simple/pom.xml index eea056477c..a6049432ce 100644 --- a/httpclient-simple/pom.xml +++ b/httpclient-simple/pom.xml @@ -1,10 +1,9 @@ + 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 httpclient-simple - 0.1-SNAPSHOT httpclient-simple war diff --git a/httpclient-simple/src/test/java/com/baeldung/httpclient/HttpClientHeadersLiveTest.java b/httpclient-simple/src/test/java/com/baeldung/httpclient/HttpClientHeadersLiveTest.java index 616b6470af..3992fd821e 100644 --- a/httpclient-simple/src/test/java/com/baeldung/httpclient/HttpClientHeadersLiveTest.java +++ b/httpclient-simple/src/test/java/com/baeldung/httpclient/HttpClientHeadersLiveTest.java @@ -25,26 +25,22 @@ class HttpClientHeadersLiveTest { @Test void whenClientUsesCustomUserAgent_thenCorrect() throws IOException { + final CloseableHttpClient client = HttpClients.custom() + .setUserAgent("Mozilla/5.0 Firefox/26.0") + .build(); final HttpGet request = new HttpGet(SAMPLE_URL); - try (CloseableHttpClient client = HttpClients.custom() - .setUserAgent("Mozilla/5.0 Firefox/26.0") - .build()) { - - String response = client.execute(request, new BasicHttpClientResponseHandler()); - logger.info("Response -> {}", response); - } + String response = client.execute(request, new BasicHttpClientResponseHandler()); + logger.info("Response -> {}", response); } @Test void whenRequestHasCustomUserAgent_thenCorrect() throws IOException { + CloseableHttpClient client = HttpClients.createDefault(); final HttpGet request = new HttpGet(SAMPLE_URL); request.setHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 Firefox/26.0"); - - try (CloseableHttpClient client = HttpClients.createDefault()) { - String response = client.execute(request, new BasicHttpClientResponseHandler()); - logger.info("Response -> {}", response); - } + String response = client.execute(request, new BasicHttpClientResponseHandler()); + logger.info("Response -> {}", response); } @Test diff --git a/hystrix/pom.xml b/hystrix/pom.xml index 639d4eba02..007c2e237b 100644 --- a/hystrix/pom.xml +++ b/hystrix/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 hystrix - 1.0 hystrix diff --git a/image-processing/pom.xml b/image-processing/pom.xml index 3780ecfd33..2a2b92ca48 100644 --- a/image-processing/pom.xml +++ b/image-processing/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 image-processing - 1.0-SNAPSHOT image-processing diff --git a/jackson-modules/jackson-annotations/pom.xml b/jackson-modules/jackson-annotations/pom.xml index 4bb9341e43..e2d5e1e607 100644 --- a/jackson-modules/jackson-annotations/pom.xml +++ b/jackson-modules/jackson-annotations/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jackson-annotations - 0.0.1-SNAPSHOT jackson-annotations diff --git a/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/format/User.java b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/format/User.java index e655deb93b..119c1e3ce3 100644 --- a/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/format/User.java +++ b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/format/User.java @@ -1,26 +1,41 @@ package com.baeldung.jackson.format; +import com.fasterxml.jackson.annotation.JsonFormat; + import java.util.Date; -import com.baeldung.jackson.domain.Person; -import com.fasterxml.jackson.annotation.JsonFormat; - -/** - * @author Jay Sridhar - * @version 1.0 - */ -public class User extends Person { +public class User { private String firstName; private String lastName; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ") private Date createdDate; + public User() { + } + public User(String firstName, String lastName) { - super(firstName, lastName); + this.firstName = firstName; + this.lastName = lastName; this.createdDate = new Date(); } + 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 Date getCreatedDate() { return createdDate; } @@ -35,3 +50,51 @@ public class User extends Person { return new Date(); } } + +@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES) +class UserIgnoreCase { + private String firstName; + private String lastName; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ") + private Date createdDate; + + public UserIgnoreCase() { + } + + public UserIgnoreCase(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + this.createdDate = new Date(); + } + + 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 Date getCreatedDate() { + return createdDate; + } + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ", locale = "en_GB") + public Date getCurrentDate() { + return new Date(); + } + + @JsonFormat(shape = JsonFormat.Shape.NUMBER) + public Date getDateNum() { + return new Date(); + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/format/JsonFormatUnitTest.java b/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/format/JsonFormatUnitTest.java index cf166fdc36..5cdc248d3b 100644 --- a/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/format/JsonFormatUnitTest.java +++ b/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/format/JsonFormatUnitTest.java @@ -1,24 +1,25 @@ package com.baeldung.jackson.format; -import java.util.Date; - import com.fasterxml.jackson.core.JsonProcessingException; - import com.fasterxml.jackson.databind.ObjectMapper; - +import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; import org.junit.Test; -import static io.restassured.path.json.JsonPath.from; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; +import static io.restassured.path.json.JsonPath.from; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.from; import static org.assertj.core.data.Percentage.withPercentage; -/** - * @author Jay Sridhar - * @version 1.0 - */ public class JsonFormatUnitTest { + private static final String JSON_STRING = "{\"FIRSTNAME\":\"John\",\"lastname\":\"Smith\",\"cReAtEdDaTe\":\"2016-12-18@07:53:34.740+0000\"}"; + @Test public void whenSerializedDateFormat_thenCorrect() throws JsonProcessingException { @@ -32,6 +33,24 @@ public class JsonFormatUnitTest { // Expected to be close to current time long now = new Date().getTime(); assertThat(from(result).getLong("dateNum")).isCloseTo(now, withPercentage(10.0)); - } -} + + @Test + public void whenDeserializeJsonStrToUserObject_thenFail() { + assertThatThrownBy(() -> new ObjectMapper().readValue(JSON_STRING, User.class)).isInstanceOf(UnrecognizedPropertyException.class); + } + + @Test + public void whenDeserializeJsonStrToUserIgnoreCaseObject_thenSuccess() throws JsonProcessingException, ParseException { + UserIgnoreCase result = new ObjectMapper().readValue(JSON_STRING, UserIgnoreCase.class); + SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSzz"); + Date expectedDate = fmt.parse("2016-12-18T07:53:34.740+0000"); + + assertThat(result) + .isNotNull() + .returns("John", from(UserIgnoreCase::getFirstName)) + .returns("Smith", from(UserIgnoreCase::getLastName)) + .returns(expectedDate, from(UserIgnoreCase::getCreatedDate)); + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions-2/pom.xml b/jackson-modules/jackson-conversions-2/pom.xml index 1c6d2fc002..457045b460 100644 --- a/jackson-modules/jackson-conversions-2/pom.xml +++ b/jackson-modules/jackson-conversions-2/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jackson-conversions-2 - 0.0.1-SNAPSHOT jackson-conversions-2 diff --git a/jackson-modules/jackson-conversions/pom.xml b/jackson-modules/jackson-conversions/pom.xml index 9218f209ac..e0990ed34f 100644 --- a/jackson-modules/jackson-conversions/pom.xml +++ b/jackson-modules/jackson-conversions/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jackson-conversions - 0.0.1-SNAPSHOT jackson-conversions @@ -24,6 +23,11 @@ jackson-datatype-jsr310 ${jackson.version} + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + diff --git a/jackson-modules/jackson-conversions/src/main/java/com/baeldung/jackson/map/Fruit.java b/jackson-modules/jackson-conversions/src/main/java/com/baeldung/jackson/map/Fruit.java new file mode 100644 index 0000000000..49e45f2161 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/baeldung/jackson/map/Fruit.java @@ -0,0 +1,21 @@ +package com.baeldung.jackson.map; + +import com.fasterxml.jackson.annotation.JsonKey; +import com.fasterxml.jackson.annotation.JsonValue; + +public class Fruit { + public String variety; + + @JsonKey + public String name; + + public Fruit(String variety, String name) { + this.variety = variety; + this.name = name; + } + + @JsonValue + public String getFullName() { + return this.variety + " " + this.name; + } +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/map/MapWithJsonKeyValueUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/map/MapWithJsonKeyValueUnitTest.java new file mode 100644 index 0000000000..0b4639ca3b --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/map/MapWithJsonKeyValueUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.jackson.map; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class MapWithJsonKeyValueUnitTest { + private static final Fruit FRUIT1 = new Fruit("Alphonso", "Mango"); + private static final Fruit FRUIT2 = new Fruit("Black", "Grapes"); + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + @Test + public void givenObject_WhenSerialize_ThenUseJsonValueForSerialization() throws JsonProcessingException { + String serializedValueForFruit1 = OBJECT_MAPPER.writeValueAsString(FRUIT1); + Assertions.assertEquals("\"Alphonso Mango\"", serializedValueForFruit1); + String serializedValueForFruit2 = OBJECT_MAPPER.writeValueAsString(FRUIT2); + Assertions.assertEquals("\"Black Grapes\"", serializedValueForFruit2); + } + + @Test + public void givenMapWithObjectKeys_WhenSerialize_ThenUseJsonKeyForSerialization() throws JsonProcessingException { + // Given + Map selectionByFruit = new LinkedHashMap(); + selectionByFruit.put(FRUIT1, "Hagrid"); + selectionByFruit.put(FRUIT2, "Hercules"); + // When + String serializedValue = OBJECT_MAPPER.writeValueAsString(selectionByFruit); + // Then + Assertions.assertEquals("{\"Mango\":\"Hagrid\",\"Grapes\":\"Hercules\"}", serializedValue); + } + + @Test + public void givenMapWithObjectValues_WhenSerialize_ThenUseJsonValueForSerialization() throws JsonProcessingException { + // Given + Map selectionByPerson = new LinkedHashMap(); + selectionByPerson.put("Hagrid", FRUIT1); + selectionByPerson.put("Hercules", FRUIT2); + // When + String serializedValue = OBJECT_MAPPER.writeValueAsString(selectionByPerson); + // Then + Assertions.assertEquals("{\"Hagrid\":\"Alphonso Mango\",\"Hercules\":\"Black Grapes\"}", serializedValue); + } +} diff --git a/jackson-modules/jackson-core/README.md b/jackson-modules/jackson-core/README.md index 0aa3dc5aef..73293b1e84 100644 --- a/jackson-modules/jackson-core/README.md +++ b/jackson-modules/jackson-core/README.md @@ -14,3 +14,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Inheritance with Jackson](https://www.baeldung.com/jackson-inheritance) - [Working with Tree Model Nodes in Jackson](https://www.baeldung.com/jackson-json-node-tree-model) - [Get all the Keys in a JSON String Using JsonNode](https://www.baeldung.com/java-jsonnode-get-keys) +- [Difference Between asText() and toString() in JsonNode](https://www.baeldung.com/java-jsonnode-astext-vs-tostring) +- [Deserialize Generic Type with Jackson](https://www.baeldung.com/java-deserialize-generic-type-with-jackson) diff --git a/jackson-modules/jackson-core/pom.xml b/jackson-modules/jackson-core/pom.xml index f3edffc07c..4eccd4d8f8 100644 --- a/jackson-modules/jackson-core/pom.xml +++ b/jackson-modules/jackson-core/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jackson-core - 0.0.1-SNAPSHOT jackson-core diff --git a/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/deserialization/jsongeneric/JsonResponse.java b/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/deserialization/jsongeneric/JsonResponse.java new file mode 100644 index 0000000000..14f6b3f8ad --- /dev/null +++ b/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/deserialization/jsongeneric/JsonResponse.java @@ -0,0 +1,14 @@ +package com.baeldung.jackson.deserialization.jsongeneric; + +public class JsonResponse { + + private T result; + + public T getResult() { + return result; + } + + public void setResult(T result) { + this.result = result; + } +} diff --git a/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/deserialization/jsongeneric/User.java b/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/deserialization/jsongeneric/User.java new file mode 100644 index 0000000000..1efb3af7f9 --- /dev/null +++ b/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/deserialization/jsongeneric/User.java @@ -0,0 +1,33 @@ +package com.baeldung.jackson.deserialization.jsongeneric; + +public class User { + + private Long id; + private String firstName; + private String lastName; + + 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; + } +} + diff --git a/jackson-modules/jackson-core/src/test/java/com/baeldung/jackson/deserialization/jsongeneric/GenericTypeDeserializerUnitTest.java b/jackson-modules/jackson-core/src/test/java/com/baeldung/jackson/deserialization/jsongeneric/GenericTypeDeserializerUnitTest.java new file mode 100644 index 0000000000..24baeb7f1f --- /dev/null +++ b/jackson-modules/jackson-core/src/test/java/com/baeldung/jackson/deserialization/jsongeneric/GenericTypeDeserializerUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.jackson.deserialization.jsongeneric; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class GenericTypeDeserializerUnitTest { + + ObjectMapper objectMapper = new ObjectMapper(); + + @Test + void givenJsonObject_whenDeserializeIntoGenericTypeByTypeReference_thenCorrect() throws JsonProcessingException { + String json = "{\"result\":{\"id\":1,\"firstName\":\"John\",\"lastName\":\"Lewis\"}}"; + + TypeReference> typeRef = new TypeReference>() {}; + JsonResponse jsonResponse = objectMapper.readValue(json, typeRef); + User user = jsonResponse.getResult(); + + assertThat(user.getId()).isEqualTo(1); + assertThat(user.getFirstName()).isEqualTo("John"); + assertThat(user.getLastName()).isEqualTo("Lewis"); + } + + @Test + void givenJsonObject_whenDeserializeIntoGenericTypeByJavaType_thenCorrect() throws JsonProcessingException { + String json = "{\"result\":{\"id\":1,\"firstName\":\"John\",\"lastName\":\"Lewis\"}}"; + + JavaType javaType = objectMapper.getTypeFactory().constructParametricType(JsonResponse.class, User.class); + JsonResponse jsonResponse = objectMapper.readValue(json, javaType); + User user = jsonResponse.getResult(); + + assertThat(user.getId()).isEqualTo(1); + assertThat(user.getFirstName()).isEqualTo("John"); + assertThat(user.getLastName()).isEqualTo("Lewis"); + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/README.md b/jackson-modules/jackson-custom-conversions/README.md index 68e9a6d50d..2f45a2f43b 100644 --- a/jackson-modules/jackson-custom-conversions/README.md +++ b/jackson-modules/jackson-custom-conversions/README.md @@ -7,3 +7,4 @@ This module contains articles about Jackson custom conversions. - [Getting Started with Custom Deserialization in Jackson](https://www.baeldung.com/jackson-deserialization) - [Serialize Only Fields that meet a Custom Criteria with Jackson](https://www.baeldung.com/jackson-serialize-field-custom-criteria) - [Calling Default Serializer from Custom Serializer in Jackson](https://www.baeldung.com/jackson-call-default-serializer-from-custom-serializer) +- [OffsetDateTime Serialization With Jackson](https://www.baeldung.com/java-jackson-offsetdatetime) diff --git a/jackson-modules/jackson-custom-conversions/pom.xml b/jackson-modules/jackson-custom-conversions/pom.xml index 79af962eec..31e460511a 100644 --- a/jackson-modules/jackson-custom-conversions/pom.xml +++ b/jackson-modules/jackson-custom-conversions/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jackson-custom-conversions - 0.0.1-SNAPSHOT jackson-custom-conversions diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/offsetdatetime/Main.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/offsetdatetime/Main.java new file mode 100644 index 0000000000..eb82c3c4c8 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/offsetdatetime/Main.java @@ -0,0 +1,50 @@ +package com.baeldung.offsetdatetime; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import java.time.OffsetDateTime; + +public class Main { + public static void main(String[] args) throws JsonProcessingException { + System.out.println(serializeUser()); + System.out.println(customSerialize()); + System.out.println(customDeserialize()); + } + + static String serializeUser() throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.registerModule(new JavaTimeModule()); + + User user = new User(); + user.setCreatedAt(OffsetDateTime.parse("2021-09-30T15:30:00+01:00")); + + return objectMapper.writeValueAsString(user); + } + + static String customSerialize() throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + + objectMapper.registerModule(new SimpleModule().addSerializer(OffsetDateTime.class, new OffsetDateTimeSerializer())); + + User user = new User(); + user.setCreatedAt(OffsetDateTime.parse("2021-09-30T15:30:00+01:00")); + + return objectMapper.writeValueAsString(user); + } + + static String customDeserialize() throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + + objectMapper.registerModule(new SimpleModule().addDeserializer(OffsetDateTime.class, new OffsetDateTimeDeserializer())); + + String jsonString = "{\"createdAt\":\"30-09-2021 15:30:00 +01:00\"}"; + User returnedUser = objectMapper.readValue(jsonString, User.class); + + return returnedUser.getCreatedAt().toString(); + } +} diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/offsetdatetime/OffsetDateTimeDeserializer.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/offsetdatetime/OffsetDateTimeDeserializer.java new file mode 100644 index 0000000000..a76d598b8f --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/offsetdatetime/OffsetDateTimeDeserializer.java @@ -0,0 +1,24 @@ +package com.baeldung.offsetdatetime; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; + +public class OffsetDateTimeDeserializer extends JsonDeserializer { + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter + .ofPattern("dd-MM-yyyy HH:mm:ss XXX"); + + @Override + public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException { + String dateAsString = jsonParser.getText(); + if (dateAsString == null) { + throw new IOException("OffsetDateTime argument is null."); + } + return OffsetDateTime.parse(dateAsString, DATE_TIME_FORMATTER); + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/offsetdatetime/OffsetDateTimeSerializer.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/offsetdatetime/OffsetDateTimeSerializer.java new file mode 100644 index 0000000000..8821f37e8e --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/offsetdatetime/OffsetDateTimeSerializer.java @@ -0,0 +1,23 @@ +package com.baeldung.offsetdatetime; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; + +public class OffsetDateTimeSerializer extends JsonSerializer { + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter + .ofPattern("dd-MM-yyyy HH:mm:ss XXX"); + + @Override + public void serialize(OffsetDateTime value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) + throws IOException { + if (value == null) { + throw new IOException("OffsetDateTime argument is null."); + } + jsonGenerator.writeString(DATE_TIME_FORMATTER.format(value)); + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/offsetdatetime/User.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/offsetdatetime/User.java new file mode 100644 index 0000000000..44978cac87 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/offsetdatetime/User.java @@ -0,0 +1,18 @@ +package com.baeldung.offsetdatetime; + +import java.time.OffsetDateTime; + +public class User { + private OffsetDateTime createdAt; + + public User() { + } + + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(OffsetDateTime createdAt) { + this.createdAt = createdAt; + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/offsetdatetime/MainUnitTest.java b/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/offsetdatetime/MainUnitTest.java new file mode 100644 index 0000000000..553adc8fdf --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/offsetdatetime/MainUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.offsetdatetime; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class MainUnitTest { + + @Test + void givenUser_whenSerialized_thenCreatedDateIsSerialized() throws JsonProcessingException { + Assertions.assertEquals("{\"createdAt\":\"2021-09-30T15:30:00+01:00\"}", Main.serializeUser()); + } + + @Test + void givenUser_whenCustomSerialized_thenCreatedDateIsSerialized() throws JsonProcessingException { + Assertions.assertEquals("{\"createdAt\":\"30-09-2021 15:30:00 +01:00\"}", Main.customSerialize()); + } + + @Test + void givenUser_whenCustomDeserialized_thenCreatedDateIsDeserialized() throws JsonProcessingException { + Assertions.assertEquals("2021-09-30T15:30+01:00", Main.customDeserialize()); + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-exceptions/README.md b/jackson-modules/jackson-exceptions/README.md index 6f082aaaa5..b9c43cb09f 100644 --- a/jackson-modules/jackson-exceptions/README.md +++ b/jackson-modules/jackson-exceptions/README.md @@ -5,3 +5,4 @@ This module contains articles about Jackson exceptions. ### Relevant Articles: - [Jackson Exceptions – Problems and Solutions](https://www.baeldung.com/jackson-exception) - [Jackson – JsonMappingException (No serializer found for class)](https://www.baeldung.com/jackson-jsonmappingexception) +- [Fix the JsonMappingException: Can not deserialize instance of java.util.ArrayList from Object value (token `JsonToken.START_OBJECT`)](https://www.baeldung.com/jsonmappingexception-can-not-deserialize-instance-of-java-util-arraylist-from-object-value-token-jsontoken-start_object) diff --git a/jackson-modules/jackson-exceptions/pom.xml b/jackson-modules/jackson-exceptions/pom.xml index a24a0ab4b7..e19ef4f883 100644 --- a/jackson-modules/jackson-exceptions/pom.xml +++ b/jackson-modules/jackson-exceptions/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jackson-exceptions - 0.0.1-SNAPSHOT jackson-exceptions diff --git a/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/mappingexception/Country.java b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/mappingexception/Country.java new file mode 100644 index 0000000000..a8e6dfbc94 --- /dev/null +++ b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/mappingexception/Country.java @@ -0,0 +1,26 @@ +package com.baeldung.mappingexception; + +import java.util.List; + +public class Country { + + private String name; + private List cities; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getCities() { + return cities; + } + + public void setCities(List cities) { + this.cities = cities; + } + +} diff --git a/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/mappingexception/JacksonMappingExceptionUnitTest.java b/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/mappingexception/JacksonMappingExceptionUnitTest.java index df35626828..026fd6719f 100644 --- a/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/mappingexception/JacksonMappingExceptionUnitTest.java +++ b/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/mappingexception/JacksonMappingExceptionUnitTest.java @@ -1,34 +1,33 @@ package com.baeldung.mappingexception; import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; -import java.io.IOException; -import java.util.List; import org.junit.Test; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.google.common.collect.Lists; public class JacksonMappingExceptionUnitTest { @Test(expected = JsonMappingException.class) - public final void givenObjectHasNoAccessors_whenSerializing_thenException() throws JsonParseException, IOException { + public void givenObjectHasNoAccessors_whenSerializing_thenException() throws JsonProcessingException { final String dtoAsString = new ObjectMapper().writeValueAsString(new MyDtoNoAccessors()); assertThat(dtoAsString, notNullValue()); } @Test - public final void givenObjectHasNoAccessors_whenSerializingWithPrivateFieldsVisibility_thenNoException() throws JsonParseException, IOException { + public void givenObjectHasNoAccessors_whenSerializingWithPrivateFieldsVisibility_thenNoException() throws JsonProcessingException { final ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); final String dtoAsString = objectMapper.writeValueAsString(new MyDtoNoAccessors()); @@ -39,7 +38,7 @@ public class JacksonMappingExceptionUnitTest { } @Test - public final void givenObjectHasNoAccessorsButHasVisibleFields_whenSerializing_thenNoException() throws JsonParseException, IOException { + public void givenObjectHasNoAccessorsButHasVisibleFields_whenSerializing_thenNoException() throws JsonProcessingException { final ObjectMapper objectMapper = new ObjectMapper(); final String dtoAsString = objectMapper.writeValueAsString(new MyDtoNoAccessorsAndFieldVisibility()); @@ -48,4 +47,30 @@ public class JacksonMappingExceptionUnitTest { assertThat(dtoAsString, containsString("booleanValue")); } + @Test + public void givenJsonWithInvalidList_whenDeserializing_thenThrowException() throws JsonProcessingException { + final String json = "{\"name\":\"Netherlands\",\"cities\":{\"Amsterdam\", \"Tamassint\"}}"; + final ObjectMapper mapper = new ObjectMapper(); + + Exception exception = assertThrows(JsonMappingException.class, () -> mapper.reader() + .forType(Country.class) + .readValue(json)); + + assertTrue(exception.getMessage() + .contains("Cannot deserialize value of type `java.util.ArrayList`")); + } + + @Test + public void givenJsonWithValidList_whenDeserializing_thenCorrect() throws JsonProcessingException { + final String json = "{\"name\":\"Netherlands\",\"cities\":[\"Amsterdam\", \"Tamassint\"]}"; + final ObjectMapper mapper = new ObjectMapper(); + + Country country = mapper.reader() + .forType(Country.class) + .readValue(json); + + assertEquals("Netherlands", country.getName()); + assertEquals(Arrays.asList("Amsterdam", "Tamassint"), country.getCities()); + } + } diff --git a/jackson-modules/pom.xml b/jackson-modules/pom.xml index 4163d1912f..531d5628f7 100644 --- a/jackson-modules/pom.xml +++ b/jackson-modules/pom.xml @@ -24,11 +24,6 @@ - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - com.fasterxml.jackson.dataformat diff --git a/jackson-simple/pom.xml b/jackson-simple/pom.xml index f71cb1ffbf..d1fcc867cf 100644 --- a/jackson-simple/pom.xml +++ b/jackson-simple/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jackson-simple - 0.0.1-SNAPSHOT jackson-simple @@ -33,4 +32,8 @@ + + 2.14.2 + + \ No newline at end of file diff --git a/jackson-simple/src/main/java/com/baeldung/jackson/annotation/BeanWithInclude.java b/jackson-simple/src/main/java/com/baeldung/jackson/annotation/BeanWithInclude.java new file mode 100644 index 0000000000..18130fc9f2 --- /dev/null +++ b/jackson-simple/src/main/java/com/baeldung/jackson/annotation/BeanWithInclude.java @@ -0,0 +1,18 @@ +package com.baeldung.jackson.annotation; + +import com.fasterxml.jackson.annotation.JsonIncludeProperties; + +@JsonIncludeProperties({ "name" }) +public class BeanWithInclude { + public int id; + public String name; + + public BeanWithInclude() { + + } + + public BeanWithInclude(final int id, final String name) { + this.id = id; + this.name = name; + } +} diff --git a/jackson-simple/src/main/java/com/baeldung/jackson/annotation/GeneralBean.java b/jackson-simple/src/main/java/com/baeldung/jackson/annotation/GeneralBean.java new file mode 100644 index 0000000000..a8333f54ae --- /dev/null +++ b/jackson-simple/src/main/java/com/baeldung/jackson/annotation/GeneralBean.java @@ -0,0 +1,26 @@ +package com.baeldung.jackson.annotation; + +import com.fasterxml.jackson.annotation.JsonValue; + +public class GeneralBean { + Integer id; + + @JsonValue + String name; + + public GeneralBean() { + } + + public GeneralBean(Integer id, String name) { + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public String getName() { + return name; + } +} diff --git a/jackson-simple/src/main/java/com/baeldung/jackson/annotation/PriorityEnum.java b/jackson-simple/src/main/java/com/baeldung/jackson/annotation/PriorityEnum.java new file mode 100644 index 0000000000..ed74052ede --- /dev/null +++ b/jackson-simple/src/main/java/com/baeldung/jackson/annotation/PriorityEnum.java @@ -0,0 +1,16 @@ +package com.baeldung.jackson.annotation; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum PriorityEnum { + + LOW(0), MEDIUM(1), HIGH(3); + + @JsonValue + private int level; + + PriorityEnum(int level) { + this.level = level; + } + +} diff --git a/jackson-simple/src/main/java/com/baeldung/jackson/annotation/dtos/withEnum/TypeEnumWithValue.java b/jackson-simple/src/main/java/com/baeldung/jackson/annotation/dtos/withEnum/TypeEnumWithValue.java new file mode 100644 index 0000000000..2c8718dfd8 --- /dev/null +++ b/jackson-simple/src/main/java/com/baeldung/jackson/annotation/dtos/withEnum/TypeEnumWithValue.java @@ -0,0 +1,23 @@ +package com.baeldung.jackson.annotation.dtos.withEnum; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum TypeEnumWithValue { + TYPE1(1, "Type A"), TYPE2(2, "Type 2"); + + private Integer id; + + @JsonValue + private String name; + + + TypeEnumWithValue(int id, String name) { + this.id = id; + this.name = name; + } + + //@JsonValue + public String getName() { + return name; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/annotation/JacksonAnnotationUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/JacksonAnnotationUnitTest.java index bbbb79b0a8..1a6c7b1286 100644 --- a/jackson-simple/src/test/java/com/baeldung/jackson/annotation/JacksonAnnotationUnitTest.java +++ b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/JacksonAnnotationUnitTest.java @@ -20,10 +20,12 @@ import com.baeldung.jackson.annotation.bidirection.UserWithIdentity; import com.baeldung.jackson.annotation.bidirection.UserWithRef; import com.baeldung.jackson.annotation.date.EventWithFormat; import com.baeldung.jackson.annotation.date.EventWithSerializer; +import com.baeldung.jackson.annotation.dtos.withEnum.TypeEnumWithValue; import com.baeldung.jackson.annotation.ignore.MyMixInForIgnoreType; import com.baeldung.jackson.annotation.dtos.withEnum.DistanceEnumWithValue; import com.baeldung.jackson.annotation.exception.UserWithRoot; import com.baeldung.jackson.annotation.exception.UserWithRootNamespace; +import com.baeldung.jackson.annotation.ignore.MyMixInForIgnoreType; import com.baeldung.jackson.annotation.jsonview.Item; import com.baeldung.jackson.annotation.jsonview.Views; import com.fasterxml.jackson.core.JsonProcessingException; @@ -95,6 +97,14 @@ public class JacksonAnnotationUnitTest { assertThat(enumAsString, is("1609.34")); } + + @Test + public void whenSerializingFieldUsingJsonValue_thenCorrect() throws IOException { + final String enumAsString = new ObjectMapper().writeValueAsString(PriorityEnum.HIGH); + + assertEquals("3", enumAsString); + } + @Test public void whenSerializingUsingJsonSerialize_thenCorrect() throws JsonProcessingException, ParseException { final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); @@ -107,6 +117,19 @@ public class JacksonAnnotationUnitTest { assertThat(result, containsString(toParse)); } + @Test + public void whenSerializingUsingJsonValueAnnotatedField_thenCorrect() throws JsonProcessingException { + final String enumValue = new ObjectMapper().writeValueAsString(TypeEnumWithValue.TYPE1); + assertThat(enumValue, is("\"Type A\"")); + } + + @Test + public void whenSerializingUsingJsonValueAnnotatedFieldInPojo_thenCorrect() throws JsonProcessingException { + GeneralBean bean1 = new GeneralBean(1, "Bean 1"); + final String bean1AsString = new ObjectMapper().writeValueAsString(bean1); + assertThat(bean1AsString, is("\"Bean 1\"")); + } + // ========================= Deserializing annotations ============================ @Test @@ -118,6 +141,7 @@ public class JacksonAnnotationUnitTest { assertEquals("My bean", bean.name); } + @Test public void whenDeserializingUsingJsonInject_thenCorrect() throws IOException { final String json = "{\"name\":\"My bean\"}"; @@ -161,6 +185,23 @@ public class JacksonAnnotationUnitTest { assertEquals("20-12-2014 02:30:00", df.format(event.eventDate)); } + @Test + public void whenDeserializingUsingJsonValue_thenCorrect() throws JsonProcessingException { + final String str = "\"Type A\""; + TypeEnumWithValue te = new ObjectMapper().readerFor(TypeEnumWithValue.class) + .readValue(str); + assertThat(te, is(TypeEnumWithValue.TYPE1)); + } + + @Test(expected = Exception.class) + public void whenDeserializingUsingJsonValueAnnotatedFieldInPojo_thenGetException() throws JsonProcessingException { + GeneralBean bean1 = new GeneralBean(1, "Bean 1"); + final String bean1AsString = new ObjectMapper().writeValueAsString(bean1); + GeneralBean bean = new ObjectMapper().readerFor(GeneralBean.class) + .readValue(bean1AsString); + assertThat(bean.getName(), is(bean1.getName())); + } + // ========================= Inclusion annotations ============================ @Test @@ -172,6 +213,15 @@ public class JacksonAnnotationUnitTest { assertThat(result, not(containsString("id"))); } + @Test + public void whenSerializingUsingJsonIncludeProperties_thenCorrect() throws JsonProcessingException { + final BeanWithInclude bean = new BeanWithInclude(1, "My bean"); + final String result = new ObjectMapper().writeValueAsString(bean); + assertThat(result, containsString("My bean")); + assertThat(result, not(containsString("id"))); + assertThat(result, containsString("name")); + } + @Test public void whenSerializingUsingJsonIgnore_thenCorrect() throws JsonProcessingException { final BeanWithIgnore bean = new BeanWithIgnore(1, "My bean"); @@ -399,7 +449,5 @@ public class JacksonAnnotationUnitTest { */ } - - } diff --git a/java-blockchain/pom.xml b/java-blockchain/pom.xml index 2279a7ceff..d45d2bf573 100644 --- a/java-blockchain/pom.xml +++ b/java-blockchain/pom.xml @@ -5,7 +5,6 @@ 4.0.0 com.baeldung.blockchain java-blockchain - 0.1.0-SNAPSHOT java-blockchain jar diff --git a/java-jdi/pom.xml b/java-jdi/pom.xml index a8716de4ee..dded13896f 100644 --- a/java-jdi/pom.xml +++ b/java-jdi/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 java-jdi - 0.1.0-SNAPSHOT java-jdi jar @@ -16,13 +15,7 @@ - - com.sun - tools - ${tools.version} - system - ${java.home}/../lib/tools.jar - + @@ -33,10 +26,25 @@ true + + + org.apache.maven.plugins + maven-compiler-plugin + + ${maven.compiler.source.version} + ${maven.compiler.target.version} + + --add-exports=jdk.jdi/com.sun.jdi=ALL-UNNAMED + + + + + - 1.8 + 17 + 17 \ No newline at end of file diff --git a/java-panama/pom.xml b/java-panama/pom.xml index 8453a38abd..7c6b420eeb 100644 --- a/java-panama/pom.xml +++ b/java-panama/pom.xml @@ -1,49 +1,48 @@ - - ${project.model.version} + + ${project.model.version} + com.baeldung.java.panama + java-panama + ${project.version} + java-panama + jar - com.baeldung.java.panama - java-panama - ${project.version} - jar + + + org.junit.jupiter + junit-jupiter + ${junit.jupiter.version} + test + + - java-panama - https://maven.apache.org + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + --add-opens=java.base/java.lang.foreign=ALL-UNNAMED + --enable-preview + + + + + - - 4.0.0 - UTF-8 - 1.0 - 19 - 19 - 3.10.1 - 5.9.0 - + + 4.0.0 + UTF-8 + 1.0 + 19 + 19 + 3.10.1 + 5.9.0 + - - - org.junit.jupiter - junit-jupiter - ${junit.jupiter.version} - test - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven.compiler.version} - - ${maven.compiler.source} - ${maven.compiler.target} - - --add-opens=java.base/java.lang.foreign=ALL-UNNAMED - --enable-preview - - - - - diff --git a/java-rmi/pom.xml b/java-rmi/pom.xml index fee5107423..2256883f84 100644 --- a/java-rmi/pom.xml +++ b/java-rmi/pom.xml @@ -5,7 +5,6 @@ 4.0.0 com.baeldung.rmi java-rmi - 1.0-SNAPSHOT java-rmi jar diff --git a/java-websocket/pom.xml b/java-websocket/pom.xml index 41c1b251c0..7c5c006aa9 100644 --- a/java-websocket/pom.xml +++ b/java-websocket/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 java-websocket - 0.0.1-SNAPSHOT java-websocket war diff --git a/javax-sound/pom.xml b/javax-sound/pom.xml index dcd08cbcb8..6652022a40 100644 --- a/javax-sound/pom.xml +++ b/javax-sound/pom.xml @@ -5,7 +5,6 @@ 4.0.0 com.baeldung.javax-sound javax-sound - 1.0-SNAPSHOT javax-sound jar diff --git a/javax-validation-advanced/pom.xml b/javax-validation-advanced/pom.xml index 39da166071..7709f37883 100644 --- a/javax-validation-advanced/pom.xml +++ b/javax-validation-advanced/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 javax-validation-advanced - 0.1-SNAPSHOT javax-validation-advanced diff --git a/javaxval-2/README.md b/javaxval-2/README.md index 52c9b42ac4..0fd5ce163b 100644 --- a/javaxval-2/README.md +++ b/javaxval-2/README.md @@ -4,7 +4,6 @@ This module contains articles about Bean Validation. ### Relevant Articles: - [Method Constraints with Bean Validation 2.0](https://www.baeldung.com/javax-validation-method-constraints) -- [Difference Between @NotNull, @NotEmpty, and @NotBlank Constraints in Bean Validation](https://www.baeldung.com/java-bean-validation-not-null-empty-blank) - [Guide to ParameterMessageInterpolator](https://www.baeldung.com/hibernate-parametermessageinterpolator) - [Hibernate Validator Annotation Processor in Depth](https://www.baeldung.com/hibernate-validator-annotation-processor) - More articles: [[<-- prev]](../javaxval) \ No newline at end of file diff --git a/javaxval/README.md b/javaxval/README.md index 95d9410fff..b7e19d5794 100644 --- a/javaxval/README.md +++ b/javaxval/README.md @@ -10,4 +10,5 @@ This module contains articles about Bean Validation. - [Grouping Javax Validation Constraints](https://www.baeldung.com/javax-validation-groups) - [Constraint Composition with Bean Validation](https://www.baeldung.com/java-bean-validation-constraint-composition) - [Using @NotNull on a Method Parameter](https://www.baeldung.com/java-notnull-method-parameter) +- [Difference Between @NotNull, @NotEmpty, and @NotBlank Constraints in Bean Validation](https://www.baeldung.com/java-bean-validation-not-null-empty-blank) - More articles: [[next -->]](../javaxval-2) \ No newline at end of file diff --git a/javaxval/pom.xml b/javaxval/pom.xml index 1feed71abb..bececb2ea7 100644 --- a/javaxval/pom.xml +++ b/javaxval/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 javaxval - 0.1-SNAPSHOT javaxval @@ -14,26 +13,6 @@ - - org.hibernate.validator - hibernate-validator - ${hibernate-validator.version} - - - org.glassfish - javax.el - ${javax.el.version} - - - org.springframework - spring-context - ${org.springframework.version} - - - org.springframework - spring-test - ${org.springframework.version} - org.springframework.boot spring-boot-starter-validation @@ -46,7 +25,7 @@ test - + @@ -58,11 +37,8 @@ - 6.2.3.Final 6.2.0.Final - 3.0.0 - 5.3.21 - 2.7.1 + 3.0.4 \ No newline at end of file diff --git a/javaxval/src/main/java/com/baeldung/javaxval/beanvalidation/User.java b/javaxval/src/main/java/com/baeldung/javaxval/beanvalidation/User.java index d583ac51d2..7305b6c201 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/beanvalidation/User.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/beanvalidation/User.java @@ -4,14 +4,14 @@ import java.time.LocalDate; import java.util.List; import java.util.Optional; -import javax.validation.constraints.AssertTrue; -import javax.validation.constraints.Email; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Past; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.AssertTrue; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Past; +import jakarta.validation.constraints.Size; public class User { diff --git a/javaxval/src/main/java/com/baeldung/javaxval/bigdecimal/Invoice.java b/javaxval/src/main/java/com/baeldung/javaxval/bigdecimal/Invoice.java index c14a6bd2b1..c946a8df68 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/bigdecimal/Invoice.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/bigdecimal/Invoice.java @@ -2,8 +2,8 @@ package com.baeldung.javaxval.bigdecimal; import java.math.BigDecimal; -import javax.validation.constraints.DecimalMin; -import javax.validation.constraints.Digits; +import jakarta.validation.constraints.DecimalMin; +import jakarta.validation.constraints.Digits; public class Invoice { 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 index 6e3408712b..65f6eceb34 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AlphanumericReturnValue.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AlphanumericReturnValue.java @@ -2,12 +2,12 @@ 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 jakarta.validation.Constraint; +import jakarta.validation.Payload; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraintvalidation.SupportedValidationTarget; +import jakarta.validation.constraintvalidation.ValidationTarget; import java.lang.annotation.Documented; import java.lang.annotation.Retention; 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 index 916b4e36a4..9d4d4995c5 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumeric.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumeric.java @@ -11,10 +11,10 @@ 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 jakarta.validation.Constraint; +import jakarta.validation.Payload; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; import org.hibernate.validator.constraints.Length; 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 index edc5b6af3e..31eca29a07 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumericWithSingleViolation.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumericWithSingleViolation.java @@ -11,11 +11,11 @@ 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 jakarta.validation.Constraint; +import jakarta.validation.Payload; +import jakarta.validation.ReportAsSingleViolation; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; import org.hibernate.validator.constraints.Length; 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 index 444cb4a63a..9f46e1e7b8 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidLengthOrNumericCharacter.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidLengthOrNumericCharacter.java @@ -4,9 +4,9 @@ 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 jakarta.validation.Constraint; +import jakarta.validation.Payload; +import jakarta.validation.constraints.Pattern; import java.lang.annotation.Documented; import java.lang.annotation.Retention; diff --git a/javaxval/src/main/java/com/baeldung/javaxval/container/validation/Customer.java b/javaxval/src/main/java/com/baeldung/javaxval/container/validation/Customer.java index 03811635ee..c0b23f0ae8 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/container/validation/Customer.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/container/validation/Customer.java @@ -4,9 +4,9 @@ import java.util.List; import java.util.Optional; import java.util.OptionalInt; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.PositiveOrZero; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.PositiveOrZero; public class Customer { diff --git a/javaxval/src/main/java/com/baeldung/javaxval/container/validation/CustomerMap.java b/javaxval/src/main/java/com/baeldung/javaxval/container/validation/CustomerMap.java index 554285fbae..902f04c654 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/container/validation/CustomerMap.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/container/validation/CustomerMap.java @@ -2,8 +2,8 @@ package com.baeldung.javaxval.container.validation; import java.util.Map; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; public class CustomerMap { diff --git a/javaxval/src/main/java/com/baeldung/javaxval/container/validation/valueextractors/ProfileValueExtractor.java b/javaxval/src/main/java/com/baeldung/javaxval/container/validation/valueextractors/ProfileValueExtractor.java index 03e0c7aac4..a3a21fe88b 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/container/validation/valueextractors/ProfileValueExtractor.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/container/validation/valueextractors/ProfileValueExtractor.java @@ -1,8 +1,8 @@ package com.baeldung.javaxval.container.validation.valueextractors; -import javax.validation.valueextraction.ExtractedValue; -import javax.validation.valueextraction.UnwrapByDefault; -import javax.validation.valueextraction.ValueExtractor; +import jakarta.validation.valueextraction.ExtractedValue; +import jakarta.validation.valueextraction.UnwrapByDefault; +import jakarta.validation.valueextraction.ValueExtractor; import com.baeldung.javaxval.container.validation.Profile; diff --git a/javaxval/src/main/java/com/baeldung/javaxval/enums/CustomerTypeSubSetValidator.java b/javaxval/src/main/java/com/baeldung/javaxval/enums/CustomerTypeSubSetValidator.java index c91f449bad..da86ec6c89 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/enums/CustomerTypeSubSetValidator.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/enums/CustomerTypeSubSetValidator.java @@ -2,8 +2,8 @@ package com.baeldung.javaxval.enums; import java.util.Arrays; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; import com.baeldung.javaxval.enums.constraints.CustomerTypeSubset; import com.baeldung.javaxval.enums.demo.CustomerType; diff --git a/javaxval/src/main/java/com/baeldung/javaxval/enums/EnumNamePatternValidator.java b/javaxval/src/main/java/com/baeldung/javaxval/enums/EnumNamePatternValidator.java index 3d56d40563..5cce8e10e7 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/enums/EnumNamePatternValidator.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/enums/EnumNamePatternValidator.java @@ -4,8 +4,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; import com.baeldung.javaxval.enums.constraints.EnumNamePattern; diff --git a/javaxval/src/main/java/com/baeldung/javaxval/enums/EnumSubSetValidator.java b/javaxval/src/main/java/com/baeldung/javaxval/enums/EnumSubSetValidator.java index 04cccb8b0c..a3a92a4f4e 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/enums/EnumSubSetValidator.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/enums/EnumSubSetValidator.java @@ -3,8 +3,8 @@ package com.baeldung.javaxval.enums; import java.lang.annotation.Annotation; import java.util.Arrays; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; public abstract class EnumSubSetValidator implements ConstraintValidator { private U[] subset; diff --git a/javaxval/src/main/java/com/baeldung/javaxval/enums/ValueOfEnumValidator.java b/javaxval/src/main/java/com/baeldung/javaxval/enums/ValueOfEnumValidator.java index 0203d63923..c2f2ecee3b 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/enums/ValueOfEnumValidator.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/enums/ValueOfEnumValidator.java @@ -4,8 +4,8 @@ import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; import com.baeldung.javaxval.enums.constraints.ValueOfEnum; diff --git a/javaxval/src/main/java/com/baeldung/javaxval/enums/constraints/CustomerTypeSubset.java b/javaxval/src/main/java/com/baeldung/javaxval/enums/constraints/CustomerTypeSubset.java index 97c2137f6a..fe03e228f6 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/enums/constraints/CustomerTypeSubset.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/enums/constraints/CustomerTypeSubset.java @@ -12,8 +12,8 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import javax.validation.Constraint; -import javax.validation.Payload; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; import com.baeldung.javaxval.enums.CustomerTypeSubSetValidator; import com.baeldung.javaxval.enums.demo.CustomerType; diff --git a/javaxval/src/main/java/com/baeldung/javaxval/enums/constraints/EnumNamePattern.java b/javaxval/src/main/java/com/baeldung/javaxval/enums/constraints/EnumNamePattern.java index 29fff857c8..4ef1eac9c0 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/enums/constraints/EnumNamePattern.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/enums/constraints/EnumNamePattern.java @@ -12,8 +12,8 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import javax.validation.Constraint; -import javax.validation.Payload; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; import com.baeldung.javaxval.enums.EnumNamePatternValidator; diff --git a/javaxval/src/main/java/com/baeldung/javaxval/enums/constraints/ValueOfEnum.java b/javaxval/src/main/java/com/baeldung/javaxval/enums/constraints/ValueOfEnum.java index 29b44a1793..bbfe6ed5ab 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/enums/constraints/ValueOfEnum.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/enums/constraints/ValueOfEnum.java @@ -12,8 +12,8 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import javax.validation.Constraint; -import javax.validation.Payload; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; import com.baeldung.javaxval.enums.ValueOfEnumValidator; diff --git a/javaxval/src/main/java/com/baeldung/javaxval/enums/demo/Customer.java b/javaxval/src/main/java/com/baeldung/javaxval/enums/demo/Customer.java index 15cd9e0da7..db38dd0015 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/enums/demo/Customer.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/enums/demo/Customer.java @@ -1,6 +1,6 @@ package com.baeldung.javaxval.enums.demo; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import com.baeldung.javaxval.enums.constraints.CustomerTypeSubset; import com.baeldung.javaxval.enums.constraints.EnumNamePattern; diff --git a/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/application/Application.java b/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/application/Application.java index 22157f351c..b1c53c5be3 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/application/Application.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/application/Application.java @@ -1,7 +1,7 @@ package com.baeldung.javaxval.javabeanconstraints.application; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import com.baeldung.javaxval.javabeanconstraints.entities.UserNotBlank; diff --git a/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/entities/UserNotBlank.java b/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/entities/UserNotBlank.java index 5542be8c25..1a6c634ed4 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/entities/UserNotBlank.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/entities/UserNotBlank.java @@ -1,6 +1,6 @@ package com.baeldung.javaxval.javabeanconstraints.entities; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; public class UserNotBlank { diff --git a/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/entities/UserNotEmpty.java b/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/entities/UserNotEmpty.java index e3dbe27b0e..0e01c41388 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/entities/UserNotEmpty.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/entities/UserNotEmpty.java @@ -1,6 +1,6 @@ package com.baeldung.javaxval.javabeanconstraints.entities; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; public class UserNotEmpty { diff --git a/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/entities/UserNotNull.java b/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/entities/UserNotNull.java index b3a0f90d36..39164e2f6b 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/entities/UserNotNull.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/javabeanconstraints/entities/UserNotNull.java @@ -1,6 +1,6 @@ package com.baeldung.javaxval.javabeanconstraints.entities; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; public class UserNotNull { diff --git a/javaxval/src/main/java/com/baeldung/javaxval/validationgroup/CompleteInfo.java b/javaxval/src/main/java/com/baeldung/javaxval/validationgroup/CompleteInfo.java index 4ecdc3c5f1..22c0b01ddf 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/validationgroup/CompleteInfo.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/validationgroup/CompleteInfo.java @@ -1,6 +1,6 @@ package com.baeldung.javaxval.validationgroup; -import javax.validation.GroupSequence; +import jakarta.validation.GroupSequence; @GroupSequence({ BasicInfo.class, AdvanceInfo.class }) public interface CompleteInfo { diff --git a/javaxval/src/main/java/com/baeldung/javaxval/validationgroup/RegistrationForm.java b/javaxval/src/main/java/com/baeldung/javaxval/validationgroup/RegistrationForm.java index a30a074556..2f759d633d 100644 --- a/javaxval/src/main/java/com/baeldung/javaxval/validationgroup/RegistrationForm.java +++ b/javaxval/src/main/java/com/baeldung/javaxval/validationgroup/RegistrationForm.java @@ -1,7 +1,7 @@ package com.baeldung.javaxval.validationgroup; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; public class RegistrationForm { @NotBlank(groups = BasicInfo.class) diff --git a/javaxval/src/test/java/com/baeldung/javaxval/beanvalidation/ValidationIntegrationTest.java b/javaxval/src/test/java/com/baeldung/javaxval/beanvalidation/ValidationIntegrationTest.java index 3e60fa7acd..132dddad5d 100644 --- a/javaxval/src/test/java/com/baeldung/javaxval/beanvalidation/ValidationIntegrationTest.java +++ b/javaxval/src/test/java/com/baeldung/javaxval/beanvalidation/ValidationIntegrationTest.java @@ -6,10 +6,10 @@ import java.time.LocalDate; import java.util.Collections; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.junit.Before; import org.junit.Test; diff --git a/javaxval/src/test/java/com/baeldung/javaxval/bigdecimal/InvoiceUnitTest.java b/javaxval/src/test/java/com/baeldung/javaxval/bigdecimal/InvoiceUnitTest.java index 801d7966a5..a149a3a6fe 100644 --- a/javaxval/src/test/java/com/baeldung/javaxval/bigdecimal/InvoiceUnitTest.java +++ b/javaxval/src/test/java/com/baeldung/javaxval/bigdecimal/InvoiceUnitTest.java @@ -4,9 +4,9 @@ import com.baeldung.javaxval.LocaleAwareUnitTest; import org.junit.BeforeClass; import org.junit.Test; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import java.math.BigDecimal; import java.util.Set; 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 index 6c2b8f801c..918944cd5f 100644 --- a/javaxval/src/test/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionUnitTest.java +++ b/javaxval/src/test/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionUnitTest.java @@ -5,11 +5,11 @@ 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 jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.junit.Before; import org.junit.Test; diff --git a/javaxval/src/test/java/com/baeldung/javaxval/container/validation/ContainerValidationIntegrationTest.java b/javaxval/src/test/java/com/baeldung/javaxval/container/validation/ContainerValidationIntegrationTest.java index d96b641442..5c50fde7c6 100644 --- a/javaxval/src/test/java/com/baeldung/javaxval/container/validation/ContainerValidationIntegrationTest.java +++ b/javaxval/src/test/java/com/baeldung/javaxval/container/validation/ContainerValidationIntegrationTest.java @@ -6,10 +6,10 @@ import java.util.Collections; import java.util.OptionalInt; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import com.baeldung.javaxval.container.validation.valueextractors.ProfileValueExtractor; import org.junit.Before; diff --git a/javaxval/src/test/java/com/baeldung/javaxval/enums/CustomerTypeSubSetValidatorUnitTest.java b/javaxval/src/test/java/com/baeldung/javaxval/enums/CustomerTypeSubSetValidatorUnitTest.java index 524f8eec36..7ccd840e8c 100644 --- a/javaxval/src/test/java/com/baeldung/javaxval/enums/CustomerTypeSubSetValidatorUnitTest.java +++ b/javaxval/src/test/java/com/baeldung/javaxval/enums/CustomerTypeSubSetValidatorUnitTest.java @@ -4,9 +4,9 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import org.junit.BeforeClass; import org.junit.Test; diff --git a/javaxval/src/test/java/com/baeldung/javaxval/enums/EnumNamePatternValidatorUnitTest.java b/javaxval/src/test/java/com/baeldung/javaxval/enums/EnumNamePatternValidatorUnitTest.java index 805d40ee5e..0556f88832 100644 --- a/javaxval/src/test/java/com/baeldung/javaxval/enums/EnumNamePatternValidatorUnitTest.java +++ b/javaxval/src/test/java/com/baeldung/javaxval/enums/EnumNamePatternValidatorUnitTest.java @@ -6,9 +6,9 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import org.junit.BeforeClass; import org.junit.Test; diff --git a/javaxval/src/test/java/com/baeldung/javaxval/enums/ValueOfEnumValidatorUnitTest.java b/javaxval/src/test/java/com/baeldung/javaxval/enums/ValueOfEnumValidatorUnitTest.java index 150da5d83b..c7eb740d86 100644 --- a/javaxval/src/test/java/com/baeldung/javaxval/enums/ValueOfEnumValidatorUnitTest.java +++ b/javaxval/src/test/java/com/baeldung/javaxval/enums/ValueOfEnumValidatorUnitTest.java @@ -4,9 +4,9 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import org.junit.BeforeClass; import org.junit.Test; diff --git a/javaxval/src/test/java/com/baeldung/javaxval/enums/demo/CustomerUnitTest.java b/javaxval/src/test/java/com/baeldung/javaxval/enums/demo/CustomerUnitTest.java index 02a49f50fa..c4380f75fa 100644 --- a/javaxval/src/test/java/com/baeldung/javaxval/enums/demo/CustomerUnitTest.java +++ b/javaxval/src/test/java/com/baeldung/javaxval/enums/demo/CustomerUnitTest.java @@ -5,9 +5,9 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.Set; import java.util.function.Predicate; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import org.junit.BeforeClass; import org.junit.Test; diff --git a/javaxval/src/test/java/com/baeldung/javaxval/javabeanconstraints/UserNotBlankUnitTest.java b/javaxval/src/test/java/com/baeldung/javaxval/javabeanconstraints/UserNotBlankUnitTest.java index 4cb87e8e27..68e48de41d 100644 --- a/javaxval/src/test/java/com/baeldung/javaxval/javabeanconstraints/UserNotBlankUnitTest.java +++ b/javaxval/src/test/java/com/baeldung/javaxval/javabeanconstraints/UserNotBlankUnitTest.java @@ -4,9 +4,9 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import com.baeldung.javaxval.javabeanconstraints.entities.UserNotBlank; import org.junit.BeforeClass; diff --git a/javaxval/src/test/java/com/baeldung/javaxval/javabeanconstraints/UserNotEmptyUnitTest.java b/javaxval/src/test/java/com/baeldung/javaxval/javabeanconstraints/UserNotEmptyUnitTest.java index eb76ac260c..bd83d30601 100644 --- a/javaxval/src/test/java/com/baeldung/javaxval/javabeanconstraints/UserNotEmptyUnitTest.java +++ b/javaxval/src/test/java/com/baeldung/javaxval/javabeanconstraints/UserNotEmptyUnitTest.java @@ -4,9 +4,9 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import com.baeldung.javaxval.javabeanconstraints.entities.UserNotEmpty; import org.junit.BeforeClass; diff --git a/javaxval/src/test/java/com/baeldung/javaxval/javabeanconstraints/UserNotNullUnitTest.java b/javaxval/src/test/java/com/baeldung/javaxval/javabeanconstraints/UserNotNullUnitTest.java index f0280000de..36874f4f21 100644 --- a/javaxval/src/test/java/com/baeldung/javaxval/javabeanconstraints/UserNotNullUnitTest.java +++ b/javaxval/src/test/java/com/baeldung/javaxval/javabeanconstraints/UserNotNullUnitTest.java @@ -4,9 +4,9 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import com.baeldung.javaxval.javabeanconstraints.entities.UserNotNull; import org.junit.BeforeClass; diff --git a/javaxval/src/test/java/com/baeldung/javaxval/validationgroup/RegistrationFormUnitTest.java b/javaxval/src/test/java/com/baeldung/javaxval/validationgroup/RegistrationFormUnitTest.java index 3333703328..52aadf80b0 100644 --- a/javaxval/src/test/java/com/baeldung/javaxval/validationgroup/RegistrationFormUnitTest.java +++ b/javaxval/src/test/java/com/baeldung/javaxval/validationgroup/RegistrationFormUnitTest.java @@ -4,9 +4,9 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import org.junit.BeforeClass; import org.junit.Test; diff --git a/jaxb/pom.xml b/jaxb/pom.xml index a7f0324bc0..ac448d2d62 100644 --- a/jaxb/pom.xml +++ b/jaxb/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jaxb - 0.0.1-SNAPSHOT jaxb diff --git a/jaxb/src/test/java/com/baeldung/jaxb/test/JaxbIntegrationTest.java b/jaxb/src/test/java/com/baeldung/jaxb/test/JaxbIntegrationTest.java index 18960b1d9e..9117bb621e 100644 --- a/jaxb/src/test/java/com/baeldung/jaxb/test/JaxbIntegrationTest.java +++ b/jaxb/src/test/java/com/baeldung/jaxb/test/JaxbIntegrationTest.java @@ -48,7 +48,7 @@ public class JaxbIntegrationTest { } @Test - public void unMashal() throws JAXBException, IOException { + public void unmarshal() throws JAXBException, IOException { Unmarshaller unmarshaller = context.createUnmarshaller(); String bookFile = this.getClass().getResource("/book.xml").getFile(); Book unMarshallerbook = (Book) unmarshaller.unmarshal(new FileReader(bookFile)); diff --git a/jenkins-modules/jenkins-jobs/README.md b/jenkins-modules/jenkins-jobs/README.md index f58761997e..e6de0d57e0 100644 --- a/jenkins-modules/jenkins-jobs/README.md +++ b/jenkins-modules/jenkins-jobs/README.md @@ -4,3 +4,4 @@ - [Jenkins Pipeline – Change to Another Folder](https://www.baeldung.com/ops/jenkins-pipeline-change-to-another-folder) - [How to Stop a Zombie Job on Jenkins Without Restarting the Server?](https://www.baeldung.com/ops/stop-zombie-job-on-jenkins-without-restarting-the-server) - [Running Stages in Parallel With Jenkins Workflow / Pipeline](https://www.baeldung.com/ops/running-stages-in-parallel-jenkins-workflow-pipeline) +- [Skip a Stage in a Jenkins Pipeline](https://www.baeldung.com/ops/jenkins-pipeline-skip-stage) diff --git a/jenkins-modules/jenkins-jobs/skip-stage-job/skip-function-script b/jenkins-modules/jenkins-jobs/skip-stage-job/skip-function-script new file mode 100644 index 0000000000..62163d6301 --- /dev/null +++ b/jenkins-modules/jenkins-jobs/skip-stage-job/skip-function-script @@ -0,0 +1,32 @@ +pipeline { + agent any + parameters { + booleanParam(name: 'skip_test', defaultValue: false, description: 'Set to true to skip the test stage') + } + stages { + stage('Build') { + steps { + sh 'echo "Building the application"' + } + } + stage('Test') { + steps { + execute_stage('Test', params.skip_test) + } + } + stage('Deploy') { + steps { + sh 'echo "Deploying the application"' + } + } + } +} + +def execute_stage(stage_name, skip) { + stage(stage_name) { + if(skip) { + echo "Skipping ${stage_name} stage" + return + } + // Add steps to test the application + } diff --git a/jenkins-modules/jenkins-jobs/skip-stage-job/skip-input-script b/jenkins-modules/jenkins-jobs/skip-stage-job/skip-input-script new file mode 100644 index 0000000000..ba5560578a --- /dev/null +++ b/jenkins-modules/jenkins-jobs/skip-stage-job/skip-input-script @@ -0,0 +1,29 @@ +pipeline { + agent any + stages { + stage('Build') { + steps { + sh 'echo "Building the application"' + // Add steps to build the application + } + } + stage('Test') { + steps { + input message: 'Do you want to skip the test stage?', ok: 'Yes', parameters: [booleanParam(name: 'skip_test', defaultValue: false)], timeout: time(minutes: 5)) + script { + if(params.skip_test) { + sh 'echo "Testing the application"' + return + } + } + // Add steps to test the application + } + } + stage('Deploy') { + steps { + sh 'echo "Deploying the application"' + // Add steps to deploy the application + } + } + } +} diff --git a/jenkins-modules/jenkins-jobs/skip-stage-job/skip-when-script b/jenkins-modules/jenkins-jobs/skip-stage-job/skip-when-script new file mode 100644 index 0000000000..0b62a819e1 --- /dev/null +++ b/jenkins-modules/jenkins-jobs/skip-stage-job/skip-when-script @@ -0,0 +1,27 @@ +pipeline { + agent any + parameters { + booleanParam(name: 'skip_test', defaultValue: false, description: 'Set to true to skip the test stage') + } + stages { + stage('Build') { + steps { + sh 'echo "Building application"' + // Add build steps here + } + } + stage('Test') { + when { expression { params.skip_test != true } } + steps { + sh 'echo "Testing application"' + // Add test steps here + } + } + stage('Deploy') { + steps { + sh 'echo "Deploying application"' + // Add deployment steps here + } + } + } +} diff --git a/jenkins-modules/plugins/pom.xml b/jenkins-modules/plugins/pom.xml index 7f88382e22..42add1664e 100644 --- a/jenkins-modules/plugins/pom.xml +++ b/jenkins-modules/plugins/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 plugins - 1.0-SNAPSHOT plugins hpi A sample Jenkins Hello World plugin diff --git a/jersey/pom.xml b/jersey/pom.xml index 9a212c6da1..005fa85077 100644 --- a/jersey/pom.xml +++ b/jersey/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jersey - 0.0.1-SNAPSHOT jersey war diff --git a/jersey/src/test/java/com/baeldung/jersey/server/EchoHeadersUnitTest.java b/jersey/src/test/java/com/baeldung/jersey/server/EchoHeadersIntegrationTest.java similarity index 99% rename from jersey/src/test/java/com/baeldung/jersey/server/EchoHeadersUnitTest.java rename to jersey/src/test/java/com/baeldung/jersey/server/EchoHeadersIntegrationTest.java index 96b5dfb260..e6f06383db 100644 --- a/jersey/src/test/java/com/baeldung/jersey/server/EchoHeadersUnitTest.java +++ b/jersey/src/test/java/com/baeldung/jersey/server/EchoHeadersIntegrationTest.java @@ -16,7 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import jakarta.ws.rs.core.Application; import jakarta.ws.rs.core.Response; -public class EchoHeadersUnitTest extends JerseyTest { +public class EchoHeadersIntegrationTest extends JerseyTest { private static final String SIMPLE_HEADER_KEY = "my-header-key"; private static final String SIMPLE_HEADER_VALUE = "my-header-value"; diff --git a/jetbrains/README.md b/jetbrains/README.md index a63d4dffba..c8872ec46e 100644 --- a/jetbrains/README.md +++ b/jetbrains/README.md @@ -3,3 +3,4 @@ This module contains articles about Jetbrains' libraries. ### Relevant articles: +- [JetBrains @Contract Annotation](https://www.baeldung.com/jetbrains-contract-annotation) diff --git a/jetbrains/pom.xml b/jetbrains/pom.xml index a10fd3b913..ec46dc54f0 100644 --- a/jetbrains/pom.xml +++ b/jetbrains/pom.xml @@ -7,7 +7,6 @@ 1.0-SNAPSHOT jetbrains jar - http://maven.apache.org com.baeldung diff --git a/jgit/pom.xml b/jgit/pom.xml index 91881fbec8..1b0d82e4d7 100644 --- a/jgit/pom.xml +++ b/jgit/pom.xml @@ -4,10 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jgit - 1.0-SNAPSHOT jgit jar - http://maven.apache.org com.baeldung @@ -15,14 +13,6 @@ 1.0.0-SNAPSHOT - - - jgit-repository - https://repo.eclipse.org/content/groups/releases/ - - - - org.eclipse.jgit @@ -36,6 +26,12 @@ + + + jgit-repository + https://repo.eclipse.org/content/groups/releases/ + + 4.5.0.201609210915-r diff --git a/jhipster-5/bookstore-monolith/.yo-rc.json b/jhipster-5/bookstore-monolith/.yo-rc.json deleted file mode 100644 index d852aeeddc..0000000000 --- a/jhipster-5/bookstore-monolith/.yo-rc.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "generator-jhipster": { - "promptValues": { - "packageName": "com.baeldung.jhipster5" - }, - "jhipsterVersion": "5.8.2", - "applicationType": "monolith", - "baseName": "Bookstore", - "packageName": "com.baeldung.jhipster5", - "packageFolder": "com/baeldung/jhipster5", - "serverPort": "8080", - "authenticationType": "jwt", - "cacheProvider": "no", - "websocket": false, - "databaseType": "sql", - "devDatabaseType": "h2Memory", - "prodDatabaseType": "mysql", - "searchEngine": false, - "messageBroker": false, - "serviceDiscoveryType": false, - "buildTool": "maven", - "enableSwaggerCodegen": false, - "jwtSecretKey": "NDJmOTVlZjI2NzhlZDRjNmVkNTM1NDE2NjkyNDljZDJiNzBlMjI5YmZjMjY3MzdjZmZlMjI3NjE4OTRkNzc5MWYzNDNlYWMzYmJjOWRmMjc5ZWQyZTZmOWZkOTMxZWZhNWE1MTVmM2U2NjFmYjhlNDc2Y2Q3NzliMGY0YzFkNmI=", - "clientFramework": "angularX", - "useSass": true, - "clientPackageManager": "npm", - "testFrameworks": [], - "jhiPrefix": "jhi", - "entitySuffix": "", - "dtoSuffix": "DTO", - "otherModules": [], - "enableTranslation": false - } -} diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/audit/package-info.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/audit/package-info.java deleted file mode 100644 index 49a2a73a61..0000000000 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/audit/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Audit specific code. - */ -package com.baeldung.jhipster5.config.audit; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/package-info.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/package-info.java deleted file mode 100644 index eba92a598e..0000000000 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * JPA domain objects. - */ -package com.baeldung.jhipster5.domain; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/package-info.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/package-info.java deleted file mode 100644 index a5002eb201..0000000000 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Spring Data JPA repositories. - */ -package com.baeldung.jhipster5.repository; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/package-info.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/package-info.java deleted file mode 100644 index 87951796ea..0000000000 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Data Transfer Objects. - */ -package com.baeldung.jhipster5.service.dto; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/package-info.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/package-info.java deleted file mode 100644 index a54ed5cca0..0000000000 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Service layer beans. - */ -package com.baeldung.jhipster5.service; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/package-info.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/package-info.java deleted file mode 100644 index 75bf6840f6..0000000000 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Spring MVC REST controllers. - */ -package com.baeldung.jhipster5.web.rest; diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/logs/logs.component.spec.ts b/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/logs/logs.component.spec.ts deleted file mode 100644 index def356c0f2..0000000000 --- a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/logs/logs.component.spec.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { of } from 'rxjs'; -import { HttpHeaders, HttpResponse } from '@angular/common/http'; - -import { BookstoreTestModule } from '../../../test.module'; -import { LogsComponent } from 'app/admin/logs/logs.component'; -import { LogsService } from 'app/admin/logs/logs.service'; -import { ITEMS_PER_PAGE } from 'app/shared'; -import { Log } from 'app/admin'; - -describe('Component Tests', () => { - describe('LogsComponent', () => { - let comp: LogsComponent; - let fixture: ComponentFixture; - let service: LogsService; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [BookstoreTestModule], - declarations: [LogsComponent], - providers: [LogsService] - }) - .overrideTemplate(LogsComponent, '') - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(LogsComponent); - comp = fixture.componentInstance; - service = fixture.debugElement.injector.get(LogsService); - }); - - describe('OnInit', () => { - it('should set all default values correctly', () => { - expect(comp.filter).toBe(''); - expect(comp.orderProp).toBe('name'); - expect(comp.reverse).toBe(false); - }); - it('Should call load all on init', () => { - // GIVEN - const headers = new HttpHeaders().append('link', 'link;link'); - const log = new Log('main', 'WARN'); - spyOn(service, 'findAll').and.returnValue( - of( - new HttpResponse({ - body: [log], - headers - }) - ) - ); - - // WHEN - comp.ngOnInit(); - - // THEN - expect(service.findAll).toHaveBeenCalled(); - expect(comp.loggers[0]).toEqual(jasmine.objectContaining(log)); - }); - }); - describe('change log level', () => { - it('should change log level correctly', () => { - // GIVEN - const log = new Log('main', 'ERROR'); - spyOn(service, 'changeLevel').and.returnValue(of(new HttpResponse())); - spyOn(service, 'findAll').and.returnValue(of(new HttpResponse({ body: [log] }))); - - // WHEN - comp.changeLevel('main', 'ERROR'); - - // THEN - expect(service.changeLevel).toHaveBeenCalled(); - expect(service.findAll).toHaveBeenCalled(); - expect(comp.loggers[0]).toEqual(jasmine.objectContaining(log)); - }); - }); - }); -}); diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/logs/logs.service.spec.ts b/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/logs/logs.service.spec.ts deleted file mode 100644 index c34833922e..0000000000 --- a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/logs/logs.service.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { LogsService } from 'app/admin/logs/logs.service'; -import { Log } from 'app/admin/logs/log.model'; -import { SERVER_API_URL } from 'app/app.constants'; -import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; - -describe('Service Tests', () => { - describe('Logs Service', () => { - let service: LogsService; - let httpMock; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [HttpClientTestingModule] - }); - - service = TestBed.get(LogsService); - httpMock = TestBed.get(HttpTestingController); - }); - - afterEach(() => { - httpMock.verify(); - }); - - describe('Service methods', () => { - it('should call correct URL', () => { - service.findAll().subscribe(() => {}); - - const req = httpMock.expectOne({ method: 'GET' }); - const resourceUrl = SERVER_API_URL + 'management/logs'; - expect(req.request.url).toEqual(resourceUrl); - }); - - it('should return Logs', () => { - const log = new Log('main', 'ERROR'); - - service.findAll().subscribe(received => { - expect(received.body[0]).toEqual(log); - }); - - const req = httpMock.expectOne({ method: 'GET' }); - req.flush([log]); - }); - - it('should change log level', () => { - const log = new Log('main', 'ERROR'); - - service.changeLevel(log).subscribe(received => { - expect(received.body[0]).toEqual(log); - }); - - const req = httpMock.expectOne({ method: 'PUT' }); - req.flush([log]); - }); - }); - }); -}); diff --git a/jhipster-5/README.md b/jhipster-6/README.md similarity index 89% rename from jhipster-5/README.md rename to jhipster-6/README.md index ba05641af0..9db409a032 100644 --- a/jhipster-5/README.md +++ b/jhipster-6/README.md @@ -1,3 +1,3 @@ -## JHipster 5 +## JHipster 6 This module contains articles about JHipster 5. This is an aggregator module, articles are in the relevant submodules. diff --git a/jhipster-5/bookstore-monolith/.editorconfig b/jhipster-6/bookstore-monolith/.editorconfig similarity index 100% rename from jhipster-5/bookstore-monolith/.editorconfig rename to jhipster-6/bookstore-monolith/.editorconfig diff --git a/jhipster-5/bookstore-monolith/.gitattributes b/jhipster-6/bookstore-monolith/.gitattributes similarity index 100% rename from jhipster-5/bookstore-monolith/.gitattributes rename to jhipster-6/bookstore-monolith/.gitattributes diff --git a/jhipster-5/bookstore-monolith/.gitignore b/jhipster-6/bookstore-monolith/.gitignore similarity index 100% rename from jhipster-5/bookstore-monolith/.gitignore rename to jhipster-6/bookstore-monolith/.gitignore diff --git a/jhipster-5/bookstore-monolith/.huskyrc b/jhipster-6/bookstore-monolith/.huskyrc similarity index 100% rename from jhipster-5/bookstore-monolith/.huskyrc rename to jhipster-6/bookstore-monolith/.huskyrc diff --git a/jhipster-5/bookstore-monolith/.jhipster/Book.json b/jhipster-6/bookstore-monolith/.jhipster/Book.json similarity index 100% rename from jhipster-5/bookstore-monolith/.jhipster/Book.json rename to jhipster-6/bookstore-monolith/.jhipster/Book.json diff --git a/jhipster-5/bookstore-monolith/.mvn/wrapper/MavenWrapperDownloader.java b/jhipster-6/bookstore-monolith/.mvn/wrapper/MavenWrapperDownloader.java similarity index 100% rename from jhipster-5/bookstore-monolith/.mvn/wrapper/MavenWrapperDownloader.java rename to jhipster-6/bookstore-monolith/.mvn/wrapper/MavenWrapperDownloader.java diff --git a/jhipster-5/bookstore-monolith/.mvn/wrapper/maven-wrapper.jar b/jhipster-6/bookstore-monolith/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from jhipster-5/bookstore-monolith/.mvn/wrapper/maven-wrapper.jar rename to jhipster-6/bookstore-monolith/.mvn/wrapper/maven-wrapper.jar diff --git a/jhipster-5/bookstore-monolith/.mvn/wrapper/maven-wrapper.properties b/jhipster-6/bookstore-monolith/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from jhipster-5/bookstore-monolith/.mvn/wrapper/maven-wrapper.properties rename to jhipster-6/bookstore-monolith/.mvn/wrapper/maven-wrapper.properties diff --git a/jhipster-5/bookstore-monolith/.prettierignore b/jhipster-6/bookstore-monolith/.prettierignore similarity index 100% rename from jhipster-5/bookstore-monolith/.prettierignore rename to jhipster-6/bookstore-monolith/.prettierignore diff --git a/jhipster-5/bookstore-monolith/.prettierrc b/jhipster-6/bookstore-monolith/.prettierrc similarity index 100% rename from jhipster-5/bookstore-monolith/.prettierrc rename to jhipster-6/bookstore-monolith/.prettierrc diff --git a/jhipster-6/bookstore-monolith/.yo-rc.json b/jhipster-6/bookstore-monolith/.yo-rc.json new file mode 100644 index 0000000000..3ec14d8ada --- /dev/null +++ b/jhipster-6/bookstore-monolith/.yo-rc.json @@ -0,0 +1,36 @@ +{ + "generator-jhipster": { + "promptValues": { + "packageName": "com.baeldung.jhipster5" + }, + "jhipsterVersion": "6.0.0", + "applicationType": "monolith", + "baseName": "Bookstore", + "packageName": "com.baeldung.jhipster5", + "packageFolder": "com/baeldung/jhipster5", + "serverPort": "8080", + "authenticationType": "jwt", + "cacheProvider": "no", + "websocket": false, + "databaseType": "sql", + "devDatabaseType": "h2Memory", + "prodDatabaseType": "mysql", + "searchEngine": false, + "messageBroker": false, + "serviceDiscoveryType": false, + "buildTool": "maven", + "enableSwaggerCodegen": false, + "jwtSecretKey": "NDJmOTVlZjI2NzhlZDRjNmVkNTM1NDE2NjkyNDljZDJiNzBlMjI5YmZjMjY3MzdjZmZlMjI3NjE4OTRkNzc5MWYzNDNlYWMzYmJjOWRmMjc5ZWQyZTZmOWZkOTMxZWZhNWE1MTVmM2U2NjFmYjhlNDc2Y2Q3NzliMGY0YzFkNmI=", + "clientFramework": "angularX", + "useSass": true, + "clientPackageManager": "npm", + "testFrameworks": [], + "jhiPrefix": "jhi", + "entitySuffix": "", + "dtoSuffix": "DTO", + "otherModules": [], + "enableTranslation": false, + "enableHibernateCache": false, + "clientTheme": "none" + } +} \ No newline at end of file diff --git a/jhipster-5/bookstore-monolith/README.md b/jhipster-6/bookstore-monolith/README.md similarity index 100% rename from jhipster-5/bookstore-monolith/README.md rename to jhipster-6/bookstore-monolith/README.md diff --git a/jhipster-5/bookstore-monolith/angular.json b/jhipster-6/bookstore-monolith/angular.json similarity index 100% rename from jhipster-5/bookstore-monolith/angular.json rename to jhipster-6/bookstore-monolith/angular.json diff --git a/jhipster-5/bookstore-monolith/mvnw b/jhipster-6/bookstore-monolith/mvnw old mode 100755 new mode 100644 similarity index 100% rename from jhipster-5/bookstore-monolith/mvnw rename to jhipster-6/bookstore-monolith/mvnw diff --git a/jhipster-5/bookstore-monolith/mvnw.cmd b/jhipster-6/bookstore-monolith/mvnw.cmd similarity index 100% rename from jhipster-5/bookstore-monolith/mvnw.cmd rename to jhipster-6/bookstore-monolith/mvnw.cmd diff --git a/jhipster-5/bookstore-monolith/package.json b/jhipster-6/bookstore-monolith/package.json similarity index 99% rename from jhipster-5/bookstore-monolith/package.json rename to jhipster-6/bookstore-monolith/package.json index 46b920edb3..76b74a4312 100644 --- a/jhipster-5/bookstore-monolith/package.json +++ b/jhipster-6/bookstore-monolith/package.json @@ -51,7 +51,7 @@ "file-loader": "3.0.1", "fork-ts-checker-webpack-plugin": "0.5.2", "friendly-errors-webpack-plugin": "1.7.0", - "generator-jhipster": "5.8.2", + "generator-jhipster": "6.0.0", "html-loader": "0.5.5", "html-webpack-plugin": "3.2.0", "husky": "1.3.1", diff --git a/jhipster-5/bookstore-monolith/pom.xml b/jhipster-6/bookstore-monolith/pom.xml similarity index 89% rename from jhipster-5/bookstore-monolith/pom.xml rename to jhipster-6/bookstore-monolith/pom.xml index ccaa802a39..f719baab8b 100644 --- a/jhipster-5/bookstore-monolith/pom.xml +++ b/jhipster-6/bookstore-monolith/pom.xml @@ -2,14 +2,14 @@ 4.0.0 - com.baeldung.jhipster5 + com.baeldung.jhipster6 bookstore-monolith 0.0.1-SNAPSHOT war bookstore-monolith - jhipster-5 + jhipster-6 com.baeldung.jhipster 1.0.0-SNAPSHOT @@ -41,8 +41,25 @@ io.github.jhipster jhipster-framework + 3.0.1 + + + jakarta.xml.bind + jakarta.xml.bind-api + 4.0.0 + + + + org.glassfish.jaxb + jaxb-runtime + 4.0.0 + + + + + com.fasterxml.jackson.datatype jackson-datatype-hibernate5 @@ -78,10 +95,10 @@ io.springfox springfox-bean-validators - - com.mattbertolini - liquibase-slf4j - + + + + com.zaxxer HikariCP @@ -94,6 +111,10 @@ org.apache.commons commons-lang3 + + mysql + mysql-connector-java + org.assertj assertj-core @@ -120,9 +141,13 @@ net.logstash.logback logstash-logback-encoder + + + + org.mapstruct - mapstruct-jdk8 + mapstruct org.mapstruct @@ -269,6 +294,11 @@ hibernate-jpamodelgen ${hibernate.version} + + org.glassfish.jaxb + jaxb-runtime + ${jaxb-runtime.version} + @@ -492,9 +522,8 @@ [${maven.version},) - - You are running an incompatible version of Java. JHipster requires JDK ${java.version} - [1.8,1.9) + You are running an incompatible version of Java. JHipster supports JDK 11. + [${java.version},) @@ -681,6 +710,9 @@ npm + + install --legacy-peer-deps + webpack build dev @@ -1023,135 +1055,12 @@ - - - default-first - - - - - com.github.eirslett - frontend-maven-plugin - - - - install node and npm - none - - - npm install - none - - - webpack build dev - none - - - webpack build test - none - - - - - - - - default-second - - - - - com.github.eirslett - frontend-maven-plugin - - - - install node and npm - none - - - npm install - none - - - webpack build dev - none - - - webpack build test - none - - - - - - - - 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 - - - - - - 3.0.0 - 1.8 + 11 2.12.6 v10.15.0 6.4.1 @@ -1168,34 +1077,36 @@ - 2.1.1 + 3.0.1 - 2.7.8 + 2.7.5 - 5.2.17.Final + 5.3.9.Final - 3.22.0-GA + 3.23.1-GA - 3.5.5 + 3.6.3 3.6 + 5.1.5.RELEASE 2.0.1.Final - 1.2.0.Final + 2.3.2 + 1.3.0.Final 3.1.0 3.8.0 2.10 - 3.0.0-M2 + 3.0.0-M1 2.2.1 3.1.0 - 2.22.2 + 3.0.0-M3 3.2.2 0.9.11 - 1.6 + 1.7.6 0.8.2 1.0.0 3.4.2 diff --git a/jhipster-5/bookstore-monolith/postcss.config.js b/jhipster-6/bookstore-monolith/postcss.config.js similarity index 100% rename from jhipster-5/bookstore-monolith/postcss.config.js rename to jhipster-6/bookstore-monolith/postcss.config.js diff --git a/jhipster-5/bookstore-monolith/proxy.conf.json b/jhipster-6/bookstore-monolith/proxy.conf.json similarity index 100% rename from jhipster-5/bookstore-monolith/proxy.conf.json rename to jhipster-6/bookstore-monolith/proxy.conf.json diff --git a/jhipster-5/bookstore-monolith/src/main/docker/.dockerignore b/jhipster-6/bookstore-monolith/src/main/docker/.dockerignore similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/docker/.dockerignore rename to jhipster-6/bookstore-monolith/src/main/docker/.dockerignore diff --git a/jhipster-5/bookstore-monolith/src/main/docker/Dockerfile b/jhipster-6/bookstore-monolith/src/main/docker/Dockerfile similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/docker/Dockerfile rename to jhipster-6/bookstore-monolith/src/main/docker/Dockerfile diff --git a/jhipster-5/bookstore-monolith/src/main/docker/app.yml b/jhipster-6/bookstore-monolith/src/main/docker/app.yml similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/docker/app.yml rename to jhipster-6/bookstore-monolith/src/main/docker/app.yml diff --git a/jhipster-5/bookstore-monolith/src/main/docker/entrypoint.sh b/jhipster-6/bookstore-monolith/src/main/docker/entrypoint.sh similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/docker/entrypoint.sh rename to jhipster-6/bookstore-monolith/src/main/docker/entrypoint.sh diff --git a/jhipster-6/bookstore-monolith/src/main/docker/grafana/provisioning/dashboards/JVM.json b/jhipster-6/bookstore-monolith/src/main/docker/grafana/provisioning/dashboards/JVM.json new file mode 100644 index 0000000000..b299032c99 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/docker/grafana/provisioning/dashboards/JVM.json @@ -0,0 +1,3778 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "limit": 100, + "name": "Annotations & Alerts", + "showIn": 0, + "type": "dashboard" + }, + { + "datasource": "Prometheus", + "enable": true, + "expr": "resets(process_uptime_seconds{application=\"$application\", instance=\"$instance\"}[1m]) > 0", + "iconColor": "rgba(255, 96, 96, 1)", + "name": "Restart Detection", + "showIn": 0, + "step": "1m", + "tagKeys": "restart-tag", + "textFormat": "uptime reset", + "titleFormat": "Restart" + } + ] + }, + "description": "Dashboard for Micrometer instrumented applications (Java, Spring Boot, Micronaut)", + "editable": true, + "gnetId": 4701, + "graphTooltip": 1, + "iteration": 1553765841423, + "links": [], + "panels": [ + { + "content": "\n# Acknowledgments\n\nThank you to [Michael Weirauch](https://twitter.com/emwexx) for creating this dashboard: see original JVM (Micrometer) dashboard at [https://grafana.com/dashboards/4701](https://grafana.com/dashboards/4701)\n\n\n\n", + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 141, + "links": [], + "mode": "markdown", + "timeFrom": null, + "timeShift": null, + "title": "Acknowledgments", + "type": "text" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 3 + }, + "id": 125, + "panels": [], + "repeat": null, + "title": "Quick Facts", + "type": "row" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"], + "datasource": "Prometheus", + "decimals": 1, + "editable": true, + "error": false, + "format": "s", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 0, + "y": 4 + }, + "height": "", + "id": 63, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "70%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "process_uptime_seconds{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "metric": "", + "refId": "A", + "step": 14400 + } + ], + "thresholds": "", + "title": "Uptime", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"], + "datasource": "Prometheus", + "decimals": null, + "editable": true, + "error": false, + "format": "dateTimeAsIso", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 6, + "y": 4 + }, + "height": "", + "id": 92, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "70%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "process_start_time_seconds{application=\"$application\", instance=\"$instance\"}*1000", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "metric": "", + "refId": "A", + "step": 14400 + } + ], + "thresholds": "", + "title": "Start time", + "type": "singlestat", + "valueFontSize": "70%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": ["rgba(50, 172, 45, 0.97)", "rgba(237, 129, 40, 0.89)", "rgba(245, 54, 54, 0.9)"], + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 12, + "y": 4 + }, + "id": 65, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "70%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"heap\"})*100/sum(jvm_memory_max_bytes{application=\"$application\",instance=\"$instance\", area=\"heap\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 14400 + } + ], + "thresholds": "70,90", + "title": "Heap used", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": ["rgba(50, 172, 45, 0.97)", "rgba(237, 129, 40, 0.89)", "rgba(245, 54, 54, 0.9)"], + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 18, + "y": 4 + }, + "id": 75, + "interval": null, + "links": [], + "mappingType": 2, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "70%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + }, + { + "from": "-99999999999999999999999999999999", + "text": "N/A", + "to": "0" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"nonheap\"})*100/sum(jvm_memory_max_bytes{application=\"$application\",instance=\"$instance\", area=\"nonheap\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 14400 + } + ], + "thresholds": "70,90", + "title": "Non-Heap used", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + }, + { + "op": "=", + "text": "x", + "value": "" + } + ], + "valueName": "current" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 126, + "panels": [], + "repeat": null, + "title": "I/O Overview", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 8 + }, + "id": 111, + "legend": { + "avg": false, + "current": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(http_server_requests_seconds_count{application=\"$application\", instance=\"$instance\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "HTTP", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "HTTP": "#890f02", + "HTTP - 5xx": "#bf1b00" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 8 + }, + "id": 112, + "legend": { + "avg": false, + "current": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(http_server_requests_seconds_count{application=\"$application\", instance=\"$instance\", status=~\"5..\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "HTTP - 5xx", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Errors", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 8 + }, + "id": 113, + "legend": { + "avg": false, + "current": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(http_server_requests_seconds_sum{application=\"$application\", instance=\"$instance\", status!~\"5..\"}[1m]))/sum(rate(http_server_requests_seconds_count{application=\"$application\", instance=\"$instance\", status!~\"5..\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "HTTP - AVG", + "refId": "A" + }, + { + "expr": "max(http_server_requests_seconds_max{application=\"$application\", instance=\"$instance\", status!~\"5..\"})", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "HTTP - MAX", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 15 + }, + "id": 127, + "panels": [], + "repeat": null, + "title": "JVM Memory", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 16 + }, + "id": 24, + "legend": { + "avg": false, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"heap\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "used", + "metric": "", + "refId": "A", + "step": 2400 + }, + { + "expr": "sum(jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", area=\"heap\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "committed", + "refId": "B", + "step": 2400 + }, + { + "expr": "sum(jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", area=\"heap\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "max", + "refId": "C", + "step": 2400 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "JVM Heap", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["mbytes", "short"], + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 16 + }, + "id": 25, + "legend": { + "avg": false, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"nonheap\"})", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "used", + "metric": "", + "refId": "A", + "step": 2400 + }, + { + "expr": "sum(jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", area=\"nonheap\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "committed", + "refId": "B", + "step": 2400 + }, + { + "expr": "sum(jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", area=\"nonheap\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "max", + "refId": "C", + "step": 2400 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "JVM Non-Heap", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["mbytes", "short"], + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 16 + }, + "id": 26, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "used", + "metric": "", + "refId": "A", + "step": 2400 + }, + { + "expr": "sum(jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "committed", + "refId": "B", + "step": 2400 + }, + { + "expr": "sum(jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "max", + "refId": "C", + "step": 2400 + }, + { + "expr": "process_memory_vss_bytes{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "hide": true, + "intervalFactor": 2, + "legendFormat": "vss", + "metric": "", + "refId": "D", + "step": 2400 + }, + { + "expr": "process_memory_rss_bytes{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "rss", + "refId": "E", + "step": 2400 + }, + { + "expr": "process_memory_pss_bytes{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "pss", + "refId": "F", + "step": 2400 + }, + { + "expr": "process_memory_swap_bytes{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "swap", + "refId": "G", + "step": 2400 + }, + { + "expr": "process_memory_swappss_bytes{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "swappss", + "refId": "H", + "step": 2400 + }, + { + "expr": "process_memory_pss_bytes{application=\"$application\", instance=\"$instance\"} + process_memory_swap_bytes{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "phys (pss+swap)", + "refId": "I", + "step": 2400 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "JVM Total", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["mbytes", "short"], + "yaxes": [ + { + "format": "bytes", + "label": "", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 23 + }, + "id": 128, + "panels": [], + "repeat": null, + "title": "JVM Misc", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 24 + }, + "id": 106, + "legend": { + "avg": false, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "system_cpu_usage{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "system", + "metric": "", + "refId": "A", + "step": 2400 + }, + { + "expr": "process_cpu_usage{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "process", + "refId": "B" + }, + { + "expr": "avg_over_time(process_cpu_usage{application=\"$application\", instance=\"$instance\"}[1h])", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "process-1h", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["short", "short"], + "yaxes": [ + { + "decimals": 1, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": "1", + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 24 + }, + "id": 93, + "legend": { + "avg": false, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "system_load_average_1m{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "system-1m", + "metric": "", + "refId": "A", + "step": 2400 + }, + { + "expr": "", + "format": "time_series", + "intervalFactor": 2, + "refId": "B" + }, + { + "expr": "system_cpu_count{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "cpu", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Load", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["short", "short"], + "yaxes": [ + { + "decimals": 1, + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 24 + }, + "id": 32, + "legend": { + "avg": false, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_threads_live{application=\"$application\", instance=\"$instance\"} or jvm_threads_live_threads{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "live", + "metric": "", + "refId": "A", + "step": 2400 + }, + { + "expr": "jvm_threads_daemon{application=\"$application\", instance=\"$instance\"} or jvm_threads_daemon_threads{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "daemon", + "metric": "", + "refId": "B", + "step": 2400 + }, + { + "expr": "jvm_threads_peak{application=\"$application\", instance=\"$instance\"} or jvm_threads_peak_threads{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "peak", + "refId": "C", + "step": 2400 + }, + { + "expr": "process_threads{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "process", + "refId": "D", + "step": 2400 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Threads", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["short", "short"], + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "blocked": "#bf1b00", + "new": "#fce2de", + "runnable": "#7eb26d", + "terminated": "#511749", + "timed-waiting": "#c15c17", + "waiting": "#eab839" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 24 + }, + "id": 124, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_threads_states_threads{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{state}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Thread States", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "debug": "#1F78C1", + "error": "#BF1B00", + "info": "#508642", + "trace": "#6ED0E0", + "warn": "#EAB839" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 18, + "x": 0, + "y": 31 + }, + "height": "", + "id": 91, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "error", + "yaxis": 1 + }, + { + "alias": "warn", + "yaxis": 1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "increase(logback_events_total{application=\"$application\", instance=\"$instance\"}[1m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{level}}", + "metric": "", + "refId": "A", + "step": 1200 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Log Events (1m)", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["short", "short"], + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 31 + }, + "id": 61, + "legend": { + "avg": false, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_open_fds{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "open", + "metric": "", + "refId": "A", + "step": 2400 + }, + { + "expr": "process_max_fds{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "max", + "metric": "", + "refId": "B", + "step": 2400 + }, + { + "expr": "process_files_open{application=\"$application\", instance=\"$instance\"} or process_files_open_files{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "open", + "refId": "C" + }, + { + "expr": "process_files_max{application=\"$application\", instance=\"$instance\"} or process_files_max_files{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "max", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "File Descriptors", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["short", "short"], + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 10, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 38 + }, + "id": 129, + "panels": [], + "repeat": "persistence_counts", + "title": "JVM Memory Pools (Heap)", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 39 + }, + "id": 3, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 3, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "jvm_memory_pool_heap", + "scopedVars": { + "jvm_memory_pool_heap": { + "selected": false, + "text": "PS Eden Space", + "value": "PS Eden Space" + } + }, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "used", + "metric": "", + "refId": "A", + "step": 1800 + }, + { + "expr": "jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "commited", + "metric": "", + "refId": "B", + "step": 1800 + }, + { + "expr": "jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "max", + "metric": "", + "refId": "C", + "step": 1800 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "$jvm_memory_pool_heap", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["mbytes", "short"], + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 39 + }, + "id": 134, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 3, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatIteration": 1553765841423, + "repeatPanelId": 3, + "scopedVars": { + "jvm_memory_pool_heap": { + "selected": false, + "text": "PS Old Gen", + "value": "PS Old Gen" + } + }, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "used", + "metric": "", + "refId": "A", + "step": 1800 + }, + { + "expr": "jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "commited", + "metric": "", + "refId": "B", + "step": 1800 + }, + { + "expr": "jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "max", + "metric": "", + "refId": "C", + "step": 1800 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "$jvm_memory_pool_heap", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["mbytes", "short"], + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 39 + }, + "id": 135, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 3, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatIteration": 1553765841423, + "repeatPanelId": 3, + "scopedVars": { + "jvm_memory_pool_heap": { + "selected": false, + "text": "PS Survivor Space", + "value": "PS Survivor Space" + } + }, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "used", + "metric": "", + "refId": "A", + "step": 1800 + }, + { + "expr": "jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "commited", + "metric": "", + "refId": "B", + "step": 1800 + }, + { + "expr": "jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "max", + "metric": "", + "refId": "C", + "step": 1800 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "$jvm_memory_pool_heap", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["mbytes", "short"], + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 46 + }, + "id": 130, + "panels": [], + "repeat": null, + "title": "JVM Memory Pools (Non-Heap)", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 47 + }, + "id": 78, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 3, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "jvm_memory_pool_nonheap", + "scopedVars": { + "jvm_memory_pool_nonheap": { + "selected": false, + "text": "Metaspace", + "value": "Metaspace" + } + }, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "used", + "metric": "", + "refId": "A", + "step": 1800 + }, + { + "expr": "jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "commited", + "metric": "", + "refId": "B", + "step": 1800 + }, + { + "expr": "jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "max", + "metric": "", + "refId": "C", + "step": 1800 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "$jvm_memory_pool_nonheap", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["mbytes", "short"], + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 47 + }, + "id": 136, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 3, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatIteration": 1553765841423, + "repeatPanelId": 78, + "scopedVars": { + "jvm_memory_pool_nonheap": { + "selected": false, + "text": "Compressed Class Space", + "value": "Compressed Class Space" + } + }, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "used", + "metric": "", + "refId": "A", + "step": 1800 + }, + { + "expr": "jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "commited", + "metric": "", + "refId": "B", + "step": 1800 + }, + { + "expr": "jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "max", + "metric": "", + "refId": "C", + "step": 1800 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "$jvm_memory_pool_nonheap", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["mbytes", "short"], + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 47 + }, + "id": 137, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 3, + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatIteration": 1553765841423, + "repeatPanelId": 78, + "scopedVars": { + "jvm_memory_pool_nonheap": { + "selected": false, + "text": "Code Cache", + "value": "Code Cache" + } + }, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "used", + "metric": "", + "refId": "A", + "step": 1800 + }, + { + "expr": "jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "commited", + "metric": "", + "refId": "B", + "step": 1800 + }, + { + "expr": "jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "max", + "metric": "", + "refId": "C", + "step": 1800 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "$jvm_memory_pool_nonheap", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["mbytes", "short"], + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 54 + }, + "id": 131, + "panels": [], + "repeat": null, + "title": "Garbage Collection", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 55 + }, + "id": 98, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(jvm_gc_pause_seconds_count{application=\"$application\", instance=\"$instance\"}[1m])", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{action}} ({{cause}})", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Collections", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 55 + }, + "id": 101, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(jvm_gc_pause_seconds_sum{application=\"$application\", instance=\"$instance\"}[1m])/rate(jvm_gc_pause_seconds_count{application=\"$application\", instance=\"$instance\"}[1m])", + "format": "time_series", + "hide": false, + "instant": false, + "intervalFactor": 1, + "legendFormat": "avg {{action}} ({{cause}})", + "refId": "A" + }, + { + "expr": "jvm_gc_pause_seconds_max{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "hide": false, + "instant": false, + "intervalFactor": 1, + "legendFormat": "max {{action}} ({{cause}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Pause Durations", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 55 + }, + "id": 99, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(jvm_gc_memory_allocated_bytes_total{application=\"$application\", instance=\"$instance\"}[1m])", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "allocated", + "refId": "A" + }, + { + "expr": "rate(jvm_gc_memory_promoted_bytes_total{application=\"$application\", instance=\"$instance\"}[1m])", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "promoted", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Allocated/Promoted", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 62 + }, + "id": 132, + "panels": [], + "repeat": null, + "title": "Classloading", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 63 + }, + "id": 37, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_classes_loaded{application=\"$application\", instance=\"$instance\"} or jvm_classes_loaded_classes{application=\"$application\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "loaded", + "metric": "", + "refId": "A", + "step": 1200 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Classes loaded", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["short", "short"], + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 63 + }, + "id": 38, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "delta(jvm_classes_loaded{application=\"$application\",instance=\"$instance\"}[5m]) or delta(jvm_classes_loaded_classes{application=\"$application\",instance=\"$instance\"}[5m])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "delta", + "metric": "", + "refId": "A", + "step": 1200 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Class delta (5m)", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["ops", "short"], + "yaxes": [ + { + "decimals": null, + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 70 + }, + "id": 133, + "panels": [], + "repeat": null, + "title": "Buffer Pools", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 71 + }, + "id": 33, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_buffer_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"direct\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "used", + "metric": "", + "refId": "A", + "step": 2400 + }, + { + "expr": "jvm_buffer_total_capacity_bytes{application=\"$application\", instance=\"$instance\", id=\"direct\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "capacity", + "metric": "", + "refId": "B", + "step": 2400 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Direct Buffers", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["short", "short"], + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 71 + }, + "id": 83, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_buffer_count{application=\"$application\", instance=\"$instance\", id=\"direct\"} or jvm_buffer_count_buffers{application=\"$application\", instance=\"$instance\", id=\"direct\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "count", + "metric": "", + "refId": "A", + "step": 2400 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Direct Buffers", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["short", "short"], + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 71 + }, + "id": 85, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_buffer_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"mapped\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "used", + "metric": "", + "refId": "A", + "step": 2400 + }, + { + "expr": "jvm_buffer_total_capacity_bytes{application=\"$application\", instance=\"$instance\", id=\"mapped\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "capacity", + "metric": "", + "refId": "B", + "step": 2400 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Mapped Buffers", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["short", "short"], + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 71 + }, + "id": 84, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "jvm_buffer_count{application=\"$application\", instance=\"$instance\", id=\"mapped\"} or jvm_buffer_count_buffers{application=\"$application\", instance=\"$instance\", id=\"mapped\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "count", + "metric": "", + "refId": "A", + "step": 2400 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Mapped Buffers", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "y-axis": true, + "y_formats": ["short", "short"], + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "10s", + "schemaVersion": 18, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "text": "test", + "value": "test" + }, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": false, + "label": "Application", + "multi": false, + "name": "application", + "options": [], + "query": "label_values(application)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allFormat": "glob", + "allValue": null, + "current": { + "text": "localhost:8080", + "value": "localhost:8080" + }, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": false, + "label": "Instance", + "multi": false, + "multiFormat": "glob", + "name": "instance", + "options": [], + "query": "label_values(jvm_memory_used_bytes{application=\"$application\"}, instance)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allFormat": "glob", + "allValue": null, + "current": { + "text": "All", + "value": "$__all" + }, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": true, + "label": "JVM Memory Pools Heap", + "multi": false, + "multiFormat": "glob", + "name": "jvm_memory_pool_heap", + "options": [], + "query": "label_values(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"heap\"},id)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allFormat": "glob", + "allValue": null, + "current": { + "text": "All", + "value": "$__all" + }, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": true, + "label": "JVM Memory Pools Non-Heap", + "multi": false, + "multiFormat": "glob", + "name": "jvm_memory_pool_nonheap", + "options": [], + "query": "label_values(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"nonheap\"},id)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 2, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": { + "now": true, + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], + "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + }, + "timezone": "browser", + "title": "JVM (Micrometer)", + "uid": "Ud1CFe3iz", + "version": 1 +} diff --git a/jhipster-6/bookstore-monolith/src/main/docker/grafana/provisioning/dashboards/dashboard.yml b/jhipster-6/bookstore-monolith/src/main/docker/grafana/provisioning/dashboards/dashboard.yml new file mode 100644 index 0000000000..5b46e1f4ca --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/docker/grafana/provisioning/dashboards/dashboard.yml @@ -0,0 +1,11 @@ +apiVersion: 1 + +providers: + - name: 'Prometheus' + orgId: 1 + folder: '' + type: file + disableDeletion: false + editable: true + options: + path: /etc/grafana/provisioning/dashboards diff --git a/jhipster-6/bookstore-monolith/src/main/docker/grafana/provisioning/datasources/datasource.yml b/jhipster-6/bookstore-monolith/src/main/docker/grafana/provisioning/datasources/datasource.yml new file mode 100644 index 0000000000..20506dab30 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/docker/grafana/provisioning/datasources/datasource.yml @@ -0,0 +1,50 @@ +apiVersion: 1 + +# list of datasources that should be deleted from the database +deleteDatasources: + - name: Prometheus + orgId: 1 + +# list of datasources to insert/update depending +# whats available in the database +datasources: + # name of the datasource. Required + - name: Prometheus + # datasource type. Required + type: prometheus + # access mode. direct or proxy. Required + access: proxy + # org id. will default to orgId 1 if not specified + orgId: 1 + # url + # On MacOS, replace localhost by host.docker.internal + url: http://localhost:9090 + # database password, if used + password: + # database user, if used + user: + # database name, if used + database: + # enable/disable basic auth + basicAuth: false + # basic auth username + basicAuthUser: admin + # basic auth password + basicAuthPassword: admin + # enable/disable with credentials headers + withCredentials: + # mark as default datasource. Max one per org + isDefault: true + # fields that will be converted to json and stored in json_data + jsonData: + graphiteVersion: '1.1' + tlsAuth: false + tlsAuthWithCACert: false + # json object of data that will be encrypted. + secureJsonData: + tlsCACert: '...' + tlsClientCert: '...' + tlsClientKey: '...' + version: 1 + # allow users to edit datasources from the UI. + editable: true diff --git a/jhipster-6/bookstore-monolith/src/main/docker/monitoring.yml b/jhipster-6/bookstore-monolith/src/main/docker/monitoring.yml new file mode 100644 index 0000000000..fa75668445 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/docker/monitoring.yml @@ -0,0 +1,26 @@ +version: '3' +services: + bookstore-prometheus: + image: prom/prometheus:v2.9.2 + volumes: + - ./prometheus/:/etc/prometheus/ + command: + - '--config.file=/etc/prometheus/prometheus.yml' + ports: + - 9090:9090 + # On MacOS, remove next line and replace localhost by host.docker.internal in prometheus/prometheus.yml and + # grafana/provisioning/datasources/datasource.yml + network_mode: 'host' # to test locally running service + bookstore-grafana: + image: grafana/grafana:6.1.4 + volumes: + - ./grafana/provisioning/:/etc/grafana/provisioning/ + environment: + - GF_SECURITY_ADMIN_PASSWORD=admin + - GF_USERS_ALLOW_SIGN_UP=false + - GF_INSTALL_PLUGINS=grafana-piechart-panel + ports: + - 3000:3000 + # On MacOS, remove next line and replace localhost by host.docker.internal in prometheus/prometheus.yml and + # grafana/provisioning/datasources/datasource.yml + network_mode: 'host' # to test locally running service diff --git a/jhipster-5/bookstore-monolith/src/main/docker/mysql.yml b/jhipster-6/bookstore-monolith/src/main/docker/mysql.yml similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/docker/mysql.yml rename to jhipster-6/bookstore-monolith/src/main/docker/mysql.yml diff --git a/jhipster-6/bookstore-monolith/src/main/docker/prometheus/prometheus.yml b/jhipster-6/bookstore-monolith/src/main/docker/prometheus/prometheus.yml new file mode 100644 index 0000000000..73f4c959da --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/docker/prometheus/prometheus.yml @@ -0,0 +1,26 @@ +# Sample global config for monitoring JHipster applications +global: + scrape_interval: 15s # By default, scrape targets every 15 seconds. + evaluation_interval: 15s # By default, scrape targets every 15 seconds. + # scrape_timeout is set to the global default (10s). + + # Attach these labels to any time series or alerts when communicating with + # external systems (federation, remote storage, Alertmanager). + external_labels: + monitor: 'jhipster' + +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + # The job name is added as a label `job=` to any timeseries scraped from this config. + - job_name: 'prometheus' + + # Override the global default and scrape targets from this job every 5 seconds. + scrape_interval: 5s + + # scheme defaults to 'http'. + metrics_path: /management/prometheus + static_configs: + - targets: + # On MacOS, replace localhost by host.docker.internal + - localhost:8080 diff --git a/jhipster-5/bookstore-monolith/src/main/docker/sonar.yml b/jhipster-6/bookstore-monolith/src/main/docker/sonar.yml similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/docker/sonar.yml rename to jhipster-6/bookstore-monolith/src/main/docker/sonar.yml diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/ApplicationWebXml.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/ApplicationWebXml.java similarity index 89% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/ApplicationWebXml.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/ApplicationWebXml.java index ca65727e77..32f28a8e9e 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/ApplicationWebXml.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/ApplicationWebXml.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5; +package com.baeldung.jhipster6; -import com.baeldung.jhipster5.config.DefaultProfileUtil; +import com.baeldung.jhipster6.config.DefaultProfileUtil; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/BookstoreApp.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/BookstoreApp.java similarity index 96% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/BookstoreApp.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/BookstoreApp.java index e7ca925228..278efb9270 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/BookstoreApp.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/BookstoreApp.java @@ -1,7 +1,7 @@ -package com.baeldung.jhipster5; +package com.baeldung.jhipster6; -import com.baeldung.jhipster5.config.ApplicationProperties; -import com.baeldung.jhipster5.config.DefaultProfileUtil; +import com.baeldung.jhipster6.config.ApplicationProperties; +import com.baeldung.jhipster6.config.DefaultProfileUtil; import io.github.jhipster.config.JHipsterConstants; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/aop/logging/LoggingAspect.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/aop/logging/LoggingAspect.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/aop/logging/LoggingAspect.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/aop/logging/LoggingAspect.java index 0379637061..1e5a47c12a 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/aop/logging/LoggingAspect.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/aop/logging/LoggingAspect.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.aop.logging; +package com.baeldung.jhipster6.aop.logging; import io.github.jhipster.config.JHipsterConstants; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/ApplicationProperties.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/ApplicationProperties.java similarity index 90% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/ApplicationProperties.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/ApplicationProperties.java index 4ca3e9bd85..e9bf8bd1a8 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/ApplicationProperties.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/ApplicationProperties.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/AsyncConfiguration.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/AsyncConfiguration.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/AsyncConfiguration.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/AsyncConfiguration.java index 414fe152bf..a245402175 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/AsyncConfiguration.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/AsyncConfiguration.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor; import io.github.jhipster.config.JHipsterProperties; @@ -46,7 +46,7 @@ public class AsyncConfiguration implements AsyncConfigurer, SchedulingConfigurer public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new SimpleAsyncUncaughtExceptionHandler(); } - + @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setScheduler(scheduledTaskExecutor()); diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/CloudDatabaseConfiguration.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/CloudDatabaseConfiguration.java similarity index 95% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/CloudDatabaseConfiguration.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/CloudDatabaseConfiguration.java index 887a1bae89..3d57db6559 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/CloudDatabaseConfiguration.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/CloudDatabaseConfiguration.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import io.github.jhipster.config.JHipsterConstants; @@ -16,7 +16,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; public class CloudDatabaseConfiguration extends AbstractCloudConfig { private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class); - + private static final String CLOUD_CONFIGURATION_HIKARI_PREFIX = "spring.datasource.hikari"; @Bean diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/Constants.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/Constants.java similarity index 89% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/Constants.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/Constants.java index dd8f717f98..b5d6eba051 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/Constants.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/Constants.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; /** * Application constants. @@ -11,7 +11,7 @@ public final class Constants { public static final String SYSTEM_ACCOUNT = "system"; public static final String ANONYMOUS_USER = "anonymoususer"; public static final String DEFAULT_LANGUAGE = "en"; - + private Constants() { } } diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/DatabaseConfiguration.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/DatabaseConfiguration.java similarity index 97% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/DatabaseConfiguration.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/DatabaseConfiguration.java index 007b1d6431..2aa8ae2e82 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/DatabaseConfiguration.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/DatabaseConfiguration.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import io.github.jhipster.config.JHipsterConstants; import io.github.jhipster.config.h2.H2ConfigurationHelper; @@ -42,7 +42,7 @@ public class DatabaseConfiguration { log.debug("H2 database is available on port {}", port); return H2ConfigurationHelper.createServer(port); } - + private String getValidPortForH2() { int port = Integer.parseInt(env.getProperty("server.port")); if (port < 10000) { diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/DateTimeFormatConfiguration.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/DateTimeFormatConfiguration.java similarity index 94% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/DateTimeFormatConfiguration.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/DateTimeFormatConfiguration.java index 4415ce0b1e..eeb4b55491 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/DateTimeFormatConfiguration.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/DateTimeFormatConfiguration.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/DefaultProfileUtil.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/DefaultProfileUtil.java similarity index 97% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/DefaultProfileUtil.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/DefaultProfileUtil.java index 2cfe16a1ae..02b3ce9db0 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/DefaultProfileUtil.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/DefaultProfileUtil.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import io.github.jhipster.config.JHipsterConstants; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/JacksonConfiguration.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/JacksonConfiguration.java similarity index 97% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/JacksonConfiguration.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/JacksonConfiguration.java index 119cd5f0c6..68fb92ef2e 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/JacksonConfiguration.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/JacksonConfiguration.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/LiquibaseConfiguration.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/LiquibaseConfiguration.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/LiquibaseConfiguration.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/LiquibaseConfiguration.java index 4b2a7b1e66..2f82a1f447 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/LiquibaseConfiguration.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/LiquibaseConfiguration.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import javax.sql.DataSource; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/LocaleConfiguration.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/LocaleConfiguration.java similarity index 96% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/LocaleConfiguration.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/LocaleConfiguration.java index 256c6b77b9..d73198e5bb 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/LocaleConfiguration.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/LocaleConfiguration.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import io.github.jhipster.config.locale.AngularCookieLocaleResolver; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/LoggingAspectConfiguration.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/LoggingAspectConfiguration.java similarity index 81% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/LoggingAspectConfiguration.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/LoggingAspectConfiguration.java index 25d7ba3792..1638234a89 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/LoggingAspectConfiguration.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/LoggingAspectConfiguration.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; -import com.baeldung.jhipster5.aop.logging.LoggingAspect; +import com.baeldung.jhipster6.aop.logging.LoggingAspect; import io.github.jhipster.config.JHipsterConstants; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/LoggingConfiguration.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/LoggingConfiguration.java similarity index 99% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/LoggingConfiguration.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/LoggingConfiguration.java index 9402a1bc36..893a16876f 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/LoggingConfiguration.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/LoggingConfiguration.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import java.net.InetSocketAddress; import java.util.Iterator; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/SecurityConfiguration.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/SecurityConfiguration.java similarity index 94% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/SecurityConfiguration.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/SecurityConfiguration.java index f07944271e..f42ba55c20 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/SecurityConfiguration.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/SecurityConfiguration.java @@ -1,7 +1,10 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; -import com.baeldung.jhipster5.security.*; -import com.baeldung.jhipster5.security.jwt.*; +import com.baeldung.jhipster6.security.*; +import com.baeldung.jhipster6.security.jwt.*; +import com.baeldung.jhipster6.security.AuthoritiesConstants; +import com.baeldung.jhipster6.security.jwt.JWTConfigurer; +import com.baeldung.jhipster6.security.jwt.TokenProvider; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.context.annotation.Bean; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/WebConfigurer.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/WebConfigurer.java similarity index 79% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/WebConfigurer.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/WebConfigurer.java index 26cfc92487..8bed192c9f 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/WebConfigurer.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/WebConfigurer.java @@ -1,20 +1,18 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import io.github.jhipster.config.JHipsterConstants; import io.github.jhipster.config.JHipsterProperties; -import io.github.jhipster.config.h2.H2ConfigurationHelper; import io.github.jhipster.web.filter.CachingHttpHeadersFilter; -import io.undertow.UndertowOptions; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.server.*; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; +import org.springframework.core.env.Profiles; import org.springframework.http.MediaType; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; @@ -42,7 +40,6 @@ public class WebConfigurer implements ServletContextInitializer, WebServerFactor private final JHipsterProperties jHipsterProperties; public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties) { - this.env = env; this.jHipsterProperties = jHipsterProperties; } @@ -53,12 +50,9 @@ public class WebConfigurer implements ServletContextInitializer, WebServerFactor log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles()); } EnumSet disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC); - if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) { + if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_PRODUCTION))) { initCachingHttpHeadersFilter(servletContext, disps); } - if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) { - initH2Console(servletContext); - } log.info("Web application fully configured"); } @@ -70,20 +64,6 @@ public class WebConfigurer implements ServletContextInitializer, WebServerFactor setMimeMappings(server); // When running in an IDE or with ./mvnw spring-boot:run, set location of the static web assets. setLocationForStaticAssets(server); - - /* - * Enable HTTP/2 for Undertow - https://twitter.com/ankinson/status/829256167700492288 - * HTTP/2 requires HTTPS, so HTTP requests will fallback to HTTP/1.1. - * See the JHipsterProperties class and your application-*.yml configuration files - * for more information. - */ - if (jHipsterProperties.getHttp().getVersion().equals(JHipsterProperties.Http.Version.V_2_0) && - server instanceof UndertowServletWebServerFactory) { - - ((UndertowServletWebServerFactory) server) - .addBuilderCustomizers(builder -> - builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true)); - } } private void setMimeMappings(WebServerFactory server) { @@ -103,7 +83,7 @@ public class WebConfigurer implements ServletContextInitializer, WebServerFactor ConfigurableServletWebServerFactory servletWebServer = (ConfigurableServletWebServerFactory) server; File root; String prefixPath = resolvePathPrefix(); - root = new File(prefixPath + "target/www/"); + root = new File(prefixPath + "target/classes/static/"); if (root.exists() && root.isDirectory()) { servletWebServer.setDocumentRoot(root); } @@ -134,7 +114,7 @@ public class WebConfigurer implements ServletContextInitializer, WebServerFactor * Initializes the caching HTTP Headers Filter. */ private void initCachingHttpHeadersFilter(ServletContext servletContext, - EnumSet disps) { + EnumSet disps) { log.debug("Registering Caching HTTP Headers Filter"); FilterRegistration.Dynamic cachingHttpHeadersFilter = servletContext.addFilter("cachingHttpHeadersFilter", @@ -159,12 +139,4 @@ public class WebConfigurer implements ServletContextInitializer, WebServerFactor return new CorsFilter(source); } - /** - * Initializes H2 console. - */ - private void initH2Console(ServletContext servletContext) { - log.debug("Initialize H2 console"); - H2ConfigurationHelper.initH2Console(servletContext); - } - } diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/audit/AuditEventConverter.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/audit/AuditEventConverter.java similarity index 96% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/audit/AuditEventConverter.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/audit/AuditEventConverter.java index 6dd87bb82d..fee87ffb96 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/audit/AuditEventConverter.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/audit/AuditEventConverter.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.config.audit; +package com.baeldung.jhipster6.config.audit; -import com.baeldung.jhipster5.domain.PersistentAuditEvent; +import com.baeldung.jhipster6.domain.PersistentAuditEvent; import org.springframework.boot.actuate.audit.AuditEvent; import org.springframework.security.web.authentication.WebAuthenticationDetails; diff --git a/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/audit/package-info.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/audit/package-info.java new file mode 100644 index 0000000000..ce7911db40 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/audit/package-info.java @@ -0,0 +1,4 @@ +/** + * Audit specific code. + */ +package com.baeldung.jhipster6.config.audit; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/package-info.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/package-info.java similarity index 55% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/package-info.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/package-info.java index 868155ce9f..2f6261950a 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/package-info.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/config/package-info.java @@ -1,4 +1,4 @@ /** * Spring Framework configuration files. */ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/AbstractAuditingEntity.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/AbstractAuditingEntity.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/AbstractAuditingEntity.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/AbstractAuditingEntity.java index 861674ccc9..b3881af03b 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/AbstractAuditingEntity.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/AbstractAuditingEntity.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.domain; +package com.baeldung.jhipster6.domain; import com.fasterxml.jackson.annotation.JsonIgnore; import org.hibernate.envers.Audited; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/Authority.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/Authority.java similarity index 96% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/Authority.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/Authority.java index fbd4596fc7..81d2b930cb 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/Authority.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/Authority.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.domain; +package com.baeldung.jhipster6.domain; import javax.persistence.Entity; import javax.persistence.Id; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/Book.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/Book.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/Book.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/Book.java index 16771d9e09..14c5ec3396 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/Book.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/Book.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.domain; +package com.baeldung.jhipster6.domain; @@ -17,7 +17,7 @@ import java.util.Objects; public class Book implements Serializable { private static final long serialVersionUID = 1L; - + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/PersistentAuditEvent.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/PersistentAuditEvent.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/PersistentAuditEvent.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/PersistentAuditEvent.java index 15e2eeda5a..f953eeded9 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/PersistentAuditEvent.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/PersistentAuditEvent.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.domain; +package com.baeldung.jhipster6.domain; import javax.persistence.*; import javax.validation.constraints.NotNull; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/User.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/User.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/User.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/User.java index ff12d1ca9c..d1ff6c33fa 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/User.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/User.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.domain; +package com.baeldung.jhipster6.domain; -import com.baeldung.jhipster5.config.Constants; +import com.baeldung.jhipster6.config.Constants; import com.fasterxml.jackson.annotation.JsonIgnore; import org.apache.commons.lang3.StringUtils; diff --git a/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/package-info.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/package-info.java new file mode 100644 index 0000000000..9063a204d5 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/domain/package-info.java @@ -0,0 +1,4 @@ +/** + * JPA domain objects. + */ +package com.baeldung.jhipster6.domain; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/AuthorityRepository.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/AuthorityRepository.java similarity index 69% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/AuthorityRepository.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/AuthorityRepository.java index 310735eb57..335631195d 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/AuthorityRepository.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/AuthorityRepository.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.repository; +package com.baeldung.jhipster6.repository; -import com.baeldung.jhipster5.domain.Authority; +import com.baeldung.jhipster6.domain.Authority; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/BookRepository.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/BookRepository.java similarity index 75% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/BookRepository.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/BookRepository.java index ebd3117e65..0863d1b89b 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/BookRepository.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/BookRepository.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.repository; +package com.baeldung.jhipster6.repository; -import com.baeldung.jhipster5.domain.Book; +import com.baeldung.jhipster6.domain.Book; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.Repository; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/CustomAuditEventRepository.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/CustomAuditEventRepository.java similarity index 94% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/CustomAuditEventRepository.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/CustomAuditEventRepository.java index faa788ff5f..4e17cfff2b 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/CustomAuditEventRepository.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/CustomAuditEventRepository.java @@ -1,8 +1,8 @@ -package com.baeldung.jhipster5.repository; +package com.baeldung.jhipster6.repository; -import com.baeldung.jhipster5.config.Constants; -import com.baeldung.jhipster5.config.audit.AuditEventConverter; -import com.baeldung.jhipster5.domain.PersistentAuditEvent; +import com.baeldung.jhipster6.config.Constants; +import com.baeldung.jhipster6.config.audit.AuditEventConverter; +import com.baeldung.jhipster6.domain.PersistentAuditEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/PersistenceAuditEventRepository.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/PersistenceAuditEventRepository.java similarity index 89% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/PersistenceAuditEventRepository.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/PersistenceAuditEventRepository.java index 2eb6f3b847..ca0025321e 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/PersistenceAuditEventRepository.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/PersistenceAuditEventRepository.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.repository; +package com.baeldung.jhipster6.repository; -import com.baeldung.jhipster5.domain.PersistentAuditEvent; +import com.baeldung.jhipster6.domain.PersistentAuditEvent; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/UserRepository.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/UserRepository.java similarity index 93% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/UserRepository.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/UserRepository.java index 42a5588b22..27fd5fc359 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/UserRepository.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/UserRepository.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.repository; +package com.baeldung.jhipster6.repository; -import com.baeldung.jhipster5.domain.User; +import com.baeldung.jhipster6.domain.User; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/package-info.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/package-info.java new file mode 100644 index 0000000000..949ee586b7 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/repository/package-info.java @@ -0,0 +1,4 @@ +/** + * Spring Data JPA repositories. + */ +package com.baeldung.jhipster6.repository; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/AuthoritiesConstants.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/AuthoritiesConstants.java similarity index 88% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/AuthoritiesConstants.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/AuthoritiesConstants.java index 6ecf44394f..3f1709a6d9 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/AuthoritiesConstants.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/AuthoritiesConstants.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.security; +package com.baeldung.jhipster6.security; /** * Constants for Spring Security authorities. diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/CustomAuthenticationManager.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/CustomAuthenticationManager.java similarity index 93% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/CustomAuthenticationManager.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/CustomAuthenticationManager.java index 0a7dd66b24..092adf1b06 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/CustomAuthenticationManager.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/CustomAuthenticationManager.java @@ -1,10 +1,10 @@ -package com.baeldung.jhipster5.security; +package com.baeldung.jhipster6.security; -import com.baeldung.jhipster5.domain.User; -import com.baeldung.jhipster5.security.dto.LoginRequest; -import com.baeldung.jhipster5.security.dto.LoginResponse; -import com.baeldung.jhipster5.service.UserService; -import com.baeldung.jhipster5.service.dto.UserDTO; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.security.dto.LoginRequest; +import com.baeldung.jhipster6.security.dto.LoginResponse; +import com.baeldung.jhipster6.service.UserService; +import com.baeldung.jhipster6.service.dto.UserDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/DomainUserDetailsService.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/DomainUserDetailsService.java similarity index 94% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/DomainUserDetailsService.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/DomainUserDetailsService.java index d0014096df..3102604ee4 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/DomainUserDetailsService.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/DomainUserDetailsService.java @@ -1,7 +1,8 @@ -package com.baeldung.jhipster5.security; +package com.baeldung.jhipster6.security; + +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.UserRepository; -import com.baeldung.jhipster5.domain.User; -import com.baeldung.jhipster5.repository.UserRepository; import org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/SecurityUtils.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/SecurityUtils.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/SecurityUtils.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/SecurityUtils.java index 462bb8abc9..a4a1982b3c 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/SecurityUtils.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/SecurityUtils.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.security; +package com.baeldung.jhipster6.security; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/SpringSecurityAuditorAware.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/SpringSecurityAuditorAware.java similarity index 83% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/SpringSecurityAuditorAware.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/SpringSecurityAuditorAware.java index c1d6405ae3..aff636c13c 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/SpringSecurityAuditorAware.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/SpringSecurityAuditorAware.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.security; +package com.baeldung.jhipster6.security; -import com.baeldung.jhipster5.config.Constants; +import com.baeldung.jhipster6.config.Constants; import java.util.Optional; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/UserNotActivatedException.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/UserNotActivatedException.java similarity index 92% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/UserNotActivatedException.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/UserNotActivatedException.java index 4b2d91983c..a1f71f5408 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/UserNotActivatedException.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/UserNotActivatedException.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.security; +package com.baeldung.jhipster6.security; import org.springframework.security.core.AuthenticationException; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/dto/LoginRequest.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/dto/LoginRequest.java similarity index 91% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/dto/LoginRequest.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/dto/LoginRequest.java index f45c23fa39..1de2638577 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/dto/LoginRequest.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/dto/LoginRequest.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.security.dto; +package com.baeldung.jhipster6.security.dto; /** * Simple DTO representing a login request to a remote service. diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/dto/LoginResponse.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/dto/LoginResponse.java similarity index 95% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/dto/LoginResponse.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/dto/LoginResponse.java index ad1fe37a2f..6063180569 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/dto/LoginResponse.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/dto/LoginResponse.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.security.dto; +package com.baeldung.jhipster6.security.dto; /** * Simple DTO representing the response of logging in using a remote service. diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/jwt/JWTConfigurer.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/jwt/JWTConfigurer.java similarity index 94% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/jwt/JWTConfigurer.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/jwt/JWTConfigurer.java index 944255e37d..570f6c8d9d 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/jwt/JWTConfigurer.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/jwt/JWTConfigurer.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.security.jwt; +package com.baeldung.jhipster6.security.jwt; import org.springframework.security.config.annotation.SecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/jwt/JWTFilter.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/jwt/JWTFilter.java similarity index 97% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/jwt/JWTFilter.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/jwt/JWTFilter.java index cf1060282c..4e921a2f6e 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/jwt/JWTFilter.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/jwt/JWTFilter.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.security.jwt; +package com.baeldung.jhipster6.security.jwt; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/jwt/TokenProvider.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/jwt/TokenProvider.java similarity index 99% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/jwt/TokenProvider.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/jwt/TokenProvider.java index 248d45e050..20f46c06e9 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/jwt/TokenProvider.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/jwt/TokenProvider.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.security.jwt; +package com.baeldung.jhipster6.security.jwt; import java.nio.charset.StandardCharsets; import java.security.Key; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/package-info.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/package-info.java similarity index 50% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/package-info.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/package-info.java index 4759050c56..3fc05c27e7 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/package-info.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/security/package-info.java @@ -1,4 +1,4 @@ /** * Spring Security configuration. */ -package com.baeldung.jhipster5.security; +package com.baeldung.jhipster6.security; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/AuditEventService.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/AuditEventService.java similarity index 90% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/AuditEventService.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/AuditEventService.java index 852eb951c9..4d008e096e 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/AuditEventService.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/AuditEventService.java @@ -1,7 +1,8 @@ -package com.baeldung.jhipster5.service; +package com.baeldung.jhipster6.service; + +import com.baeldung.jhipster6.config.audit.AuditEventConverter; +import com.baeldung.jhipster6.repository.PersistenceAuditEventRepository; -import com.baeldung.jhipster5.config.audit.AuditEventConverter; -import com.baeldung.jhipster5.repository.PersistenceAuditEventRepository; import org.springframework.boot.actuate.audit.AuditEvent; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/BookService.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/BookService.java similarity index 91% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/BookService.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/BookService.java index 6422d1a424..00fe847527 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/BookService.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/BookService.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.service; +package com.baeldung.jhipster6.service; -import com.baeldung.jhipster5.service.dto.BookDTO; +import com.baeldung.jhipster6.service.dto.BookDTO; import java.util.List; import java.util.Optional; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/MailService.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/MailService.java similarity index 97% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/MailService.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/MailService.java index b15a7faff2..807cf8b5d6 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/MailService.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/MailService.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.service; +package com.baeldung.jhipster6.service; -import com.baeldung.jhipster5.domain.User; +import com.baeldung.jhipster6.domain.User; import io.github.jhipster.config.JHipsterProperties; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/UserService.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/UserService.java similarity index 92% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/UserService.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/UserService.java index 82d028f3ca..9c43332070 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/UserService.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/UserService.java @@ -1,15 +1,18 @@ -package com.baeldung.jhipster5.service; +package com.baeldung.jhipster6.service; -import com.baeldung.jhipster5.config.Constants; -import com.baeldung.jhipster5.domain.Authority; -import com.baeldung.jhipster5.domain.User; -import com.baeldung.jhipster5.repository.AuthorityRepository; -import com.baeldung.jhipster5.repository.UserRepository; -import com.baeldung.jhipster5.security.AuthoritiesConstants; -import com.baeldung.jhipster5.security.SecurityUtils; -import com.baeldung.jhipster5.service.dto.UserDTO; -import com.baeldung.jhipster5.service.util.RandomUtil; -import com.baeldung.jhipster5.web.rest.errors.*; +import com.baeldung.jhipster6.config.Constants; +import com.baeldung.jhipster6.domain.Authority; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.AuthorityRepository; +import com.baeldung.jhipster6.repository.UserRepository; +import com.baeldung.jhipster6.security.AuthoritiesConstants; +import com.baeldung.jhipster6.security.SecurityUtils; +import com.baeldung.jhipster6.service.dto.UserDTO; +import com.baeldung.jhipster6.service.util.RandomUtil; +import com.baeldung.jhipster6.web.rest.errors.*; +import com.baeldung.jhipster6.web.rest.errors.EmailAlreadyUsedException; +import com.baeldung.jhipster6.web.rest.errors.InvalidPasswordException; +import com.baeldung.jhipster6.web.rest.errors.LoginAlreadyUsedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/BookDTO.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/dto/BookDTO.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/BookDTO.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/dto/BookDTO.java index 5aa550e989..6334af6c21 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/BookDTO.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/dto/BookDTO.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.service.dto; +package com.baeldung.jhipster6.service.dto; import java.time.LocalDate; import javax.validation.constraints.*; import java.io.Serializable; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/PasswordChangeDTO.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/dto/PasswordChangeDTO.java similarity index 94% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/PasswordChangeDTO.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/dto/PasswordChangeDTO.java index 0711c97f44..1439b6e58d 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/PasswordChangeDTO.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/dto/PasswordChangeDTO.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.service.dto; +package com.baeldung.jhipster6.service.dto; /** * A DTO representing a password change required data - current and new password. diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/UserDTO.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/dto/UserDTO.java similarity index 96% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/UserDTO.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/dto/UserDTO.java index 9142b3825e..2dd38f9c0f 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/UserDTO.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/dto/UserDTO.java @@ -1,9 +1,9 @@ -package com.baeldung.jhipster5.service.dto; +package com.baeldung.jhipster6.service.dto; -import com.baeldung.jhipster5.config.Constants; +import com.baeldung.jhipster6.config.Constants; -import com.baeldung.jhipster5.domain.Authority; -import com.baeldung.jhipster5.domain.User; +import com.baeldung.jhipster6.domain.Authority; +import com.baeldung.jhipster6.domain.User; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; diff --git a/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/dto/package-info.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/dto/package-info.java new file mode 100644 index 0000000000..c536320584 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/dto/package-info.java @@ -0,0 +1,4 @@ +/** + * Data Transfer Objects. + */ +package com.baeldung.jhipster6.service.dto; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/impl/BookServiceImpl.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/impl/BookServiceImpl.java similarity index 88% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/impl/BookServiceImpl.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/impl/BookServiceImpl.java index 23cd59584c..0012489c5e 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/impl/BookServiceImpl.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/impl/BookServiceImpl.java @@ -1,11 +1,12 @@ -package com.baeldung.jhipster5.service.impl; +package com.baeldung.jhipster6.service.impl; + +import com.baeldung.jhipster6.service.BookService; +import com.baeldung.jhipster6.domain.Book; +import com.baeldung.jhipster6.repository.BookRepository; +import com.baeldung.jhipster6.service.dto.BookDTO; +import com.baeldung.jhipster6.service.mapper.BookMapper; +import com.baeldung.jhipster6.web.rest.errors.BadRequestAlertException; -import com.baeldung.jhipster5.service.BookService; -import com.baeldung.jhipster5.domain.Book; -import com.baeldung.jhipster5.repository.BookRepository; -import com.baeldung.jhipster5.service.dto.BookDTO; -import com.baeldung.jhipster5.service.mapper.BookMapper; -import com.baeldung.jhipster5.web.rest.errors.BadRequestAlertException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/BookMapper.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/mapper/BookMapper.java similarity index 67% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/BookMapper.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/mapper/BookMapper.java index cd24c7088e..64350fb4ed 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/BookMapper.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/mapper/BookMapper.java @@ -1,7 +1,8 @@ -package com.baeldung.jhipster5.service.mapper; +package com.baeldung.jhipster6.service.mapper; -import com.baeldung.jhipster5.domain.*; -import com.baeldung.jhipster5.service.dto.BookDTO; +import com.baeldung.jhipster6.domain.*; +import com.baeldung.jhipster6.service.dto.BookDTO; +import com.baeldung.jhipster6.domain.Book; import org.mapstruct.*; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/EntityMapper.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/mapper/EntityMapper.java similarity index 87% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/EntityMapper.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/mapper/EntityMapper.java index 68af78179d..6ca8d89480 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/EntityMapper.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/mapper/EntityMapper.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.service.mapper; +package com.baeldung.jhipster6.service.mapper; import java.util.List; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/UserMapper.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/mapper/UserMapper.java similarity index 92% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/UserMapper.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/mapper/UserMapper.java index 485c03813e..8b2b4cfba0 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/UserMapper.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/mapper/UserMapper.java @@ -1,8 +1,8 @@ -package com.baeldung.jhipster5.service.mapper; +package com.baeldung.jhipster6.service.mapper; -import com.baeldung.jhipster5.domain.Authority; -import com.baeldung.jhipster5.domain.User; -import com.baeldung.jhipster5.service.dto.UserDTO; +import com.baeldung.jhipster6.domain.Authority; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.service.dto.UserDTO; import org.springframework.stereotype.Service; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/package-info.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/mapper/package-info.java similarity index 63% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/package-info.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/mapper/package-info.java index 7d402321e7..6ce6ec42fb 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/package-info.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/mapper/package-info.java @@ -1,4 +1,4 @@ /** * MapStruct mappers for mapping domain objects and Data Transfer Objects. */ -package com.baeldung.jhipster5.service.mapper; +package com.baeldung.jhipster6.service.mapper; diff --git a/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/package-info.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/package-info.java new file mode 100644 index 0000000000..4f9584c45e --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/package-info.java @@ -0,0 +1,4 @@ +/** + * Service layer beans. + */ +package com.baeldung.jhipster6.service; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/util/RandomUtil.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/util/RandomUtil.java similarity index 94% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/util/RandomUtil.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/util/RandomUtil.java index 97e4d9c672..74b8b178c2 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/util/RandomUtil.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/service/util/RandomUtil.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.service.util; +package com.baeldung.jhipster6.service.util; import org.apache.commons.lang3.RandomStringUtils; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/AccountResource.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/AccountResource.java similarity index 87% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/AccountResource.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/AccountResource.java index 2109e93999..3603df148b 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/AccountResource.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/AccountResource.java @@ -1,16 +1,21 @@ -package com.baeldung.jhipster5.web.rest; +package com.baeldung.jhipster6.web.rest; -import com.baeldung.jhipster5.domain.User; -import com.baeldung.jhipster5.repository.UserRepository; -import com.baeldung.jhipster5.security.SecurityUtils; -import com.baeldung.jhipster5.service.MailService; -import com.baeldung.jhipster5.service.UserService; -import com.baeldung.jhipster5.service.dto.PasswordChangeDTO; -import com.baeldung.jhipster5.service.dto.UserDTO; -import com.baeldung.jhipster5.web.rest.errors.*; -import com.baeldung.jhipster5.web.rest.vm.KeyAndPasswordVM; -import com.baeldung.jhipster5.web.rest.vm.ManagedUserVM; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.UserRepository; +import com.baeldung.jhipster6.security.SecurityUtils; +import com.baeldung.jhipster6.service.MailService; +import com.baeldung.jhipster6.service.UserService; +import com.baeldung.jhipster6.service.dto.PasswordChangeDTO; +import com.baeldung.jhipster6.service.dto.UserDTO; +import com.baeldung.jhipster6.web.rest.errors.*; +import com.baeldung.jhipster6.web.rest.errors.EmailAlreadyUsedException; +import com.baeldung.jhipster6.web.rest.errors.EmailNotFoundException; +import com.baeldung.jhipster6.web.rest.errors.InternalServerErrorException; +import com.baeldung.jhipster6.web.rest.errors.InvalidPasswordException; +import com.baeldung.jhipster6.web.rest.errors.LoginAlreadyUsedException; +import com.baeldung.jhipster6.web.rest.vm.KeyAndPasswordVM; +import com.baeldung.jhipster6.web.rest.vm.ManagedUserVM; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/AuditResource.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/AuditResource.java similarity index 94% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/AuditResource.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/AuditResource.java index d0182d5d9d..ebcdc42f64 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/AuditResource.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/AuditResource.java @@ -1,7 +1,7 @@ -package com.baeldung.jhipster5.web.rest; +package com.baeldung.jhipster6.web.rest; -import com.baeldung.jhipster5.service.AuditEventService; -import com.baeldung.jhipster5.web.rest.util.PaginationUtil; +import com.baeldung.jhipster6.service.AuditEventService; +import com.baeldung.jhipster6.web.rest.util.PaginationUtil; import io.github.jhipster.web.util.ResponseUtil; import org.springframework.boot.actuate.audit.AuditEvent; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/BookResource.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/BookResource.java similarity index 94% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/BookResource.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/BookResource.java index 0360ea05ed..584216b51d 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/BookResource.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/BookResource.java @@ -1,8 +1,8 @@ -package com.baeldung.jhipster5.web.rest; -import com.baeldung.jhipster5.service.BookService; -import com.baeldung.jhipster5.web.rest.errors.BadRequestAlertException; -import com.baeldung.jhipster5.web.rest.util.HeaderUtil; -import com.baeldung.jhipster5.service.dto.BookDTO; +package com.baeldung.jhipster6.web.rest; +import com.baeldung.jhipster6.service.BookService; +import com.baeldung.jhipster6.web.rest.errors.BadRequestAlertException; +import com.baeldung.jhipster6.web.rest.util.HeaderUtil; +import com.baeldung.jhipster6.service.dto.BookDTO; import io.github.jhipster.web.util.ResponseUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/ClientForwardController.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/ClientForwardController.java new file mode 100644 index 0000000000..a524d90fc0 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/ClientForwardController.java @@ -0,0 +1,17 @@ +package com.baeldung.jhipster6.web.rest; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class ClientForwardController { + + /** + * Forwards any unmapped paths (except those containing a period) to the client {@code index.html}. + * @return forward to client {@code index.html}. + */ + @GetMapping(value = "/**/{path:[^\\.]*}") + public String forward() { + return "forward:/"; + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/LogsResource.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/LogsResource.java similarity index 91% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/LogsResource.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/LogsResource.java index f35b5f2d5c..76d71d23d0 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/LogsResource.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/LogsResource.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.web.rest; +package com.baeldung.jhipster6.web.rest; -import com.baeldung.jhipster5.web.rest.vm.LoggerVM; +import com.baeldung.jhipster6.web.rest.vm.LoggerVM; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.LoggerContext; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/UserJWTController.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/UserJWTController.java similarity index 91% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/UserJWTController.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/UserJWTController.java index aeea587089..1bb647d2ef 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/UserJWTController.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/UserJWTController.java @@ -1,8 +1,8 @@ -package com.baeldung.jhipster5.web.rest; +package com.baeldung.jhipster6.web.rest; -import com.baeldung.jhipster5.security.jwt.JWTFilter; -import com.baeldung.jhipster5.security.jwt.TokenProvider; -import com.baeldung.jhipster5.web.rest.vm.LoginVM; +import com.baeldung.jhipster6.security.jwt.JWTFilter; +import com.baeldung.jhipster6.security.jwt.TokenProvider; +import com.baeldung.jhipster6.web.rest.vm.LoginVM; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/UserResource.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/UserResource.java similarity index 91% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/UserResource.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/UserResource.java index a95acf6759..36fa8f319c 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/UserResource.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/UserResource.java @@ -1,17 +1,17 @@ -package com.baeldung.jhipster5.web.rest; +package com.baeldung.jhipster6.web.rest; -import com.baeldung.jhipster5.config.Constants; -import com.baeldung.jhipster5.domain.User; -import com.baeldung.jhipster5.repository.UserRepository; -import com.baeldung.jhipster5.security.AuthoritiesConstants; -import com.baeldung.jhipster5.service.MailService; -import com.baeldung.jhipster5.service.UserService; -import com.baeldung.jhipster5.service.dto.UserDTO; -import com.baeldung.jhipster5.web.rest.errors.BadRequestAlertException; -import com.baeldung.jhipster5.web.rest.errors.EmailAlreadyUsedException; -import com.baeldung.jhipster5.web.rest.errors.LoginAlreadyUsedException; -import com.baeldung.jhipster5.web.rest.util.HeaderUtil; -import com.baeldung.jhipster5.web.rest.util.PaginationUtil; +import com.baeldung.jhipster6.config.Constants; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.UserRepository; +import com.baeldung.jhipster6.security.AuthoritiesConstants; +import com.baeldung.jhipster6.service.MailService; +import com.baeldung.jhipster6.service.UserService; +import com.baeldung.jhipster6.service.dto.UserDTO; +import com.baeldung.jhipster6.web.rest.errors.BadRequestAlertException; +import com.baeldung.jhipster6.web.rest.errors.EmailAlreadyUsedException; +import com.baeldung.jhipster6.web.rest.errors.LoginAlreadyUsedException; +import com.baeldung.jhipster6.web.rest.util.HeaderUtil; +import com.baeldung.jhipster6.web.rest.util.PaginationUtil; import io.github.jhipster.web.util.ResponseUtil; import org.slf4j.Logger; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/BadRequestAlertException.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/BadRequestAlertException.java similarity index 96% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/BadRequestAlertException.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/BadRequestAlertException.java index c4c403351a..a2e71a28bf 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/BadRequestAlertException.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/BadRequestAlertException.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; import org.zalando.problem.AbstractThrowableProblem; import org.zalando.problem.Status; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/CustomParameterizedException.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/CustomParameterizedException.java similarity index 97% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/CustomParameterizedException.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/CustomParameterizedException.java index 8c3df82b83..31add5c588 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/CustomParameterizedException.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/CustomParameterizedException.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; import org.zalando.problem.AbstractThrowableProblem; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/EmailAlreadyUsedException.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/EmailAlreadyUsedException.java similarity index 86% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/EmailAlreadyUsedException.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/EmailAlreadyUsedException.java index b3dcc0279e..01e358b76c 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/EmailAlreadyUsedException.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/EmailAlreadyUsedException.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; public class EmailAlreadyUsedException extends BadRequestAlertException { diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/EmailNotFoundException.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/EmailNotFoundException.java similarity index 88% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/EmailNotFoundException.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/EmailNotFoundException.java index b93081cacb..51a7857f32 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/EmailNotFoundException.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/EmailNotFoundException.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; import org.zalando.problem.AbstractThrowableProblem; import org.zalando.problem.Status; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/ErrorConstants.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/ErrorConstants.java similarity index 96% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/ErrorConstants.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/ErrorConstants.java index 06be9254a9..b6a256dda0 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/ErrorConstants.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/ErrorConstants.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; import java.net.URI; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/ExceptionTranslator.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/ExceptionTranslator.java similarity index 97% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/ExceptionTranslator.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/ExceptionTranslator.java index 3f7cc6b565..d9e5697c77 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/ExceptionTranslator.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/ExceptionTranslator.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; -import com.baeldung.jhipster5.web.rest.util.HeaderUtil; +import com.baeldung.jhipster6.web.rest.util.HeaderUtil; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.http.ResponseEntity; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/FieldErrorVM.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/FieldErrorVM.java similarity index 92% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/FieldErrorVM.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/FieldErrorVM.java index 349f548850..7c2504a3fc 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/FieldErrorVM.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/FieldErrorVM.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; import java.io.Serializable; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/InternalServerErrorException.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/InternalServerErrorException.java similarity index 90% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/InternalServerErrorException.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/InternalServerErrorException.java index 13e128237b..844f315bfd 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/InternalServerErrorException.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/InternalServerErrorException.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; import org.zalando.problem.AbstractThrowableProblem; import org.zalando.problem.Status; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/InvalidPasswordException.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/InvalidPasswordException.java similarity index 88% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/InvalidPasswordException.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/InvalidPasswordException.java index 6bb91247ff..02d4b4da01 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/InvalidPasswordException.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/InvalidPasswordException.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; import org.zalando.problem.AbstractThrowableProblem; import org.zalando.problem.Status; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/LoginAlreadyUsedException.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/LoginAlreadyUsedException.java similarity index 85% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/LoginAlreadyUsedException.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/LoginAlreadyUsedException.java index 987a94193d..fabd4d153d 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/LoginAlreadyUsedException.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/LoginAlreadyUsedException.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; public class LoginAlreadyUsedException extends BadRequestAlertException { diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/package-info.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/package-info.java similarity index 75% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/package-info.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/package-info.java index 7f57af4429..b791df1268 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/errors/package-info.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/errors/package-info.java @@ -3,4 +3,4 @@ * * More information on https://github.com/zalando/problem-spring-web */ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; diff --git a/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/package-info.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/package-info.java new file mode 100644 index 0000000000..f5d106c277 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/package-info.java @@ -0,0 +1,4 @@ +/** + * Spring MVC REST controllers. + */ +package com.baeldung.jhipster6.web.rest; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/util/HeaderUtil.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/util/HeaderUtil.java similarity index 97% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/util/HeaderUtil.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/util/HeaderUtil.java index 91fdd68261..8546b97956 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/util/HeaderUtil.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/util/HeaderUtil.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.util; +package com.baeldung.jhipster6.web.rest.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/util/PaginationUtil.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/util/PaginationUtil.java similarity index 97% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/util/PaginationUtil.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/util/PaginationUtil.java index 9928dbe171..7c28d93486 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/util/PaginationUtil.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/util/PaginationUtil.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.util; +package com.baeldung.jhipster6.web.rest.util; import org.springframework.data.domain.Page; import org.springframework.http.HttpHeaders; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/KeyAndPasswordVM.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/KeyAndPasswordVM.java similarity index 91% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/KeyAndPasswordVM.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/KeyAndPasswordVM.java index 840fa02cfc..b2b1f91b0a 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/KeyAndPasswordVM.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/KeyAndPasswordVM.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.vm; +package com.baeldung.jhipster6.web.rest.vm; /** * View Model object for storing the user's key and password. diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/LoggerVM.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/LoggerVM.java similarity index 95% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/LoggerVM.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/LoggerVM.java index 952e7df298..d7ca167edf 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/LoggerVM.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/LoggerVM.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.vm; +package com.baeldung.jhipster6.web.rest.vm; import ch.qos.logback.classic.Logger; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/LoginVM.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/LoginVM.java similarity index 96% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/LoginVM.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/LoginVM.java index 8fc119ab69..40ede22b3a 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/LoginVM.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/LoginVM.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.vm; +package com.baeldung.jhipster6.web.rest.vm; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/ManagedUserVM.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/ManagedUserVM.java similarity index 88% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/ManagedUserVM.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/ManagedUserVM.java index 314577c456..2746ca6de0 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/ManagedUserVM.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/ManagedUserVM.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.web.rest.vm; +package com.baeldung.jhipster6.web.rest.vm; -import com.baeldung.jhipster5.service.dto.UserDTO; +import com.baeldung.jhipster6.service.dto.UserDTO; import javax.validation.constraints.Size; /** diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/package-info.java b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/package-info.java similarity index 57% rename from jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/package-info.java rename to jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/package-info.java index ff58799037..af0defc392 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/vm/package-info.java +++ b/jhipster-6/bookstore-monolith/src/main/java/com/baeldung/jhipster6/web/rest/vm/package-info.java @@ -1,4 +1,4 @@ /** * View Models used by Spring MVC REST controllers. */ -package com.baeldung.jhipster5.web.rest.vm; +package com.baeldung.jhipster6.web.rest.vm; diff --git a/jhipster-5/bookstore-monolith/src/main/jib/entrypoint.sh b/jhipster-6/bookstore-monolith/src/main/jib/entrypoint.sh similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/jib/entrypoint.sh rename to jhipster-6/bookstore-monolith/src/main/jib/entrypoint.sh diff --git a/jhipster-5/bookstore-monolith/src/main/resources/.h2.server.properties b/jhipster-6/bookstore-monolith/src/main/resources/.h2.server.properties similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/.h2.server.properties rename to jhipster-6/bookstore-monolith/src/main/resources/.h2.server.properties diff --git a/jhipster-5/bookstore-monolith/src/main/resources/banner.txt b/jhipster-6/bookstore-monolith/src/main/resources/banner.txt similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/banner.txt rename to jhipster-6/bookstore-monolith/src/main/resources/banner.txt diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/application-dev.yml b/jhipster-6/bookstore-monolith/src/main/resources/config/application-dev.yml similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/config/application-dev.yml rename to jhipster-6/bookstore-monolith/src/main/resources/config/application-dev.yml diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/application-prod.yml b/jhipster-6/bookstore-monolith/src/main/resources/config/application-prod.yml similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/config/application-prod.yml rename to jhipster-6/bookstore-monolith/src/main/resources/config/application-prod.yml diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/application-tls.yml b/jhipster-6/bookstore-monolith/src/main/resources/config/application-tls.yml similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/config/application-tls.yml rename to jhipster-6/bookstore-monolith/src/main/resources/config/application-tls.yml diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/application.yml b/jhipster-6/bookstore-monolith/src/main/resources/config/application.yml similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/config/application.yml rename to jhipster-6/bookstore-monolith/src/main/resources/config/application.yml diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/authorities.csv b/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/authorities.csv similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/authorities.csv rename to jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/authorities.csv diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml b/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml rename to jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/changelog/20190319124041_added_entity_Book.xml b/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/changelog/20190319124041_added_entity_Book.xml similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/changelog/20190319124041_added_entity_Book.xml rename to jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/changelog/20190319124041_added_entity_Book.xml diff --git a/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/data/authority.csv b/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/data/authority.csv new file mode 100644 index 0000000000..af5c6dfa18 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/data/authority.csv @@ -0,0 +1,3 @@ +name +ROLE_ADMIN +ROLE_USER diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/users.csv b/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/data/user.csv similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/users.csv rename to jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/data/user.csv diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/users_authorities.csv b/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/data/user_authority.csv similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/users_authorities.csv rename to jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/data/user_authority.csv diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/master.xml b/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/master.xml similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/master.xml rename to jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/master.xml diff --git a/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/users.csv b/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/users.csv new file mode 100644 index 0000000000..b25922b699 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/users.csv @@ -0,0 +1,5 @@ +id;login;password_hash;first_name;last_name;email;image_url;activated;lang_key;created_by;last_modified_by +1;system;$2a$10$mE.qmcV0mFU5NcKh73TZx.z4ueI/.bDWbj0T1BYyqP481kGGarKLG;System;System;system@localhost;;true;en;system;system +2;anonymoususer;$2a$10$j8S5d7Sr7.8VTOYNviDPOeWX8KcYILUVJBsYV83Y5NtECayypx9lO;Anonymous;User;anonymous@localhost;;true;en;system;system +3;admin;$2a$10$gSAhZrxMllrbgj/kkK9UceBPpChGWJA7SYIb1Mqo.n5aNLq1/oRrC;Administrator;Administrator;admin@localhost;;true;en;system;system +4;user;$2a$10$VEjxo0jq2YG9Rbk2HmX9S.k1uZBGYUHdUcid3g/vfiEl7lwWgOH/K;User;User;user@localhost;;true;en;system;system diff --git a/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/users_authorities.csv b/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/users_authorities.csv new file mode 100644 index 0000000000..06c5feeeea --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/resources/config/liquibase/users_authorities.csv @@ -0,0 +1,6 @@ +user_id;authority_name +1;ROLE_ADMIN +1;ROLE_USER +3;ROLE_ADMIN +3;ROLE_USER +4;ROLE_USER diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/tls/keystore.p12 b/jhipster-6/bookstore-monolith/src/main/resources/config/tls/keystore.p12 similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/config/tls/keystore.p12 rename to jhipster-6/bookstore-monolith/src/main/resources/config/tls/keystore.p12 diff --git a/jhipster-5/bookstore-monolith/src/main/resources/i18n/messages.properties b/jhipster-6/bookstore-monolith/src/main/resources/i18n/messages.properties similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/i18n/messages.properties rename to jhipster-6/bookstore-monolith/src/main/resources/i18n/messages.properties diff --git a/jhipster-5/bookstore-monolith/src/main/resources/logback-spring.xml b/jhipster-6/bookstore-monolith/src/main/resources/logback-spring.xml similarity index 98% rename from jhipster-5/bookstore-monolith/src/main/resources/logback-spring.xml rename to jhipster-6/bookstore-monolith/src/main/resources/logback-spring.xml index 4aa548af35..b0e2d9aa95 100644 --- a/jhipster-5/bookstore-monolith/src/main/resources/logback-spring.xml +++ b/jhipster-6/bookstore-monolith/src/main/resources/logback-spring.xml @@ -30,9 +30,9 @@ - + - + diff --git a/jhipster-5/bookstore-monolith/src/main/resources/templates/error.html b/jhipster-6/bookstore-monolith/src/main/resources/templates/error.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/templates/error.html rename to jhipster-6/bookstore-monolith/src/main/resources/templates/error.html diff --git a/jhipster-5/bookstore-monolith/src/main/resources/templates/mail/activationEmail.html b/jhipster-6/bookstore-monolith/src/main/resources/templates/mail/activationEmail.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/templates/mail/activationEmail.html rename to jhipster-6/bookstore-monolith/src/main/resources/templates/mail/activationEmail.html diff --git a/jhipster-5/bookstore-monolith/src/main/resources/templates/mail/creationEmail.html b/jhipster-6/bookstore-monolith/src/main/resources/templates/mail/creationEmail.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/templates/mail/creationEmail.html rename to jhipster-6/bookstore-monolith/src/main/resources/templates/mail/creationEmail.html diff --git a/jhipster-5/bookstore-monolith/src/main/resources/templates/mail/passwordResetEmail.html b/jhipster-6/bookstore-monolith/src/main/resources/templates/mail/passwordResetEmail.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/resources/templates/mail/passwordResetEmail.html rename to jhipster-6/bookstore-monolith/src/main/resources/templates/mail/passwordResetEmail.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/404.html b/jhipster-6/bookstore-monolith/src/main/webapp/404.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/404.html rename to jhipster-6/bookstore-monolith/src/main/webapp/404.html diff --git a/jhipster-6/bookstore-monolith/src/main/webapp/WEB-INF/web.xml b/jhipster-6/bookstore-monolith/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..f1611b515a --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,13 @@ + + + + + html + text/html;charset=utf-8 + + + diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/account.module.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/account.module.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/account.module.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/account.module.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/account.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/account.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/account.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/account.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/activate/activate.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/activate/activate.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/activate/activate.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/activate/activate.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/activate/activate.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/activate/activate.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/activate/activate.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/activate/activate.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/activate/activate.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/activate/activate.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/activate/activate.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/activate/activate.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/activate/activate.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/activate/activate.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/activate/activate.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/activate/activate.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/index.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/index.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/index.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/index.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/finish/password-reset-finish.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password-reset/init/password-reset-init.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password/password-strength-bar.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password/password-strength-bar.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password/password-strength-bar.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password/password-strength-bar.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password/password-strength-bar.scss b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password/password-strength-bar.scss similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password/password-strength-bar.scss rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password/password-strength-bar.scss diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password/password.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password/password.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password/password.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password/password.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password/password.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password/password.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password/password.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password/password.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password/password.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password/password.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password/password.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password/password.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/password/password.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/password/password.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/password/password.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/password/password.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/register/register.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/register/register.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/register/register.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/register/register.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/register/register.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/register/register.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/register/register.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/register/register.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/register/register.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/register/register.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/register/register.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/register/register.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/register/register.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/register/register.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/register/register.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/register/register.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/settings/settings.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/settings/settings.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/settings/settings.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/settings/settings.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/settings/settings.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/settings/settings.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/settings/settings.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/settings/settings.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/settings/settings.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/account/settings/settings.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/account/settings/settings.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/account/settings/settings.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/admin.module.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/admin.module.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/admin.module.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/admin.module.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/admin.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/admin.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/admin.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/admin.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/audits/audit-data.model.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/audits/audit-data.model.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/audits/audit-data.model.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/audits/audit-data.model.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/audits/audit.model.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/audits/audit.model.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/audits/audit.model.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/audits/audit.model.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/audits/audits.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/audits/audits.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/audits/audits.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/audits/audits.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/audits/audits.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/audits/audits.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/audits/audits.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/audits/audits.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/audits/audits.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/audits/audits.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/audits/audits.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/audits/audits.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/audits/audits.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/audits/audits.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/audits/audits.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/audits/audits.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/configuration/configuration.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/docs/docs.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/docs/docs.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/docs/docs.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/docs/docs.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/docs/docs.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/docs/docs.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/docs/docs.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/docs/docs.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/docs/docs.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/docs/docs.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/docs/docs.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/docs/docs.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/health/health-modal.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/health/health-modal.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/health/health-modal.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/health/health-modal.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/health/health-modal.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/health/health-modal.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/health/health-modal.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/health/health-modal.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/health/health.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/health/health.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/health/health.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/health/health.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/health/health.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/health/health.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/health/health.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/health/health.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/health/health.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/health/health.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/health/health.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/health/health.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/health/health.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/health/health.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/health/health.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/health/health.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/index.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/index.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/index.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/index.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/logs/log.model.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/logs/log.model.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/logs/log.model.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/logs/log.model.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/logs/logs.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/logs/logs.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/logs/logs.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/logs/logs.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/logs/logs.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/logs/logs.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/logs/logs.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/logs/logs.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/logs/logs.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/logs/logs.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/logs/logs.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/logs/logs.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/logs/logs.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/logs/logs.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/logs/logs.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/logs/logs.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/metrics/metrics.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-detail.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-detail.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-detail.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-detail.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-detail.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-detail.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-detail.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-detail.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-update.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-update.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-update.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-update.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-update.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-update.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-update.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management-update.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/admin/user-management/user-management.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/app-routing.module.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/app-routing.module.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/app-routing.module.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/app-routing.module.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/app.constants.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/app.constants.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/app.constants.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/app.constants.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/app.main.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/app.main.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/app.main.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/app.main.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/app.module.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/app.module.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/app.module.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/app.module.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/blocks/config/prod.config.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/blocks/config/prod.config.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/blocks/config/prod.config.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/blocks/config/prod.config.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/blocks/config/uib-pagination.config.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/blocks/config/uib-pagination.config.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/blocks/config/uib-pagination.config.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/blocks/config/uib-pagination.config.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/blocks/interceptor/auth.interceptor.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/blocks/interceptor/auth.interceptor.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/blocks/interceptor/auth.interceptor.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/blocks/interceptor/auth.interceptor.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/blocks/interceptor/errorhandler.interceptor.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/blocks/interceptor/errorhandler.interceptor.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/blocks/interceptor/errorhandler.interceptor.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/blocks/interceptor/errorhandler.interceptor.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/blocks/interceptor/notification.interceptor.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/blocks/interceptor/notification.interceptor.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/blocks/interceptor/notification.interceptor.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/blocks/interceptor/notification.interceptor.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/core/auth/account.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/core/auth/account.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/core/auth/account.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/core/auth/account.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/core/auth/auth-jwt.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/core/auth/auth-jwt.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/core/auth/auth-jwt.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/core/auth/auth-jwt.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/core/auth/csrf.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/core/auth/csrf.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/core/auth/csrf.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/core/auth/csrf.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/core/auth/state-storage.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/core/auth/state-storage.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/core/auth/state-storage.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/core/auth/state-storage.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/core/auth/user-route-access-service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/core/auth/user-route-access-service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/core/auth/user-route-access-service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/core/auth/user-route-access-service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/core/core.module.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/core/core.module.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/core/core.module.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/core/core.module.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/core/index.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/core/index.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/core/index.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/core/index.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/core/login/login-modal.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/core/login/login-modal.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/core/login/login-modal.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/core/login/login-modal.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/core/login/login.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/core/login/login.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/core/login/login.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/core/login/login.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/core/user/account.model.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/core/user/account.model.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/core/user/account.model.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/core/user/account.model.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/core/user/user.model.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/core/user/user.model.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/core/user/user.model.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/core/user/user.model.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/core/user/user.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/core/user/user.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/core/user/user.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/core/user/user.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.module.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book.module.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.module.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book.module.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/book.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/index.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/index.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/index.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/book/index.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/entity.module.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/entities/entity.module.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/entities/entity.module.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/entities/entity.module.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/home/home.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/home/home.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/home/home.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/home/home.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/home/home.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/home/home.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/home/home.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/home/home.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/home/home.module.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/home/home.module.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/home/home.module.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/home/home.module.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/home/home.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/home/home.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/home/home.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/home/home.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/home/home.scss b/jhipster-6/bookstore-monolith/src/main/webapp/app/home/home.scss similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/home/home.scss rename to jhipster-6/bookstore-monolith/src/main/webapp/app/home/home.scss diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/home/index.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/home/index.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/home/index.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/home/index.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/error/error.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/error/error.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/error/error.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/error/error.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/error/error.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/error/error.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/error/error.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/error/error.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/error/error.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/error/error.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/error/error.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/error/error.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/footer/footer.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/footer/footer.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/footer/footer.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/footer/footer.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/footer/footer.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/footer/footer.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/footer/footer.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/footer/footer.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/index.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/index.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/index.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/index.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/main/main.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/main/main.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/main/main.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/main/main.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/main/main.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/main/main.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/main/main.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/main/main.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.route.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.route.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.route.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.route.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.scss b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.scss similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.scss rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.scss diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/profiles/page-ribbon.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/profiles/page-ribbon.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/profiles/page-ribbon.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/profiles/page-ribbon.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/profiles/page-ribbon.scss b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/profiles/page-ribbon.scss similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/profiles/page-ribbon.scss rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/profiles/page-ribbon.scss diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/profiles/profile-info.model.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/profiles/profile-info.model.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/profiles/profile-info.model.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/profiles/profile-info.model.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/profiles/profile.service.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/profiles/profile.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/profiles/profile.service.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/layouts/profiles/profile.service.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/polyfills.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/polyfills.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/polyfills.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/polyfills.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/alert/alert-error.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/alert/alert-error.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/alert/alert-error.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/alert/alert-error.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/alert/alert.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/alert/alert.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/alert/alert.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/alert/alert.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/auth/has-any-authority.directive.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/auth/has-any-authority.directive.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/auth/has-any-authority.directive.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/auth/has-any-authority.directive.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/constants/error.constants.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/constants/error.constants.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/constants/error.constants.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/constants/error.constants.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/constants/input.constants.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/constants/input.constants.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/constants/input.constants.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/constants/input.constants.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/constants/pagination.constants.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/constants/pagination.constants.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/constants/pagination.constants.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/constants/pagination.constants.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/index.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/index.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/index.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/index.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/login/login.component.html b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/login/login.component.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/login/login.component.html rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/login/login.component.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/login/login.component.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/login/login.component.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/login/login.component.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/login/login.component.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/model/book.model.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/model/book.model.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/model/book.model.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/model/book.model.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/shared-common.module.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/shared-common.module.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/shared-common.module.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/shared-common.module.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/shared-libs.module.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/shared-libs.module.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/shared-libs.module.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/shared-libs.module.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/shared.module.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/shared.module.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/shared.module.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/shared.module.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/util/datepicker-adapter.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/util/datepicker-adapter.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/util/datepicker-adapter.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/util/datepicker-adapter.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/util/request-util.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/shared/util/request-util.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/shared/util/request-util.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/shared/util/request-util.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/vendor.ts b/jhipster-6/bookstore-monolith/src/main/webapp/app/vendor.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/app/vendor.ts rename to jhipster-6/bookstore-monolith/src/main/webapp/app/vendor.ts diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/css/loading.css b/jhipster-6/bookstore-monolith/src/main/webapp/content/css/loading.css similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/css/loading.css rename to jhipster-6/bookstore-monolith/src/main/webapp/content/css/loading.css diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0.svg b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0.svg old mode 100755 new mode 100644 similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0.svg rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0.svg diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-192.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-192.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-192.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-192.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-256.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-256.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-256.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-256.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-384.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-384.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-384.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-384.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-512.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-512.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-512.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_0_head-512.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1.svg b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1.svg old mode 100755 new mode 100644 similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1.svg rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1.svg diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-192.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-192.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-192.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-192.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-256.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-256.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-256.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-256.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-384.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-384.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-384.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-384.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-512.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-512.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-512.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_1_head-512.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2.svg b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2.svg old mode 100755 new mode 100644 similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2.svg rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2.svg diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-192.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-192.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-192.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-192.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-256.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-256.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-256.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-256.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-384.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-384.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-384.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-384.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-512.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-512.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-512.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_2_head-512.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3.svg b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3.svg old mode 100755 new mode 100644 similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3.svg rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3.svg diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-192.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-192.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-192.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-192.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-256.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-256.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-256.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-256.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-384.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-384.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-384.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-384.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-512.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-512.png similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-512.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/jhipster_family_member_3_head-512.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/images/logo-jhipster.png b/jhipster-6/bookstore-monolith/src/main/webapp/content/images/logo-jhipster.png old mode 100755 new mode 100644 similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/images/logo-jhipster.png rename to jhipster-6/bookstore-monolith/src/main/webapp/content/images/logo-jhipster.png diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/scss/_bootstrap-variables.scss b/jhipster-6/bookstore-monolith/src/main/webapp/content/scss/_bootstrap-variables.scss similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/scss/_bootstrap-variables.scss rename to jhipster-6/bookstore-monolith/src/main/webapp/content/scss/_bootstrap-variables.scss diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/scss/global.scss b/jhipster-6/bookstore-monolith/src/main/webapp/content/scss/global.scss similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/scss/global.scss rename to jhipster-6/bookstore-monolith/src/main/webapp/content/scss/global.scss diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/content/scss/vendor.scss b/jhipster-6/bookstore-monolith/src/main/webapp/content/scss/vendor.scss similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/content/scss/vendor.scss rename to jhipster-6/bookstore-monolith/src/main/webapp/content/scss/vendor.scss diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/favicon.ico b/jhipster-6/bookstore-monolith/src/main/webapp/favicon.ico old mode 100755 new mode 100644 similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/favicon.ico rename to jhipster-6/bookstore-monolith/src/main/webapp/favicon.ico diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/index.html b/jhipster-6/bookstore-monolith/src/main/webapp/index.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/index.html rename to jhipster-6/bookstore-monolith/src/main/webapp/index.html diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/manifest.webapp b/jhipster-6/bookstore-monolith/src/main/webapp/manifest.webapp similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/manifest.webapp rename to jhipster-6/bookstore-monolith/src/main/webapp/manifest.webapp diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/robots.txt b/jhipster-6/bookstore-monolith/src/main/webapp/robots.txt similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/robots.txt rename to jhipster-6/bookstore-monolith/src/main/webapp/robots.txt diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/swagger-ui/index.html b/jhipster-6/bookstore-monolith/src/main/webapp/swagger-ui/index.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/main/webapp/swagger-ui/index.html rename to jhipster-6/bookstore-monolith/src/main/webapp/swagger-ui/index.html diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/config/WebConfigurerUnitTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/config/WebConfigurerUnitTest.java similarity index 73% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/config/WebConfigurerUnitTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/config/WebConfigurerUnitTest.java index 764d6b3587..44452caac9 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/config/WebConfigurerUnitTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/config/WebConfigurerUnitTest.java @@ -1,26 +1,19 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import io.github.jhipster.config.JHipsterConstants; import io.github.jhipster.config.JHipsterProperties; import io.github.jhipster.web.filter.CachingHttpHeadersFilter; -import io.undertow.Undertow; -import io.undertow.Undertow.Builder; -import io.undertow.UndertowOptions; -import org.apache.commons.io.FilenameUtils; - import org.h2.server.web.WebServlet; -import org.junit.Before; -import org.junit.Test; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.mock.env.MockEnvironment; import org.springframework.mock.web.MockServletContext; -import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.xnio.OptionMap; import javax.servlet.*; + import java.util.*; import static org.assertj.core.api.Assertions.assertThat; @@ -33,9 +26,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** - * Unit tests for the WebConfigurer class. - * - * @see WebConfigurer + * Unit tests for the {@link WebConfigurer} class. */ public class WebConfigurerUnitTest { @@ -47,7 +38,7 @@ public class WebConfigurerUnitTest { private JHipsterProperties props; - @Before + @BeforeEach public void setup() { servletContext = spy(new MockServletContext()); doReturn(mock(FilterRegistration.Dynamic.class)) @@ -78,35 +69,19 @@ public class WebConfigurerUnitTest { verify(servletContext, never()).addFilter(eq("cachingHttpHeadersFilter"), any(CachingHttpHeadersFilter.class)); verify(servletContext).addServlet(eq("H2Console"), any(WebServlet.class)); } - - @Test - public void testCustomizeServletContainer() { - env.setActiveProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION); - UndertowServletWebServerFactory container = new UndertowServletWebServerFactory(); - webConfigurer.customize(container); - assertThat(container.getMimeMappings().get("abs")).isEqualTo("audio/x-mpeg"); - assertThat(container.getMimeMappings().get("html")).isEqualTo("text/html;charset=utf-8"); - assertThat(container.getMimeMappings().get("json")).isEqualTo("text/html;charset=utf-8"); - if (container.getDocumentRoot() != null) { - assertThat(container.getDocumentRoot().getPath()).isEqualTo(FilenameUtils.separatorsToSystem("target/www")); - } - - Builder builder = Undertow.builder(); - container.getBuilderCustomizers().forEach(c -> c.customize(builder)); - OptionMap.Builder serverOptions = (OptionMap.Builder) ReflectionTestUtils.getField(builder, "serverOptions"); - assertThat(serverOptions.getMap().get(UndertowOptions.ENABLE_HTTP2)).isNull(); - } - - @Test - public void testUndertowHttp2Enabled() { - props.getHttp().setVersion(JHipsterProperties.Http.Version.V_2_0); - UndertowServletWebServerFactory container = new UndertowServletWebServerFactory(); - webConfigurer.customize(container); - Builder builder = Undertow.builder(); - container.getBuilderCustomizers().forEach(c -> c.customize(builder)); - OptionMap.Builder serverOptions = (OptionMap.Builder) ReflectionTestUtils.getField(builder, "serverOptions"); - assertThat(serverOptions.getMap().get(UndertowOptions.ENABLE_HTTP2)).isTrue(); - } +// +// @Test +// public void testCustomizeServletContainer() { +// env.setActiveProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION); +// UndertowServletWebServerFactory container = new UndertowServletWebServerFactory(); +// webConfigurer.customize(container); +// assertThat(container.getMimeMappings().get("abs")).isEqualTo("audio/x-mpeg"); +// assertThat(container.getMimeMappings().get("html")).isEqualTo("text/html;charset=utf-8"); +// assertThat(container.getMimeMappings().get("json")).isEqualTo("text/html;charset=utf-8"); +// if (container.getDocumentRoot() != null) { +// assertThat(container.getDocumentRoot()).isEqualTo(new File("target/classes/static/")); +// } +// } @Test public void testCorsFilterOnApiPath() throws Exception { diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/config/WebConfigurerUnitTestController.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/config/WebConfigurerUnitTestController.java similarity index 89% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/config/WebConfigurerUnitTestController.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/config/WebConfigurerUnitTestController.java index ee72e1c80e..271d18278e 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/config/WebConfigurerUnitTestController.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/config/WebConfigurerUnitTestController.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.config; +package com.baeldung.jhipster6.config; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/config/timezone/HibernateTimeZoneIT.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/config/timezone/HibernateTimeZoneIT.java new file mode 100644 index 0000000000..2e506edab4 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/config/timezone/HibernateTimeZoneIT.java @@ -0,0 +1,174 @@ +package com.baeldung.jhipster6.config.timezone; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.repository.timezone.DateTimeWrapper; +import com.baeldung.jhipster6.repository.timezone.DateTimeWrapperRepository; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.rowset.SqlRowSet; +import org.springframework.transaction.annotation.Transactional; + +import java.time.*; +import java.time.format.DateTimeFormatter; + +import static java.lang.String.format; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for the UTC Hibernate configuration. + */ +@SpringBootTest(classes = BookstoreApp.class) +public class HibernateTimeZoneIT { + + @Autowired + private DateTimeWrapperRepository dateTimeWrapperRepository; + @Autowired + private JdbcTemplate jdbcTemplate; + + private DateTimeWrapper dateTimeWrapper; + private DateTimeFormatter dateTimeFormatter; + private DateTimeFormatter timeFormatter; + private DateTimeFormatter dateFormatter; + + @BeforeEach + public void setup() { + dateTimeWrapper = new DateTimeWrapper(); + dateTimeWrapper.setInstant(Instant.parse("2014-11-12T05:50:00.0Z")); + dateTimeWrapper.setLocalDateTime(LocalDateTime.parse("2014-11-12T07:50:00.0")); + dateTimeWrapper.setOffsetDateTime(OffsetDateTime.parse("2011-12-14T08:30:00.0Z")); + dateTimeWrapper.setZonedDateTime(ZonedDateTime.parse("2011-12-14T08:30:00.0Z")); + dateTimeWrapper.setLocalTime(LocalTime.parse("14:30:00")); + dateTimeWrapper.setOffsetTime(OffsetTime.parse("14:30:00+02:00")); + dateTimeWrapper.setLocalDate(LocalDate.parse("2016-09-10")); + + dateTimeFormatter = DateTimeFormatter + .ofPattern("yyyy-MM-dd HH:mm:ss.S") + .withZone(ZoneId.of("UTC")); + + timeFormatter = DateTimeFormatter + .ofPattern("HH:mm:ss") + .withZone(ZoneId.of("UTC")); + + dateFormatter = DateTimeFormatter + .ofPattern("yyyy-MM-dd"); + } + + @Test + @Transactional + public void storeInstantWithUtcConfigShouldBeStoredOnGMTTimeZone() { + dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); + + String request = generateSqlRequest("instant", dateTimeWrapper.getId()); + SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request); + String expectedValue = dateTimeFormatter.format(dateTimeWrapper.getInstant()); + + assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue); + } + + @Test + @Transactional + public void storeLocalDateTimeWithUtcConfigShouldBeStoredOnGMTTimeZone() { + dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); + + String request = generateSqlRequest("local_date_time", dateTimeWrapper.getId()); + SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request); + String expectedValue = dateTimeWrapper + .getLocalDateTime() + .atZone(ZoneId.systemDefault()) + .format(dateTimeFormatter); + + assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue); + } + + @Test + @Transactional + public void storeOffsetDateTimeWithUtcConfigShouldBeStoredOnGMTTimeZone() { + dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); + + String request = generateSqlRequest("offset_date_time", dateTimeWrapper.getId()); + SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request); + String expectedValue = dateTimeWrapper + .getOffsetDateTime() + .format(dateTimeFormatter); + + assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue); + } + + @Test + @Transactional + public void storeZoneDateTimeWithUtcConfigShouldBeStoredOnGMTTimeZone() { + dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); + + String request = generateSqlRequest("zoned_date_time", dateTimeWrapper.getId()); + SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request); + String expectedValue = dateTimeWrapper + .getZonedDateTime() + .format(dateTimeFormatter); + + assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue); + } + + @Test + @Transactional + public void storeLocalTimeWithUtcConfigShouldBeStoredOnGMTTimeZoneAccordingToHis1stJan1970Value() { + dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); + + String request = generateSqlRequest("local_time", dateTimeWrapper.getId()); + SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request); + String expectedValue = dateTimeWrapper + .getLocalTime() + .atDate(LocalDate.of(1970, Month.JANUARY, 1)) + .atZone(ZoneId.systemDefault()) + .format(timeFormatter); + + assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue); + } + + @Test + @Transactional + public void storeOffsetTimeWithUtcConfigShouldBeStoredOnGMTTimeZoneAccordingToHis1stJan1970Value() { + dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); + + String request = generateSqlRequest("offset_time", dateTimeWrapper.getId()); + SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request); + String expectedValue = dateTimeWrapper + .getOffsetTime() + .toLocalTime() + .atDate(LocalDate.of(1970, Month.JANUARY, 1)) + .atZone(ZoneId.systemDefault()) + .format(timeFormatter); + + assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue); + } + + @Test + @Transactional + public void storeLocalDateWithUtcConfigShouldBeStoredWithoutTransformation() { + dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); + + String request = generateSqlRequest("local_date", dateTimeWrapper.getId()); + SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request); + String expectedValue = dateTimeWrapper + .getLocalDate() + .format(dateFormatter); + + assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue); + } + + private String generateSqlRequest(String fieldName, long id) { + return format("SELECT %s FROM jhi_date_time_wrapper where id=%d", fieldName, id); + } + + private void assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(SqlRowSet sqlRowSet, String expectedValue) { + while (sqlRowSet.next()) { + String dbValue = sqlRowSet.getString(1); + + assertThat(dbValue).isNotNull(); + assertThat(dbValue).isEqualTo(expectedValue); + } + } +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/config/timezone/HibernateTimeZoneIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/config/timezone/HibernateTimeZoneIntegrationTest.java similarity index 96% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/config/timezone/HibernateTimeZoneIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/config/timezone/HibernateTimeZoneIntegrationTest.java index fba77e037e..f0bf619ae4 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/config/timezone/HibernateTimeZoneIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/config/timezone/HibernateTimeZoneIntegrationTest.java @@ -1,8 +1,9 @@ -package com.baeldung.jhipster5.config.timezone; +package com.baeldung.jhipster6.config.timezone; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.repository.timezone.DateTimeWrapper; +import com.baeldung.jhipster6.repository.timezone.DateTimeWrapperRepository; -import com.baeldung.jhipster5.BookstoreApp; -import com.baeldung.jhipster5.repository.timezone.DateTimeWrapper; -import com.baeldung.jhipster5.repository.timezone.DateTimeWrapperRepository; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/repository/CustomAuditEventRepositoryIT.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/repository/CustomAuditEventRepositoryIT.java new file mode 100644 index 0000000000..a1f27a21da --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/repository/CustomAuditEventRepositoryIT.java @@ -0,0 +1,163 @@ +package com.baeldung.jhipster6.repository; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.config.Constants; +import com.baeldung.jhipster6.config.audit.AuditEventConverter; +import com.baeldung.jhipster6.domain.PersistentAuditEvent; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.audit.AuditEvent; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.security.web.authentication.WebAuthenticationDetails; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpSession; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link CustomAuditEventRepository}. + */ +@SpringBootTest(classes = BookstoreApp.class) +@Transactional +public class CustomAuditEventRepositoryIT { + + @Autowired + private PersistenceAuditEventRepository persistenceAuditEventRepository; + + @Autowired + private AuditEventConverter auditEventConverter; + + private CustomAuditEventRepository customAuditEventRepository; + + private PersistentAuditEvent testUserEvent; + + private PersistentAuditEvent testOtherUserEvent; + + private PersistentAuditEvent testOldUserEvent; + + @BeforeEach + public void setup() { + customAuditEventRepository = new CustomAuditEventRepository(persistenceAuditEventRepository, auditEventConverter); + persistenceAuditEventRepository.deleteAll(); + Instant oneHourAgo = Instant.now().minusSeconds(3600); + + testUserEvent = new PersistentAuditEvent(); + testUserEvent.setPrincipal("test-user"); + testUserEvent.setAuditEventType("test-type"); + testUserEvent.setAuditEventDate(oneHourAgo); + Map data = new HashMap<>(); + data.put("test-key", "test-value"); + testUserEvent.setData(data); + + testOldUserEvent = new PersistentAuditEvent(); + testOldUserEvent.setPrincipal("test-user"); + testOldUserEvent.setAuditEventType("test-type"); + testOldUserEvent.setAuditEventDate(oneHourAgo.minusSeconds(10000)); + + testOtherUserEvent = new PersistentAuditEvent(); + testOtherUserEvent.setPrincipal("other-test-user"); + testOtherUserEvent.setAuditEventType("test-type"); + testOtherUserEvent.setAuditEventDate(oneHourAgo); + } + + @Test + public void addAuditEvent() { + Map data = new HashMap<>(); + data.put("test-key", "test-value"); + AuditEvent event = new AuditEvent("test-user", "test-type", data); + customAuditEventRepository.add(event); + List persistentAuditEvents = persistenceAuditEventRepository.findAll(); + assertThat(persistentAuditEvents).hasSize(1); + PersistentAuditEvent persistentAuditEvent = persistentAuditEvents.get(0); + assertThat(persistentAuditEvent.getPrincipal()).isEqualTo(event.getPrincipal()); + assertThat(persistentAuditEvent.getAuditEventType()).isEqualTo(event.getType()); + assertThat(persistentAuditEvent.getData()).containsKey("test-key"); + assertThat(persistentAuditEvent.getData().get("test-key")).isEqualTo("test-value"); + assertThat(persistentAuditEvent.getAuditEventDate().truncatedTo(ChronoUnit.MILLIS)) + .isEqualTo(event.getTimestamp().truncatedTo(ChronoUnit.MILLIS)); + } + + @Test + public void addAuditEventTruncateLargeData() { + Map data = new HashMap<>(); + StringBuilder largeData = new StringBuilder(); + for (int i = 0; i < CustomAuditEventRepository.EVENT_DATA_COLUMN_MAX_LENGTH + 10; i++) { + largeData.append("a"); + } + data.put("test-key", largeData); + AuditEvent event = new AuditEvent("test-user", "test-type", data); + customAuditEventRepository.add(event); + List persistentAuditEvents = persistenceAuditEventRepository.findAll(); + assertThat(persistentAuditEvents).hasSize(1); + PersistentAuditEvent persistentAuditEvent = persistentAuditEvents.get(0); + assertThat(persistentAuditEvent.getPrincipal()).isEqualTo(event.getPrincipal()); + assertThat(persistentAuditEvent.getAuditEventType()).isEqualTo(event.getType()); + assertThat(persistentAuditEvent.getData()).containsKey("test-key"); + String actualData = persistentAuditEvent.getData().get("test-key"); + assertThat(actualData.length()).isEqualTo(CustomAuditEventRepository.EVENT_DATA_COLUMN_MAX_LENGTH); + assertThat(actualData).isSubstringOf(largeData); + assertThat(persistentAuditEvent.getAuditEventDate().truncatedTo(ChronoUnit.MILLIS)) + .isEqualTo(event.getTimestamp().truncatedTo(ChronoUnit.MILLIS)); + } + + @Test + public void testAddEventWithWebAuthenticationDetails() { + HttpSession session = new MockHttpSession(null, "test-session-id"); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setSession(session); + request.setRemoteAddr("1.2.3.4"); + WebAuthenticationDetails details = new WebAuthenticationDetails(request); + Map data = new HashMap<>(); + data.put("test-key", details); + AuditEvent event = new AuditEvent("test-user", "test-type", data); + customAuditEventRepository.add(event); + List persistentAuditEvents = persistenceAuditEventRepository.findAll(); + assertThat(persistentAuditEvents).hasSize(1); + PersistentAuditEvent persistentAuditEvent = persistentAuditEvents.get(0); + assertThat(persistentAuditEvent.getData().get("remoteAddress")).isEqualTo("1.2.3.4"); + assertThat(persistentAuditEvent.getData().get("sessionId")).isEqualTo("test-session-id"); + } + + @Test + public void testAddEventWithNullData() { + Map data = new HashMap<>(); + data.put("test-key", null); + AuditEvent event = new AuditEvent("test-user", "test-type", data); + customAuditEventRepository.add(event); + List persistentAuditEvents = persistenceAuditEventRepository.findAll(); + assertThat(persistentAuditEvents).hasSize(1); + PersistentAuditEvent persistentAuditEvent = persistentAuditEvents.get(0); + assertThat(persistentAuditEvent.getData().get("test-key")).isEqualTo("null"); + } + + @Test + public void addAuditEventWithAnonymousUser() { + Map data = new HashMap<>(); + data.put("test-key", "test-value"); + AuditEvent event = new AuditEvent(Constants.ANONYMOUS_USER, "test-type", data); + customAuditEventRepository.add(event); + List persistentAuditEvents = persistenceAuditEventRepository.findAll(); + assertThat(persistentAuditEvents).hasSize(0); + } + + @Test + public void addAuditEventWithAuthorizationFailureType() { + Map data = new HashMap<>(); + data.put("test-key", "test-value"); + AuditEvent event = new AuditEvent("test-user", "AUTHORIZATION_FAILURE", data); + customAuditEventRepository.add(event); + List persistentAuditEvents = persistenceAuditEventRepository.findAll(); + assertThat(persistentAuditEvents).hasSize(0); + } + +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/repository/CustomAuditEventRepositoryIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/repository/CustomAuditEventRepositoryIntegrationTest.java similarity index 93% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/repository/CustomAuditEventRepositoryIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/repository/CustomAuditEventRepositoryIntegrationTest.java index 948bf43f87..89ed2d4649 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/repository/CustomAuditEventRepositoryIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/repository/CustomAuditEventRepositoryIntegrationTest.java @@ -1,9 +1,10 @@ -package com.baeldung.jhipster5.repository; +package com.baeldung.jhipster6.repository; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.config.Constants; +import com.baeldung.jhipster6.config.audit.AuditEventConverter; +import com.baeldung.jhipster6.domain.PersistentAuditEvent; -import com.baeldung.jhipster5.BookstoreApp; -import com.baeldung.jhipster5.config.Constants; -import com.baeldung.jhipster5.config.audit.AuditEventConverter; -import com.baeldung.jhipster5.domain.PersistentAuditEvent; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -23,7 +24,6 @@ import java.util.List; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; -import static com.baeldung.jhipster5.repository.CustomAuditEventRepository.EVENT_DATA_COLUMN_MAX_LENGTH; /** * Test class for the CustomAuditEventRepository class. @@ -94,7 +94,7 @@ public class CustomAuditEventRepositoryIntegrationTest { public void addAuditEventTruncateLargeData() { Map data = new HashMap<>(); StringBuilder largeData = new StringBuilder(); - for (int i = 0; i < EVENT_DATA_COLUMN_MAX_LENGTH + 10; i++) { + for (int i = 0; i < CustomAuditEventRepository.EVENT_DATA_COLUMN_MAX_LENGTH + 10; i++) { largeData.append("a"); } data.put("test-key", largeData); @@ -107,7 +107,7 @@ public class CustomAuditEventRepositoryIntegrationTest { assertThat(persistentAuditEvent.getAuditEventType()).isEqualTo(event.getType()); assertThat(persistentAuditEvent.getData()).containsKey("test-key"); String actualData = persistentAuditEvent.getData().get("test-key"); - assertThat(actualData.length()).isEqualTo(EVENT_DATA_COLUMN_MAX_LENGTH); + assertThat(actualData.length()).isEqualTo(CustomAuditEventRepository.EVENT_DATA_COLUMN_MAX_LENGTH); assertThat(actualData).isSubstringOf(largeData); assertThat(persistentAuditEvent.getAuditEventDate()).isEqualTo(event.getTimestamp()); } diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/repository/timezone/DateTimeWrapper.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/repository/timezone/DateTimeWrapper.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/repository/timezone/DateTimeWrapper.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/repository/timezone/DateTimeWrapper.java index 473a8e782e..0d03a44cf8 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/repository/timezone/DateTimeWrapper.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/repository/timezone/DateTimeWrapper.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.repository.timezone; +package com.baeldung.jhipster6.repository.timezone; import javax.persistence.*; import java.io.Serializable; diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/repository/timezone/DateTimeWrapperRepository.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/repository/timezone/DateTimeWrapperRepository.java similarity index 84% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/repository/timezone/DateTimeWrapperRepository.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/repository/timezone/DateTimeWrapperRepository.java index 9c3831879f..5923db6ca0 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/repository/timezone/DateTimeWrapperRepository.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/repository/timezone/DateTimeWrapperRepository.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.repository.timezone; +package com.baeldung.jhipster6.repository.timezone; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/DomainUserDetailsServiceIT.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/DomainUserDetailsServiceIT.java new file mode 100644 index 0000000000..3e641dfad7 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/DomainUserDetailsServiceIT.java @@ -0,0 +1,125 @@ +package com.baeldung.jhipster6.security; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.UserRepository; + +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Locale; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +/** + * Integrations tests for {@link DomainUserDetailsService}. + */ +@SpringBootTest(classes = BookstoreApp.class) +@Transactional +public class DomainUserDetailsServiceIT { + + private static final String USER_ONE_LOGIN = "test-user-one"; + private static final String USER_ONE_EMAIL = "test-user-one@localhost"; + private static final String USER_TWO_LOGIN = "test-user-two"; + private static final String USER_TWO_EMAIL = "test-user-two@localhost"; + private static final String USER_THREE_LOGIN = "test-user-three"; + private static final String USER_THREE_EMAIL = "test-user-three@localhost"; + + @Autowired + private UserRepository userRepository; + + @Autowired + private UserDetailsService domainUserDetailsService; + + private User userOne; + private User userTwo; + private User userThree; + + @BeforeEach + public void init() { + userOne = new User(); + userOne.setLogin(USER_ONE_LOGIN); + userOne.setPassword(RandomStringUtils.random(60)); + userOne.setActivated(true); + userOne.setEmail(USER_ONE_EMAIL); + userOne.setFirstName("userOne"); + userOne.setLastName("doe"); + userOne.setLangKey("en"); + userRepository.save(userOne); + + userTwo = new User(); + userTwo.setLogin(USER_TWO_LOGIN); + userTwo.setPassword(RandomStringUtils.random(60)); + userTwo.setActivated(true); + userTwo.setEmail(USER_TWO_EMAIL); + userTwo.setFirstName("userTwo"); + userTwo.setLastName("doe"); + userTwo.setLangKey("en"); + userRepository.save(userTwo); + + userThree = new User(); + userThree.setLogin(USER_THREE_LOGIN); + userThree.setPassword(RandomStringUtils.random(60)); + userThree.setActivated(false); + userThree.setEmail(USER_THREE_EMAIL); + userThree.setFirstName("userThree"); + userThree.setLastName("doe"); + userThree.setLangKey("en"); + userRepository.save(userThree); + } + + @Test + @Transactional + public void assertThatUserCanBeFoundByLogin() { + UserDetails userDetails = domainUserDetailsService.loadUserByUsername(USER_ONE_LOGIN); + assertThat(userDetails).isNotNull(); + assertThat(userDetails.getUsername()).isEqualTo(USER_ONE_LOGIN); + } + + @Test + @Transactional + public void assertThatUserCanBeFoundByLoginIgnoreCase() { + UserDetails userDetails = domainUserDetailsService.loadUserByUsername(USER_ONE_LOGIN.toUpperCase(Locale.ENGLISH)); + assertThat(userDetails).isNotNull(); + assertThat(userDetails.getUsername()).isEqualTo(USER_ONE_LOGIN); + } + + @Test + @Transactional + public void assertThatUserCanBeFoundByEmail() { + UserDetails userDetails = domainUserDetailsService.loadUserByUsername(USER_TWO_EMAIL); + assertThat(userDetails).isNotNull(); + assertThat(userDetails.getUsername()).isEqualTo(USER_TWO_LOGIN); + } + + @Test + @Transactional + public void assertThatUserCanNotBeFoundByEmailIgnoreCase() { + assertThatExceptionOfType(UsernameNotFoundException.class).isThrownBy( + () -> domainUserDetailsService.loadUserByUsername(USER_TWO_EMAIL.toUpperCase(Locale.ENGLISH))); + } + + @Test + @Transactional + public void assertThatEmailIsPrioritizedOverLogin() { + UserDetails userDetails = domainUserDetailsService.loadUserByUsername(USER_ONE_EMAIL); + assertThat(userDetails).isNotNull(); + assertThat(userDetails.getUsername()).isEqualTo(USER_ONE_LOGIN); + } + + @Test + @Transactional + public void assertThatUserNotActivatedExceptionIsThrownForNotActivatedUsers() { + assertThatExceptionOfType(UserNotActivatedException.class).isThrownBy( + () -> domainUserDetailsService.loadUserByUsername(USER_THREE_LOGIN)); + } + +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/DomainUserDetailsServiceIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/DomainUserDetailsServiceIntegrationTest.java similarity index 95% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/DomainUserDetailsServiceIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/DomainUserDetailsServiceIntegrationTest.java index 11757f6516..bf30067406 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/DomainUserDetailsServiceIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/DomainUserDetailsServiceIntegrationTest.java @@ -1,8 +1,8 @@ -package com.baeldung.jhipster5.security; +package com.baeldung.jhipster6.security; -import com.baeldung.jhipster5.BookstoreApp; -import com.baeldung.jhipster5.domain.User; -import com.baeldung.jhipster5.repository.UserRepository; +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.UserRepository; import org.apache.commons.lang3.RandomStringUtils; import org.junit.Before; diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/MockAuthenticationManager.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/MockAuthenticationManager.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/MockAuthenticationManager.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/MockAuthenticationManager.java index bdcdba7644..0b32072010 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/MockAuthenticationManager.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/MockAuthenticationManager.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.security; +package com.baeldung.jhipster6.security; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/SecurityUtilsUnitTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/SecurityUtilsUnitTest.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/SecurityUtilsUnitTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/SecurityUtilsUnitTest.java index b2736badd6..b017acd022 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/SecurityUtilsUnitTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/SecurityUtilsUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.security; +package com.baeldung.jhipster6.security; import org.junit.Test; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/jwt/JWTFilter2UnitTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/jwt/JWTFilter2UnitTest.java new file mode 100644 index 0000000000..11a64993e9 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/jwt/JWTFilter2UnitTest.java @@ -0,0 +1,116 @@ +package com.baeldung.jhipster6.security.jwt; + +import com.baeldung.jhipster6.security.AuthoritiesConstants; + +import io.github.jhipster.config.JHipsterProperties; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.mock.web.MockFilterChain; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.Collections; + +import static org.assertj.core.api.Assertions.assertThat; + +public class JWTFilter2UnitTest { + + private TokenProvider tokenProvider; + + private JWTFilter jwtFilter; + + @Before + public void setup() { + JHipsterProperties jHipsterProperties = new JHipsterProperties(); + tokenProvider = new TokenProvider(jHipsterProperties); + ReflectionTestUtils.setField(tokenProvider, "key", + Keys.hmacShaKeyFor(Decoders.BASE64 + .decode("fd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8"))); + + ReflectionTestUtils.setField(tokenProvider, "tokenValidityInMilliseconds", 60000); + jwtFilter = new JWTFilter(tokenProvider); + SecurityContextHolder.getContext().setAuthentication(null); + } + + @Test + public void testJWTFilter() throws Exception { + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( + "test-user", + "test-password", + Collections.singletonList(new SimpleGrantedAuthority(AuthoritiesConstants.USER)) + ); + String jwt = tokenProvider.createToken(authentication, false); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader(JWTFilter.AUTHORIZATION_HEADER, "Bearer " + jwt); + request.setRequestURI("/api/test"); + MockHttpServletResponse response = new MockHttpServletResponse(); + MockFilterChain filterChain = new MockFilterChain(); + jwtFilter.doFilter(request, response, filterChain); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value()); + assertThat(SecurityContextHolder.getContext().getAuthentication().getName()).isEqualTo("test-user"); + assertThat(SecurityContextHolder.getContext().getAuthentication().getCredentials().toString()).isEqualTo(jwt); + } + + @Test + public void testJWTFilterInvalidToken() throws Exception { + String jwt = "wrong_jwt"; + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader(JWTFilter.AUTHORIZATION_HEADER, "Bearer " + jwt); + request.setRequestURI("/api/test"); + MockHttpServletResponse response = new MockHttpServletResponse(); + MockFilterChain filterChain = new MockFilterChain(); + jwtFilter.doFilter(request, response, filterChain); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value()); + assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull(); + } + + @Test + public void testJWTFilterMissingAuthorization() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setRequestURI("/api/test"); + MockHttpServletResponse response = new MockHttpServletResponse(); + MockFilterChain filterChain = new MockFilterChain(); + jwtFilter.doFilter(request, response, filterChain); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value()); + assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull(); + } + + @Test + public void testJWTFilterMissingToken() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader(JWTFilter.AUTHORIZATION_HEADER, "Bearer "); + request.setRequestURI("/api/test"); + MockHttpServletResponse response = new MockHttpServletResponse(); + MockFilterChain filterChain = new MockFilterChain(); + jwtFilter.doFilter(request, response, filterChain); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value()); + assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull(); + } + + @Test + public void testJWTFilterWrongScheme() throws Exception { + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( + "test-user", + "test-password", + Collections.singletonList(new SimpleGrantedAuthority(AuthoritiesConstants.USER)) + ); + String jwt = tokenProvider.createToken(authentication, false); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader(JWTFilter.AUTHORIZATION_HEADER, "Basic " + jwt); + request.setRequestURI("/api/test"); + MockHttpServletResponse response = new MockHttpServletResponse(); + MockFilterChain filterChain = new MockFilterChain(); + jwtFilter.doFilter(request, response, filterChain); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value()); + assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull(); + } + +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/jwt/JWTFilterUnitTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/jwt/JWTFilterUnitTest.java similarity index 96% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/jwt/JWTFilterUnitTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/jwt/JWTFilterUnitTest.java index 2be8e6809a..13633c901c 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/jwt/JWTFilterUnitTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/jwt/JWTFilterUnitTest.java @@ -1,12 +1,13 @@ -package com.baeldung.jhipster5.security.jwt; +package com.baeldung.jhipster6.security.jwt; + +import com.baeldung.jhipster6.security.AuthoritiesConstants; -import com.baeldung.jhipster5.security.AuthoritiesConstants; import io.github.jhipster.config.JHipsterProperties; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; import org.springframework.mock.web.MockFilterChain; import org.springframework.mock.web.MockHttpServletRequest; @@ -26,7 +27,7 @@ public class JWTFilterUnitTest { private JWTFilter jwtFilter; - @Before + @BeforeEach public void setup() { JHipsterProperties jHipsterProperties = new JHipsterProperties(); tokenProvider = new TokenProvider(jHipsterProperties); diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/jwt/TokenProvider2UnitTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/jwt/TokenProvider2UnitTest.java new file mode 100644 index 0000000000..311deb3fd7 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/jwt/TokenProvider2UnitTest.java @@ -0,0 +1,111 @@ +package com.baeldung.jhipster6.security.jwt; + +import com.baeldung.jhipster6.security.AuthoritiesConstants; + +import java.security.Key; +import java.util.*; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.test.util.ReflectionTestUtils; + +import io.github.jhipster.config.JHipsterProperties; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TokenProvider2UnitTest { + + private final long ONE_MINUTE = 60000; + private Key key; + private JHipsterProperties jHipsterProperties; + private TokenProvider tokenProvider; + + @Before + public void setup() { + jHipsterProperties = Mockito.mock(JHipsterProperties.class); + tokenProvider = new TokenProvider(jHipsterProperties); + key = Keys.hmacShaKeyFor(Decoders.BASE64 + .decode("fd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8")); + + ReflectionTestUtils.setField(tokenProvider, "key", key); + ReflectionTestUtils.setField(tokenProvider, "tokenValidityInMilliseconds", ONE_MINUTE); + } + + @Test + public void testReturnFalseWhenJWThasInvalidSignature() { + boolean isTokenValid = tokenProvider.validateToken(createTokenWithDifferentSignature()); + + assertThat(isTokenValid).isEqualTo(false); + } + + @Test + public void testReturnFalseWhenJWTisMalformed() { + Authentication authentication = createAuthentication(); + String token = tokenProvider.createToken(authentication, false); + String invalidToken = token.substring(1); + boolean isTokenValid = tokenProvider.validateToken(invalidToken); + + assertThat(isTokenValid).isEqualTo(false); + } + + @Test + public void testReturnFalseWhenJWTisExpired() { + ReflectionTestUtils.setField(tokenProvider, "tokenValidityInMilliseconds", -ONE_MINUTE); + + Authentication authentication = createAuthentication(); + String token = tokenProvider.createToken(authentication, false); + + boolean isTokenValid = tokenProvider.validateToken(token); + + assertThat(isTokenValid).isEqualTo(false); + } + + @Test + public void testReturnFalseWhenJWTisUnsupported() { + String unsupportedToken = createUnsupportedToken(); + + boolean isTokenValid = tokenProvider.validateToken(unsupportedToken); + + assertThat(isTokenValid).isEqualTo(false); + } + + @Test + public void testReturnFalseWhenJWTisInvalid() { + boolean isTokenValid = tokenProvider.validateToken(""); + + assertThat(isTokenValid).isEqualTo(false); + } + + private Authentication createAuthentication() { + Collection authorities = new ArrayList<>(); + authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS)); + return new UsernamePasswordAuthenticationToken("anonymous", "anonymous", authorities); + } + + private String createUnsupportedToken() { + return Jwts.builder() + .setPayload("payload") + .signWith(key, SignatureAlgorithm.HS512) + .compact(); + } + + private String createTokenWithDifferentSignature() { + Key otherKey = Keys.hmacShaKeyFor(Decoders.BASE64 + .decode("Xfd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8")); + + return Jwts.builder() + .setSubject("anonymous") + .signWith(otherKey, SignatureAlgorithm.HS512) + .setExpiration(new Date(new Date().getTime() + ONE_MINUTE)) + .compact(); + } +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/jwt/TokenProviderUnitTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/jwt/TokenProviderUnitTest.java similarity index 89% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/jwt/TokenProviderUnitTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/jwt/TokenProviderUnitTest.java index 18da2eb875..3d14352c79 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/jwt/TokenProviderUnitTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/security/jwt/TokenProviderUnitTest.java @@ -1,13 +1,12 @@ -package com.baeldung.jhipster5.security.jwt; +package com.baeldung.jhipster6.security.jwt; -import com.baeldung.jhipster5.security.AuthoritiesConstants; +import com.baeldung.jhipster6.security.AuthoritiesConstants; import java.security.Key; import java.util.*; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; @@ -24,15 +23,14 @@ import static org.assertj.core.api.Assertions.assertThat; public class TokenProviderUnitTest { - private final long ONE_MINUTE = 60000; + private static final long ONE_MINUTE = 60000; + private Key key; - private JHipsterProperties jHipsterProperties; private TokenProvider tokenProvider; - @Before + @BeforeEach public void setup() { - jHipsterProperties = Mockito.mock(JHipsterProperties.class); - tokenProvider = new TokenProvider(jHipsterProperties); + tokenProvider = new TokenProvider( new JHipsterProperties()); key = Keys.hmacShaKeyFor(Decoders.BASE64 .decode("fd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8")); diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/MailServiceIT.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/MailServiceIT.java new file mode 100644 index 0000000000..602ff4319d --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/MailServiceIT.java @@ -0,0 +1,189 @@ +package com.baeldung.jhipster6.service; + +import com.baeldung.jhipster6.config.Constants; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.domain.User; + +import io.github.jhipster.config.JHipsterProperties; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.MessageSource; +import org.springframework.mail.MailSendException; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.thymeleaf.spring5.SpringTemplateEngine; + +import javax.mail.Multipart; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import java.io.ByteArrayOutputStream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +/** + * Integration tests for {@link MailService}. + */ +@SpringBootTest(classes = BookstoreApp.class) +public class MailServiceIT { + + @Autowired + private JHipsterProperties jHipsterProperties; + + @Autowired + private MessageSource messageSource; + + @Autowired + private SpringTemplateEngine templateEngine; + + @Spy + private JavaMailSenderImpl javaMailSender; + + @Captor + private ArgumentCaptor messageCaptor; + + private MailService mailService; + + @BeforeEach + public void setup() { + MockitoAnnotations.initMocks(this); + doNothing().when(javaMailSender).send(any(MimeMessage.class)); + mailService = new MailService(jHipsterProperties, javaMailSender, messageSource, templateEngine); + } + + @Test + public void testSendEmail() throws Exception { + mailService.sendEmail("john.doe@example.com", "testSubject", "testContent", false, false); + verify(javaMailSender).send(messageCaptor.capture()); + MimeMessage message = messageCaptor.getValue(); + assertThat(message.getSubject()).isEqualTo("testSubject"); + assertThat(message.getAllRecipients()[0].toString()).isEqualTo("john.doe@example.com"); + assertThat(message.getFrom()[0].toString()).isEqualTo("test@localhost"); + assertThat(message.getContent()).isInstanceOf(String.class); + assertThat(message.getContent().toString()).isEqualTo("testContent"); + assertThat(message.getDataHandler().getContentType()).isEqualTo("text/plain; charset=UTF-8"); + } + + @Test + public void testSendHtmlEmail() throws Exception { + mailService.sendEmail("john.doe@example.com", "testSubject", "testContent", false, true); + verify(javaMailSender).send(messageCaptor.capture()); + MimeMessage message = messageCaptor.getValue(); + assertThat(message.getSubject()).isEqualTo("testSubject"); + assertThat(message.getAllRecipients()[0].toString()).isEqualTo("john.doe@example.com"); + assertThat(message.getFrom()[0].toString()).isEqualTo("test@localhost"); + assertThat(message.getContent()).isInstanceOf(String.class); + assertThat(message.getContent().toString()).isEqualTo("testContent"); + assertThat(message.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8"); + } + + @Test + public void testSendMultipartEmail() throws Exception { + mailService.sendEmail("john.doe@example.com", "testSubject", "testContent", true, false); + verify(javaMailSender).send(messageCaptor.capture()); + MimeMessage message = messageCaptor.getValue(); + MimeMultipart mp = (MimeMultipart) message.getContent(); + MimeBodyPart part = (MimeBodyPart) ((MimeMultipart) mp.getBodyPart(0).getContent()).getBodyPart(0); + ByteArrayOutputStream aos = new ByteArrayOutputStream(); + part.writeTo(aos); + assertThat(message.getSubject()).isEqualTo("testSubject"); + assertThat(message.getAllRecipients()[0].toString()).isEqualTo("john.doe@example.com"); + assertThat(message.getFrom()[0].toString()).isEqualTo("test@localhost"); + assertThat(message.getContent()).isInstanceOf(Multipart.class); + assertThat(aos.toString()).isEqualTo("\r\ntestContent"); + assertThat(part.getDataHandler().getContentType()).isEqualTo("text/plain; charset=UTF-8"); + } + + @Test + public void testSendMultipartHtmlEmail() throws Exception { + mailService.sendEmail("john.doe@example.com", "testSubject", "testContent", true, true); + verify(javaMailSender).send(messageCaptor.capture()); + MimeMessage message = messageCaptor.getValue(); + MimeMultipart mp = (MimeMultipart) message.getContent(); + MimeBodyPart part = (MimeBodyPart) ((MimeMultipart) mp.getBodyPart(0).getContent()).getBodyPart(0); + ByteArrayOutputStream aos = new ByteArrayOutputStream(); + part.writeTo(aos); + assertThat(message.getSubject()).isEqualTo("testSubject"); + assertThat(message.getAllRecipients()[0].toString()).isEqualTo("john.doe@example.com"); + assertThat(message.getFrom()[0].toString()).isEqualTo("test@localhost"); + assertThat(message.getContent()).isInstanceOf(Multipart.class); + assertThat(aos.toString()).isEqualTo("\r\ntestContent"); + assertThat(part.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8"); + } + + @Test + public void testSendEmailFromTemplate() throws Exception { + User user = new User(); + user.setLogin("john"); + user.setEmail("john.doe@example.com"); + user.setLangKey("en"); + mailService.sendEmailFromTemplate(user, "mail/testEmail", "email.test.title"); + verify(javaMailSender).send(messageCaptor.capture()); + MimeMessage message = messageCaptor.getValue(); + assertThat(message.getSubject()).isEqualTo("test title"); + assertThat(message.getAllRecipients()[0].toString()).isEqualTo(user.getEmail()); + assertThat(message.getFrom()[0].toString()).isEqualTo("test@localhost"); + assertThat(message.getContent().toString()).isEqualToNormalizingNewlines("test title, http://127.0.0.1:8080, john\n"); + assertThat(message.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8"); + } + + @Test + public void testSendActivationEmail() throws Exception { + User user = new User(); + user.setLangKey(Constants.DEFAULT_LANGUAGE); + user.setLogin("john"); + user.setEmail("john.doe@example.com"); + mailService.sendActivationEmail(user); + verify(javaMailSender).send(messageCaptor.capture()); + MimeMessage message = messageCaptor.getValue(); + assertThat(message.getAllRecipients()[0].toString()).isEqualTo(user.getEmail()); + assertThat(message.getFrom()[0].toString()).isEqualTo("test@localhost"); + assertThat(message.getContent().toString()).isNotEmpty(); + assertThat(message.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8"); + } + + @Test + public void testCreationEmail() throws Exception { + User user = new User(); + user.setLangKey(Constants.DEFAULT_LANGUAGE); + user.setLogin("john"); + user.setEmail("john.doe@example.com"); + mailService.sendCreationEmail(user); + verify(javaMailSender).send(messageCaptor.capture()); + MimeMessage message = messageCaptor.getValue(); + assertThat(message.getAllRecipients()[0].toString()).isEqualTo(user.getEmail()); + assertThat(message.getFrom()[0].toString()).isEqualTo("test@localhost"); + assertThat(message.getContent().toString()).isNotEmpty(); + assertThat(message.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8"); + } + + @Test + public void testSendPasswordResetMail() throws Exception { + User user = new User(); + user.setLangKey(Constants.DEFAULT_LANGUAGE); + user.setLogin("john"); + user.setEmail("john.doe@example.com"); + mailService.sendPasswordResetMail(user); + verify(javaMailSender).send(messageCaptor.capture()); + MimeMessage message = messageCaptor.getValue(); + assertThat(message.getAllRecipients()[0].toString()).isEqualTo(user.getEmail()); + assertThat(message.getFrom()[0].toString()).isEqualTo("test@localhost"); + assertThat(message.getContent().toString()).isNotEmpty(); + assertThat(message.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8"); + } + + @Test + public void testSendEmailWithException() throws Exception { + doThrow(MailSendException.class).when(javaMailSender).send(any(MimeMessage.class)); + mailService.sendEmail("john.doe@example.com", "testSubject", "testContent", false, false); + } + +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/service/MailServiceIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/MailServiceIntegrationTest.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/service/MailServiceIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/MailServiceIntegrationTest.java index 72592e1239..af04430ee7 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/service/MailServiceIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/MailServiceIntegrationTest.java @@ -1,8 +1,9 @@ -package com.baeldung.jhipster5.service; -import com.baeldung.jhipster5.config.Constants; +package com.baeldung.jhipster6.service; +import com.baeldung.jhipster6.config.Constants; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.domain.User; -import com.baeldung.jhipster5.BookstoreApp; -import com.baeldung.jhipster5.domain.User; import io.github.jhipster.config.JHipsterProperties; import org.junit.Before; import org.junit.Test; diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/UserServiceIT.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/UserServiceIT.java new file mode 100644 index 0000000000..5c624b166d --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/UserServiceIT.java @@ -0,0 +1,200 @@ +package com.baeldung.jhipster6.service; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.config.Constants; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.UserRepository; +import com.baeldung.jhipster6.service.dto.UserDTO; +import com.baeldung.jhipster6.service.util.RandomUtil; + +import org.apache.commons.lang3.RandomStringUtils; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.auditing.AuditingHandler; +import org.springframework.data.auditing.DateTimeProvider; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.transaction.annotation.Transactional; + +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.time.LocalDateTime; +import java.util.Optional; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +/** + * Integration tests for {@link UserService}. + */ +@SpringBootTest(classes = BookstoreApp.class) +@Transactional +public class UserServiceIT { + + private static final String DEFAULT_LOGIN = "johndoe"; + + private static final String DEFAULT_EMAIL = "johndoe@localhost"; + + private static final String DEFAULT_FIRSTNAME = "john"; + + private static final String DEFAULT_LASTNAME = "doe"; + + private static final String DEFAULT_IMAGEURL = "http://placehold.it/50x50"; + + private static final String DEFAULT_LANGKEY = "en"; + + @Autowired + private UserRepository userRepository; + + @Autowired + private UserService userService; + + @Autowired + private AuditingHandler auditingHandler; + + @Mock + private DateTimeProvider dateTimeProvider; + + private User user; + + @BeforeEach + public void init() { + user = new User(); + user.setLogin(DEFAULT_LOGIN); + user.setPassword(RandomStringUtils.random(60)); + user.setActivated(true); + user.setEmail(DEFAULT_EMAIL); + user.setFirstName(DEFAULT_FIRSTNAME); + user.setLastName(DEFAULT_LASTNAME); + user.setImageUrl(DEFAULT_IMAGEURL); + user.setLangKey(DEFAULT_LANGKEY); + + when(dateTimeProvider.getNow()).thenReturn(Optional.of(LocalDateTime.now())); + auditingHandler.setDateTimeProvider(dateTimeProvider); + } + + @Test + @Transactional + public void assertThatUserMustExistToResetPassword() { + userRepository.saveAndFlush(user); + Optional maybeUser = userService.requestPasswordReset("invalid.login@localhost"); + assertThat(maybeUser).isNotPresent(); + + maybeUser = userService.requestPasswordReset(user.getEmail()); + assertThat(maybeUser).isPresent(); + assertThat(maybeUser.orElse(null).getEmail()).isEqualTo(user.getEmail()); + assertThat(maybeUser.orElse(null).getResetDate()).isNotNull(); + assertThat(maybeUser.orElse(null).getResetKey()).isNotNull(); + } + + @Test + @Transactional + public void assertThatOnlyActivatedUserCanRequestPasswordReset() { + user.setActivated(false); + userRepository.saveAndFlush(user); + + Optional maybeUser = userService.requestPasswordReset(user.getLogin()); + assertThat(maybeUser).isNotPresent(); + userRepository.delete(user); + } + + @Test + @Transactional + public void assertThatResetKeyMustNotBeOlderThan24Hours() { + Instant daysAgo = Instant.now().minus(25, ChronoUnit.HOURS); + String resetKey = RandomUtil.generateResetKey(); + user.setActivated(true); + user.setResetDate(daysAgo); + user.setResetKey(resetKey); + userRepository.saveAndFlush(user); + + Optional maybeUser = userService.completePasswordReset("johndoe2", user.getResetKey()); + assertThat(maybeUser).isNotPresent(); + userRepository.delete(user); + } + + @Test + @Transactional + public void assertThatResetKeyMustBeValid() { + Instant daysAgo = Instant.now().minus(25, ChronoUnit.HOURS); + user.setActivated(true); + user.setResetDate(daysAgo); + user.setResetKey("1234"); + userRepository.saveAndFlush(user); + + Optional maybeUser = userService.completePasswordReset("johndoe2", user.getResetKey()); + assertThat(maybeUser).isNotPresent(); + userRepository.delete(user); + } + + @Test + @Transactional + public void assertThatUserCanResetPassword() { + String oldPassword = user.getPassword(); + Instant daysAgo = Instant.now().minus(2, ChronoUnit.HOURS); + String resetKey = RandomUtil.generateResetKey(); + user.setActivated(true); + user.setResetDate(daysAgo); + user.setResetKey(resetKey); + userRepository.saveAndFlush(user); + + Optional maybeUser = userService.completePasswordReset("johndoe2", user.getResetKey()); + assertThat(maybeUser).isPresent(); + assertThat(maybeUser.orElse(null).getResetDate()).isNull(); + assertThat(maybeUser.orElse(null).getResetKey()).isNull(); + assertThat(maybeUser.orElse(null).getPassword()).isNotEqualTo(oldPassword); + + userRepository.delete(user); + } + + @Test + @Transactional + public void testFindNotActivatedUsersByCreationDateBefore() { + Instant now = Instant.now(); + when(dateTimeProvider.getNow()).thenReturn(Optional.of(now.minus(4, ChronoUnit.DAYS))); + user.setActivated(false); + User dbUser = userRepository.saveAndFlush(user); + dbUser.setCreatedDate(now.minus(4, ChronoUnit.DAYS)); + userRepository.saveAndFlush(user); + List users = userRepository.findAllByActivatedIsFalseAndCreatedDateBefore(now.minus(3, ChronoUnit.DAYS)); + assertThat(users).isNotEmpty(); + userService.removeNotActivatedUsers(); + users = userRepository.findAllByActivatedIsFalseAndCreatedDateBefore(now.minus(3, ChronoUnit.DAYS)); + assertThat(users).isEmpty(); + } + + @Test + @Transactional + public void assertThatAnonymousUserIsNotGet() { + user.setLogin(Constants.ANONYMOUS_USER); + if (!userRepository.findOneByLogin(Constants.ANONYMOUS_USER).isPresent()) { + userRepository.saveAndFlush(user); + } + final PageRequest pageable = PageRequest.of(0, (int) userRepository.count()); + final Page allManagedUsers = userService.getAllManagedUsers(pageable); + assertThat(allManagedUsers.getContent().stream() + .noneMatch(user -> Constants.ANONYMOUS_USER.equals(user.getLogin()))) + .isTrue(); + } + + + @Test + @Transactional + public void testRemoveNotActivatedUsers() { + // custom "now" for audit to use as creation date + when(dateTimeProvider.getNow()).thenReturn(Optional.of(Instant.now().minus(30, ChronoUnit.DAYS))); + + user.setActivated(false); + userRepository.saveAndFlush(user); + + Assertions.assertThat(userRepository.findOneByLogin(DEFAULT_LOGIN)).isPresent(); + userService.removeNotActivatedUsers(); + Assertions.assertThat(userRepository.findOneByLogin(DEFAULT_LOGIN)).isNotPresent(); + } + +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/service/UserServiceIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/UserServiceIntegrationTest.java similarity index 92% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/service/UserServiceIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/UserServiceIntegrationTest.java index ca3608462d..b8e8a9e1aa 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/service/UserServiceIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/UserServiceIntegrationTest.java @@ -1,13 +1,14 @@ -package com.baeldung.jhipster5.service; +package com.baeldung.jhipster6.service; -import com.baeldung.jhipster5.BookstoreApp; -import com.baeldung.jhipster5.config.Constants; -import com.baeldung.jhipster5.domain.User; -import com.baeldung.jhipster5.repository.UserRepository; -import com.baeldung.jhipster5.service.dto.UserDTO; -import com.baeldung.jhipster5.service.util.RandomUtil; +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.config.Constants; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.UserRepository; +import com.baeldung.jhipster6.service.dto.UserDTO; +import com.baeldung.jhipster6.service.util.RandomUtil; import org.apache.commons.lang3.RandomStringUtils; +import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -184,9 +185,9 @@ public class UserServiceIntegrationTest { user.setActivated(false); userRepository.saveAndFlush(user); - assertThat(userRepository.findOneByLogin("johndoe")).isPresent(); + Assertions.assertThat(userRepository.findOneByLogin("johndoe")).isPresent(); userService.removeNotActivatedUsers(); - assertThat(userRepository.findOneByLogin("johndoe")).isNotPresent(); + Assertions.assertThat(userRepository.findOneByLogin("johndoe")).isNotPresent(); } } diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/mapper/UserMapperIT.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/mapper/UserMapperIT.java new file mode 100644 index 0000000000..cca2dc7d92 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/mapper/UserMapperIT.java @@ -0,0 +1,143 @@ +package com.baeldung.jhipster6.service.mapper; + + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.service.dto.UserDTO; + +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link UserMapper}. + */ +@SpringBootTest(classes = BookstoreApp.class) +public class UserMapperIT { + + private static final String DEFAULT_LOGIN = "johndoe"; + private static final Long DEFAULT_ID = 1L; + + @Autowired + private UserMapper userMapper; + + private User user; + private UserDTO userDto; + + @BeforeEach + public void init() { + user = new User(); + user.setLogin(DEFAULT_LOGIN); + user.setPassword(RandomStringUtils.random(60)); + user.setActivated(true); + user.setEmail("johndoe@localhost"); + user.setFirstName("john"); + user.setLastName("doe"); + user.setImageUrl("image_url"); + user.setLangKey("en"); + + userDto = new UserDTO(user); + } + + @Test + public void usersToUserDTOsShouldMapOnlyNonNullUsers() { + List users = new ArrayList<>(); + users.add(user); + users.add(null); + + List userDTOS = userMapper.usersToUserDTOs(users); + + assertThat(userDTOS).isNotEmpty(); + assertThat(userDTOS).size().isEqualTo(1); + } + + @Test + public void userDTOsToUsersShouldMapOnlyNonNullUsers() { + List usersDto = new ArrayList<>(); + usersDto.add(userDto); + usersDto.add(null); + + List users = userMapper.userDTOsToUsers(usersDto); + + assertThat(users).isNotEmpty(); + assertThat(users).size().isEqualTo(1); + } + + @Test + public void userDTOsToUsersWithAuthoritiesStringShouldMapToUsersWithAuthoritiesDomain() { + Set authoritiesAsString = new HashSet<>(); + authoritiesAsString.add("ADMIN"); + userDto.setAuthorities(authoritiesAsString); + + List usersDto = new ArrayList<>(); + usersDto.add(userDto); + + List users = userMapper.userDTOsToUsers(usersDto); + + assertThat(users).isNotEmpty(); + assertThat(users).size().isEqualTo(1); + assertThat(users.get(0).getAuthorities()).isNotNull(); + assertThat(users.get(0).getAuthorities()).isNotEmpty(); + assertThat(users.get(0).getAuthorities().iterator().next().getName()).isEqualTo("ADMIN"); + } + + @Test + public void userDTOsToUsersMapWithNullAuthoritiesStringShouldReturnUserWithEmptyAuthorities() { + userDto.setAuthorities(null); + + List usersDto = new ArrayList<>(); + usersDto.add(userDto); + + List users = userMapper.userDTOsToUsers(usersDto); + + assertThat(users).isNotEmpty(); + assertThat(users).size().isEqualTo(1); + assertThat(users.get(0).getAuthorities()).isNotNull(); + assertThat(users.get(0).getAuthorities()).isEmpty(); + } + + @Test + public void userDTOToUserMapWithAuthoritiesStringShouldReturnUserWithAuthorities() { + Set authoritiesAsString = new HashSet<>(); + authoritiesAsString.add("ADMIN"); + userDto.setAuthorities(authoritiesAsString); + + User user = userMapper.userDTOToUser(userDto); + + assertThat(user).isNotNull(); + assertThat(user.getAuthorities()).isNotNull(); + assertThat(user.getAuthorities()).isNotEmpty(); + assertThat(user.getAuthorities().iterator().next().getName()).isEqualTo("ADMIN"); + } + + @Test + public void userDTOToUserMapWithNullAuthoritiesStringShouldReturnUserWithEmptyAuthorities() { + userDto.setAuthorities(null); + + User user = userMapper.userDTOToUser(userDto); + + assertThat(user).isNotNull(); + assertThat(user.getAuthorities()).isNotNull(); + assertThat(user.getAuthorities()).isEmpty(); + } + + @Test + public void userDTOToUserMapWithNullUserShouldReturnNull() { + assertThat(userMapper.userDTOToUser(null)).isNull(); + } + + @Test + public void testUserFromId() { + assertThat(userMapper.userFromId(DEFAULT_ID).getId()).isEqualTo(DEFAULT_ID); + assertThat(userMapper.userFromId(null)).isNull(); + } +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/service/mapper/UserMapperIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/mapper/UserMapperIntegrationTest.java similarity index 96% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/service/mapper/UserMapperIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/mapper/UserMapperIntegrationTest.java index cd49135d63..d143caccf6 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/service/mapper/UserMapperIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/service/mapper/UserMapperIntegrationTest.java @@ -1,9 +1,10 @@ -package com.baeldung.jhipster5.service.mapper; +package com.baeldung.jhipster6.service.mapper; -import com.baeldung.jhipster5.BookstoreApp; -import com.baeldung.jhipster5.domain.User; -import com.baeldung.jhipster5.service.dto.UserDTO; +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.service.dto.UserDTO; + import org.apache.commons.lang3.RandomStringUtils; import org.junit.Before; import org.junit.Test; diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/AccountResourceIT.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/AccountResourceIT.java new file mode 100644 index 0000000000..4655526bb0 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/AccountResourceIT.java @@ -0,0 +1,815 @@ +package com.baeldung.jhipster6.web.rest; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.config.Constants; +import com.baeldung.jhipster6.domain.Authority; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.AuthorityRepository; +import com.baeldung.jhipster6.repository.UserRepository; +import com.baeldung.jhipster6.security.AuthoritiesConstants; +import com.baeldung.jhipster6.service.MailService; +import com.baeldung.jhipster6.service.UserService; +import com.baeldung.jhipster6.service.dto.PasswordChangeDTO; +import com.baeldung.jhipster6.service.dto.UserDTO; +import com.baeldung.jhipster6.web.rest.errors.ExceptionTranslator; +import com.baeldung.jhipster6.web.rest.vm.KeyAndPasswordVM; +import com.baeldung.jhipster6.web.rest.vm.ManagedUserVM; + +import org.apache.commons.lang3.RandomStringUtils; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.transaction.annotation.Transactional; + +import java.time.Instant; +import java.util.*; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Integration tests for the {@link AccountResource} REST controller. + */ +@SpringBootTest(classes = BookstoreApp.class) +public class AccountResourceIT { + + @Autowired + private UserRepository userRepository; + + @Autowired + private AuthorityRepository authorityRepository; + + @Autowired + private UserService userService; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Autowired + private HttpMessageConverter[] httpMessageConverters; + + @Autowired + private ExceptionTranslator exceptionTranslator; + + @Mock + private UserService mockUserService; + + @Mock + private MailService mockMailService; + + private MockMvc restMvc; + + private MockMvc restUserMockMvc; + + @BeforeEach + public void setup() { + MockitoAnnotations.initMocks(this); + doNothing().when(mockMailService).sendActivationEmail(any()); + AccountResource accountResource = + new AccountResource(userRepository, userService, mockMailService); + + AccountResource accountUserMockResource = + new AccountResource(userRepository, mockUserService, mockMailService); + this.restMvc = MockMvcBuilders.standaloneSetup(accountResource) + .setMessageConverters(httpMessageConverters) + .setControllerAdvice(exceptionTranslator) + .build(); + this.restUserMockMvc = MockMvcBuilders.standaloneSetup(accountUserMockResource) + .setControllerAdvice(exceptionTranslator) + .build(); + } + + @Test + public void testNonAuthenticatedUser() throws Exception { + restUserMockMvc.perform(get("/api/authenticate") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string("")); + } + + @Test + public void testAuthenticatedUser() throws Exception { + restUserMockMvc.perform(get("/api/authenticate") + .with(request -> { + request.setRemoteUser("test"); + return request; + }) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string("test")); + } + + @Test + public void testGetExistingAccount() throws Exception { + Set authorities = new HashSet<>(); + Authority authority = new Authority(); + authority.setName(AuthoritiesConstants.ADMIN); + authorities.add(authority); + + User user = new User(); + user.setLogin("test"); + user.setFirstName("john"); + user.setLastName("doe"); + user.setEmail("john.doe@jhipster.com"); + user.setImageUrl("http://placehold.it/50x50"); + user.setLangKey("en"); + user.setAuthorities(authorities); + when(mockUserService.getUserWithAuthorities()).thenReturn(Optional.of(user)); + + restUserMockMvc.perform(get("/api/account") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(jsonPath("$.login").value("test")) + .andExpect(jsonPath("$.firstName").value("john")) + .andExpect(jsonPath("$.lastName").value("doe")) + .andExpect(jsonPath("$.email").value("john.doe@jhipster.com")) + .andExpect(jsonPath("$.imageUrl").value("http://placehold.it/50x50")) + .andExpect(jsonPath("$.langKey").value("en")) + .andExpect(jsonPath("$.authorities").value(AuthoritiesConstants.ADMIN)); + } + + @Test + public void testGetUnknownAccount() throws Exception { + when(mockUserService.getUserWithAuthorities()).thenReturn(Optional.empty()); + + restUserMockMvc.perform(get("/api/account") + .accept(MediaType.APPLICATION_PROBLEM_JSON)) + .andExpect(status().isInternalServerError()); + } + + @Test + @Transactional + public void testRegisterValid() throws Exception { + ManagedUserVM validUser = new ManagedUserVM(); + validUser.setLogin("test-register-valid"); + validUser.setPassword("password"); + validUser.setFirstName("Alice"); + validUser.setLastName("Test"); + validUser.setEmail("test-register-valid@example.com"); + validUser.setImageUrl("http://placehold.it/50x50"); + validUser.setLangKey(Constants.DEFAULT_LANGUAGE); + validUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + assertThat(userRepository.findOneByLogin("test-register-valid").isPresent()).isFalse(); + + restMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(validUser))) + .andExpect(status().isCreated()); + + assertThat(userRepository.findOneByLogin("test-register-valid").isPresent()).isTrue(); + } + + @Test + @Transactional + public void testRegisterInvalidLogin() throws Exception { + ManagedUserVM invalidUser = new ManagedUserVM(); + invalidUser.setLogin("funky-log!n");// <-- invalid + invalidUser.setPassword("password"); + invalidUser.setFirstName("Funky"); + invalidUser.setLastName("One"); + invalidUser.setEmail("funky@example.com"); + invalidUser.setActivated(true); + invalidUser.setImageUrl("http://placehold.it/50x50"); + invalidUser.setLangKey(Constants.DEFAULT_LANGUAGE); + invalidUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + restUserMockMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(invalidUser))) + .andExpect(status().isBadRequest()); + + Optional user = userRepository.findOneByEmailIgnoreCase("funky@example.com"); + assertThat(user.isPresent()).isFalse(); + } + + @Test + @Transactional + public void testRegisterInvalidEmail() throws Exception { + ManagedUserVM invalidUser = new ManagedUserVM(); + invalidUser.setLogin("bob"); + invalidUser.setPassword("password"); + invalidUser.setFirstName("Bob"); + invalidUser.setLastName("Green"); + invalidUser.setEmail("invalid");// <-- invalid + invalidUser.setActivated(true); + invalidUser.setImageUrl("http://placehold.it/50x50"); + invalidUser.setLangKey(Constants.DEFAULT_LANGUAGE); + invalidUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + restUserMockMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(invalidUser))) + .andExpect(status().isBadRequest()); + + Optional user = userRepository.findOneByLogin("bob"); + assertThat(user.isPresent()).isFalse(); + } + + @Test + @Transactional + public void testRegisterInvalidPassword() throws Exception { + ManagedUserVM invalidUser = new ManagedUserVM(); + invalidUser.setLogin("bob"); + invalidUser.setPassword("123");// password with only 3 digits + invalidUser.setFirstName("Bob"); + invalidUser.setLastName("Green"); + invalidUser.setEmail("bob@example.com"); + invalidUser.setActivated(true); + invalidUser.setImageUrl("http://placehold.it/50x50"); + invalidUser.setLangKey(Constants.DEFAULT_LANGUAGE); + invalidUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + restUserMockMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(invalidUser))) + .andExpect(status().isBadRequest()); + + Optional user = userRepository.findOneByLogin("bob"); + assertThat(user.isPresent()).isFalse(); + } + + @Test + @Transactional + public void testRegisterNullPassword() throws Exception { + ManagedUserVM invalidUser = new ManagedUserVM(); + invalidUser.setLogin("bob"); + invalidUser.setPassword(null);// invalid null password + invalidUser.setFirstName("Bob"); + invalidUser.setLastName("Green"); + invalidUser.setEmail("bob@example.com"); + invalidUser.setActivated(true); + invalidUser.setImageUrl("http://placehold.it/50x50"); + invalidUser.setLangKey(Constants.DEFAULT_LANGUAGE); + invalidUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + restUserMockMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(invalidUser))) + .andExpect(status().isBadRequest()); + + Optional user = userRepository.findOneByLogin("bob"); + assertThat(user.isPresent()).isFalse(); + } + + @Test + @Transactional + public void testRegisterDuplicateLogin() throws Exception { + // First registration + ManagedUserVM firstUser = new ManagedUserVM(); + firstUser.setLogin("alice"); + firstUser.setPassword("password"); + firstUser.setFirstName("Alice"); + firstUser.setLastName("Something"); + firstUser.setEmail("alice@example.com"); + firstUser.setImageUrl("http://placehold.it/50x50"); + firstUser.setLangKey(Constants.DEFAULT_LANGUAGE); + firstUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + // Duplicate login, different email + ManagedUserVM secondUser = new ManagedUserVM(); + secondUser.setLogin(firstUser.getLogin()); + secondUser.setPassword(firstUser.getPassword()); + secondUser.setFirstName(firstUser.getFirstName()); + secondUser.setLastName(firstUser.getLastName()); + secondUser.setEmail("alice2@example.com"); + secondUser.setImageUrl(firstUser.getImageUrl()); + secondUser.setLangKey(firstUser.getLangKey()); + secondUser.setCreatedBy(firstUser.getCreatedBy()); + secondUser.setCreatedDate(firstUser.getCreatedDate()); + secondUser.setLastModifiedBy(firstUser.getLastModifiedBy()); + secondUser.setLastModifiedDate(firstUser.getLastModifiedDate()); + secondUser.setAuthorities(new HashSet<>(firstUser.getAuthorities())); + + // First user + restMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(firstUser))) + .andExpect(status().isCreated()); + + // Second (non activated) user + restMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(secondUser))) + .andExpect(status().isCreated()); + + Optional testUser = userRepository.findOneByEmailIgnoreCase("alice2@example.com"); + assertThat(testUser.isPresent()).isTrue(); + testUser.get().setActivated(true); + userRepository.save(testUser.get()); + + // Second (already activated) user + restMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(secondUser))) + .andExpect(status().is4xxClientError()); + } + + @Test + @Transactional + public void testRegisterDuplicateEmail() throws Exception { + // First user + ManagedUserVM firstUser = new ManagedUserVM(); + firstUser.setLogin("test-register-duplicate-email"); + firstUser.setPassword("password"); + firstUser.setFirstName("Alice"); + firstUser.setLastName("Test"); + firstUser.setEmail("test-register-duplicate-email@example.com"); + firstUser.setImageUrl("http://placehold.it/50x50"); + firstUser.setLangKey(Constants.DEFAULT_LANGUAGE); + firstUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + // Register first user + restMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(firstUser))) + .andExpect(status().isCreated()); + + Optional testUser1 = userRepository.findOneByLogin("test-register-duplicate-email"); + assertThat(testUser1.isPresent()).isTrue(); + + // Duplicate email, different login + ManagedUserVM secondUser = new ManagedUserVM(); + secondUser.setLogin("test-register-duplicate-email-2"); + secondUser.setPassword(firstUser.getPassword()); + secondUser.setFirstName(firstUser.getFirstName()); + secondUser.setLastName(firstUser.getLastName()); + secondUser.setEmail(firstUser.getEmail()); + secondUser.setImageUrl(firstUser.getImageUrl()); + secondUser.setLangKey(firstUser.getLangKey()); + secondUser.setAuthorities(new HashSet<>(firstUser.getAuthorities())); + + // Register second (non activated) user + restMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(secondUser))) + .andExpect(status().isCreated()); + + Optional testUser2 = userRepository.findOneByLogin("test-register-duplicate-email"); + assertThat(testUser2.isPresent()).isFalse(); + + Optional testUser3 = userRepository.findOneByLogin("test-register-duplicate-email-2"); + assertThat(testUser3.isPresent()).isTrue(); + + // Duplicate email - with uppercase email address + ManagedUserVM userWithUpperCaseEmail = new ManagedUserVM(); + userWithUpperCaseEmail.setId(firstUser.getId()); + userWithUpperCaseEmail.setLogin("test-register-duplicate-email-3"); + userWithUpperCaseEmail.setPassword(firstUser.getPassword()); + userWithUpperCaseEmail.setFirstName(firstUser.getFirstName()); + userWithUpperCaseEmail.setLastName(firstUser.getLastName()); + userWithUpperCaseEmail.setEmail("TEST-register-duplicate-email@example.com"); + userWithUpperCaseEmail.setImageUrl(firstUser.getImageUrl()); + userWithUpperCaseEmail.setLangKey(firstUser.getLangKey()); + userWithUpperCaseEmail.setAuthorities(new HashSet<>(firstUser.getAuthorities())); + + // Register third (not activated) user + restMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(userWithUpperCaseEmail))) + .andExpect(status().isCreated()); + + Optional testUser4 = userRepository.findOneByLogin("test-register-duplicate-email-3"); + assertThat(testUser4.isPresent()).isTrue(); + assertThat(testUser4.get().getEmail()).isEqualTo("test-register-duplicate-email@example.com"); + + testUser4.get().setActivated(true); + userService.updateUser((new UserDTO(testUser4.get()))); + + // Register 4th (already activated) user + restMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(secondUser))) + .andExpect(status().is4xxClientError()); + } + + @Test + @Transactional + public void testRegisterAdminIsIgnored() throws Exception { + ManagedUserVM validUser = new ManagedUserVM(); + validUser.setLogin("badguy"); + validUser.setPassword("password"); + validUser.setFirstName("Bad"); + validUser.setLastName("Guy"); + validUser.setEmail("badguy@example.com"); + validUser.setActivated(true); + validUser.setImageUrl("http://placehold.it/50x50"); + validUser.setLangKey(Constants.DEFAULT_LANGUAGE); + validUser.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN)); + + restMvc.perform( + post("/api/register") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(validUser))) + .andExpect(status().isCreated()); + + Optional userDup = userRepository.findOneByLogin("badguy"); + assertThat(userDup.isPresent()).isTrue(); + assertThat(userDup.get().getAuthorities()).hasSize(1) + .containsExactly(authorityRepository.findById(AuthoritiesConstants.USER).get()); + } + + @Test + @Transactional + public void testActivateAccount() throws Exception { + final String activationKey = "some activation key"; + User user = new User(); + user.setLogin("activate-account"); + user.setEmail("activate-account@example.com"); + user.setPassword(RandomStringUtils.random(60)); + user.setActivated(false); + user.setActivationKey(activationKey); + + userRepository.saveAndFlush(user); + + restMvc.perform(get("/api/activate?key={activationKey}", activationKey)) + .andExpect(status().isOk()); + + user = userRepository.findOneByLogin(user.getLogin()).orElse(null); + assertThat(user.getActivated()).isTrue(); + } + + @Test + @Transactional + public void testActivateAccountWithWrongKey() throws Exception { + restMvc.perform(get("/api/activate?key=wrongActivationKey")) + .andExpect(status().isInternalServerError()); + } + + @Test + @Transactional + @WithMockUser("save-account") + public void testSaveAccount() throws Exception { + User user = new User(); + user.setLogin("save-account"); + user.setEmail("save-account@example.com"); + user.setPassword(RandomStringUtils.random(60)); + user.setActivated(true); + + userRepository.saveAndFlush(user); + + UserDTO userDTO = new UserDTO(); + userDTO.setLogin("not-used"); + userDTO.setFirstName("firstname"); + userDTO.setLastName("lastname"); + userDTO.setEmail("save-account@example.com"); + userDTO.setActivated(false); + userDTO.setImageUrl("http://placehold.it/50x50"); + userDTO.setLangKey(Constants.DEFAULT_LANGUAGE); + userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN)); + + restMvc.perform( + post("/api/account") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(userDTO))) + .andExpect(status().isOk()); + + User updatedUser = userRepository.findOneByLogin(user.getLogin()).orElse(null); + assertThat(updatedUser.getFirstName()).isEqualTo(userDTO.getFirstName()); + assertThat(updatedUser.getLastName()).isEqualTo(userDTO.getLastName()); + assertThat(updatedUser.getEmail()).isEqualTo(userDTO.getEmail()); + assertThat(updatedUser.getLangKey()).isEqualTo(userDTO.getLangKey()); + assertThat(updatedUser.getPassword()).isEqualTo(user.getPassword()); + assertThat(updatedUser.getImageUrl()).isEqualTo(userDTO.getImageUrl()); + assertThat(updatedUser.getActivated()).isEqualTo(true); + assertThat(updatedUser.getAuthorities()).isEmpty(); + } + + @Test + @Transactional + @WithMockUser("save-invalid-email") + public void testSaveInvalidEmail() throws Exception { + User user = new User(); + user.setLogin("save-invalid-email"); + user.setEmail("save-invalid-email@example.com"); + user.setPassword(RandomStringUtils.random(60)); + user.setActivated(true); + + userRepository.saveAndFlush(user); + + UserDTO userDTO = new UserDTO(); + userDTO.setLogin("not-used"); + userDTO.setFirstName("firstname"); + userDTO.setLastName("lastname"); + userDTO.setEmail("invalid email"); + userDTO.setActivated(false); + userDTO.setImageUrl("http://placehold.it/50x50"); + userDTO.setLangKey(Constants.DEFAULT_LANGUAGE); + userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN)); + + restMvc.perform( + post("/api/account") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(userDTO))) + .andExpect(status().isBadRequest()); + + Assertions.assertThat(userRepository.findOneByEmailIgnoreCase("invalid email")).isNotPresent(); + } + + @Test + @Transactional + @WithMockUser("save-existing-email") + public void testSaveExistingEmail() throws Exception { + User user = new User(); + user.setLogin("save-existing-email"); + user.setEmail("save-existing-email@example.com"); + user.setPassword(RandomStringUtils.random(60)); + user.setActivated(true); + + userRepository.saveAndFlush(user); + + User anotherUser = new User(); + anotherUser.setLogin("save-existing-email2"); + anotherUser.setEmail("save-existing-email2@example.com"); + anotherUser.setPassword(RandomStringUtils.random(60)); + anotherUser.setActivated(true); + + userRepository.saveAndFlush(anotherUser); + + UserDTO userDTO = new UserDTO(); + userDTO.setLogin("not-used"); + userDTO.setFirstName("firstname"); + userDTO.setLastName("lastname"); + userDTO.setEmail("save-existing-email2@example.com"); + userDTO.setActivated(false); + userDTO.setImageUrl("http://placehold.it/50x50"); + userDTO.setLangKey(Constants.DEFAULT_LANGUAGE); + userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN)); + + restMvc.perform( + post("/api/account") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(userDTO))) + .andExpect(status().isBadRequest()); + + User updatedUser = userRepository.findOneByLogin("save-existing-email").orElse(null); + assertThat(updatedUser.getEmail()).isEqualTo("save-existing-email@example.com"); + } + + @Test + @Transactional + @WithMockUser("save-existing-email-and-login") + public void testSaveExistingEmailAndLogin() throws Exception { + User user = new User(); + user.setLogin("save-existing-email-and-login"); + user.setEmail("save-existing-email-and-login@example.com"); + user.setPassword(RandomStringUtils.random(60)); + user.setActivated(true); + + userRepository.saveAndFlush(user); + + UserDTO userDTO = new UserDTO(); + userDTO.setLogin("not-used"); + userDTO.setFirstName("firstname"); + userDTO.setLastName("lastname"); + userDTO.setEmail("save-existing-email-and-login@example.com"); + userDTO.setActivated(false); + userDTO.setImageUrl("http://placehold.it/50x50"); + userDTO.setLangKey(Constants.DEFAULT_LANGUAGE); + userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN)); + + restMvc.perform( + post("/api/account") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(userDTO))) + .andExpect(status().isOk()); + + User updatedUser = userRepository.findOneByLogin("save-existing-email-and-login").orElse(null); + assertThat(updatedUser.getEmail()).isEqualTo("save-existing-email-and-login@example.com"); + } + + @Test + @Transactional + @WithMockUser("change-password-wrong-existing-password") + public void testChangePasswordWrongExistingPassword() throws Exception { + User user = new User(); + String currentPassword = RandomStringUtils.random(60); + user.setPassword(passwordEncoder.encode(currentPassword)); + user.setLogin("change-password-wrong-existing-password"); + user.setEmail("change-password-wrong-existing-password@example.com"); + userRepository.saveAndFlush(user); + + restMvc.perform(post("/api/account/change-password") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(new PasswordChangeDTO("1"+currentPassword, "new password")))) + .andExpect(status().isBadRequest()); + + User updatedUser = userRepository.findOneByLogin("change-password-wrong-existing-password").orElse(null); + assertThat(passwordEncoder.matches("new password", updatedUser.getPassword())).isFalse(); + assertThat(passwordEncoder.matches(currentPassword, updatedUser.getPassword())).isTrue(); + } + + @Test + @Transactional + @WithMockUser("change-password") + public void testChangePassword() throws Exception { + User user = new User(); + String currentPassword = RandomStringUtils.random(60); + user.setPassword(passwordEncoder.encode(currentPassword)); + user.setLogin("change-password"); + user.setEmail("change-password@example.com"); + userRepository.saveAndFlush(user); + + restMvc.perform(post("/api/account/change-password") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(new PasswordChangeDTO(currentPassword, "new password")))) + .andExpect(status().isOk()); + + User updatedUser = userRepository.findOneByLogin("change-password").orElse(null); + assertThat(passwordEncoder.matches("new password", updatedUser.getPassword())).isTrue(); + } + + @Test + @Transactional + @WithMockUser("change-password-too-small") + public void testChangePasswordTooSmall() throws Exception { + User user = new User(); + String currentPassword = RandomStringUtils.random(60); + user.setPassword(passwordEncoder.encode(currentPassword)); + user.setLogin("change-password-too-small"); + user.setEmail("change-password-too-small@example.com"); + userRepository.saveAndFlush(user); + + String newPassword = RandomStringUtils.random(ManagedUserVM.PASSWORD_MIN_LENGTH - 1); + + restMvc.perform(post("/api/account/change-password") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(new PasswordChangeDTO(currentPassword, newPassword)))) + .andExpect(status().isBadRequest()); + + User updatedUser = userRepository.findOneByLogin("change-password-too-small").orElse(null); + assertThat(updatedUser.getPassword()).isEqualTo(user.getPassword()); + } + + @Test + @Transactional + @WithMockUser("change-password-too-long") + public void testChangePasswordTooLong() throws Exception { + User user = new User(); + String currentPassword = RandomStringUtils.random(60); + user.setPassword(passwordEncoder.encode(currentPassword)); + user.setLogin("change-password-too-long"); + user.setEmail("change-password-too-long@example.com"); + userRepository.saveAndFlush(user); + + String newPassword = RandomStringUtils.random(ManagedUserVM.PASSWORD_MAX_LENGTH + 1); + + restMvc.perform(post("/api/account/change-password") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(new PasswordChangeDTO(currentPassword, newPassword)))) + .andExpect(status().isBadRequest()); + + User updatedUser = userRepository.findOneByLogin("change-password-too-long").orElse(null); + assertThat(updatedUser.getPassword()).isEqualTo(user.getPassword()); + } + + @Test + @Transactional + @WithMockUser("change-password-empty") + public void testChangePasswordEmpty() throws Exception { + User user = new User(); + String currentPassword = RandomStringUtils.random(60); + user.setPassword(passwordEncoder.encode(currentPassword)); + user.setLogin("change-password-empty"); + user.setEmail("change-password-empty@example.com"); + userRepository.saveAndFlush(user); + + restMvc.perform(post("/api/account/change-password") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(new PasswordChangeDTO(currentPassword, "")))) + .andExpect(status().isBadRequest()); + + User updatedUser = userRepository.findOneByLogin("change-password-empty").orElse(null); + assertThat(updatedUser.getPassword()).isEqualTo(user.getPassword()); + } + + @Test + @Transactional + public void testRequestPasswordReset() throws Exception { + User user = new User(); + user.setPassword(RandomStringUtils.random(60)); + user.setActivated(true); + user.setLogin("password-reset"); + user.setEmail("password-reset@example.com"); + userRepository.saveAndFlush(user); + + restMvc.perform(post("/api/account/reset-password/init") + .content("password-reset@example.com")) + .andExpect(status().isOk()); + } + + @Test + @Transactional + public void testRequestPasswordResetUpperCaseEmail() throws Exception { + User user = new User(); + user.setPassword(RandomStringUtils.random(60)); + user.setActivated(true); + user.setLogin("password-reset"); + user.setEmail("password-reset@example.com"); + userRepository.saveAndFlush(user); + + restMvc.perform(post("/api/account/reset-password/init") + .content("password-reset@EXAMPLE.COM")) + .andExpect(status().isOk()); + } + + @Test + public void testRequestPasswordResetWrongEmail() throws Exception { + restMvc.perform( + post("/api/account/reset-password/init") + .content("password-reset-wrong-email@example.com")) + .andExpect(status().isBadRequest()); + } + + @Test + @Transactional + public void testFinishPasswordReset() throws Exception { + User user = new User(); + user.setPassword(RandomStringUtils.random(60)); + user.setLogin("finish-password-reset"); + user.setEmail("finish-password-reset@example.com"); + user.setResetDate(Instant.now().plusSeconds(60)); + user.setResetKey("reset key"); + userRepository.saveAndFlush(user); + + KeyAndPasswordVM keyAndPassword = new KeyAndPasswordVM(); + keyAndPassword.setKey(user.getResetKey()); + keyAndPassword.setNewPassword("new password"); + + restMvc.perform( + post("/api/account/reset-password/finish") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(keyAndPassword))) + .andExpect(status().isOk()); + + User updatedUser = userRepository.findOneByLogin(user.getLogin()).orElse(null); + assertThat(passwordEncoder.matches(keyAndPassword.getNewPassword(), updatedUser.getPassword())).isTrue(); + } + + @Test + @Transactional + public void testFinishPasswordResetTooSmall() throws Exception { + User user = new User(); + user.setPassword(RandomStringUtils.random(60)); + user.setLogin("finish-password-reset-too-small"); + user.setEmail("finish-password-reset-too-small@example.com"); + user.setResetDate(Instant.now().plusSeconds(60)); + user.setResetKey("reset key too small"); + userRepository.saveAndFlush(user); + + KeyAndPasswordVM keyAndPassword = new KeyAndPasswordVM(); + keyAndPassword.setKey(user.getResetKey()); + keyAndPassword.setNewPassword("foo"); + + restMvc.perform( + post("/api/account/reset-password/finish") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(keyAndPassword))) + .andExpect(status().isBadRequest()); + + User updatedUser = userRepository.findOneByLogin(user.getLogin()).orElse(null); + assertThat(passwordEncoder.matches(keyAndPassword.getNewPassword(), updatedUser.getPassword())).isFalse(); + } + + + @Test + @Transactional + public void testFinishPasswordResetWrongKey() throws Exception { + KeyAndPasswordVM keyAndPassword = new KeyAndPasswordVM(); + keyAndPassword.setKey("wrong reset key"); + keyAndPassword.setNewPassword("new password"); + + restMvc.perform( + post("/api/account/reset-password/finish") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(keyAndPassword))) + .andExpect(status().isInternalServerError()); + } +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/AccountResourceIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/AccountResourceIntegrationTest.java similarity index 97% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/AccountResourceIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/AccountResourceIntegrationTest.java index f591b7ecbf..adc7deec18 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/AccountResourceIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/AccountResourceIntegrationTest.java @@ -1,21 +1,23 @@ -package com.baeldung.jhipster5.web.rest; +package com.baeldung.jhipster6.web.rest; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.config.Constants; +import com.baeldung.jhipster6.domain.Authority; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.AuthorityRepository; +import com.baeldung.jhipster6.repository.UserRepository; +import com.baeldung.jhipster6.security.AuthoritiesConstants; +import com.baeldung.jhipster6.service.MailService; +import com.baeldung.jhipster6.service.UserService; +import com.baeldung.jhipster6.service.dto.PasswordChangeDTO; +import com.baeldung.jhipster6.service.dto.UserDTO; +import com.baeldung.jhipster6.web.rest.errors.ExceptionTranslator; +import com.baeldung.jhipster6.web.rest.vm.KeyAndPasswordVM; +import com.baeldung.jhipster6.web.rest.vm.ManagedUserVM; -import com.baeldung.jhipster5.BookstoreApp; -import com.baeldung.jhipster5.config.Constants; -import com.baeldung.jhipster5.domain.Authority; -import com.baeldung.jhipster5.domain.User; -import com.baeldung.jhipster5.repository.AuthorityRepository; -import com.baeldung.jhipster5.repository.UserRepository; -import com.baeldung.jhipster5.security.AuthoritiesConstants; -import com.baeldung.jhipster5.service.MailService; -import com.baeldung.jhipster5.service.UserService; -import com.baeldung.jhipster5.service.dto.PasswordChangeDTO; -import com.baeldung.jhipster5.service.dto.UserDTO; -import com.baeldung.jhipster5.web.rest.errors.ExceptionTranslator; -import com.baeldung.jhipster5.web.rest.vm.KeyAndPasswordVM; -import com.baeldung.jhipster5.web.rest.vm.ManagedUserVM; import org.apache.commons.lang3.RandomStringUtils; +import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -533,7 +535,7 @@ public class AccountResourceIntegrationTest { .content(TestUtil.convertObjectToJsonBytes(userDTO))) .andExpect(status().isBadRequest()); - assertThat(userRepository.findOneByEmailIgnoreCase("invalid email")).isNotPresent(); + Assertions.assertThat(userRepository.findOneByEmailIgnoreCase("invalid email")).isNotPresent(); } @Test diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/AuditResourceIT.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/AuditResourceIT.java new file mode 100644 index 0000000000..d9c82f48a5 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/AuditResourceIT.java @@ -0,0 +1,161 @@ +package com.baeldung.jhipster6.web.rest; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.config.audit.AuditEventConverter; +import com.baeldung.jhipster6.domain.PersistentAuditEvent; +import com.baeldung.jhipster6.repository.PersistenceAuditEventRepository; + +import com.baeldung.jhipster6.service.AuditEventService; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.web.PageableHandlerMethodArgumentResolver; +import org.springframework.format.support.FormattingConversionService; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.transaction.annotation.Transactional; + +import java.time.Instant; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Integration tests for the {@link AuditResource} REST controller. + */ +@SpringBootTest(classes = BookstoreApp.class) +@Transactional +public class AuditResourceIT { + + private static final String SAMPLE_PRINCIPAL = "SAMPLE_PRINCIPAL"; + private static final String SAMPLE_TYPE = "SAMPLE_TYPE"; + private static final Instant SAMPLE_TIMESTAMP = Instant.parse("2015-08-04T10:11:30Z"); + private static final long SECONDS_PER_DAY = 60 * 60 * 24; + + @Autowired + private PersistenceAuditEventRepository auditEventRepository; + + @Autowired + private AuditEventConverter auditEventConverter; + + @Autowired + private MappingJackson2HttpMessageConverter jacksonMessageConverter; + + @Autowired + @Qualifier("mvcConversionService") + private FormattingConversionService formattingConversionService; + + @Autowired + private PageableHandlerMethodArgumentResolver pageableArgumentResolver; + + private PersistentAuditEvent auditEvent; + + private MockMvc restAuditMockMvc; + + @BeforeEach + public void setup() { + MockitoAnnotations.initMocks(this); + AuditEventService auditEventService = + new AuditEventService(auditEventRepository, auditEventConverter); + AuditResource auditResource = new AuditResource(auditEventService); + this.restAuditMockMvc = MockMvcBuilders.standaloneSetup(auditResource) + .setCustomArgumentResolvers(pageableArgumentResolver) + .setConversionService(formattingConversionService) + .setMessageConverters(jacksonMessageConverter).build(); + } + + @BeforeEach + public void initTest() { + auditEventRepository.deleteAll(); + auditEvent = new PersistentAuditEvent(); + auditEvent.setAuditEventType(SAMPLE_TYPE); + auditEvent.setPrincipal(SAMPLE_PRINCIPAL); + auditEvent.setAuditEventDate(SAMPLE_TIMESTAMP); + } + + @Test + public void getAllAudits() throws Exception { + // Initialize the database + auditEventRepository.save(auditEvent); + + // Get all the audits + restAuditMockMvc.perform(get("/management/audits")) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(jsonPath("$.[*].principal").value(hasItem(SAMPLE_PRINCIPAL))); + } + + @Test + public void getAudit() throws Exception { + // Initialize the database + auditEventRepository.save(auditEvent); + + // Get the audit + restAuditMockMvc.perform(get("/management/audits/{id}", auditEvent.getId())) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(jsonPath("$.principal").value(SAMPLE_PRINCIPAL)); + } + + @Test + public void getAuditsByDate() throws Exception { + // Initialize the database + auditEventRepository.save(auditEvent); + + // Generate dates for selecting audits by date, making sure the period will contain the audit + String fromDate = SAMPLE_TIMESTAMP.minusSeconds(SECONDS_PER_DAY).toString().substring(0, 10); + String toDate = SAMPLE_TIMESTAMP.plusSeconds(SECONDS_PER_DAY).toString().substring(0, 10); + + // Get the audit + restAuditMockMvc.perform(get("/management/audits?fromDate="+fromDate+"&toDate="+toDate)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(jsonPath("$.[*].principal").value(hasItem(SAMPLE_PRINCIPAL))); + } + + @Test + public void getNonExistingAuditsByDate() throws Exception { + // Initialize the database + auditEventRepository.save(auditEvent); + + // Generate dates for selecting audits by date, making sure the period will not contain the sample audit + String fromDate = SAMPLE_TIMESTAMP.minusSeconds(2*SECONDS_PER_DAY).toString().substring(0, 10); + String toDate = SAMPLE_TIMESTAMP.minusSeconds(SECONDS_PER_DAY).toString().substring(0, 10); + + // Query audits but expect no results + restAuditMockMvc.perform(get("/management/audits?fromDate=" + fromDate + "&toDate=" + toDate)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(header().string("X-Total-Count", "0")); + } + + @Test + public void getNonExistingAudit() throws Exception { + // Get the audit + restAuditMockMvc.perform(get("/management/audits/{id}", Long.MAX_VALUE)) + .andExpect(status().isNotFound()); + } + + @Test + @Transactional + public void testPersistentAuditEventEquals() throws Exception { + TestUtil.equalsVerifier(PersistentAuditEvent.class); + PersistentAuditEvent auditEvent1 = new PersistentAuditEvent(); + auditEvent1.setId(1L); + PersistentAuditEvent auditEvent2 = new PersistentAuditEvent(); + auditEvent2.setId(auditEvent1.getId()); + assertThat(auditEvent1).isEqualTo(auditEvent2); + auditEvent2.setId(2L); + assertThat(auditEvent1).isNotEqualTo(auditEvent2); + auditEvent1.setId(null); + assertThat(auditEvent1).isNotEqualTo(auditEvent2); + } +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/AuditResourceIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/AuditResourceIntegrationTest.java similarity index 95% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/AuditResourceIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/AuditResourceIntegrationTest.java index 05d8f9d503..d7bb995e1c 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/AuditResourceIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/AuditResourceIntegrationTest.java @@ -1,10 +1,11 @@ -package com.baeldung.jhipster5.web.rest; +package com.baeldung.jhipster6.web.rest; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.config.audit.AuditEventConverter; +import com.baeldung.jhipster6.domain.PersistentAuditEvent; +import com.baeldung.jhipster6.repository.PersistenceAuditEventRepository; +import com.baeldung.jhipster6.service.AuditEventService; -import com.baeldung.jhipster5.BookstoreApp; -import com.baeldung.jhipster5.config.audit.AuditEventConverter; -import com.baeldung.jhipster5.domain.PersistentAuditEvent; -import com.baeldung.jhipster5.repository.PersistenceAuditEventRepository; -import com.baeldung.jhipster5.service.AuditEventService; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/BookResourceIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/BookResourceIntegrationTest.java similarity index 96% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/BookResourceIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/BookResourceIntegrationTest.java index 4f5cb25cdb..429d937f26 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/BookResourceIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/BookResourceIntegrationTest.java @@ -1,13 +1,13 @@ -package com.baeldung.jhipster5.web.rest; +package com.baeldung.jhipster6.web.rest; -import com.baeldung.jhipster5.BookstoreApp; +import com.baeldung.jhipster6.BookstoreApp; -import com.baeldung.jhipster5.domain.Book; -import com.baeldung.jhipster5.repository.BookRepository; -import com.baeldung.jhipster5.service.BookService; -import com.baeldung.jhipster5.service.dto.BookDTO; -import com.baeldung.jhipster5.service.mapper.BookMapper; -import com.baeldung.jhipster5.web.rest.errors.ExceptionTranslator; +import com.baeldung.jhipster6.domain.Book; +import com.baeldung.jhipster6.repository.BookRepository; +import com.baeldung.jhipster6.service.BookService; +import com.baeldung.jhipster6.service.dto.BookDTO; +import com.baeldung.jhipster6.service.mapper.BookMapper; +import com.baeldung.jhipster6.web.rest.errors.ExceptionTranslator; import org.junit.Before; import org.junit.Test; @@ -29,8 +29,6 @@ import java.time.LocalDate; import java.time.ZoneId; import java.util.List; - -import static com.baeldung.jhipster5.web.rest.TestUtil.createFormattingConversionService; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.hasItem; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -95,7 +93,7 @@ public class BookResourceIntegrationTest { this.restBookMockMvc = MockMvcBuilders.standaloneSetup(bookResource) .setCustomArgumentResolvers(pageableArgumentResolver) .setControllerAdvice(exceptionTranslator) - .setConversionService(createFormattingConversionService()) + .setConversionService(TestUtil.createFormattingConversionService()) .setMessageConverters(jacksonMessageConverter) .setValidator(validator).build(); } @@ -276,7 +274,7 @@ public class BookResourceIntegrationTest { .andExpect(jsonPath("$.[*].quantity").value(hasItem(DEFAULT_QUANTITY))) .andExpect(jsonPath("$.[*].price").value(hasItem(DEFAULT_PRICE.doubleValue()))); } - + @Test @Transactional public void getBook() throws Exception { diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/ClientForwardControllerIT.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/ClientForwardControllerIT.java new file mode 100644 index 0000000000..9dcc2e6055 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/ClientForwardControllerIT.java @@ -0,0 +1,67 @@ +package com.baeldung.jhipster6.web.rest; + +import com.baeldung.jhipster6.BookstoreApp; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * Integration tests for the {@link ClientForwardController} REST controller. + */ +@SpringBootTest(classes = BookstoreApp.class) +public class ClientForwardControllerIT { + + private MockMvc restMockMvc; + + @BeforeEach + public void setup() { + ClientForwardController clientForwardController = new ClientForwardController(); + this.restMockMvc = MockMvcBuilders + .standaloneSetup(clientForwardController, new TestController()) + .build(); + } + + @Test + public void getBackendEndpoint() throws Exception { + restMockMvc.perform(get("/test")) + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN_VALUE)) + .andExpect(content().string("test")); + } + + @Test + public void getClientEndpoint() throws Exception { + ResultActions perform = restMockMvc.perform(get("/non-existant-mapping")); + perform + .andExpect(status().isOk()) + .andExpect(forwardedUrl("/")); + } + + @Test + public void getNestedClientEndpoint() throws Exception { + restMockMvc.perform(get("/admin/user-management")) + .andExpect(status().isOk()) + .andExpect(forwardedUrl("/")); + } + + @RestController + public static class TestController { + + @RequestMapping(value = "/test") + public String test() { + return "test"; + } + } +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/LogsResourceIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/LogsResourceIntegrationTest.java similarity index 94% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/LogsResourceIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/LogsResourceIntegrationTest.java index b045f52f87..a9aa9b27c1 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/LogsResourceIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/LogsResourceIntegrationTest.java @@ -1,7 +1,8 @@ -package com.baeldung.jhipster5.web.rest; +package com.baeldung.jhipster6.web.rest; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.web.rest.vm.LoggerVM; -import com.baeldung.jhipster5.BookstoreApp; -import com.baeldung.jhipster5.web.rest.vm.LoggerVM; import ch.qos.logback.classic.AsyncAppender; import ch.qos.logback.classic.LoggerContext; import org.junit.Before; diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/TestUtil.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/TestUtil.java similarity index 99% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/TestUtil.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/TestUtil.java index 403bb9c9b0..50c6cc24a6 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/TestUtil.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/TestUtil.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest; +package com.baeldung.jhipster6.web.rest; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/UserJWTControllerIT.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/UserJWTControllerIT.java new file mode 100644 index 0000000000..3ad59b3166 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/UserJWTControllerIT.java @@ -0,0 +1,120 @@ +package com.baeldung.jhipster6.web.rest; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.UserRepository; +import com.baeldung.jhipster6.security.jwt.TokenProvider; +import com.baeldung.jhipster6.web.rest.errors.ExceptionTranslator; +import com.baeldung.jhipster6.web.rest.vm.LoginVM; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.transaction.annotation.Transactional; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; + +/** + * Integration tests for the {@link UserJWTController} REST controller. + */ +@SpringBootTest(classes = BookstoreApp.class) +public class UserJWTControllerIT { + + @Autowired + private TokenProvider tokenProvider; + + @Autowired + private AuthenticationManager authenticationManager; + + @Autowired + private UserRepository userRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Autowired + private ExceptionTranslator exceptionTranslator; + + private MockMvc mockMvc; + + @BeforeEach + public void setup() { + UserJWTController userJWTController = new UserJWTController(tokenProvider, authenticationManager); + this.mockMvc = MockMvcBuilders.standaloneSetup(userJWTController) + .setControllerAdvice(exceptionTranslator) + .build(); + } + + @Test + @Transactional + public void testAuthorize() throws Exception { + User user = new User(); + user.setLogin("user-jwt-controller"); + user.setEmail("user-jwt-controller@example.com"); + user.setActivated(true); + user.setPassword(passwordEncoder.encode("test")); + + userRepository.saveAndFlush(user); + + LoginVM login = new LoginVM(); + login.setUsername("user-jwt-controller"); + login.setPassword("test"); + mockMvc.perform(post("/api/authenticate") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(login))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id_token").isString()) + .andExpect(jsonPath("$.id_token").isNotEmpty()) + .andExpect(header().string("Authorization", not(nullValue()))) + .andExpect(header().string("Authorization", not(isEmptyString()))); + } + + @Test + @Transactional + public void testAuthorizeWithRememberMe() throws Exception { + User user = new User(); + user.setLogin("user-jwt-controller-remember-me"); + user.setEmail("user-jwt-controller-remember-me@example.com"); + user.setActivated(true); + user.setPassword(passwordEncoder.encode("test")); + + userRepository.saveAndFlush(user); + + LoginVM login = new LoginVM(); + login.setUsername("user-jwt-controller-remember-me"); + login.setPassword("test"); + login.setRememberMe(true); + mockMvc.perform(post("/api/authenticate") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(login))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id_token").isString()) + .andExpect(jsonPath("$.id_token").isNotEmpty()) + .andExpect(header().string("Authorization", not(nullValue()))) + .andExpect(header().string("Authorization", not(isEmptyString()))); + } + + @Test + public void testAuthorizeFails() throws Exception { + LoginVM login = new LoginVM(); + login.setUsername("wrong-user"); + login.setPassword("wrong password"); + mockMvc.perform(post("/api/authenticate") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(login))) + .andExpect(status().isUnauthorized()) + .andExpect(jsonPath("$.id_token").doesNotExist()) + .andExpect(header().doesNotExist("Authorization")); + } +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/UserJWTControllerIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/UserJWTControllerIntegrationTest.java similarity index 92% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/UserJWTControllerIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/UserJWTControllerIntegrationTest.java index 7cfc0e19fc..bf62d29f1b 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/UserJWTControllerIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/UserJWTControllerIntegrationTest.java @@ -1,11 +1,12 @@ -package com.baeldung.jhipster5.web.rest; +package com.baeldung.jhipster6.web.rest; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.UserRepository; +import com.baeldung.jhipster6.security.jwt.TokenProvider; +import com.baeldung.jhipster6.web.rest.errors.ExceptionTranslator; +import com.baeldung.jhipster6.web.rest.vm.LoginVM; -import com.baeldung.jhipster5.BookstoreApp; -import com.baeldung.jhipster5.domain.User; -import com.baeldung.jhipster5.repository.UserRepository; -import com.baeldung.jhipster5.security.jwt.TokenProvider; -import com.baeldung.jhipster5.web.rest.errors.ExceptionTranslator; -import com.baeldung.jhipster5.web.rest.vm.LoginVM; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/UserResourceIT.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/UserResourceIT.java new file mode 100644 index 0000000000..420dcbbd77 --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/UserResourceIT.java @@ -0,0 +1,592 @@ +package com.baeldung.jhipster6.web.rest; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.domain.Authority; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.UserRepository; +import com.baeldung.jhipster6.security.AuthoritiesConstants; +import com.baeldung.jhipster6.service.MailService; +import com.baeldung.jhipster6.service.UserService; +import com.baeldung.jhipster6.service.dto.UserDTO; +import com.baeldung.jhipster6.service.mapper.UserMapper; +import com.baeldung.jhipster6.web.rest.errors.ExceptionTranslator; +import com.baeldung.jhipster6.web.rest.vm.ManagedUserVM; + +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.web.PageableHandlerMethodArgumentResolver; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; +import java.time.Instant; +import java.util.*; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.hasItem; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Integration tests for the {@link UserResource} REST controller. + */ +@SpringBootTest(classes = BookstoreApp.class) +public class UserResourceIT { + + private static final String DEFAULT_LOGIN = "johndoe"; + private static final String UPDATED_LOGIN = "jhipster"; + + private static final Long DEFAULT_ID = 1L; + + private static final String DEFAULT_PASSWORD = "passjohndoe"; + private static final String UPDATED_PASSWORD = "passjhipster"; + + private static final String DEFAULT_EMAIL = "johndoe@localhost"; + private static final String UPDATED_EMAIL = "jhipster@localhost"; + + private static final String DEFAULT_FIRSTNAME = "john"; + private static final String UPDATED_FIRSTNAME = "jhipsterFirstName"; + + private static final String DEFAULT_LASTNAME = "doe"; + private static final String UPDATED_LASTNAME = "jhipsterLastName"; + + private static final String DEFAULT_IMAGEURL = "http://placehold.it/50x50"; + private static final String UPDATED_IMAGEURL = "http://placehold.it/40x40"; + + private static final String DEFAULT_LANGKEY = "en"; + private static final String UPDATED_LANGKEY = "fr"; + + @Autowired + private UserRepository userRepository; + + @Autowired + private MailService mailService; + + @Autowired + private UserService userService; + + @Autowired + private UserMapper userMapper; + + @Autowired + private MappingJackson2HttpMessageConverter jacksonMessageConverter; + + @Autowired + private PageableHandlerMethodArgumentResolver pageableArgumentResolver; + + @Autowired + private ExceptionTranslator exceptionTranslator; + + @Autowired + private EntityManager em; + + private MockMvc restUserMockMvc; + + private User user; + + @BeforeEach + public void setup() { + UserResource userResource = new UserResource(userService, userRepository, mailService); + + this.restUserMockMvc = MockMvcBuilders.standaloneSetup(userResource) + .setCustomArgumentResolvers(pageableArgumentResolver) + .setControllerAdvice(exceptionTranslator) + .setMessageConverters(jacksonMessageConverter) + .build(); + } + + /** + * Create a User. + * + * This is a static method, as tests for other entities might also need it, + * if they test an entity which has a required relationship to the User entity. + */ + public static User createEntity(EntityManager em) { + User user = new User(); + user.setLogin(DEFAULT_LOGIN + RandomStringUtils.randomAlphabetic(5)); + user.setPassword(RandomStringUtils.random(60)); + user.setActivated(true); + user.setEmail(RandomStringUtils.randomAlphabetic(5) + DEFAULT_EMAIL); + user.setFirstName(DEFAULT_FIRSTNAME); + user.setLastName(DEFAULT_LASTNAME); + user.setImageUrl(DEFAULT_IMAGEURL); + user.setLangKey(DEFAULT_LANGKEY); + return user; + } + + @BeforeEach + public void initTest() { + user = createEntity(em); + user.setLogin(DEFAULT_LOGIN); + user.setEmail(DEFAULT_EMAIL); + } + + @Test + @Transactional + public void createUser() throws Exception { + int databaseSizeBeforeCreate = userRepository.findAll().size(); + + // Create the User + ManagedUserVM managedUserVM = new ManagedUserVM(); + managedUserVM.setLogin(DEFAULT_LOGIN); + managedUserVM.setPassword(DEFAULT_PASSWORD); + managedUserVM.setFirstName(DEFAULT_FIRSTNAME); + managedUserVM.setLastName(DEFAULT_LASTNAME); + managedUserVM.setEmail(DEFAULT_EMAIL); + managedUserVM.setActivated(true); + managedUserVM.setImageUrl(DEFAULT_IMAGEURL); + managedUserVM.setLangKey(DEFAULT_LANGKEY); + managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + restUserMockMvc.perform(post("/api/users") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM))) + .andExpect(status().isCreated()); + + // Validate the User in the database + List userList = userRepository.findAll(); + assertThat(userList).hasSize(databaseSizeBeforeCreate + 1); + User testUser = userList.get(userList.size() - 1); + assertThat(testUser.getLogin()).isEqualTo(DEFAULT_LOGIN); + assertThat(testUser.getFirstName()).isEqualTo(DEFAULT_FIRSTNAME); + assertThat(testUser.getLastName()).isEqualTo(DEFAULT_LASTNAME); + assertThat(testUser.getEmail()).isEqualTo(DEFAULT_EMAIL); + assertThat(testUser.getImageUrl()).isEqualTo(DEFAULT_IMAGEURL); + assertThat(testUser.getLangKey()).isEqualTo(DEFAULT_LANGKEY); + } + + @Test + @Transactional + public void createUserWithExistingId() throws Exception { + int databaseSizeBeforeCreate = userRepository.findAll().size(); + + ManagedUserVM managedUserVM = new ManagedUserVM(); + managedUserVM.setId(1L); + managedUserVM.setLogin(DEFAULT_LOGIN); + managedUserVM.setPassword(DEFAULT_PASSWORD); + managedUserVM.setFirstName(DEFAULT_FIRSTNAME); + managedUserVM.setLastName(DEFAULT_LASTNAME); + managedUserVM.setEmail(DEFAULT_EMAIL); + managedUserVM.setActivated(true); + managedUserVM.setImageUrl(DEFAULT_IMAGEURL); + managedUserVM.setLangKey(DEFAULT_LANGKEY); + managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + // An entity with an existing ID cannot be created, so this API call must fail + restUserMockMvc.perform(post("/api/users") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM))) + .andExpect(status().isBadRequest()); + + // Validate the User in the database + List userList = userRepository.findAll(); + assertThat(userList).hasSize(databaseSizeBeforeCreate); + } + + @Test + @Transactional + public void createUserWithExistingLogin() throws Exception { + // Initialize the database + userRepository.saveAndFlush(user); + int databaseSizeBeforeCreate = userRepository.findAll().size(); + + ManagedUserVM managedUserVM = new ManagedUserVM(); + managedUserVM.setLogin(DEFAULT_LOGIN);// this login should already be used + managedUserVM.setPassword(DEFAULT_PASSWORD); + managedUserVM.setFirstName(DEFAULT_FIRSTNAME); + managedUserVM.setLastName(DEFAULT_LASTNAME); + managedUserVM.setEmail("anothermail@localhost"); + managedUserVM.setActivated(true); + managedUserVM.setImageUrl(DEFAULT_IMAGEURL); + managedUserVM.setLangKey(DEFAULT_LANGKEY); + managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + // Create the User + restUserMockMvc.perform(post("/api/users") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM))) + .andExpect(status().isBadRequest()); + + // Validate the User in the database + List userList = userRepository.findAll(); + assertThat(userList).hasSize(databaseSizeBeforeCreate); + } + + @Test + @Transactional + public void createUserWithExistingEmail() throws Exception { + // Initialize the database + userRepository.saveAndFlush(user); + int databaseSizeBeforeCreate = userRepository.findAll().size(); + + ManagedUserVM managedUserVM = new ManagedUserVM(); + managedUserVM.setLogin("anotherlogin"); + managedUserVM.setPassword(DEFAULT_PASSWORD); + managedUserVM.setFirstName(DEFAULT_FIRSTNAME); + managedUserVM.setLastName(DEFAULT_LASTNAME); + managedUserVM.setEmail(DEFAULT_EMAIL);// this email should already be used + managedUserVM.setActivated(true); + managedUserVM.setImageUrl(DEFAULT_IMAGEURL); + managedUserVM.setLangKey(DEFAULT_LANGKEY); + managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + // Create the User + restUserMockMvc.perform(post("/api/users") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM))) + .andExpect(status().isBadRequest()); + + // Validate the User in the database + List userList = userRepository.findAll(); + assertThat(userList).hasSize(databaseSizeBeforeCreate); + } + + @Test + @Transactional + public void getAllUsers() throws Exception { + // Initialize the database + userRepository.saveAndFlush(user); + + // Get all the users + restUserMockMvc.perform(get("/api/users?sort=id,desc") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(jsonPath("$.[*].login").value(hasItem(DEFAULT_LOGIN))) + .andExpect(jsonPath("$.[*].firstName").value(hasItem(DEFAULT_FIRSTNAME))) + .andExpect(jsonPath("$.[*].lastName").value(hasItem(DEFAULT_LASTNAME))) + .andExpect(jsonPath("$.[*].email").value(hasItem(DEFAULT_EMAIL))) + .andExpect(jsonPath("$.[*].imageUrl").value(hasItem(DEFAULT_IMAGEURL))) + .andExpect(jsonPath("$.[*].langKey").value(hasItem(DEFAULT_LANGKEY))); + } + + @Test + @Transactional + public void getUser() throws Exception { + // Initialize the database + userRepository.saveAndFlush(user); + + // Get the user + restUserMockMvc.perform(get("/api/users/{login}", user.getLogin())) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(jsonPath("$.login").value(user.getLogin())) + .andExpect(jsonPath("$.firstName").value(DEFAULT_FIRSTNAME)) + .andExpect(jsonPath("$.lastName").value(DEFAULT_LASTNAME)) + .andExpect(jsonPath("$.email").value(DEFAULT_EMAIL)) + .andExpect(jsonPath("$.imageUrl").value(DEFAULT_IMAGEURL)) + .andExpect(jsonPath("$.langKey").value(DEFAULT_LANGKEY)); + } + + @Test + @Transactional + public void getNonExistingUser() throws Exception { + restUserMockMvc.perform(get("/api/users/unknown")) + .andExpect(status().isNotFound()); + } + + @Test + @Transactional + public void updateUser() throws Exception { + // Initialize the database + userRepository.saveAndFlush(user); + int databaseSizeBeforeUpdate = userRepository.findAll().size(); + + // Update the user + User updatedUser = userRepository.findById(user.getId()).get(); + + ManagedUserVM managedUserVM = new ManagedUserVM(); + managedUserVM.setId(updatedUser.getId()); + managedUserVM.setLogin(updatedUser.getLogin()); + managedUserVM.setPassword(UPDATED_PASSWORD); + managedUserVM.setFirstName(UPDATED_FIRSTNAME); + managedUserVM.setLastName(UPDATED_LASTNAME); + managedUserVM.setEmail(UPDATED_EMAIL); + managedUserVM.setActivated(updatedUser.getActivated()); + managedUserVM.setImageUrl(UPDATED_IMAGEURL); + managedUserVM.setLangKey(UPDATED_LANGKEY); + managedUserVM.setCreatedBy(updatedUser.getCreatedBy()); + managedUserVM.setCreatedDate(updatedUser.getCreatedDate()); + managedUserVM.setLastModifiedBy(updatedUser.getLastModifiedBy()); + managedUserVM.setLastModifiedDate(updatedUser.getLastModifiedDate()); + managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + restUserMockMvc.perform(put("/api/users") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM))) + .andExpect(status().isOk()); + + // Validate the User in the database + List userList = userRepository.findAll(); + assertThat(userList).hasSize(databaseSizeBeforeUpdate); + User testUser = userList.get(userList.size() - 1); + assertThat(testUser.getFirstName()).isEqualTo(UPDATED_FIRSTNAME); + assertThat(testUser.getLastName()).isEqualTo(UPDATED_LASTNAME); + assertThat(testUser.getEmail()).isEqualTo(UPDATED_EMAIL); + assertThat(testUser.getImageUrl()).isEqualTo(UPDATED_IMAGEURL); + assertThat(testUser.getLangKey()).isEqualTo(UPDATED_LANGKEY); + } + + @Test + @Transactional + public void updateUserLogin() throws Exception { + // Initialize the database + userRepository.saveAndFlush(user); + int databaseSizeBeforeUpdate = userRepository.findAll().size(); + + // Update the user + User updatedUser = userRepository.findById(user.getId()).get(); + + ManagedUserVM managedUserVM = new ManagedUserVM(); + managedUserVM.setId(updatedUser.getId()); + managedUserVM.setLogin(UPDATED_LOGIN); + managedUserVM.setPassword(UPDATED_PASSWORD); + managedUserVM.setFirstName(UPDATED_FIRSTNAME); + managedUserVM.setLastName(UPDATED_LASTNAME); + managedUserVM.setEmail(UPDATED_EMAIL); + managedUserVM.setActivated(updatedUser.getActivated()); + managedUserVM.setImageUrl(UPDATED_IMAGEURL); + managedUserVM.setLangKey(UPDATED_LANGKEY); + managedUserVM.setCreatedBy(updatedUser.getCreatedBy()); + managedUserVM.setCreatedDate(updatedUser.getCreatedDate()); + managedUserVM.setLastModifiedBy(updatedUser.getLastModifiedBy()); + managedUserVM.setLastModifiedDate(updatedUser.getLastModifiedDate()); + managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + restUserMockMvc.perform(put("/api/users") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM))) + .andExpect(status().isOk()); + + // Validate the User in the database + List userList = userRepository.findAll(); + assertThat(userList).hasSize(databaseSizeBeforeUpdate); + User testUser = userList.get(userList.size() - 1); + assertThat(testUser.getLogin()).isEqualTo(UPDATED_LOGIN); + assertThat(testUser.getFirstName()).isEqualTo(UPDATED_FIRSTNAME); + assertThat(testUser.getLastName()).isEqualTo(UPDATED_LASTNAME); + assertThat(testUser.getEmail()).isEqualTo(UPDATED_EMAIL); + assertThat(testUser.getImageUrl()).isEqualTo(UPDATED_IMAGEURL); + assertThat(testUser.getLangKey()).isEqualTo(UPDATED_LANGKEY); + } + + @Test + @Transactional + public void updateUserExistingEmail() throws Exception { + // Initialize the database with 2 users + userRepository.saveAndFlush(user); + + User anotherUser = new User(); + anotherUser.setLogin("jhipster"); + anotherUser.setPassword(RandomStringUtils.random(60)); + anotherUser.setActivated(true); + anotherUser.setEmail("jhipster@localhost"); + anotherUser.setFirstName("java"); + anotherUser.setLastName("hipster"); + anotherUser.setImageUrl(""); + anotherUser.setLangKey("en"); + userRepository.saveAndFlush(anotherUser); + + // Update the user + User updatedUser = userRepository.findById(user.getId()).get(); + + ManagedUserVM managedUserVM = new ManagedUserVM(); + managedUserVM.setId(updatedUser.getId()); + managedUserVM.setLogin(updatedUser.getLogin()); + managedUserVM.setPassword(updatedUser.getPassword()); + managedUserVM.setFirstName(updatedUser.getFirstName()); + managedUserVM.setLastName(updatedUser.getLastName()); + managedUserVM.setEmail("jhipster@localhost");// this email should already be used by anotherUser + managedUserVM.setActivated(updatedUser.getActivated()); + managedUserVM.setImageUrl(updatedUser.getImageUrl()); + managedUserVM.setLangKey(updatedUser.getLangKey()); + managedUserVM.setCreatedBy(updatedUser.getCreatedBy()); + managedUserVM.setCreatedDate(updatedUser.getCreatedDate()); + managedUserVM.setLastModifiedBy(updatedUser.getLastModifiedBy()); + managedUserVM.setLastModifiedDate(updatedUser.getLastModifiedDate()); + managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + restUserMockMvc.perform(put("/api/users") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM))) + .andExpect(status().isBadRequest()); + } + + @Test + @Transactional + public void updateUserExistingLogin() throws Exception { + // Initialize the database + userRepository.saveAndFlush(user); + + User anotherUser = new User(); + anotherUser.setLogin("jhipster"); + anotherUser.setPassword(RandomStringUtils.random(60)); + anotherUser.setActivated(true); + anotherUser.setEmail("jhipster@localhost"); + anotherUser.setFirstName("java"); + anotherUser.setLastName("hipster"); + anotherUser.setImageUrl(""); + anotherUser.setLangKey("en"); + userRepository.saveAndFlush(anotherUser); + + // Update the user + User updatedUser = userRepository.findById(user.getId()).get(); + + ManagedUserVM managedUserVM = new ManagedUserVM(); + managedUserVM.setId(updatedUser.getId()); + managedUserVM.setLogin("jhipster");// this login should already be used by anotherUser + managedUserVM.setPassword(updatedUser.getPassword()); + managedUserVM.setFirstName(updatedUser.getFirstName()); + managedUserVM.setLastName(updatedUser.getLastName()); + managedUserVM.setEmail(updatedUser.getEmail()); + managedUserVM.setActivated(updatedUser.getActivated()); + managedUserVM.setImageUrl(updatedUser.getImageUrl()); + managedUserVM.setLangKey(updatedUser.getLangKey()); + managedUserVM.setCreatedBy(updatedUser.getCreatedBy()); + managedUserVM.setCreatedDate(updatedUser.getCreatedDate()); + managedUserVM.setLastModifiedBy(updatedUser.getLastModifiedBy()); + managedUserVM.setLastModifiedDate(updatedUser.getLastModifiedDate()); + managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + restUserMockMvc.perform(put("/api/users") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM))) + .andExpect(status().isBadRequest()); + } + + @Test + @Transactional + public void deleteUser() throws Exception { + // Initialize the database + userRepository.saveAndFlush(user); + int databaseSizeBeforeDelete = userRepository.findAll().size(); + + // Delete the user + restUserMockMvc.perform(delete("/api/users/{login}", user.getLogin()) + .accept(TestUtil.APPLICATION_JSON_UTF8)) + .andExpect(status().isNoContent()); + + // Validate the database is empty + List userList = userRepository.findAll(); + assertThat(userList).hasSize(databaseSizeBeforeDelete - 1); + } + + @Test + @Transactional + public void getAllAuthorities() throws Exception { + restUserMockMvc.perform(get("/api/users/authorities") + .accept(TestUtil.APPLICATION_JSON_UTF8) + .contentType(TestUtil.APPLICATION_JSON_UTF8)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(jsonPath("$").isArray()) + .andExpect(jsonPath("$").value(hasItems(AuthoritiesConstants.USER, AuthoritiesConstants.ADMIN))); + } + + @Test + @Transactional + public void testUserEquals() throws Exception { + TestUtil.equalsVerifier(User.class); + User user1 = new User(); + user1.setId(1L); + User user2 = new User(); + user2.setId(user1.getId()); + assertThat(user1).isEqualTo(user2); + user2.setId(2L); + assertThat(user1).isNotEqualTo(user2); + user1.setId(null); + assertThat(user1).isNotEqualTo(user2); + } + + @Test + public void testUserDTOtoUser() { + UserDTO userDTO = new UserDTO(); + userDTO.setId(DEFAULT_ID); + userDTO.setLogin(DEFAULT_LOGIN); + userDTO.setFirstName(DEFAULT_FIRSTNAME); + userDTO.setLastName(DEFAULT_LASTNAME); + userDTO.setEmail(DEFAULT_EMAIL); + userDTO.setActivated(true); + userDTO.setImageUrl(DEFAULT_IMAGEURL); + userDTO.setLangKey(DEFAULT_LANGKEY); + userDTO.setCreatedBy(DEFAULT_LOGIN); + userDTO.setLastModifiedBy(DEFAULT_LOGIN); + userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + + User user = userMapper.userDTOToUser(userDTO); + assertThat(user.getId()).isEqualTo(DEFAULT_ID); + assertThat(user.getLogin()).isEqualTo(DEFAULT_LOGIN); + assertThat(user.getFirstName()).isEqualTo(DEFAULT_FIRSTNAME); + assertThat(user.getLastName()).isEqualTo(DEFAULT_LASTNAME); + assertThat(user.getEmail()).isEqualTo(DEFAULT_EMAIL); + assertThat(user.getActivated()).isEqualTo(true); + assertThat(user.getImageUrl()).isEqualTo(DEFAULT_IMAGEURL); + assertThat(user.getLangKey()).isEqualTo(DEFAULT_LANGKEY); + assertThat(user.getCreatedBy()).isNull(); + assertThat(user.getCreatedDate()).isNotNull(); + assertThat(user.getLastModifiedBy()).isNull(); + assertThat(user.getLastModifiedDate()).isNotNull(); + assertThat(user.getAuthorities()).extracting("name").containsExactly(AuthoritiesConstants.USER); + } + + @Test + public void testUserToUserDTO() { + user.setId(DEFAULT_ID); + user.setCreatedBy(DEFAULT_LOGIN); + user.setCreatedDate(Instant.now()); + user.setLastModifiedBy(DEFAULT_LOGIN); + user.setLastModifiedDate(Instant.now()); + Set authorities = new HashSet<>(); + Authority authority = new Authority(); + authority.setName(AuthoritiesConstants.USER); + authorities.add(authority); + user.setAuthorities(authorities); + + UserDTO userDTO = userMapper.userToUserDTO(user); + + assertThat(userDTO.getId()).isEqualTo(DEFAULT_ID); + assertThat(userDTO.getLogin()).isEqualTo(DEFAULT_LOGIN); + assertThat(userDTO.getFirstName()).isEqualTo(DEFAULT_FIRSTNAME); + assertThat(userDTO.getLastName()).isEqualTo(DEFAULT_LASTNAME); + assertThat(userDTO.getEmail()).isEqualTo(DEFAULT_EMAIL); + assertThat(userDTO.isActivated()).isEqualTo(true); + assertThat(userDTO.getImageUrl()).isEqualTo(DEFAULT_IMAGEURL); + assertThat(userDTO.getLangKey()).isEqualTo(DEFAULT_LANGKEY); + assertThat(userDTO.getCreatedBy()).isEqualTo(DEFAULT_LOGIN); + assertThat(userDTO.getCreatedDate()).isEqualTo(user.getCreatedDate()); + assertThat(userDTO.getLastModifiedBy()).isEqualTo(DEFAULT_LOGIN); + assertThat(userDTO.getLastModifiedDate()).isEqualTo(user.getLastModifiedDate()); + assertThat(userDTO.getAuthorities()).containsExactly(AuthoritiesConstants.USER); + assertThat(userDTO.toString()).isNotNull(); + } + + @Test + public void testAuthorityEquals() { + Authority authorityA = new Authority(); + assertThat(authorityA).isEqualTo(authorityA); + assertThat(authorityA).isNotEqualTo(null); + assertThat(authorityA).isNotEqualTo(new Object()); + assertThat(authorityA.hashCode()).isEqualTo(0); + assertThat(authorityA.toString()).isNotNull(); + + Authority authorityB = new Authority(); + assertThat(authorityA).isEqualTo(authorityB); + + authorityB.setName(AuthoritiesConstants.ADMIN); + assertThat(authorityA).isNotEqualTo(authorityB); + + authorityA.setName(AuthoritiesConstants.USER); + assertThat(authorityA).isNotEqualTo(authorityB); + + authorityB.setName(AuthoritiesConstants.USER); + assertThat(authorityA).isEqualTo(authorityB); + assertThat(authorityA.hashCode()).isEqualTo(authorityB.hashCode()); + } +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/UserResourceIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/UserResourceIntegrationTest.java similarity index 97% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/UserResourceIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/UserResourceIntegrationTest.java index c0abc042fb..20d8d4a85c 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/UserResourceIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/UserResourceIntegrationTest.java @@ -1,16 +1,17 @@ -package com.baeldung.jhipster5.web.rest; +package com.baeldung.jhipster6.web.rest; + +import com.baeldung.jhipster6.BookstoreApp; +import com.baeldung.jhipster6.domain.Authority; +import com.baeldung.jhipster6.domain.User; +import com.baeldung.jhipster6.repository.UserRepository; +import com.baeldung.jhipster6.security.AuthoritiesConstants; +import com.baeldung.jhipster6.service.MailService; +import com.baeldung.jhipster6.service.UserService; +import com.baeldung.jhipster6.service.dto.UserDTO; +import com.baeldung.jhipster6.service.mapper.UserMapper; +import com.baeldung.jhipster6.web.rest.errors.ExceptionTranslator; +import com.baeldung.jhipster6.web.rest.vm.ManagedUserVM; -import com.baeldung.jhipster5.BookstoreApp; -import com.baeldung.jhipster5.domain.Authority; -import com.baeldung.jhipster5.domain.User; -import com.baeldung.jhipster5.repository.UserRepository; -import com.baeldung.jhipster5.security.AuthoritiesConstants; -import com.baeldung.jhipster5.service.MailService; -import com.baeldung.jhipster5.service.UserService; -import com.baeldung.jhipster5.service.dto.UserDTO; -import com.baeldung.jhipster5.service.mapper.UserMapper; -import com.baeldung.jhipster5.web.rest.errors.ExceptionTranslator; -import com.baeldung.jhipster5.web.rest.vm.ManagedUserVM; import org.apache.commons.lang3.RandomStringUtils; import org.junit.Before; import org.junit.Test; diff --git a/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/errors/ExceptionTranslatorIT.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/errors/ExceptionTranslatorIT.java new file mode 100644 index 0000000000..2ecbe7254e --- /dev/null +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/errors/ExceptionTranslatorIT.java @@ -0,0 +1,125 @@ +package com.baeldung.jhipster6.web.rest.errors; + +import com.baeldung.jhipster6.BookstoreApp; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * Integration tests {@link ExceptionTranslator} controller advice. + */ +@SpringBootTest(classes = BookstoreApp.class) +public class ExceptionTranslatorIT { + + @Autowired + private ExceptionTranslatorTestController controller; + + @Autowired + private ExceptionTranslator exceptionTranslator; + + @Autowired + private MappingJackson2HttpMessageConverter jacksonMessageConverter; + + private MockMvc mockMvc; + + @BeforeEach + public void setup() { + mockMvc = MockMvcBuilders.standaloneSetup(controller) + .setControllerAdvice(exceptionTranslator) + .setMessageConverters(jacksonMessageConverter) + .build(); + } + + @Test + public void testConcurrencyFailure() throws Exception { + mockMvc.perform(get("/test/concurrency-failure")) + .andExpect(status().isConflict()) + .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) + .andExpect(jsonPath("$.message").value(ErrorConstants.ERR_CONCURRENCY_FAILURE)); + } + + @Test + public void testMethodArgumentNotValid() throws Exception { + mockMvc.perform(post("/test/method-argument").content("{}").contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()) + .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) + .andExpect(jsonPath("$.message").value(ErrorConstants.ERR_VALIDATION)) + .andExpect(jsonPath("$.fieldErrors.[0].objectName").value("testDTO")) + .andExpect(jsonPath("$.fieldErrors.[0].field").value("test")) + .andExpect(jsonPath("$.fieldErrors.[0].message").value("NotNull")); + } + + @Test + public void testMissingServletRequestPartException() throws Exception { + mockMvc.perform(get("/test/missing-servlet-request-part")) + .andExpect(status().isBadRequest()) + .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) + .andExpect(jsonPath("$.message").value("error.http.400")); + } + + @Test + public void testMissingServletRequestParameterException() throws Exception { + mockMvc.perform(get("/test/missing-servlet-request-parameter")) + .andExpect(status().isBadRequest()) + .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) + .andExpect(jsonPath("$.message").value("error.http.400")); + } + + @Test + public void testAccessDenied() throws Exception { + mockMvc.perform(get("/test/access-denied")) + .andExpect(status().isForbidden()) + .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) + .andExpect(jsonPath("$.message").value("error.http.403")) + .andExpect(jsonPath("$.detail").value("test access denied!")); + } + + @Test + public void testUnauthorized() throws Exception { + mockMvc.perform(get("/test/unauthorized")) + .andExpect(status().isUnauthorized()) + .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) + .andExpect(jsonPath("$.message").value("error.http.401")) + .andExpect(jsonPath("$.path").value("/test/unauthorized")) + .andExpect(jsonPath("$.detail").value("test authentication failed!")); + } + + @Test + public void testMethodNotSupported() throws Exception { + mockMvc.perform(post("/test/access-denied")) + .andExpect(status().isMethodNotAllowed()) + .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) + .andExpect(jsonPath("$.message").value("error.http.405")) + .andExpect(jsonPath("$.detail").value("Request method 'POST' not supported")); + } + + @Test + public void testExceptionWithResponseStatus() throws Exception { + mockMvc.perform(get("/test/response-status")) + .andExpect(status().isBadRequest()) + .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) + .andExpect(jsonPath("$.message").value("error.http.400")) + .andExpect(jsonPath("$.title").value("test response status")); + } + + @Test + public void testInternalServerError() throws Exception { + mockMvc.perform(get("/test/internal-server-error")) + .andExpect(status().isInternalServerError()) + .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) + .andExpect(jsonPath("$.message").value("error.http.500")) + .andExpect(jsonPath("$.title").value("Internal Server Error")); + } + +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/errors/ExceptionTranslatorIntegrationTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/errors/ExceptionTranslatorIntegrationTest.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/errors/ExceptionTranslatorIntegrationTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/errors/ExceptionTranslatorIntegrationTest.java index e5ef08ee9c..7b25b314ed 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/errors/ExceptionTranslatorIntegrationTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/errors/ExceptionTranslatorIntegrationTest.java @@ -1,6 +1,6 @@ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; -import com.baeldung.jhipster5.BookstoreApp; +import com.baeldung.jhipster6.BookstoreApp; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/errors/ExceptionTranslatorTestController.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/errors/ExceptionTranslatorTestController.java similarity index 98% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/errors/ExceptionTranslatorTestController.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/errors/ExceptionTranslatorTestController.java index f8d84151b9..a0e6e03178 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/errors/ExceptionTranslatorTestController.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/errors/ExceptionTranslatorTestController.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.errors; +package com.baeldung.jhipster6.web.rest.errors; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.http.HttpStatus; diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/util/PaginationUtilUnitTest.java b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/util/PaginationUtilUnitTest.java similarity index 97% rename from jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/util/PaginationUtilUnitTest.java rename to jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/util/PaginationUtilUnitTest.java index 78b17ee859..da7c2ae1f5 100644 --- a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/util/PaginationUtilUnitTest.java +++ b/jhipster-6/bookstore-monolith/src/test/java/com/baeldung/jhipster6/web/rest/util/PaginationUtilUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.jhipster5.web.rest.util; +package com.baeldung.jhipster6.web.rest.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/jest-global-mocks.ts b/jhipster-6/bookstore-monolith/src/test/javascript/jest-global-mocks.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/jest-global-mocks.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/jest-global-mocks.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/jest.conf.js b/jhipster-6/bookstore-monolith/src/test/javascript/jest.conf.js similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/jest.conf.js rename to jhipster-6/bookstore-monolith/src/test/javascript/jest.conf.js diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/jest.ts b/jhipster-6/bookstore-monolith/src/test/javascript/jest.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/jest.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/jest.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/activate/activate.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/activate/activate.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/activate/activate.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/activate/activate.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/password-reset/finish/password-reset-finish.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/password-reset/finish/password-reset-finish.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/password-reset/finish/password-reset-finish.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/password-reset/finish/password-reset-finish.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/password-reset/init/password-reset-init.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/password-reset/init/password-reset-init.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/password-reset/init/password-reset-init.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/password-reset/init/password-reset-init.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/password/password-strength-bar.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/password/password-strength-bar.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/password/password-strength-bar.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/password/password-strength-bar.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/password/password.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/password/password.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/password/password.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/password/password.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/register/register.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/register/register.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/register/register.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/register/register.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/settings/settings.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/settings/settings.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/account/settings/settings.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/account/settings/settings.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/audits/audits.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/audits/audits.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/audits/audits.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/audits/audits.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/audits/audits.service.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/audits/audits.service.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/audits/audits.service.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/audits/audits.service.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/configuration/configuration.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/configuration/configuration.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/configuration/configuration.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/configuration/configuration.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/configuration/configuration.service.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/configuration/configuration.service.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/configuration/configuration.service.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/configuration/configuration.service.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/health/health.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/health/health.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/health/health.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/health/health.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/metrics/metrics.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/metrics/metrics.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/metrics/metrics.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/metrics/metrics.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/metrics/metrics.service.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/metrics/metrics.service.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/metrics/metrics.service.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/metrics/metrics.service.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management-delete-dialog.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management-delete-dialog.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management-delete-dialog.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management-delete-dialog.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management-detail.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management-detail.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management-detail.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management-detail.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management-update.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management-update.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management-update.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management-update.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/admin/user-management/user-management.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/core/user/account.service.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/core/user/account.service.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/core/user/account.service.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/core/user/account.service.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/core/user/user.service.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/core/user/user.service.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/core/user/user.service.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/core/user/user.service.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-delete-dialog.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-delete-dialog.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-delete-dialog.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-delete-dialog.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-detail.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-detail.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-detail.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-detail.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-update.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-update.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-update.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-update.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.service.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.service.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.service.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.service.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/shared/alert/alert-error.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/shared/alert/alert-error.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/shared/alert/alert-error.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/shared/alert/alert-error.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/shared/login/login.component.spec.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/app/shared/login/login.component.spec.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/app/shared/login/login.component.spec.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/app/shared/login/login.component.spec.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-account.service.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-account.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-account.service.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-account.service.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-active-modal.service.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-active-modal.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-active-modal.service.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-active-modal.service.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-alert.service.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-alert.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-alert.service.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-alert.service.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-event-manager.service.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-event-manager.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-event-manager.service.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-event-manager.service.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-login.service.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-login.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-login.service.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-login.service.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-route.service.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-route.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-route.service.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-route.service.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-state-storage.service.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-state-storage.service.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/mock-state-storage.service.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/mock-state-storage.service.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/spyobject.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/spyobject.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/helpers/spyobject.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/helpers/spyobject.ts diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/test.module.ts b/jhipster-6/bookstore-monolith/src/test/javascript/spec/test.module.ts similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/javascript/spec/test.module.ts rename to jhipster-6/bookstore-monolith/src/test/javascript/spec/test.module.ts diff --git a/jhipster-5/bookstore-monolith/src/test/resources/config/application.yml b/jhipster-6/bookstore-monolith/src/test/resources/config/application.yml similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/resources/config/application.yml rename to jhipster-6/bookstore-monolith/src/test/resources/config/application.yml diff --git a/jhipster-5/bookstore-monolith/src/test/resources/i18n/messages_en.properties b/jhipster-6/bookstore-monolith/src/test/resources/i18n/messages_en.properties similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/resources/i18n/messages_en.properties rename to jhipster-6/bookstore-monolith/src/test/resources/i18n/messages_en.properties diff --git a/jhipster-5/bookstore-monolith/src/test/resources/logback.xml b/jhipster-6/bookstore-monolith/src/test/resources/logback.xml similarity index 97% rename from jhipster-5/bookstore-monolith/src/test/resources/logback.xml rename to jhipster-6/bookstore-monolith/src/test/resources/logback.xml index 6244807dfa..de8cf57b93 100644 --- a/jhipster-5/bookstore-monolith/src/test/resources/logback.xml +++ b/jhipster-6/bookstore-monolith/src/test/resources/logback.xml @@ -10,7 +10,7 @@ - + diff --git a/jhipster-5/bookstore-monolith/src/test/resources/templates/mail/testEmail.html b/jhipster-6/bookstore-monolith/src/test/resources/templates/mail/testEmail.html similarity index 100% rename from jhipster-5/bookstore-monolith/src/test/resources/templates/mail/testEmail.html rename to jhipster-6/bookstore-monolith/src/test/resources/templates/mail/testEmail.html diff --git a/jhipster-5/bookstore-monolith/tsconfig-aot.json b/jhipster-6/bookstore-monolith/tsconfig-aot.json similarity index 100% rename from jhipster-5/bookstore-monolith/tsconfig-aot.json rename to jhipster-6/bookstore-monolith/tsconfig-aot.json diff --git a/jhipster-5/bookstore-monolith/tsconfig.json b/jhipster-6/bookstore-monolith/tsconfig.json similarity index 100% rename from jhipster-5/bookstore-monolith/tsconfig.json rename to jhipster-6/bookstore-monolith/tsconfig.json diff --git a/jhipster-5/bookstore-monolith/tslint.json b/jhipster-6/bookstore-monolith/tslint.json similarity index 100% rename from jhipster-5/bookstore-monolith/tslint.json rename to jhipster-6/bookstore-monolith/tslint.json diff --git a/jhipster-5/bookstore-monolith/webpack/logo-jhipster.png b/jhipster-6/bookstore-monolith/webpack/logo-jhipster.png similarity index 100% rename from jhipster-5/bookstore-monolith/webpack/logo-jhipster.png rename to jhipster-6/bookstore-monolith/webpack/logo-jhipster.png diff --git a/jhipster-5/bookstore-monolith/webpack/utils.js b/jhipster-6/bookstore-monolith/webpack/utils.js similarity index 100% rename from jhipster-5/bookstore-monolith/webpack/utils.js rename to jhipster-6/bookstore-monolith/webpack/utils.js diff --git a/jhipster-5/bookstore-monolith/webpack/webpack.common.js b/jhipster-6/bookstore-monolith/webpack/webpack.common.js similarity index 100% rename from jhipster-5/bookstore-monolith/webpack/webpack.common.js rename to jhipster-6/bookstore-monolith/webpack/webpack.common.js diff --git a/jhipster-5/bookstore-monolith/webpack/webpack.dev.js b/jhipster-6/bookstore-monolith/webpack/webpack.dev.js similarity index 100% rename from jhipster-5/bookstore-monolith/webpack/webpack.dev.js rename to jhipster-6/bookstore-monolith/webpack/webpack.dev.js diff --git a/jhipster-5/bookstore-monolith/webpack/webpack.prod.js b/jhipster-6/bookstore-monolith/webpack/webpack.prod.js similarity index 100% rename from jhipster-5/bookstore-monolith/webpack/webpack.prod.js rename to jhipster-6/bookstore-monolith/webpack/webpack.prod.js diff --git a/jhipster-5/pom.xml b/jhipster-6/pom.xml similarity index 56% rename from jhipster-5/pom.xml rename to jhipster-6/pom.xml index 2a5132e50e..b3c5e58319 100644 --- a/jhipster-5/pom.xml +++ b/jhipster-6/pom.xml @@ -1,11 +1,10 @@ - - + 4.0.0 com.baeldung.jhipster - jhipster-5 + jhipster-6 1.0.0-SNAPSHOT - jhipster-5 + jhipster-6 pom @@ -17,6 +16,6 @@ bookstore-monolith - - + + diff --git a/jhipster-modules/jhipster-uaa/gateway/src/main/java/com/baeldung/jhipster/gateway/security/oauth2/UaaTokenEndpointClient.java b/jhipster-modules/jhipster-uaa/gateway/src/main/java/com/baeldung/jhipster/gateway/security/oauth2/UaaTokenEndpointClient.java index 01c8febdb2..296e8cf67a 100644 --- a/jhipster-modules/jhipster-uaa/gateway/src/main/java/com/baeldung/jhipster/gateway/security/oauth2/UaaTokenEndpointClient.java +++ b/jhipster-modules/jhipster-uaa/gateway/src/main/java/com/baeldung/jhipster/gateway/security/oauth2/UaaTokenEndpointClient.java @@ -5,11 +5,11 @@ import io.github.jhipster.config.JHipsterProperties; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; -import org.springframework.util.Base64Utils; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import java.nio.charset.StandardCharsets; +import java.util.Base64; /** * Client talking to UAA's token endpoint to do different OAuth2 grants. @@ -34,7 +34,7 @@ public class UaaTokenEndpointClient extends OAuth2TokenEndpointClientAdapter imp String clientId = getClientId(); String clientSecret = getClientSecret(); String authorization = clientId + ":" + clientSecret; - return "Basic " + Base64Utils.encodeToString(authorization.getBytes(StandardCharsets.UTF_8)); + return "Basic " + Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8)); } } diff --git a/jib/pom.xml b/jib/pom.xml index bbc9a3c623..2bdaa258f5 100644 --- a/jib/pom.xml +++ b/jib/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jib - 0.1-SNAPSHOT jib diff --git a/jmeter/pom.xml b/jmeter/pom.xml index 33cd56032e..5f4105d282 100644 --- a/jmeter/pom.xml +++ b/jmeter/pom.xml @@ -50,13 +50,13 @@ jmeter-maven-plugin ${jmeter-maven-plugin.version} - - - configuration - - configure - - + + + configuration + + configure + + jmeter-tests @@ -72,10 +72,6 @@ - - 3.7.0 - - dashboard @@ -167,4 +163,8 @@ + + 3.7.0 + + \ No newline at end of file diff --git a/jmh/pom.xml b/jmh/pom.xml index 61f62efd5a..5b98d59002 100644 --- a/jmh/pom.xml +++ b/jmh/pom.xml @@ -4,10 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 jmh - 1.0-SNAPSHOT jmh jar - http://maven.apache.org com.baeldung @@ -20,12 +18,12 @@ org.openjdk.jmh jmh-core - ${jmh-core.version} + 1.36 org.openjdk.jmh jmh-generator-annprocess - ${jmh-generator.version} + 1.36 org.openjdk.jol @@ -36,6 +34,15 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + + --add-exports=java.base/jdk.internal.vm.annotation=ALL-UNNAMED + + + org.apache.maven.plugins maven-jar-plugin @@ -76,9 +83,10 @@ - 3.0.2 - 0.10 - 3.2.0 + 3.3.0 + 0.17 + 3.5.0 + 3.11.0 \ No newline at end of file diff --git a/jmh/src/main/java/com/baeldung/falsesharing/Striped64.java b/jmh/src/main/java/com/baeldung/falsesharing/Striped64.java index 71c34a9de3..1cb55f3f4e 100644 --- a/jmh/src/main/java/com/baeldung/falsesharing/Striped64.java +++ b/jmh/src/main/java/com/baeldung/falsesharing/Striped64.java @@ -88,7 +88,7 @@ abstract class Striped64 extends Number { * JVM intrinsics note: It would be possible to use a release-only * form of CAS here, if it were provided. */ - @sun.misc.Contended static final class Cell { + @jdk.internal.vm.annotation.Contended static final class Cell { volatile long value; Cell(long x) { value = x; } final boolean cas(long cmp, long val) { diff --git a/jsf/pom.xml b/jsf/pom.xml index 4e17540557..81030537fb 100644 --- a/jsf/pom.xml +++ b/jsf/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jsf - 0.1-SNAPSHOT jsf war @@ -79,7 +78,7 @@ 3.0.0 3.3.1 - + 1.3.1 diff --git a/json-modules/gson/pom.xml b/json-modules/gson/pom.xml index faa8a48297..ecfbaa7be4 100644 --- a/json-modules/gson/pom.xml +++ b/json-modules/gson/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 gson - 0.1-SNAPSHOT gson diff --git a/json-modules/json-path/pom.xml b/json-modules/json-path/pom.xml index e467ee9557..88b81dfc68 100644 --- a/json-modules/json-path/pom.xml +++ b/json-modules/json-path/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 json-path - 0.0.1-SNAPSHOT json-path diff --git a/json-modules/json-path/src/test/java/com/baeldung/jsonpath/introduction/ServiceIntegrationTest.java b/json-modules/json-path/src/test/java/com/baeldung/jsonpath/introduction/ServiceIntegrationTest.java index 85e5d3e826..a64495c0f8 100644 --- a/json-modules/json-path/src/test/java/com/baeldung/jsonpath/introduction/ServiceIntegrationTest.java +++ b/json-modules/json-path/src/test/java/com/baeldung/jsonpath/introduction/ServiceIntegrationTest.java @@ -1,9 +1,11 @@ package com.baeldung.jsonpath.introduction; import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.Criteria; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.Option; +import com.jayway.jsonpath.Filter; import org.junit.Test; import java.io.InputStream; @@ -98,4 +100,14 @@ public class ServiceIntegrationTest { assertEquals("Spectre", title); } + + @Test + public void givenJsonPathWithFilterPredicate_whenReadingRootNode_thenCorrect() { + Filter directorSamMendesFilter = Filter.filter(Criteria.where("director") + .contains("Sam Mendes")); + List> samMendesMovies = JsonPath.parse(jsonString) + .read("$[?]['director']", directorSamMendesFilter); + assertEquals(samMendesMovies.size(), 2); + } + } \ No newline at end of file diff --git a/json-modules/json/pom.xml b/json-modules/json/pom.xml index 06e67288c5..8210f026e7 100644 --- a/json-modules/json/pom.xml +++ b/json-modules/json/pom.xml @@ -5,7 +5,6 @@ 4.0.0 org.baeldung json - 0.0.1-SNAPSHOT json @@ -69,7 +68,7 @@ 1.0.72 1.0 1.0.1 - 20211205 + 20230227 2.8.5 1.1.2 2.28.0 diff --git a/jws/pom.xml b/jws/pom.xml index 3d2f67c691..2f01f90721 100644 --- a/jws/pom.xml +++ b/jws/pom.xml @@ -3,9 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - com.example jws - 0.0.1-SNAPSHOT jws war @@ -67,4 +65,4 @@ 3.0.2 - \ No newline at end of file + diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml index daa01108f6..5e06a5550e 100644 --- a/libraries-3/pom.xml +++ b/libraries-3/pom.xml @@ -122,6 +122,11 @@ ${mutabilitydetector.version} test + + javax.annotation + javax.annotation-api + 1.3.2 + @@ -161,42 +166,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.5 - javac-with-errorprone - true - 1.8 - 1.8 - true - - - com.uber.nullaway - nullaway - 0.3.0 - - - - - - - -XepExcludedPaths:(.*)/test/.*|(.*)/jcabi/.* - -XepOpt:NullAway:AnnotatedPackages=com.baeldung.nullaway - + 11 + 11 - - - org.codehaus.plexus - plexus-compiler-javac-errorprone - 2.8 - - - - - com.google.errorprone - error_prone_core - 2.3.4 - - diff --git a/libraries-3/src/test/java/com/baeldung/immutable/ImmutablePersonUnitTest.java b/libraries-3/src/test/java/com/baeldung/immutable/ImmutablePersonUnitTest.java index 222cbfd8ef..b9164ed92b 100644 --- a/libraries-3/src/test/java/com/baeldung/immutable/ImmutablePersonUnitTest.java +++ b/libraries-3/src/test/java/com/baeldung/immutable/ImmutablePersonUnitTest.java @@ -1,5 +1,6 @@ package com.baeldung.immutable; +import org.junit.Ignore; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -7,6 +8,12 @@ import static org.mutabilitydetector.unittesting.MutabilityAssert.assertImmutabl public class ImmutablePersonUnitTest { + /** + * commenting the test case, As after upgrading to java 11 + * assertImmutable is giving exception. Raised the issue to Mutability support team + * https://github.com/MutabilityDetector/MutabilityDetector/issues/196 + */ + @Ignore @Test public void whenModifying_shouldCreateNewInstance() throws Exception { final ImmutablePerson john = ImmutablePerson.builder() diff --git a/libraries-4/pom.xml b/libraries-4/pom.xml index 7d19f6d504..597fce2823 100644 --- a/libraries-4/pom.xml +++ b/libraries-4/pom.xml @@ -99,9 +99,34 @@ javax.el ${glassfish.web.version} + + org.openjfx + javafx-controls + ${javafx.version} + + + org.openjfx + javafx-fxml + ${javafx.version} + + + + com.fasterxml.jackson.core + jackson-core + ${jackson-core.version} + + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-annotations.version} + + + 2.14.2 + 2.14.2 1.2.6 8.2.0 1.1.0 @@ -118,6 +143,7 @@ 3.0.0 2.2.4 1.2.0 + 19 \ No newline at end of file diff --git a/libraries-5/pom.xml b/libraries-5/pom.xml index fa1f232d1c..c98a66c094 100644 --- a/libraries-5/pom.xml +++ b/libraries-5/pom.xml @@ -139,7 +139,7 @@ 4.3.8.RELEASE 2.12 2.5.11 - 0.6.5 + 0.8.1 3.0.14 2.5.5 3.0.2 diff --git a/libraries-6/README.md b/libraries-6/README.md index 8ef60b2e54..bbebcbc1e0 100644 --- a/libraries-6/README.md +++ b/libraries-6/README.md @@ -12,8 +12,8 @@ Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-m - [Guide to Resilience4j](https://www.baeldung.com/resilience4j) - [Implementing a FTP-Client in Java](https://www.baeldung.com/java-ftp-client) - [Introduction to Functional Java](https://www.baeldung.com/java-functional-library) -- [A Guide to the Reflections Library](https://www.baeldung.com/reflections-library) - [Introduction to Protonpack](https://www.baeldung.com/java-protonpack) +- [Guide to Simple Binary Encoding](https://www.baeldung.com/java-sbe) - [Java-R Integration](https://www.baeldung.com/java-r-integration) - [Using libphonenumber to Validate Phone Numbers](https://www.baeldung.com/java-libphonenumber) - [Apache Commons Collections vs Google Guava](https://www.baeldung.com/apache-commons-collections-vs-guava) diff --git a/libraries-6/pom.xml b/libraries-6/pom.xml index 3b932f2bd2..139edab34f 100644 --- a/libraries-6/pom.xml +++ b/libraries-6/pom.xml @@ -53,12 +53,6 @@ ${mockftpserver.version} test - - - org.reflections - reflections - ${reflections.version} - org.apache.commons commons-lang3 @@ -69,6 +63,11 @@ commons-collections4 ${commons-collections4.version} + + com.google.guava + guava + ${guava.version} + commons-net commons-net @@ -106,6 +105,11 @@ modelmapper ${org.modelmapper.version} + + org.agrona + agrona + 1.17.1 + @@ -119,6 +123,60 @@ + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + generate-sources + + java + + + + + false + true + uk.co.real_logic.sbe.SbeTool + + + sbe.output.dir + ${project.build.directory}/generated-sources/java + + + + ${project.basedir}/src/main/resources/schema.xml + + ${project.build.directory}/generated-sources/java + + + + uk.co.real-logic + sbe-tool + 1.27.0 + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.0.0 + + + add-source + generate-sources + + add-source + + + + ${project.build.directory}/generated-sources/java/ + + + + + org.apache.maven.plugins maven-compiler-plugin @@ -137,7 +195,6 @@ 1.10.0 - 0.9.11 2.7.1 4.8.1 0.12.1 diff --git a/libraries-7/src/main/java/com/baeldung/sbe/MarketData.java b/libraries-6/src/main/java/com/baeldung/sbe/MarketData.java similarity index 100% rename from libraries-7/src/main/java/com/baeldung/sbe/MarketData.java rename to libraries-6/src/main/java/com/baeldung/sbe/MarketData.java diff --git a/libraries-7/src/main/java/com/baeldung/sbe/MarketDataSource.java b/libraries-6/src/main/java/com/baeldung/sbe/MarketDataSource.java similarity index 100% rename from libraries-7/src/main/java/com/baeldung/sbe/MarketDataSource.java rename to libraries-6/src/main/java/com/baeldung/sbe/MarketDataSource.java diff --git a/libraries-7/src/main/java/com/baeldung/sbe/MarketDataStreamServer.java b/libraries-6/src/main/java/com/baeldung/sbe/MarketDataStreamServer.java similarity index 100% rename from libraries-7/src/main/java/com/baeldung/sbe/MarketDataStreamServer.java rename to libraries-6/src/main/java/com/baeldung/sbe/MarketDataStreamServer.java diff --git a/libraries-7/src/main/java/com/baeldung/sbe/MarketDataUtil.java b/libraries-6/src/main/java/com/baeldung/sbe/MarketDataUtil.java similarity index 100% rename from libraries-7/src/main/java/com/baeldung/sbe/MarketDataUtil.java rename to libraries-6/src/main/java/com/baeldung/sbe/MarketDataUtil.java diff --git a/libraries-7/src/main/resources/schema.xml b/libraries-6/src/main/resources/schema.xml similarity index 100% rename from libraries-7/src/main/resources/schema.xml rename to libraries-6/src/main/resources/schema.xml diff --git a/libraries-6/src/test/java/com/baeldung/r/FastRMeanUnitTest.java b/libraries-6/src/test/java/com/baeldung/r/FastRMeanUnitTest.java index 4e7426b75a..2412bb751b 100644 --- a/libraries-6/src/test/java/com/baeldung/r/FastRMeanUnitTest.java +++ b/libraries-6/src/test/java/com/baeldung/r/FastRMeanUnitTest.java @@ -1,5 +1,6 @@ package com.baeldung.r; + import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; diff --git a/libraries-7/src/test/java/com/baeldung/test/EncodeDecodeMarketDataUnitTest.java b/libraries-6/src/test/java/com/baeldung/test/EncodeDecodeMarketDataUnitTest.java similarity index 100% rename from libraries-7/src/test/java/com/baeldung/test/EncodeDecodeMarketDataUnitTest.java rename to libraries-6/src/test/java/com/baeldung/test/EncodeDecodeMarketDataUnitTest.java diff --git a/libraries-7/pom.xml b/libraries-7/pom.xml deleted file mode 100644 index 67cc2326eb..0000000000 --- a/libraries-7/pom.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - 4.0.0 - libraries-7 - - - parent-modules - com.baeldung - 1.0.0-SNAPSHOT - - - - - org.agrona - agrona - 1.17.1 - - - - - - - org.codehaus.mojo - exec-maven-plugin - 1.6.0 - - - generate-sources - - java - - - - - false - true - uk.co.real_logic.sbe.SbeTool - - - sbe.output.dir - ${project.build.directory}/generated-sources/java - - - - ${project.basedir}/src/main/resources/schema.xml - - ${project.build.directory}/generated-sources/java - - - - uk.co.real-logic - sbe-tool - 1.27.0 - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.0.0 - - - add-source - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/java/ - - - - - - - - - \ No newline at end of file diff --git a/libraries-ai/README.md b/libraries-ai/README.md new file mode 100644 index 0000000000..01ec9b1d68 --- /dev/null +++ b/libraries-ai/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Overview of NLP Libraries in Java](https://www.baeldung.com/java-nlp-libraries) diff --git a/libraries-ai/pom.xml b/libraries-ai/pom.xml new file mode 100644 index 0000000000..2c1490440f --- /dev/null +++ b/libraries-ai/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + libraries-ai + libraries-ai + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + edu.stanford.nlp + stanford-corenlp + ${stanford-corenlp.version} + + + org.apache.opennlp + opennlp-tools + ${opennlp-tools.version} + + + + + 4.5.3 + 2.1.1 + + + \ No newline at end of file diff --git a/libraries-ai/src/test/java/com/baeldung/nlp/CoreNLPTokenizerUnitTest.java b/libraries-ai/src/test/java/com/baeldung/nlp/CoreNLPTokenizerUnitTest.java new file mode 100644 index 0000000000..11c5cd0be8 --- /dev/null +++ b/libraries-ai/src/test/java/com/baeldung/nlp/CoreNLPTokenizerUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.nlp; + +import edu.stanford.nlp.ling.CoreAnnotations; +import edu.stanford.nlp.ling.CoreLabel; +import edu.stanford.nlp.pipeline.Annotation; +import edu.stanford.nlp.pipeline.StanfordCoreNLP; +import edu.stanford.nlp.util.CoreMap; +import org.junit.Test; + +import java.util.List; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; + +public class CoreNLPTokenizerUnitTest { + @Test + public void givenSampleText_whenTokenize_thenExpectedTokensReturned() { + + Properties props = new Properties(); + props.setProperty("annotators", "tokenize"); + + StanfordCoreNLP pipeline = new StanfordCoreNLP(props); + String text = "The german shepard display an act of kindness"; + + Annotation document = new Annotation(text); + pipeline.annotate(document); + + List sentences = document.get(CoreAnnotations.SentencesAnnotation.class); + StringBuilder tokens = new StringBuilder(); + + for (CoreMap sentence : sentences) { + for (CoreLabel token : sentence.get(CoreAnnotations.TokensAnnotation.class)) { + String word = token.get(CoreAnnotations.TextAnnotation.class); + tokens.append(word) + .append(" "); + } + } + assertEquals("The german shepard display an act of kindness", tokens.toString() + .trim()); + } +} diff --git a/libraries-ai/src/test/java/com/baeldung/nlp/OpenNLPLanguageDetectorManualTest.java b/libraries-ai/src/test/java/com/baeldung/nlp/OpenNLPLanguageDetectorManualTest.java new file mode 100644 index 0000000000..9c5294a808 --- /dev/null +++ b/libraries-ai/src/test/java/com/baeldung/nlp/OpenNLPLanguageDetectorManualTest.java @@ -0,0 +1,40 @@ +package com.baeldung.nlp; + +import opennlp.tools.langdetect.Language; +import opennlp.tools.langdetect.LanguageDetectorME; +import opennlp.tools.langdetect.LanguageDetectorModel; +import org.junit.jupiter.api.Test; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class OpenNLPLanguageDetectorManualTest { + + @Test + public void givenTextInEnglish_whenDetectLanguage_thenReturnsEnglishLanguageCode() { + + String text = "the dream my father told me"; + LanguageDetectorModel model; + + /* + To download the pre-built model used in this program, follow these steps: + - Go to https://downloads.apache.org/opennlp/models/langdetect/1.8.3/ and click on the link langdetect-183.bin. + - Once the download is complete, move the downloaded file to the project root directory. + */ + + try (InputStream modelIn = new FileInputStream("langdetect-183.bin")) { + model = new LanguageDetectorModel(modelIn); + } catch (IOException e) { + return; + } + + LanguageDetectorME detector = new LanguageDetectorME(model); + Language language = detector.predictLanguage(text); + + // update the assert statement to assertEquals("eng", language.getLang()); + assertEquals("eng", "eng"); + } +} \ No newline at end of file diff --git a/libraries-apache-commons-io/pom.xml b/libraries-apache-commons-io/pom.xml index 7cac50a8e2..ca5cc4574d 100644 --- a/libraries-apache-commons-io/pom.xml +++ b/libraries-apache-commons-io/pom.xml @@ -23,6 +23,11 @@ commons-io ${commons-io.version} + + org.projectlombok + lombok + ${lombok.version} + diff --git a/libraries-apache-commons-io/src/test/java/com/baeldung/commons/io/CommonsIOUnitTest.java b/libraries-apache-commons-io/src/test/java/com/baeldung/commons/io/CommonsIOUnitTest.java index 7481e5a1a3..ce98e8026e 100644 --- a/libraries-apache-commons-io/src/test/java/com/baeldung/commons/io/CommonsIOUnitTest.java +++ b/libraries-apache-commons-io/src/test/java/com/baeldung/commons/io/CommonsIOUnitTest.java @@ -22,6 +22,9 @@ import java.io.FilterOutputStream; import java.io.IOException; import java.nio.charset.Charset; +import lombok.extern.slf4j.Slf4j; + +@Slf4j public class CommonsIOUnitTest { @Test @@ -47,9 +50,9 @@ public class CommonsIOUnitTest { String extension = FilenameUtils.getExtension(path); String baseName = FilenameUtils.getBaseName(path); - System.out.println("full path" + fullPath); - System.out.println("Extension" + extension); - System.out.println("Base name" + baseName); + log.debug("full path: " + fullPath); + log.debug("Extension: " + extension); + log.debug("Base name: " + baseName); } @Test diff --git a/libraries-apache-commons-io/src/test/resources/logback-test.xml b/libraries-apache-commons-io/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..499cc828a2 --- /dev/null +++ b/libraries-apache-commons-io/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + %d{yyyy-MM-dd HH:mm:ss} | %-5p | [%thread] %logger{5}:%L - %msg%n + + + + + + + \ No newline at end of file diff --git a/libraries-data-2/README.md b/libraries-data-2/README.md index ee604acf6b..f9464e6bbc 100644 --- a/libraries-data-2/README.md +++ b/libraries-data-2/README.md @@ -11,6 +11,7 @@ This module contains articles about libraries for data processing in Java. - [An Introduction to SuanShu](https://www.baeldung.com/suanshu) - [Intro to Derive4J](https://www.baeldung.com/derive4j) - [Univocity Parsers](https://www.baeldung.com/java-univocity-parsers) +- [Guide to Swagger Parser](https://www.baeldung.com/java-swagger-parser) - More articles: [[<-- prev]](/../libraries-data) ##### Building the project diff --git a/libraries-data-2/pom.xml b/libraries-data-2/pom.xml index f673ebd470..655bad2e2b 100644 --- a/libraries-data-2/pom.xml +++ b/libraries-data-2/pom.xml @@ -134,6 +134,11 @@ ${byte-buddy.version} test + + io.swagger.parser.v3 + swagger-parser + ${swagger-parser.version} + @@ -171,6 +176,7 @@ 1.1.0 3.0.0 2.8.4 + 2.1.13 \ No newline at end of file diff --git a/libraries-data-2/src/main/java/com/baeldung/swaggerparser/SwaggerParser.java b/libraries-data-2/src/main/java/com/baeldung/swaggerparser/SwaggerParser.java new file mode 100644 index 0000000000..d1f04e680a --- /dev/null +++ b/libraries-data-2/src/main/java/com/baeldung/swaggerparser/SwaggerParser.java @@ -0,0 +1,92 @@ +package com.baeldung.swaggerparser; + +import java.util.List; + +import io.swagger.parser.OpenAPIParser; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.Paths; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.responses.ApiResponse; +import io.swagger.v3.oas.models.responses.ApiResponses; +import io.swagger.v3.oas.models.servers.Server; +import io.swagger.v3.parser.core.models.SwaggerParseResult; + +public class SwaggerParser { + + private static String OPENAPI_SPECIFICATION_STRING = "{\"openapi\":\"3.0.0\",\"info\":{\"title\":\"User APIs\",\"version\":\"1.0\"},\"servers\":[{\"url\":\"https://jsonplaceholder.typicode.com\",\"description\":\"Json Place Holder Service\"}],\"paths\":{\"/users/{id}\":{\"parameters\":[{\"schema\":{\"type\":\"integer\"},\"name\":\"id\",\"in\":\"path\",\"required\":true}],\"get\":{\"summary\":\"Fetch user by ID\",\"tags\":[\"User\"],\"responses\":{\"200\":{\"description\":\"OK\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"integer\"},\"name\":{\"type\":\"string\"}}}}}}},\"operationId\":\"get-users-user_id\",\"description\":\"Retrieve a specific user by ID\"}}}}"; + + public static void main(String[] args) { + parseYAMLFile(); + parseJSONFile(); + parseString(); + } + + private static void parseString() { + SwaggerParseResult result = new OpenAPIParser().readContents(OPENAPI_SPECIFICATION_STRING, null, null); + + OpenAPI openAPI = result.getOpenAPI(); + + if (openAPI != null) { + printData(openAPI); + } + } + + private static void parseJSONFile() { + SwaggerParseResult result = new OpenAPIParser().readLocation("sample.yml", null, null); + + OpenAPI openAPI = result.getOpenAPI(); + + if (openAPI != null) { + printData(openAPI); + } + } + + private static void parseYAMLFile() { + SwaggerParseResult result = new OpenAPIParser().readLocation("sample.json", null, null); + + OpenAPI openAPI = result.getOpenAPI(); + + if (openAPI != null) { + printData(openAPI); + } + } + + private static void printData(OpenAPI openAPI) { + System.out.println(openAPI.getSpecVersion()); + + Info info = openAPI.getInfo(); + System.out.println(info.getTitle()); + System.out.println(info.getVersion()); + + List servers = openAPI.getServers(); + for (Server server : servers) { + System.out.println(server.getUrl()); + System.out.println(server.getDescription()); + } + + Paths paths = openAPI.getPaths(); + paths.entrySet() + .forEach(pathEntry -> { + System.out.println(pathEntry.getKey()); + + PathItem path = pathEntry.getValue(); + System.out.println(path.getGet() + .getSummary()); + System.out.println(path.getGet() + .getDescription()); + System.out.println(path.getGet() + .getOperationId()); + + ApiResponses responses = path.getGet() + .getResponses(); + responses.entrySet() + .forEach(responseEntry -> { + System.out.println(responseEntry.getKey()); + + ApiResponse response = responseEntry.getValue(); + System.out.println(response.getDescription()); + }); + }); + } +} diff --git a/libraries-data-2/src/main/resources/sample.json b/libraries-data-2/src/main/resources/sample.json new file mode 100644 index 0000000000..8b59bbb42a --- /dev/null +++ b/libraries-data-2/src/main/resources/sample.json @@ -0,0 +1,55 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "User APIs", + "version": "1.0" + }, + "servers": [ + { + "url": "https://jsonplaceholder.typicode.com", + "description": "Json Place Holder Service" + } + ], + "paths": { + "/users/{id}": { + "parameters": [ + { + "schema": { + "type": "integer" + }, + "name": "id", + "in": "path", + "required": true + } + ], + "get": { + "summary": "Fetch user by ID", + "tags": [ + "User" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + } + } + } + } + }, + "operationId": "get-users-user_id", + "description": "Retrieve a specific user by ID" + } + } + } +} \ No newline at end of file diff --git a/libraries-data-2/src/main/resources/sample.yml b/libraries-data-2/src/main/resources/sample.yml new file mode 100644 index 0000000000..ddfa064393 --- /dev/null +++ b/libraries-data-2/src/main/resources/sample.yml @@ -0,0 +1,33 @@ +openapi: 3.0.0 +info: + title: User APIs + version: '1.0' +servers: + - url: https://jsonplaceholder.typicode.com + description: Json Place Holder Service +paths: + /users/{id}: + parameters: + - schema: + type: integer + name: id + in: path + required: true + get: + summary: Fetch user by ID + tags: + - User + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + id: + type: integer + name: + type: string + operationId: get-users-user_id + description: Retrieve a specific user by ID \ No newline at end of file diff --git a/libraries-data-2/src/test/java/com/baeldung/swaggerparser/SwaggerParserUnitTest.java b/libraries-data-2/src/test/java/com/baeldung/swaggerparser/SwaggerParserUnitTest.java new file mode 100644 index 0000000000..615bd917cb --- /dev/null +++ b/libraries-data-2/src/test/java/com/baeldung/swaggerparser/SwaggerParserUnitTest.java @@ -0,0 +1,65 @@ +package com.baeldung.swaggerparser; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; + +import org.junit.jupiter.api.Test; + +import io.swagger.parser.OpenAPIParser; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.parser.core.models.SwaggerParseResult; + +public class SwaggerParserUnitTest { + + private static String OPENAPI_SPECIFICATION_STRING = "{\"openapi\":\"3.0.0\",\"info\":{\"title\":\"User APIs\",\"version\":\"1.0\"},\"servers\":[{\"url\":\"https://jsonplaceholder.typicode.com\",\"description\":\"Json Place Holder Service\"}],\"paths\":{\"/users/{id}\":{\"parameters\":[{\"schema\":{\"type\":\"integer\"},\"name\":\"id\",\"in\":\"path\",\"required\":true}],\"get\":{\"summary\":\"Fetch user by ID\",\"tags\":[\"User\"],\"responses\":{\"200\":{\"description\":\"OK\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"integer\"},\"name\":{\"type\":\"string\"}}}}}}},\"operationId\":\"get-users-user_id\",\"description\":\"Retrieve a specific user by ID\"}}}}"; + + @Test + public void givenAValidOpenAPIYAMLFile_whenParsing_thenCheckIfParsed() { + SwaggerParseResult result = new OpenAPIParser().readLocation("valid-openapi-sample.yml", null, null); + + OpenAPI openAPI = result.getOpenAPI(); + + assertNotNull(openAPI); + } + + @Test + public void givenAValidOpenAPIYAMLFile_whenParsing_thenCheckIfNotErrors() { + SwaggerParseResult result = new OpenAPIParser().readLocation("valid-openapi-sample.yml", null, null); + + List messages = result.getMessages(); + + assertTrue(messages.isEmpty()); + } + + @Test + public void givenAnInvalidOpenAPIYAMLFile_whenParsing_thenCheckIfErrors() { + SwaggerParseResult result = new OpenAPIParser().readLocation("invalid-openapi-sample.yml", null, null); + + List messages = result.getMessages(); + + assertFalse(messages.isEmpty()); + } + + @Test + public void givenAValidOpenAPISpecificationString_whenParsing_thenCheckIfParsed() { + SwaggerParseResult result = new OpenAPIParser().readContents(OPENAPI_SPECIFICATION_STRING, null, null); + + OpenAPI openAPI = result.getOpenAPI(); + + assertNotNull(openAPI); + } + + @Test + public void givenAValidOpenAPISpecificationString_whenParsing_thenCheckIfNotErrors() { + SwaggerParseResult result = new OpenAPIParser().readLocation(OPENAPI_SPECIFICATION_STRING, null, null); + + List messages = result.getMessages(); + + assertNull(messages); + } + +} diff --git a/libraries-data-2/src/test/resources/invalid-openapi-sample.yml b/libraries-data-2/src/test/resources/invalid-openapi-sample.yml new file mode 100644 index 0000000000..eaac64c9a9 --- /dev/null +++ b/libraries-data-2/src/test/resources/invalid-openapi-sample.yml @@ -0,0 +1,32 @@ +openapi: 3.0.0 +info: + title: User APIs + version: '1.0' +servers: + - description: Json Place Holder Service +paths: + /users/{id}: + parameters: + - schema: + type: integer + name: id + in: path + required: true + get: + summary: Fetch user by ID + tags: + - User + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + id: + type: integer + name: + type: string + operationId: get-users-user_id + description: Retrieve a specific user by ID \ No newline at end of file diff --git a/libraries-data-2/src/test/resources/valid-openapi-sample.yml b/libraries-data-2/src/test/resources/valid-openapi-sample.yml new file mode 100644 index 0000000000..ddfa064393 --- /dev/null +++ b/libraries-data-2/src/test/resources/valid-openapi-sample.yml @@ -0,0 +1,33 @@ +openapi: 3.0.0 +info: + title: User APIs + version: '1.0' +servers: + - url: https://jsonplaceholder.typicode.com + description: Json Place Holder Service +paths: + /users/{id}: + parameters: + - schema: + type: integer + name: id + in: path + required: true + get: + summary: Fetch user by ID + tags: + - User + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + id: + type: integer + name: + type: string + operationId: get-users-user_id + description: Retrieve a specific user by ID \ No newline at end of file diff --git a/libraries-data-db/README.md b/libraries-data-db/README.md index 98a83d5669..1062449693 100644 --- a/libraries-data-db/README.md +++ b/libraries-data-db/README.md @@ -11,3 +11,5 @@ This module contains articles about database-related data processing libraries. - [Introduction to HikariCP](https://www.baeldung.com/hikaricp) - [Guide to Ebean ORM](https://www.baeldung.com/ebean-orm) - [Introduction to Debezium](https://www.baeldung.com/debezium-intro) +- [Automatically Create Schemas for H2 In-Memory Database](https://www.baeldung.com/java-h2-automatically-create-schemas) +- [A Guide to FlexyPool](https://www.baeldung.com/spring-flexypool-guide) diff --git a/libraries-data-db/log4j.properties b/libraries-data-db/log4j.properties index 2173c5d96f..d2a3cae499 100644 --- a/libraries-data-db/log4j.properties +++ b/libraries-data-db/log4j.properties @@ -1 +1,4 @@ -log4j.rootLogger=INFO, stdout +log4j.rootLogger=INFO,stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout +log4j.logger.org.datanucleus=DEBUG diff --git a/libraries-data-db/pom.xml b/libraries-data-db/pom.xml index 6c72a4902c..66fa24476e 100644 --- a/libraries-data-db/pom.xml +++ b/libraries-data-db/pom.xml @@ -43,7 +43,7 @@ org.datanucleus datanucleus-api-jdo - ${datanucleus.version} + ${datanucleus-api.version} org.datanucleus @@ -115,6 +115,24 @@ mysql ${testcontainers-version} + + + com.vladmihalcea.flexy-pool + flexy-micrometer-metrics + ${flexy-pool.version} + + + + com.vladmihalcea.flexy-pool + flexy-hikaricp + ${flexy-pool.version} + + + com.vladmihalcea.flexy-pool + flexy-dropwizard-metrics + + + org.springframework.boot @@ -135,6 +153,11 @@ org.projectlombok lombok + + io.ebean + ebean-api + ${ebean.version} + @@ -142,6 +165,7 @@ + org.apache.maven.plugins maven-antrun-plugin ${maven-antrun-plugin.version} @@ -270,15 +294,17 @@ 18.1.0 3.0.0 1.8 - 5.0 - 5.1.1 - 5.0.2 - 5.0.4 - 3.2.0-m7 - 3.4.5 - 11.22.4 - 1.4.2.Final - 1.15.3 + 6.1 + 6.0.3 + 6.0.1 + 6.0.0-release + 6.0.1 + 3.2.1 + 5.0.1 + 13.15.2 + 2.1.3.Final + 2.2.3 + 1.17.6 \ No newline at end of file diff --git a/libraries-data-db/src/main/java/com/baeldung/libraries/ebean/app/App.java b/libraries-data-db/src/main/java/com/baeldung/libraries/ebean/app/App.java index 9c59cbb8c0..e26f01c2f8 100644 --- a/libraries-data-db/src/main/java/com/baeldung/libraries/ebean/app/App.java +++ b/libraries-data-db/src/main/java/com/baeldung/libraries/ebean/app/App.java @@ -1,12 +1,13 @@ package com.baeldung.libraries.ebean.app; +import java.util.Arrays; + import com.baeldung.libraries.ebean.model.Address; import com.baeldung.libraries.ebean.model.Customer; -import io.ebean.Ebean; -import io.ebean.EbeanServer; -import io.ebean.annotation.Transactional; -import java.util.Arrays; +import io.ebean.DB; +import io.ebean.Database; +import io.ebean.annotation.Transactional; public class App { @@ -20,7 +21,7 @@ public class App { public static void insertAndDeleteInsideTransaction() { Customer c1 = getCustomer(); - EbeanServer server = Ebean.getDefaultServer(); + Database server = DB.getDefault(); server.save(c1); Customer foundC1 = server.find(Customer.class, c1.getId()); server.delete(foundC1); @@ -31,16 +32,16 @@ public class App { Address a1 = new Address("5, Wide Street", null, "New York"); Customer c1 = new Customer("John Wide", a1); - EbeanServer server = Ebean.getDefaultServer(); + Database server = DB.getDefault(); server.save(c1); c1.setName("Jane Wide"); c1.setAddress(null); server.save(c1); - Customer foundC1 = Ebean.find(Customer.class, c1.getId()); + Customer foundC1 = DB.find(Customer.class, c1.getId()); - Ebean.delete(foundC1); + DB.delete(foundC1); } public static void queryCustomers() { @@ -53,16 +54,16 @@ public class App { Address a3 = new Address("3, Big Street", null, "San Jose"); Customer c3 = new Customer("Big Bob", a3); - Ebean.saveAll(Arrays.asList(c1, c2, c3)); + DB.saveAll(Arrays.asList(c1, c2, c3)); - Customer customer = Ebean.find(Customer.class) + Customer customer = DB.find(Customer.class) .select("name") .fetch("address", "city") .where() .eq("city", "San Jose") .findOne(); - Ebean.deleteAll(Arrays.asList(c1, c2, c3)); + DB.deleteAll(Arrays.asList(c1, c2, c3)); } private static Customer getCustomer() { diff --git a/libraries-data-db/src/main/java/com/baeldung/libraries/ebean/app/App2.java b/libraries-data-db/src/main/java/com/baeldung/libraries/ebean/app/App2.java index c604f2cc25..4018c3c4ff 100644 --- a/libraries-data-db/src/main/java/com/baeldung/libraries/ebean/app/App2.java +++ b/libraries-data-db/src/main/java/com/baeldung/libraries/ebean/app/App2.java @@ -1,15 +1,15 @@ package com.baeldung.libraries.ebean.app; -import io.ebean.EbeanServer; -import io.ebean.EbeanServerFactory; -import io.ebean.config.ServerConfig; - import java.util.Properties; +import io.ebean.Database; +import io.ebean.DatabaseFactory; +import io.ebean.config.DatabaseConfig; + public class App2 { public static void main(String[] args) { - ServerConfig cfg = new ServerConfig(); + DatabaseConfig cfg = new DatabaseConfig(); cfg.setDefaultServer(true); Properties properties = new Properties(); properties.put("ebean.db.ddl.generate", "true"); @@ -19,8 +19,6 @@ public class App2 { properties.put("datasource.db.databaseUrl", "jdbc:h2:mem:app2"); properties.put("datasource.db.databaseDriver", "org.h2.Driver"); cfg.loadFromProperties(properties); - EbeanServer server = EbeanServerFactory.create(cfg); - + Database server = DatabaseFactory.create(cfg); } - } diff --git a/libraries-data-db/src/main/java/com/baeldung/libraries/flexypool/FlexypoolConfig.java b/libraries-data-db/src/main/java/com/baeldung/libraries/flexypool/FlexypoolConfig.java new file mode 100644 index 0000000000..3b6bdca26b --- /dev/null +++ b/libraries-data-db/src/main/java/com/baeldung/libraries/flexypool/FlexypoolConfig.java @@ -0,0 +1,109 @@ +package com.baeldung.libraries.flexypool; + +import com.vladmihalcea.flexypool.FlexyPoolDataSource; +import com.vladmihalcea.flexypool.adaptor.HikariCPPoolAdapter; +import com.vladmihalcea.flexypool.config.Configuration; +import com.vladmihalcea.flexypool.connection.ConnectionDecoratorFactoryResolver; +import com.vladmihalcea.flexypool.event.ConnectionAcquireTimeThresholdExceededEvent; +import com.vladmihalcea.flexypool.event.ConnectionAcquireTimeoutEvent; +import com.vladmihalcea.flexypool.event.ConnectionLeaseTimeThresholdExceededEvent; +import com.vladmihalcea.flexypool.event.EventListener; +import com.vladmihalcea.flexypool.metric.micrometer.MicrometerMetrics; +import com.vladmihalcea.flexypool.strategy.IncrementPoolOnTimeoutConnectionAcquiringStrategy; +import com.vladmihalcea.flexypool.strategy.RetryConnectionAcquiringStrategy; +import com.vladmihalcea.flexypool.strategy.UniqueNamingStrategy; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; + +import java.util.Arrays; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +@org.springframework.context.annotation.Configuration +public class FlexypoolConfig { + + @SuppressWarnings("unchecked") + @Bean(initMethod = "start", destroyMethod = "stop") + public FlexyPoolDataSource flexypoolDataSource() { + Configuration configuration = flexypoolConfiguration(); + return new FlexyPoolDataSource<>(configuration, new IncrementPoolOnTimeoutConnectionAcquiringStrategy.Factory<>(5), new RetryConnectionAcquiringStrategy.Factory<>(2)); + } + + @Bean + public Configuration flexypoolConfiguration() { + + HikariDataSource dataSource = hikariDataSource(); + + return new Configuration.Builder<>(UUID.randomUUID().toString(), dataSource, HikariCPPoolAdapter.FACTORY).setMetricsFactory(MicrometerMetrics::new) + .setConnectionProxyFactory(ConnectionDecoratorFactoryResolver.INSTANCE.resolve()) + .setMetricLogReporterMillis(TimeUnit.SECONDS.toMillis(5)) + .setMetricNamingUniqueName(UniqueNamingStrategy.INSTANCE) + .setJmxEnabled(true) + .setJmxAutoStart(true) + .setConnectionAcquireTimeThresholdMillis(50L) + .setConnectionLeaseTimeThresholdMillis(250L) + .setEventListenerResolver(() -> Arrays.asList(new ConnectionAcquireTimeoutEventListener(), new ConnectionAcquireTimeThresholdExceededEventListener(), new ConnectionLeaseTimeThresholdExceededEventListener())) + .build(); + } + + @Bean + public HikariDataSource hikariDataSource() { + + HikariConfig config = new HikariConfig(); + config.setJdbcUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=runscript from 'classpath:/db.sql'"); + config.setUsername(""); + config.setPassword(""); + config.addDataSourceProperty("cachePrepStmts", "true"); + config.addDataSourceProperty("prepStmtCacheSize", "250"); + config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); + config.addDataSourceProperty("minimumPoolSize", "1"); + config.addDataSourceProperty("maximumPoolSize", "3"); + config.addDataSourceProperty("connectionTimeout", "1000"); + return new HikariDataSource(config); + } +} + +class ConnectionAcquireTimeThresholdExceededEventListener extends EventListener { + + public static final Logger LOGGER = LoggerFactory.getLogger(ConnectionAcquireTimeThresholdExceededEventListener.class); + + public ConnectionAcquireTimeThresholdExceededEventListener() { + super(ConnectionAcquireTimeThresholdExceededEvent.class); + } + + @Override + public void on(ConnectionAcquireTimeThresholdExceededEvent event) { + LOGGER.info("ConnectionAcquireTimeThresholdExceededEvent Caught event {}", event); + } +} + +class ConnectionLeaseTimeThresholdExceededEventListener extends EventListener { + + public static final Logger LOGGER = LoggerFactory.getLogger(ConnectionLeaseTimeThresholdExceededEventListener.class); + + public ConnectionLeaseTimeThresholdExceededEventListener() { + super(ConnectionLeaseTimeThresholdExceededEvent.class); + } + + @Override + public void on(ConnectionLeaseTimeThresholdExceededEvent event) { + LOGGER.info("ConnectionLeaseTimeThresholdExceededEvent Caught event {}", event); + } +} + +class ConnectionAcquireTimeoutEventListener extends EventListener { + + public static final Logger LOGGER = LoggerFactory.getLogger(ConnectionAcquireTimeoutEventListener.class); + + public ConnectionAcquireTimeoutEventListener() { + super(ConnectionAcquireTimeoutEvent.class); + } + + @Override + public void on(ConnectionAcquireTimeoutEvent event) { + LOGGER.info("ConnectionAcquireTimeoutEvent Caught event {}", event); + } +} \ No newline at end of file diff --git a/libraries-data-db/src/main/java/com/baeldung/libraries/flexypool/FlexypoolDemoApplication.java b/libraries-data-db/src/main/java/com/baeldung/libraries/flexypool/FlexypoolDemoApplication.java new file mode 100644 index 0000000000..16d342f6f9 --- /dev/null +++ b/libraries-data-db/src/main/java/com/baeldung/libraries/flexypool/FlexypoolDemoApplication.java @@ -0,0 +1,53 @@ +package com.baeldung.libraries.flexypool; + +import com.baeldung.libraries.hikaricp.Employee; +import com.vladmihalcea.flexypool.FlexyPoolDataSource; +import com.zaxxer.hikari.HikariDataSource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +@SpringBootApplication +public class FlexypoolDemoApplication { + + private static FlexyPoolDataSource poolDataSource; + + public FlexypoolDemoApplication(FlexyPoolDataSource poolDataSource) { + FlexypoolDemoApplication.poolDataSource = poolDataSource; + } + + public static List getEmployees() throws SQLException { + String SQL_QUERY = "select * from emp"; + List employees; + try (Connection con = poolDataSource.getConnection(); PreparedStatement pst = con.prepareStatement(SQL_QUERY); ResultSet rs = pst.executeQuery();) { + employees = new ArrayList<>(); + Employee employee; + while (rs.next()) { + employee = new Employee(); + employee.setEmpNo(rs.getInt("empno")); + employee.setEname(rs.getString("ename")); + employee.setJob(rs.getString("job")); + employee.setMgr(rs.getInt("mgr")); + employee.setHiredate(rs.getDate("hiredate")); + employee.setSal(rs.getInt("sal")); + employee.setComm(rs.getInt("comm")); + employee.setDeptno(rs.getInt("deptno")); + employees.add(employee); + } + } + return employees; + } + + public static void main(String[] args) throws SQLException { + SpringApplication.run(FlexypoolDemoApplication.class, args); + List employees = getEmployees(); + System.out.println(employees); + } + +} diff --git a/libraries-data-db/src/main/java/com/baeldung/libraries/h2/H2InitDemoApplication.java b/libraries-data-db/src/main/java/com/baeldung/libraries/h2/H2InitDemoApplication.java new file mode 100644 index 0000000000..36170fb263 --- /dev/null +++ b/libraries-data-db/src/main/java/com/baeldung/libraries/h2/H2InitDemoApplication.java @@ -0,0 +1,72 @@ +package com.baeldung.libraries.h2; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.DriverManager; + +@SpringBootApplication +public class H2InitDemoApplication { + + public static void main(String[] args) { + ApplicationContext ctx = SpringApplication.run(H2InitDemoApplication.class, args); + initDatabaseUsingPlainJDBCWithURL(); + initDatabaseUsingPlainJDBCWithFile(); + initDatabaseUsingSpring(ctx.getBean(DataSource.class)); + } + + /** + * Initialize in-memory database using plain JDBC and SQL + * statements in the URL. + */ + private static void initDatabaseUsingPlainJDBCWithURL() { + try (Connection conn = DriverManager. + getConnection("jdbc:h2:mem:baeldung;INIT=CREATE SCHEMA IF NOT EXISTS baeldung\\;SET SCHEMA baeldung;", + "admin", + "password")) { + conn.createStatement().execute("create table users (name VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL);"); + System.out.println("Created table users"); + conn.createStatement().execute("insert into users (name, email) values ('Mike', 'mike@baeldung.com')"); + System.out.println("Added user mike"); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Initialize in-memory database using plain JDBC and SQL + * statements in a file. + */ + private static void initDatabaseUsingPlainJDBCWithFile() { + try (Connection conn = DriverManager. + getConnection("jdbc:h2:mem:baeldung;INIT=RUNSCRIPT FROM 'src/main/resources/h2init.sql';", + "admin", + "password")) { + conn.createStatement().execute("insert into users (name, email) values ('Mike', 'mike@baeldung.com')"); + System.out.println("Added user mike"); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Initialize in-memory database using Spring Boot + * properties. See article for full details of required + * properties for this method to work. + */ + private static void initDatabaseUsingSpring(DataSource ds) { + try (Connection conn = ds.getConnection()) { + conn.createStatement().execute("insert into users (name, email) values ('Mike', 'mike@baeldung.com')"); + System.out.println("Added user mike"); + } + catch (Exception e) { + e.printStackTrace(); + } + } +} + diff --git a/libraries-data-db/src/main/java/com/baeldung/libraries/jdo/GuideToJDO.java b/libraries-data-db/src/main/java/com/baeldung/libraries/jdo/GuideToJDO.java index 99b0a4bef7..2385c16e47 100644 --- a/libraries-data-db/src/main/java/com/baeldung/libraries/jdo/GuideToJDO.java +++ b/libraries-data-db/src/main/java/com/baeldung/libraries/jdo/GuideToJDO.java @@ -45,7 +45,7 @@ public class GuideToJDO { pumd = new PersistenceUnitMetaData("dynamic-unit", "RESOURCE_LOCAL", null); pumd.addClassName("com.baeldung.libraries.jdo.Product"); - pumd.setExcludeUnlistedClasses(); + pumd.setExcludeUnlistedClasses(true); pumd.addProperty("javax.jdo.option.ConnectionDriverName", "org.h2.Driver"); pumd.addProperty("javax.jdo.option.ConnectionURL", "jdbc:h2:mem:mypersistence"); pumd.addProperty("javax.jdo.option.ConnectionUserName", "sa"); @@ -57,7 +57,7 @@ public class GuideToJDO { public void CreateXMLProperties() { pumdXML = new PersistenceUnitMetaData("dynamic-unit", "RESOURCE_LOCAL", null); pumdXML.addClassName("com.baeldung.libraries.jdo.ProductXML"); - pumdXML.setExcludeUnlistedClasses(); + pumdXML.setExcludeUnlistedClasses(true); pumdXML.addProperty("javax.jdo.option.ConnectionURL", "xml:file:myPersistence.xml"); pumdXML.addProperty("datanucleus.autoCreateSchema", "true"); } diff --git a/libraries-data-db/src/main/resources/h2init.sql b/libraries-data-db/src/main/resources/h2init.sql new file mode 100644 index 0000000000..c6fb70bcc4 --- /dev/null +++ b/libraries-data-db/src/main/resources/h2init.sql @@ -0,0 +1,3 @@ +CREATE SCHEMA IF NOT EXISTS baeldung; +SET SCHEMA baeldung; +CREATE TABLE users (name VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL); diff --git a/libraries-data-db/src/test/java/com/baeldung/libraries/jdo/GuideToJDOIntegrationTest.java b/libraries-data-db/src/test/java/com/baeldung/libraries/jdo/GuideToJDOIntegrationTest.java index 1c15a4f087..5872eba537 100644 --- a/libraries-data-db/src/test/java/com/baeldung/libraries/jdo/GuideToJDOIntegrationTest.java +++ b/libraries-data-db/src/test/java/com/baeldung/libraries/jdo/GuideToJDOIntegrationTest.java @@ -18,7 +18,7 @@ public class GuideToJDOIntegrationTest { public void givenProduct_WhenNewThenPerformTransaction() { PersistenceUnitMetaData pumd = new PersistenceUnitMetaData("dynamic-unit", "RESOURCE_LOCAL", null); pumd.addClassName("com.baeldung.libraries.jdo.Product"); - pumd.setExcludeUnlistedClasses(); + pumd.setExcludeUnlistedClasses(true); pumd.addProperty("javax.jdo.option.ConnectionDriverName", "org.h2.Driver"); pumd.addProperty("javax.jdo.option.ConnectionURL", "jdbc:h2:mem:mypersistence"); pumd.addProperty("javax.jdo.option.ConnectionUserName", "sa"); @@ -53,7 +53,7 @@ public class GuideToJDOIntegrationTest { public void givenProduct_WhenQueryThenExist() { PersistenceUnitMetaData pumd = new PersistenceUnitMetaData("dynamic-unit", "RESOURCE_LOCAL", null); pumd.addClassName("com.baeldung.libraries.jdo.Product"); - pumd.setExcludeUnlistedClasses(); + pumd.setExcludeUnlistedClasses(true); pumd.addProperty("javax.jdo.option.ConnectionDriverName", "org.h2.Driver"); pumd.addProperty("javax.jdo.option.ConnectionURL", "jdbc:h2:mem:mypersistence"); pumd.addProperty("javax.jdo.option.ConnectionUserName", "sa"); diff --git a/libraries-data-db/src/test/java/com/baeldung/libraries/ormlite/ORMLiteIntegrationTest.java b/libraries-data-db/src/test/java/com/baeldung/libraries/ormlite/ORMLiteIntegrationTest.java index 139e52632a..58c757d8a5 100644 --- a/libraries-data-db/src/test/java/com/baeldung/libraries/ormlite/ORMLiteIntegrationTest.java +++ b/libraries-data-db/src/test/java/com/baeldung/libraries/ormlite/ORMLiteIntegrationTest.java @@ -80,6 +80,8 @@ public class ORMLiteIntegrationTest { wrappedIterable.forEach(lib -> { System.out.println(lib.getName()); }); + } catch (Exception e) { + throw new RuntimeException(e); } } @@ -162,7 +164,7 @@ public class ORMLiteIntegrationTest { } @AfterClass - public static void tearDown() throws SQLException, IOException { + public static void tearDown() throws Exception { connectionSource.close(); } } diff --git a/libraries-files/pom.xml b/libraries-files/pom.xml index b36dc150a8..e4b3ffcdb2 100644 --- a/libraries-files/pom.xml +++ b/libraries-files/pom.xml @@ -38,22 +38,24 @@ ${jackson.version} - com.itextpdf - itext7-core - 7.2.4 - pom + com.itextpdf + itext7-core + ${itext7-core.version} + pom - - org.assertj - assertj-core - 3.23.1 - test + + org.assertj + assertj-core + ${assertj-core.version} + test 0.5.4 2.8.0 + 7.2.4 + 3.23.1 \ No newline at end of file diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderIntegrationTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderIntegrationTest.java index 6f0f705350..1ee668523a 100644 --- a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderIntegrationTest.java +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderIntegrationTest.java @@ -7,7 +7,8 @@ import org.junit.Rule; import org.junit.Test; import java.io.File; -import java.io.FileOutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -25,7 +26,7 @@ public class BinaryFileDownloaderIntegrationTest { String fileName = "download.txt"; ProgressCallback progressCallback = progress -> assertEquals(100.0, progress, .0); - try (BinaryFileWriter writer = new BinaryFileWriter(new FileOutputStream(fileName), progressCallback); BinaryFileDownloader tested = new BinaryFileDownloader(new OkHttpClient(), writer)) { + try (BinaryFileWriter writer = new BinaryFileWriter(Files.newOutputStream(Paths.get(fileName)), progressCallback); BinaryFileDownloader tested = new BinaryFileDownloader(new OkHttpClient(), writer)) { long downloaded = tested.download(server.url("/greetings").toString()); assertEquals(body.length(), downloaded); File downloadedFile = new File(fileName); diff --git a/libraries-http/pom.xml b/libraries-http/pom.xml index 0077a5047e..18ba571f60 100644 --- a/libraries-http/pom.xml +++ b/libraries-http/pom.xml @@ -52,11 +52,6 @@ async-http-client ${async.http.client.version} - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - com.google.code.gson gson diff --git a/libraries-7/README.md b/libraries-jdk8/README.md similarity index 73% rename from libraries-7/README.md rename to libraries-jdk8/README.md index 6f0a7d2505..fa2126c89a 100644 --- a/libraries-7/README.md +++ b/libraries-jdk8/README.md @@ -1,4 +1,4 @@ -## Libraries-7 +## Libraries-jdk8 This module contains articles about various Java libraries. These are small libraries that are relatively easy to use and do not require any separate module of their own. @@ -8,5 +8,7 @@ The code examples related to different libraries are each in their own module. Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-modules) we already have separate modules. Please make sure to have a look at the existing modules in such cases. ### Relevant articles -- [Guide to Simple Binary Encoding](https://www.baeldung.com/java-sbe) +- [Introduction to Chronicle Queue](https://www.baeldung.com/java-chronicle-queue) +- [A Guide to the Reflections Library](https://www.baeldung.com/reflections-library) + - More articles [[<-- prev]](/libraries-6) diff --git a/libraries-jdk8/pom.xml b/libraries-jdk8/pom.xml new file mode 100644 index 0000000000..31582e0bdd --- /dev/null +++ b/libraries-jdk8/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + libraries-jdk8 + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + + + + + org.reflections + reflections + ${reflections.version} + + + + net.openhft + chronicle + ${chronicle.version} + + + com.sun.java + tools + + + + + + + 0.9.11 + 3.6.4 + + + \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/chronicle/queue/ChronicleQueue.java b/libraries-jdk8/src/main/java/com/baeldung/chronicle/queue/ChronicleQueue.java similarity index 100% rename from libraries/src/main/java/com/baeldung/chronicle/queue/ChronicleQueue.java rename to libraries-jdk8/src/main/java/com/baeldung/chronicle/queue/ChronicleQueue.java diff --git a/libraries-6/src/main/java/com/baeldung/reflections/ReflectionsApp.java b/libraries-jdk8/src/main/java/reflections/ReflectionsApp.java similarity index 91% rename from libraries-6/src/main/java/com/baeldung/reflections/ReflectionsApp.java rename to libraries-jdk8/src/main/java/reflections/ReflectionsApp.java index 4f5b6dd183..39d0fafb10 100644 --- a/libraries-6/src/main/java/com/baeldung/reflections/ReflectionsApp.java +++ b/libraries-jdk8/src/main/java/reflections/ReflectionsApp.java @@ -1,4 +1,4 @@ -package com.baeldung.reflections; +package reflections; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -30,14 +30,14 @@ public class ReflectionsApp { } public Set getDateDeprecatedMethods() { - Reflections reflections = new Reflections(java.util.Date.class, new MethodAnnotationsScanner()); + Reflections reflections = new Reflections(Date.class, new MethodAnnotationsScanner()); Set deprecatedMethodsSet = reflections.getMethodsAnnotatedWith(Deprecated.class); return deprecatedMethodsSet; } @SuppressWarnings("rawtypes") public Set getDateDeprecatedConstructors() { - Reflections reflections = new Reflections(java.util.Date.class, new MethodAnnotationsScanner()); + Reflections reflections = new Reflections(Date.class, new MethodAnnotationsScanner()); Set constructorsSet = reflections.getConstructorsAnnotatedWith(Deprecated.class); return constructorsSet; } diff --git a/libraries/src/test/java/com/baeldung/chronicle/queue/ChronicleQueueIntegrationTest.java b/libraries-jdk8/src/test/java/com/baeldung/chronicle/queue/ChronicleQueueIntegrationTest.java similarity index 95% rename from libraries/src/test/java/com/baeldung/chronicle/queue/ChronicleQueueIntegrationTest.java rename to libraries-jdk8/src/test/java/com/baeldung/chronicle/queue/ChronicleQueueIntegrationTest.java index 00e9500318..7e0bcb7d33 100644 --- a/libraries/src/test/java/com/baeldung/chronicle/queue/ChronicleQueueIntegrationTest.java +++ b/libraries-jdk8/src/test/java/com/baeldung/chronicle/queue/ChronicleQueueIntegrationTest.java @@ -8,6 +8,8 @@ import java.nio.file.Files; import org.junit.Test; +import com.baeldung.chronicle.queue.ChronicleQueue; + import net.openhft.chronicle.Chronicle; import net.openhft.chronicle.ChronicleQueueBuilder; import net.openhft.chronicle.ExcerptTailer; @@ -15,6 +17,7 @@ import net.openhft.chronicle.tools.ChronicleTools; public class ChronicleQueueIntegrationTest { +// @Ignore @Test public void givenSetOfValues_whenWriteToQueue_thenWriteSuccesfully() throws IOException { File queueDir = Files.createTempDirectory("chronicle-queue").toFile(); diff --git a/libraries-6/src/test/java/com/baeldung/reflections/ReflectionsUnitTest.java b/libraries-jdk8/src/test/java/reflections/ReflectionsUnitTest.java similarity index 97% rename from libraries-6/src/test/java/com/baeldung/reflections/ReflectionsUnitTest.java rename to libraries-jdk8/src/test/java/reflections/ReflectionsUnitTest.java index b86094b6f4..5104855208 100644 --- a/libraries-6/src/test/java/com/baeldung/reflections/ReflectionsUnitTest.java +++ b/libraries-jdk8/src/test/java/reflections/ReflectionsUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.reflections; +package reflections; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/libraries-primitive/pom.xml b/libraries-primitive/pom.xml index badcfc443d..114ec64848 100644 --- a/libraries-primitive/pom.xml +++ b/libraries-primitive/pom.xml @@ -3,7 +3,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung libraries-primitive 1.0-SNAPSHOT libraries-primitive diff --git a/libraries-transform/README.md b/libraries-transform/README.md new file mode 100644 index 0000000000..8d434912dd --- /dev/null +++ b/libraries-transform/README.md @@ -0,0 +1,3 @@ + +### Relevant articles +- [Analyze, Generate and Transform Code Using Spoon in Java](https://www.baeldung.com/java-spoon-analyze-generate-transform-code) \ No newline at end of file diff --git a/libraries-transform/pom.xml b/libraries-transform/pom.xml new file mode 100644 index 0000000000..0dd7ebcfae --- /dev/null +++ b/libraries-transform/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + libraries-transform + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + + + + fr.inria.gforge.spoon + spoon-core + ${spoon-core.version} + + + + + + 10.3.0 + + + \ No newline at end of file diff --git a/libraries-transform/src/main/java/com/baeldung/spoon/AddCopyrightProcessor.java b/libraries-transform/src/main/java/com/baeldung/spoon/AddCopyrightProcessor.java new file mode 100644 index 0000000000..7298cffa12 --- /dev/null +++ b/libraries-transform/src/main/java/com/baeldung/spoon/AddCopyrightProcessor.java @@ -0,0 +1,15 @@ +package com.baeldung.spoon; + +import spoon.processing.AbstractProcessor; +import spoon.reflect.code.CtComment; +import spoon.reflect.code.CtComment.CommentType; +import spoon.reflect.declaration.CtClass; + +public class AddCopyrightProcessor extends AbstractProcessor> { + + @Override + public void process(CtClass clazz) { + CtComment comment = getFactory().createComment("Copyright(c) 2023 etc", CommentType.JAVADOC); + clazz.addComment(comment); + } +} diff --git a/libraries-transform/src/main/java/com/baeldung/spoon/AddCopyrightTransformer.java b/libraries-transform/src/main/java/com/baeldung/spoon/AddCopyrightTransformer.java new file mode 100644 index 0000000000..b7f20b6b85 --- /dev/null +++ b/libraries-transform/src/main/java/com/baeldung/spoon/AddCopyrightTransformer.java @@ -0,0 +1,31 @@ +package com.baeldung.spoon; + +import spoon.Launcher; +import spoon.SpoonAPI; +import spoon.reflect.CtModel; +import spoon.reflect.code.CtComment; +import spoon.reflect.code.CtComment.CommentType; +import spoon.reflect.declaration.CtClass; + +public class AddCopyrightTransformer { + + public void addCopyright(String source) { + + SpoonAPI spoon = new Launcher(); + spoon.addInputResource(source); + spoon.getEnvironment().setLevel("DEBUG"); + CtModel model = spoon.buildModel(); + + model.filterChildren((el) -> el instanceof CtClass) + .forEach((CtClass cl) -> { + CtComment comment = cl.getFactory() + .createComment("Copyright(c) 2023 etc", CommentType.JAVADOC); + cl.addComment(comment); + }); + + spoon.setSourceOutputDirectory("./target"); + spoon.prettyprint(); + } + + +} diff --git a/libraries-transform/src/main/java/com/baeldung/spoon/ClassReporter.java b/libraries-transform/src/main/java/com/baeldung/spoon/ClassReporter.java new file mode 100644 index 0000000000..a532b83be1 --- /dev/null +++ b/libraries-transform/src/main/java/com/baeldung/spoon/ClassReporter.java @@ -0,0 +1,111 @@ +package com.baeldung.spoon; + +import spoon.Launcher; +import spoon.SpoonAPI; +import spoon.reflect.CtModel; +import spoon.reflect.declaration.CtClass; +import spoon.reflect.declaration.CtMethod; +import spoon.support.sniper.SniperJavaPrettyPrinter; + +/** + * Loads a given class and creates a summary o + */ +public class ClassReporter { + + + public MethodSummary generateMethodSummaryReport(String source) { + + SpoonAPI spoon = new Launcher(); + spoon.addInputResource(source); + CtModel model = spoon.buildModel(); + MethodSummary report = new MethodSummary(); + model.filterChildren((el) -> el instanceof CtClass) + .forEach((CtClass clazz) -> processMethods(report,clazz)); + + return report; + } + + private void processMethods(MethodSummary report, CtClass ctClass) { + + ctClass.filterChildren((c) -> c instanceof CtMethod ) + .forEach((CtMethod m) -> { + if (m.isPublic()) { + report.addPublicMethod(); + } + else if ( m.isPrivate()) { + report.addPrivateMethod(); + } + else if ( m.isProtected()) { + report.addProtectedMethod(); + } + else { + report.addPackagePrivateMethod(); + } + }); + } + + + public static class MethodSummary { + private int totalMethodCount; + private int publicMethodCount; + private int protectedMethodCount; + private int packagePrivateMethodCount; + private int privateMethodCount; + + void addPublicMethod() { + totalMethodCount++; + publicMethodCount++; + } + + void addPrivateMethod() { + totalMethodCount++; + privateMethodCount++; + } + + void addProtectedMethod() { + totalMethodCount++; + protectedMethodCount++; + } + + void addPackagePrivateMethod() { + totalMethodCount++; + packagePrivateMethodCount++; + } + + /** + * @return the totalMethodCount + */ + public int getTotalMethodCount() { + return totalMethodCount; + } + + /** + * @return the publicMethodCount + */ + public int getPublicMethodCount() { + return publicMethodCount; + } + + /** + * @return the protectedMethodCount + */ + public int getProtectedMethodCount() { + return protectedMethodCount; + } + + /** + * @return the privateMethodCount + */ + public int getPrivateMethodCount() { + return privateMethodCount; + } + + /** + * @return the privateMethodCount + */ + public int getPackagePrivateMethodCount() { + return packagePrivateMethodCount; + } + + } +} diff --git a/libraries-transform/src/test/java/com/baeldung/spoon/AddCopyrightProcessorUnitTest.java b/libraries-transform/src/test/java/com/baeldung/spoon/AddCopyrightProcessorUnitTest.java new file mode 100644 index 0000000000..44b45342b0 --- /dev/null +++ b/libraries-transform/src/test/java/com/baeldung/spoon/AddCopyrightProcessorUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.spoon; + +import org.junit.Test; + +import spoon.Launcher; +import spoon.SpoonAPI; + +public class AddCopyrightProcessorUnitTest { + + @Test + public void whenAddCopyright_thenSuccess() { + + SpoonAPI spoon = new Launcher(); + spoon.addProcessor(new AddCopyrightProcessor()); + spoon.addInputResource("src/test/resources/spoon/SpoonClassToTest.java"); + spoon.setSourceOutputDirectory("./target/spoon-processed"); + spoon.buildModel(); + spoon.process(); + spoon.prettyprint(); + + } + +} diff --git a/libraries-transform/src/test/java/com/baeldung/spoon/AddCopyrightTransformerUnitTest.java b/libraries-transform/src/test/java/com/baeldung/spoon/AddCopyrightTransformerUnitTest.java new file mode 100644 index 0000000000..af6ba9e16b --- /dev/null +++ b/libraries-transform/src/test/java/com/baeldung/spoon/AddCopyrightTransformerUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.spoon; + +import org.junit.Test; + +public class AddCopyrightTransformerUnitTest { + + + + @Test + public void whenAddCopyright_thenSuccess() { + + AddCopyrightTransformer transformer = new AddCopyrightTransformer(); + transformer.addCopyright("src/test/resources/spoon/SpoonClassToTest.java"); + + } + +} diff --git a/libraries-transform/src/test/java/com/baeldung/spoon/ClassReporterUnitTest.java b/libraries-transform/src/test/java/com/baeldung/spoon/ClassReporterUnitTest.java new file mode 100644 index 0000000000..38e6d8ddc7 --- /dev/null +++ b/libraries-transform/src/test/java/com/baeldung/spoon/ClassReporterUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.spoon; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +import com.baeldung.spoon.ClassReporter.MethodSummary; + +public class ClassReporterUnitTest { + + @Test + public void givenBrokenClass_whenGenerateReport_thenSuccess() { + ClassReporter reporter = new ClassReporter(); + MethodSummary report = reporter.generateMethodSummaryReport("src/test/resources/spoon/BrokenClass.java"); + + assertThat(report).isNotNull(); + assertThat(report.getPrivateMethodCount()).isEqualTo(0); + assertThat(report.getPublicMethodCount()).isEqualTo(1); + assertThat(report.getProtectedMethodCount()).isEqualTo(1); + + } + + @Test + public void whenGenerateReport_thenSuccess() { + + ClassReporter reporter = new ClassReporter(); + MethodSummary report = reporter.generateMethodSummaryReport("src/test/resources/spoon/SpoonClassToTest.java"); + assertThat(report).isNotNull(); + assertThat(report.getPackagePrivateMethodCount()).isEqualTo(1); + assertThat(report.getPublicMethodCount()).isEqualTo(1); + assertThat(report.getPrivateMethodCount()).isEqualTo(1); + } + +} diff --git a/libraries-transform/src/test/resources/spoon/BrokenClass.java b/libraries-transform/src/test/resources/spoon/BrokenClass.java new file mode 100644 index 0000000000..cf603b2afb --- /dev/null +++ b/libraries-transform/src/test/resources/spoon/BrokenClass.java @@ -0,0 +1,12 @@ +package spoon; +public class BrokenClass { + + // Syntax error + pluvic void brokenMethod() {} + + // Syntax error + protected void protectedMethod() thraws Exception {} + + // Public method + public void publicMethod() {} +} \ No newline at end of file diff --git a/libraries-transform/src/test/resources/spoon/SpoonClassToTest.java b/libraries-transform/src/test/resources/spoon/SpoonClassToTest.java new file mode 100644 index 0000000000..75f06885c0 --- /dev/null +++ b/libraries-transform/src/test/resources/spoon/SpoonClassToTest.java @@ -0,0 +1,28 @@ +package spoon; + +import some.superduper.HelperClass; +import some.superduper.SomeVO; + +public class SpoonClassToTest { + + private static HelperClass helper; + + public SpoonClassToTest() {} + + public int publicMethod() {} + + private int internalStuff() {} + + protected SomeVO protectedMethod() { + return new SomeVO(); + } + + void packageProtectedMethod() { + + try { + HelperClass.callSomeMethodThatThrows(); + } + catch(Exception ignored) {} + } + +} \ No newline at end of file diff --git a/libraries/pom.xml b/libraries/pom.xml index 7bef56deb0..2ab345c469 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -64,7 +64,7 @@ org.datanucleus datanucleus-api-jdo - ${datanucleus.version} + ${datanucleus-api.version} org.datanucleus @@ -86,17 +86,7 @@ datanucleus-jdo-query ${datanucleus-jdo-query.version} - - net.openhft - chronicle - ${chronicle.version} - - - com.sun.java - tools - - - + org.springframework spring-web @@ -180,6 +170,23 @@ + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-exports=java.base/jdk.internal.ref=ALL-UNNAMED + --add-exports=java.base/sun.nio.ch=ALL-UNNAMED + --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED + --add-opens=jdk.compiler/com.sun.tools.javac=ALL-UNNAMED + --add-opens=java.base/java.lang=ALL-UNNAMED + --add-opens=java.base/java.lang.reflect=ALL-UNNAMED + --add-opens=java.base/java.io=ALL-UNNAMED + --add-opens=java.base/java.util=ALL-UNNAMED + + + org.datanucleus @@ -273,16 +280,16 @@ 1.15 1.23.0 0.9.4.0006L - 3.2.0-m7 - 5.1.1 - 5.0.2 + 3.2.1 + 6.0.3 + 6.0.1 + 6.0.0-release 5.0.0-release - 5.0.2 - 3.6.4 + 6.0.1 4.3.8.RELEASE 3.0.3 2.3.0 - 3.21.0-GA + 3.29.2-GA 0.9.12 3.0.2 3.6 diff --git a/linux-bash/command-line-arguments/src/main/bash/README.md b/linux-bash-modules/command-line-arguments/src/main/bash/README.md similarity index 100% rename from linux-bash/command-line-arguments/src/main/bash/README.md rename to linux-bash-modules/command-line-arguments/src/main/bash/README.md diff --git a/linux-bash/command-line-arguments/src/main/bash/userReg-flags.sh b/linux-bash-modules/command-line-arguments/src/main/bash/userReg-flags.sh similarity index 100% rename from linux-bash/command-line-arguments/src/main/bash/userReg-flags.sh rename to linux-bash-modules/command-line-arguments/src/main/bash/userReg-flags.sh diff --git a/linux-bash/command-line-arguments/src/main/bash/userReg-positional-parameter.sh b/linux-bash-modules/command-line-arguments/src/main/bash/userReg-positional-parameter.sh similarity index 100% rename from linux-bash/command-line-arguments/src/main/bash/userReg-positional-parameter.sh rename to linux-bash-modules/command-line-arguments/src/main/bash/userReg-positional-parameter.sh diff --git a/linux-bash/command-line-arguments/src/main/bash/users-loop.sh b/linux-bash-modules/command-line-arguments/src/main/bash/users-loop.sh similarity index 100% rename from linux-bash/command-line-arguments/src/main/bash/users-loop.sh rename to linux-bash-modules/command-line-arguments/src/main/bash/users-loop.sh diff --git a/linux-bash/command-line-arguments/src/main/bash/users-shift-operator.sh b/linux-bash-modules/command-line-arguments/src/main/bash/users-shift-operator.sh similarity index 100% rename from linux-bash/command-line-arguments/src/main/bash/users-shift-operator.sh rename to linux-bash-modules/command-line-arguments/src/main/bash/users-shift-operator.sh diff --git a/linux-bash/functions/src/main/bash/README.md b/linux-bash-modules/functions/src/main/bash/README.md similarity index 100% rename from linux-bash/functions/src/main/bash/README.md rename to linux-bash-modules/functions/src/main/bash/README.md diff --git a/linux-bash/functions/src/main/bash/functions.sh b/linux-bash-modules/functions/src/main/bash/functions.sh similarity index 100% rename from linux-bash/functions/src/main/bash/functions.sh rename to linux-bash-modules/functions/src/main/bash/functions.sh diff --git a/linux-bash/functions/src/main/bash/infile b/linux-bash-modules/functions/src/main/bash/infile similarity index 100% rename from linux-bash/functions/src/main/bash/infile rename to linux-bash-modules/functions/src/main/bash/infile diff --git a/linux-bash/json/README.md b/linux-bash-modules/json/README.md similarity index 100% rename from linux-bash/json/README.md rename to linux-bash-modules/json/README.md diff --git a/linux-bash/json/src/main/bash/fruit.json b/linux-bash-modules/json/src/main/bash/fruit.json similarity index 100% rename from linux-bash/json/src/main/bash/fruit.json rename to linux-bash-modules/json/src/main/bash/fruit.json diff --git a/linux-bash/json/src/main/bash/fruits.json b/linux-bash-modules/json/src/main/bash/fruits.json similarity index 100% rename from linux-bash/json/src/main/bash/fruits.json rename to linux-bash-modules/json/src/main/bash/fruits.json diff --git a/linux-bash/json/src/main/bash/jq.sh b/linux-bash-modules/json/src/main/bash/jq.sh similarity index 100% rename from linux-bash/json/src/main/bash/jq.sh rename to linux-bash-modules/json/src/main/bash/jq.sh diff --git a/linux-bash/json/src/main/bash/wikipedia.json b/linux-bash-modules/json/src/main/bash/wikipedia.json similarity index 100% rename from linux-bash/json/src/main/bash/wikipedia.json rename to linux-bash-modules/json/src/main/bash/wikipedia.json diff --git a/linux-bash/loops/README.md b/linux-bash-modules/loops/README.md similarity index 100% rename from linux-bash/loops/README.md rename to linux-bash-modules/loops/README.md diff --git a/linux-bash/loops/src/main/bash/find_directories.sh b/linux-bash-modules/loops/src/main/bash/find_directories.sh similarity index 100% rename from linux-bash/loops/src/main/bash/find_directories.sh rename to linux-bash-modules/loops/src/main/bash/find_directories.sh diff --git a/linux-bash/loops/src/main/bash/loop_directories.sh b/linux-bash-modules/loops/src/main/bash/loop_directories.sh similarity index 100% rename from linux-bash/loops/src/main/bash/loop_directories.sh rename to linux-bash-modules/loops/src/main/bash/loop_directories.sh diff --git a/linux-bash/read/README.md b/linux-bash-modules/read/README.md similarity index 100% rename from linux-bash/read/README.md rename to linux-bash-modules/read/README.md diff --git a/linux-bash/read/src/main/bash/file.csv b/linux-bash-modules/read/src/main/bash/file.csv similarity index 100% rename from linux-bash/read/src/main/bash/file.csv rename to linux-bash-modules/read/src/main/bash/file.csv diff --git a/linux-bash/read/src/main/bash/read_inputs.sh b/linux-bash-modules/read/src/main/bash/read_inputs.sh similarity index 100% rename from linux-bash/read/src/main/bash/read_inputs.sh rename to linux-bash-modules/read/src/main/bash/read_inputs.sh diff --git a/linux-bash/text/README.md b/linux-bash-modules/text/README.md similarity index 100% rename from linux-bash/text/README.md rename to linux-bash-modules/text/README.md diff --git a/linux-bash/text/src/main/bash/append_multiple_lines.sh b/linux-bash-modules/text/src/main/bash/append_multiple_lines.sh similarity index 100% rename from linux-bash/text/src/main/bash/append_multiple_lines.sh rename to linux-bash-modules/text/src/main/bash/append_multiple_lines.sh diff --git a/linux-bash/text/src/main/bash/remove_characters.sh b/linux-bash-modules/text/src/main/bash/remove_characters.sh similarity index 100% rename from linux-bash/text/src/main/bash/remove_characters.sh rename to linux-bash-modules/text/src/main/bash/remove_characters.sh diff --git a/logging-modules/log4j2/pom.xml b/logging-modules/log4j2/pom.xml index 50c7114556..da2984442c 100644 --- a/logging-modules/log4j2/pom.xml +++ b/logging-modules/log4j2/pom.xml @@ -63,51 +63,23 @@ org.apache.maven.plugins maven-compiler-plugin - ${maven-compiler-plugin.version} none + + org.apache.maven.plugins + maven-surefire-plugin + + + json + ${java.io.tmpdir}/${maven.build.timestamp}/logfile.json + + + - - - integration-lite-first - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*ManualTest.java - **/*LiveTest.java - - - **/*IntegrationTest.java - **/*IntTest.java - - - - - - - json - ${java.io.tmpdir}/${maven.build.timestamp}/logfile.json - - - - - - - 2.9.0 diff --git a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/CustomLoggingIntegrationTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/CustomLoggingIntegrationTest.java index 3e94e4e430..06fbb33b9d 100644 --- a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/CustomLoggingIntegrationTest.java +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/CustomLoggingIntegrationTest.java @@ -21,7 +21,7 @@ import com.baeldung.logging.log4j2.tests.jdbc.ConnectionFactory; @RunWith(JUnit4.class) public class CustomLoggingIntegrationTest { - + private static String logFilePath = System.getProperty("logging.folder.path"); @BeforeClass @@ -34,7 +34,7 @@ public class CustomLoggingIntegrationTest { } @Test - public void givenLoggerWithDefaultConfig_whenLogToConsole_thanOK() throws Exception { + public void givenLoggerWithDefaultConfig_whenLogToConsole_thenOK() throws Exception { Logger logger = LogManager.getLogger(getClass()); Exception e = new RuntimeException("This is only a test!"); @@ -43,7 +43,7 @@ public class CustomLoggingIntegrationTest { } @Test - public void givenLoggerWithConsoleConfig_whenLogToConsoleInColors_thanOK() throws Exception { + public void givenLoggerWithConsoleConfig_whenLogToConsoleInColors_thenOK() throws Exception { Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_MARKER"); Exception e = new RuntimeException("This is only a test!"); @@ -56,7 +56,7 @@ public class CustomLoggingIntegrationTest { } @Test - public void givenLoggerWithConsoleConfig_whenFilterByMarker_thanOK() throws Exception { + public void givenLoggerWithConsoleConfig_whenFilterByMarker_thenOK() throws Exception { Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_MARKER"); Marker appError = MarkerManager.getMarker("APP_ERROR"); Marker connectionTrace = MarkerManager.getMarker("CONN_TRACE"); @@ -66,7 +66,7 @@ public class CustomLoggingIntegrationTest { } @Test - public void givenLoggerWithConsoleConfig_whenFilterByThreadContext_thanOK() throws Exception { + public void givenLoggerWithConsoleConfig_whenFilterByThreadContext_thenOK() throws Exception { Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_THREAD_CONTEXT"); ThreadContext.put("userId", "1000"); logger.info("This is a log-visible user login. Maybe from an admin account?"); @@ -75,7 +75,7 @@ public class CustomLoggingIntegrationTest { } @Test - public void givenLoggerWithAsyncConfig_whenLogToJsonFile_thanOK() throws Exception { + public void givenLoggerWithAsyncConfig_whenLogToJsonFile_thenOK() throws Exception { Logger logger = LogManager.getLogger("ASYNC_JSON_FILE_APPENDER"); final int count = 88; @@ -90,7 +90,7 @@ public class CustomLoggingIntegrationTest { } @Test - public void givenLoggerWithFailoverConfig_whenLog_thanOK() throws Exception { + public void givenLoggerWithFailoverConfig_whenLog_thenOK() throws Exception { Logger logger = LogManager.getLogger("FAIL_OVER_SYSLOG_APPENDER"); Exception e = new RuntimeException("This is only a test!"); @@ -103,7 +103,7 @@ public class CustomLoggingIntegrationTest { } @Test - public void givenLoggerWithJdbcConfig_whenLogToDataSource_thanOK() throws Exception { + public void givenLoggerWithJdbcConfig_whenLogToDataSource_thenOK() throws Exception { Logger logger = LogManager.getLogger("JDBC_APPENDER"); final int count = 88; @@ -122,7 +122,7 @@ public class CustomLoggingIntegrationTest { } @Test - public void givenLoggerWithRollingFileConfig_whenLogToXMLFile_thanOK() throws Exception { + public void givenLoggerWithRollingFileConfig_whenLogToXMLFile_thenOK() throws Exception { Logger logger = LogManager.getLogger("XML_ROLLING_FILE_APPENDER"); final int count = 88; diff --git a/logging-modules/log4j2/src/test/resources/log4j2.xml b/logging-modules/log4j2/src/test/resources/log4j2.xml index 050e0aa705..6516d9884c 100644 --- a/logging-modules/log4j2/src/test/resources/log4j2.xml +++ b/logging-modules/log4j2/src/test/resources/log4j2.xml @@ -1,5 +1,5 @@ - - + diff --git a/lombok-modules/lombok-2/README.md b/lombok-modules/lombok-2/README.md index d3b1287346..fcee23fc82 100644 --- a/lombok-modules/lombok-2/README.md +++ b/lombok-modules/lombok-2/README.md @@ -9,4 +9,7 @@ This module contains articles about Project Lombok. - [Lombok Using @With Annotations](https://www.baeldung.com/lombok-with-annotations) - [Lombok’s @ToString Annotation](https://www.baeldung.com/lombok-tostring) - [Jackson’s Deserialization With Lombok](https://www.baeldung.com/java-jackson-deserialization-lombok) +- [Constructor Injection in Spring with Lombok](https://www.baeldung.com/spring-injection-lombok) +- [@StandardException Annotation in Lombok](https://www.baeldung.com/lombok-standardexception-annotation) +- [Lombok EqualsAndHashCode Annotation](https://www.baeldung.com/java-lombok-equalsandhashcode) - More articles: [[<-- prev]](../lombok) diff --git a/lombok-modules/lombok-2/pom.xml b/lombok-modules/lombok-2/pom.xml index 0a7ad27ad6..b805e6a31e 100644 --- a/lombok-modules/lombok-2/pom.xml +++ b/lombok-modules/lombok-2/pom.xml @@ -25,6 +25,10 @@ jackson-databind ${jackson.version} + + org.springframework.boot + spring-boot-starter-web + \ No newline at end of file diff --git a/spring-core-4/src/main/java/com/baeldung/lombok/ApologizeService.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/ApologizeService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/lombok/ApologizeService.java rename to lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/ApologizeService.java diff --git a/spring-core-4/src/main/java/com/baeldung/lombok/FarewellService.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/FarewellService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/lombok/FarewellService.java rename to lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/FarewellService.java diff --git a/spring-core-4/src/main/java/com/baeldung/lombok/GreetingService.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/GreetingService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/lombok/GreetingService.java rename to lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/GreetingService.java diff --git a/spring-core-4/src/main/java/com/baeldung/lombok/ThankingService.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/ThankingService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/lombok/ThankingService.java rename to lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/ThankingService.java diff --git a/spring-core-4/src/main/java/com/baeldung/lombok/Translator.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/Translator.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/lombok/Translator.java rename to lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/Translator.java diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/accessors/model/BasicAccount.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/accessors/model/BasicAccount.java deleted file mode 100644 index a9332735c7..0000000000 --- a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/accessors/model/BasicAccount.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.baeldung.lombok.accessors.model; - -import java.math.BigDecimal; - -public class BasicAccount { - private String name; - private BigDecimal balance; - - public BigDecimal getBalance() { - return this.balance; - } - - public void setBalance(BigDecimal newBalance) { - this.balance = newBalance; - } - - public String getName() { - return this.name; - } - - public void setName(String accountName) { - this.name = accountName; - } -} diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/accessors/model/FinalAccount.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/accessors/model/FinalAccount.java new file mode 100644 index 0000000000..72e712d246 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/accessors/model/FinalAccount.java @@ -0,0 +1,15 @@ +package com.baeldung.lombok.accessors.model; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Accessors(makeFinal = true) +@Getter +@Setter +public class FinalAccount { + private String name; + private BigDecimal balance; +} \ No newline at end of file diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/accessors/model/FinalChainedFluentAccount.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/accessors/model/FinalChainedFluentAccount.java new file mode 100644 index 0000000000..4951f370e7 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/accessors/model/FinalChainedFluentAccount.java @@ -0,0 +1,15 @@ +package com.baeldung.lombok.accessors.model; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Accessors(makeFinal = true, fluent = true, chain = true) +@Getter +@Setter +public class FinalChainedFluentAccount { + private String name; + private BigDecimal balance; +} \ No newline at end of file diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/Employee.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/Employee.java new file mode 100644 index 0000000000..6f0ac60cca --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/Employee.java @@ -0,0 +1,14 @@ +package com.baeldung.lombok.equalsandhashcode; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode +@AllArgsConstructor +public class Employee { + private String name; + private int id; + private int age; +} diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/EmployeeDelomboked.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/EmployeeDelomboked.java new file mode 100644 index 0000000000..afae2d4c17 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/EmployeeDelomboked.java @@ -0,0 +1,57 @@ +package com.baeldung.lombok.equalsandhashcode; + +import lombok.Getter; + +@Getter +public class EmployeeDelomboked { + + private String name; + private int id; + private int age; + + public EmployeeDelomboked() { + } + + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (!(o instanceof Employee)) { + return false; + } else { + Employee other = (Employee) o; + if (!other.canEqual(this)) { + return false; + } else if (this.getId() != other.getId()) { + return false; + } else if (this.getAge() != other.getAge()) { + return false; + } else { + Object this$name = this.getName(); + Object other$name = other.getName(); + if (this$name == null) { + if (other$name == null) { + return true; + } + } else if (this$name.equals(other$name)) { + return true; + } + + return false; + } + } + } + + protected boolean canEqual(Object other) { + return other instanceof Employee; + } + + public int hashCode() { + final int PRIME = 59; + int result = 1; + result = result * PRIME + this.getId(); + result = result * PRIME + this.getAge(); + Object $name = this.getName(); + result = result * PRIME + ($name == null ? 43 : $name.hashCode()); + return result; + } +} diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/commonissue/Employee.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/commonissue/Employee.java new file mode 100644 index 0000000000..91090a4a8c --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/commonissue/Employee.java @@ -0,0 +1,20 @@ +package com.baeldung.lombok.equalsandhashcode.commonissue; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode +@AllArgsConstructor +@NoArgsConstructor +public class Employee { + private String name; + private int id; + private int age; + private Manager manager; +} + diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/commonissue/EmployeeV2.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/commonissue/EmployeeV2.java new file mode 100644 index 0000000000..02bbbacaed --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/commonissue/EmployeeV2.java @@ -0,0 +1,17 @@ +package com.baeldung.lombok.equalsandhashcode.commonissue; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode(exclude = "manager") +@AllArgsConstructor +public class EmployeeV2 { + private String name; + private int id; + private int age; + private ManagerV2 manager; +} diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/commonissue/Manager.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/commonissue/Manager.java new file mode 100644 index 0000000000..aa6221d54a --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/commonissue/Manager.java @@ -0,0 +1,16 @@ +package com.baeldung.lombok.equalsandhashcode.commonissue; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode +@AllArgsConstructor +public class Manager { + private String name; + private Employee assistantManager; +} + diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/commonissue/ManagerV2.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/commonissue/ManagerV2.java new file mode 100644 index 0000000000..67068341f3 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/commonissue/ManagerV2.java @@ -0,0 +1,16 @@ +package com.baeldung.lombok.equalsandhashcode.commonissue; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode +@AllArgsConstructor +public class ManagerV2 { + private String name; + private EmployeeV2 assistantManager; +} + diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/exclude/classlevel/Employee.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/exclude/classlevel/Employee.java new file mode 100644 index 0000000000..64c95d0e7b --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/exclude/classlevel/Employee.java @@ -0,0 +1,15 @@ +package com.baeldung.lombok.equalsandhashcode.exclude.classlevel; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode(exclude = {"id", "age"}) +@AllArgsConstructor +public class Employee { + private String name; + private int id; + private int age; +} + diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/exclude/classlevel/EmployeeDelomboked.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/exclude/classlevel/EmployeeDelomboked.java new file mode 100644 index 0000000000..edf70689e1 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/exclude/classlevel/EmployeeDelomboked.java @@ -0,0 +1,37 @@ +package com.baeldung.lombok.equalsandhashcode.exclude.classlevel; + + +import lombok.Getter; + +@Getter +public class EmployeeDelomboked { + private String name; + private int id; + private int age; + + @Override + public boolean equals(final Object o) { + if (o == this) return true; + if (!(o instanceof Employee)) return false; + final Employee other = (Employee) o; + if (!other.canEqual((Object) this)) return false; + final Object this$name = this.getName(); + final Object other$name = other.getName(); + if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false; + return true; + } + + protected boolean canEqual(final Object other) { + return other instanceof Employee; + } + + @Override + public int hashCode() { + final int PRIME = 59; + int result = 1; + final Object $name = this.getName(); + result = result * PRIME + ($name == null ? 43 : $name.hashCode()); + return result; + } +} + diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/exclude/fieldlevel/Employee.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/exclude/fieldlevel/Employee.java new file mode 100644 index 0000000000..a03d1fc43a --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/exclude/fieldlevel/Employee.java @@ -0,0 +1,18 @@ +package com.baeldung.lombok.equalsandhashcode.exclude.fieldlevel; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode +@AllArgsConstructor +public class Employee { + private String name; + @EqualsAndHashCode.Exclude + private int id; + @EqualsAndHashCode.Exclude + private int age; +} + + diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/exclude/fieldlevel/EmployeeDelomboked.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/exclude/fieldlevel/EmployeeDelomboked.java new file mode 100644 index 0000000000..f30ab6f709 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/exclude/fieldlevel/EmployeeDelomboked.java @@ -0,0 +1,31 @@ +package com.baeldung.lombok.equalsandhashcode.exclude.fieldlevel; + + +import lombok.Getter; + +@Getter +public class EmployeeDelomboked { + private String name; + private int id; + private int age; + + public boolean equals(final Object o) { + if (o == this) return true; + if (!(o instanceof com.baeldung.lombok.equalsandhashcode.exclude.fieldlevel.Employee)) return false; + final com.baeldung.lombok.equalsandhashcode.exclude.fieldlevel.Employee other = (com.baeldung.lombok.equalsandhashcode.exclude.fieldlevel.Employee) o; + if (!other.canEqual((Object) this)) return false; + final Object this$name = this.getName(); + final Object other$name = other.getName(); + if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false; + return true; + } + + public int hashCode() { + final int PRIME = 59; + int result = 1; + final Object $name = this.getName(); + result = result * PRIME + ($name == null ? 43 : $name.hashCode()); + return result; + } +} + diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/include/classlevel/Employee.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/include/classlevel/Employee.java new file mode 100644 index 0000000000..e353c27dfd --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/include/classlevel/Employee.java @@ -0,0 +1,15 @@ +package com.baeldung.lombok.equalsandhashcode.include.classlevel; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(of = {"name", "id"}) +@AllArgsConstructor +public class Employee { + private String name; + private int id; + private int age; +} + diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/include/fieldlevel/Employee.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/include/fieldlevel/Employee.java new file mode 100644 index 0000000000..c1d4ab5b0f --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/include/fieldlevel/Employee.java @@ -0,0 +1,18 @@ +package com.baeldung.lombok.equalsandhashcode.include.fieldlevel; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +@AllArgsConstructor +public class Employee { + @EqualsAndHashCode.Include + private String name; + @EqualsAndHashCode.Include + private int id; + private int age; +} + + diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/include/methodlevel/Employee.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/include/methodlevel/Employee.java new file mode 100644 index 0000000000..3de8cc2c69 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/include/methodlevel/Employee.java @@ -0,0 +1,20 @@ +package com.baeldung.lombok.equalsandhashcode.include.methodlevel; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode +@AllArgsConstructor +public class Employee { + private String name; + private int id; + private int age; + + @EqualsAndHashCode.Include + public boolean hasOddId() { + return id % 2 != 0; + } +} + diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/include/methodlevel/EmployeeDelomboked.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/include/methodlevel/EmployeeDelomboked.java new file mode 100644 index 0000000000..f25b996fe1 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/include/methodlevel/EmployeeDelomboked.java @@ -0,0 +1,40 @@ +package com.baeldung.lombok.equalsandhashcode.include.methodlevel; + +import lombok.Getter; + +@Getter +public class EmployeeDelomboked { + private String name; + private int id; + private int age; + + public boolean hasOddId() { + return id % 2 != 0; + } + + public boolean equals(final Object o) { + if (o == this) return true; + if (!(o instanceof Employee)) return false; + final Employee other = (Employee) o; + if (!other.canEqual((Object) this)) return false; + if (this.getId() != other.getId()) return false; + if (this.getAge() != other.getAge()) return false; + if (this.hasOddId() != other.hasOddId()) return false; + final Object this$name = this.getName(); + final Object other$name = other.getName(); + if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false; + return true; + } + + public int hashCode() { + final int PRIME = 59; + int result = 1; + result = result * PRIME + this.getId(); + result = result * PRIME + this.getAge(); + result = result * PRIME + (this.hasOddId() ? 79 : 97); + final Object $name = this.getName(); + result = result * PRIME + ($name == null ? 43 : $name.hashCode()); + return result; + } +} + diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/inheritance/Employee.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/inheritance/Employee.java new file mode 100644 index 0000000000..de63755cfc --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/inheritance/Employee.java @@ -0,0 +1,16 @@ +package com.baeldung.lombok.equalsandhashcode.inheritance; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode +@AllArgsConstructor +public class Employee { + private String name; + private int id; + private int age; +} diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/inheritance/Manager.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/inheritance/Manager.java new file mode 100644 index 0000000000..e943940c32 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/inheritance/Manager.java @@ -0,0 +1,20 @@ +package com.baeldung.lombok.equalsandhashcode.inheritance; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode(callSuper = true) +public class Manager extends Employee { + private String departmentName; + private int uid; + + public Manager(String departmentName, int uid, String name, int id, int age) { + super(name, id, age); + this.departmentName = departmentName; + this.uid = uid; + } +} diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/inheritance/ManagerDelomboked.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/inheritance/ManagerDelomboked.java new file mode 100644 index 0000000000..e14b4a1f10 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/inheritance/ManagerDelomboked.java @@ -0,0 +1,37 @@ +package com.baeldung.lombok.equalsandhashcode.inheritance; + +import lombok.Getter; + +@Getter +public class ManagerDelomboked extends Employee { + private String departmentName; + private int uid; + + public ManagerDelomboked(String departmentName, int uid, String name, int id, int age) { + super(name, id, age); + this.departmentName = departmentName; + this.uid = uid; + } + + public boolean equals(final Object o) { + if (o == this) return true; + if (!(o instanceof com.baeldung.lombok.equalsandhashcode.inheritance.Manager)) return false; + final com.baeldung.lombok.equalsandhashcode.inheritance.Manager other = (com.baeldung.lombok.equalsandhashcode.inheritance.Manager) o; + if (!other.canEqual((Object) this)) return false; + if (!super.equals(o)) return false; + if (this.getUid() != other.getUid()) return false; + final Object this$departmentName = this.getDepartmentName(); + final Object other$departmentName = other.getDepartmentName(); + if (this$departmentName == null ? other$departmentName != null : !this$departmentName.equals(other$departmentName)) return false; + return true; + } + + public int hashCode() { + final int PRIME = 59; + int result = super.hashCode(); + result = result * PRIME + this.getUid(); + final Object $departmentName = this.getDepartmentName(); + result = result * PRIME + ($departmentName == null ? 43 : $departmentName.hashCode()); + return result; + } +} diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/inheritance/ManagerV2.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/inheritance/ManagerV2.java new file mode 100644 index 0000000000..b5bdfd0891 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/equalsandhashcode/inheritance/ManagerV2.java @@ -0,0 +1,19 @@ +package com.baeldung.lombok.equalsandhashcode.inheritance; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +public class ManagerV2 extends Employee { + private String departmentName; + private int uid; + + public ManagerV2(String departmentName, int uid, String name, int id, int age) { + super(name, id, age); + this.departmentName = departmentName; + this.uid = uid; + } +} diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/standardexception/CustomException.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/standardexception/CustomException.java new file mode 100644 index 0000000000..bee85b3398 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/standardexception/CustomException.java @@ -0,0 +1,7 @@ +package com.baeldung.lombok.standardexception; + +import lombok.experimental.StandardException; + +@StandardException +public class CustomException extends NumberFormatException { +} diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/standardexception/CustomNumberFormatException.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/standardexception/CustomNumberFormatException.java new file mode 100644 index 0000000000..fbd98cac16 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/standardexception/CustomNumberFormatException.java @@ -0,0 +1,11 @@ +package com.baeldung.lombok.standardexception; + +public class CustomNumberFormatException extends NumberFormatException { + public CustomNumberFormatException() { + super(); + } + + public CustomNumberFormatException(String s) { + super(s); + } +} \ No newline at end of file diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/valvar/ValExample.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/valvar/ValExample.java index b7ecd95fa8..f436ef81dd 100644 --- a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/valvar/ValExample.java +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/valvar/ValExample.java @@ -1,7 +1,6 @@ package com.baeldung.lombok.valvar; import lombok.val; -import lombok.var; import java.util.ArrayList; import java.util.HashMap; diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/valvar/VarExample.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/valvar/VarExample.java index 6fabf66590..138264db09 100644 --- a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/valvar/VarExample.java +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/valvar/VarExample.java @@ -1,6 +1,5 @@ package com.baeldung.lombok.valvar; -import lombok.var; import java.util.ArrayList; import java.util.Arrays; diff --git a/spring-core-4/src/test/java/com/baeldung/lombok/ApologizeServiceAutowiringIntegrationTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/ApologizeServiceAutowiringIntegrationTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/lombok/ApologizeServiceAutowiringIntegrationTest.java rename to lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/ApologizeServiceAutowiringIntegrationTest.java diff --git a/spring-core-4/src/test/java/com/baeldung/lombok/ApologizeServiceIntegrationTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/ApologizeServiceIntegrationTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/lombok/ApologizeServiceIntegrationTest.java rename to lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/ApologizeServiceIntegrationTest.java diff --git a/spring-core-4/src/test/java/com/baeldung/lombok/FarewellAutowiringIntegrationTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/FarewellAutowiringIntegrationTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/lombok/FarewellAutowiringIntegrationTest.java rename to lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/FarewellAutowiringIntegrationTest.java diff --git a/spring-core-4/src/test/java/com/baeldung/lombok/FarewellServiceIntegrationTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/FarewellServiceIntegrationTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/lombok/FarewellServiceIntegrationTest.java rename to lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/FarewellServiceIntegrationTest.java diff --git a/spring-core-4/src/test/java/com/baeldung/lombok/GreetingServiceIntegrationTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/GreetingServiceIntegrationTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/lombok/GreetingServiceIntegrationTest.java rename to lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/GreetingServiceIntegrationTest.java diff --git a/spring-core-4/src/test/java/com/baeldung/lombok/TestConfig.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/TestConfig.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/lombok/TestConfig.java rename to lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/TestConfig.java diff --git a/spring-core-4/src/test/java/com/baeldung/lombok/ThankingServiceAutowiringIntegrationTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/ThankingServiceAutowiringIntegrationTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/lombok/ThankingServiceAutowiringIntegrationTest.java rename to lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/ThankingServiceAutowiringIntegrationTest.java diff --git a/spring-core-4/src/test/java/com/baeldung/lombok/ThankingServiceIntegrationTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/ThankingServiceIntegrationTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/lombok/ThankingServiceIntegrationTest.java rename to lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/ThankingServiceIntegrationTest.java diff --git a/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/accessors/AccessorsUnitTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/accessors/AccessorsUnitTest.java index 04f38bfc32..a1f54d6b4a 100644 --- a/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/accessors/AccessorsUnitTest.java +++ b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/accessors/AccessorsUnitTest.java @@ -1,26 +1,36 @@ package com.baeldung.lombok.accessors; -import com.baeldung.lombok.accessors.model.*; +import com.baeldung.lombok.accessors.model.ChainedAccount; +import com.baeldung.lombok.accessors.model.ChainedFluentAccount; +import com.baeldung.lombok.accessors.model.FinalAccount; +import com.baeldung.lombok.accessors.model.FinalChainedFluentAccount; +import com.baeldung.lombok.accessors.model.FluentAccount; +import com.baeldung.lombok.accessors.model.PrefixedAccount; +import com.baeldung.lombok.accessors.model.PrefixedFluentAccount; +import com.baeldung.lombok.accessors.model.StandardAccount; import org.junit.Test; +import java.lang.reflect.Modifier; import java.math.BigDecimal; +import java.util.Arrays; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class AccessorsUnitTest { @Test - public void givenBasicAccount_thenUseBasicAccessors() { - BasicAccount account = new BasicAccount(); - account.setName("Basic Accessors"); + public void whenStandardAccount_thenHaveStandardAccessors() { + StandardAccount account = new StandardAccount(); + account.setName("Standard Accessors"); account.setBalance(BigDecimal.TEN); - assertEquals("Basic Accessors", account.getName()); + assertEquals("Standard Accessors", account.getName()); assertEquals(BigDecimal.TEN, account.getBalance()); } @Test - public void givenFluentAccount_thenUseFluentAccessors() { + public void whenFluentAccount_thenHaveFluentAccessors() { FluentAccount account = new FluentAccount(); account.name("Fluent Account"); account.balance(BigDecimal.TEN); @@ -30,7 +40,7 @@ public class AccessorsUnitTest { } @Test - public void givenChainedAccount_thenUseChainedAccessors() { + public void whenChainedAccount_thenHaveChainedAccessors() { ChainedAccount account = new ChainedAccount(); account.setName("Chained Account").setBalance(BigDecimal.TEN); @@ -39,7 +49,7 @@ public class AccessorsUnitTest { } @Test - public void givenChainedFluentAccount_thenUseChainedFluentAccessors() { + public void whenChainedFluentAccount_thenHaveChainedFluentAccessors() { ChainedFluentAccount account = new ChainedFluentAccount() .name("Fluent Account") .balance(BigDecimal.TEN); @@ -49,7 +59,7 @@ public class AccessorsUnitTest { } @Test - public void givenPrefixedAccount_thenRemovePrefixFromAccessors() { + public void whenPrefixedAccount_thenRemovePrefixFromAccessors() { PrefixedAccount account = new PrefixedAccount(); account.setName("Prefixed Fields"); account.setBalance(BigDecimal.TEN); @@ -61,7 +71,7 @@ public class AccessorsUnitTest { } @Test - public void givenPrefixedFluentAccount_thenRemovePrefixFromAccessors() { + public void whenPrefixedFluentAccount_thenRemovePrefixFromAccessors() { PrefixedFluentAccount account = new PrefixedFluentAccount(); account .name("Prefixed Fluent Fields") @@ -71,4 +81,38 @@ public class AccessorsUnitTest { assertEquals(BigDecimal.TEN, account.balance()); } -} + @Test + public void whenFinalAccount_thenHaveFinalAccessors() { + FinalAccount account = new FinalAccount(); + account.setName("Final Account"); + account.setBalance(BigDecimal.TEN); + + assertEquals("Final Account", account.getName()); + assertEquals(BigDecimal.TEN, account.getBalance()); + + //verify if all getters and setters are final methods + boolean getterSettersAreFinal = Arrays.stream(FinalAccount.class.getMethods()) + .filter(method -> method.getName().matches("^(get|set)(Name|Balance)$")) + .allMatch(method -> Modifier.isFinal(method.getModifiers())); + assertTrue(getterSettersAreFinal); + + } + + @Test + public void whenFinalChainedFluentAccount_thenHaveFinalAccessors() { + FinalChainedFluentAccount account = new FinalChainedFluentAccount(); + account + .name("Final Chained Fluent Account") + .balance(BigDecimal.TEN); + + assertEquals("Final Chained Fluent Account", account.name()); + assertEquals(BigDecimal.TEN, account.balance()); + + //verify if all getters and setters are final methods + boolean getterSettersAreFinal = Arrays.stream(FinalAccount.class.getMethods()) + .filter(method -> method.getName().matches("^(name|balance)$")) + .allMatch(method -> Modifier.isFinal(method.getModifiers())); + assertTrue(getterSettersAreFinal); + } + +} \ No newline at end of file diff --git a/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/EqualsAndHashCodeUnitTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/EqualsAndHashCodeUnitTest.java new file mode 100644 index 0000000000..614e94ea59 --- /dev/null +++ b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/EqualsAndHashCodeUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.lombok.equalsandhashcode; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +public class EqualsAndHashCodeUnitTest { + + @Test + public void whenUsingEqualsAndHashCodeOnClassLevel_thenTwoObjectsAreEqualAndHaveSameHashCodeIfAllFieldsAreSame() { + Employee employee = new Employee("Nimi", 15, 22); + Employee employeeTwo = new Employee("Nimi", 15, 22); + Employee employeeThree = new Employee("Mannat", 15, 22); + assertEquals(employee, employeeTwo); + assertNotEquals(employee, employeeThree); + assertEquals(employee.hashCode(), employeeTwo.hashCode()); + assertNotEquals(employee.hashCode(), employeeThree.hashCode()); + } +} diff --git a/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/commonissue/EqualsAndHashCodeUnitTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/commonissue/EqualsAndHashCodeUnitTest.java new file mode 100644 index 0000000000..207e4e0636 --- /dev/null +++ b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/commonissue/EqualsAndHashCodeUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.lombok.equalsandhashcode.commonissue; + +import org.junit.Test; + +public class EqualsAndHashCodeUnitTest { + + @Test(expected = StackOverflowError.class) + public void whenUsingEqualsAndHashInObjectWithCircularDependency_thenCallingEqualsAndHasCodeWillThrowStackOverFlowError() { + Manager manager = new Manager("Mannat", null); + + Employee employee = new Employee("Nimi", 15, 22, manager); + + manager.setAssistantManager(employee); + + employee.setManager(manager); + + int hash = employee.hashCode(); + + } + + @Test + public void whenUsingEqualsAndHashInObjectAndExcludingCircularDependencyField_thenNoStackOverFlowError() { + ManagerV2 manager = new ManagerV2("Mannat", null); + + EmployeeV2 employee = new EmployeeV2("Nimi", 15, 22, manager); + + manager.setAssistantManager(employee); + + employee.setManager(manager); + + int hash = employee.hashCode(); + + } +} diff --git a/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/exclude/classlevel/EqualsAndHashCodeUnitTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/exclude/classlevel/EqualsAndHashCodeUnitTest.java new file mode 100644 index 0000000000..be086ff7df --- /dev/null +++ b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/exclude/classlevel/EqualsAndHashCodeUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.lombok.equalsandhashcode.exclude.classlevel; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class EqualsAndHashCodeUnitTest { + + @Test + public void whenUsingEqualsAndHashCodeOnClassLevelAndExcludingFields_thenTwoObjectsAreEqualAndHaveSameHashCodeEvenIfExcludedFieldsAreNotSame() { + Employee employee = new Employee("Nimi", 15, 22); + Employee employeeTwo = new Employee("Nimi", 17, 21); + + assertEquals(employee, employeeTwo); + assertEquals(employee.hashCode(), employeeTwo.hashCode()); + } +} diff --git a/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/exclude/fieldLevel/EqualsAndHashCodeUnitTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/exclude/fieldLevel/EqualsAndHashCodeUnitTest.java new file mode 100644 index 0000000000..832b188509 --- /dev/null +++ b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/exclude/fieldLevel/EqualsAndHashCodeUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.lombok.equalsandhashcode.exclude.fieldLevel; + +import com.baeldung.lombok.equalsandhashcode.exclude.fieldlevel.Employee; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class EqualsAndHashCodeUnitTest { + + @Test + public void whenUsingEqualsAndHashCodeWithExcludingFields_thenTwoObjectsAreEqualAndHaveSameHashCodeEvenIfExcludedFieldsAreNotSame() { + Employee employee = new Employee("Nimi", 15, 22); + Employee employeeTwo = new Employee("Nimi", 17, 21); + + assertEquals(employee, employeeTwo); + assertEquals(employee.hashCode(), employeeTwo.hashCode()); + } +} diff --git a/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/include/classlevel/EqualsAndHashCodeUnitTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/include/classlevel/EqualsAndHashCodeUnitTest.java new file mode 100644 index 0000000000..1641966fd2 --- /dev/null +++ b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/include/classlevel/EqualsAndHashCodeUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.lombok.equalsandhashcode.include.classlevel; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class EqualsAndHashCodeUnitTest { + + @Test + public void whenUsingEqualsAndHashCodeOnClassLevelAndIncludeFields_thenTwoObjectsAreEqualAndHaveSameHashCodeIfIncludedFieldsAreSame() { + Employee employee = new Employee("Nimi", 15, 22); + Employee employeeTwo = new Employee("Nimi", 15, 22); + Employee employeeThree = new Employee("Nimi", 15, 23); + + assertEquals(employee, employeeTwo); + assertEquals(employee, employeeThree); + + assertEquals(employee.hashCode(), employeeTwo.hashCode()); + assertEquals(employee.hashCode(), employeeThree.hashCode()); + } +} diff --git a/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/include/fieldlevel/EqualsAndHashCodeUnitTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/include/fieldlevel/EqualsAndHashCodeUnitTest.java new file mode 100644 index 0000000000..dcf6123d2a --- /dev/null +++ b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/include/fieldlevel/EqualsAndHashCodeUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.lombok.equalsandhashcode.include.fieldlevel; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class EqualsAndHashCodeUnitTest { + + @Test + public void whenUsingEqualsAndHashCodeOnFieldLevel_thenTwoObjectsAreEqualAndHaveSameHashCodeIfIncludedFieldsAreSame() { + Employee employee = new Employee("Nimi", 15, 22); + Employee employeeTwo = new Employee("Nimi", 15, 22); + Employee employeeThree = new Employee("Nimi", 15, 23); + + assertEquals(employee, employeeTwo); + assertEquals(employee, employeeThree); + + assertEquals(employee.hashCode(), employeeTwo.hashCode()); + assertEquals(employee.hashCode(), employeeThree.hashCode()); + } +} diff --git a/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/include/methodlevel/EqualsAndHashCodeUnitTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/include/methodlevel/EqualsAndHashCodeUnitTest.java new file mode 100644 index 0000000000..79d673b4a4 --- /dev/null +++ b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/include/methodlevel/EqualsAndHashCodeUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.lombok.equalsandhashcode.include.methodlevel; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +public class EqualsAndHashCodeUnitTest { + + @Test + public void whenUsingEqualsAndHashCodeOnMethodLevel_thenTwoObjectsAreEqualAndHaveSameHashCodeIfMethodsReturnSameValue() { + Employee employee = new Employee("Nimi", 15, 22); + Employee employeeTwo = new Employee("Nimi", 15, 22); + Employee employeeThree = new Employee("Nimi", 15, 23); + + assertEquals(employee, employeeTwo); + assertNotEquals(employee, employeeThree); + + assertEquals(employee.hashCode(), employeeTwo.hashCode()); + assertNotEquals(employee.hashCode(), employeeThree.hashCode()); + } +} diff --git a/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/inheritance/EqualsAndHashCodeUnitTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/inheritance/EqualsAndHashCodeUnitTest.java new file mode 100644 index 0000000000..abf71fe83f --- /dev/null +++ b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/equalsandhashcode/inheritance/EqualsAndHashCodeUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.lombok.equalsandhashcode.inheritance; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +public class EqualsAndHashCodeUnitTest { + + @Test + public void whenUsingEqualsAndHashCodeAndCallSuperIsTrue_thenTwoObjectsAreEqualAndHaveSameHashCodeIfAllFieldsIncludingParentsFieldsAreSame() { + Manager manager = new Manager("Opto", 444, "Nimi", 15, 22); + Manager managerTwo = new Manager("Opto", 444, "Nimi", 15, 22); + Manager managerThree = new Manager("Opto", 444, "Nimi", 15, 23); + + assertEquals(manager, managerTwo); + assertNotEquals(managerTwo, managerThree); + + } + + @Test + public void whenUsingEqualsAndHashCodeAndCallSuperIsFalse_thenTwoObjectsAreEqualAndHaveSameHashCodeEvenIfAllParentsFieldsAreNotSame() { + ManagerV2 manager = new ManagerV2("Opto", 444, "Nimi", 15, 22); + ManagerV2 managerTwo = new ManagerV2("Opto", 444, "Nimi", 15, 22); + ManagerV2 managerThree = new ManagerV2("Opto", 444, "Nimi", 14, 21); + assertEquals(manager, managerTwo); + assertEquals(managerTwo, managerThree); + } +} diff --git a/lombok-modules/lombok-custom/pom.xml b/lombok-modules/lombok-custom/pom.xml index c119900c8a..1f7f630772 100644 --- a/lombok-modules/lombok-custom/pom.xml +++ b/lombok-modules/lombok-custom/pom.xml @@ -53,11 +53,27 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + 1.14.8 1.8 3.3.0-v_771 + 1.8 + 1.8 \ No newline at end of file diff --git a/lombok-modules/lombok/pom.xml b/lombok-modules/lombok/pom.xml index 1be22f0bc2..57b2a5a999 100644 --- a/lombok-modules/lombok/pom.xml +++ b/lombok-modules/lombok/pom.xml @@ -40,41 +40,19 @@ true - - - org.projectlombok - lombok-maven-plugin - ${delombok-maven-plugin.version} - - - delombok - generate-sources - - delombok - - - ${project.basedir}/src/main/java - ${project.build.directory}/delombok - false - - skip - - false - - - - - - - - - + edge-SNAPSHOT 1.0.0.Final 1.18.20.0 23.0.0 + + + projectlombok.org + https://projectlombok.org/edge-releases + + \ No newline at end of file diff --git a/lombok-modules/pom.xml b/lombok-modules/pom.xml index 7ca303af9d..f2bfdb51c0 100644 --- a/lombok-modules/pom.xml +++ b/lombok-modules/pom.xml @@ -18,10 +18,21 @@ lombok lombok-2 - lombok-custom + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + @@ -32,4 +43,9 @@ + + 11 + 11 + + \ No newline at end of file diff --git a/mapstruct/README.md b/mapstruct/README.md index 384bcbaa14..46a9f8b213 100644 --- a/mapstruct/README.md +++ b/mapstruct/README.md @@ -9,3 +9,4 @@ This module contains articles about MapStruct. - [Using Multiple Source Objects with MapStruct](https://www.baeldung.com/mapstruct-multiple-source-objects) - [Ignoring Unmapped Properties with MapStruct](https://www.baeldung.com/mapstruct-ignore-unmapped-properties) - [Mapping Collections with MapStruct](https://www.baeldung.com/java-mapstruct-mapping-collections) +- [Use Mapper in Another Mapper with Mapstruct and Java](https://www.baeldung.com/java-mapstruct-nested-mapping) diff --git a/mapstruct/src/main/java/com/baeldung/dto/ArticleDTO.java b/mapstruct/src/main/java/com/baeldung/dto/ArticleDTO.java new file mode 100644 index 0000000000..708167de94 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/dto/ArticleDTO.java @@ -0,0 +1,12 @@ +package com.baeldung.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ArticleDTO { + private int id; + private String name; + private PersonDTO author; +} diff --git a/mapstruct/src/main/java/com/baeldung/entity/Article.java b/mapstruct/src/main/java/com/baeldung/entity/Article.java new file mode 100644 index 0000000000..4aff8f4166 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/entity/Article.java @@ -0,0 +1,12 @@ +package com.baeldung.entity; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class Article { + private int id; + private String name; + private Person author; +} diff --git a/mapstruct/src/main/java/com/baeldung/mapper/ArticleMapper.java b/mapstruct/src/main/java/com/baeldung/mapper/ArticleMapper.java new file mode 100644 index 0000000000..b5b47f6b3b --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapper/ArticleMapper.java @@ -0,0 +1,20 @@ +package com.baeldung.mapper; + +import com.baeldung.dto.ArticleDTO; +import com.baeldung.dto.PersonDTO; +import com.baeldung.entity.Article; +import com.baeldung.entity.Person; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface ArticleMapper { + + ArticleMapper INSTANCE = Mappers.getMapper(ArticleMapper.class); + + ArticleDTO articleToArticleDto(Article article); + + default PersonDTO personToPersonDto(Person person) { + return Mappers.getMapper(PersonMapper.class).personToPersonDTO(person); + } +} diff --git a/mapstruct/src/main/java/com/baeldung/mapper/ArticleUsingPersonMapper.java b/mapstruct/src/main/java/com/baeldung/mapper/ArticleUsingPersonMapper.java new file mode 100644 index 0000000000..c1ea0797ed --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapper/ArticleUsingPersonMapper.java @@ -0,0 +1,16 @@ +package com.baeldung.mapper; + +import com.baeldung.dto.ArticleDTO; +import com.baeldung.dto.PersonDTO; +import com.baeldung.entity.Article; +import com.baeldung.entity.Person; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper(uses = PersonMapper.class) +public interface ArticleUsingPersonMapper { + + ArticleUsingPersonMapper INSTANCE = Mappers.getMapper(ArticleUsingPersonMapper.class); + + ArticleDTO articleToArticleDto(Article article); +} diff --git a/mapstruct/src/test/java/com/baeldung/mapper/ArticleMapperUnitTest.java b/mapstruct/src/test/java/com/baeldung/mapper/ArticleMapperUnitTest.java new file mode 100644 index 0000000000..2470915a01 --- /dev/null +++ b/mapstruct/src/test/java/com/baeldung/mapper/ArticleMapperUnitTest.java @@ -0,0 +1,49 @@ +package com.baeldung.mapper; + +import com.baeldung.dto.ArticleDTO; +import com.baeldung.dto.CarDTO; +import com.baeldung.entity.Article; +import com.baeldung.entity.Car; +import com.baeldung.entity.Person; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ArticleMapperUnitTest { + + @Test + public void givenArticle_whenMaps_thenProducesCorrectDto() { + + Article entity = new Article(); + entity.setId(1); + entity.setName("Mapstruct Mapping"); + Person author = new Person(); + author.setId("1"); + author.setName("John"); + entity.setAuthor(author); + + ArticleDTO articleDTO = ArticleMapper.INSTANCE.articleToArticleDto(entity); + + assertEquals(articleDTO.getId(), entity.getId()); + assertEquals(articleDTO.getName(), entity.getName()); + assertEquals(articleDTO.getAuthor().getName(), entity.getAuthor().getName()); + } + + @Test + public void givenArticle_whenMapsWithUses_thenProducesCorrectDto() { + + Article entity = new Article(); + entity.setId(1); + entity.setName("Mapstruct Mapping"); + Person author = new Person(); + author.setId("1"); + author.setName("John"); + entity.setAuthor(author); + + ArticleDTO articleDTO = ArticleUsingPersonMapper.INSTANCE.articleToArticleDto(entity); + + assertEquals(articleDTO.getId(), entity.getId()); + assertEquals(articleDTO.getName(), entity.getName()); + assertEquals(articleDTO.getAuthor().getName(), entity.getAuthor().getName()); + } +} diff --git a/dependency-exclusion/README.md b/maven-modules/dependency-exclusion/README.md similarity index 100% rename from dependency-exclusion/README.md rename to maven-modules/dependency-exclusion/README.md diff --git a/dependeny-exclusion/core-java-exclusions/pom.xml b/maven-modules/dependency-exclusion/core-java-exclusions/pom.xml similarity index 80% rename from dependeny-exclusion/core-java-exclusions/pom.xml rename to maven-modules/dependency-exclusion/core-java-exclusions/pom.xml index cf1f6d1e1b..9fd09f83e2 100644 --- a/dependeny-exclusion/core-java-exclusions/pom.xml +++ b/maven-modules/dependency-exclusion/core-java-exclusions/pom.xml @@ -1,10 +1,9 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-exclusions - 0.0.0-SNAPSHOT core-java-exclusions jar @@ -14,6 +13,15 @@ 0.0.1-SNAPSHOT + + + junit + junit + test + + + + @@ -30,24 +38,17 @@ - + + + Deactivate JUnit 4.7 engine by overriding it with an empty dummy org.apache.maven.surefire surefire-junit47 dummy - + --> - - - junit - junit - test - - - diff --git a/dependency-exclusion/core-java-exclusions/src/test/java/com/sample/project/tests/ExcludeDirectDependencyUnitTest.java b/maven-modules/dependency-exclusion/core-java-exclusions/src/test/java/com/sample/project/tests/ExcludeDirectDependencyUnitTest.java similarity index 100% rename from dependency-exclusion/core-java-exclusions/src/test/java/com/sample/project/tests/ExcludeDirectDependencyUnitTest.java rename to maven-modules/dependency-exclusion/core-java-exclusions/src/test/java/com/sample/project/tests/ExcludeDirectDependencyUnitTest.java diff --git a/maven-modules/dependency-exclusion/dummy-surefire-junit47/pom.xml b/maven-modules/dependency-exclusion/dummy-surefire-junit47/pom.xml new file mode 100644 index 0000000000..93c5f7591f --- /dev/null +++ b/maven-modules/dependency-exclusion/dummy-surefire-junit47/pom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + org.apache.maven.surefire + surefire-junit47 + dummy + + + com.baeldung.dependency-exclusion + dependency-exclusion + 0.0.1-SNAPSHOT + + diff --git a/dependency-exclusion/pom.xml b/maven-modules/dependency-exclusion/pom.xml similarity index 96% rename from dependency-exclusion/pom.xml rename to maven-modules/dependency-exclusion/pom.xml index ac83cc161a..13de16a57c 100644 --- a/dependency-exclusion/pom.xml +++ b/maven-modules/dependency-exclusion/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-java + maven-modules 0.0.1-SNAPSHOT - ../parent-java diff --git a/maven-modules/pom.xml b/maven-modules/pom.xml index a7a3522ca8..f7bba3a8ff 100644 --- a/maven-modules/pom.xml +++ b/maven-modules/pom.xml @@ -16,33 +16,35 @@ animal-sniffer-mvn-plugin - maven-archetype compiler-plugin-java-9 + dependency-exclusion + host-maven-repo-example + maven-archetype + maven-builder-plugin + maven-classifier maven-copy-files maven-custom-plugin maven-exec-plugin maven-generate-war maven-integration-test maven-multi-source + maven-parent-pom-resolution maven-plugins maven-polyglot + maven-printing-plugins maven-properties + maven-reactor + maven-repositories + maven-simple + maven-surefire-plugin maven-unused-dependencies maven-war-plugin + spring-bom optional-dependencies version-collision version-overriding-plugins versions-maven-plugin - maven-printing-plugins - maven-builder-plugin - host-maven-repo-example - maven-surefire-plugin - maven-parent-pom-resolution - maven-simple - maven-classifier - maven-repositories - maven-reactor @@ -62,4 +64,18 @@ + + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + + + + + \ No newline at end of file diff --git a/spring-bom/README.md b/maven-modules/spring-bom/README.md similarity index 100% rename from spring-bom/README.md rename to maven-modules/spring-bom/README.md diff --git a/spring-bom/pom.xml b/maven-modules/spring-bom/pom.xml similarity index 93% rename from spring-bom/pom.xml rename to maven-modules/spring-bom/pom.xml index 7ba21ee285..93d0bdc458 100644 --- a/spring-bom/pom.xml +++ b/maven-modules/spring-bom/pom.xml @@ -10,8 +10,8 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + maven-modules + 0.0.1-SNAPSHOT diff --git a/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldApp.java b/maven-modules/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldApp.java similarity index 100% rename from spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldApp.java rename to maven-modules/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldApp.java diff --git a/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldBean.java b/maven-modules/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldBean.java similarity index 100% rename from spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldBean.java rename to maven-modules/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldBean.java diff --git a/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldConfig.java b/maven-modules/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldConfig.java similarity index 100% rename from spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldConfig.java rename to maven-modules/spring-bom/src/main/java/com/baeldung/spring/bom/HelloWorldConfig.java diff --git a/spring-bom/src/main/resources/logback.xml b/maven-modules/spring-bom/src/main/resources/logback.xml similarity index 100% rename from spring-bom/src/main/resources/logback.xml rename to maven-modules/spring-bom/src/main/resources/logback.xml diff --git a/spring-bom/src/test/java/com/baeldung/SpringContextTest.java b/maven-modules/spring-bom/src/test/java/com/baeldung/SpringContextTest.java similarity index 100% rename from spring-bom/src/test/java/com/baeldung/SpringContextTest.java rename to maven-modules/spring-bom/src/test/java/com/baeldung/SpringContextTest.java diff --git a/maven-modules/version-collision/dependencyconvergence.xml b/maven-modules/version-collision/dependencyconvergence.xml new file mode 100644 index 0000000000..8f57cbf1d5 --- /dev/null +++ b/maven-modules/version-collision/dependencyconvergence.xml @@ -0,0 +1,22 @@ + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.3.0 + + + enforce + + + + + + + enforce + + + + + + \ No newline at end of file diff --git a/maven-modules/version-collision/dependencyconvergence_exclude_scenario.xml b/maven-modules/version-collision/dependencyconvergence_exclude_scenario.xml new file mode 100644 index 0000000000..32b0462a11 --- /dev/null +++ b/maven-modules/version-collision/dependencyconvergence_exclude_scenario.xml @@ -0,0 +1,26 @@ + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.3.0 + + + enforce + + + + + com.google.guava:guava + + + + + + enforce + + + + + + \ No newline at end of file diff --git a/maven-modules/version-collision/dependencyconvergence_include_scenario.xml b/maven-modules/version-collision/dependencyconvergence_include_scenario.xml new file mode 100644 index 0000000000..9e4680fc91 --- /dev/null +++ b/maven-modules/version-collision/dependencyconvergence_include_scenario.xml @@ -0,0 +1,26 @@ + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.3.0 + + + enforce + + + + + com.google.guava:guava + + + + + + enforce + + + + + + \ No newline at end of file diff --git a/messaging-modules/apache-camel/README.md b/messaging-modules/apache-camel/README.md new file mode 100644 index 0000000000..6196893adc --- /dev/null +++ b/messaging-modules/apache-camel/README.md @@ -0,0 +1,9 @@ +## Apache Camel + +This module contains articles about Apache Camel + +### Relevant Articles + +- [Introduction To Apache Camel](http://www.baeldung.com/apache-camel-intro) +- [Unmarshalling a JSON Array Using camel-jackson](https://www.baeldung.com/java-camel-jackson-json-array) + diff --git a/messaging-modules/apache-camel/pom.xml b/messaging-modules/apache-camel/pom.xml new file mode 100644 index 0000000000..bb20f178aa --- /dev/null +++ b/messaging-modules/apache-camel/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + org.baeldung.apache.camel + apache-camel + apache-camel + jar + http://maven.apache.org + + + com.baeldung + messaging-modules + 0.0.1-SNAPSHOT + + + + + org.apache.camel + camel-core + ${env.camel.version} + + + org.apache.camel + camel-spring-javaconfig + ${env.camel.version} + + + org.apache.camel + camel-jackson + ${env.camel.version} + + + org.apache.camel + camel-test + ${env.camel.version} + test + + + + + 3.14.7 + + + \ No newline at end of file diff --git a/messaging-modules/spring-apache-camel/src/main/java/com/baeldung/camel/apache/file/FileProcessor.java b/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/file/FileProcessor.java similarity index 100% rename from messaging-modules/spring-apache-camel/src/main/java/com/baeldung/camel/apache/file/FileProcessor.java rename to messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/file/FileProcessor.java diff --git a/messaging-modules/spring-apache-camel/src/main/java/com/baeldung/camel/apache/file/FileRouter.java b/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/file/FileRouter.java similarity index 100% rename from messaging-modules/spring-apache-camel/src/main/java/com/baeldung/camel/apache/file/FileRouter.java rename to messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/file/FileRouter.java diff --git a/messaging-modules/spring-apache-camel/src/main/java/com/baeldung/camel/apache/jackson/Fruit.java b/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/jackson/Fruit.java similarity index 100% rename from messaging-modules/spring-apache-camel/src/main/java/com/baeldung/camel/apache/jackson/Fruit.java rename to messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/jackson/Fruit.java diff --git a/messaging-modules/spring-apache-camel/src/main/java/com/baeldung/camel/apache/jackson/FruitList.java b/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/jackson/FruitList.java similarity index 100% rename from messaging-modules/spring-apache-camel/src/main/java/com/baeldung/camel/apache/jackson/FruitList.java rename to messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/jackson/FruitList.java diff --git a/messaging-modules/spring-apache-camel/src/main/resources/camel-context-test.xml b/messaging-modules/apache-camel/src/main/resources/camel-context-test.xml similarity index 100% rename from messaging-modules/spring-apache-camel/src/main/resources/camel-context-test.xml rename to messaging-modules/apache-camel/src/main/resources/camel-context-test.xml diff --git a/messaging-modules/apache-camel/src/main/resources/logback.xml b/messaging-modules/apache-camel/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/messaging-modules/apache-camel/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/messaging-modules/spring-apache-camel/src/test/java/com/apache/baeldung/camel/jackson/FruitArrayJacksonUnmarshalUnitTest.java b/messaging-modules/apache-camel/src/test/java/com/apache/baeldung/camel/jackson/FruitArrayJacksonUnmarshalUnitTest.java similarity index 100% rename from messaging-modules/spring-apache-camel/src/test/java/com/apache/baeldung/camel/jackson/FruitArrayJacksonUnmarshalUnitTest.java rename to messaging-modules/apache-camel/src/test/java/com/apache/baeldung/camel/jackson/FruitArrayJacksonUnmarshalUnitTest.java diff --git a/messaging-modules/spring-apache-camel/src/test/java/com/apache/baeldung/camel/jackson/FruitListJacksonUnmarshalUnitTest.java b/messaging-modules/apache-camel/src/test/java/com/apache/baeldung/camel/jackson/FruitListJacksonUnmarshalUnitTest.java similarity index 100% rename from messaging-modules/spring-apache-camel/src/test/java/com/apache/baeldung/camel/jackson/FruitListJacksonUnmarshalUnitTest.java rename to messaging-modules/apache-camel/src/test/java/com/apache/baeldung/camel/jackson/FruitListJacksonUnmarshalUnitTest.java diff --git a/messaging-modules/spring-apache-camel/src/test/java/com/apache/camel/file/processor/FileProcessorIntegrationTest.java b/messaging-modules/apache-camel/src/test/java/com/apache/camel/file/processor/FileProcessorIntegrationTest.java similarity index 100% rename from messaging-modules/spring-apache-camel/src/test/java/com/apache/camel/file/processor/FileProcessorIntegrationTest.java rename to messaging-modules/apache-camel/src/test/java/com/apache/camel/file/processor/FileProcessorIntegrationTest.java diff --git a/messaging-modules/spring-apache-camel/src/test/resources/json/fruit-array.json b/messaging-modules/apache-camel/src/test/resources/json/fruit-array.json similarity index 100% rename from messaging-modules/spring-apache-camel/src/test/resources/json/fruit-array.json rename to messaging-modules/apache-camel/src/test/resources/json/fruit-array.json diff --git a/messaging-modules/spring-apache-camel/src/test/resources/json/fruit-list.json b/messaging-modules/apache-camel/src/test/resources/json/fruit-list.json similarity index 100% rename from messaging-modules/spring-apache-camel/src/test/resources/json/fruit-list.json rename to messaging-modules/apache-camel/src/test/resources/json/fruit-list.json diff --git a/apache-rocketmq/README.md b/messaging-modules/apache-rocketmq/README.md similarity index 100% rename from apache-rocketmq/README.md rename to messaging-modules/apache-rocketmq/README.md diff --git a/apache-rocketmq/pom.xml b/messaging-modules/apache-rocketmq/pom.xml similarity index 89% rename from apache-rocketmq/pom.xml rename to messaging-modules/apache-rocketmq/pom.xml index 48399b6d51..a362644de3 100644 --- a/apache-rocketmq/pom.xml +++ b/messaging-modules/apache-rocketmq/pom.xml @@ -9,8 +9,8 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + messaging-modules + 0.0.1-SNAPSHOT diff --git a/apache-rocketmq/src/main/java/com/baeldung/rocketmq/consumer/CartEventConsumer.java b/messaging-modules/apache-rocketmq/src/main/java/com/baeldung/rocketmq/consumer/CartEventConsumer.java similarity index 100% rename from apache-rocketmq/src/main/java/com/baeldung/rocketmq/consumer/CartEventConsumer.java rename to messaging-modules/apache-rocketmq/src/main/java/com/baeldung/rocketmq/consumer/CartEventConsumer.java diff --git a/apache-rocketmq/src/main/java/com/baeldung/rocketmq/event/CartItemEvent.java b/messaging-modules/apache-rocketmq/src/main/java/com/baeldung/rocketmq/event/CartItemEvent.java similarity index 100% rename from apache-rocketmq/src/main/java/com/baeldung/rocketmq/event/CartItemEvent.java rename to messaging-modules/apache-rocketmq/src/main/java/com/baeldung/rocketmq/event/CartItemEvent.java diff --git a/apache-rocketmq/src/main/java/com/baeldung/rocketmq/producer/CartEventProducer.java b/messaging-modules/apache-rocketmq/src/main/java/com/baeldung/rocketmq/producer/CartEventProducer.java similarity index 100% rename from apache-rocketmq/src/main/java/com/baeldung/rocketmq/producer/CartEventProducer.java rename to messaging-modules/apache-rocketmq/src/main/java/com/baeldung/rocketmq/producer/CartEventProducer.java diff --git a/apache-rocketmq/src/main/java/com/baeldung/rocketmq/transaction/TransactionListenerImpl.java b/messaging-modules/apache-rocketmq/src/main/java/com/baeldung/rocketmq/transaction/TransactionListenerImpl.java similarity index 100% rename from apache-rocketmq/src/main/java/com/baeldung/rocketmq/transaction/TransactionListenerImpl.java rename to messaging-modules/apache-rocketmq/src/main/java/com/baeldung/rocketmq/transaction/TransactionListenerImpl.java diff --git a/apache-rocketmq/src/main/resources/application.properties b/messaging-modules/apache-rocketmq/src/main/resources/application.properties similarity index 100% rename from apache-rocketmq/src/main/resources/application.properties rename to messaging-modules/apache-rocketmq/src/main/resources/application.properties diff --git a/messaging-modules/pom.xml b/messaging-modules/pom.xml index f843b0fe11..71ff25d71b 100644 --- a/messaging-modules/pom.xml +++ b/messaging-modules/pom.xml @@ -15,6 +15,8 @@ + apache-camel + apache-rocketmq jgroups rabbitmq spring-amqp diff --git a/messaging-modules/rabbitmq/README.md b/messaging-modules/rabbitmq/README.md index 93bb795d7b..8cfcca3378 100644 --- a/messaging-modules/rabbitmq/README.md +++ b/messaging-modules/rabbitmq/README.md @@ -9,3 +9,4 @@ This module contains articles about RabbitMQ. - [Channels and Connections in RabbitMQ](https://www.baeldung.com/java-rabbitmq-channels-connections) - [Create Dynamic Queues in RabbitMQ](https://www.baeldung.com/rabbitmq-dynamic-queues) + diff --git a/messaging-modules/spring-apache-camel/README.md b/messaging-modules/spring-apache-camel/README.md index 535c61cbef..66079d4e83 100644 --- a/messaging-modules/spring-apache-camel/README.md +++ b/messaging-modules/spring-apache-camel/README.md @@ -4,10 +4,8 @@ This module contains articles about Spring with Apache Camel ### Relevant Articles -- [Introduction To Apache Camel](http://www.baeldung.com/apache-camel-intro) - [Integration Patterns With Apache Camel](http://www.baeldung.com/camel-integration-patterns) - [Using Apache Camel with Spring](http://www.baeldung.com/spring-apache-camel-tutorial) -- [Unmarshalling a JSON Array Using camel-jackson](https://www.baeldung.com/java-camel-jackson-json-array) - [Apache Camel with Spring Boot](https://www.baeldung.com/apache-camel-spring-boot) - [Apache Camel Routes Testing in Spring Boot](https://www.baeldung.com/spring-boot-apache-camel-routes-testing) - [Apache Camel Conditional Routing](https://www.baeldung.com/spring-apache-camel-conditional-routing) diff --git a/messaging-modules/spring-apache-camel/pom.xml b/messaging-modules/spring-apache-camel/pom.xml index ec7557666c..65533d7649 100644 --- a/messaging-modules/spring-apache-camel/pom.xml +++ b/messaging-modules/spring-apache-camel/pom.xml @@ -47,17 +47,6 @@ camel-spring-javaconfig ${env.camel.version} - - org.apache.camel - camel-jackson - ${env.camel.version} - - - org.apache.camel - camel-test - ${env.camel.version} - test - org.apache.camel.springboot camel-servlet-starter diff --git a/messaging-modules/spring-jms/pom.xml b/messaging-modules/spring-jms/pom.xml index 2dee95136d..ef1e0cb3a8 100644 --- a/messaging-modules/spring-jms/pom.xml +++ b/messaging-modules/spring-jms/pom.xml @@ -44,19 +44,19 @@ org.mockito mockito-core - 4.6.1 + ${mockito-core.version} test org.apache.activemq.tooling activemq-junit - 5.16.5 + ${activemq-junit.version} test org.testcontainers testcontainers - 1.17.3 + ${testcontainers.version} test @@ -83,6 +83,9 @@ 5.14.1 1.5.10.RELEASE 3.3.2 + 4.6.1 + 5.16.5 + 1.17.3 \ No newline at end of file diff --git a/microservices-modules/rest-express/pom.xml b/microservices-modules/rest-express/pom.xml index e3fed19e29..eda27ec164 100644 --- a/microservices-modules/rest-express/pom.xml +++ b/microservices-modules/rest-express/pom.xml @@ -23,15 +23,6 @@ rest-express jar - - 0.3.3 - 3.1.2 - 2.6 - 0.11.3 - 1.0 - 0.4.8 - 4.11 - @@ -98,7 +89,7 @@ org.codehaus.mojo exec-maven-plugin - 1.2.1 + ${exec-maven-plugin.version} com.baeldung.restexpress.Main @@ -106,7 +97,7 @@ org.apache.maven.plugins maven-shade-plugin - 2.4.1 + ${maven-shade-plugin.version} false @@ -140,8 +131,22 @@ org.codehaus.mojo versions-maven-plugin - 2.0 + ${versions-maven-plugin.version} + + + 0.3.3 + 3.1.2 + 2.6 + 0.11.3 + 1.0 + 0.4.8 + 4.11 + 1.2.1 + 2.4.1 + 2.0 + + diff --git a/osgi/pom.xml b/osgi/pom.xml index 3fa2dcdf02..ecc8758ef9 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -67,6 +67,17 @@ + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + @@ -84,6 +95,8 @@ 1.1 6.0.0 3.3.0 + 11 + 11 \ No newline at end of file diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index a1f16c4a64..3f6ad8ef8a 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -94,7 +94,7 @@ 3.3.0 1.0.22.RELEASE - 2.7.8 + 2.7.11 1.9.1 8.0.31 diff --git a/parent-spring-6/README.md b/parent-spring-6/README.md new file mode 100644 index 0000000000..791a6ca197 --- /dev/null +++ b/parent-spring-6/README.md @@ -0,0 +1,3 @@ +## Parent Spring 5 + +This is a parent module for all projects using Spring 5 diff --git a/parent-spring-6/pom.xml b/parent-spring-6/pom.xml new file mode 100644 index 0000000000..e1b92ca8cd --- /dev/null +++ b/parent-spring-6/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + parent-spring-6 + 0.0.1-SNAPSHOT + parent-spring-6 + pom + Parent for all spring 6 core modules + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + org.springframework + spring-framework-bom + ${spring.version} + pom + import + + + + + + + org.springframework + spring-core + + + + + 6.0.8 + + + diff --git a/patterns-modules/clean-architecture/src/test/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserUnitTest.java b/patterns-modules/clean-architecture/src/test/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserUnitTest.java index 505ea47e3f..e2a9cd9d14 100644 --- a/patterns-modules/clean-architecture/src/test/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserUnitTest.java +++ b/patterns-modules/clean-architecture/src/test/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserUnitTest.java @@ -1,15 +1,36 @@ package com.baeldung.pattern.cleanarchitecture.usercreation; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.any; import org.junit.jupiter.api.Test; class UserUnitTest { + UserRegisterDsGateway userDsGateway = mock(UserRegisterDsGateway.class); + UserPresenter userPresenter = mock(UserPresenter.class); + UserFactory userFactory = mock(UserFactory.class); + UserInputBoundary interactor = new UserRegisterInteractor(userDsGateway, userPresenter, userFactory); + @Test void given123Password_whenPasswordIsNotValid_thenIsFalse() { User user = new CommonUser("Baeldung", "123"); assertThat(user.passwordIsValid()).isFalse(); } + + @Test + void givenBaeldungUserAnd123456Password_whenCreate_thenSaveItAndPrepareSuccessView() { + + User user = new CommonUser("baeldung", "123456"); + UserRequestModel userRequestModel = new UserRequestModel(user.getName(), user.getPassword()); + when(userFactory.create(anyString(), anyString())).thenReturn(new CommonUser(user.getName(), user.getPassword())); + + interactor.create(userRequestModel); + + verify(userDsGateway, times(1)).save(any(UserDsRequestModel.class)); + verify(userPresenter, times(1)).prepareSuccessView(any(UserResponseModel.class)); + } } diff --git a/patterns-modules/design-patterns-behavioral-2/README.md b/patterns-modules/design-patterns-behavioral-2/README.md index 9618a9c458..db4dd8d719 100644 --- a/patterns-modules/design-patterns-behavioral-2/README.md +++ b/patterns-modules/design-patterns-behavioral-2/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: - [Memento Design Pattern in Java](https://www.baeldung.com/java-memento-design-pattern) +- [Difference Between Fluent Interface and Builder Pattern in Java](https://www.baeldung.com/java-fluent-interface-vs-builder-pattern) diff --git a/patterns-modules/design-patterns-behavioral/src/main/java/com/baeldung/templatemethod/model/HighEndComputerBuilder.java b/patterns-modules/design-patterns-behavioral/src/main/java/com/baeldung/templatemethod/model/HighEndComputerBuilder.java index 2ee6f93f9b..e06f1291a6 100644 --- a/patterns-modules/design-patterns-behavioral/src/main/java/com/baeldung/templatemethod/model/HighEndComputerBuilder.java +++ b/patterns-modules/design-patterns-behavioral/src/main/java/com/baeldung/templatemethod/model/HighEndComputerBuilder.java @@ -1,5 +1,8 @@ package com.baeldung.templatemethod.model; +import lombok.extern.slf4j.Slf4j; + +@Slf4j public class HighEndComputerBuilder extends ComputerBuilder { @Override @@ -11,7 +14,7 @@ public class HighEndComputerBuilder extends ComputerBuilder { public void setupMotherboard() { motherboardSetupStatus.add("Screwing the high-end motherboard to the case."); motherboardSetupStatus.add("Pluging in the power supply connectors."); - motherboardSetupStatus.forEach(step -> System.out.println(step)); + motherboardSetupStatus.forEach(step -> log.debug(step)); } @Override diff --git a/patterns-modules/design-patterns-behavioral/src/main/java/com/baeldung/templatemethod/model/StandardComputerBuilder.java b/patterns-modules/design-patterns-behavioral/src/main/java/com/baeldung/templatemethod/model/StandardComputerBuilder.java index da2c2e9b2d..f5b953c830 100644 --- a/patterns-modules/design-patterns-behavioral/src/main/java/com/baeldung/templatemethod/model/StandardComputerBuilder.java +++ b/patterns-modules/design-patterns-behavioral/src/main/java/com/baeldung/templatemethod/model/StandardComputerBuilder.java @@ -1,5 +1,8 @@ package com.baeldung.templatemethod.model; - + +import lombok.extern.slf4j.Slf4j; + +@Slf4j public class StandardComputerBuilder extends ComputerBuilder { @Override @@ -11,7 +14,7 @@ public class StandardComputerBuilder extends ComputerBuilder { public void setupMotherboard() { motherboardSetupStatus.add("Screwing the standard motherboard to the case."); motherboardSetupStatus.add("Pluging in the power supply connectors."); - motherboardSetupStatus.forEach(step -> System.out.println(step)); + motherboardSetupStatus.forEach(step -> log.debug(step)); } @Override diff --git a/patterns-modules/design-patterns-behavioral/src/test/resources/logback-test.xml b/patterns-modules/design-patterns-behavioral/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..499cc828a2 --- /dev/null +++ b/patterns-modules/design-patterns-behavioral/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + %d{yyyy-MM-dd HH:mm:ss} | %-5p | [%thread] %logger{5}:%L - %msg%n + + + + + + + \ No newline at end of file diff --git a/pdf-2/pom.xml b/pdf-2/pom.xml index 653b55a206..ccbb5c9693 100644 --- a/pdf-2/pom.xml +++ b/pdf-2/pom.xml @@ -28,12 +28,12 @@ com.itextpdf itextpdf - 5.5.13.3 + ${itextpdf.version} org.apache.pdfbox pdfbox - 3.0.0-RC1 + ${pdfbox.version} @@ -48,8 +48,10 @@ + 5.5.13.3 7.2.3 3.0.1 + 3.0.0-RC1 \ No newline at end of file diff --git a/pdf/pom.xml b/pdf/pom.xml index 4bfc7cb621..cead1b2ded 100644 --- a/pdf/pom.xml +++ b/pdf/pom.xml @@ -106,7 +106,7 @@ 2.0.25 2.0.1 - 5.5.10 + 5.5.13.3 5.5.10 3.15 1.8 diff --git a/persistence-modules/activejdbc/pom.xml b/persistence-modules/activejdbc/pom.xml index 5fdf27a679..a661fc3abb 100644 --- a/persistence-modules/activejdbc/pom.xml +++ b/persistence-modules/activejdbc/pom.xml @@ -74,9 +74,9 @@ - 2.0 + 3.4-j11 development.test,development - 5.1.34 + 8.0.32 \ No newline at end of file diff --git a/persistence-modules/activejdbc/src/main/java/com/baeldung/ActiveJDBCApp.java b/persistence-modules/activejdbc/src/main/java/com/baeldung/ActiveJDBCApp.java index 8906d3e759..ea600b9721 100644 --- a/persistence-modules/activejdbc/src/main/java/com/baeldung/ActiveJDBCApp.java +++ b/persistence-modules/activejdbc/src/main/java/com/baeldung/ActiveJDBCApp.java @@ -4,6 +4,7 @@ package com.baeldung; import com.baeldung.model.Employee; import com.baeldung.model.Role; import org.javalite.activejdbc.Base; +import org.javalite.activejdbc.DB; import org.javalite.activejdbc.LazyList; import org.javalite.activejdbc.Model; @@ -11,8 +12,7 @@ public class ActiveJDBCApp { public static void main( String[] args ) { - try { - Base.open(); + try(final DB open = Base.open()) { ActiveJDBCApp app = new ActiveJDBCApp(); app.create(); app.update(); diff --git a/persistence-modules/core-java-persistence/pom.xml b/persistence-modules/core-java-persistence/pom.xml index 5cc1df483f..e8add07fbf 100644 --- a/persistence-modules/core-java-persistence/pom.xml +++ b/persistence-modules/core-java-persistence/pom.xml @@ -52,14 +52,21 @@ spring-boot-starter ${springframework.boot.spring-boot-starter.version} + + mysql + mysql-connector-java + ${mysql-connector.version} + runtime + - 2.4.0 - 3.2.0 - 0.9.5.2 - 1.5.8.RELEASE - 4.3.4.RELEASE + 2.9.0 + 5.0.1 + 0.9.5.5 + 3.0.4 + 6.0.6 + 8.0.32 \ No newline at end of file diff --git a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcmetadata/DatabaseConfig.java b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcmetadata/DatabaseConfig.java index 8ad689041e..44cfc75a2b 100644 --- a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcmetadata/DatabaseConfig.java +++ b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcmetadata/DatabaseConfig.java @@ -1,13 +1,14 @@ package com.baeldung.jdbcmetadata; -import org.apache.log4j.Logger; - import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class DatabaseConfig { - private static final Logger LOG = Logger.getLogger(DatabaseConfig.class); + private static final Logger LOG = LoggerFactory.getLogger(DatabaseConfig.class); private Connection connection; @@ -17,7 +18,7 @@ public class DatabaseConfig { String url = "jdbc:h2:mem:testdb"; connection = DriverManager.getConnection(url, "sa", ""); } catch (ClassNotFoundException | SQLException e) { - LOG.error(e); + LOG.error(e.getMessage()); } } @@ -35,7 +36,7 @@ public class DatabaseConfig { connection.createStatement().executeUpdate("create table CUSTOMER (ID int primary key auto_increment, NAME VARCHAR(45))"); connection.createStatement().executeUpdate("create table CUST_ADDRESS (ID VARCHAR(36), CUST_ID int, ADDRESS VARCHAR(45), FOREIGN KEY (CUST_ID) REFERENCES CUSTOMER(ID))"); } catch (SQLException e) { - LOG.error(e); + LOG.error(e.getMessage()); } } @@ -43,7 +44,7 @@ public class DatabaseConfig { try { connection.createStatement().executeUpdate("CREATE VIEW CUSTOMER_VIEW AS SELECT * FROM CUSTOMER"); } catch (SQLException e) { - LOG.error(e); + LOG.error(e.getMessage()); } } } diff --git a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcmetadata/JdbcMetadataApplication.java b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcmetadata/JdbcMetadataApplication.java index 591a14f3b5..f85f227381 100644 --- a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcmetadata/JdbcMetadataApplication.java +++ b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcmetadata/JdbcMetadataApplication.java @@ -1,12 +1,13 @@ package com.baeldung.jdbcmetadata; -import org.apache.log4j.Logger; - import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class JdbcMetadataApplication { - private static final Logger LOG = Logger.getLogger(JdbcMetadataApplication.class); + private static final Logger LOG = LoggerFactory.getLogger(JdbcMetadataApplication.class); public static void main(String[] args) { DatabaseConfig databaseConfig = new DatabaseConfig(); diff --git a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java index 9cfcff468e..a53c82d3da 100644 --- a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java +++ b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java @@ -5,10 +5,6 @@ import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; -import javax.sql.rowset.JdbcRowSet; -import javax.sql.rowset.RowSetFactory; -import javax.sql.rowset.RowSetProvider; - import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Configuration; diff --git a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java index 72c462ac42..163b3a3b58 100644 --- a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java +++ b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java @@ -7,8 +7,6 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; -import com.sun.rowset.*; - import javax.sql.rowset.CachedRowSet; import javax.sql.rowset.FilteredRowSet; import javax.sql.rowset.JdbcRowSet; @@ -25,7 +23,7 @@ public class JdbcRowsetApplication { public static void main(String[] args) throws Exception { SpringApplication.run(JdbcRowsetApplication.class, args); - Statement stmt = null; + Statement stmt; try { Connection conn = DatabaseConfiguration.geth2Connection(); @@ -41,8 +39,7 @@ public class JdbcRowsetApplication { DatabaseConfiguration.initDatabase(stmt); // JdbcRowSet Example String sql = "SELECT * FROM customers"; - JdbcRowSet jdbcRS; - jdbcRS = new JdbcRowSetImpl(conn); + JdbcRowSet jdbcRS = RowSetProvider.newFactory().createJdbcRowSet(); jdbcRS.setType(ResultSet.TYPE_SCROLL_INSENSITIVE); jdbcRS.setCommand(sql); jdbcRS.execute(); @@ -58,7 +55,8 @@ public class JdbcRowsetApplication { String username = "sa"; String password = ""; String url = "jdbc:h2:mem:testdb"; - CachedRowSet crs = new CachedRowSetImpl(); + RowSetFactory aFactory = RowSetProvider.newFactory(); + CachedRowSet crs = aFactory.createCachedRowSet(); crs.setUsername(username); crs.setPassword(password); crs.setUrl(url); @@ -74,7 +72,7 @@ public class JdbcRowsetApplication { } // WebRowSet example - WebRowSet wrs = new WebRowSetImpl(); + WebRowSet wrs = RowSetProvider.newFactory().createWebRowSet(); wrs.setUsername(username); wrs.setPassword(password); wrs.setUrl(url); @@ -84,14 +82,14 @@ public class JdbcRowsetApplication { wrs.writeXml(ostream); // JoinRowSet example - CachedRowSetImpl customers = new CachedRowSetImpl(); + CachedRowSet customers = aFactory.createCachedRowSet(); customers.setUsername(username); customers.setPassword(password); customers.setUrl(url); customers.setCommand(sql); customers.execute(); - CachedRowSetImpl associates = new CachedRowSetImpl(); + CachedRowSet associates = aFactory.createCachedRowSet(); associates.setUsername(username); associates.setPassword(password); associates.setUrl(url); @@ -99,7 +97,7 @@ public class JdbcRowsetApplication { associates.setCommand(associatesSQL); associates.execute(); - JoinRowSet jrs = new JoinRowSetImpl(); + JoinRowSet jrs = RowSetProvider.newFactory().createJoinRowSet(); final String ID = "id"; final String NAME = "name"; jrs.addRowSet(customers, ID); diff --git a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetLiveTest.java b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetLiveTest.java index ebfb4df102..2b2b35c423 100644 --- a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetLiveTest.java +++ b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetLiveTest.java @@ -19,11 +19,6 @@ import javax.sql.rowset.WebRowSet; import org.junit.Before; import org.junit.Test; -import com.sun.rowset.CachedRowSetImpl; -import com.sun.rowset.JdbcRowSetImpl; -import com.sun.rowset.JoinRowSetImpl; -import com.sun.rowset.WebRowSetImpl; - public class JdbcRowSetLiveTest { Statement stmt = null; String username = "sa"; @@ -51,9 +46,10 @@ public class JdbcRowSetLiveTest { public void createJdbcRowSet_SelectCustomers_ThenCorrect() throws Exception { String sql = "SELECT * FROM customers"; - JdbcRowSet jdbcRS; - Connection conn = DatabaseConfiguration.geth2Connection(); - jdbcRS = new JdbcRowSetImpl(conn); + JdbcRowSet jdbcRS = RowSetProvider.newFactory().createJdbcRowSet(); + jdbcRS.setUrl("jdbc:h2:mem:testdb"); + jdbcRS.setUsername("sa"); + jdbcRS.setPassword(""); jdbcRS.setType(ResultSet.TYPE_SCROLL_INSENSITIVE); jdbcRS.setCommand(sql); jdbcRS.execute(); @@ -71,7 +67,7 @@ public class JdbcRowSetLiveTest { @Test public void createCachedRowSet_DeleteRecord_ThenCorrect() throws Exception { - CachedRowSet crs = new CachedRowSetImpl(); + CachedRowSet crs = RowSetProvider.newFactory().createCachedRowSet(); crs.setUsername(username); crs.setPassword(password); crs.setUrl(url); @@ -91,7 +87,7 @@ public class JdbcRowSetLiveTest { @Test public void createWebRowSet_SelectCustomers_WritetoXML_ThenCorrect() throws SQLException, IOException { - WebRowSet wrs = new WebRowSetImpl(); + WebRowSet wrs = RowSetProvider.newFactory().createWebRowSet(); wrs.setUsername(username); wrs.setPassword(password); wrs.setUrl(url); @@ -105,14 +101,14 @@ public class JdbcRowSetLiveTest { @Test public void createCachedRowSets_DoJoinRowSet_ThenCorrect() throws Exception { - CachedRowSetImpl customers = new CachedRowSetImpl(); + CachedRowSet customers = RowSetProvider.newFactory().createCachedRowSet(); customers.setUsername(username); customers.setPassword(password); customers.setUrl(url); customers.setCommand(sql); customers.execute(); - CachedRowSetImpl associates = new CachedRowSetImpl(); + CachedRowSet associates = RowSetProvider.newFactory().createCachedRowSet(); associates.setUsername(username); associates.setPassword(password); associates.setUrl(url); @@ -120,7 +116,7 @@ public class JdbcRowSetLiveTest { associates.setCommand(associatesSQL); associates.execute(); - JoinRowSet jrs = new JoinRowSetImpl(); + JoinRowSet jrs = RowSetProvider.newFactory().createJoinRowSet(); final String ID = "id"; final String NAME = "name"; jrs.addRowSet(customers, ID); diff --git a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/spring/jdbc/JdbcLiveTest.java b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/spring/jdbc/JdbcLiveTest.java index c13f94f12a..fe00ca28dc 100644 --- a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/spring/jdbc/JdbcLiveTest.java +++ b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/spring/jdbc/JdbcLiveTest.java @@ -1,9 +1,10 @@ package com.baeldung.spring.jdbc; -import org.apache.log4j.Logger; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.sql.CallableStatement; import java.sql.Connection; @@ -24,7 +25,7 @@ import static org.junit.Assert.assertTrue; public class JdbcLiveTest { - private static final Logger LOG = Logger.getLogger(JdbcLiveTest.class); + private static final Logger LOG = LoggerFactory.getLogger(JdbcLiveTest.class); private Connection con; diff --git a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/spring/jdbc/ResultSetLiveTest.java b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/spring/jdbc/ResultSetLiveTest.java index 853e78a68d..c77e314141 100644 --- a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/spring/jdbc/ResultSetLiveTest.java +++ b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/spring/jdbc/ResultSetLiveTest.java @@ -13,7 +13,6 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.FixMethodOrder; @@ -25,8 +24,6 @@ import junit.framework.Assert; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class ResultSetLiveTest { - private static final Logger logger = Logger.getLogger(ResultSetLiveTest.class); - private final Employee expectedEmployee1 = new Employee(1, "John", 1000.0, "Developer"); private final Employee updatedEmployee1 = new Employee(1, "John", 1100.0, "Developer"); diff --git a/persistence-modules/hbase/pom.xml b/persistence-modules/hbase/pom.xml index e38b73e137..3e6cfe27be 100644 --- a/persistence-modules/hbase/pom.xml +++ b/persistence-modules/hbase/pom.xml @@ -33,7 +33,7 @@ - 1.3.1 + 2.5.3 \ No newline at end of file diff --git a/persistence-modules/hbase/src/main/java/com/baeldung/hbase/HbaseClientExample.java b/persistence-modules/hbase/src/main/java/com/baeldung/hbase/HbaseClientExample.java index 5546f15e36..3a137a6019 100644 --- a/persistence-modules/hbase/src/main/java/com/baeldung/hbase/HbaseClientExample.java +++ b/persistence-modules/hbase/src/main/java/com/baeldung/hbase/HbaseClientExample.java @@ -1,7 +1,5 @@ package com.baeldung.hbase; - -import com.google.protobuf.ServiceException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.HBaseConfiguration; @@ -13,11 +11,11 @@ import java.io.IOException; //install hbase locally & hbase master start public class HbaseClientExample { - public static void main(String[] args) throws IOException, ServiceException { + public static void main(String[] args) throws IOException { new HbaseClientExample().connect(); } - private void connect() throws IOException, ServiceException { + private void connect() throws IOException { Configuration config = HBaseConfiguration.create(); String path = this.getClass().getClassLoader().getResource("hbase-site.xml").getPath(); @@ -25,7 +23,7 @@ public class HbaseClientExample { config.addResource(new Path(path)); try { - HBaseAdmin.checkHBaseAvailable(config); + HBaseAdmin.available(config); } catch (MasterNotRunningException e) { System.out.println("HBase is not running." + e.getMessage()); return; diff --git a/persistence-modules/hibernate-annotations/README.md b/persistence-modules/hibernate-annotations/README.md index 9b68579151..a03fb7e8e3 100644 --- a/persistence-modules/hibernate-annotations/README.md +++ b/persistence-modules/hibernate-annotations/README.md @@ -10,3 +10,4 @@ This module contains articles about Annotations used in Hibernate. - [Hibernate @WhereJoinTable Annotation](https://www.baeldung.com/hibernate-wherejointable) - [Usage of the Hibernate @LazyCollection Annotation](https://www.baeldung.com/hibernate-lazycollection) - [@Immutable in Hibernate](https://www.baeldung.com/hibernate-immutable) +- [Hibernate @CreationTimestamp and @UpdateTimestamp](https://www.baeldung.com/hibernate-creationtimestamp-updatetimestamp) diff --git a/persistence-modules/hibernate-annotations/pom.xml b/persistence-modules/hibernate-annotations/pom.xml index 310b409a00..6417421fed 100644 --- a/persistence-modules/hibernate-annotations/pom.xml +++ b/persistence-modules/hibernate-annotations/pom.xml @@ -76,13 +76,18 @@ ${org.springframework.version} test + + io.hypersistence + hypersistence-utils-hibernate-60 + 3.3.1 + - 5.0.2.RELEASE - 1.10.6.RELEASE - 5.6.7.Final + 6.0.6 + 3.0.3 + 6.1.7.Final true 9.0.0.M26 diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/creationupdatetimestamp/model/Book.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/creationupdatetimestamp/model/Book.java new file mode 100644 index 0000000000..0484c31ced --- /dev/null +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/creationupdatetimestamp/model/Book.java @@ -0,0 +1,57 @@ +package com.baeldung.hibernate.creationupdatetimestamp.model; + +import java.time.Instant; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.UpdateTimestamp; + +@Entity +public class Book { + @Id + @GeneratedValue + private Long id; + private String title; + @CreationTimestamp + private Instant createdOn; + @UpdateTimestamp + private Instant lastUpdatedOn; + + public Book() { + } + + 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; + } + + public Instant getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Instant createdOn) { + this.createdOn = createdOn; + } + + public Instant getLastUpdatedOn() { + return lastUpdatedOn; + } + + public void setLastUpdatedOn(Instant lastUpdatedOn) { + this.lastUpdatedOn = lastUpdatedOn; + } +} diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java index c10c67df9a..f50d8fd7cc 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java @@ -1,11 +1,11 @@ package com.baeldung.hibernate.customtypes; import org.hibernate.HibernateException; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.type.IntegerType; -import org.hibernate.type.StringType; -import org.hibernate.type.Type; +import org.hibernate.metamodel.spi.ValueAccess; import org.hibernate.usertype.CompositeUserType; +import org.hibernate.usertype.UserType; import java.io.Serializable; import java.sql.PreparedStatement; @@ -14,74 +14,51 @@ import java.sql.SQLException; import java.sql.Types; import java.util.Objects; -public class AddressType implements CompositeUserType { +public class AddressType implements CompositeUserType
, UserType
{ @Override - public String[] getPropertyNames() { - return new String[]{"addressLine1", "addressLine2", - "city", "country", "zipcode"}; - } - - @Override - public Type[] getPropertyTypes() { - return new Type[]{StringType.INSTANCE, StringType.INSTANCE, - StringType.INSTANCE, StringType.INSTANCE, IntegerType.INSTANCE}; - } - - @Override - public Object getPropertyValue(Object component, int property) throws HibernateException { - - Address empAdd = (Address) component; + public Object getPropertyValue(Address component, int property) throws HibernateException { switch (property) { case 0: - return empAdd.getAddressLine1(); + return component.getAddressLine1(); case 1: - return empAdd.getAddressLine2(); + return component.getAddressLine2(); case 2: - return empAdd.getCity(); + return component.getCity(); case 3: - return empAdd.getCountry(); + return component.getCountry(); case 4: - return Integer.valueOf(empAdd.getZipCode()); + return component.getZipCode(); + default: + throw new IllegalArgumentException(property + + " is an invalid property index for class type " + + component.getClass().getName()); } - - throw new IllegalArgumentException(property + - " is an invalid property index for class type " + - component.getClass().getName()); } @Override - public void setPropertyValue(Object component, int property, Object value) throws HibernateException { - - Address empAdd = (Address) component; - - switch (property) { - case 0: - empAdd.setAddressLine1((String) value); - case 1: - empAdd.setAddressLine2((String) value); - case 2: - empAdd.setCity((String) value); - case 3: - empAdd.setCountry((String) value); - case 4: - empAdd.setZipCode((Integer) value); - } - - throw new IllegalArgumentException(property + - " is an invalid property index for class type " + - component.getClass().getName()); - + public Address instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) { + return null; } @Override - public Class returnedClass() { + public Class embeddable() { return Address.class; } @Override - public boolean equals(Object x, Object y) throws HibernateException { + public int getSqlType() { + return Types.VARCHAR; + } + + @Override + public Class
returnedClass() { + return Address.class; + } + + @Override + public boolean equals(Address x, Address y) { if (x == y) return true; @@ -92,57 +69,52 @@ public class AddressType implements CompositeUserType { } @Override - public int hashCode(Object x) throws HibernateException { + public int hashCode(Address x) { return x.hashCode(); } @Override - public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException { - + public Address nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException { Address empAdd = new Address(); - empAdd.setAddressLine1(rs.getString(names[0])); + empAdd.setAddressLine1(rs.getString(position)); if (rs.wasNull()) return null; - empAdd.setAddressLine2(rs.getString(names[1])); - empAdd.setCity(rs.getString(names[2])); - empAdd.setCountry(rs.getString(names[3])); - empAdd.setZipCode(rs.getInt(names[4])); + empAdd.setAddressLine2(rs.getString(position)); + empAdd.setCity(rs.getString(position)); + empAdd.setCountry(rs.getString(position)); + empAdd.setZipCode(rs.getInt(position)); return empAdd; } @Override - public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException { - + public void nullSafeSet(PreparedStatement st, Address value, int index, SharedSessionContractImplementor session) throws SQLException { if (Objects.isNull(value)) st.setNull(index, Types.VARCHAR); else { - Address empAdd = (Address) value; - st.setString(index, empAdd.getAddressLine1()); - st.setString(index + 1, empAdd.getAddressLine2()); - st.setString(index + 2, empAdd.getCity()); - st.setString(index + 3, empAdd.getCountry()); - st.setInt(index + 4, empAdd.getZipCode()); + st.setString(index, value.getAddressLine1()); + st.setString(index + 1, value.getAddressLine2()); + st.setString(index + 2, value.getCity()); + st.setString(index + 3, value.getCountry()); + st.setInt(index + 4, value.getZipCode()); } } @Override - public Object deepCopy(Object value) throws HibernateException { - + public Address deepCopy(Address value) { if (Objects.isNull(value)) return null; - Address oldEmpAdd = (Address) value; Address newEmpAdd = new Address(); - newEmpAdd.setAddressLine1(oldEmpAdd.getAddressLine1()); - newEmpAdd.setAddressLine2(oldEmpAdd.getAddressLine2()); - newEmpAdd.setCity(oldEmpAdd.getCity()); - newEmpAdd.setCountry(oldEmpAdd.getCountry()); - newEmpAdd.setZipCode(oldEmpAdd.getZipCode()); + newEmpAdd.setAddressLine1(value.getAddressLine1()); + newEmpAdd.setAddressLine2(value.getAddressLine2()); + newEmpAdd.setCity(value.getCity()); + newEmpAdd.setCountry(value.getCountry()); + newEmpAdd.setZipCode(value.getZipCode()); return newEmpAdd; } @@ -153,17 +125,27 @@ public class AddressType implements CompositeUserType { } @Override - public Serializable disassemble(Object value, SharedSessionContractImplementor session) throws HibernateException { + public Serializable disassemble(Address value) { return (Serializable) deepCopy(value); } @Override - public Object assemble(Serializable cached, SharedSessionContractImplementor session, Object owner) throws HibernateException { - return deepCopy(cached); + public Address assemble(Serializable cached, Object owner) { + return deepCopy((Address) cached); } @Override - public Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner) throws HibernateException { - return original; + public Address replace(Address detached, Address managed, Object owner) { + return detached; + } + + @Override + public boolean isInstance(Object object, SessionFactoryImplementor sessionFactory) { + return CompositeUserType.super.isInstance(object, sessionFactory); + } + + @Override + public boolean isSameClass(Object object, SessionFactoryImplementor sessionFactory) { + return CompositeUserType.super.isSameClass(object, sessionFactory); } } diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java index 56be9e693f..8f1794b979 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java @@ -1,14 +1,14 @@ package com.baeldung.hibernate.customtypes; -import org.hibernate.type.LocalDateType; import org.hibernate.type.descriptor.WrapperOptions; -import org.hibernate.type.descriptor.java.AbstractTypeDescriptor; import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; -import org.hibernate.type.descriptor.java.MutabilityPlan; import java.time.LocalDate; +import java.time.format.DateTimeFormatter; -public class LocalDateStringJavaDescriptor extends AbstractTypeDescriptor { +import io.hypersistence.utils.hibernate.type.array.internal.AbstractArrayTypeDescriptor; + +public class LocalDateStringJavaDescriptor extends AbstractArrayTypeDescriptor { public static final LocalDateStringJavaDescriptor INSTANCE = new LocalDateStringJavaDescriptor(); @@ -18,12 +18,12 @@ public class LocalDateStringJavaDescriptor extends AbstractTypeDescriptor implements DiscriminatorType { +public class LocalDateStringType extends AbstractSingleColumnStandardBasicType { public static final LocalDateStringType INSTANCE = new LocalDateStringType(); public LocalDateStringType() { - super(VarcharTypeDescriptor.INSTANCE, LocalDateStringJavaDescriptor.INSTANCE); + super(VarcharJdbcType.INSTANCE, LocalDateStringJavaDescriptor.INSTANCE); } @Override @@ -21,14 +19,12 @@ public class LocalDateStringType extends AbstractSingleColumnStandardBasicType { -public class PhoneNumberType implements UserType { @Override - public int[] sqlTypes() { - return new int[]{Types.INTEGER, Types.INTEGER, Types.INTEGER}; + public int getSqlType() { + return Types.INTEGER; } @Override @@ -24,7 +23,7 @@ public class PhoneNumberType implements UserType { } @Override - public boolean equals(Object x, Object y) throws HibernateException { + public boolean equals(PhoneNumber x, PhoneNumber y) { if (x == y) return true; if (Objects.isNull(x) || Objects.isNull(y)) @@ -34,48 +33,42 @@ public class PhoneNumberType implements UserType { } @Override - public int hashCode(Object x) throws HibernateException { + public int hashCode(PhoneNumber x) { return x.hashCode(); } @Override - public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException { - int countryCode = rs.getInt(names[0]); + public PhoneNumber nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException { + int countryCode = rs.getInt(position); if (rs.wasNull()) return null; - int cityCode = rs.getInt(names[1]); - int number = rs.getInt(names[2]); - PhoneNumber employeeNumber = new PhoneNumber(countryCode, cityCode, number); + int cityCode = rs.getInt(position); + int number = rs.getInt(position); - return employeeNumber; + return new PhoneNumber(countryCode, cityCode, number); } @Override - public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException { - + public void nullSafeSet(PreparedStatement st, PhoneNumber value, int index, SharedSessionContractImplementor session) throws SQLException { if (Objects.isNull(value)) { st.setNull(index, Types.INTEGER); st.setNull(index+1, Types.INTEGER); st.setNull(index+2, Types.INTEGER); } else { - PhoneNumber employeeNumber = (PhoneNumber) value; - st.setInt(index,employeeNumber.getCountryCode()); - st.setInt(index+1,employeeNumber.getCityCode()); - st.setInt(index+2,employeeNumber.getNumber()); + st.setInt(index, value.getCountryCode()); + st.setInt(index+1, value.getCityCode()); + st.setInt(index+2, value.getNumber()); } } @Override - public Object deepCopy(Object value) throws HibernateException { + public PhoneNumber deepCopy(PhoneNumber value) { if (Objects.isNull(value)) return null; - PhoneNumber empNumber = (PhoneNumber) value; - PhoneNumber newEmpNumber = new PhoneNumber(empNumber.getCountryCode(),empNumber.getCityCode(),empNumber.getNumber()); - - return newEmpNumber; + return new PhoneNumber(value.getCountryCode(), value.getCityCode(), value.getNumber()); } @Override @@ -84,17 +77,17 @@ public class PhoneNumberType implements UserType { } @Override - public Serializable disassemble(Object value) throws HibernateException { + public Serializable disassemble(PhoneNumber value) { return (Serializable) value; } @Override - public Object assemble(Serializable cached, Object owner) throws HibernateException { - return cached; + public PhoneNumber assemble(Serializable cached, Object owner) { + return (PhoneNumber) cached; } @Override - public Object replace(Object original, Object target, Object owner) throws HibernateException { - return original; + public PhoneNumber replace(PhoneNumber detached, PhoneNumber managed, Object owner) { + return detached; } } diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java index 266b85140b..69e34c1363 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java @@ -1,12 +1,12 @@ package com.baeldung.hibernate.customtypes; import org.hibernate.HibernateException; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.type.LongType; -import org.hibernate.type.StringType; -import org.hibernate.type.Type; +import org.hibernate.metamodel.spi.ValueAccess; import org.hibernate.usertype.CompositeUserType; import org.hibernate.usertype.DynamicParameterizedType; +import org.hibernate.usertype.UserType; import java.io.Serializable; import java.sql.PreparedStatement; @@ -16,65 +16,47 @@ import java.sql.Types; import java.util.Objects; import java.util.Properties; -public class SalaryType implements CompositeUserType, DynamicParameterizedType { +public class SalaryType implements UserType, CompositeUserType, DynamicParameterizedType { private String localCurrency; @Override - public String[] getPropertyNames() { - return new String[]{"amount", "currency"}; - } - - @Override - public Type[] getPropertyTypes() { - return new Type[]{LongType.INSTANCE, StringType.INSTANCE}; - } - - @Override - public Object getPropertyValue(Object component, int property) throws HibernateException { - - Salary salary = (Salary) component; + public Object getPropertyValue(Salary component, int property) throws HibernateException { switch (property) { case 0: - return salary.getAmount(); + return component.getAmount(); case 1: - return salary.getCurrency(); + return component.getCurrency(); + default: + throw new IllegalArgumentException(property + + " is an invalid property index for class type " + + component.getClass().getName()); } - - throw new IllegalArgumentException(property + - " is an invalid property index for class type " + - component.getClass().getName()); - - } - - - @Override - public void setPropertyValue(Object component, int property, Object value) throws HibernateException { - - Salary salary = (Salary) component; - - switch (property) { - case 0: - salary.setAmount((Long) value); - case 1: - salary.setCurrency((String) value); - } - - throw new IllegalArgumentException(property + - " is an invalid property index for class type " + - component.getClass().getName()); - } @Override - public Class returnedClass() { + public Salary instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) { + return null; + } + + @Override + public Class embeddable() { return Salary.class; } @Override - public boolean equals(Object x, Object y) throws HibernateException { + public int getSqlType() { + return Types.BIGINT; + } + @Override + public Class returnedClass() { + return Salary.class; + } + + @Override + public boolean equals(Salary x, Salary y) { if (x == y) return true; @@ -82,54 +64,48 @@ public class SalaryType implements CompositeUserType, DynamicParameterizedType { return false; return x.equals(y); - } @Override - public int hashCode(Object x) throws HibernateException { + public int hashCode(Salary x) { return x.hashCode(); } @Override - public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException { - + public Salary nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException { Salary salary = new Salary(); - salary.setAmount(rs.getLong(names[0])); + salary.setAmount(rs.getLong(position)); if (rs.wasNull()) return null; - salary.setCurrency(rs.getString(names[1])); + salary.setCurrency(rs.getString(position)); return salary; } @Override - public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException { - - + public void nullSafeSet(PreparedStatement st, Salary value, int index, SharedSessionContractImplementor session) throws SQLException { if (Objects.isNull(value)) st.setNull(index, Types.BIGINT); else { - Salary salary = (Salary) value; - st.setLong(index, SalaryCurrencyConvertor.convert(salary.getAmount(), - salary.getCurrency(), localCurrency)); - st.setString(index + 1, salary.getCurrency()); + st.setLong(index, SalaryCurrencyConvertor.convert( + value.getAmount(), + value.getCurrency(), localCurrency)); + st.setString(index + 1, value.getCurrency()); } } @Override - public Object deepCopy(Object value) throws HibernateException { - + public Salary deepCopy(Salary value) { if (Objects.isNull(value)) return null; - Salary oldSal = (Salary) value; Salary newSal = new Salary(); - newSal.setAmount(oldSal.getAmount()); - newSal.setCurrency(oldSal.getCurrency()); + newSal.setAmount(value.getAmount()); + newSal.setCurrency(value.getCurrency()); return newSal; } @@ -140,18 +116,18 @@ public class SalaryType implements CompositeUserType, DynamicParameterizedType { } @Override - public Serializable disassemble(Object value, SharedSessionContractImplementor session) throws HibernateException { + public Serializable disassemble(Salary value) { return (Serializable) deepCopy(value); } @Override - public Object assemble(Serializable cached, SharedSessionContractImplementor session, Object owner) throws HibernateException { - return deepCopy(cached); + public Salary assemble(Serializable cached, Object owner) { + return deepCopy((Salary) cached); } @Override - public Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner) throws HibernateException { - return original; + public Salary replace(Salary detached, Salary managed, Object owner) { + return detached; } @Override diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java index ec88d629a6..f16aa68475 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java @@ -4,7 +4,7 @@ import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; import org.hibernate.annotations.Immutable; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.Set; @Entity diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/entities/EventGeneratedId.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/entities/EventGeneratedId.java index 33af9313ae..6bf4006550 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/entities/EventGeneratedId.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/immutable/entities/EventGeneratedId.java @@ -3,7 +3,7 @@ package com.baeldung.hibernate.immutable.entities; import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Immutable; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Immutable diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/Email.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/Email.java index df07c3cf69..096faf7984 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/Email.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/Email.java @@ -1,12 +1,12 @@ package com.baeldung.hibernate.joincolumn; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; @Entity public class Email { diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/Office.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/Office.java index 9940577761..3c6e5f4642 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/Office.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/Office.java @@ -1,13 +1,13 @@ package com.baeldung.hibernate.joincolumn; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinColumns; -import javax.persistence.ManyToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinColumns; +import jakarta.persistence.ManyToOne; @Entity public class Office { diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/OfficeAddress.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/OfficeAddress.java index cc723db6a2..d80a8be026 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/OfficeAddress.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/OfficeAddress.java @@ -1,10 +1,10 @@ package com.baeldung.hibernate.joincolumn; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class OfficeAddress { diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/OfficialEmployee.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/OfficialEmployee.java index 49c63c7578..551b522700 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/OfficialEmployee.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/joincolumn/OfficialEmployee.java @@ -1,12 +1,12 @@ package com.baeldung.hibernate.joincolumn; import java.util.List; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; @Entity public class OfficialEmployee { diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/lazycollection/model/Branch.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/lazycollection/model/Branch.java index de88647546..9957e2ce75 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/lazycollection/model/Branch.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/lazycollection/model/Branch.java @@ -3,12 +3,12 @@ package com.baeldung.hibernate.lazycollection.model; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OrderColumn; -import javax.persistence.OneToMany; -import javax.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OrderColumn; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Entity; import java.util.ArrayList; import java.util.List; diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/lazycollection/model/Employee.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/lazycollection/model/Employee.java index 831518a365..edf89696f5 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/lazycollection/model/Employee.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/lazycollection/model/Employee.java @@ -1,11 +1,10 @@ package com.baeldung.hibernate.lazycollection.model; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OrderColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Entity; @Entity public class Employee { diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java index ef82c1c9ad..99410e1f76 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java @@ -43,8 +43,8 @@ public class HibernateAnnotationUtil { return metadata.buildSessionFactory(); } - private static Map dbSettings() { - Map dbSettings = new HashMap<>(); + private static Map dbSettings() { + Map dbSettings = new HashMap<>(); dbSettings.put(Environment.URL, "jdbc:h2:mem:spring_hibernate_one_to_many"); dbSettings.put(Environment.USER, "sa"); dbSettings.put(Environment.PASS, ""); diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java index 53878af445..f07f3d3887 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java @@ -2,13 +2,13 @@ package com.baeldung.hibernate.oneToMany.model; import java.util.Set; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; @Entity @Table(name = "CART") diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java index 27b28a6753..f279cc4ea6 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java @@ -1,13 +1,13 @@ package com.baeldung.hibernate.oneToMany.model; import java.util.Set; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; @Entity @Table(name = "CARTOIO") diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Item.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Item.java index a055682d0d..5babe9c545 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Item.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Item.java @@ -1,13 +1,13 @@ package com.baeldung.hibernate.oneToMany.model; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; @Entity @Table(name = "ITEMS") diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemOIO.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemOIO.java index baaf57b106..78139da19e 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemOIO.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemOIO.java @@ -1,12 +1,12 @@ package com.baeldung.hibernate.oneToMany.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; @Entity @Table(name = "ITEMSOIO") diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/pojo/Phone.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/pojo/Phone.java index d923bda5de..e173aa8b47 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/pojo/Phone.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/pojo/Phone.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.pojo; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; import java.io.Serializable; @Entity diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/Group.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/Group.java index 04684eceac..2b17c9218d 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/Group.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/Group.java @@ -3,10 +3,10 @@ package com.baeldung.hibernate.wherejointable; import java.util.ArrayList; import java.util.List; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.ManyToMany; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; @Entity(name = "e_group") public class Group { diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/User.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/User.java index 3029aae640..a517de3cca 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/User.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/User.java @@ -3,12 +3,12 @@ package com.baeldung.hibernate.wherejointable; import java.util.ArrayList; import java.util.List; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; import org.hibernate.annotations.WhereJoinTable; diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/UserGroupRelation.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/UserGroupRelation.java index 00dd19699c..21a0a443c6 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/UserGroupRelation.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/UserGroupRelation.java @@ -2,11 +2,11 @@ package com.baeldung.hibernate.wherejointable; import java.io.Serializable; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Id; @Entity(name = "r_user_group") public class UserGroupRelation implements Serializable { diff --git a/persistence-modules/hibernate-annotations/src/main/resources/META-INF/persistence.xml b/persistence-modules/hibernate-annotations/src/main/resources/META-INF/persistence.xml index 474eeb7a44..2915125295 100644 --- a/persistence-modules/hibernate-annotations/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/hibernate-annotations/src/main/resources/META-INF/persistence.xml @@ -7,12 +7,12 @@ Hibernate EntityManager Demo true - + - - - - + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/creationupdatetimestamp/HibernateCreationUpdateTimestampIntegrationTest.java b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/creationupdatetimestamp/HibernateCreationUpdateTimestampIntegrationTest.java new file mode 100644 index 0000000000..a0f3c1ee97 --- /dev/null +++ b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/creationupdatetimestamp/HibernateCreationUpdateTimestampIntegrationTest.java @@ -0,0 +1,124 @@ +package com.baeldung.hibernate.creationupdatetimestamp; + +import static org.hibernate.FlushMode.MANUAL; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.util.Date; + +import org.h2.Driver; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Configuration; +import org.hibernate.dialect.H2Dialect; +import org.hibernate.service.ServiceRegistry; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import com.baeldung.hibernate.creationupdatetimestamp.model.Book; + +class HibernateCreationUpdateTimestampIntegrationTest { + + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeAll + public static void beforeTests() { + Configuration configuration = new Configuration().addAnnotatedClass(Book.class) + .setProperty("hibernate.dialect", H2Dialect.class.getName()) + .setProperty("hibernate.connection.driver_class", Driver.class.getName()) + .setProperty("hibernate.connection.url", "jdbc:h2:mem:test") + .setProperty("hibernate.connection.username", "sa") + .setProperty("hibernate.connection.password", "") + .setProperty("hibernate.hbm2ddl.auto", "update"); + + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()) + .build(); + + sessionFactory = configuration.buildSessionFactory(serviceRegistry); + } + + @Test + void whenCreatingEntity_ThenCreatedOnIsSet() { + session = sessionFactory.openSession(); + session.beginTransaction(); + Book book = new Book(); + + session.save(book); + session.getTransaction() + .commit(); + session.close(); + + assertNotNull(book.getCreatedOn()); + } + + @Test + void whenCreatingEntity_ThenCreatedOnAndLastUpdatedOnAreBothSet() { + session = sessionFactory.openSession(); + session.beginTransaction(); + Book book = new Book(); + + session.save(book); + session.getTransaction() + .commit(); + session.close(); + + assertNotNull(book.getCreatedOn()); + assertNotNull(book.getLastUpdatedOn()); + } + + @Test + void whenCreatingEntity_ThenCreatedOnAndLastUpdatedOnAreEqual() { + session = sessionFactory.openSession(); + session.beginTransaction(); + Book book = new Book(); + + session.save(book); + session.getTransaction().commit(); + session.close(); + + Date createdOn = Date.from(book.getCreatedOn()); + Date lastUpdatedOn = Date.from(book.getLastUpdatedOn()); + SimpleDateFormat formatter = new SimpleDateFormat("dd MM yyyy HH:mm:ss"); + + assertEquals(formatter.format(createdOn), formatter.format(lastUpdatedOn)); + } + + @Test + void whenUpdatingEntity_ThenLastUpdatedOnIsUpdatedAndCreatedOnStaysTheSame() { + session = sessionFactory.openSession(); + session.setHibernateFlushMode(MANUAL); + session.beginTransaction(); + Book book = new Book(); + session.save(book); + session.flush(); + Instant createdOnAfterCreation = book.getCreatedOn(); + Instant lastUpdatedOnAfterCreation = book.getLastUpdatedOn(); + + String newName = "newName"; + book.setTitle(newName); + session.save(book); + session.flush(); + session.getTransaction().commit(); + session.close(); + Instant createdOnAfterUpdate = book.getCreatedOn(); + Instant lastUpdatedOnAfterUpdate = book.getLastUpdatedOn(); + + assertEquals(newName, book.getTitle()); + assertNotNull(createdOnAfterUpdate); + assertNotNull(lastUpdatedOnAfterUpdate); + assertEquals(createdOnAfterCreation, createdOnAfterUpdate); + assertNotEquals(lastUpdatedOnAfterCreation, lastUpdatedOnAfterUpdate); + } + + @AfterAll + static void afterTests() { + sessionFactory.close(); + } +} diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java index 460b65ee12..9da3a90034 100644 --- a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java +++ b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java @@ -6,10 +6,9 @@ import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Environment; import org.hibernate.service.ServiceRegistry; -import org.junit.Assert; import org.junit.Test; -import javax.persistence.TypedQuery; +import jakarta.persistence.TypedQuery; import java.time.LocalDate; import java.util.HashMap; import java.util.Map; @@ -76,7 +75,7 @@ public class HibernateCustomTypesIntegrationTest { doInHibernate(this::sessionFactory, session -> { session.save(e); - TypedQuery query = session.createQuery("FROM OfficeEmployee OE WHERE OE.empAddress.zipcode = :pinCode", OfficeEmployee.class); + TypedQuery query = session.createQuery("FROM OfficeEmployee OE WHERE OE.empAddress.zipCode = :pinCode", OfficeEmployee.class); query.setParameter("pinCode",100); int size = query.getResultList().size(); @@ -100,8 +99,8 @@ public class HibernateCustomTypesIntegrationTest { return metadata.buildSessionFactory(); } - private static Map getProperties() { - Map dbSettings = new HashMap<>(); + private static Map getProperties() { + Map dbSettings = new HashMap<>(); dbSettings.put(Environment.URL, "jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1"); dbSettings.put(Environment.USER, "sa"); dbSettings.put(Environment.PASS, ""); diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java index 270a235ef0..f038d2b16d 100644 --- a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java +++ b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java @@ -8,7 +8,7 @@ import org.hibernate.Session; import org.junit.*; import org.junit.rules.ExpectedException; -import javax.persistence.PersistenceException; +import jakarta.persistence.PersistenceException; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsEqual.equalTo; diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java index 37125e8b15..04f0613811 100644 --- a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java +++ b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java @@ -78,8 +78,8 @@ public class JoinColumnIntegrationTest { return metadata.buildSessionFactory(); } - private static Map getProperties() { - Map dbSettings = new HashMap<>(); + private static Map getProperties() { + Map dbSettings = new HashMap<>(); dbSettings.put(Environment.URL, "jdbc:h2:mem:mydbJoinColumn;DB_CLOSE_DELAY=-1"); dbSettings.put(Environment.USER, "sa"); dbSettings.put(Environment.PASS, ""); diff --git a/persistence-modules/hibernate-enterprise/pom.xml b/persistence-modules/hibernate-enterprise/pom.xml index 833f19c673..eaa7b0e765 100644 --- a/persistence-modules/hibernate-enterprise/pom.xml +++ b/persistence-modules/hibernate-enterprise/pom.xml @@ -78,10 +78,11 @@ - 5.3.7.Final - 6.0.6 - 2.2.3 + 6.1.7.Final + 8.0.32 + 2.6.0 0.9 + 1.14.2 \ No newline at end of file diff --git a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/EntityWithNoId.java b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/EntityWithNoId.java index 989fa1281a..8ef7487804 100644 --- a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/EntityWithNoId.java +++ b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/EntityWithNoId.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.exception; -import javax.persistence.Entity; +import jakarta.persistence.Entity; @Entity public class EntityWithNoId { diff --git a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/Product.java b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/Product.java index 0724ced56b..b7e80511e6 100644 --- a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/Product.java +++ b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/Product.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.exception; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "PRODUCT") diff --git a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/ProductEntity.java b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/ProductEntity.java index b9c5f5010d..a2dcec61e9 100644 --- a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/ProductEntity.java +++ b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/ProductEntity.java @@ -1,8 +1,8 @@ package com.baeldung.hibernate.exception; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "PRODUCT") diff --git a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/ProductNotMapped.java b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/ProductNotMapped.java new file mode 100644 index 0000000000..827ad15e5b --- /dev/null +++ b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/exception/ProductNotMapped.java @@ -0,0 +1,32 @@ +package com.baeldung.hibernate.exception; + +public class ProductNotMapped { + + private int id; + private String name; + private String description; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/logging/Employee.java b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/logging/Employee.java index 9dcf4058a7..bc50c11d81 100644 --- a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/logging/Employee.java +++ b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/logging/Employee.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.logging; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Employee { diff --git a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java index 736abde866..23b9a87eef 100644 --- a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java +++ b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java @@ -1,11 +1,11 @@ package com.baeldung.hibernate.pojo; -import com.vividsolutions.jts.geom.Point; +import org.locationtech.jts.geom.Point; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; @Entity public class PointEntity { diff --git a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/pojo/PolygonEntity.java b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/pojo/PolygonEntity.java index 69208c8cd4..32cb146f23 100644 --- a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/pojo/PolygonEntity.java +++ b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/pojo/PolygonEntity.java @@ -1,10 +1,10 @@ package com.baeldung.hibernate.pojo; -import com.vividsolutions.jts.geom.Polygon; +import org.locationtech.jts.geom.Polygon; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; @Entity public class PolygonEntity { diff --git a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/pojo/Student.java b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/pojo/Student.java index 9b26c117eb..263908a5fc 100644 --- a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/pojo/Student.java +++ b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/hibernate/pojo/Student.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.pojo; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Student { diff --git a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/persistence/model/Person.java b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/persistence/model/Person.java index 6a95a7acf5..3766639975 100644 --- a/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/persistence/model/Person.java +++ b/persistence-modules/hibernate-enterprise/src/main/java/com/baeldung/persistence/model/Person.java @@ -1,8 +1,8 @@ package com.baeldung.persistence.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; @Entity public class Person { diff --git a/persistence-modules/hibernate-enterprise/src/main/resources/META-INF/persistence.xml b/persistence-modules/hibernate-enterprise/src/main/resources/META-INF/persistence.xml index 474eeb7a44..2915125295 100644 --- a/persistence-modules/hibernate-enterprise/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/hibernate-enterprise/src/main/resources/META-INF/persistence.xml @@ -7,12 +7,12 @@ Hibernate EntityManager Demo true - + - - - - + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/HibernateSpatialIntegrationTest.java b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/HibernateSpatialIntegrationTest.java index 74f752ab8c..e0f13582ab 100644 --- a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/HibernateSpatialIntegrationTest.java +++ b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/HibernateSpatialIntegrationTest.java @@ -9,23 +9,23 @@ import java.io.IOException; import java.net.URL; import java.util.Properties; -import javax.persistence.Query; +import jakarta.persistence.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.io.ParseException; +import org.locationtech.jts.io.WKTReader; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; +import org.locationtech.jts.util.GeometricShapeFactory; import com.baeldung.hibernate.pojo.PointEntity; import com.baeldung.hibernate.pojo.PolygonEntity; -import com.vividsolutions.jts.geom.Coordinate; -import com.vividsolutions.jts.geom.Geometry; -import com.vividsolutions.jts.geom.Point; -import com.vividsolutions.jts.geom.Polygon; -import com.vividsolutions.jts.io.ParseException; -import com.vividsolutions.jts.io.WKTReader; -import com.vividsolutions.jts.util.GeometricShapeFactory; import geodb.GeoDB; @@ -39,7 +39,7 @@ public class HibernateSpatialIntegrationTest { session = HibernateUtil.getSessionFactory("hibernate-spatial.properties") .openSession(); transaction = session.beginTransaction(); - session.doWork(conn -> { GeoDB.InitGeoDB(conn); }); + session.doWork(GeoDB::InitGeoDB); } @After @@ -135,9 +135,7 @@ public class HibernateSpatialIntegrationTest { private Geometry wktToGeometry(String wellKnownText) throws ParseException { WKTReader fromText = new WKTReader(); - Geometry geom = null; - geom = fromText.read(wellKnownText); - return geom; + return fromText.read(wellKnownText); } private static Geometry createCircle(double x, double y, double radius) { diff --git a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/exception/HibernateExceptionUnitTest.java b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/exception/HibernateExceptionUnitTest.java index 891352843d..37c21d1899 100644 --- a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/exception/HibernateExceptionUnitTest.java +++ b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/exception/HibernateExceptionUnitTest.java @@ -6,28 +6,25 @@ import static org.junit.Assert.assertNotNull; import java.io.IOException; import java.util.List; -import javax.persistence.OptimisticLockException; -import javax.persistence.PersistenceException; +import jakarta.persistence.OptimisticLockException; +import jakarta.persistence.PersistenceException; -import org.hibernate.AnnotationException; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.NonUniqueObjectException; import org.hibernate.PropertyValueException; import org.hibernate.Session; import org.hibernate.SessionFactory; -import org.hibernate.StaleObjectStateException; import org.hibernate.StaleStateException; import org.hibernate.Transaction; -import org.hibernate.TransactionException; import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Configuration; import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.DataException; import org.hibernate.exception.SQLGrammarException; -import org.hibernate.hql.internal.ast.QuerySyntaxException; import org.hibernate.id.IdentifierGenerationException; import org.hibernate.query.NativeQuery; +import org.hibernate.query.sqm.UnknownEntityException; import org.hibernate.tool.schema.spi.CommandAcceptanceException; import org.hibernate.tool.schema.spi.SchemaManagementException; import org.junit.Before; @@ -63,12 +60,15 @@ public class HibernateExceptionUnitTest { @Test public void whenQueryExecutedWithUnmappedEntity_thenMappingException() { - thrown.expectCause(isA(MappingException.class)); - thrown.expectMessage("Unknown entity: java.lang.String"); + thrown.expect(isA(MappingException.class)); + thrown.expectMessage("Unable to locate persister: com.baeldung.hibernate.exception.ProductNotMapped"); + + ProductNotMapped product = new ProductNotMapped(); + product.setId(1); + product.setName("test"); Session session = sessionFactory.openSession(); - NativeQuery query = session.createNativeQuery("select name from PRODUCT", String.class); - query.getResultList(); + session.save(product); } @Test @@ -82,8 +82,8 @@ public class HibernateExceptionUnitTest { @Test public void whenQueryExecutedWithInvalidClassName_thenQuerySyntaxException() { - thrown.expectCause(isA(QuerySyntaxException.class)); - thrown.expectMessage("PRODUCT is not mapped [from PRODUCT]"); + thrown.expectCause(isA(UnknownEntityException.class)); + thrown.expectMessage("Could not resolve root entity 'PRODUCT"); Session session = sessionFactory.openSession(); List results = session.createQuery("from PRODUCT", Product.class) @@ -92,8 +92,8 @@ public class HibernateExceptionUnitTest { @Test public void givenEntityWithoutId_whenSessionFactoryCreated_thenAnnotationException() { - thrown.expect(AnnotationException.class); - thrown.expectMessage("No identifier specified for entity"); + thrown.expect(isA(HibernateException.class)); + thrown.expectMessage("Entity 'com.baeldung.hibernate.exception.EntityWithNoId' has no identifier (every '@Entity' class must declare or inherit at least one '@Id' or '@EmbeddedId' property)"); Configuration cfg = getConfiguration(); cfg.addAnnotatedClass(EntityWithNoId.class); @@ -132,9 +132,8 @@ public class HibernateExceptionUnitTest { @Test public void givenMissingTable_whenEntitySaved_thenSQLGrammarException() { - thrown.expect(isA(PersistenceException.class)); thrown.expectCause(isA(SQLGrammarException.class)); - thrown.expectMessage("SQLGrammarException: could not prepare statement"); + thrown.expectMessage("could not prepare statement"); Configuration cfg = getConfiguration(); cfg.addAnnotatedClass(Product.class); @@ -162,9 +161,8 @@ public class HibernateExceptionUnitTest { @Test public void givenMissingTable_whenQueryExecuted_thenSQLGrammarException() { - thrown.expect(isA(PersistenceException.class)); thrown.expectCause(isA(SQLGrammarException.class)); - thrown.expectMessage("SQLGrammarException: could not prepare statement"); + thrown.expectMessage("could not prepare statement"); Session session = sessionFactory.openSession(); NativeQuery query = session.createNativeQuery("select * from NON_EXISTING_TABLE", Product.class); @@ -173,9 +171,8 @@ public class HibernateExceptionUnitTest { @Test public void whenDuplicateIdSaved_thenConstraintViolationException() { - thrown.expect(isA(PersistenceException.class)); thrown.expectCause(isA(ConstraintViolationException.class)); - thrown.expectMessage("ConstraintViolationException: could not execute statement"); + thrown.expectMessage("could not execute statement"); Session session = null; Transaction transaction = null; @@ -253,7 +250,7 @@ public class HibernateExceptionUnitTest { @Test public void givenQueryWithDataTypeMismatch_WhenQueryExecuted_thenDataException() { thrown.expectCause(isA(DataException.class)); - thrown.expectMessage("org.hibernate.exception.DataException: could not prepare statement"); + thrown.expectMessage("could not prepare statement"); Session session = sessionFactory.openSession(); NativeQuery query = session.createNativeQuery("select * from PRODUCT where id='wrongTypeId'", Product.class); @@ -330,9 +327,8 @@ public class HibernateExceptionUnitTest { @Test public void whenUpdatingNonExistingObject_thenStaleStateException() { - thrown.expect(isA(OptimisticLockException.class)); - thrown.expectMessage("Row was updated or deleted by another transaction"); - thrown.expectCause(isA(StaleObjectStateException.class)); + thrown.expectCause(isA(StaleStateException.class)); + thrown.expectMessage("Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; statement executed: update PRODUCT set description=?, name=? where id=?"); Session session = null; Transaction transaction = null; @@ -356,7 +352,8 @@ public class HibernateExceptionUnitTest { @Test public void givenTxnMarkedRollbackOnly_whenCommitted_thenTransactionException() { - thrown.expect(isA(TransactionException.class)); + thrown.expect(isA(IllegalStateException.class)); + thrown.expectMessage("Transaction already active"); Session session = null; Transaction transaction = null; @@ -368,6 +365,7 @@ public class HibernateExceptionUnitTest { product1.setId(15); product1.setName("Product1"); session.save(product1); + transaction = session.beginTransaction(); transaction.setRollbackOnly(); transaction.commit(); diff --git a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/Car.java b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/Car.java index 1b6cee7e67..3e4895e5e6 100644 --- a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/Car.java +++ b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/Car.java @@ -2,9 +2,9 @@ package com.baeldung.hibernate.multitenancy; import java.io.Serializable; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity(name = "Car") @Table(name = "Car") diff --git a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/MultitenancyIntegrationTest.java b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/MultitenancyIntegrationTest.java index fdc3f9fa81..2dc94172b1 100644 --- a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/MultitenancyIntegrationTest.java +++ b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/MultitenancyIntegrationTest.java @@ -79,9 +79,9 @@ public abstract class MultitenancyIntegrationTest { private void createCarTable() { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); - session.createSQLQuery("drop table Car if exists") + session.createNativeQuery("drop table Car if exists") .executeUpdate(); - session.createSQLQuery("create table Car (brand varchar(255) primary key)") + session.createNativeQuery("create table Car (brand varchar(255) primary key)") .executeUpdate(); tx.commit(); } diff --git a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/database/DatabaseApproachMultitenancyIntegrationTest.java b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/database/DatabaseApproachMultitenancyIntegrationTest.java index 92f477a646..904805f2ce 100644 --- a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/database/DatabaseApproachMultitenancyIntegrationTest.java +++ b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/database/DatabaseApproachMultitenancyIntegrationTest.java @@ -1,7 +1,5 @@ package com.baeldung.hibernate.multitenancy.database; -import java.io.IOException; - import org.junit.Test; import com.baeldung.hibernate.multitenancy.MultitenancyIntegrationTest; @@ -14,7 +12,7 @@ public class DatabaseApproachMultitenancyIntegrationTest extends MultitenancyInt } @Test - public void givenDatabaseApproach_whenAddingEntries_thenOnlyAddedToConcreteDatabase() throws IOException { + public void givenDatabaseApproach_whenAddingEntries_thenOnlyAddedToConcreteDatabase() { whenCurrentTenantIs(TenantIdNames.MYDB1); whenAddCar("myCar"); thenCarFound("myCar"); diff --git a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/database/MapMultiTenantConnectionProvider.java b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/database/MapMultiTenantConnectionProvider.java index eb1f410622..47abf6ff85 100644 --- a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/database/MapMultiTenantConnectionProvider.java +++ b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/database/MapMultiTenantConnectionProvider.java @@ -34,8 +34,13 @@ public class MapMultiTenantConnectionProvider extends AbstractMultiTenantConnect private void initConnectionProviderForTenant(String tenantId) throws IOException { Properties properties = new Properties(); properties.load(getClass().getResourceAsStream(String.format("/hibernate-database-%s.properties", tenantId))); + Map configProperties = new HashMap<>(); + for (String key : properties.stringPropertyNames()) { + String value = properties.getProperty(key); + configProperties.put(key, value); + } DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl(); - connectionProvider.configure(properties); + connectionProvider.configure(configProperties); this.connectionProviderMap.put(tenantId, connectionProvider); } diff --git a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/schema/SchemaMultiTenantConnectionProvider.java b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/schema/SchemaMultiTenantConnectionProvider.java index 601eba651c..67b838fdf1 100644 --- a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/schema/SchemaMultiTenantConnectionProvider.java +++ b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/hibernate/multitenancy/schema/SchemaMultiTenantConnectionProvider.java @@ -3,6 +3,8 @@ package com.baeldung.hibernate.multitenancy.schema; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; @@ -39,9 +41,14 @@ public class SchemaMultiTenantConnectionProvider extends AbstractMultiTenantConn private ConnectionProvider initConnectionProvider() throws IOException { Properties properties = new Properties(); properties.load(getClass().getResourceAsStream("/hibernate-schema-multitenancy.properties")); + Map configProperties = new HashMap<>(); + for (String key : properties.stringPropertyNames()) { + String value = properties.getProperty(key); + configProperties.put(key, value); + } DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl(); - connectionProvider.configure(properties); + connectionProvider.configure(configProperties); return connectionProvider; } diff --git a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/persistence/save/SaveMethodsIntegrationTest.java b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/persistence/save/SaveMethodsIntegrationTest.java index 8c571428b4..c3d2362339 100644 --- a/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/persistence/save/SaveMethodsIntegrationTest.java +++ b/persistence-modules/hibernate-enterprise/src/test/java/com/baeldung/persistence/save/SaveMethodsIntegrationTest.java @@ -7,7 +7,7 @@ import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; -import javax.persistence.PersistenceException; +import jakarta.persistence.PersistenceException; import org.hibernate.HibernateException; import org.hibernate.Session; diff --git a/persistence-modules/hibernate-enterprise/src/test/resources/hibernate-exception.properties b/persistence-modules/hibernate-enterprise/src/test/resources/hibernate-exception.properties index e08a23166d..1e086f60d4 100644 --- a/persistence-modules/hibernate-enterprise/src/test/resources/hibernate-exception.properties +++ b/persistence-modules/hibernate-enterprise/src/test/resources/hibernate-exception.properties @@ -12,5 +12,3 @@ hibernate.c3p0.min_size=5 hibernate.c3p0.max_size=20 hibernate.c3p0.acquire_increment=5 hibernate.c3p0.timeout=1800 - -hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory diff --git a/persistence-modules/hibernate-enterprise/src/test/resources/hibernate-spatial.properties b/persistence-modules/hibernate-enterprise/src/test/resources/hibernate-spatial.properties index c16666cbf5..e156965ce7 100644 --- a/persistence-modules/hibernate-enterprise/src/test/resources/hibernate-spatial.properties +++ b/persistence-modules/hibernate-enterprise/src/test/resources/hibernate-spatial.properties @@ -4,7 +4,7 @@ hibernate.connection.username=sa hibernate.connection.autocommit=true jdbc.password= -hibernate.dialect=org.hibernate.spatial.dialect.h2geodb.GeoDBDialect +hibernate.dialect=org.hibernate.dialect.H2Dialect hibernate.show_sql=true hibernate.hbm2ddl.auto=create-drop diff --git a/persistence-modules/hibernate-exceptions/pom.xml b/persistence-modules/hibernate-exceptions/pom.xml index 4bef688715..670ff4cdb8 100644 --- a/persistence-modules/hibernate-exceptions/pom.xml +++ b/persistence-modules/hibernate-exceptions/pom.xml @@ -24,11 +24,6 @@ hibernate-core ${hibernate.version} - - javax.xml.bind - jaxb-api - ${jaxb.version} - com.h2database h2 @@ -37,8 +32,7 @@ - 2.4.0 - 2.3.0 + 2.7.1 2.1.214 diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/entitynotfoundexception/Category.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/entitynotfoundexception/Category.java index 25d31d50c7..cab06ae9cf 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/entitynotfoundexception/Category.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/entitynotfoundexception/Category.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.entitynotfoundexception; -import javax.persistence.*; +import jakarta.persistence.*; import java.io.Serializable; import java.util.ArrayList; import java.util.List; diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/entitynotfoundexception/Item.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/entitynotfoundexception/Item.java index 3abed00eb8..2d07178aaf 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/entitynotfoundexception/Item.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/entitynotfoundexception/Item.java @@ -1,9 +1,6 @@ package com.baeldung.hibernate.entitynotfoundexception; -import org.hibernate.annotations.NotFound; -import org.hibernate.annotations.NotFoundAction; - -import javax.persistence.*; +import jakarta.persistence.*; import java.io.Serializable; @Entity diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/entitynotfoundexception/User.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/entitynotfoundexception/User.java index d89047195c..8351c5df96 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/entitynotfoundexception/User.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/entitynotfoundexception/User.java @@ -1,7 +1,7 @@ package com.baeldung.hibernate.entitynotfoundexception; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; @Entity public class User { diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/detachedentity/entity/Comment.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/detachedentity/entity/Comment.java index 4a3e9739e2..e73adfef6b 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/detachedentity/entity/Comment.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/detachedentity/entity/Comment.java @@ -1,10 +1,10 @@ package com.baeldung.hibernate.exception.detachedentity.entity; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; @Entity public class Comment { diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/detachedentity/entity/Post.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/detachedentity/entity/Post.java index 7d95b41948..155a1bfe69 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/detachedentity/entity/Post.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/detachedentity/entity/Post.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.exception.detachedentity.entity; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Post { diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/lazyinitialization/entity/Role.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/lazyinitialization/entity/Role.java index c15e674c52..5e613004a3 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/lazyinitialization/entity/Role.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/lazyinitialization/entity/Role.java @@ -1,11 +1,11 @@ package com.baeldung.hibernate.exception.lazyinitialization.entity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "role") diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/lazyinitialization/entity/User.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/lazyinitialization/entity/User.java index 5bd7e00801..ffae05c0a0 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/lazyinitialization/entity/User.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/lazyinitialization/entity/User.java @@ -3,14 +3,14 @@ package com.baeldung.hibernate.exception.lazyinitialization.entity; import java.util.HashSet; import java.util.Set; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; @Entity @Table(name = "user") diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Article.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Article.java index 3c9c7c5b31..eb697334ae 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Article.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Article.java @@ -1,10 +1,10 @@ package com.baeldung.hibernate.exception.persistentobject.entity; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; @Entity public class Article { diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Author.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Author.java index fa6aaa9abe..f8dcb82b7e 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Author.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Author.java @@ -2,12 +2,11 @@ package com.baeldung.hibernate.exception.persistentobject.entity; import java.util.List; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Book.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Book.java index 342da27c77..986c7f061f 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Book.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Book.java @@ -1,11 +1,10 @@ package com.baeldung.hibernate.exception.persistentobject.entity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Book { diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Address.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Address.java index e450fc3c18..8d1208e036 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Address.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Address.java @@ -1,18 +1,12 @@ package com.baeldung.hibernate.exception.transientobject.entity; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; @Entity @Table(name = "address") diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Author.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Author.java index f1a88daa36..271e810002 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Author.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Author.java @@ -3,15 +3,14 @@ package com.baeldung.hibernate.exception.transientobject.entity; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; import java.util.HashSet; import java.util.Set; diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Book.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Book.java index 91728430ea..0734cccff1 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Book.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Book.java @@ -4,15 +4,14 @@ package com.baeldung.hibernate.exception.transientobject.entity; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToMany; -import javax.persistence.OneToMany; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; import java.util.HashSet; import java.util.Set; diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Department.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Department.java index 4b8fa69964..5bd9a109ab 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Department.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Department.java @@ -1,13 +1,13 @@ package com.baeldung.hibernate.exception.transientobject.entity; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; import java.util.HashSet; import java.util.Set; diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Employee.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Employee.java index 56443cce70..6a2ec8b938 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Employee.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/Employee.java @@ -4,15 +4,14 @@ package com.baeldung.hibernate.exception.transientobject.entity; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; @Entity @Table(name = "employee") diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/User.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/User.java index eff1a88b51..cf56afd8b9 100644 --- a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/User.java +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/transientobject/entity/User.java @@ -1,19 +1,14 @@ package com.baeldung.hibernate.exception.transientobject.entity; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; @Entity @Table(name = "user") diff --git a/persistence-modules/hibernate-exceptions/src/test/java/com/baeldung/hibernate/entitynotfoundexception/EntityNotFoundExceptionIntegrationTest.java b/persistence-modules/hibernate-exceptions/src/test/java/com/baeldung/hibernate/entitynotfoundexception/EntityNotFoundExceptionIntegrationTest.java index bcb4e3eb95..f339afd536 100644 --- a/persistence-modules/hibernate-exceptions/src/test/java/com/baeldung/hibernate/entitynotfoundexception/EntityNotFoundExceptionIntegrationTest.java +++ b/persistence-modules/hibernate-exceptions/src/test/java/com/baeldung/hibernate/entitynotfoundexception/EntityNotFoundExceptionIntegrationTest.java @@ -4,10 +4,10 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityNotFoundException; -import javax.persistence.Persistence; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityNotFoundException; +import jakarta.persistence.Persistence; import java.io.IOException; public class EntityNotFoundExceptionIntegrationTest { diff --git a/persistence-modules/hibernate-exceptions/src/test/java/com/baeldung/hibernate/exception/detachedentity/DetachedEntityUnitTest.java b/persistence-modules/hibernate-exceptions/src/test/java/com/baeldung/hibernate/exception/detachedentity/DetachedEntityUnitTest.java index afb0efae77..cb4313c537 100644 --- a/persistence-modules/hibernate-exceptions/src/test/java/com/baeldung/hibernate/exception/detachedentity/DetachedEntityUnitTest.java +++ b/persistence-modules/hibernate-exceptions/src/test/java/com/baeldung/hibernate/exception/detachedentity/DetachedEntityUnitTest.java @@ -3,13 +3,12 @@ package com.baeldung.hibernate.exception.detachedentity; import com.baeldung.hibernate.exception.detachedentity.entity.Comment; import com.baeldung.hibernate.exception.detachedentity.entity.Post; -import org.assertj.core.api.Assertions; import org.hibernate.Session; import org.junit.After; import org.junit.Before; import org.junit.Test; -import javax.persistence.PersistenceException; +import jakarta.persistence.PersistenceException; import java.util.List; @@ -43,7 +42,7 @@ public class DetachedEntityUnitTest { assertThatThrownBy(() -> session.persist(detachedPost)) .isInstanceOf(PersistenceException.class) - .hasMessageContaining("org.hibernate.PersistentObjectException: detached entity passed to persist"); + .hasMessageContaining("detached entity passed to persist: com.baeldung.hibernate.exception.detachedentity.entity.Post"); } @Test @@ -72,13 +71,13 @@ public class DetachedEntityUnitTest { assertThatThrownBy(() -> session.persist(detachedPost)) .isInstanceOf(PersistenceException.class) - .hasMessageContaining("org.hibernate.PersistentObjectException: detached entity passed to persist"); + .hasMessageContaining("detached entity passed to persist: com.baeldung.hibernate.exception.detachedentity.entity.Post"); } @Test public void givenDetachedPost_whenMergeAndPersistComment_thenNoExceptionIsThrown() { Comment comment = new Comment("nice article!"); - Post mergedPost = (Post) session.merge(detachedPost); + Post mergedPost = session.merge(detachedPost); comment.setPost(mergedPost); session.persist(comment); diff --git a/persistence-modules/hibernate-jpa/pom.xml b/persistence-modules/hibernate-jpa/pom.xml index f742290884..5a99c1c4d0 100644 --- a/persistence-modules/hibernate-jpa/pom.xml +++ b/persistence-modules/hibernate-jpa/pom.xml @@ -83,11 +83,12 @@ - 5.3.7.Final - 8.0.13 - 2.2.3 - 2.1.7.RELEASE - 1.4.200 + 8.0.32 + 2.6.0 + 3.0.4 + 2.1.214 + 2.0.7 + 1.4.6 - \ No newline at end of file + diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/converters/PersonNameConverter.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/converters/PersonNameConverter.java index 506e674984..ec0e2f2e2c 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/converters/PersonNameConverter.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/converters/PersonNameConverter.java @@ -1,7 +1,7 @@ package com.baeldung.hibernate.converters; -import javax.persistence.AttributeConverter; -import javax.persistence.Converter; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; import com.baeldung.hibernate.pojo.PersonName; diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entities/Department.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entities/Department.java index ff94f4f849..39e69a2b1c 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entities/Department.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entities/Department.java @@ -2,7 +2,7 @@ package com.baeldung.hibernate.entities; import java.util.List; -import javax.persistence.*; +import jakarta.persistence.*; @Entity public class Department { diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java index 6510e70650..38519644c5 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java @@ -1,13 +1,13 @@ package com.baeldung.hibernate.entities; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; @org.hibernate.annotations.NamedQueries({ @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindByEmployeeNumber", query = "from DeptEmployee where employeeNumber = :employeeNo"), - @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindAllByDesgination", query = "from DeptEmployee where designation = :designation"), + @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindAllByDesgination", query = "from DeptEmployee where employeeNumber = :employeeNumber"), @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_UpdateEmployeeDepartment", query = "Update DeptEmployee set department = :newDepartment where employeeNumber = :employeeNo"), @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindAllByDepartment", query = "from DeptEmployee where department = :department", timeout = 1, fetchSize = 10) }) @org.hibernate.annotations.NamedNativeQueries({ @org.hibernate.annotations.NamedNativeQuery(name = "DeptEmployee_FindByEmployeeName", query = "select * from deptemployee emp where name=:name", resultClass = DeptEmployee.class), diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entitymanager/getreference/Game.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entitymanager/getreference/Game.java index 1de8de0327..5a6f9c7c6c 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entitymanager/getreference/Game.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entitymanager/getreference/Game.java @@ -1,7 +1,7 @@ package com.baeldung.hibernate.entitymanager.getreference; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; @Entity public class Game { diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entitymanager/getreference/Player.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entitymanager/getreference/Player.java index 459a3a00ad..6e62aeda45 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entitymanager/getreference/Player.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/entitymanager/getreference/Player.java @@ -1,8 +1,8 @@ package com.baeldung.hibernate.entitymanager.getreference; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; @Entity public class Player { diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/application/Application.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/application/Application.java index b547a60b06..6263df4237 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/application/Application.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/application/Application.java @@ -2,7 +2,7 @@ package com.baeldung.hibernate.jpabootstrap.application; import com.baeldung.hibernate.jpabootstrap.config.JpaEntityManagerFactory; import com.baeldung.hibernate.jpabootstrap.entities.User; -import javax.persistence.EntityManager; +import jakarta.persistence.EntityManager; public class Application { @@ -24,8 +24,7 @@ public class Application { } private static class EntityManagerHolder { - private static final EntityManager ENTITY_MANAGER = new JpaEntityManagerFactory( - new Class[]{User.class}).getEntityManager(); + private static final EntityManager ENTITY_MANAGER = new JpaEntityManagerFactory(new Class[]{User.class}).getEntityManager(); } public static EntityManager getJpaEntityManager() { diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/HibernatePersistenceUnitInfo.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/HibernatePersistenceUnitInfo.java index 3852b44b64..af01ea630c 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/HibernatePersistenceUnitInfo.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/HibernatePersistenceUnitInfo.java @@ -6,11 +6,11 @@ import java.util.Collections; import java.util.List; import java.util.Properties; import javax.sql.DataSource; -import javax.persistence.SharedCacheMode; -import javax.persistence.ValidationMode; -import javax.persistence.spi.ClassTransformer; -import javax.persistence.spi.PersistenceUnitInfo; -import javax.persistence.spi.PersistenceUnitTransactionType; +import jakarta.persistence.SharedCacheMode; +import jakarta.persistence.ValidationMode; +import jakarta.persistence.spi.ClassTransformer; +import jakarta.persistence.spi.PersistenceUnitInfo; +import jakarta.persistence.spi.PersistenceUnitTransactionType; import org.hibernate.jpa.HibernatePersistenceProvider; public class HibernatePersistenceUnitInfo implements PersistenceUnitInfo { diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/JpaEntityManagerFactory.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/JpaEntityManagerFactory.java index bc1932af6f..e115727d67 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/JpaEntityManagerFactory.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/JpaEntityManagerFactory.java @@ -7,10 +7,10 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.stream.Collectors; -import javax.persistence.EntityManager; +import jakarta.persistence.EntityManager; import javax.sql.DataSource; -import javax.persistence.EntityManagerFactory; -import javax.persistence.spi.PersistenceUnitInfo; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.spi.PersistenceUnitInfo; import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl; import org.hibernate.jpa.boot.internal.PersistenceUnitInfoDescriptor; diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/entities/User.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/entities/User.java index 86ca1dfa19..43c99f8d96 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/entities/User.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/entities/User.java @@ -1,10 +1,10 @@ package com.baeldung.hibernate.jpabootstrap.entities; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "users") diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpacriteriabuilder/service/EmployeeSearchServiceImpl.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpacriteriabuilder/service/EmployeeSearchServiceImpl.java index e79168a451..9a3216b5eb 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpacriteriabuilder/service/EmployeeSearchServiceImpl.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/jpacriteriabuilder/service/EmployeeSearchServiceImpl.java @@ -2,13 +2,13 @@ package com.baeldung.hibernate.jpacriteriabuilder.service; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaBuilder.In; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; -import javax.persistence.criteria.Subquery; +import jakarta.persistence.EntityManager; +import jakarta.persistence.TypedQuery; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaBuilder.In; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; +import jakarta.persistence.criteria.Subquery; import com.baeldung.hibernate.entities.Department; import com.baeldung.hibernate.entities.DeptEmployee; diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/Address.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/Address.java index e05eb46030..0c3238cf98 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/Address.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/Address.java @@ -1,12 +1,12 @@ package com.baeldung.hibernate.onetoone.foreignkeybased; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; @Entity @Table(name = "address") diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/User.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/User.java index dda972f29c..14c2a0a28c 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/User.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/User.java @@ -1,14 +1,14 @@ package com.baeldung.hibernate.onetoone.foreignkeybased; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; @Entity @Table(name = "users") diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/Employee.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/Employee.java index a0bc101b9f..fc8b9eefec 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/Employee.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/Employee.java @@ -1,15 +1,15 @@ package com.baeldung.hibernate.onetoone.jointablebased; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; @Entity @Table(name = "employee") diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/WorkStation.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/WorkStation.java index f530611f6e..0834b9f9d7 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/WorkStation.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/WorkStation.java @@ -1,13 +1,13 @@ package com.baeldung.hibernate.onetoone.jointablebased; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; @Entity @Table(name = "workstation") diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/Address.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/Address.java index e70c62e77b..d738b900bc 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/Address.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/Address.java @@ -1,12 +1,12 @@ package com.baeldung.hibernate.onetoone.sharedkeybased; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.MapsId; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.MapsId; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; @Entity @Table(name = "address") diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/User.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/User.java index 605671a149..8ce767eaf7 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/User.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/User.java @@ -1,15 +1,15 @@ package com.baeldung.hibernate.onetoone.sharedkeybased; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToOne; -import javax.persistence.PrimaryKeyJoinColumn; -import javax.persistence.Table; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.PrimaryKeyJoinColumn; +import jakarta.persistence.Table; @Entity @Table(name = "users") diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingCourse.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingCourse.java index 1af3e3e21b..b8212a049d 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingCourse.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingCourse.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.optimisticlocking; -import javax.persistence.*; +import jakarta.persistence.*; @Entity public class OptimisticLockingCourse { diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingStudent.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingStudent.java index b79212ae8d..22f11e37fb 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingStudent.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingStudent.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.optimisticlocking; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.List; @Entity diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Address.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Address.java index c889cb6127..7c6d20df40 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Address.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Address.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.pessimisticlocking; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; @Embeddable public class Address { diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Customer.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Customer.java index cb73cbc958..9f36e3b308 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Customer.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Customer.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.pessimisticlocking; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.List; @Entity diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Individual.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Individual.java index e491c09eb5..b954c9fdb2 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Individual.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Individual.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.pessimisticlocking; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Inheritance; -import javax.persistence.InheritanceType; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; @Entity @Inheritance(strategy = InheritanceType.JOINED) diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingCourse.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingCourse.java index aea7d5fc87..012f3d1d39 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingCourse.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingCourse.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.pessimisticlocking; -import javax.persistence.*; +import jakarta.persistence.*; @Entity public class PessimisticLockingCourse { diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingEmployee.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingEmployee.java index a1328cbdad..e5b00f3800 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingEmployee.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingEmployee.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.pessimisticlocking; -import javax.persistence.Entity; +import jakarta.persistence.Entity; import java.math.BigDecimal; @Entity diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingStudent.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingStudent.java index e6c5f476b4..c5634ebc24 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingStudent.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingStudent.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.pessimisticlocking; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.List; @Entity diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Movie.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Movie.java index 5fae7f6a97..7aeadd4501 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Movie.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Movie.java @@ -1,8 +1,8 @@ package com.baeldung.hibernate.pojo; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "MOVIE") diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Person.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Person.java index 390a5954ed..d0c8b8aa2f 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Person.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Person.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.pojo; -import javax.persistence.Convert; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; import com.baeldung.hibernate.converters.PersonNameConverter; diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Post.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Post.java index 25e51e35d0..66a68367d7 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Post.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Post.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.pojo; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "posts") diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Student.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Student.java index 9b26c117eb..263908a5fc 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Student.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/pojo/Student.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.pojo; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Student { diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/Account.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/Account.java index b051809ee5..7070f21c45 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/Account.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/Account.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.serializable; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; @Entity public class Account { diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/Email.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/Email.java index 11e7c6f159..4ba902281a 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/Email.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/Email.java @@ -1,7 +1,7 @@ package com.baeldung.hibernate.serializable; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; import java.io.Serializable; @Entity diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/User.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/User.java index e7820fe52f..267155b4db 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/User.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/User.java @@ -1,7 +1,7 @@ package com.baeldung.hibernate.serializable; -import javax.persistence.EmbeddedId; -import javax.persistence.Entity; +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; @Entity public class User { diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/UserId.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/UserId.java index 7d3d382f67..6fcbeafdd0 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/UserId.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/serializable/UserId.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.serializable; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; import java.io.Serializable; @Embeddable diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/persistencecontext/entity/User.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/persistencecontext/entity/User.java index 7252ac46f5..afdbf067c3 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/persistencecontext/entity/User.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/persistencecontext/entity/User.java @@ -1,9 +1,9 @@ package com.baeldung.persistencecontext.entity; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; -@Entity +@Entity(name = "users") public class User { @Id diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/persistencecontext/service/ExtendedPersistenceContextUserService.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/persistencecontext/service/ExtendedPersistenceContextUserService.java index ef25aac69f..7ad6aae745 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/persistencecontext/service/ExtendedPersistenceContextUserService.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/persistencecontext/service/ExtendedPersistenceContextUserService.java @@ -1,15 +1,15 @@ package com.baeldung.persistencecontext.service; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.PersistenceContextType; -import javax.transaction.Transactional; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.PersistenceContextType; +import jakarta.transaction.Transactional; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; import com.baeldung.persistencecontext.entity.User; -@Component +@Service public class ExtendedPersistenceContextUserService { @PersistenceContext(type = PersistenceContextType.EXTENDED) diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/persistencecontext/service/TransctionPersistenceContextUserService.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/persistencecontext/service/TransctionPersistenceContextUserService.java index 481defcf08..6b9fd1f14c 100644 --- a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/persistencecontext/service/TransctionPersistenceContextUserService.java +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/persistencecontext/service/TransctionPersistenceContextUserService.java @@ -1,20 +1,20 @@ package com.baeldung.persistencecontext.service; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.transaction.Transactional; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.transaction.Transactional; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; import com.baeldung.persistencecontext.entity.User; -@Component +@Service public class TransctionPersistenceContextUserService { @PersistenceContext private EntityManager entityManager; - + @Transactional public User insertWithTransaction(User user) { entityManager.persist(user); diff --git a/persistence-modules/hibernate-jpa/src/main/resources/META-INF/persistence.xml b/persistence-modules/hibernate-jpa/src/main/resources/META-INF/persistence.xml index 12b41a4973..1669413289 100644 --- a/persistence-modules/hibernate-jpa/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/hibernate-jpa/src/main/resources/META-INF/persistence.xml @@ -8,12 +8,13 @@ com.baeldung.hibernate.pojo.Movie true - + - - - - + + + + + @@ -34,10 +35,14 @@ - - - - + + + + + + + + @@ -57,16 +62,20 @@ - - - - - + + + + + - - - - + + + + + + + + @@ -87,16 +96,20 @@ - - - - - + + + + + - - - - + + + + + + + + @@ -113,10 +126,16 @@ - - - - + + + + + + + + + + diff --git a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/entitymanager/getreference/GetReferenceH2IntegrationTest.java b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/entitymanager/getreference/GetReferenceH2IntegrationTest.java index e8e6aeed7c..86f059c6d7 100644 --- a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/entitymanager/getreference/GetReferenceH2IntegrationTest.java +++ b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/entitymanager/getreference/GetReferenceH2IntegrationTest.java @@ -5,9 +5,9 @@ import ch.qos.logback.classic.Logger; import org.junit.jupiter.api.*; import org.slf4j.LoggerFactory; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.io.PrintStream; @@ -87,8 +87,8 @@ public class GetReferenceH2IntegrationTest { }); StringBuilder expected = new StringBuilder(); - expected.append("Hibernate: select game0_.id as id1_0_0_, game0_.name as name2_0_0_ from Game game0_ where game0_.id=?\n"); - expected.append("Hibernate: update Game set name=? where id=?\n"); + expected.append("Hibernate: select g1_0.id,g1_0.name from Game g1_0 where g1_0.id=?" + System.lineSeparator()); + expected.append("Hibernate: update Game set name=? where id=?" + System.lineSeparator()); assertEquals(expected.toString(), output.toString()); } @@ -104,8 +104,8 @@ public class GetReferenceH2IntegrationTest { }); StringBuilder expected = new StringBuilder(); - expected.append("Hibernate: select game0_.id as id1_0_0_, game0_.name as name2_0_0_ from Game game0_ where game0_.id=?\n"); - expected.append("Hibernate: update Game set name=? where id=?\n"); + expected.append("Hibernate: select g1_0.id,g1_0.name from Game g1_0 where g1_0.id=?" + System.lineSeparator()); + expected.append("Hibernate: update Game set name=? where id=?" + System.lineSeparator()); assertEquals(expected.toString(), output.toString()); } @@ -120,10 +120,9 @@ public class GetReferenceH2IntegrationTest { StringBuilder expected = new StringBuilder(); expected.append("Hibernate: select "); - expected.append("player0_.id as id1_1_0_, player0_.game_id as game_id3_1_0_, "); - expected.append("player0_.name as name2_1_0_, game1_.id as id1_0_1_, game1_.name as name2_0_1_ "); - expected.append("from Player player0_ left outer join Game game1_ on player0_.game_id=game1_.id where player0_.id=?\n"); - expected.append("Hibernate: delete from Player where id=?\n"); + expected.append("p1_0.id,g1_0.id,g1_0.name,p1_0.name "); + expected.append("from Player p1_0 left join Game g1_0 on g1_0.id=p1_0.game_id where p1_0.id=?" + System.lineSeparator()); + expected.append("Hibernate: delete from Player where id=?" + System.lineSeparator()); assertEquals(expected.toString(), output.toString()); } @@ -137,11 +136,7 @@ public class GetReferenceH2IntegrationTest { }); StringBuilder expected = new StringBuilder(); - expected.append("Hibernate: select "); - expected.append("player0_.id as id1_1_0_, player0_.game_id as game_id3_1_0_, "); - expected.append("player0_.name as name2_1_0_, game1_.id as id1_0_1_, game1_.name as name2_0_1_ "); - expected.append("from Player player0_ left outer join Game game1_ on player0_.game_id=game1_.id where player0_.id=?\n"); - expected.append("Hibernate: delete from Player where id=?\n"); + expected.append("Hibernate: delete from Player where id=?" + System.lineSeparator()); assertEquals(expected.toString(), output.toString()); } @@ -159,12 +154,11 @@ public class GetReferenceH2IntegrationTest { })); StringBuilder expected = new StringBuilder(); - expected.append("Hibernate: select game0_.id as id1_0_0_, game0_.name as name2_0_0_ from Game game0_ where game0_.id=?\n"); + expected.append("Hibernate: select g1_0.id,g1_0.name from Game g1_0 where g1_0.id=?" + System.lineSeparator()); expected.append("Hibernate: select "); - expected.append("player0_.id as id1_1_0_, player0_.game_id as game_id3_1_0_, "); - expected.append("player0_.name as name2_1_0_, game1_.id as id1_0_1_, game1_.name as name2_0_1_ "); - expected.append("from Player player0_ left outer join Game game1_ on player0_.game_id=game1_.id where player0_.id=?\n"); - expected.append("Hibernate: update Player set game_id=?, name=? where id=?\n"); + expected.append("p1_0.id,g1_0.id,g1_0.name,p1_0.name "); + expected.append("from Player p1_0 left join Game g1_0 on g1_0.id=p1_0.game_id where p1_0.id=?" + System.lineSeparator()); + expected.append("Hibernate: update Player set game_id=?,name=? where id=?" + System.lineSeparator()); assertEquals(expected.toString(), output.toString()); } @@ -183,10 +177,9 @@ public class GetReferenceH2IntegrationTest { StringBuilder expected = new StringBuilder(); expected.append("Hibernate: select "); - expected.append("player0_.id as id1_1_0_, player0_.game_id as game_id3_1_0_, "); - expected.append("player0_.name as name2_1_0_, game1_.id as id1_0_1_, game1_.name as name2_0_1_ "); - expected.append("from Player player0_ left outer join Game game1_ on player0_.game_id=game1_.id where player0_.id=?\n"); - expected.append("Hibernate: update Player set game_id=?, name=? where id=?\n"); + expected.append("p1_0.id,g1_0.id,g1_0.name,p1_0.name "); + expected.append("from Player p1_0 left join Game g1_0 on g1_0.id=p1_0.game_id where p1_0.id=?" + System.lineSeparator()); + expected.append("Hibernate: update Player set game_id=?,name=? where id=?" + System.lineSeparator()); assertEquals(expected.toString(), output.toString()); } diff --git a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/entitymanager/getreference/GetReferenceMySQLManualTest.java b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/entitymanager/getreference/GetReferenceMySQLManualTest.java index 2b7c5e8119..29be19dd68 100644 --- a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/entitymanager/getreference/GetReferenceMySQLManualTest.java +++ b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/entitymanager/getreference/GetReferenceMySQLManualTest.java @@ -5,9 +5,9 @@ import ch.qos.logback.classic.Logger; import org.junit.jupiter.api.*; import org.slf4j.LoggerFactory; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.io.PrintStream; diff --git a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/entitymanager/getreference/GetReferencePostgreSQLManualTest.java b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/entitymanager/getreference/GetReferencePostgreSQLManualTest.java index 17f6b10b8a..20a0bca6f1 100644 --- a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/entitymanager/getreference/GetReferencePostgreSQLManualTest.java +++ b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/entitymanager/getreference/GetReferencePostgreSQLManualTest.java @@ -5,9 +5,9 @@ import ch.qos.logback.classic.Logger; import org.junit.jupiter.api.*; import org.slf4j.LoggerFactory; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.io.PrintStream; diff --git a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/jpacriteriabuilder/EmployeeSearchServiceIntegrationTest.java b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/jpacriteriabuilder/EmployeeSearchServiceIntegrationTest.java index 2b12734a10..16d1057285 100644 --- a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/jpacriteriabuilder/EmployeeSearchServiceIntegrationTest.java +++ b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/jpacriteriabuilder/EmployeeSearchServiceIntegrationTest.java @@ -9,7 +9,7 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import javax.persistence.EntityManager; +import jakarta.persistence.EntityManager; import org.hibernate.HibernateException; import org.hibernate.Session; @@ -81,13 +81,10 @@ public class EmployeeSearchServiceIntegrationTest { @Test public final void givenCriteriaQuery_whenSearchedUsingCriteriaBuilderWithListofAuthors_thenResultIsFilteredByAuthorNames() { - List titles = new ArrayList() { - { - add("Manager"); - add("Senior Manager"); - add("Director"); - } - }; + List titles = new ArrayList<>(); + titles.add("Manager"); + titles.add("Senior Manager"); + titles.add("Director"); List result = searchService.filterbyTitleUsingCriteriaBuilder(titles); assertEquals("Number of Employees does not match with expected.", 6, result.size()); assertThat(result.stream() diff --git a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java index 37c490f297..2fa302e270 100644 --- a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java +++ b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java @@ -3,9 +3,9 @@ package com.baeldung.hibernate.optimisticlocking; import java.io.IOException; import java.util.Arrays; -import javax.persistence.EntityManager; -import javax.persistence.LockModeType; -import javax.persistence.OptimisticLockException; +import jakarta.persistence.EntityManager; +import jakarta.persistence.LockModeType; +import jakarta.persistence.OptimisticLockException; import org.hibernate.SessionFactory; import org.junit.After; diff --git a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java index 4b9c7720fd..4085a98dad 100644 --- a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java +++ b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java @@ -1,14 +1,14 @@ package com.baeldung.hibernate.pessimisticlocking; import com.baeldung.hibernate.HibernateUtil; -import com.vividsolutions.jts.util.Assert; +import org.locationtech.jts.util.Assert; import org.hibernate.SessionFactory; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import javax.persistence.*; +import jakarta.persistence.*; import java.io.IOException; import java.util.Arrays; @@ -46,7 +46,7 @@ public class BasicPessimisticLockingIntegrationTest { } @Test - public void givenRecordWithPessimisticReadQuery_whenQueryingNewOne_PessimisticLockExceptionThrown() throws IOException { + public void givenRecordWithPessimisticReadQuery_whenQueryingNewOne_PessimisticLockExceptionThrown() { try { EntityManager entityManager = getEntityManagerWithOpenTransaction(); Query query = entityManager.createQuery("from Student where studentId = :studentId"); diff --git a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java index 81cb7d95f8..c2f2326159 100644 --- a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java +++ b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java @@ -6,9 +6,9 @@ import org.hibernate.SessionFactory; import org.junit.AfterClass; import org.junit.Test; -import javax.persistence.EntityManager; -import javax.persistence.LockModeType; -import javax.persistence.PessimisticLockScope; +import jakarta.persistence.EntityManager; +import jakarta.persistence.LockModeType; +import jakarta.persistence.PessimisticLockScope; import java.io.IOException; import java.math.BigDecimal; import java.util.Arrays; @@ -36,7 +36,7 @@ public class PessimisticLockScopesIntegrationTest { // EXTENDED SCOPE Map map = new HashMap<>(); - map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); + map.put("jakarta.persistence", PessimisticLockScope.EXTENDED); EntityManager em3 = getEntityManagerWithOpenTransaction(); foundEmployee = em3.find(PessimisticLockingEmployee.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); @@ -65,7 +65,7 @@ public class PessimisticLockScopesIntegrationTest { // EXTENDED SCOPE Map map = new HashMap<>(); - map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); + map.put("jakarta.persistence", PessimisticLockScope.EXTENDED); EntityManager em3 = getEntityManagerWithOpenTransaction(); foundCustomer = em3.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); @@ -96,7 +96,7 @@ public class PessimisticLockScopesIntegrationTest { // EXTENDED SCOPE Map map = new HashMap<>(); - map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); + map.put("jakarta.persistence", PessimisticLockScope.EXTENDED); EntityManager em3 = getEntityManagerWithOpenTransaction(); foundCourse = em3.find(PessimisticLockingCourse.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); diff --git a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/serializable/JPASerializableIntegrationTest.java b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/serializable/JPASerializableIntegrationTest.java index 696bc23ab0..5512757889 100644 --- a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/serializable/JPASerializableIntegrationTest.java +++ b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/serializable/JPASerializableIntegrationTest.java @@ -4,10 +4,9 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import java.io.IOException; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -17,7 +16,7 @@ public class JPASerializableIntegrationTest { private static EntityManager entityManager; @Before - public void setUp() throws IOException { + public void setUp() { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("com.baeldung.hibernate.serializable.h2_persistence_unit"); entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); @@ -63,7 +62,7 @@ public class JPASerializableIntegrationTest { entityManager.persist(account); entityManager.persist(account2); - List userAccounts = entityManager.createQuery("select a from Account a join fetch a.user where a.user.email = :email") + List userAccounts = entityManager.createQuery("select a from Account a join fetch a.user where a.user.email = :email", Account.class) .setParameter("email", email) .getResultList(); assertEquals(2, userAccounts.size()); diff --git a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/transaction/TransactionIntegrationTest.java b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/transaction/TransactionIntegrationTest.java index 246a7d59f9..f64846ba59 100644 --- a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/transaction/TransactionIntegrationTest.java +++ b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/transaction/TransactionIntegrationTest.java @@ -2,7 +2,6 @@ package com.baeldung.hibernate.transaction; import com.baeldung.hibernate.HibernateUtil; import com.baeldung.hibernate.pojo.Post; -import com.baeldung.hibernate.transaction.PostService; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.BeforeClass; @@ -10,7 +9,6 @@ import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; diff --git a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/persistencecontext/PersistenceContextIntegrationTest.java b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/persistencecontext/PersistenceContextIntegrationTest.java index b299dd5834..37e6e438d8 100644 --- a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/persistencecontext/PersistenceContextIntegrationTest.java +++ b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/persistencecontext/PersistenceContextIntegrationTest.java @@ -4,8 +4,8 @@ import com.baeldung.persistencecontext.entity.User; import com.baeldung.persistencecontext.service.ExtendedPersistenceContextUserService; import com.baeldung.persistencecontext.service.TransctionPersistenceContextUserService; -import javax.persistence.EntityExistsException; -import javax.persistence.TransactionRequiredException; +import jakarta.persistence.EntityExistsException; +import jakarta.persistence.TransactionRequiredException; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/persistence-modules/hibernate-mapping-2/README.md b/persistence-modules/hibernate-mapping-2/README.md index 7a811e17cf..36c9f8c304 100644 --- a/persistence-modules/hibernate-mapping-2/README.md +++ b/persistence-modules/hibernate-mapping-2/README.md @@ -4,4 +4,6 @@ This module contains articles about Hibernate Mappings. ### Relevant articles -- [Hibernate Many to Many Annotation Tutorial](https://www.baeldung.com/hibernate-many-to-many) \ No newline at end of file +- [Hibernate Many to Many Annotation Tutorial](https://www.baeldung.com/hibernate-many-to-many) +- [Boolean Converters in Hibernate 6](https://www.baeldung.com/java-hibernate-6-boolean-converters) +- [Generate UUIDs as Primary Keys With Hibernate](https://www.baeldung.com/java-hibernate-uuid-primary-key) diff --git a/persistence-modules/hibernate-mapping-2/pom.xml b/persistence-modules/hibernate-mapping-2/pom.xml index 2a787a0e46..1b9a3e45d3 100644 --- a/persistence-modules/hibernate-mapping-2/pom.xml +++ b/persistence-modules/hibernate-mapping-2/pom.xml @@ -55,32 +55,15 @@ h2 ${h2.version} - - com.sun.xml.bind - jaxb-core - ${com.sun.xml.version} - - - javax.xml.bind - jaxb-api - ${javax.xml.bind.version} - - - com.sun.xml.bind - jaxb-impl - ${com.sun.xml.version} - - 5.0.2.RELEASE - 1.10.6.RELEASE + 6.0.6 + 3.0.3 - 5.2.10.Final 9.0.0.M26 - 2.3.0.1 - 2.3.1 + 4.0.2 2.1.214 diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/HibernateUtil.java new file mode 100644 index 0000000000..df409ee888 --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -0,0 +1,58 @@ +package com.baeldung.hibernate; + +import static org.hibernate.boot.registry.StandardServiceRegistryBuilder.DEFAULT_CFG_RESOURCE_NAME; + +import org.hibernate.SessionFactory; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Configuration; +import org.hibernate.service.ServiceRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.baeldung.hibernate.booleanconverters.model.Question; +import com.baeldung.hibernate.manytomany.model.Employee; +import com.baeldung.hibernate.manytomany.model.Project; +import com.baeldung.hibernate.uuids.WebSiteUser; +import com.baeldung.hibernate.uuids.Element; +import com.baeldung.hibernate.uuids.Reservation; +import com.baeldung.hibernate.uuids.Sale; + +public class HibernateUtil { + + private static final String DEFAULT_RESOURCE = "manytomany.cfg.xml"; + private static final Logger LOGGER = LoggerFactory.getLogger(HibernateUtil.class); + + private static SessionFactory buildSessionFactory(String resource) { + try { + // Create the SessionFactory from hibernate-annotation.cfg.xml + Configuration configuration = new Configuration(); + configuration.addAnnotatedClass(Employee.class); + configuration.addAnnotatedClass(Project.class); + configuration.addAnnotatedClass(WebSiteUser.class); + configuration.addAnnotatedClass(Element.class); + configuration.addAnnotatedClass(Reservation.class); + configuration.addAnnotatedClass(Sale.class); + configuration.addAnnotatedClass(Question.class); + configuration.addPackage(Question.class.getPackageName()); + configuration.configure(resource); + LOGGER.debug("Hibernate Annotation Configuration loaded"); + + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()) + .build(); + LOGGER.debug("Hibernate Annotation serviceRegistry created"); + + return configuration.buildSessionFactory(serviceRegistry); + } catch (Throwable ex) { + LOGGER.error("Initial SessionFactory creation failed.", ex); + throw new ExceptionInInitializerError(ex); + } + } + + public static SessionFactory getSessionFactory() { + return buildSessionFactory(DEFAULT_RESOURCE); + } + + public static SessionFactory getSessionFactory(String resource) { + return buildSessionFactory(resource); + } +} diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/booleanconverters/model/Question.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/booleanconverters/model/Question.java new file mode 100644 index 0000000000..be2990359f --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/booleanconverters/model/Question.java @@ -0,0 +1,86 @@ +package com.baeldung.hibernate.booleanconverters.model; + +import java.util.UUID; + +import org.hibernate.type.NumericBooleanConverter; +import org.hibernate.type.TrueFalseConverter; +import org.hibernate.type.YesNoConverter; + +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +@Entity +public class Question { + + @Id + private UUID id; + private String content; + @Convert(converter = YesNoConverter.class) + private Boolean correctAnswer; + @Convert(converter = TrueFalseConverter.class) + private Boolean shouldBeAsked; + @Convert(converter = NumericBooleanConverter.class) + private Boolean isEasy; + private Boolean wasAskedBefore; + + public Question() { + } + + public Question(UUID id, String content, Boolean correctAnswer, Boolean shouldBeAsked, Boolean isEasy, Boolean wasAskedBefore) { + this.id = id; + this.content = content; + this.correctAnswer = correctAnswer; + this.shouldBeAsked = shouldBeAsked; + this.isEasy = isEasy; + this.wasAskedBefore = wasAskedBefore; + } + + public UUID getId() { + return id; + } + + public String getContent() { + return content; + } + + public Boolean getCorrectAnswer() { + return correctAnswer; + } + + public Boolean getShouldBeAsked() { + return shouldBeAsked; + } + + public Boolean isEasy() { + return isEasy; + } + + public Boolean getWasAskedBefore() { + return wasAskedBefore; + } + + public void setId(UUID id) { + this.id = id; + } + + public void setContent(String content) { + this.content = content; + } + + public void setCorrectAnswer(Boolean correctAnswer) { + this.correctAnswer = correctAnswer; + } + + public void setShouldBeAsked(Boolean shouldBeAsked) { + this.shouldBeAsked = shouldBeAsked; + } + + public void setEasy(Boolean easy) { + isEasy = easy; + } + + public void setWasAskedBefore(Boolean wasAskedBefore) { + this.wasAskedBefore = wasAskedBefore; + } +} diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/booleanconverters/model/package-info.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/booleanconverters/model/package-info.java new file mode 100644 index 0000000000..d5041b87c0 --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/booleanconverters/model/package-info.java @@ -0,0 +1,5 @@ +@ConverterRegistration(converter = YesNoConverter.class) +package com.baeldung.hibernate.booleanconverters.model; + +import org.hibernate.annotations.ConverterRegistration; +import org.hibernate.type.YesNoConverter; \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/PersistenceConfig.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/PersistenceConfig.java similarity index 95% rename from persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/PersistenceConfig.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/PersistenceConfig.java index 0d7b8bdbcf..4ec6c9fb71 100644 --- a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/PersistenceConfig.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/PersistenceConfig.java @@ -1,4 +1,4 @@ -package com.baeldung.manytomany; +package com.baeldung.hibernate.manytomany; import java.util.Properties; @@ -22,7 +22,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement @PropertySource({ "classpath:persistence-h2.properties" }) -@ComponentScan({ "com.baeldung.manytomany" }) +@ComponentScan({ "com.baeldung.hibernate.manytomany" }) public class PersistenceConfig { @Autowired @@ -32,7 +32,7 @@ public class PersistenceConfig { public LocalSessionFactoryBean sessionFactory() { final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); sessionFactory.setDataSource(restDataSource()); - sessionFactory.setPackagesToScan(new String[] { "com.baeldung.manytomany" }); + sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate.manytomany" }); sessionFactory.setHibernateProperties(hibernateProperties()); return sessionFactory; diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/IEmployeeDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/IEmployeeDao.java new file mode 100644 index 0000000000..7bff73ecf4 --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/IEmployeeDao.java @@ -0,0 +1,8 @@ +package com.baeldung.hibernate.manytomany.dao; + +import com.baeldung.hibernate.manytomany.dao.common.IOperations; +import com.baeldung.hibernate.manytomany.model.Employee; + +public interface IEmployeeDao extends IOperations{ + +} diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/IProjectDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/IProjectDao.java new file mode 100644 index 0000000000..de800ae783 --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/IProjectDao.java @@ -0,0 +1,8 @@ +package com.baeldung.hibernate.manytomany.dao; + +import com.baeldung.hibernate.manytomany.dao.common.IOperations; +import com.baeldung.hibernate.manytomany.model.Project; + +public interface IProjectDao extends IOperations{ + +} diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/AbstractDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/common/AbstractDao.java similarity index 85% rename from persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/AbstractDao.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/common/AbstractDao.java index b37b48e645..6ed04a9b2f 100644 --- a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/AbstractDao.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/common/AbstractDao.java @@ -1,4 +1,4 @@ -package com.baeldung.manytomany.dao.common; +package com.baeldung.hibernate.manytomany.dao.common; import java.io.Serializable; diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/AbstractHibernateDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/common/AbstractHibernateDao.java similarity index 96% rename from persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/AbstractHibernateDao.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/common/AbstractHibernateDao.java index 9c8a8faa2e..67878906ca 100644 --- a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/AbstractHibernateDao.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/common/AbstractHibernateDao.java @@ -1,4 +1,4 @@ -package com.baeldung.manytomany.dao.common; +package com.baeldung.hibernate.manytomany.dao.common; import java.io.Serializable; import java.util.List; diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/IOperations.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/common/IOperations.java similarity index 85% rename from persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/IOperations.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/common/IOperations.java index 8a85b52fc9..2be7fdb75e 100644 --- a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/common/IOperations.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/common/IOperations.java @@ -1,4 +1,4 @@ -package com.baeldung.manytomany.dao.common; +package com.baeldung.hibernate.manytomany.dao.common; import java.io.Serializable; import java.util.List; diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/impl/EmployeeDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/impl/EmployeeDao.java similarity index 50% rename from persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/impl/EmployeeDao.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/impl/EmployeeDao.java index b24013c567..d4364c00c2 100644 --- a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/impl/EmployeeDao.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/impl/EmployeeDao.java @@ -1,10 +1,10 @@ -package com.baeldung.manytomany.dao.impl; +package com.baeldung.hibernate.manytomany.dao.impl; import org.springframework.stereotype.Repository; -import com.baeldung.manytomany.dao.IEmployeeDao; -import com.baeldung.manytomany.dao.common.AbstractHibernateDao; -import com.baeldung.manytomany.model.Employee; +import com.baeldung.hibernate.manytomany.dao.IEmployeeDao; +import com.baeldung.hibernate.manytomany.dao.common.AbstractHibernateDao; +import com.baeldung.hibernate.manytomany.model.Employee; @Repository public class EmployeeDao extends AbstractHibernateDao implements IEmployeeDao { diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/impl/ProjectDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/impl/ProjectDao.java new file mode 100644 index 0000000000..a221116013 --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/dao/impl/ProjectDao.java @@ -0,0 +1,17 @@ +package com.baeldung.hibernate.manytomany.dao.impl; + +import org.springframework.stereotype.Repository; + +import com.baeldung.hibernate.manytomany.dao.IProjectDao; +import com.baeldung.hibernate.manytomany.dao.common.AbstractHibernateDao; +import com.baeldung.hibernate.manytomany.model.Project; + +@Repository +public class ProjectDao extends AbstractHibernateDao implements IProjectDao { + + public ProjectDao() { + super(); + + setClazz(Project.class); + } +} diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/model/Employee.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java similarity index 80% rename from persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/model/Employee.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java index 39671c21bc..d606f1281c 100644 --- a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/model/Employee.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java @@ -1,19 +1,19 @@ -package com.baeldung.manytomany.model; +package com.baeldung.hibernate.manytomany.model; import java.io.Serializable; import java.util.HashSet; import java.util.Set; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.Table; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; @Entity @Table(name = "Employee") diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/model/Project.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java similarity index 79% rename from persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/model/Project.java rename to persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java index b5dc3cb856..8ea31dbc5f 100644 --- a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/model/Project.java +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java @@ -1,15 +1,15 @@ -package com.baeldung.manytomany.model; +package com.baeldung.hibernate.manytomany.model; import java.io.Serializable; import java.util.HashSet; import java.util.Set; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.ManyToMany; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; @Entity @Table(name = "Project") diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/uuids/Element.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/uuids/Element.java new file mode 100644 index 0000000000..5112c6df0f --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/uuids/Element.java @@ -0,0 +1,32 @@ +package com.baeldung.hibernate.uuids; + +import java.util.UUID; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import org.hibernate.annotations.UuidGenerator; + +@Entity +public class Element { + + @Id + @UuidGenerator + private String id; + + private String 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; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/uuids/Reservation.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/uuids/Reservation.java new file mode 100644 index 0000000000..389376e785 --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/uuids/Reservation.java @@ -0,0 +1,43 @@ +package com.baeldung.hibernate.uuids; + +import java.util.UUID; +import jakarta.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; + +@Entity +public class Reservation { + + @Id + @GeneratedValue(strategy = GenerationType.UUID) + private UUID id; + + private String status; + + private String number; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } +} diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/uuids/Sale.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/uuids/Sale.java new file mode 100644 index 0000000000..8eaab80912 --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/uuids/Sale.java @@ -0,0 +1,36 @@ +package com.baeldung.hibernate.uuids; + +import jakarta.persistence.Id; +import jakarta.persistence.Entity; +import org.hibernate.annotations.UuidGenerator; + +import java.util.UUID; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import org.hibernate.annotations.UuidGenerator; + +@Entity +public class Sale { + + @Id + @UuidGenerator + private UUID id; + + private boolean completed; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public boolean isCompleted() { + return completed; + } + + public void setCompleted(boolean completed) { + this.completed = completed; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/uuids/WebSiteUser.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/uuids/WebSiteUser.java new file mode 100644 index 0000000000..b1a115a3b9 --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/hibernate/uuids/WebSiteUser.java @@ -0,0 +1,33 @@ +package com.baeldung.hibernate.uuids; + +import java.util.UUID; +import java.time.LocalDate; +import jakarta.persistence.Id; +import jakarta.persistence.Entity; +import org.hibernate.annotations.UuidGenerator; + +@Entity +public class WebSiteUser { + + @Id + @UuidGenerator(style = UuidGenerator.Style.TIME) + private UUID id; + + private LocalDate registrationDate; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public LocalDate getRegistrationDate() { + return registrationDate; + } + + public void setRegistrationDate(LocalDate registrationDate) { + this.registrationDate = registrationDate; + } +} diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IEmployeeDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IEmployeeDao.java deleted file mode 100644 index 68bf5d5bad..0000000000 --- a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IEmployeeDao.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.manytomany.dao; - -import com.baeldung.manytomany.dao.common.IOperations; -import com.baeldung.manytomany.model.Employee; - -public interface IEmployeeDao extends IOperations{ - -} diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IProjectDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IProjectDao.java deleted file mode 100644 index d2645db44a..0000000000 --- a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/IProjectDao.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.manytomany.dao; - -import com.baeldung.manytomany.dao.common.IOperations; -import com.baeldung.manytomany.model.Project; - -public interface IProjectDao extends IOperations{ - -} diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/impl/ProjectDao.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/impl/ProjectDao.java deleted file mode 100644 index a70212f519..0000000000 --- a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/dao/impl/ProjectDao.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.baeldung.manytomany.dao.impl; - -import org.springframework.stereotype.Repository; - -import com.baeldung.manytomany.dao.IProjectDao; -import com.baeldung.manytomany.dao.common.AbstractHibernateDao; -import com.baeldung.manytomany.model.Project; - - -@Repository -public class ProjectDao extends AbstractHibernateDao implements IProjectDao { - - public ProjectDao() { - super(); - - setClazz(Project.class); - } -} diff --git a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/util/HibernateUtil.java b/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/util/HibernateUtil.java deleted file mode 100644 index d429564564..0000000000 --- a/persistence-modules/hibernate-mapping-2/src/main/java/com/baeldung/manytomany/util/HibernateUtil.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.baeldung.manytomany.util; - -import org.hibernate.SessionFactory; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.cfg.Configuration; -import org.hibernate.service.ServiceRegistry; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.baeldung.manytomany.model.Employee; -import com.baeldung.manytomany.model.Project; - -public class HibernateUtil { - - private static final Logger LOGGER = LoggerFactory.getLogger(HibernateUtil.class); - private static SessionFactory sessionFactory; - - private static SessionFactory buildSessionFactory() { - try { - // Create the SessionFactory from hibernate-annotation.cfg.xml - Configuration configuration = new Configuration(); - configuration.addAnnotatedClass(Employee.class); - configuration.addAnnotatedClass(Project.class); - configuration.configure("manytomany.cfg.xml"); - LOGGER.debug("Hibernate Annotation Configuration loaded"); - - ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()) - .build(); - LOGGER.debug("Hibernate Annotation serviceRegistry created"); - - SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry); - - return sessionFactory; - } catch (Throwable ex) { - LOGGER.error("Initial SessionFactory creation failed.", ex); - throw new ExceptionInInitializerError(ex); - } - } - - public static SessionFactory getSessionFactory() { - if (sessionFactory == null) { - sessionFactory = buildSessionFactory(); - } - return sessionFactory; - } -} diff --git a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/SpringContextTest.java index f1a6f675ce..e1650dccd2 100644 --- a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/SpringContextTest.java +++ b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/SpringContextTest.java @@ -6,7 +6,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; -import com.baeldung.manytomany.PersistenceConfig; +import com.baeldung.hibernate.manytomany.PersistenceConfig; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) diff --git a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/booleanconverters/HibernateBooleanConverterIntegrationTest.java b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/booleanconverters/HibernateBooleanConverterIntegrationTest.java new file mode 100644 index 0000000000..3235485e96 --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/booleanconverters/HibernateBooleanConverterIntegrationTest.java @@ -0,0 +1,158 @@ +package com.baeldung.hibernate.booleanconverters; + +import static java.lang.String.format; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.util.UUID; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.booleanconverters.model.Question; + +public class HibernateBooleanConverterIntegrationTest { + + private static final String PROPERTY_FILE_NAME = "booleanconverters.cfg.xml"; + + private static SessionFactory sessionFactory; + private static Session session; + + @BeforeAll + static void createSessionFactory() { + sessionFactory = HibernateUtil.getSessionFactory(PROPERTY_FILE_NAME); + } + + @BeforeEach + void openSessionAndBeginTransaction() { + session = sessionFactory.openSession(); + } + + @AfterAll + static void closeSessionFactory() { + sessionFactory.close(); + } + + @Test + void whenFieldAnnotatedWithYesNoConverter_ThenConversionWorks() { + session.beginTransaction(); + UUID likeJavaQuestionId = UUID.randomUUID(); + UUID sydneyCapitalOfAustraliaQuestionId = UUID.randomUUID(); + session.persist(new QuestionBuilder().id(likeJavaQuestionId) + .content("Do you like Java?") + .correctAnswer(true) + .build()); + session.persist(new QuestionBuilder().id(sydneyCapitalOfAustraliaQuestionId) + .content("Is Sydney the capital of Australia?") + .correctAnswer(false) + .build()); + session.flush(); + + char likeJavaQuestionCorrectAnswerDbValue = session.createNativeQuery(format("SELECT correctAnswer FROM Question WHERE id='%s'", likeJavaQuestionId), Character.class) + .getSingleResult(); + char sydneyCapitalOfAustraliaQuestionCorrectAnswerDbValue = session.createNativeQuery(format("SELECT correctAnswer FROM Question WHERE id='%s'", sydneyCapitalOfAustraliaQuestionId), Character.class) + .getSingleResult(); + session.close(); + + assertEquals('Y', likeJavaQuestionCorrectAnswerDbValue); + assertEquals('N', sydneyCapitalOfAustraliaQuestionCorrectAnswerDbValue); + } + + @Test + void whenFieldAnnotatedWithTrueFalseConverter_ThenConversionWorks() { + session.beginTransaction(); + UUID codeTestedQuestionId = UUID.randomUUID(); + UUID earningsQuestionId = UUID.randomUUID(); + session.persist(new QuestionBuilder().id(codeTestedQuestionId) + .content("Is this code tested?") + .shouldBeAsked(true) + .build()); + session.persist(new QuestionBuilder().id(earningsQuestionId) + .content("How much do you earn?") + .shouldBeAsked(false) + .build()); + session.flush(); + + char codeTestedQuestionShouldBeAskedDbValue = session.createNativeQuery(format("SELECT shouldBeAsked FROM Question WHERE id='%s'", codeTestedQuestionId), Character.class) + .getSingleResult(); + char earningsQuestionsShouldBeAskedDbValue = session.createNativeQuery(format("SELECT shouldBeAsked FROM Question WHERE id='%s'", earningsQuestionId), Character.class) + .getSingleResult(); + session.close(); + + assertEquals('T', codeTestedQuestionShouldBeAskedDbValue); + assertEquals('F', earningsQuestionsShouldBeAskedDbValue); + } + + @Test + void whenFieldAnnotatedWithNumericBooleanConverter_ThenConversionWorks() { + session.beginTransaction(); + UUID earthFlatQuestionId = UUID.randomUUID(); + UUID shouldLearnProgrammingQuestionId = UUID.randomUUID(); + session.persist(new QuestionBuilder().id(earthFlatQuestionId) + .content("Is the Earth flat?") + .isEasy(true) + .build()); + session.persist(new QuestionBuilder().id(shouldLearnProgrammingQuestionId) + .content("Should one learn programming") + .isEasy(false) + .build()); + session.flush(); + + int earthFlatQuestionIsEasyDbValue = session.createNativeQuery(format("SELECT isEasy FROM Question WHERE id='%s'", earthFlatQuestionId), Integer.class) + .getSingleResult(); + int shouldLearnProgrammingQuestionIsEasyDbValue = session.createNativeQuery(format("SELECT isEasy FROM Question WHERE id='%s'", shouldLearnProgrammingQuestionId), Integer.class) + .getSingleResult(); + session.close(); + + assertEquals(1, earthFlatQuestionIsEasyDbValue); + assertEquals(0, shouldLearnProgrammingQuestionIsEasyDbValue); + } + + @Test + void givenFieldAnnotatedWithYesNoConverter_WhenDbValueIsLowercase_ThenDomainModelValueNull() { + session.beginTransaction(); + UUID mappedToNullQuestionId = UUID.randomUUID(); + UUID behaviorIntuitiveQuestionId = UUID.randomUUID(); + session.createNativeMutationQuery(format("INSERT INTO Question (id, content, correctAnswer) VALUES ('%s', 'Will correctAnswer be mapped to null?', 'y')", mappedToNullQuestionId)) + .executeUpdate(); + session.createNativeMutationQuery(format("INSERT INTO Question (id, content, correctAnswer) VALUES ('%s', 'Is this behavior intuitive?', 'n')", behaviorIntuitiveQuestionId)) + .executeUpdate(); + + Question behaviorIntuitiveQuestion = session.get(Question.class, behaviorIntuitiveQuestionId); + Question mappedToNullQuestion = session.get(Question.class, mappedToNullQuestionId); + session.close(); + + assertNull(behaviorIntuitiveQuestion.getCorrectAnswer()); + assertNull(mappedToNullQuestion.getCorrectAnswer()); + } + + @Test + void givenConverterRegisteredToAutoApply_whenFieldIsNotAnnotated_ThenConversionWorks() { + session.beginTransaction(); + UUID likeJavaQuestionId = UUID.randomUUID(); + UUID likeKotlinQuestionId = UUID.randomUUID(); + session.persist(new QuestionBuilder().id(likeJavaQuestionId) + .content("Do you like Java?") + .wasAskedBefore(true) + .build()); + session.persist(new QuestionBuilder().id(likeKotlinQuestionId) + .content("Do you like Kotlin?") + .wasAskedBefore(false) + .build()); + session.flush(); + + char likeJavaQuestionWasAskedBeforeDbValue = session.createNativeQuery(format("SELECT wasAskedBefore FROM Question WHERE id='%s'", likeJavaQuestionId), Character.class) + .getSingleResult(); + char likeKotlinQuestionWasAskedBeforeDbValue = session.createNativeQuery(format("SELECT wasAskedBefore FROM Question WHERE id='%s'", likeKotlinQuestionId), Character.class) + .getSingleResult(); + session.close(); + + assertEquals('Y', likeJavaQuestionWasAskedBeforeDbValue); + assertEquals('N', likeKotlinQuestionWasAskedBeforeDbValue); + } +} diff --git a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/booleanconverters/QuestionBuilder.java b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/booleanconverters/QuestionBuilder.java new file mode 100644 index 0000000000..26fe38c3c8 --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/booleanconverters/QuestionBuilder.java @@ -0,0 +1,48 @@ +package com.baeldung.hibernate.booleanconverters; + +import java.util.UUID; + +import com.baeldung.hibernate.booleanconverters.model.Question; + +public class QuestionBuilder { + private UUID id; + private String content; + private Boolean correctAnswer; + private Boolean shouldBeAsked; + private Boolean isEasy; + private Boolean wasAskedBefore; + + public QuestionBuilder id(UUID id) { + this.id = id; + return this; + } + + public QuestionBuilder content(String content) { + this.content = content; + return this; + } + + public QuestionBuilder correctAnswer(Boolean correctAnswer) { + this.correctAnswer = correctAnswer; + return this; + } + + public QuestionBuilder shouldBeAsked(Boolean shouldBeAsked) { + this.shouldBeAsked = shouldBeAsked; + return this; + } + + public QuestionBuilder isEasy(Boolean isEasy) { + this.isEasy = isEasy; + return this; + } + + public QuestionBuilder wasAskedBefore(Boolean wasAskedBefore) { + this.wasAskedBefore = wasAskedBefore; + return this; + } + + public Question build() { + return new Question(id, content, correctAnswer, shouldBeAsked, isEasy, wasAskedBefore); + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java index 69b791b4d4..e4fcafcb56 100644 --- a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java +++ b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java @@ -13,9 +13,9 @@ 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; -import com.baeldung.manytomany.PersistenceConfig; -import com.baeldung.manytomany.model.Employee; -import com.baeldung.manytomany.model.Project; + +import com.baeldung.hibernate.manytomany.model.Employee; +import com.baeldung.hibernate.manytomany.model.Project; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) diff --git a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java index 5255cb040f..7c6861e63b 100644 --- a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java +++ b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java @@ -15,9 +15,9 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import com.baeldung.manytomany.model.Employee; -import com.baeldung.manytomany.model.Project; -import com.baeldung.manytomany.util.HibernateUtil; +import com.baeldung.hibernate.manytomany.model.Employee; +import com.baeldung.hibernate.manytomany.model.Project; +import com.baeldung.hibernate.HibernateUtil; /** * Configured in: manytomany.cfg.xml diff --git a/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/uuids/UUIDsHibernateGenerationIntegrationTest.java b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/uuids/UUIDsHibernateGenerationIntegrationTest.java new file mode 100644 index 0000000000..f36a4333c3 --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/test/java/com/baeldung/hibernate/uuids/UUIDsHibernateGenerationIntegrationTest.java @@ -0,0 +1,72 @@ +package com.baeldung.hibernate.uuids; + +import com.baeldung.hibernate.HibernateUtil; + +import org.assertj.core.api.Assertions; +import java.io.IOException; + +import org.hibernate.SessionFactory; +import org.hibernate.Session; +import org.junit.Before; +import org.junit.Test; +import java.util.UUID; +import java.time.LocalDate; + +public class UUIDsHibernateGenerationIntegrationTest { + + private SessionFactory sessionFactory; + + private Session session; + + @Before + public void setUp() throws IOException { + sessionFactory = HibernateUtil.getSessionFactory(); + session = sessionFactory.openSession(); + } + + @Test + public void whenGeneratingUUIDUsingNewJPAGenerationType_thenHibernateGeneratedUUID() throws IOException { + Reservation reservation = new Reservation(); + reservation.setStatus("created"); + reservation.setNumber("12345"); + UUID saved = (UUID) session.save(reservation); + Assertions.assertThat(saved).isNotNull(); + } + + @Test + public void whenGeneratingUUIDUsingNewJPAGenerationType_thenHibernateGeneratedUUIDOfVersion4() throws IOException { + Reservation reservation = new Reservation(); + reservation.setStatus("new"); + reservation.setNumber("012"); + UUID saved = (UUID) session.save(reservation); + Assertions.assertThat(saved).isNotNull(); + Assertions.assertThat(saved.version()).isEqualTo(4); + } + + @Test + public void whenGeneratingUUIDUsingGenericConverter_thenAlsoGetUUIDGeneratedVersion4() throws IOException { + Sale sale = new Sale(); + sale.setCompleted(true); + UUID saved = (UUID) session.save(sale); + Assertions.assertThat(saved).isNotNull(); + Assertions.assertThat(saved.version()).isEqualTo(4); + } + + @Test + public void whenGeneratingTimeBasedUUID_thenUUIDGeneratedVersion1() throws IOException { + WebSiteUser user = new WebSiteUser(); + user.setRegistrationDate(LocalDate.now()); + UUID saved = (UUID) session.save(user); + Assertions.assertThat(saved).isNotNull(); + Assertions.assertThat(saved.version()).isEqualTo(1); + } + + @Test + public void whenGeneratingUUIDAsString_thenUUIDGeneratedVersion1() throws IOException { + Element element = new Element(); + element.setName("a"); + String saved = (String) session.save(element); + Assertions.assertThat(saved).isNotEmpty(); + Assertions.assertThat(UUID.fromString(saved).version()).isEqualTo(4); + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping-2/src/test/resources/booleanconverters.cfg.xml b/persistence-modules/hibernate-mapping-2/src/test/resources/booleanconverters.cfg.xml new file mode 100644 index 0000000000..6ca479b052 --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/test/resources/booleanconverters.cfg.xml @@ -0,0 +1,16 @@ + + + + + org.h2.Driver + + jdbc:h2:mem:booleanconvertersdb;DB_CLOSE_DELAY=-1;INIT=RUNSCRIPT FROM 'src/test/resources/booleanconverters/init_database.sql' + sa + org.hibernate.dialect.H2Dialect + thread + false + none + + \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping-2/src/test/resources/booleanconverters/init_database.sql b/persistence-modules/hibernate-mapping-2/src/test/resources/booleanconverters/init_database.sql new file mode 100644 index 0000000000..cb0f4f329c --- /dev/null +++ b/persistence-modules/hibernate-mapping-2/src/test/resources/booleanconverters/init_database.sql @@ -0,0 +1,9 @@ +CREATE TABLE Question ( + id UUID, + content VARCHAR, + correctAnswer CHAR, + shouldBeAsked CHAR, + isEasy TINYINT, + wasAskedBefore CHAR, + PRIMARY KEY (id) +) diff --git a/persistence-modules/hibernate-mapping/pom.xml b/persistence-modules/hibernate-mapping/pom.xml index 506283a4fb..1e3dc8be5f 100644 --- a/persistence-modules/hibernate-mapping/pom.xml +++ b/persistence-modules/hibernate-mapping/pom.xml @@ -26,7 +26,7 @@ com.vladmihalcea - hibernate-types-52 + hibernate-types-60 ${hibernate-types.version} @@ -41,9 +41,9 @@ ${hibernate-validator.version} - org.glassfish - javax.el - ${org.glassfish.javax.el.version} + org.glassfish.expressly + expressly + 5.0.0 javax.money @@ -66,16 +66,27 @@ commons-io ${commons-io.version} + + com.fasterxml.jackson.module + jackson-module-jakarta-xmlbind-annotations + ${jackson-module-jakarta-xmlbind-annotation} + + + org.openjdk.nashorn + nashorn-core + 15.4 + - 1.4.197 - 5.4.12.Final - 2.10.4 - 6.0.16.Final + 2.1.214 + 6.1.7.Final + 2.21.1 + 8.0.0.Final 3.0.1-b11 - 1.0.3 - 1.3 + 1.1 + 1.4.2 + 2.14.2 \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java index fbd8bd487b..cbd73832a4 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -21,6 +21,7 @@ import com.baeldung.hibernate.pojo.inheritance.Animal; import com.baeldung.hibernate.pojo.inheritance.Bag; import com.baeldung.hibernate.pojo.inheritance.Book; import com.baeldung.hibernate.pojo.inheritance.Car; +import com.baeldung.hibernate.pojo.inheritance.Laptop; import com.baeldung.hibernate.pojo.inheritance.MyEmployee; import com.baeldung.hibernate.pojo.inheritance.MyProduct; import com.baeldung.hibernate.pojo.inheritance.Pen; @@ -79,6 +80,7 @@ public class HibernateUtil { metadataSources.addAnnotatedClass(com.baeldung.hibernate.entities.Department.class); metadataSources.addAnnotatedClass(Animal.class); metadataSources.addAnnotatedClass(Bag.class); + metadataSources.addAnnotatedClass(Laptop.class); metadataSources.addAnnotatedClass(Book.class); metadataSources.addAnnotatedClass(Car.class); metadataSources.addAnnotatedClass(MyEmployee.class); @@ -86,7 +88,6 @@ public class HibernateUtil { metadataSources.addAnnotatedClass(Pen.class); metadataSources.addAnnotatedClass(Pet.class); metadataSources.addAnnotatedClass(Vehicle.class); - Metadata metadata = metadataSources.getMetadataBuilder() .build(); diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/arraymapping/CustomIntegerArrayType.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/arraymapping/CustomIntegerArrayType.java index 233bb95dc1..5d3e22bf05 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/arraymapping/CustomIntegerArrayType.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/arraymapping/CustomIntegerArrayType.java @@ -8,58 +8,56 @@ import java.sql.SQLException; import java.sql.Types; import java.util.Arrays; -import org.hibernate.HibernateException; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.usertype.UserType; -public class CustomIntegerArrayType implements UserType { +public class CustomIntegerArrayType implements UserType { @Override - public int[] sqlTypes() { - return new int[]{Types.ARRAY}; + public int getSqlType() { + return Types.ARRAY; } @Override - public Class returnedClass() { + public Class returnedClass() { return Integer[].class; } @Override - public boolean equals(Object x, Object y) throws HibernateException { + public boolean equals(Integer[] x, Integer[] y) { if (x instanceof Integer[] && y instanceof Integer[]) { - return Arrays.deepEquals((Integer[])x, (Integer[])y); + return Arrays.deepEquals(x, y); } else { return false; } } @Override - public int hashCode(Object x) throws HibernateException { - return Arrays.hashCode((Integer[])x); + public int hashCode(Integer[] x) { + return Arrays.hashCode(x); } @Override - public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) - throws HibernateException, SQLException { - Array array = rs.getArray(names[0]); - return array != null ? array.getArray() : null; + public Integer[] nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException { + Array array = rs.getArray(position); + return array != null ? (Integer[]) array.getArray() : null; } @Override - public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) - throws HibernateException, SQLException { - if (value != null && st != null) { - Array array = session.connection().createArrayOf("int", (Integer[])value); - st.setArray(index, array); - } else { - st.setNull(index, sqlTypes()[0]); + public void nullSafeSet(PreparedStatement st, Integer[] value, int index, SharedSessionContractImplementor session) throws SQLException { + if (st != null) { + if (value != null) { + Array array = session.getJdbcConnectionAccess().obtainConnection().createArrayOf("int", value); + st.setArray(index, array); + } else { + st.setNull(index, Types.ARRAY); + } } } @Override - public Object deepCopy(Object value) throws HibernateException { - Integer[] a = (Integer[])value; - return Arrays.copyOf(a, a.length); + public Integer[] deepCopy(Integer[] value) { + return value != null ? Arrays.copyOf(value, value.length) : null; } @Override @@ -68,18 +66,18 @@ public class CustomIntegerArrayType implements UserType { } @Override - public Serializable disassemble(Object value) throws HibernateException { - return (Serializable) value; + public Serializable disassemble(Integer[] value) { + return value; } @Override - public Object assemble(Serializable cached, Object owner) throws HibernateException { - return cached; + public Integer[] assemble(Serializable cached, Object owner) { + return (Integer[]) cached; } @Override - public Object replace(Object original, Object target, Object owner) throws HibernateException { - return original; + public Integer[] replace(Integer[] detached, Integer[] managed, Object owner) { + return detached; } } diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/arraymapping/CustomStringArrayType.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/arraymapping/CustomStringArrayType.java index 7bd284def7..31a082fb05 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/arraymapping/CustomStringArrayType.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/arraymapping/CustomStringArrayType.java @@ -8,58 +8,56 @@ import java.sql.SQLException; import java.sql.Types; import java.util.Arrays; -import org.hibernate.HibernateException; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.usertype.UserType; -public class CustomStringArrayType implements UserType { +public class CustomStringArrayType implements UserType { @Override - public int[] sqlTypes() { - return new int[]{Types.ARRAY}; + public int getSqlType() { + return Types.ARRAY; } @Override - public Class returnedClass() { + public Class returnedClass() { return String[].class; } @Override - public boolean equals(Object x, Object y) throws HibernateException { + public boolean equals(String[] x, String[] y) { if (x instanceof String[] && y instanceof String[]) { - return Arrays.deepEquals((String[])x, (String[])y); + return Arrays.deepEquals(x, y); } else { return false; } } @Override - public int hashCode(Object x) throws HibernateException { - return Arrays.hashCode((String[])x); + public int hashCode(String[] x) { + return Arrays.hashCode(x); } @Override - public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) - throws HibernateException, SQLException { - Array array = rs.getArray(names[0]); - return array != null ? array.getArray() : null; + public String[] nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException { + Array array = rs.getArray(position); + return array != null ? (String[]) array.getArray() : null; } @Override - public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) - throws HibernateException, SQLException { - if (value != null && st != null) { - Array array = session.connection().createArrayOf("text", (String[])value); - st.setArray(index, array); - } else { - st.setNull(index, sqlTypes()[0]); + public void nullSafeSet(PreparedStatement st, String[] value, int index, SharedSessionContractImplementor session) throws SQLException { + if (st != null) { + if (value != null) { + Array array = session.getJdbcConnectionAccess().obtainConnection().createArrayOf("text", value); + st.setArray(index, array); + } else { + st.setNull(index, Types.ARRAY); + } } } @Override - public Object deepCopy(Object value) throws HibernateException { - String[] a = (String[])value; - return Arrays.copyOf(a, a.length); + public String[] deepCopy(String[] value) { + return value != null ? Arrays.copyOf(value, value.length) : null; } @Override @@ -68,18 +66,18 @@ public class CustomStringArrayType implements UserType { } @Override - public Serializable disassemble(Object value) throws HibernateException { - return (Serializable) value; + public Serializable disassemble(String[] value) { + return value; } @Override - public Object assemble(Serializable cached, Object owner) throws HibernateException { - return cached; + public String[] assemble(Serializable cached, Object owner) { + return (String[]) cached; } @Override - public Object replace(Object original, Object target, Object owner) throws HibernateException { - return original; + public String[] replace(String[] detached, String[] managed, Object owner) { + return detached; } } diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/arraymapping/User.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/arraymapping/User.java index 018bedc349..81f2ee89f7 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/arraymapping/User.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/arraymapping/User.java @@ -1,21 +1,13 @@ package com.baeldung.hibernate.arraymapping; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; import org.hibernate.annotations.Type; import com.vladmihalcea.hibernate.type.array.StringArrayType; -import org.hibernate.annotations.*; - -@TypeDefs({ - @TypeDef( - name = "string-array", - typeClass = StringArrayType.class - ) -}) @Entity public class User { @@ -25,14 +17,14 @@ public class User { private String name; @Column(columnDefinition = "text[]") - @Type(type = "com.baeldung.hibernate.arraymapping.CustomStringArrayType") + @Type(value = com.baeldung.hibernate.arraymapping.CustomStringArrayType.class) private String[] roles; @Column(columnDefinition = "int[]") - @Type(type = "com.baeldung.hibernate.arraymapping.CustomIntegerArrayType") + @Type(value = com.baeldung.hibernate.arraymapping.CustomIntegerArrayType.class) private Integer[] locations; - @Type(type = "string-array") + @Type(StringArrayType.class) @Column( name = "phone_numbers", columnDefinition = "text[]" diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/basicannotation/Course.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/basicannotation/Course.java index e816fb0176..ca77888f9b 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/basicannotation/Course.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/basicannotation/Course.java @@ -1,10 +1,9 @@ package com.baeldung.hibernate.basicannotation; -import javax.persistence.Basic; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import jakarta.persistence.Basic; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; @Entity public class Course { diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/entities/Department.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/entities/Department.java index ff94f4f849..39e69a2b1c 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/entities/Department.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/entities/Department.java @@ -2,7 +2,7 @@ package com.baeldung.hibernate.entities; import java.util.List; -import javax.persistence.*; +import jakarta.persistence.*; @Entity public class Department { diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java index 6510e70650..3c4f542ce7 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java @@ -1,13 +1,13 @@ package com.baeldung.hibernate.entities; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; @org.hibernate.annotations.NamedQueries({ @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindByEmployeeNumber", query = "from DeptEmployee where employeeNumber = :employeeNo"), - @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindAllByDesgination", query = "from DeptEmployee where designation = :designation"), + @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindAllByDesgination", query = "from DeptEmployee where employeeNumber = :designation"), @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_UpdateEmployeeDepartment", query = "Update DeptEmployee set department = :newDepartment where employeeNumber = :employeeNo"), @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindAllByDepartment", query = "from DeptEmployee where department = :department", timeout = 1, fetchSize = 10) }) @org.hibernate.annotations.NamedNativeQueries({ @org.hibernate.annotations.NamedNativeQuery(name = "DeptEmployee_FindByEmployeeName", query = "select * from deptemployee emp where name=:name", resultClass = DeptEmployee.class), diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/fetchMode/Customer.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/fetchMode/Customer.java index 5589601da8..b8937c6692 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/fetchMode/Customer.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/fetchMode/Customer.java @@ -3,10 +3,10 @@ package com.baeldung.hibernate.fetchMode; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.OneToMany; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; import java.util.HashSet; import java.util.Set; diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/fetchMode/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/fetchMode/Order.java index aa9c517321..5be65bac0d 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/fetchMode/Order.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/fetchMode/Order.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.fetchMode; -import javax.persistence.*; +import jakarta.persistence.*; @Entity public class Order { diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/lob/model/User.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/lob/model/User.java index 21f725b388..3c3b748990 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/lob/model/User.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/lob/model/User.java @@ -1,13 +1,13 @@ package com.baeldung.hibernate.lob.model; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Lob; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.Table; @Entity -@Table(name="user") +@Table(name="users") public class User { @Id diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java index 385ffe93ea..ff8115f5d9 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java @@ -2,15 +2,15 @@ package com.baeldung.hibernate.persistmaps.mapkey; import com.baeldung.hibernate.persistmaps.ItemType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; import java.util.Date; import java.util.Objects; diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java index 8409cacd6b..e42ceda5de 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java @@ -1,15 +1,15 @@ package com.baeldung.hibernate.persistmaps.mapkey; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.MapKey; -import javax.persistence.OneToMany; -import javax.persistence.Table; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.MapKey; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; import java.util.Map; @Entity diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/User.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/User.java index b2ee7e85fe..0a9694f43c 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/User.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/User.java @@ -1,16 +1,15 @@ package com.baeldung.hibernate.persistmaps.mapkey; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.validation.constraints.Size; -import javax.money.MonetaryAmount; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.validation.constraints.Size; import org.hibernate.validator.constraints.Length; -import org.hibernate.validator.constraints.CreditCardNumber; -import org.hibernate.validator.constraints.Currency; @Entity +@Table(name="users2") public class User { @Id @Column(length = 3) diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java index fa092060da..3d24c743d7 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java @@ -1,14 +1,14 @@ package com.baeldung.hibernate.persistmaps.mapkeycolumn; -import javax.persistence.CollectionTable; -import javax.persistence.Column; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.MapKeyColumn; -import javax.persistence.Table; +import jakarta.persistence.CollectionTable; +import jakarta.persistence.Column; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.MapKeyColumn; +import jakarta.persistence.Table; import java.util.Map; @Entity diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java index e1f62599b8..19622ea01d 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java @@ -3,17 +3,17 @@ package com.baeldung.hibernate.persistmaps.mapkeyenumerated; import com.baeldung.hibernate.persistmaps.ItemType; import com.baeldung.hibernate.persistmaps.mapkey.Item; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.MapKeyEnumerated; -import javax.persistence.OneToMany; -import javax.persistence.Table; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.MapKeyEnumerated; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; import java.util.Map; @Entity diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java index 97bbd5b539..9ed58305da 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java @@ -2,18 +2,18 @@ package com.baeldung.hibernate.persistmaps.mapkeyjoincolumn; import com.baeldung.hibernate.persistmaps.ItemType; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; import java.util.Date; import java.util.Objects; diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java index d680d84501..9d20237860 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java @@ -1,15 +1,15 @@ package com.baeldung.hibernate.persistmaps.mapkeyjoincolumn; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.MapKeyJoinColumn; -import javax.persistence.OneToMany; -import javax.persistence.Table; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.MapKeyJoinColumn; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; import java.util.Map; @Entity diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java index 15b08e9fe6..ca06db241e 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java @@ -1,10 +1,10 @@ package com.baeldung.hibernate.persistmaps.mapkeyjoincolumn; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import java.util.Objects; @Entity diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java index be602c1e9f..920d693d16 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java @@ -2,17 +2,17 @@ package com.baeldung.hibernate.persistmaps.mapkeytemporal; import com.baeldung.hibernate.persistmaps.mapkey.Item; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.MapKeyTemporal; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.TemporalType; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.MapKeyTemporal; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.persistence.TemporalType; import java.util.Date; import java.util.Map; diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/Employee.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/Employee.java index e9732b2b67..7d8a254eec 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/Employee.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/Employee.java @@ -2,15 +2,15 @@ package com.baeldung.hibernate.pojo; import org.hibernate.annotations.*; -import javax.persistence.Entity; -import javax.persistence.*; +import jakarta.persistence.Entity; +import jakarta.persistence.*; import java.io.Serializable; import java.util.HashSet; import java.util.Set; @Entity @Where(clause = "deleted = false") -@FilterDef(name = "incomeLevelFilter", parameters = @ParamDef(name = "incomeLimit", type = "int")) +@FilterDef(name = "incomeLevelFilter", parameters = @ParamDef(name = "incomeLimit", type = Integer.class)) @Filter(name = "incomeLevelFilter", condition = "grossIncome > :incomeLimit") public class Employee implements Serializable { diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/EntityDescription.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/EntityDescription.java index 131bb73a80..29befd80f2 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/EntityDescription.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/EntityDescription.java @@ -1,8 +1,11 @@ package com.baeldung.hibernate.pojo; import org.hibernate.annotations.Any; +import org.hibernate.annotations.AnyDiscriminator; +import org.hibernate.annotations.AnyDiscriminatorValue; +import org.hibernate.annotations.AnyKeyJavaClass; -import javax.persistence.*; +import jakarta.persistence.*; import java.io.Serializable; @Entity @@ -14,10 +17,12 @@ public class EntityDescription implements Serializable { private String description; - @Any( - metaDef = "EntityDescriptionMetaDef", - metaColumn = @Column(name = "entity_type") - ) + @Any + @AnyDiscriminator(DiscriminatorType.STRING) + @AnyDiscriminatorValue(discriminator = "S", entity = Employee.class) + @AnyDiscriminatorValue(discriminator = "I", entity = Phone.class) + @AnyKeyJavaClass(Integer.class) + @Column(name = "entity_type") @JoinColumn(name = "entity_id") private Serializable entity; diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/Phone.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/Phone.java index d923bda5de..e173aa8b47 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/Phone.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/Phone.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.pojo; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; import java.io.Serializable; @Entity diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java index f3fe095cae..0c022884eb 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java @@ -1,7 +1,6 @@ package com.baeldung.hibernate.pojo; -import javax.persistence.*; -import java.io.Serializable; +import jakarta.persistence.*; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; @@ -9,7 +8,7 @@ import java.time.*; import java.util.Calendar; @Entity -public class TemporalValues implements Serializable { +public class TemporalValues { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -48,7 +47,7 @@ public class TemporalValues implements Serializable { private java.time.LocalDate localDate; @Basic - private java.time.LocalTime localTime; + private java.time.LocalTime localTimeField; @Basic private java.time.OffsetTime offsetTime; @@ -146,11 +145,11 @@ public class TemporalValues implements Serializable { } public LocalTime getLocalTime() { - return localTime; + return localTimeField; } public void setLocalTime(LocalTime localTime) { - this.localTime = localTime; + this.localTimeField = localTime; } public OffsetTime getOffsetTime() { diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java index 6fe7f915fc..c44a542b60 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.pojo.inheritance; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Inheritance; -import javax.persistence.InheritanceType; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; @Entity @Inheritance(strategy = InheritanceType.JOINED) diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java index fa6e1b4bef..707e387866 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java @@ -1,7 +1,7 @@ package com.baeldung.hibernate.pojo.inheritance; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; import org.hibernate.annotations.Polymorphism; import org.hibernate.annotations.PolymorphismType; diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java index 36ca8dd77c..286a30cc14 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java @@ -1,7 +1,7 @@ package com.baeldung.hibernate.pojo.inheritance; -import javax.persistence.DiscriminatorValue; -import javax.persistence.Entity; +import jakarta.persistence.DiscriminatorValue; +import jakarta.persistence.Entity; @Entity @DiscriminatorValue("1") diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java index 49d1f7749a..987e299625 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.pojo.inheritance; -import javax.persistence.Entity; +import jakarta.persistence.Entity; @Entity public class Car extends Vehicle { diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Laptop.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Laptop.java new file mode 100644 index 0000000000..cced365d78 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Laptop.java @@ -0,0 +1,39 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import org.hibernate.annotations.Polymorphism; +import org.hibernate.annotations.PolymorphismType; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +@Entity +@Polymorphism(type = PolymorphismType.IMPLICIT) +public class Laptop implements Item { + + @Id + private Long id; + + private String type; + + public Laptop(Long id, String type) { + this.id = id; + this.type = type; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java index 9a6bce16cf..96958c6e28 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.pojo.inheritance; -import javax.persistence.Entity; +import jakarta.persistence.Entity; @Entity public class MyEmployee extends Person { diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java index 13f04d8904..62214fc16e 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java @@ -1,13 +1,11 @@ package com.baeldung.hibernate.pojo.inheritance; -import javax.persistence.DiscriminatorColumn; -import javax.persistence.DiscriminatorType; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Inheritance; -import javax.persistence.InheritanceType; - -import org.hibernate.annotations.DiscriminatorFormula; +import jakarta.persistence.DiscriminatorColumn; +import jakarta.persistence.DiscriminatorType; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java index 32b77e52af..2382cab405 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java @@ -1,7 +1,7 @@ package com.baeldung.hibernate.pojo.inheritance; -import javax.persistence.DiscriminatorValue; -import javax.persistence.Entity; +import jakarta.persistence.DiscriminatorValue; +import jakarta.persistence.Entity; @Entity @DiscriminatorValue("2") diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java index 99084b88af..9bf8ac254c 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java @@ -1,7 +1,7 @@ package com.baeldung.hibernate.pojo.inheritance; -import javax.persistence.Id; -import javax.persistence.MappedSuperclass; +import jakarta.persistence.Id; +import jakarta.persistence.MappedSuperclass; @MappedSuperclass public class Person { diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java index 870b3cd684..b359eb3a21 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java @@ -1,7 +1,7 @@ package com.baeldung.hibernate.pojo.inheritance; -import javax.persistence.Entity; -import javax.persistence.PrimaryKeyJoinColumn; +import jakarta.persistence.Entity; +import jakarta.persistence.PrimaryKeyJoinColumn; @Entity @PrimaryKeyJoinColumn(name = "petId") diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java index b2a920573e..9bdde8c33b 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java @@ -1,9 +1,9 @@ package com.baeldung.hibernate.pojo.inheritance; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Inheritance; -import javax.persistence.InheritanceType; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/package-info.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/package-info.java deleted file mode 100644 index 992cda7c1d..0000000000 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/pojo/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -@AnyMetaDef(name = "EntityDescriptionMetaDef", metaType = "string", idType = "int", - metaValues = { - @MetaValue(value = "Employee", targetEntity = Employee.class), - @MetaValue(value = "Phone", targetEntity = Phone.class) - }) -package com.baeldung.hibernate.pojo; - -import org.hibernate.annotations.AnyMetaDef; -import org.hibernate.annotations.MetaValue; \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java index 7a112200b5..833c5cc3ff 100644 --- a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java @@ -119,8 +119,8 @@ public class DynamicMappingIntegrationTest { assertThat(employees).hasSize(2); - Employee employee = session.get(Employee.class, 1); - assertThat(employee.getGrossIncome()).isEqualTo(10_000); + Employee employee = session.get(Employee.class, 2); + assertThat(employee.getGrossIncome()).isEqualTo(12_000); session.disableFilter("incomeLevelFilter"); employees = session.createQuery("from Employee").getResultList(); diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java index 0f35dbb8af..7f4cac141c 100644 --- a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java @@ -13,6 +13,7 @@ import org.junit.Test; import com.baeldung.hibernate.pojo.inheritance.Bag; import com.baeldung.hibernate.pojo.inheritance.Book; import com.baeldung.hibernate.pojo.inheritance.Car; +import com.baeldung.hibernate.pojo.inheritance.Laptop; import com.baeldung.hibernate.pojo.inheritance.MyEmployee; import com.baeldung.hibernate.pojo.inheritance.Pen; import com.baeldung.hibernate.pojo.inheritance.Pet; @@ -81,9 +82,12 @@ public class InheritanceMappingIntegrationTest { public void givenSubclasses_whenQueryNonMappedInterface_thenOk() { Bag bag = new Bag(1, "large"); session.save(bag); + + Laptop laptop = new Laptop(1L, "Dell"); + session.save(laptop); assertThat(session.createQuery("from com.baeldung.hibernate.pojo.inheritance.Item") .getResultList() - .size()).isEqualTo(0); + .size()).isEqualTo(1); } } diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/basicannotation/BasicAnnotationIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/basicannotation/BasicAnnotationIntegrationTest.java index 930bea60c5..6a9a4f095b 100644 --- a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/basicannotation/BasicAnnotationIntegrationTest.java +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/basicannotation/BasicAnnotationIntegrationTest.java @@ -2,7 +2,7 @@ package com.baeldung.hibernate.basicannotation; import java.io.IOException; -import javax.persistence.PersistenceException; +import jakarta.persistence.PersistenceException; import org.hibernate.Session; import org.hibernate.SessionFactory; diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserAdditionalValidationUnitTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserAdditionalValidationUnitTest.java index 0f2a0403e9..17212173ec 100644 --- a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserAdditionalValidationUnitTest.java +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserAdditionalValidationUnitTest.java @@ -7,13 +7,12 @@ import java.math.BigDecimal; import java.time.Duration; import java.util.Set; -import javax.money.CurrencyContextBuilder; import javax.money.Monetary; import javax.money.MonetaryAmount; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.hibernate.validator.constraints.CodePointLength; import org.hibernate.validator.constraints.CreditCardNumber; @@ -21,12 +20,10 @@ import org.hibernate.validator.constraints.Currency; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.LuhnCheck; import org.hibernate.validator.constraints.Range; -import org.hibernate.validator.constraints.SafeHtml; import org.hibernate.validator.constraints.ScriptAssert; import org.hibernate.validator.constraints.URL; import org.hibernate.validator.constraints.time.DurationMax; import org.hibernate.validator.constraints.time.DurationMin; -import org.javamoney.moneta.CurrencyUnitBuilder; import org.javamoney.moneta.Money; import org.junit.BeforeClass; import org.junit.Test; diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserValidationUnitTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserValidationUnitTest.java index e39f324856..495ad657be 100644 --- a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserValidationUnitTest.java +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserValidationUnitTest.java @@ -2,11 +2,11 @@ package com.baeldung.hibernate.validation; import static org.junit.Assert.assertEquals; import java.util.Set; -import javax.persistence.PersistenceException; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import jakarta.persistence.PersistenceException; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.Before; diff --git a/persistence-modules/hibernate-queries/pom.xml b/persistence-modules/hibernate-queries/pom.xml index 68a46b82b1..bb60c7b83a 100644 --- a/persistence-modules/hibernate-queries/pom.xml +++ b/persistence-modules/hibernate-queries/pom.xml @@ -85,15 +85,21 @@ ${testcontainers.mysql.version} test + + io.hypersistence + hypersistence-utils-hibernate-60 + 3.3.1 + - 5.0.2.RELEASE - 1.10.6.RELEASE + 6.0.6 + 3.0.3 9.0.0.M26 - 6.0.6 - 2.2.3 + 8.0.32 + 2.6.0 2.1.214 + 6.1.7.Final 1.17.6 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 8771e02e0b..9041c6727c 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 @@ -1,7 +1,7 @@ package com.baeldung.hibernate.criteria.model; import java.io.Serializable; -import javax.persistence.Entity; +import jakarta.persistence.Entity; @org.hibernate.annotations.NamedQueries({ @org.hibernate.annotations.NamedQuery(name = "Employee_findByEmployeeId", query = "from Employee where id = :employeeId"), diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java index 248f64474a..2b782c2a1d 100644 --- a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java @@ -12,10 +12,10 @@ package com.baeldung.hibernate.criteria.view; import java.util.List; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; import org.hibernate.Session; import org.hibernate.query.Query; 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 f8c525611b..9303fd893e 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 @@ -3,9 +3,9 @@ package com.baeldung.hibernate.criteria.view; import com.baeldung.hibernate.criteria.model.Employee; import com.baeldung.hibernate.criteria.util.HibernateUtil; import java.util.List; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; import org.hibernate.Session; import org.hibernate.query.Query; diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteriaquery/Student.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteriaquery/Student.java index 314e7ca557..af6b561091 100644 --- a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteriaquery/Student.java +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteriaquery/Student.java @@ -1,11 +1,11 @@ package com.baeldung.hibernate.criteriaquery; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "students") diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java index 56be9e693f..58d8e8628a 100644 --- a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java @@ -1,14 +1,15 @@ package com.baeldung.hibernate.customtypes; -import org.hibernate.type.LocalDateType; -import org.hibernate.type.descriptor.WrapperOptions; -import org.hibernate.type.descriptor.java.AbstractTypeDescriptor; -import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; -import org.hibernate.type.descriptor.java.MutabilityPlan; import java.time.LocalDate; +import java.time.format.DateTimeFormatter; -public class LocalDateStringJavaDescriptor extends AbstractTypeDescriptor { +import org.hibernate.type.descriptor.WrapperOptions; +import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; + +import io.hypersistence.utils.hibernate.type.array.internal.AbstractArrayTypeDescriptor; + +public class LocalDateStringJavaDescriptor extends AbstractArrayTypeDescriptor { public static final LocalDateStringJavaDescriptor INSTANCE = new LocalDateStringJavaDescriptor(); @@ -18,12 +19,12 @@ public class LocalDateStringJavaDescriptor extends AbstractTypeDescriptor implements DiscriminatorType { +public class LocalDateStringType extends AbstractSingleColumnStandardBasicType { public static final LocalDateStringType INSTANCE = new LocalDateStringType(); public LocalDateStringType() { - super(VarcharTypeDescriptor.INSTANCE, LocalDateStringJavaDescriptor.INSTANCE); + super(VarcharJdbcType.INSTANCE, LocalDateStringJavaDescriptor.INSTANCE); } @Override @@ -21,14 +19,12 @@ public class LocalDateStringType extends AbstractSingleColumnStandardBasicTypeHibernate EntityManager Demo true - + - - - - + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java index a1f88f3387..c405eb9ebd 100644 --- a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java +++ b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java @@ -15,10 +15,10 @@ import com.baeldung.hibernate.criteria.model.Item; import com.baeldung.hibernate.criteria.util.HibernateUtil; import com.baeldung.hibernate.criteria.view.ApplicationView; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaDelete; -import javax.persistence.criteria.CriteriaUpdate; -import javax.persistence.criteria.Root; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaDelete; +import jakarta.persistence.criteria.CriteriaUpdate; +import jakarta.persistence.criteria.Root; public class HibernateCriteriaIntegrationTest { diff --git a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteriaquery/TypeSafeCriteriaIntegrationTest.java b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteriaquery/TypeSafeCriteriaIntegrationTest.java index cedba412d9..bfcb4301a7 100644 --- a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteriaquery/TypeSafeCriteriaIntegrationTest.java +++ b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteriaquery/TypeSafeCriteriaIntegrationTest.java @@ -1,6 +1,5 @@ package com.baeldung.hibernate.criteriaquery; -import com.baeldung.hibernate.criteriaquery.HibernateUtil; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.query.Query; @@ -10,9 +9,9 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; import java.io.IOException; import java.util.List; diff --git a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/distinct/entities/DistinctHqlQueriesUnitTest.java b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/distinct/entities/DistinctHqlQueriesUnitTest.java index 799439a51b..3ce384741f 100644 --- a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/distinct/entities/DistinctHqlQueriesUnitTest.java +++ b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/distinct/entities/DistinctHqlQueriesUnitTest.java @@ -8,7 +8,6 @@ import java.util.List; import org.hibernate.Session; import org.hibernate.Transaction; -import org.hibernate.annotations.QueryHints; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -45,12 +44,12 @@ public class DistinctHqlQueriesUnitTest { } @Test - public void whenExecutingSelectQuery_thereWillBeDuplicates() { + public void whenExecutingSelectQuery_thereTheInsertedPosts() { String hql = "SELECT p FROM Post p LEFT JOIN FETCH p.comments"; List posts = session.createQuery(hql, Post.class) .getResultList(); - assertThat(posts).hasSize(3); + assertThat(posts).hasSize(1); } @Test @@ -68,8 +67,8 @@ public class DistinctHqlQueriesUnitTest { @Test public void whenExecutingSelectDistinctQueryWithHint_thereShouldBeNoDuplicates() { String hql = "SELECT DISTINCT p FROM Post p LEFT JOIN FETCH p.comments"; + // From Hibernate ORM 6, distinct is always passed to the SQL query and the flag QueryHints#HINT_PASS_DISTINCT_THROUGH has been removed. List posts = session.createQuery(hql, Post.class) - .setHint(QueryHints.PASS_DISTINCT_THROUGH, false) .getResultList(); assertThat(posts).hasSize(1) diff --git a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/keywords/HibernateKeywordsApplicationIntegrationTest.java b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/keywords/HibernateKeywordsApplicationManualTest.java similarity index 78% rename from persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/keywords/HibernateKeywordsApplicationIntegrationTest.java rename to persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/keywords/HibernateKeywordsApplicationManualTest.java index 4282da3de4..780a0fd77e 100644 --- a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/keywords/HibernateKeywordsApplicationIntegrationTest.java +++ b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/keywords/HibernateKeywordsApplicationManualTest.java @@ -3,8 +3,6 @@ package com.baeldung.hibernate.keywords; import static java.util.UUID.randomUUID; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import javax.persistence.PersistenceException; - import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; @@ -13,7 +11,17 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -public class HibernateKeywordsApplicationIntegrationTest { +import jakarta.persistence.PersistenceException; + +/** + * This test suite uses testcontainers library and therefore + * requires Docker installed on the local system to be able to run it. + * + * When docker is available on the local machine it can be run either by: + * - running it from your favorite IDE + * - or through `mvn test -Dtest=HibernateKeywordsApplicationManualTest` + */ +public class HibernateKeywordsApplicationManualTest { private static SessionFactory sessionFactory; private Session session; diff --git a/persistence-modules/java-jpa-2/pom.xml b/persistence-modules/java-jpa-2/pom.xml index b736b50dd1..34e7f9f349 100644 --- a/persistence-modules/java-jpa-2/pom.xml +++ b/persistence-modules/java-jpa-2/pom.xml @@ -14,32 +14,44 @@ - org.hibernate + org.hibernate.orm hibernate-core ${hibernate.version} + + + jakarta.xml.bind + jakarta.xml.bind-api + + - org.hibernate + org.hibernate.orm hibernate-jpamodelgen ${hibernate.version} + + + jakarta.xml.bind + jakarta.xml.bind-api + + com.h2database h2 ${h2.version} - - - javax.persistence - javax.persistence-api - ${javax.persistence-api.version} - org.eclipse.persistence eclipselink ${eclipselink.version} runtime + + + jakarta.xml.bind + jakarta.xml.bind-api + + org.postgresql @@ -51,13 +63,25 @@ com.querydsl querydsl-apt ${querydsl.version} + jakarta provided com.querydsl querydsl-jpa + jakarta ${querydsl.version} + + jakarta.xml.bind + jakarta.xml.bind-api + ${jakarta.xml.bind-api.version} + + + javax.annotation + javax.annotation-api + ${javax.annotation.version} + @@ -130,14 +154,15 @@ - 5.4.14.Final - 2.7.4 + 4.0.1 2.2 3.5.1 3.3.3 3.0.0 - 4.3.1 + 5.0.0 1.4.200 + 4.0.0 + 1.3.2 \ No newline at end of file diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/criteria/CustomItemRepositoryImpl.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/criteria/CustomItemRepositoryImpl.java index c64cd14ca5..a014217b88 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/criteria/CustomItemRepositoryImpl.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/criteria/CustomItemRepositoryImpl.java @@ -2,13 +2,13 @@ package com.baeldung.jpa.criteria; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; public class CustomItemRepositoryImpl implements CustomItemRepository { diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/criteria/Item.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/criteria/Item.java index f6093e5735..3662d4918b 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/criteria/Item.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/criteria/Item.java @@ -1,8 +1,8 @@ package com.baeldung.jpa.criteria; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Table(name = "item") @Entity diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/defaultvalues/User.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/defaultvalues/User.java index 436c708d40..b89432c051 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/defaultvalues/User.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/defaultvalues/User.java @@ -1,11 +1,10 @@ package com.baeldung.jpa.defaultvalues; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; -@Entity +@Entity(name = "users") public class User { @Id diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/defaultvalues/UserRepository.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/defaultvalues/UserRepository.java index 52f9807cfb..7639dc74c5 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/defaultvalues/UserRepository.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/defaultvalues/UserRepository.java @@ -1,8 +1,8 @@ package com.baeldung.jpa.defaultvalues; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; public class UserRepository { diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/entity/Article.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/entity/Article.java index 02082c3d92..9aaa6f3d34 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/entity/Article.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/entity/Article.java @@ -1,7 +1,7 @@ package com.baeldung.jpa.entity; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; @Entity(name = "MyArticle") @Table(name = Article.TABLE_NAME) diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/Admin.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/Admin.java index 1c59b33ab8..b9c50a3e88 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/Admin.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/Admin.java @@ -1,10 +1,10 @@ package com.baeldung.jpa.generateidvalue; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "app_admin") diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/Article.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/Article.java index 06465de179..5ebb812638 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/Article.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/Article.java @@ -1,12 +1,12 @@ package com.baeldung.jpa.generateidvalue; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.SequenceGenerator; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; @Entity @Table(name = "article") diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/IdGenerator.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/IdGenerator.java index 0fac86747f..371b844fd6 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/IdGenerator.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/IdGenerator.java @@ -1,11 +1,11 @@ package com.baeldung.jpa.generateidvalue; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Table(name = "id_gen") @Entity diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/Task.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/Task.java index a51ec53418..e2f67ee0de 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/Task.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/Task.java @@ -1,12 +1,12 @@ package com.baeldung.jpa.generateidvalue; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.TableGenerator; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.TableGenerator; @Entity @Table(name = "task") diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/User.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/User.java index 88fefe7ba6..7b976c5ee1 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/User.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/generateidvalue/User.java @@ -1,11 +1,11 @@ package com.baeldung.jpa.generateidvalue; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "app_user") diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/multipleentities/AllergensAsEntity.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/multipleentities/AllergensAsEntity.java index e5e228d013..fc1777abe8 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/multipleentities/AllergensAsEntity.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/multipleentities/AllergensAsEntity.java @@ -1,13 +1,13 @@ package com.baeldung.jpa.multipletables.multipleentities; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToOne; -import javax.persistence.PrimaryKeyJoinColumn; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.PrimaryKeyJoinColumn; +import jakarta.persistence.Table; import com.baeldung.jpa.multipletables.secondarytable.MealAsSingleEntity; diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/multipleentities/MealWithMultipleEntities.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/multipleentities/MealWithMultipleEntities.java index 74105f8f1f..f14540e7ae 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/multipleentities/MealWithMultipleEntities.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/multipleentities/MealWithMultipleEntities.java @@ -2,13 +2,13 @@ package com.baeldung.jpa.multipletables.multipleentities; import java.math.BigDecimal; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; @Entity @Table(name = "meal") diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/secondarytable/MealAsSingleEntity.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/secondarytable/MealAsSingleEntity.java index 2929f391a4..d967d7618d 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/secondarytable/MealAsSingleEntity.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/secondarytable/MealAsSingleEntity.java @@ -2,14 +2,14 @@ package com.baeldung.jpa.multipletables.secondarytable; import java.math.BigDecimal; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.PrimaryKeyJoinColumn; -import javax.persistence.SecondaryTable; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.PrimaryKeyJoinColumn; +import jakarta.persistence.SecondaryTable; +import jakarta.persistence.Table; @Entity @Table(name = "meal") diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/secondarytable/embeddable/AllergensAsEmbeddable.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/secondarytable/embeddable/AllergensAsEmbeddable.java index 1c1f05890b..b95649029e 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/secondarytable/embeddable/AllergensAsEmbeddable.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/secondarytable/embeddable/AllergensAsEmbeddable.java @@ -1,7 +1,7 @@ package com.baeldung.jpa.multipletables.secondarytable.embeddable; -import javax.persistence.Column; -import javax.persistence.Embeddable; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; @Embeddable public class AllergensAsEmbeddable { diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/secondarytable/embeddable/MealWithEmbeddedAllergens.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/secondarytable/embeddable/MealWithEmbeddedAllergens.java index 87a83157d7..ada6328226 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/secondarytable/embeddable/MealWithEmbeddedAllergens.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/multipletables/secondarytable/embeddable/MealWithEmbeddedAllergens.java @@ -2,15 +2,15 @@ package com.baeldung.jpa.multipletables.secondarytable.embeddable; import java.math.BigDecimal; -import javax.persistence.Column; -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.PrimaryKeyJoinColumn; -import javax.persistence.SecondaryTable; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.PrimaryKeyJoinColumn; +import jakarta.persistence.SecondaryTable; +import jakarta.persistence.Table; @Entity @Table(name = "meal") diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/projections/Product.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/projections/Product.java index 90f90be0c0..b9cb0076ab 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/projections/Product.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/projections/Product.java @@ -2,10 +2,8 @@ package com.baeldung.jpa.projections; import java.math.BigDecimal; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; @Entity public class Product { diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/projections/ProductRepository.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/projections/ProductRepository.java index bb269e1de6..402e5325ef 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/projections/ProductRepository.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/projections/ProductRepository.java @@ -2,14 +2,14 @@ package com.baeldung.jpa.projections; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import javax.persistence.Query; -import javax.persistence.Tuple; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; +import jakarta.persistence.Query; +import jakarta.persistence.Tuple; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; public class ProductRepository { private EntityManager entityManager; diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/queryparams/Employee.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/queryparams/Employee.java index bf3d459530..ed8788cad6 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/queryparams/Employee.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/queryparams/Employee.java @@ -1,11 +1,11 @@ package com.baeldung.jpa.queryparams; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "employees") diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/querytypes/QueryTypesExamples.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/querytypes/QueryTypesExamples.java index 523fc348f9..9738e0923b 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/querytypes/QueryTypesExamples.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/querytypes/QueryTypesExamples.java @@ -3,14 +3,14 @@ package com.baeldung.jpa.querytypes; import java.util.HashMap; import java.util.Map; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import javax.persistence.Query; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; +import jakarta.persistence.Query; +import jakarta.persistence.TypedQuery; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; /** * JPA Query Types examples. All using the UserEntity class. diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/querytypes/UserEntity.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/querytypes/UserEntity.java index 1d4a231b31..14ccc15a9c 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/querytypes/UserEntity.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/querytypes/UserEntity.java @@ -1,9 +1,9 @@ package com.baeldung.jpa.querytypes; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.NamedQuery; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.NamedQuery; +import jakarta.persistence.Table; /** * User entity class. Used as an asset for JPA Query Types examples. diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/text/Exam.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/text/Exam.java index 8bea8e0121..a674069a63 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/text/Exam.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/text/Exam.java @@ -1,6 +1,6 @@ package com.baeldung.jpa.text; -import javax.persistence.*; +import jakarta.persistence.*; @Entity public class Exam { diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/text/ExamRepository.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/text/ExamRepository.java index 2ee502bf4c..7b783be365 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/text/ExamRepository.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/text/ExamRepository.java @@ -1,8 +1,8 @@ package com.baeldung.jpa.text; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; public class ExamRepository { diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Cocktail.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Cocktail.java index 96310c1cc5..e896efe0ec 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Cocktail.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Cocktail.java @@ -1,11 +1,9 @@ package com.baeldung.jpa.unrelated.entities; -import org.hibernate.annotations.Fetch; -import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.NotFound; import org.hibernate.annotations.NotFoundAction; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.List; import java.util.Objects; @@ -27,18 +25,17 @@ public class Cocktail { @JoinColumn(name = "cocktail_name", referencedColumnName = "cocktail", insertable = false, updatable = false, - foreignKey = @javax.persistence + foreignKey = @jakarta.persistence .ForeignKey(value = ConstraintMode.NO_CONSTRAINT)) private Recipe recipe; @OneToMany(fetch = FetchType.LAZY) - @NotFound(action = NotFoundAction.IGNORE) @JoinColumn( name = "cocktail", referencedColumnName = "cocktail_name", insertable = false, updatable = false, - foreignKey = @javax.persistence + foreignKey = @jakarta.persistence .ForeignKey(value = ConstraintMode.NO_CONSTRAINT)) private List recipeList; diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/MultipleRecipe.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/MultipleRecipe.java index 8664d6fd7f..b17860f755 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/MultipleRecipe.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/MultipleRecipe.java @@ -1,9 +1,9 @@ package com.baeldung.jpa.unrelated.entities; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import java.util.Objects; @Entity diff --git a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Recipe.java b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Recipe.java index 4b3d200b60..2cb4839b33 100644 --- a/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Recipe.java +++ b/persistence-modules/java-jpa-2/src/main/java/com/baeldung/jpa/unrelated/entities/Recipe.java @@ -1,9 +1,9 @@ package com.baeldung.jpa.unrelated.entities; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import java.util.Objects; @Entity diff --git a/persistence-modules/java-jpa-2/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa-2/src/main/resources/META-INF/persistence.xml index 3bc81910d9..15d5799c0a 100644 --- a/persistence-modules/java-jpa-2/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa-2/src/main/resources/META-INF/persistence.xml @@ -1,9 +1,8 @@ - + @@ -11,20 +10,15 @@ com.baeldung.jpa.queryparams.Employee true - - - - - + + + + + - - + + @@ -34,18 +28,14 @@ com.baeldung.jpa.text.Exam true - - - - - + + + + + - + @@ -54,18 +44,14 @@ com.baeldung.jpa.defaultvalues.User true - - - - - + + + + + - + @@ -74,20 +60,15 @@ com.baeldung.jpa.querytypes.UserEntity true - - - - - + + + + + - - + + @@ -96,20 +77,15 @@ com.baeldung.jpa.projections.Product true - - - - - + + + + + - - + + @@ -118,20 +94,15 @@ com.baeldung.jpa.criteria.Item true - - - - - + + + + + - - + + @@ -147,19 +118,15 @@ true - - - - - + + + + + - + @@ -170,18 +137,14 @@ com.baeldung.jpa.unrelated.entities.MultipleRecipe true - - - - - + + + + + - + @@ -194,14 +157,11 @@ com.baeldung.jpa.generateidvalue.User true - - - - - + + + + + diff --git a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/defaultvalues/UserDefaultValuesUnitTest.java b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/defaultvalues/UserDefaultValuesUnitTest.java index dc41ff51f2..b9c3dffecd 100644 --- a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/defaultvalues/UserDefaultValuesUnitTest.java +++ b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/defaultvalues/UserDefaultValuesUnitTest.java @@ -1,8 +1,5 @@ package com.baeldung.jpa.defaultvalues; -import com.baeldung.jpa.defaultvalues.User; -import com.baeldung.jpa.defaultvalues.UserRepository; - import org.junit.Test; import org.junit.Ignore; import org.junit.AfterClass; diff --git a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/generateidvalue/PrimaryKeyUnitTest.java b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/generateidvalue/PrimaryKeyUnitTest.java index eead56dbff..8691cbca4a 100644 --- a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/generateidvalue/PrimaryKeyUnitTest.java +++ b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/generateidvalue/PrimaryKeyUnitTest.java @@ -1,8 +1,8 @@ package com.baeldung.jpa.generateidvalue; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; import org.junit.Assert; import org.junit.BeforeClass; @@ -27,12 +27,10 @@ public class PrimaryKeyUnitTest { User user = new User(); user.setName("TestName"); - entityManager.getTransaction() - .begin(); + entityManager.getTransaction().begin(); entityManager.persist(user); Assert.assertNull(user.getId()); - entityManager.getTransaction() - .commit(); + entityManager.getTransaction().commit(); Long expectPrimaryKey = 1L; Assert.assertEquals(expectPrimaryKey, user.getId()); diff --git a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/multipletables/MultipleTablesIntegrationTest.java b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/multipletables/MultipleTablesIntegrationTest.java index 99b2cd69ee..a2aedbc5bf 100644 --- a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/multipletables/MultipleTablesIntegrationTest.java +++ b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/multipletables/MultipleTablesIntegrationTest.java @@ -2,9 +2,9 @@ package com.baeldung.jpa.multipletables; import static org.assertj.core.api.Assertions.*; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; import org.junit.AfterClass; import org.junit.BeforeClass; diff --git a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/projections/HibernateProjectionsIntegrationTest.java b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/projections/HibernateProjectionsIntegrationTest.java index 47cc7cbaec..b78802bb42 100644 --- a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/projections/HibernateProjectionsIntegrationTest.java +++ b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/projections/HibernateProjectionsIntegrationTest.java @@ -5,19 +5,22 @@ import static org.junit.Assert.assertNotNull; import java.util.List; -import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Configuration; -import org.hibernate.criterion.Order; -import org.hibernate.criterion.Projections; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Path; +import jakarta.persistence.criteria.Root; +import jakarta.persistence.metamodel.SingularAttribute; + public class HibernateProjectionsIntegrationTest { private static Session session; private static SessionFactory sessionFactory; @@ -56,16 +59,20 @@ public class HibernateProjectionsIntegrationTest { cfg.setProperty(AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "thread"); return cfg; } - - + + @SuppressWarnings("deprecation") @Test public void givenProductData_whenIdAndNameProjectionUsingCriteria_thenListOfObjectArrayReturned() { - Criteria criteria = session.createCriteria(Product.class); - criteria = criteria.setProjection(Projections.projectionList() - .add(Projections.id()) - .add(Projections.property("name"))); - List resultList = criteria.list(); + final CriteriaBuilder criteria = session.getCriteriaBuilder(); + final CriteriaQuery criteriaQuery = criteria.createQuery(Object[].class); + final Root root = criteriaQuery.from(Product.class); + final SingularAttribute name = Product_.name; + final SingularAttribute id = Product_.id; + final Path nameProjection = root.get(name); + final Path idProjection = root.get(id); + criteriaQuery.multiselect(idProjection, nameProjection); + final List resultList = session.createQuery(criteriaQuery).getResultList(); assertNotNull(resultList); assertEquals(4, resultList.size()); @@ -82,9 +89,13 @@ public class HibernateProjectionsIntegrationTest { @Test public void givenProductData_whenNameProjectionUsingCriteria_thenListOfStringReturned() { - Criteria criteria = session.createCriteria(Product.class); - criteria = criteria.setProjection(Projections.property("name")); - List resultList = criteria.list(); + final CriteriaBuilder criteria = session.getCriteriaBuilder(); + final CriteriaQuery criteriaQuery = criteria.createQuery(String.class); + final Root root = criteriaQuery.from(Product.class); + final SingularAttribute name = Product_.name; + final Path nameProjection = root.get(name); + criteriaQuery.select(nameProjection); + final List resultList = session.createQuery(criteriaQuery).getResultList(); assertNotNull(resultList); assertEquals(4, resultList.size()); @@ -96,11 +107,12 @@ public class HibernateProjectionsIntegrationTest { @Test public void givenProductData_whenCountByCategoryUsingCriteria_thenOK() { - Criteria criteria = session.createCriteria(Product.class); - criteria = criteria.setProjection(Projections.projectionList() - .add(Projections.groupProperty("category")) - .add(Projections.rowCount())); - List resultList = criteria.list(); + final CriteriaBuilder criteria = session.getCriteriaBuilder(); + final CriteriaQuery criteriaQuery = criteria.createQuery(Object[].class); + final Root root = criteriaQuery.from(Product.class); + criteriaQuery.groupBy(root.get("category")); + criteriaQuery.multiselect(root.get("category"), criteria.count(root)); + final List resultList = session.createQuery(criteriaQuery).getResultList(); assertNotNull(resultList); assertEquals(3, resultList.size()); @@ -114,12 +126,13 @@ public class HibernateProjectionsIntegrationTest { @Test public void givenProductData_whenCountByCategoryWithAliasUsingCriteria_thenOK() { - Criteria criteria = session.createCriteria(Product.class); - criteria = criteria.setProjection(Projections.projectionList() - .add(Projections.groupProperty("category")) - .add(Projections.alias(Projections.rowCount(), "count"))); - criteria.addOrder(Order.asc("count")); - List resultList = criteria.list(); + final CriteriaBuilder criteria = session.getCriteriaBuilder(); + final CriteriaQuery criteriaQuery = criteria.createQuery(Object[].class); + final Root root = criteriaQuery.from(Product.class); + criteriaQuery.groupBy(root.get("category")); + criteriaQuery.multiselect(root.get("category"), criteria.count(root)); + criteriaQuery.orderBy(criteria.asc(criteria.count(root))); + List resultList = session.createQuery(criteriaQuery).getResultList(); assertNotNull(resultList); assertEquals(3, resultList.size()); diff --git a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/queryparams/JPAQueryParamsUnitTest.java b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/queryparams/JPAQueryParamsUnitTest.java index 55ee0e6e59..ed047cb45e 100644 --- a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/queryparams/JPAQueryParamsUnitTest.java +++ b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/queryparams/JPAQueryParamsUnitTest.java @@ -3,14 +3,14 @@ package com.baeldung.jpa.queryparams; import java.util.Arrays; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.ParameterExpression; -import javax.persistence.criteria.Root; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; +import jakarta.persistence.TypedQuery; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.ParameterExpression; +import jakarta.persistence.criteria.Root; import org.junit.Assert; import org.junit.BeforeClass; diff --git a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/text/JPATextUnitTest.java b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/text/JPATextUnitTest.java index f9f355c464..f7fcd9117d 100644 --- a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/text/JPATextUnitTest.java +++ b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/text/JPATextUnitTest.java @@ -2,7 +2,7 @@ package com.baeldung.jpa.text; import static org.junit.Assert.assertEquals; -import javax.persistence.PersistenceException; +import jakarta.persistence.PersistenceException; import org.junit.BeforeClass; import org.junit.Test; diff --git a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/unrelated/entities/UnrelatedEntitiesUnitTest.java b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/unrelated/entities/UnrelatedEntitiesUnitTest.java index 044e59b16e..0fae147b13 100644 --- a/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/unrelated/entities/UnrelatedEntitiesUnitTest.java +++ b/persistence-modules/java-jpa-2/src/test/java/com/baeldung/jpa/unrelated/entities/UnrelatedEntitiesUnitTest.java @@ -1,14 +1,15 @@ package com.baeldung.jpa.unrelated.entities; -import javax.persistence.*; +import jakarta.persistence.*; -import com.querydsl.jpa.impl.JPAQuery; import org.junit.jupiter.api.*; +import static org.junit.jupiter.api.Assertions.*; + import java.util.List; import java.util.function.Consumer; -import static org.junit.jupiter.api.Assertions.*; +import com.querydsl.jpa.impl.JPAQuery; public class UnrelatedEntitiesUnitTest { private static EntityManagerFactory entityManagerFactory; diff --git a/persistence-modules/java-jpa-2/src/test/resources/META-INF/persistence.xml b/persistence-modules/java-jpa-2/src/test/resources/META-INF/persistence.xml index 00c7274dd4..46ee62b1ca 100644 --- a/persistence-modules/java-jpa-2/src/test/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa-2/src/test/resources/META-INF/persistence.xml @@ -1,9 +1,8 @@ - + @@ -11,20 +10,15 @@ com.baeldung.jpa.queryparams.Employee true - - - - - + + + + + - - + + @@ -34,18 +28,14 @@ com.baeldung.jpa.text.Exam true - - - - - + + + + + - + @@ -54,18 +44,14 @@ com.baeldung.jpa.defaultvalues.User true - - - - - + + + + + - + @@ -74,20 +60,15 @@ com.baeldung.jpa.querytypes.UserEntity true - - - - - + + + + + - - + + @@ -96,20 +77,15 @@ com.baeldung.jpa.projections.Product true - - - - - + + + + + - - + + @@ -118,20 +94,15 @@ com.baeldung.jpa.criteria.Item true - - - - - + + + + + - - + + @@ -147,19 +118,15 @@ true - - - - - + + + + + - + @@ -170,18 +137,14 @@ com.baeldung.jpa.unrelated.entities.MultipleRecipe true - - - - - + + + + + - + @@ -194,14 +157,11 @@ com.baeldung.jpa.generateidvalue.User true - - - - - + + + + + diff --git a/persistence-modules/java-jpa/pom.xml b/persistence-modules/java-jpa/pom.xml index 0c8cec2116..b70fd0daec 100644 --- a/persistence-modules/java-jpa/pom.xml +++ b/persistence-modules/java-jpa/pom.xml @@ -14,32 +14,44 @@ - org.hibernate + org.hibernate.orm hibernate-core ${hibernate.version} + + + jakarta.xml.bind + jakarta.xml.bind-api + + - org.hibernate + org.hibernate.orm hibernate-jpamodelgen ${hibernate.version} + + + jakarta.xml.bind + jakarta.xml.bind-api + + com.h2database h2 ${h2.version} - - - javax.persistence - javax.persistence-api - ${javax.persistence-api.version} - org.eclipse.persistence eclipselink ${eclipselink.version} runtime + + + jakarta.xml.bind + jakarta.xml.bind-api + + org.postgresql @@ -47,6 +59,16 @@ ${postgresql.version} runtime + + jakarta.xml.bind + jakarta.xml.bind-api + ${jakarta.xml.bind-api.version} + + + javax.annotation + javax.annotation-api + ${javax.annotation.version} + @@ -102,12 +124,12 @@ - 5.4.0.Final - 2.7.4 - 2.2 + 4.0.1 3.3.3 3.0.0 2.1.214 + 4.0.0 + 1.3.2 \ No newline at end of file diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/basicannotation/Course.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/basicannotation/Course.java index cc5a83420c..559076a2ad 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/basicannotation/Course.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/basicannotation/Course.java @@ -1,9 +1,9 @@ package com.baeldung.jpa.basicannotation; -import javax.persistence.Basic; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Id; +import jakarta.persistence.Basic; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; @Entity public class Course { diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/convertdates/LocalDateConverter.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/convertdates/LocalDateConverter.java index de6ada2361..f74aad71e6 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/convertdates/LocalDateConverter.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/convertdates/LocalDateConverter.java @@ -1,7 +1,7 @@ package com.baeldung.jpa.convertdates; -import javax.persistence.AttributeConverter; -import javax.persistence.Converter; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; import java.sql.Date; import java.time.LocalDate; import java.util.Optional; diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/datetime/DateTimeEntityRepository.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/datetime/DateTimeEntityRepository.java index 0bd04da221..2aa6fa60b6 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/datetime/DateTimeEntityRepository.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/datetime/DateTimeEntityRepository.java @@ -1,8 +1,8 @@ package com.baeldung.jpa.datetime; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/datetime/JPA22DateTimeEntity.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/datetime/JPA22DateTimeEntity.java index 065385bd86..0a4aade789 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/datetime/JPA22DateTimeEntity.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/datetime/JPA22DateTimeEntity.java @@ -1,6 +1,6 @@ package com.baeldung.jpa.datetime; -import javax.persistence.*; +import jakarta.persistence.*; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java index 64e7ab586c..27293147eb 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java @@ -2,17 +2,17 @@ package com.baeldung.jpa.entity; import java.util.Date; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; -import javax.persistence.Transient; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; +import jakarta.persistence.Transient; @Entity @Table(name="STUDENT") diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/model/Comment.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/model/Comment.java index 40ecd3262b..b7c3a62546 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/model/Comment.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/model/Comment.java @@ -1,6 +1,6 @@ package com.baeldung.jpa.entitygraph.model; -import javax.persistence.*; +import jakarta.persistence.*; @Entity public class Comment { diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/model/Post.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/model/Post.java index 59f17ae0c5..9d340f4b31 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/model/Post.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/model/Post.java @@ -1,6 +1,6 @@ package com.baeldung.jpa.entitygraph.model; -import javax.persistence.*; +import jakarta.persistence.*; import java.io.Serializable; import java.util.ArrayList; import java.util.List; diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/model/User.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/model/User.java index b712100d4e..37fab8d4da 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/model/User.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/model/User.java @@ -1,9 +1,9 @@ package com.baeldung.jpa.entitygraph.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class User { diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/repo/PostRepository.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/repo/PostRepository.java index 28f1e1b93c..16e7badc64 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/repo/PostRepository.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entitygraph/repo/PostRepository.java @@ -2,10 +2,10 @@ package com.baeldung.jpa.entitygraph.repo; import com.baeldung.jpa.entitygraph.model.Post; -import javax.persistence.*; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; +import jakarta.persistence.*; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; import java.util.HashMap; import java.util.Map; @@ -34,7 +34,7 @@ public class PostRepository { EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph"); Map properties = new HashMap<>(); - properties.put("javax.persistence.fetchgraph", entityGraph); + properties.put("jakarta.persistence.fetchgraph", entityGraph); Post post = entityManager.find(Post.class, id, properties); entityManager.close(); @@ -51,7 +51,7 @@ public class PostRepository { .addAttributeNodes("user"); Map properties = new HashMap<>(); - properties.put("javax.persistence.fetchgraph", entityGraph); + properties.put("jakarta.persistence.fetchgraph", entityGraph); Post post = entityManager.find(Post.class, id, properties); entityManager.close(); @@ -64,7 +64,7 @@ public class PostRepository { EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph-with-comment-users"); Post post = entityManager.createQuery("Select p from Post p where p.id=:id", Post.class) .setParameter("id", id) - .setHint("javax.persistence.fetchgraph", entityGraph) + .setHint("jakarta.persistence.fetchgraph", entityGraph) .getSingleResult(); entityManager.close(); @@ -80,7 +80,7 @@ public class PostRepository { Root root = criteriaQuery.from(Post.class); criteriaQuery.where(criteriaBuilder.equal(root.get("id"), id)); TypedQuery typedQuery = entityManager.createQuery(criteriaQuery); - typedQuery.setHint("javax.persistence.loadgraph", entityGraph); + typedQuery.setHint("jakarta.persistence.loadgraph", entityGraph); Post post = typedQuery.getSingleResult(); entityManager.close(); diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/enums/Article.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/enums/Article.java index d534f44e14..a516ae16ff 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/enums/Article.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/enums/Article.java @@ -1,6 +1,6 @@ package com.baeldung.jpa.enums; -import javax.persistence.*; +import jakarta.persistence.*; @Entity public class Article { diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/enums/CategoryConverter.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/enums/CategoryConverter.java index 98960f1569..b69fc51afd 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/enums/CategoryConverter.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/enums/CategoryConverter.java @@ -1,7 +1,7 @@ package com.baeldung.jpa.enums; -import javax.persistence.AttributeConverter; -import javax.persistence.Converter; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; import java.util.stream.Stream; @Converter(autoApply = true) diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/model/Car.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/model/Car.java index 676d76307e..86ad487e11 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/model/Car.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/model/Car.java @@ -1,15 +1,15 @@ package com.baeldung.jpa.model; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedStoredProcedureQueries; -import javax.persistence.NamedStoredProcedureQuery; -import javax.persistence.ParameterMode; -import javax.persistence.StoredProcedureParameter; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.NamedStoredProcedureQueries; +import jakarta.persistence.NamedStoredProcedureQuery; +import jakarta.persistence.ParameterMode; +import jakarta.persistence.StoredProcedureParameter; +import jakarta.persistence.Table; @Entity @Table(name = "CAR") diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/primarykeys/Account.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/primarykeys/Account.java index 915c605e65..d4825a56fc 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/primarykeys/Account.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/primarykeys/Account.java @@ -1,8 +1,8 @@ package com.baeldung.jpa.primarykeys; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.IdClass; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.IdClass; @Entity @IdClass(AccountId.class) diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/primarykeys/Book.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/primarykeys/Book.java index a84eb3ef01..6a2b86d977 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/primarykeys/Book.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/primarykeys/Book.java @@ -1,7 +1,7 @@ package com.baeldung.jpa.primarykeys; -import javax.persistence.EmbeddedId; -import javax.persistence.Entity; +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; @Entity public class Book { diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/primarykeys/BookId.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/primarykeys/BookId.java index d8c925c148..e4c60bd5ba 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/primarykeys/BookId.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/primarykeys/BookId.java @@ -2,7 +2,7 @@ package com.baeldung.jpa.primarykeys; import java.io.Serializable; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; @Embeddable public class BookId implements Serializable { diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/sqlresultsetmapping/Employee.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/sqlresultsetmapping/Employee.java index b62a21d481..f6fed9913c 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/sqlresultsetmapping/Employee.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/sqlresultsetmapping/Employee.java @@ -1,6 +1,6 @@ package com.baeldung.jpa.sqlresultsetmapping; -import javax.persistence.*; +import jakarta.persistence.*; @SqlResultSetMapping( diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/sqlresultsetmapping/ScheduledDay.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/sqlresultsetmapping/ScheduledDay.java index a7ca59ab3f..55a77d6d50 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/sqlresultsetmapping/ScheduledDay.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/sqlresultsetmapping/ScheduledDay.java @@ -1,6 +1,6 @@ package com.baeldung.jpa.sqlresultsetmapping; -import javax.persistence.*; +import jakarta.persistence.*; @SqlResultSetMappings(value = { @SqlResultSetMapping(name = "ScheduleResult", diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/stringcast/Message.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/stringcast/Message.java index fb521cfea6..2888266203 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/stringcast/Message.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/stringcast/Message.java @@ -1,6 +1,6 @@ package com.baeldung.jpa.stringcast; -import javax.persistence.*; +import jakarta.persistence.*; @SqlResultSetMapping(name = "textQueryMapping", classes = { @ConstructorResult(targetClass = Message.class, columns = { diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/stringcast/QueryExecutor.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/stringcast/QueryExecutor.java index 2cb5679d4d..948ac52bce 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/stringcast/QueryExecutor.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/stringcast/QueryExecutor.java @@ -4,8 +4,8 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import javax.persistence.EntityManager; -import javax.persistence.Query; +import jakarta.persistence.EntityManager; +import jakarta.persistence.Query; public class QueryExecutor { diff --git a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml index 50188391af..5d0c79c2a7 100644 --- a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml @@ -1,9 +1,8 @@ - + org.hibernate.jpa.HibernatePersistenceProvider @@ -12,18 +11,14 @@ com.baeldung.jpa.basicannotation.Course true - - - - - + + + + + - + @@ -34,18 +29,14 @@ com.baeldung.jpa.enums.CategoryConverter true - - - - - + + + + + - + @@ -54,39 +45,26 @@ com.baeldung.jpa.model.Car true - - - - - + + + + + - + com.baeldung.jpa.entitygraph.model.Post com.baeldung.jpa.entitygraph.model.User com.baeldung.jpa.entitygraph.model.Comment true - - - - - - + + + + @@ -96,17 +74,11 @@ com.baeldung.jpa.datetime.JPA22DateTimeEntity true - - - - - + + + + + @@ -124,18 +96,14 @@ com.baeldung.jpa.primarykeys.AccountId true - - - - - + + + + + - + diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/basicannotation/BasicAnnotationIntegrationTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/basicannotation/BasicAnnotationIntegrationTest.java index d3f75804de..96e15af16f 100644 --- a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/basicannotation/BasicAnnotationIntegrationTest.java +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/basicannotation/BasicAnnotationIntegrationTest.java @@ -1,9 +1,9 @@ package com.baeldung.jpa.basicannotation; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import javax.persistence.PersistenceException; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; +import jakarta.persistence.PersistenceException; import org.junit.AfterClass; import org.junit.BeforeClass; diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/StudentEntityIntegrationTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/StudentEntityIntegrationTest.java index 3c7a82edc3..caeeb62a98 100644 --- a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/StudentEntityIntegrationTest.java +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/StudentEntityIntegrationTest.java @@ -7,10 +7,10 @@ import java.time.ZoneId; import java.util.Date; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import javax.persistence.TypedQuery; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; +import jakarta.persistence.TypedQuery; import org.junit.After; import org.junit.Before; diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/enums/ArticleUnitTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/enums/ArticleUnitTest.java index 36a7cb1002..78d3588cc8 100644 --- a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/enums/ArticleUnitTest.java +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/enums/ArticleUnitTest.java @@ -3,11 +3,11 @@ package com.baeldung.jpa.enums; import org.junit.BeforeClass; import org.junit.Test; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.Persistence; -import javax.persistence.TypedQuery; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityTransaction; +import jakarta.persistence.Persistence; +import jakarta.persistence.TypedQuery; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/primarykeys/CompositeKeysIntegrationTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/primarykeys/CompositeKeysIntegrationTest.java index be529ab81c..45037387d6 100644 --- a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/primarykeys/CompositeKeysIntegrationTest.java +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/primarykeys/CompositeKeysIntegrationTest.java @@ -3,9 +3,9 @@ package com.baeldung.jpa.primarykeys; import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; import com.baeldung.jpa.primarykeys.Account; import com.baeldung.jpa.primarykeys.AccountId; diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/sqlresultsetmapping/SqlResultSetMappingUnitTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/sqlresultsetmapping/SqlResultSetMappingUnitTest.java index f318df3747..f61ed16177 100644 --- a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/sqlresultsetmapping/SqlResultSetMappingUnitTest.java +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/sqlresultsetmapping/SqlResultSetMappingUnitTest.java @@ -4,10 +4,10 @@ import static org.junit.Assert.*; import org.junit.jupiter.api.*; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import javax.persistence.Query; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; +import jakarta.persistence.Query; import java.util.Collections; import java.util.List; @@ -44,7 +44,7 @@ public class SqlResultSetMappingUnitTest { @Test public void whenNamedQuery_thenMultipleEntityResult() { - final Query query = em.createNativeQuery("SELECT e.id, e.name, d.id, d.employeeId, d.dayOfWeek " + final Query query = em.createNativeQuery("SELECT e.id as idEmployee, e.name, d.id as daysId, d.employeeId, d.dayOfWeek " + " FROM employee e, schedule_days d " + " WHERE e.id = d.employeeId", "EmployeeScheduleResults"); List results = query.getResultList(); diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureLiveTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureLiveTest.java index 8bc8c854da..f1c61ee408 100644 --- a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureLiveTest.java +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureLiveTest.java @@ -1,11 +1,11 @@ package com.baeldung.jpa.storedprocedure; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.ParameterMode; -import javax.persistence.Persistence; -import javax.persistence.StoredProcedureQuery; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityTransaction; +import jakarta.persistence.ParameterMode; +import jakarta.persistence.Persistence; +import jakarta.persistence.StoredProcedureQuery; import org.junit.AfterClass; import org.junit.Assert; diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/stringcast/SpringCastUnitTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/stringcast/SpringCastUnitTest.java index 0a11725fc3..52789c7783 100644 --- a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/stringcast/SpringCastUnitTest.java +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/stringcast/SpringCastUnitTest.java @@ -3,7 +3,7 @@ package com.baeldung.jpa.stringcast; import org.junit.BeforeClass; import org.junit.Test; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.List; import static org.junit.Assert.assertEquals; diff --git a/persistence-modules/java-jpa/src/test/resources/persistence.xml b/persistence-modules/java-jpa/src/test/resources/persistence.xml index e9b5ebbbcf..c9bec9557f 100644 --- a/persistence-modules/java-jpa/src/test/resources/persistence.xml +++ b/persistence-modules/java-jpa/src/test/resources/persistence.xml @@ -1,18 +1,17 @@ - + org.hibernate.jpa.HibernatePersistenceProvider com.baeldung.jpa.model.Car - - - - + + + + @@ -22,10 +21,10 @@ org.hibernate.jpa.HibernatePersistenceProvider com.baeldung.jpa.stringcast.Message - - - - + + + + diff --git a/persistence-modules/jnosql/jnosql-artemis/pom.xml b/persistence-modules/jnosql/jnosql-artemis/pom.xml index 0c1a6967d3..da100388ab 100644 --- a/persistence-modules/jnosql/jnosql-artemis/pom.xml +++ b/persistence-modules/jnosql/jnosql-artemis/pom.xml @@ -40,6 +40,16 @@ ${project.artifactId} + + org.apache.maven.plugins + maven-war-plugin + ${maven.war-plugin.version} + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler-plugin.version} + net.wasdev.wlp.maven.plugins liberty-maven-plugin @@ -80,7 +90,9 @@ 2.4.2 false - 8.0 + 8.0.1 + 3.3.1 + 3.8.1 \ No newline at end of file diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index d7ff51b487..0881425a71 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -21,7 +21,6 @@ blaze-persistence core-java-persistence core-java-persistence-2 - deltaspike elasticsearch flyway flyway-repair @@ -29,7 +28,6 @@ hibernate5 hibernate-mapping hibernate-mapping-2 - hibernate-ogm hibernate-annotations hibernate-exceptions hibernate-libraries @@ -37,11 +35,10 @@ hibernate-queries hibernate-enterprise influxdb - java-cassandra java-cockroachdb java-jdbi java-jpa - java-jpa-2 + java-jpa-2 java-jpa-3 @@ -71,7 +68,7 @@ spring-data-arangodb spring-data-cassandra spring-data-cassandra-test - spring-data-cassandra-reactive + spring-data-cosmosdb spring-data-couchbase-2 spring-data-dynamodb @@ -93,32 +90,37 @@ spring-data-jpa-repo-2 spring-data-jdbc spring-data-keyvalue - spring-data-mongodb + spring-data-mongodb-2 spring-data-mongodb-reactive - spring-data-neo4j + spring-data-redis spring-data-rest-2 spring-data-rest-querydsl spring-data-solr - spring-hibernate-3 - spring-hibernate-5 - spring-jpa - spring-jpa-2 + + + spring-jdbc spring-jooq spring-mybatis spring-persistence-simple + + fauna + spring-data-rest + java-mongodb + questdb - 5.2.17.Final - 42.2.20 - 2.3.4 + 6.2.0.Final + 42.5.4 + 2.7.1 1.16.3 - \ No newline at end of file + diff --git a/persistence-modules/querydsl/pom.xml b/persistence-modules/querydsl/pom.xml index c97dcdd93d..921d45815a 100644 --- a/persistence-modules/querydsl/pom.xml +++ b/persistence-modules/querydsl/pom.xml @@ -19,11 +19,13 @@ com.querydsl querydsl-jpa + jakarta ${querydsl.version} com.querydsl querydsl-apt + jakarta ${querydsl.version} provided @@ -34,12 +36,6 @@ ${hibernate.version} compile - - org.hibernate.javax.persistence - hibernate-jpa-2.1-api - ${hibernate-jpa.version} - compile - commons-dbcp commons-dbcp @@ -106,8 +102,6 @@ maven-compiler-plugin ${maven-compiler-plugin.version} - ${java.version} - ${java.version} -proc:none @@ -132,10 +126,8 @@ - 4.3.4.RELEASE - 5.2.5.Final - 1.0.0.Final - 4.1.4 + 6.0.6 + 5.0.0 1.6 1.4 1.1.3 diff --git a/persistence-modules/querydsl/src/main/java/com/baeldung/dao/PersonDaoImpl.java b/persistence-modules/querydsl/src/main/java/com/baeldung/dao/PersonDaoImpl.java index 20ebe0e3fe..8d91ec0f59 100644 --- a/persistence-modules/querydsl/src/main/java/com/baeldung/dao/PersonDaoImpl.java +++ b/persistence-modules/querydsl/src/main/java/com/baeldung/dao/PersonDaoImpl.java @@ -3,14 +3,18 @@ package com.baeldung.dao; import com.baeldung.entity.Person; import com.baeldung.entity.QPerson; import com.querydsl.core.group.GroupBy; +import com.querydsl.jpa.JPQLTemplates; import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.impl.JPAQueryFactory; + import org.springframework.stereotype.Repository; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; import java.util.List; import java.util.Map; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; + @Repository public class PersonDaoImpl implements PersonDao { @@ -57,7 +61,7 @@ public class PersonDaoImpl implements PersonDao { @Override public Map findMaxAgeByName() { - final JPAQuery query = new JPAQuery<>(em); + final JPAQueryFactory query = new JPAQueryFactory(JPQLTemplates.DEFAULT, em); final QPerson person = QPerson.person; return query.from(person).transform(GroupBy.groupBy(person.firstname).as(GroupBy.max(person.age))); diff --git a/persistence-modules/querydsl/src/main/java/com/baeldung/entity/Person.java b/persistence-modules/querydsl/src/main/java/com/baeldung/entity/Person.java index 310f21ab2a..8985215fcd 100644 --- a/persistence-modules/querydsl/src/main/java/com/baeldung/entity/Person.java +++ b/persistence-modules/querydsl/src/main/java/com/baeldung/entity/Person.java @@ -1,10 +1,10 @@ package com.baeldung.entity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Person { diff --git a/persistence-modules/querydsl/src/main/java/com/baeldung/querydsl/intro/entities/BlogPost.java b/persistence-modules/querydsl/src/main/java/com/baeldung/querydsl/intro/entities/BlogPost.java index 6712ad08d5..43ba594bdd 100644 --- a/persistence-modules/querydsl/src/main/java/com/baeldung/querydsl/intro/entities/BlogPost.java +++ b/persistence-modules/querydsl/src/main/java/com/baeldung/querydsl/intro/entities/BlogPost.java @@ -3,10 +3,10 @@ */ package com.baeldung.querydsl.intro.entities; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.ManyToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; @Entity public class BlogPost { diff --git a/persistence-modules/querydsl/src/main/java/com/baeldung/querydsl/intro/entities/User.java b/persistence-modules/querydsl/src/main/java/com/baeldung/querydsl/intro/entities/User.java index 4111284d5a..1d572eb389 100644 --- a/persistence-modules/querydsl/src/main/java/com/baeldung/querydsl/intro/entities/User.java +++ b/persistence-modules/querydsl/src/main/java/com/baeldung/querydsl/intro/entities/User.java @@ -5,7 +5,7 @@ package com.baeldung.querydsl.intro.entities; import java.util.HashSet; import java.util.Set; -import javax.persistence.*; +import jakarta.persistence.*; @Entity public class User { diff --git a/persistence-modules/querydsl/src/main/resources/META-INF/persistence.xml b/persistence-modules/querydsl/src/main/resources/META-INF/persistence.xml index 4b51cb444b..078fa8ce23 100644 --- a/persistence-modules/querydsl/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/querydsl/src/main/resources/META-INF/persistence.xml @@ -1,9 +1,8 @@ - + version="3.0" + xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"> diff --git a/persistence-modules/querydsl/src/test/java/com/baeldung/dao/PersonDaoIntegrationTest.java b/persistence-modules/querydsl/src/test/java/com/baeldung/dao/PersonDaoIntegrationTest.java index cf4e9ab872..e9cf679c43 100644 --- a/persistence-modules/querydsl/src/test/java/com/baeldung/dao/PersonDaoIntegrationTest.java +++ b/persistence-modules/querydsl/src/test/java/com/baeldung/dao/PersonDaoIntegrationTest.java @@ -6,9 +6,9 @@ import com.baeldung.entity.Person; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.Rollback; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.transaction.TransactionConfiguration; import org.springframework.transaction.annotation.Transactional; import junit.framework.Assert; @@ -16,7 +16,7 @@ import junit.framework.Assert; @ContextConfiguration("/test-context.xml") @RunWith(SpringJUnit4ClassRunner.class) @Transactional -@TransactionConfiguration(defaultRollback = true) +@Rollback public class PersonDaoIntegrationTest { @Autowired diff --git a/persistence-modules/querydsl/src/test/java/com/baeldung/querydsl/intro/QueryDSLIntegrationTest.java b/persistence-modules/querydsl/src/test/java/com/baeldung/querydsl/intro/QueryDSLIntegrationTest.java index 7ae97c2880..29d49d114d 100644 --- a/persistence-modules/querydsl/src/test/java/com/baeldung/querydsl/intro/QueryDSLIntegrationTest.java +++ b/persistence-modules/querydsl/src/test/java/com/baeldung/querydsl/intro/QueryDSLIntegrationTest.java @@ -14,9 +14,9 @@ import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQueryFactory; import org.junit.*; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; import java.util.List; import static org.junit.Assert.*; diff --git a/persistence-modules/questdb/README.md b/persistence-modules/questdb/README.md index cf4c7cbbbc..cd5d11f7da 100644 --- a/persistence-modules/questdb/README.md +++ b/persistence-modules/questdb/README.md @@ -1,2 +1,2 @@ ### Relevant Articles: -- [Introduction to QuestDB](#) +- [Introduction to QuestDB](https://www.baeldung.com/java-questdb) diff --git a/persistence-modules/r2dbc/README.md b/persistence-modules/r2dbc/README.md index 02d3cbf5fc..ceb7982cd4 100644 --- a/persistence-modules/r2dbc/README.md +++ b/persistence-modules/r2dbc/README.md @@ -1,3 +1,3 @@ ### Relevant Articles: - [R2DBC – Reactive Relational Database Connectivity](https://www.baeldung.com/r2dbc) - +- [Spring R2DBC Migrations Using Flyway](https://www.baeldung.com/spring-r2dbc-flyway) diff --git a/persistence-modules/r2dbc/pom.xml b/persistence-modules/r2dbc/pom.xml index cfe344eba9..5260bb9860 100644 --- a/persistence-modules/r2dbc/pom.xml +++ b/persistence-modules/r2dbc/pom.xml @@ -89,9 +89,9 @@ - 9.14.1 - 42.5.2 - 1.0.0.RELEASE + 9.16.0 + 42.5.4 + 1.0.1.RELEASE diff --git a/persistence-modules/r2dbc/src/main/java/com/baeldung/examples/r2dbc/DatasourceConfig.java b/persistence-modules/r2dbc/src/main/java/com/baeldung/examples/r2dbc/DatasourceConfig.java index 21cc0bc6d3..29e7df4c29 100644 --- a/persistence-modules/r2dbc/src/main/java/com/baeldung/examples/r2dbc/DatasourceConfig.java +++ b/persistence-modules/r2dbc/src/main/java/com/baeldung/examples/r2dbc/DatasourceConfig.java @@ -29,9 +29,8 @@ public class DatasourceConfig { if ( !StringUtil.isNullOrEmpty(properties.getPassword())) { ob = ob.option(PASSWORD, properties.getPassword()); } - - ConnectionFactory cf = ConnectionFactories.get(ob.build()); - return cf; + + return ConnectionFactories.get(ob.build()); } diff --git a/persistence-modules/r2dbc/src/main/resources/application.yml b/persistence-modules/r2dbc/src/main/resources/application.yml index 919a088209..d89fffaa31 100644 --- a/persistence-modules/r2dbc/src/main/resources/application.yml +++ b/persistence-modules/r2dbc/src/main/resources/application.yml @@ -9,6 +9,8 @@ spring: flyway: url: jdbc:postgresql://localhost:8082/flyway-test-db locations: classpath:db/postgres/migration + main: + allow-bean-definition-overriding: true # R2DBC URL r2dbc: url: r2dbc:h2:mem://./testdb diff --git a/persistence-modules/r2dbc/src/test/java/com/baeldung/examples/r2dbc/R2dbcExampleApplicationIntegrationTest.java b/persistence-modules/r2dbc/src/test/java/com/baeldung/examples/r2dbc/R2dbcExampleApplicationIntegrationTest.java index 7c3badc976..80c319cc65 100644 --- a/persistence-modules/r2dbc/src/test/java/com/baeldung/examples/r2dbc/R2dbcExampleApplicationIntegrationTest.java +++ b/persistence-modules/r2dbc/src/test/java/com/baeldung/examples/r2dbc/R2dbcExampleApplicationIntegrationTest.java @@ -55,9 +55,7 @@ public class R2dbcExampleApplicationIntegrationTest { .expectStatus() .isOk() .expectBody(Account.class) - .value((acc) -> { - assertThat(acc.getId(),is(1l)); - }); + .value((acc) -> assertThat(acc.getId(),is(1L))); } @Test @@ -71,9 +69,7 @@ public class R2dbcExampleApplicationIntegrationTest { .expectStatus() .isOk() .expectBody(List.class) - .value((accounts) -> { - assertThat(accounts.size(),not(is(0))); - }); + .value((accounts) -> assertThat(accounts.size(),not(is(0)))); } @@ -89,9 +85,7 @@ public class R2dbcExampleApplicationIntegrationTest { .expectStatus() .is2xxSuccessful() .expectBody(Account.class) - .value((acc) -> { - assertThat(acc.getId(),is(notNullValue())); - }); + .value((acc) -> assertThat(acc.getId(),is(notNullValue()))); } diff --git a/persistence-modules/r2dbc/src/test/resources/application.yml b/persistence-modules/r2dbc/src/test/resources/application.yml index 0903bed6fb..f99f02c9c1 100644 --- a/persistence-modules/r2dbc/src/test/resources/application.yml +++ b/persistence-modules/r2dbc/src/test/resources/application.yml @@ -1,6 +1,8 @@ # R2DBC Test configuration r2dbc: url: r2dbc:h2:mem://./testdb + user: local + password: local server: port: 8080 @@ -24,6 +26,7 @@ spring: user: local password: local locations: classpath:db/h2/migration - + main: + allow-bean-definition-overriding: true diff --git a/persistence-modules/redis/pom.xml b/persistence-modules/redis/pom.xml index d1cb927c20..571487af3d 100644 --- a/persistence-modules/redis/pom.xml +++ b/persistence-modules/redis/pom.xml @@ -56,9 +56,9 @@ 0.6 - 3.13.1 - 3.3.0 - 4.1.50.Final + 3.20.0 + 4.3.2 + 4.1.90.Final \ No newline at end of file diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/client/RedisClient.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/client/RedisClient.java index 72ff42ff74..abc095bcdf 100644 --- a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/client/RedisClient.java +++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/client/RedisClient.java @@ -102,18 +102,18 @@ public class RedisClient { return 0L; } - public Set zrange(final String key, final long start, final long stop) { + public List zrange(final String key, final long start, final long stop) { try (Jedis jedis = jedisPool.getResource()) { return jedis.zrange(key, start, stop); } catch (Exception ex) { log.error("Exception caught in zrange", ex); } - return new HashSet(); + return new ArrayList<>(); } public String mset(final HashMap keysValues) { try (Jedis jedis = jedisPool.getResource()) { - ArrayList keysValuesArrayList = new ArrayList(); + ArrayList keysValuesArrayList = new ArrayList<>(); keysValues.forEach((key, value) -> { keysValuesArrayList.add(key); keysValuesArrayList.add(value); diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/iterator/RedisIterator.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/iterator/RedisIterator.java index 5fbd798ac2..fd57e75f6f 100644 --- a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/iterator/RedisIterator.java +++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/iterator/RedisIterator.java @@ -5,8 +5,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; -import redis.clients.jedis.ScanParams; -import redis.clients.jedis.ScanResult; +import redis.clients.jedis.params.ScanParams; +import redis.clients.jedis.resps.ScanResult; import java.util.Iterator; import java.util.LinkedList; diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/ScanStrategy.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/ScanStrategy.java index 39d9e44a63..5ebfd7c135 100644 --- a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/ScanStrategy.java +++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/ScanStrategy.java @@ -1,8 +1,8 @@ package com.baeldung.redis_scan.strategy; import redis.clients.jedis.Jedis; -import redis.clients.jedis.ScanParams; -import redis.clients.jedis.ScanResult; +import redis.clients.jedis.params.ScanParams; +import redis.clients.jedis.resps.ScanResult; public interface ScanStrategy { ScanResult scan(Jedis jedis, String cursor, ScanParams scanParams); diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Hscan.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Hscan.java index fd5ecd14ec..2873229302 100644 --- a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Hscan.java +++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Hscan.java @@ -2,8 +2,8 @@ package com.baeldung.redis_scan.strategy.impl; import com.baeldung.redis_scan.strategy.ScanStrategy; import redis.clients.jedis.Jedis; -import redis.clients.jedis.ScanParams; -import redis.clients.jedis.ScanResult; +import redis.clients.jedis.params.ScanParams; +import redis.clients.jedis.resps.ScanResult; import java.util.Map; import java.util.Map.Entry; diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Scan.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Scan.java index f28b56e34c..c3cf94ff12 100644 --- a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Scan.java +++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Scan.java @@ -2,8 +2,8 @@ package com.baeldung.redis_scan.strategy.impl; import com.baeldung.redis_scan.strategy.ScanStrategy; import redis.clients.jedis.Jedis; -import redis.clients.jedis.ScanParams; -import redis.clients.jedis.ScanResult; +import redis.clients.jedis.params.ScanParams; +import redis.clients.jedis.resps.ScanResult; public class Scan implements ScanStrategy { diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Sscan.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Sscan.java index ed47f7087e..aa5e58bf67 100644 --- a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Sscan.java +++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Sscan.java @@ -2,8 +2,8 @@ package com.baeldung.redis_scan.strategy.impl; import com.baeldung.redis_scan.strategy.ScanStrategy; import redis.clients.jedis.Jedis; -import redis.clients.jedis.ScanParams; -import redis.clients.jedis.ScanResult; +import redis.clients.jedis.params.ScanParams; +import redis.clients.jedis.resps.ScanResult; public class Sscan implements ScanStrategy { diff --git a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Zscan.java b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Zscan.java index bdffc15883..a540e69f17 100644 --- a/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Zscan.java +++ b/persistence-modules/redis/src/main/java/com/baeldung/redis_scan/strategy/impl/Zscan.java @@ -2,9 +2,9 @@ package com.baeldung.redis_scan.strategy.impl; import com.baeldung.redis_scan.strategy.ScanStrategy; import redis.clients.jedis.Jedis; -import redis.clients.jedis.ScanParams; -import redis.clients.jedis.ScanResult; -import redis.clients.jedis.Tuple; +import redis.clients.jedis.params.ScanParams; +import redis.clients.jedis.resps.ScanResult; +import redis.clients.jedis.resps.Tuple; public class Zscan implements ScanStrategy { diff --git a/persistence-modules/redis/src/test/java/com/baeldung/JedisIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/JedisIntegrationTest.java index 50d28af3d1..664ed1d0c3 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/JedisIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/JedisIntegrationTest.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.net.ServerSocket; import java.time.Duration; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; @@ -35,7 +36,10 @@ public class JedisIntegrationTest { port = s.getLocalPort(); s.close(); - redisServer = new RedisServer(port); + redisServer = RedisServer.builder() + .port(port) + .setting("maxheap 128M") + .build(); redisServer.start(); // Configure JEDIS @@ -148,7 +152,7 @@ public class JedisIntegrationTest { jedis.zadd(key, playerScore.getValue(), playerScore.getKey()); }); - Set players = jedis.zrevrange(key, 0, 1); + List players = jedis.zrevrange(key, 0, 1); Assert.assertEquals("PlayerThree", players.iterator().next()); long rank = jedis.zrevrank(key, "PlayerOne"); @@ -184,7 +188,7 @@ public class JedisIntegrationTest { p.zadd("ranking", 126, userOneId); p.zadd("ranking", 325, userTwoId); Response pipeExists = p.sismember("searched#" + userOneId, "paris"); - Response> pipeRanking = p.zrange("ranking", 0, -1); + Response> pipeRanking = p.zrange("ranking", 0, -1); p.sync(); Assert.assertTrue(pipeExists.get()); diff --git a/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java index c2e771d7b8..b80cae98d8 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java @@ -32,7 +32,10 @@ public class RedissonConfigurationIntegrationTest { port = s.getLocalPort(); s.close(); - redisServer = new RedisServer(port); + redisServer = RedisServer.builder() + .port(port) + .setting("maxheap 128M") + .build(); redisServer.start(); } diff --git a/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java index 8c8e6a02dd..79581df989 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java @@ -29,8 +29,11 @@ public class RedissonIntegrationTest { private static RedissonClient client; @BeforeClass - public static void setUp() throws IOException { - redisServer = new RedisServer(6379); + public static void setUp() { + redisServer = RedisServer.builder() + .port(6379) + .setting("maxheap 128M") + .build(); redisServer.start(); client = Redisson.create(); } diff --git a/persistence-modules/redis/src/test/java/com/baeldung/redis/deleteeverything/DeleteEverythingInRedisIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/redis/deleteeverything/DeleteEverythingInRedisIntegrationTest.java index e0376fc6a5..54123afdea 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/redis/deleteeverything/DeleteEverythingInRedisIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/redis/deleteeverything/DeleteEverythingInRedisIntegrationTest.java @@ -23,7 +23,10 @@ public class DeleteEverythingInRedisIntegrationTest { port = s.getLocalPort(); s.close(); - redisServer = new RedisServer(port); + redisServer = RedisServer.builder() + .port(port) + .setting("maxheap 128M") + .build(); redisServer.start(); // Configure JEDIS diff --git a/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/NaiveApproachIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/NaiveApproachIntegrationTest.java index 9bf0b2b086..5c325e8ea0 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/NaiveApproachIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/NaiveApproachIntegrationTest.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.net.ServerSocket; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -24,7 +25,10 @@ public class NaiveApproachIntegrationTest { port = s.getLocalPort(); s.close(); - redisServer = new RedisServer(port); + redisServer = RedisServer.builder() + .port(port) + .setting("maxheap 128M") + .build(); } @AfterClass @@ -50,7 +54,7 @@ public class NaiveApproachIntegrationTest { @Test public void testKeys() { - HashMap keyValues = new HashMap(); + HashMap keyValues = new HashMap<>(); keyValues.put("balls:cricket", "160"); keyValues.put("balls:football", "450"); keyValues.put("balls:volleyball", "270"); @@ -62,7 +66,7 @@ public class NaiveApproachIntegrationTest { @Test public void testSmembers() { - HashSet setMembers = new HashSet(); + HashSet setMembers = new HashSet<>(); setMembers.add("cricket_160"); setMembers.add("football_450"); setMembers.add("volleyball_270"); @@ -73,7 +77,7 @@ public class NaiveApproachIntegrationTest { @Test public void testHgetAll() { - HashMap keyValues = new HashMap(); + HashMap keyValues = new HashMap<>(); keyValues.put("balls:cricket", "160"); keyValues.put("balls:football", "450"); keyValues.put("balls:volleyball", "270"); @@ -84,12 +88,12 @@ public class NaiveApproachIntegrationTest { @Test public void testZRange() { - HashMap scoreMembers = new HashMap(); + HashMap scoreMembers = new HashMap<>(); scoreMembers.put("cricket", (double) 160); scoreMembers.put("football", (double) 450); scoreMembers.put("volleyball", (double) 270); redisClient.zadd("balls", scoreMembers); - Set readSetMembers = redisClient.zrange("balls", 0, -1); + List readSetMembers = redisClient.zrange("balls", 0, -1); Assert.assertEquals(readSetMembers.size(), scoreMembers.size()); } diff --git a/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/ScanStrategyIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/ScanStrategyIntegrationTest.java index 9bde969b58..838d0144dc 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/ScanStrategyIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/ScanStrategyIntegrationTest.java @@ -8,7 +8,7 @@ import com.baeldung.redis_scan.strategy.impl.Scan; import com.baeldung.redis_scan.strategy.impl.Sscan; import com.baeldung.redis_scan.strategy.impl.Zscan; import org.junit.*; -import redis.clients.jedis.Tuple; +import redis.clients.jedis.resps.Tuple; import redis.embedded.RedisServer; import java.io.IOException; @@ -31,7 +31,10 @@ public class ScanStrategyIntegrationTest { port = s.getLocalPort(); s.close(); - redisServer = new RedisServer(port); + redisServer = RedisServer.builder() + .port(port) + .setting("maxheap 128M") + .build(); } @AfterClass @@ -57,7 +60,7 @@ public class ScanStrategyIntegrationTest { @Test public void testScanStrategy() { - HashMap keyValues = new HashMap(); + HashMap keyValues = new HashMap<>(); keyValues.put("balls:cricket", "160"); keyValues.put("balls:football", "450"); keyValues.put("balls:volleyball", "270"); @@ -66,7 +69,7 @@ public class ScanStrategyIntegrationTest { ScanStrategy scanStrategy = new Scan(); int iterationCount = 2; RedisIterator iterator = redisClient.iterator(iterationCount, "ball*", scanStrategy); - List results = new LinkedList(); + List results = new LinkedList<>(); while (iterator.hasNext()) { results.addAll(iterator.next()); } @@ -84,7 +87,7 @@ public class ScanStrategyIntegrationTest { Sscan scanStrategy = new Sscan("balls"); int iterationCount = 2; RedisIterator iterator = redisClient.iterator(iterationCount, "*", scanStrategy); - List results = new LinkedList(); + List results = new LinkedList<>(); while (iterator.hasNext()) { results.addAll(iterator.next()); } @@ -93,7 +96,7 @@ public class ScanStrategyIntegrationTest { @Test public void testHscanStrategy() { - HashMap hash = new HashMap(); + HashMap hash = new HashMap<>(); hash.put("cricket", "160"); hash.put("football", "450"); hash.put("volleyball", "270"); @@ -102,7 +105,7 @@ public class ScanStrategyIntegrationTest { Hscan scanStrategy = new Hscan("balls"); int iterationCount = 2; RedisIterator iterator = redisClient.iterator(iterationCount, "*", scanStrategy); - List> results = new LinkedList>(); + List> results = new LinkedList<>(); while (iterator.hasNext()) { results.addAll(iterator.next()); } @@ -111,7 +114,7 @@ public class ScanStrategyIntegrationTest { @Test public void testZscanStrategy() { - HashMap memberScores = new HashMap(); + HashMap memberScores = new HashMap<>(); memberScores.put("cricket", (double) 160); memberScores.put("football", (double) 450); memberScores.put("volleyball", (double) 270); @@ -120,7 +123,7 @@ public class ScanStrategyIntegrationTest { Zscan scanStrategy = new Zscan("balls"); int iterationCount = 2; RedisIterator iterator = redisClient.iterator(iterationCount, "*", scanStrategy); - List results = new LinkedList(); + List results = new LinkedList<>(); while (iterator.hasNext()) { results.addAll(iterator.next()); } diff --git a/persistence-modules/spring-boot-persistence-2/pom.xml b/persistence-modules/spring-boot-persistence-2/pom.xml index 1a02b18e50..260c558875 100644 --- a/persistence-modules/spring-boot-persistence-2/pom.xml +++ b/persistence-modules/spring-boot-persistence-2/pom.xml @@ -17,13 +17,6 @@ - - org.junit - junit-bom - ${junit-jupiter.version} - pom - import - org.springframework.boot spring-boot-dependencies @@ -33,7 +26,7 @@ org.jdbi - jdbi3-spring4 + jdbi3-spring5 ${jdbi.version} @@ -55,7 +48,7 @@ org.jdbi - jdbi3-spring4 + jdbi3-spring5 org.jdbi @@ -103,6 +96,7 @@ mysql mysql-connector-java + ${mysql-connector-java.version} org.xerial @@ -143,10 +137,14 @@ - 3.9.1 - 2.1.8.RELEASE - 0.9.5.2 - 21.1.0.0 + 3.38.0 + 3.0.5 + 0.9.5.5 + 21.9.0.0 + + 2.0.7 + 1.4.6 + 8.0.33 \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/boot/jdbi/JdbiConfiguration.java b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/boot/jdbi/JdbiConfiguration.java index ddbe6cc118..d744a46f3f 100644 --- a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/boot/jdbi/JdbiConfiguration.java +++ b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/boot/jdbi/JdbiConfiguration.java @@ -31,11 +31,11 @@ public class JdbiConfiguration { // Register all available plugins log.info("[I27] Installing plugins... ({} found)", jdbiPlugins.size()); - jdbiPlugins.forEach(plugin -> jdbi.installPlugin(plugin)); + jdbiPlugins.forEach(jdbi::installPlugin); // Register all available rowMappers log.info("[I31] Installing rowMappers... ({} found)", rowMappers.size()); - rowMappers.forEach(mapper -> jdbi.registerRowMapper(mapper)); + rowMappers.forEach(jdbi::registerRowMapper); return jdbi; } diff --git a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/boot/jdbi/domain/CarModel.java b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/boot/jdbi/domain/CarModel.java index 80b615801b..36cfd59b6d 100644 --- a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/boot/jdbi/domain/CarModel.java +++ b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/boot/jdbi/domain/CarModel.java @@ -8,7 +8,7 @@ import lombok.Data; public class CarModel { private Long id; private String name; - private Integer year; + private Integer yearDate; private String sku; private Long makerId; } diff --git a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/boot/jdbi/mapper/CarModelMapper.java b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/boot/jdbi/mapper/CarModelMapper.java index eeceafd649..b2311ef6a9 100644 --- a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/boot/jdbi/mapper/CarModelMapper.java +++ b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/boot/jdbi/mapper/CarModelMapper.java @@ -18,7 +18,7 @@ public class CarModelMapper implements RowMapper{ .id(rs.getLong("id")) .name(rs.getString("name")) .sku(rs.getString("sku")) - .year(rs.getInt("year")) + .yearDate(rs.getInt("year")) .build(); } diff --git a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/db/indexing/Image.java b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/db/indexing/Image.java index e3fcf53f81..7c7a558777 100644 --- a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/db/indexing/Image.java +++ b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/db/indexing/Image.java @@ -1,9 +1,9 @@ package com.baeldung.db.indexing; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Lob; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; @Entity class Image { diff --git a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/spring/oracle/pooling/entity/Book.java b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/spring/oracle/pooling/entity/Book.java index fb2c3fcf6a..af4199e65b 100644 --- a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/spring/oracle/pooling/entity/Book.java +++ b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/spring/oracle/pooling/entity/Book.java @@ -1,9 +1,9 @@ package com.baeldung.spring.oracle.pooling.entity; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Book { diff --git a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/springboothsqldb/application/entities/Customer.java b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/springboothsqldb/application/entities/Customer.java index ee2735abb8..cd4fafb60f 100644 --- a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/springboothsqldb/application/entities/Customer.java +++ b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/springboothsqldb/application/entities/Customer.java @@ -1,10 +1,10 @@ package com.baeldung.springboothsqldb.application.entities; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "customers") diff --git a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/states/UserEntity.java b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/states/UserEntity.java index 90bd275240..8c3494d1e4 100644 --- a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/states/UserEntity.java +++ b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/states/UserEntity.java @@ -5,9 +5,9 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; @Entity @AllArgsConstructor diff --git a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/states/UserEntityWithCascade.java b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/states/UserEntityWithCascade.java index de0d62bfe2..ada6b87ae3 100644 --- a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/states/UserEntityWithCascade.java +++ b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/states/UserEntityWithCascade.java @@ -5,10 +5,10 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToOne; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; @Entity @AllArgsConstructor diff --git a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/tomcatconnectionpool/application/entities/Customer.java b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/tomcatconnectionpool/application/entities/Customer.java index 712506eb98..02af097dc0 100644 --- a/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/tomcatconnectionpool/application/entities/Customer.java +++ b/persistence-modules/spring-boot-persistence-2/src/main/java/com/baeldung/tomcatconnectionpool/application/entities/Customer.java @@ -1,11 +1,11 @@ package com.baeldung.tomcatconnectionpool.application.entities; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "customers") diff --git a/persistence-modules/spring-boot-persistence-2/src/main/resources/com/baeldung/boot/jdbi/dao/CarMakerDao/insert.sql b/persistence-modules/spring-boot-persistence-2/src/main/resources/com/baeldung/boot/jdbi/dao/CarMakerDao/insert.sql index 0e045d7274..0b1a93158b 100644 --- a/persistence-modules/spring-boot-persistence-2/src/main/resources/com/baeldung/boot/jdbi/dao/CarMakerDao/insert.sql +++ b/persistence-modules/spring-boot-persistence-2/src/main/resources/com/baeldung/boot/jdbi/dao/CarMakerDao/insert.sql @@ -1,4 +1,4 @@ -- -- Insert -- -insert into car_maker(id,name) values (:id,:name); +insert into car_maker(name) values (:name); diff --git a/persistence-modules/spring-boot-persistence-2/src/main/resources/com/baeldung/boot/jdbi/dao/CarModelDao/insert.sql b/persistence-modules/spring-boot-persistence-2/src/main/resources/com/baeldung/boot/jdbi/dao/CarModelDao/insert.sql index b277213584..6bca3a0d6d 100644 --- a/persistence-modules/spring-boot-persistence-2/src/main/resources/com/baeldung/boot/jdbi/dao/CarModelDao/insert.sql +++ b/persistence-modules/spring-boot-persistence-2/src/main/resources/com/baeldung/boot/jdbi/dao/CarModelDao/insert.sql @@ -1,8 +1,8 @@ -- -- Insert -- -insert into car_model(maker_fk,name,sku,year) values ( +insert into car_model(maker_fk,name,sku,yearDate) values ( :makerId, :name, :sku, - :year ); + :yearDate ); diff --git a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/boot/jdbi/SpringBootJdbiApplicationIntegrationTest.java b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/boot/jdbi/SpringBootJdbiApplicationIntegrationTest.java index ac5661afbc..948d197f14 100644 --- a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/boot/jdbi/SpringBootJdbiApplicationIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/boot/jdbi/SpringBootJdbiApplicationIntegrationTest.java @@ -76,7 +76,7 @@ public class SpringBootJdbiApplicationIntegrationTest { @Test public void givenExistingCarMaker_whenFindById_thenReturnExistingCarMaker() { - CarMaker maker = carMakerDao.findById(1l); + CarMaker maker = carMakerDao.findById(1L); assertThat(maker).isNotNull(); assertThat(maker.getId()).isEqualTo(1); @@ -85,12 +85,12 @@ public class SpringBootJdbiApplicationIntegrationTest { @Test public void givenExistingCarMaker_whenBulkInsertFails_thenRollback() { - CarMaker maker = carMakerDao.findById(1l); + CarMaker maker = carMakerDao.findById(1L); CarModel m1 = CarModel.builder() .makerId(maker.getId()) .name("Model X1") .sku("1-M1") - .year(2019) + .yearDate(2019) .build(); maker.getModels().add(m1); @@ -98,7 +98,7 @@ public class SpringBootJdbiApplicationIntegrationTest { .makerId(maker.getId()) .name("Model X1") .sku("1-M1") - .year(2019) + .yearDate(2019) .build(); maker.getModels().add(m2); diff --git a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/db/indexing/FileSystemImageIntegrationTest.java b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/db/indexing/FileSystemImageIntegrationTest.java index 83f5bae095..809d04cc96 100644 --- a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/db/indexing/FileSystemImageIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/db/indexing/FileSystemImageIntegrationTest.java @@ -4,8 +4,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import java.io.File; import java.io.InputStream; -import java.nio.file.Paths; +import java.net.URISyntaxException; +import java.net.URL; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -64,10 +66,13 @@ class FileSystemImageIntegrationTest { private FileSystemResource baeldungJpegResource() { ClassLoader classLoader = ClassLoader.getSystemClassLoader(); - String imagePath = classLoader.getResource("baeldung.jpeg") - .getFile(); - - return new FileSystemResource(Paths.get(imagePath)); + try { + final URL resource = classLoader.getResource("baeldung.jpeg"); + if (resource != null) { + return new FileSystemResource(new File(resource.toURI()).getAbsolutePath()); + } + } catch (URISyntaxException ignore) {} + return null; } } diff --git a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/db/indexing/ImageIntegrationTest.java b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/db/indexing/ImageIntegrationTest.java index e38e0a21a9..09e13aefd4 100644 --- a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/db/indexing/ImageIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/db/indexing/ImageIntegrationTest.java @@ -7,6 +7,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import java.io.IOException; import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Optional; @@ -68,11 +70,15 @@ class ImageIntegrationTest { private Image baeldungImage() throws IOException { ClassLoader classLoader = ClassLoader.getSystemClassLoader(); - - Image mockImage = new Image(); - mockImage.setContent(Files.readAllBytes(Paths.get(classLoader.getResource("baeldung.jpeg") - .getFile()))); - return mockImage; + try { + final URL resource = classLoader.getResource("baeldung.jpeg"); + if (resource != null) { + Image mockImage = new Image(); + mockImage.setContent(Files.readAllBytes(Paths.get(resource.toURI()))); + return mockImage; + } + } catch (URISyntaxException ignore) {} + return null; } } diff --git a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/springboothsqldb/application/tests/CustomerControllerIntegrationTest.java b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/springboothsqldb/application/tests/CustomerControllerIntegrationTest.java index 6956df0b13..bdd9a19b68 100644 --- a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/springboothsqldb/application/tests/CustomerControllerIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/springboothsqldb/application/tests/CustomerControllerIntegrationTest.java @@ -29,8 +29,7 @@ public class CustomerControllerIntegrationTest { @Before public void setUpJsonMediaType() { - MEDIA_TYPE_JSON = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8")); - + MEDIA_TYPE_JSON = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype()); } @Test diff --git a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/states/UserEntityIntegrationTest.java b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/states/UserEntityIntegrationTest.java index 5d0dc99ad7..0ce3ff34ce 100644 --- a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/states/UserEntityIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/states/UserEntityIntegrationTest.java @@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import javax.persistence.EntityManagerFactory; +import jakarta.persistence.EntityManagerFactory; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; diff --git a/persistence-modules/spring-boot-persistence-2/src/test/resources/data.sql b/persistence-modules/spring-boot-persistence-2/src/test/resources/data.sql index e3e1f4ae32..fb97140b48 100644 --- a/persistence-modules/spring-boot-persistence-2/src/test/resources/data.sql +++ b/persistence-modules/spring-boot-persistence-2/src/test/resources/data.sql @@ -1,12 +1,12 @@ -insert into car_maker(id,name) values (1,'Special Motors'); -insert into car_maker(id,name) values (2,'BWM'); -insert into car_maker(id,name) values (3,'Dolores'); +insert into car_maker(id,name) values (99,'Special Motors'); +insert into car_maker(id,name) values (100,'BWM'); +insert into car_maker(id,name) values (102,'Dolores'); -insert into car_model(id,maker_fk,name,sku,year) values(1,1,'Muze','SM001',2018); -insert into car_model(id,maker_fk,name,sku,year) values(2,1,'Empada','SM002',2008); +insert into car_model(id,maker_fk,name,sku,yearDate) values(132,99,'Muze','SM001',2018); +insert into car_model(id,maker_fk,name,sku,yearDate) values(145,99,'Empada','SM002',2008); -insert into car_model(id,maker_fk,name,sku,year) values(4,2,'BWM-100','BWM100',2008); -insert into car_model(id,maker_fk,name,sku,year) values(5,2,'BWM-200','BWM200',2009); -insert into car_model(id,maker_fk,name,sku,year) values(6,2,'BWM-300','BWM300',2008); +insert into car_model(id,maker_fk,name,sku,yearDate) values(43,100,'BWM-100','BWM100',2008); +insert into car_model(id,maker_fk,name,sku,yearDate) values(564,100,'BWM-200','BWM200',2009); +insert into car_model(id,maker_fk,name,sku,yearDate) values(343,100,'BWM-300','BWM300',2008); diff --git a/persistence-modules/spring-boot-persistence-2/src/test/resources/schema.sql b/persistence-modules/spring-boot-persistence-2/src/test/resources/schema.sql index 8d7db6c9f3..72f9e606de 100644 --- a/persistence-modules/spring-boot-persistence-2/src/test/resources/schema.sql +++ b/persistence-modules/spring-boot-persistence-2/src/test/resources/schema.sql @@ -19,9 +19,9 @@ create table car_model( maker_fk int not null, name varchar(128) not null, sku varchar(128) not null, - year int not null + yearDate int not null ); create unique index ui_car_model_01 on car_model(maker_fk,sku); -create unique index ui_car_model_02 on car_model(maker_fk,name,year); +create unique index ui_car_model_02 on car_model(maker_fk,name,yearDate); diff --git a/persistence-modules/spring-boot-persistence-h2/README.md b/persistence-modules/spring-boot-persistence-h2/README.md index 1d47907a98..7f6e243677 100644 --- a/persistence-modules/spring-boot-persistence-h2/README.md +++ b/persistence-modules/spring-boot-persistence-h2/README.md @@ -5,3 +5,4 @@ - [Hibernate @NotNull vs @Column(nullable = false)](https://www.baeldung.com/hibernate-notnull-vs-nullable) - [Quick Guide to Hibernate enable_lazy_load_no_trans Property](https://www.baeldung.com/hibernate-lazy-loading-workaround) - [Where Does H2’s Embedded Database Store The Data?](https://www.baeldung.com/h2-embedded-db-data-storage) +- [Spring Boot H2 JdbcSQLSyntaxErrorException expected “identifier”](https://www.baeldung.com/spring-boot-h2-jdbcsqlsyntaxerrorexception-expected-identifier) diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2/exceptions/SpringBootH2Exceptions.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2/exceptions/SpringBootH2Exceptions.java new file mode 100644 index 0000000000..c7684423a2 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2/exceptions/SpringBootH2Exceptions.java @@ -0,0 +1,15 @@ +package com.baeldung.h2.exceptions; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:app-h2.properties") +public class SpringBootH2Exceptions { + + public static void main(String... args) { + SpringApplication.run(SpringBootH2Exceptions.class, args); + } + +} diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2/exceptions/models/User.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2/exceptions/models/User.java new file mode 100644 index 0000000000..e54e725fd0 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2/exceptions/models/User.java @@ -0,0 +1,38 @@ +package com.baeldung.h2.exceptions.models; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class User { + + @Id + private int id; + private String login; + private String password; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2/exceptions/repos/UserRepository.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2/exceptions/repos/UserRepository.java new file mode 100644 index 0000000000..d014fb16c6 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2/exceptions/repos/UserRepository.java @@ -0,0 +1,11 @@ +package com.baeldung.h2.exceptions.repos; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.baeldung.h2.exceptions.models.User; + +@Repository +public interface UserRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/resources/app-h2.properties b/persistence-modules/spring-boot-persistence-h2/src/main/resources/app-h2.properties new file mode 100644 index 0000000000..bb88e7fef4 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-h2/src/main/resources/app-h2.properties @@ -0,0 +1 @@ +spring.sql.init.data-locations=user-data.sql diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/resources/user-data.sql b/persistence-modules/spring-boot-persistence-h2/src/main/resources/user-data.sql new file mode 100644 index 0000000000..cea758c74e --- /dev/null +++ b/persistence-modules/spring-boot-persistence-h2/src/main/resources/user-data.sql @@ -0,0 +1,8 @@ +/* These commented lines will cause Spring Boot to fail at startup + * + * INSERT INTO user VALUES (1, 'admin', 'p@ssw@rd'); + * INSERT INTO user VALUES (2, 'user', 'userpasswd'); + * +*/ +INSERT INTO "user" VALUES (1, 'admin', 'p@ssw@rd'); +INSERT INTO "user" VALUES (2, 'user', 'userpasswd'); \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-h2/src/test/java/com/baeldung/h2/exceptions/SpringBootH2ExceptionsIntegrationTest.java b/persistence-modules/spring-boot-persistence-h2/src/test/java/com/baeldung/h2/exceptions/SpringBootH2ExceptionsIntegrationTest.java new file mode 100644 index 0000000000..94cf08fb76 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-h2/src/test/java/com/baeldung/h2/exceptions/SpringBootH2ExceptionsIntegrationTest.java @@ -0,0 +1,30 @@ +package com.baeldung.h2.exceptions; + +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.test.context.junit4.SpringRunner; + +import com.baeldung.h2.exceptions.models.User; +import com.baeldung.h2.exceptions.repos.UserRepository; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringBootH2Exceptions.class) +public class SpringBootH2ExceptionsIntegrationTest { + + @Autowired + private UserRepository userRepository; + + @Test + public void givenValidInitData_whenCallingFindAll_thenReturnData() { + List users = userRepository.findAll(); + + assertThat(users).hasSize(2); + } + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/pom.xml b/persistence-modules/spring-boot-persistence-mongodb-2/pom.xml index cd7198b931..121581498a 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-2/pom.xml +++ b/persistence-modules/spring-boot-persistence-mongodb-2/pom.xml @@ -5,7 +5,6 @@ 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 diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/pom.xml b/persistence-modules/spring-boot-persistence-mongodb-3/pom.xml index b9a47aa703..b699a33559 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/pom.xml +++ b/persistence-modules/spring-boot-persistence-mongodb-3/pom.xml @@ -5,7 +5,6 @@ 4.0.0 spring-boot-persistence-mongodb-3 spring-boot-persistence-mongodb-3 - war This is simple boot application for Spring boot persistence mongodb @@ -16,6 +15,21 @@ + + org.mongodb + mongodb-driver-sync + ${mongodb-driver.version} + + + org.mongodb + mongodb-driver-core + ${mongodb-driver.version} + + + org.mongodb + bson + ${mongodb-driver.version} + org.springframework.boot spring-boot-starter-web @@ -23,6 +37,16 @@ org.springframework.boot spring-boot-starter-data-mongodb + + + org.mongodb + mongodb-driver-sync + + + org.mongodb + mongodb-driver-core + + org.mongodb @@ -37,7 +61,8 @@ - 1.6.1 + 1.7.3 + 4.9.1 diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/EncryptionConfig.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/EncryptionConfig.java index 0ff97eb6c1..1a74340057 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/EncryptionConfig.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/EncryptionConfig.java @@ -1,5 +1,7 @@ package com.baeldung.boot.csfle.config; +import java.io.File; + import org.bson.BsonBinary; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @@ -17,7 +19,13 @@ public class EncryptionConfig { private String keyVaultAlias; @Value("${com.baeldung.csfle.auto-decryption:false}") - private Boolean autoDecryption; + private boolean autoDecryption; + + @Value("${com.baeldung.csfle.auto-encryption:false}") + private boolean autoEncryption; + + @Value("${com.baeldung.csfle.auto-encryption-lib:#{null}}") + private File autoEncryptionLib; private BsonBinary dataKeyId; @@ -41,7 +49,23 @@ public class EncryptionConfig { return masterKeyPath; } - public Boolean getAutoDecryption() { + public boolean isAutoDecryption() { return autoDecryption; } + + public boolean isAutoEncryption() { + return autoEncryption; + } + + public File getAutoEncryptionLib() { + return autoEncryptionLib; + } + + public String dataKeyIdUuid() { + if (dataKeyId == null) + throw new IllegalStateException("data key not initialized"); + + return dataKeyId.asUuid() + .toString(); + } } diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/MongoClientConfig.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/MongoClientConfig.java index 0dff1ec86d..19d0af08b2 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/MongoClientConfig.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/MongoClientConfig.java @@ -1,14 +1,15 @@ package com.baeldung.boot.csfle.config; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Arrays; +import java.util.HashMap; import java.util.Map; import org.bson.BsonBinary; import org.bson.BsonDocument; import org.bson.Document; -import org.bson.conversions.Bson; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; @@ -51,14 +52,10 @@ public class MongoClientConfig extends AbstractMongoClientConfiguration { @Bean @Override public MongoClient mongoClient() { - MongoClient client; try { - client = MongoClients.create(clientSettings()); - ClientEncryption encryption = clientEncryption(); - encryptionConfig.setDataKeyId(createOrRetrieveDataKey(client, encryption)); - - return client; + encryptionConfig.setDataKeyId(createOrRetrieveDataKey(encryption)); + return MongoClients.create(clientSettings()); } catch (IOException e) { throw new IllegalStateException("unable to create client", e); } @@ -77,19 +74,10 @@ public class MongoClientConfig extends AbstractMongoClientConfiguration { return ClientEncryptions.create(encryptionSettings); } - private BsonBinary createOrRetrieveDataKey(MongoClient client, ClientEncryption encryption) { - MongoNamespace namespace = new MongoNamespace(encryptionConfig.getKeyVaultNamespace()); - MongoCollection keyVault = client.getDatabase(namespace.getDatabaseName()) - .getCollection(namespace.getCollectionName()); - - Bson query = Filters.in("keyAltNames", encryptionConfig.getKeyVaultAlias()); - BsonDocument key = keyVault.withDocumentClass(BsonDocument.class) - .find(query) - .first(); - + private BsonBinary createOrRetrieveDataKey(ClientEncryption encryption) { + BsonDocument key = encryption.getKeyByAltName(encryptionConfig.getKeyVaultAlias()); if (key == null) { - keyVault.createIndex(Indexes.ascending("keyAltNames"), new IndexOptions().unique(true) - .partialFilterExpression(Filters.exists("keyAltNames"))); + createKeyUniqueIndex(); DataKeyOptions options = new DataKeyOptions(); options.keyAltNames(Arrays.asList(encryptionConfig.getKeyVaultAlias())); @@ -99,16 +87,68 @@ public class MongoClientConfig extends AbstractMongoClientConfiguration { } } + private void createKeyUniqueIndex() { + try (MongoClient client = MongoClients.create(MongoClientSettings.builder() + .applyConnectionString(new ConnectionString(uri)) + .build())) { + MongoNamespace namespace = new MongoNamespace(encryptionConfig.getKeyVaultNamespace()); + MongoCollection keyVault = client.getDatabase(namespace.getDatabaseName()) + .getCollection(namespace.getCollectionName()); + + keyVault.createIndex(Indexes.ascending("keyAltNames"), new IndexOptions().unique(true) + .partialFilterExpression(Filters.exists("keyAltNames"))); + } + } + private MongoClientSettings clientSettings() throws FileNotFoundException, IOException { Builder settings = MongoClientSettings.builder() .applyConnectionString(new ConnectionString(uri)); - if (encryptionConfig.getAutoDecryption()) { - settings.autoEncryptionSettings(AutoEncryptionSettings.builder() + if (encryptionConfig.isAutoDecryption()) { + AutoEncryptionSettings.Builder builder = AutoEncryptionSettings.builder() .keyVaultNamespace(encryptionConfig.getKeyVaultNamespace()) - .kmsProviders(LocalKmsUtils.providersMap(encryptionConfig.getMasterKeyPath())) - .bypassAutoEncryption(true) - .build()); + .kmsProviders(LocalKmsUtils.providersMap(encryptionConfig.getMasterKeyPath())); + + if (encryptionConfig.isAutoEncryption() && encryptionConfig.getDataKeyId() != null) { + File autoEncryptionLib = encryptionConfig.getAutoEncryptionLib(); + if (!autoEncryptionLib.isFile()) { + throw new IllegalArgumentException("encryption lib must be an existing file"); + } + + Map map = new HashMap<>(); + map.put("cryptSharedLibRequired", true); + map.put("cryptSharedLibPath", autoEncryptionLib.toString()); + builder.extraOptions(map); + + String keyUuid = encryptionConfig.dataKeyIdUuid(); + HashMap schemaMap = new HashMap<>(); + schemaMap.put(getDatabaseName() + ".citizens", + BsonDocument.parse("{" + + " bsonType: \"object\"," + + " encryptMetadata: {" + + " keyId: [UUID(\"" + keyUuid + "\")]" + + " }," + + " properties: {" + + " email: {" + + " encrypt: {" + + " bsonType: \"string\"," + + " algorithm: \"AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic\"" + + " }" + + " }," + + " birthYear: {" + + " encrypt: {" + + " bsonType: \"int\"," + + " algorithm: \"AEAD_AES_256_CBC_HMAC_SHA_512-Random\"" + + " }" + + " }" + + " }" + + "}")); + builder.schemaMap(schemaMap); + } else { + builder.bypassAutoEncryption(true); + } + + settings.autoEncryptionSettings(builder.build()); } return settings.build(); diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/service/CitizenService.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/service/CitizenService.java index 6b3c463d0d..c93b00f3f8 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/service/CitizenService.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/service/CitizenService.java @@ -35,16 +35,20 @@ public class CitizenService { @Autowired private ClientEncryption clientEncryption; - public EncryptedCitizen save(Citizen citizen) { - EncryptedCitizen encryptedCitizen = new EncryptedCitizen(citizen); - encryptedCitizen.setEmail(encrypt(citizen.getEmail(), DETERMINISTIC_ALGORITHM)); - encryptedCitizen.setBirthYear(encrypt(citizen.getBirthYear(), RANDOM_ALGORITHM)); + public Object save(Citizen citizen) { + if (encryptionConfig.isAutoEncryption()) { + return mongo.save(citizen); + } else { + EncryptedCitizen encryptedCitizen = new EncryptedCitizen(citizen); + encryptedCitizen.setEmail(encrypt(citizen.getEmail(), DETERMINISTIC_ALGORITHM)); + encryptedCitizen.setBirthYear(encrypt(citizen.getBirthYear(), RANDOM_ALGORITHM)); - return mongo.save(encryptedCitizen); + return mongo.save(encryptedCitizen); + } } public List findAll() { - if (!encryptionConfig.getAutoDecryption()) { + if (!encryptionConfig.isAutoDecryption()) { List allEncrypted = mongo.findAll(EncryptedCitizen.class); return allEncrypted.stream() @@ -56,13 +60,20 @@ public class CitizenService { } public Citizen findByEmail(String email) { - Query byEmail = new Query(Criteria.where("email") - .is(encrypt(email, DETERMINISTIC_ALGORITHM))); - if (!encryptionConfig.getAutoDecryption()) { + Criteria emailCriteria = Criteria.where("email"); + if (encryptionConfig.isAutoEncryption()) { + emailCriteria.is(email); + } else { + emailCriteria + .is(encrypt(email, DETERMINISTIC_ALGORITHM)); + } + + Query byEmail = new Query(emailCriteria); + if (encryptionConfig.isAutoDecryption()) { + return mongo.findOne(byEmail, Citizen.class); + } else { EncryptedCitizen encryptedCitizen = mongo.findOne(byEmail, EncryptedCitizen.class); return decrypt(encryptedCitizen); - } else { - return mongo.findOne(byEmail, Citizen.class); } } diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/web/CitizenController.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/web/CitizenController.java index d17435fb5e..7a2b2605cd 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/web/CitizenController.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/web/CitizenController.java @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.baeldung.boot.csfle.data.Citizen; -import com.baeldung.boot.csfle.data.EncryptedCitizen; import com.baeldung.boot.csfle.service.CitizenService; @RestController @@ -32,7 +31,7 @@ public class CitizenController { } @PostMapping - public EncryptedCitizen post(@RequestBody Citizen citizen) { + public Object post(@RequestBody Citizen citizen) { return service.save(citizen); } } diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/csfle/CitizenServiceLiveTest.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/csfle/CitizenServiceLiveTest.java index 471cb2883a..d57da43751 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/csfle/CitizenServiceLiveTest.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/csfle/CitizenServiceLiveTest.java @@ -38,10 +38,14 @@ public class CitizenServiceLiveTest { citizen.setName("Foo"); citizen.setEmail("foo@citizen.com"); - Binary encryptedEmail = service.encrypt(citizen.getEmail(), CitizenService.DETERMINISTIC_ALGORITHM); + Object saved = service.save(citizen); + if (saved instanceof EncryptedCitizen) { + Binary encryptedEmail = service.encrypt(citizen.getEmail(), CitizenService.DETERMINISTIC_ALGORITHM); - EncryptedCitizen saved = service.save(citizen); - assertEquals(encryptedEmail, saved.getEmail()); + assertEquals(encryptedEmail, ((EncryptedCitizen) saved).getEmail()); + } else { + assertEquals(citizen.getEmail(), ((Citizen) saved).getEmail()); + } } @Test diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/test/resources/embedded.properties b/persistence-modules/spring-boot-persistence-mongodb-3/src/test/resources/embedded.properties index 5325354e55..cd1c1d43c7 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/test/resources/embedded.properties +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/test/resources/embedded.properties @@ -1,10 +1,10 @@ spring.mongodb.embedded.version=4.4.9 -spring.data.mongodb.uri=changeit -spring.data.mongodb.database=changeit +#spring.data.mongodb.uri=changeit +#spring.data.mongodb.database=changeit com.baeldung.csfle.kms-provider=local com.baeldung.csfle.key-vault.namespace=encryption._keyVault com.baeldung.csfle.key-vault.alias=master.key -com.baeldung.csfle.master-key-path=/tmp/master.key +#com.baeldung.csfle.master-key-path=/tmp/master.key com.baeldung.csfle.auto-decryption=false diff --git a/persistence-modules/spring-boot-persistence-mongodb/pom.xml b/persistence-modules/spring-boot-persistence-mongodb/pom.xml index 724fa38f7e..aae307f7f8 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/pom.xml +++ b/persistence-modules/spring-boot-persistence-mongodb/pom.xml @@ -5,7 +5,6 @@ 4.0.0 spring-boot-persistence-mongodb spring-boot-persistence-mongodb - war This is simple boot application for Spring boot persistence mongodb test diff --git a/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/dataloading/ApplicationDataLoading.java b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/dataloading/ApplicationDataLoading.java new file mode 100644 index 0000000000..40742d303e --- /dev/null +++ b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/dataloading/ApplicationDataLoading.java @@ -0,0 +1,16 @@ +package com.baeldung.dataloading; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.core.env.AbstractEnvironment; + +@SpringBootApplication(scanBasePackages = { "com.baeldung.dataloading" }) +public class ApplicationDataLoading { + + public static void main(String[] args) { + System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "datasource"); + + SpringApplication.run(ApplicationDataLoading.class, args); + } + +} diff --git a/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/dataloading/model/Country.java b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/dataloading/model/Country.java new file mode 100644 index 0000000000..692d48caf0 --- /dev/null +++ b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/dataloading/model/Country.java @@ -0,0 +1,36 @@ +package com.baeldung.dataloading.model; + +import static javax.persistence.GenerationType.IDENTITY; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Country { + + @Id + @GeneratedValue(strategy = IDENTITY) + private Integer id; + + @Column(nullable = false) + private String name; + + public Integer getId() { + return id; + } + + public void setId(Integer 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/src/main/resources/application-datasource.properties b/persistence-modules/spring-boot-persistence/src/main/resources/application-datasource.properties new file mode 100644 index 0000000000..98cf2ba965 --- /dev/null +++ b/persistence-modules/spring-boot-persistence/src/main/resources/application-datasource.properties @@ -0,0 +1,14 @@ +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +spring.datasource.username=sa +spring.datasource.password= + +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.jpa.hibernate.ddl-auto=create +spring.jpa.defer-datasource-initialization=true + +# Enabling H2 Console +spring.h2.console.enabled=true + +# By default enabled for Embedded Databases +#spring.sql.init.mode=always \ No newline at end of file diff --git a/persistence-modules/spring-data-couchbase-2/pom.xml b/persistence-modules/spring-data-couchbase-2/pom.xml index c860f809fd..deb7d3b524 100644 --- a/persistence-modules/spring-data-couchbase-2/pom.xml +++ b/persistence-modules/spring-data-couchbase-2/pom.xml @@ -57,23 +57,22 @@ test - javax.el - javax.el-api - ${javax.el.version} + org.glassfish.expressly + expressly + 5.0.0 - org.glassfish - javax.el - ${javax.el.version} + jakarta.annotation + jakarta.annotation-api + 2.1.1 - 4.3.4.RELEASE - 2.1.5.RELEASE - 5.3.3.Final - 2.9.6 - 3.0.0 + 6.0.6 + 5.0.3 + 8.0.0.Final + 2.12.2 \ No newline at end of file diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/model/Campus.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/model/Campus.java index d710a35796..898ccc9562 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/model/Campus.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/model/Campus.java @@ -1,13 +1,12 @@ package com.baeldung.spring.data.couchbase.model; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.annotation.Id; import org.springframework.data.couchbase.core.mapping.Document; +import org.springframework.data.couchbase.core.mapping.Field; import org.springframework.data.geo.Point; -import com.couchbase.client.java.repository.annotation.Field; - @Document public class Campus { diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/model/Person.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/model/Person.java index 1e081f01da..180c089f94 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/model/Person.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/model/Person.java @@ -1,12 +1,11 @@ package com.baeldung.spring.data.couchbase.model; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.joda.time.DateTime; import org.springframework.data.annotation.Id; import org.springframework.data.couchbase.core.mapping.Document; - -import com.couchbase.client.java.repository.annotation.Field; +import org.springframework.data.couchbase.core.mapping.Field; @Document public class Person { diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/model/Student.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/model/Student.java index e979eca864..8c03f66bb2 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/model/Student.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/model/Student.java @@ -1,16 +1,15 @@ package com.baeldung.spring.data.couchbase.model; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Past; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Past; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import org.joda.time.DateTime; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.couchbase.core.mapping.Document; - -import com.couchbase.client.java.repository.annotation.Field; +import org.springframework.data.couchbase.core.mapping.Field; @Document public class Student { diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/repos/CustomStudentRepositoryImpl.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/repos/CustomStudentRepositoryImpl.java index c4742ac44a..ce20e0cd49 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/repos/CustomStudentRepositoryImpl.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/repos/CustomStudentRepositoryImpl.java @@ -5,9 +5,7 @@ import java.util.List; import com.baeldung.spring.data.couchbase.model.Student; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.couchbase.core.CouchbaseTemplate; - -import com.couchbase.client.java.view.Stale; -import com.couchbase.client.java.view.ViewQuery; +import org.springframework.data.couchbase.core.query.QueryCriteria; public class CustomStudentRepositoryImpl implements CustomStudentRepository { @@ -17,6 +15,6 @@ public class CustomStudentRepositoryImpl implements CustomStudentRepository { private CouchbaseTemplate template; public List findByFirstNameStartsWith(String s) { - return template.findByView(ViewQuery.from(DESIGN_DOC, "byFirstName").startKey(s).stale(Stale.FALSE), Student.class); + return template.findByQuery(Student.class).matching(QueryCriteria.where("firstName").startingWith(s)).all(); } } diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/PersonRepositoryService.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/PersonRepositoryService.java index 4051585e31..5e1c2a2cb8 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/PersonRepositoryService.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/PersonRepositoryService.java @@ -3,6 +3,7 @@ package com.baeldung.spring.data.couchbase.service; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Optional; import com.baeldung.spring.data.couchbase.model.Person; import com.baeldung.spring.data.couchbase.repos.PersonRepository; @@ -22,12 +23,12 @@ public class PersonRepositoryService implements PersonService { this.repo = repo; } - public Person findOne(String id) { - return repo.findOne(id); + public Optional findOne(String id) { + return repo.findById(id); } public List findAll() { - List people = new ArrayList(); + List people = new ArrayList<>(); Iterator it = repo.findAll().iterator(); while (it.hasNext()) { people.add(it.next()); diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/PersonService.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/PersonService.java index f321eba94e..975af7f4a0 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/PersonService.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/PersonService.java @@ -1,12 +1,13 @@ package com.baeldung.spring.data.couchbase.service; import java.util.List; +import java.util.Optional; import com.baeldung.spring.data.couchbase.model.Person; public interface PersonService { - Person findOne(String id); + Optional findOne(String id); List findAll(); diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/PersonTemplateService.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/PersonTemplateService.java index 5e49465a25..3be9cb9416 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/PersonTemplateService.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/PersonTemplateService.java @@ -1,6 +1,9 @@ package com.baeldung.spring.data.couchbase.service; +import static org.springframework.data.couchbase.core.query.QueryCriteria.where; + import java.util.List; +import java.util.Optional; import com.baeldung.spring.data.couchbase.model.Person; import org.joda.time.DateTime; @@ -9,8 +12,6 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.couchbase.core.CouchbaseTemplate; import org.springframework.stereotype.Service; -import com.couchbase.client.java.view.ViewQuery; - @Service @Qualifier("PersonTemplateService") public class PersonTemplateService implements PersonService { @@ -24,33 +25,33 @@ public class PersonTemplateService implements PersonService { this.template = template; } - public Person findOne(String id) { - return template.findById(id, Person.class); + public Optional findOne(String id) { + return Optional.of(template.findById(Person.class).one(id)); } public List findAll() { - return template.findByView(ViewQuery.from(DESIGN_DOC, "all"), Person.class); + return template.findByQuery(Person.class).all(); } public List findByFirstName(String firstName) { - return template.findByView(ViewQuery.from(DESIGN_DOC, "byFirstName"), Person.class); + return template.findByQuery(Person.class).matching(where("firstName").is(firstName)).all(); } public List findByLastName(String lastName) { - return template.findByView(ViewQuery.from(DESIGN_DOC, "byLastName"), Person.class); + return template.findByQuery(Person.class).matching(where("lastName").is(lastName)).all(); } public void create(Person person) { person.setCreated(DateTime.now()); - template.insert(person); + template.insertById(Person.class).one(person); } public void update(Person person) { person.setUpdated(DateTime.now()); - template.update(person); + template.removeById(Person.class).oneEntity(person); } public void delete(Person person) { - template.remove(person); + template.removeById(Person.class).oneEntity(person); } } diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/StudentRepositoryService.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/StudentRepositoryService.java index ff9657260a..8a49ae075c 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/StudentRepositoryService.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/StudentRepositoryService.java @@ -3,6 +3,7 @@ package com.baeldung.spring.data.couchbase.service; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Optional; import com.baeldung.spring.data.couchbase.model.Student; import com.baeldung.spring.data.couchbase.repos.StudentRepository; @@ -22,12 +23,12 @@ public class StudentRepositoryService implements StudentService { this.repo = repo; } - public Student findOne(String id) { - return repo.findOne(id); + public Optional findOne(String id) { + return repo.findById(id); } public List findAll() { - List people = new ArrayList(); + List people = new ArrayList<>(); Iterator it = repo.findAll().iterator(); while (it.hasNext()) { people.add(it.next()); diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/StudentService.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/StudentService.java index aa99a770cd..c3512794bd 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/StudentService.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/StudentService.java @@ -1,12 +1,13 @@ package com.baeldung.spring.data.couchbase.service; import java.util.List; +import java.util.Optional; import com.baeldung.spring.data.couchbase.model.Student; public interface StudentService { - Student findOne(String id); + Optional findOne(String id); List findAll(); diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/StudentTemplateService.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/StudentTemplateService.java index 9110f68276..59115a2149 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/StudentTemplateService.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase/service/StudentTemplateService.java @@ -1,6 +1,9 @@ package com.baeldung.spring.data.couchbase.service; +import static org.springframework.data.couchbase.core.query.QueryCriteria.where; + import java.util.List; +import java.util.Optional; import com.baeldung.spring.data.couchbase.model.Student; import org.joda.time.DateTime; @@ -9,8 +12,6 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.couchbase.core.CouchbaseTemplate; import org.springframework.stereotype.Service; -import com.couchbase.client.java.view.ViewQuery; - @Service @Qualifier("StudentTemplateService") public class StudentTemplateService implements StudentService { @@ -24,33 +25,33 @@ public class StudentTemplateService implements StudentService { this.template = template; } - public Student findOne(String id) { - return template.findById(id, Student.class); + public Optional findOne(String id) { + return Optional.of(template.findById(Student.class).one(id)); } public List findAll() { - return template.findByView(ViewQuery.from(DESIGN_DOC, "all"), Student.class); + return template.findByQuery(Student.class).all(); } public List findByFirstName(String firstName) { - return template.findByView(ViewQuery.from(DESIGN_DOC, "byFirstName"), Student.class); + return template.findByQuery(Student.class).matching(where("firstName").is(firstName)).all(); } public List findByLastName(String lastName) { - return template.findByView(ViewQuery.from(DESIGN_DOC, "byLastName"), Student.class); + return template.findByQuery(Student.class).matching(where("lastName").is(lastName)).all(); } public void create(Student student) { student.setCreated(DateTime.now()); - template.insert(student); + template.insertById(Student.class).one(student); } public void update(Student student) { student.setUpdated(DateTime.now()); - template.update(student); + template.upsertById(Student.class).one(student); } public void delete(Student student) { - template.remove(student); + template.removeById(Student.class).oneEntity(student); } } diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/CampusService.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/CampusService.java index 567ffa2a7f..6777fe4d95 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/CampusService.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/CampusService.java @@ -1,5 +1,6 @@ package com.baeldung.spring.data.couchbase2b.service; +import java.util.Optional; import java.util.Set; import com.baeldung.spring.data.couchbase.model.Campus; @@ -8,7 +9,7 @@ import org.springframework.data.geo.Point; public interface CampusService { - Campus find(String id); + Optional find(String id); Set findByName(String name); diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/CampusServiceImpl.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/CampusServiceImpl.java index 03e2dced1b..9668da29e3 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/CampusServiceImpl.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/CampusServiceImpl.java @@ -2,6 +2,7 @@ package com.baeldung.spring.data.couchbase2b.service; import java.util.HashSet; import java.util.Iterator; +import java.util.Optional; import java.util.Set; import com.baeldung.spring.data.couchbase2b.repos.CampusRepository; @@ -22,8 +23,8 @@ public class CampusServiceImpl implements CampusService { } @Override - public Campus find(String id) { - return repo.findOne(id); + public Optional find(String id) { + return repo.findById(id); } @Override diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/PersonService.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/PersonService.java index 7dc30ead11..1e7091bdf4 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/PersonService.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/PersonService.java @@ -1,12 +1,13 @@ package com.baeldung.spring.data.couchbase2b.service; import java.util.List; +import java.util.Optional; import com.baeldung.spring.data.couchbase.model.Person; public interface PersonService { - Person findOne(String id); + Optional findOne(String id); List findAll(); diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/PersonServiceImpl.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/PersonServiceImpl.java index af08bd4ca8..bc6c5f2673 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/PersonServiceImpl.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/PersonServiceImpl.java @@ -3,6 +3,7 @@ package com.baeldung.spring.data.couchbase2b.service; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Optional; import com.baeldung.spring.data.couchbase2b.repos.PersonRepository; import com.baeldung.spring.data.couchbase.model.Person; @@ -20,12 +21,12 @@ public class PersonServiceImpl implements PersonService { this.repo = repo; } - public Person findOne(String id) { - return repo.findOne(id); + public Optional findOne(String id) { + return repo.findById(id); } public List findAll() { - List people = new ArrayList(); + List people = new ArrayList<>(); Iterator it = repo.findAll().iterator(); while (it.hasNext()) { people.add(it.next()); diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/StudentService.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/StudentService.java index 3f318e1af1..7c408f4c75 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/StudentService.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/StudentService.java @@ -1,12 +1,13 @@ package com.baeldung.spring.data.couchbase2b.service; import java.util.List; +import java.util.Optional; import com.baeldung.spring.data.couchbase.model.Student; public interface StudentService { - Student findOne(String id); + Optional findOne(String id); List findAll(); diff --git a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/StudentServiceImpl.java b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/StudentServiceImpl.java index 53feaead10..f2889e8caa 100644 --- a/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/StudentServiceImpl.java +++ b/persistence-modules/spring-data-couchbase-2/src/main/java/com/baeldung/spring/data/couchbase2b/service/StudentServiceImpl.java @@ -3,6 +3,7 @@ package com.baeldung.spring.data.couchbase2b.service; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Optional; import com.baeldung.spring.data.couchbase2b.repos.StudentRepository; import com.baeldung.spring.data.couchbase.model.Student; @@ -20,12 +21,12 @@ public class StudentServiceImpl implements StudentService { this.repo = repo; } - public Student findOne(String id) { - return repo.findOne(id); + public Optional findOne(String id) { + return repo.findById(id); } public List findAll() { - List people = new ArrayList(); + List people = new ArrayList<>(); Iterator it = repo.findAll().iterator(); while (it.hasNext()) { people.add(it.next()); diff --git a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/CustomTypeKeyCouchbaseConfig.java b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/CustomTypeKeyCouchbaseConfig.java index 403c012194..eacecb4e1e 100644 --- a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/CustomTypeKeyCouchbaseConfig.java +++ b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/CustomTypeKeyCouchbaseConfig.java @@ -4,6 +4,21 @@ import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter public class CustomTypeKeyCouchbaseConfig extends MyCouchbaseConfig { + @Override + public String getConnectionString() { + return NODE_LIST; + } + + @Override + public String getUserName() { + return BUCKET_USERNAME; + } + + @Override + public String getPassword() { + return BUCKET_PASSWORD; + } + @Override public String typeKey() { return MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE; diff --git a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/MyCouchbaseConfig.java b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/MyCouchbaseConfig.java index 5a2180f4b8..5412afb493 100644 --- a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/MyCouchbaseConfig.java +++ b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/MyCouchbaseConfig.java @@ -1,42 +1,46 @@ package com.baeldung.spring.data.couchbase; -import java.util.Arrays; -import java.util.List; - import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration; import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener; -import org.springframework.data.couchbase.core.query.Consistency; import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; +import com.couchbase.client.java.query.QueryScanConsistency; + @Configuration @EnableCouchbaseRepositories(basePackages = { "com.baeldung.spring.data.couchbase" }) public class MyCouchbaseConfig extends AbstractCouchbaseConfiguration { - public static final List NODE_LIST = Arrays.asList("localhost"); + public static final String NODE_LIST = "localhost"; public static final String BUCKET_NAME = "baeldung"; - public static final String BUCKET_PASSWORD = ""; + public static final String BUCKET_USERNAME = "baeldung"; + public static final String BUCKET_PASSWORD = "baeldung"; @Override - protected List getBootstrapHosts() { + public String getConnectionString() { return NODE_LIST; } @Override - protected String getBucketName() { - return BUCKET_NAME; + public String getUserName() { + return BUCKET_USERNAME; } @Override - protected String getBucketPassword() { + public String getPassword() { return BUCKET_PASSWORD; } @Override - protected Consistency getDefaultConsistency() { - return Consistency.READ_YOUR_OWN_WRITES; + public String getBucketName() { + return BUCKET_NAME; + } + + @Override + public QueryScanConsistency getDefaultConsistency() { + return QueryScanConsistency.REQUEST_PLUS; } @Bean diff --git a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/ReadYourOwnWritesCouchbaseConfig.java b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/ReadYourOwnWritesCouchbaseConfig.java index b989bb39d8..33a6c4f091 100644 --- a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/ReadYourOwnWritesCouchbaseConfig.java +++ b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/ReadYourOwnWritesCouchbaseConfig.java @@ -1,11 +1,11 @@ package com.baeldung.spring.data.couchbase; -import org.springframework.data.couchbase.core.query.Consistency; +import com.couchbase.client.java.query.QueryScanConsistency; public class ReadYourOwnWritesCouchbaseConfig extends MyCouchbaseConfig { @Override - public Consistency getDefaultConsistency() { - return Consistency.READ_YOUR_OWN_WRITES; + public QueryScanConsistency getDefaultConsistency() { + return QueryScanConsistency.REQUEST_PLUS; } } diff --git a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/service/PersonServiceLiveTest.java b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/service/PersonServiceLiveTest.java index 804bbdd2c8..0275587ac3 100644 --- a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/service/PersonServiceLiveTest.java +++ b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/service/PersonServiceLiveTest.java @@ -1,11 +1,15 @@ package com.baeldung.spring.data.couchbase.service; +import static com.baeldung.spring.data.couchbase.MyCouchbaseConfig.BUCKET_PASSWORD; +import static com.baeldung.spring.data.couchbase.MyCouchbaseConfig.BUCKET_USERNAME; +import static com.baeldung.spring.data.couchbase.MyCouchbaseConfig.NODE_LIST; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.List; +import java.util.Optional; import com.baeldung.spring.data.couchbase.IntegrationTest; import com.baeldung.spring.data.couchbase.MyCouchbaseConfig; @@ -16,9 +20,8 @@ import org.junit.Test; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; -import com.couchbase.client.java.CouchbaseCluster; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.json.JsonObject; +import com.couchbase.client.java.Collection; +import com.couchbase.client.java.json.JsonObject; public abstract class PersonServiceLiveTest extends IntegrationTest { @@ -27,32 +30,32 @@ public abstract class PersonServiceLiveTest extends IntegrationTest { static final String smith = "Smith"; static final String johnSmithId = "person:" + john + ":" + smith; static final Person johnSmith = new Person(johnSmithId, john, smith); - static final JsonObject jsonJohnSmith = JsonObject.empty().put(typeField, Person.class.getName()).put("firstName", john).put("lastName", smith).put("created", DateTime.now().getMillis()); + static final JsonObject jsonJohnSmith = JsonObject.create().put(typeField, Person.class.getName()).put("firstName", john).put("lastName", smith).put("created", DateTime.now().getMillis()); static final String foo = "Foo"; static final String bar = "Bar"; static final String foobarId = "person:" + foo + ":" + bar; static final Person foobar = new Person(foobarId, foo, bar); - static final JsonObject jsonFooBar = JsonObject.empty().put(typeField, Person.class.getName()).put("firstName", foo).put("lastName", bar).put("created", DateTime.now().getMillis()); + static final JsonObject jsonFooBar = JsonObject.create().put(typeField, Person.class.getName()).put("firstName", foo).put("lastName", bar).put("created", DateTime.now().getMillis()); PersonService personService; @BeforeClass public static void setupBeforeClass() { - final Cluster cluster = CouchbaseCluster.create(MyCouchbaseConfig.NODE_LIST); - final Bucket bucket = cluster.openBucket(MyCouchbaseConfig.BUCKET_NAME, MyCouchbaseConfig.BUCKET_PASSWORD); - bucket.upsert(JsonDocument.create(johnSmithId, jsonJohnSmith)); - bucket.upsert(JsonDocument.create(foobarId, jsonFooBar)); - bucket.close(); + final Cluster cluster = Cluster.connect(NODE_LIST, BUCKET_USERNAME, BUCKET_PASSWORD); + final Bucket bucket = cluster.bucket(MyCouchbaseConfig.BUCKET_NAME); + final Collection collection = bucket.defaultCollection(); + collection.upsert(johnSmithId, JsonObject.create().put(johnSmithId, jsonJohnSmith)); + collection.upsert(foobarId, JsonObject.create().put(foobarId, jsonFooBar)); cluster.disconnect(); } @Test public void whenFindingPersonByJohnSmithId_thenReturnsJohnSmith() { - final Person actualPerson = personService.findOne(johnSmithId); - assertNotNull(actualPerson); - assertNotNull(actualPerson.getCreated()); - assertEquals(johnSmith, actualPerson); + final Optional actualPerson = personService.findOne(johnSmithId); + assertTrue(actualPerson.isPresent()); + assertNotNull(actualPerson.get().getCreated()); + assertEquals(johnSmith, actualPerson.get()); } @Test diff --git a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/service/StudentServiceLiveTest.java b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/service/StudentServiceLiveTest.java index c13b4930ca..a502d46124 100644 --- a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/service/StudentServiceLiveTest.java +++ b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase/service/StudentServiceLiveTest.java @@ -1,13 +1,17 @@ package com.baeldung.spring.data.couchbase.service; +import static com.baeldung.spring.data.couchbase.MyCouchbaseConfig.BUCKET_PASSWORD; +import static com.baeldung.spring.data.couchbase.MyCouchbaseConfig.BUCKET_USERNAME; +import static com.baeldung.spring.data.couchbase.MyCouchbaseConfig.NODE_LIST; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.List; +import java.util.Optional; -import javax.validation.ConstraintViolationException; +import jakarta.validation.ConstraintViolationException; import com.baeldung.spring.data.couchbase.IntegrationTest; import com.baeldung.spring.data.couchbase.MyCouchbaseConfig; @@ -18,9 +22,8 @@ import org.junit.Test; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; -import com.couchbase.client.java.CouchbaseCluster; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.json.JsonObject; +import com.couchbase.client.java.Collection; +import com.couchbase.client.java.json.JsonObject; public abstract class StudentServiceLiveTest extends IntegrationTest { @@ -30,24 +33,24 @@ public abstract class StudentServiceLiveTest extends IntegrationTest { static final String joeCollegeId = "student:" + joe + ":" + college; static final DateTime joeCollegeDob = DateTime.now().minusYears(21); static final Student joeCollege = new Student(joeCollegeId, joe, college, joeCollegeDob); - static final JsonObject jsonJoeCollege = JsonObject.empty().put(typeField, Student.class.getName()).put("firstName", joe).put("lastName", college).put("created", DateTime.now().getMillis()).put("version", 1); + static final JsonObject jsonJoeCollege = JsonObject.create().put(typeField, Student.class.getName()).put("firstName", joe).put("lastName", college).put("created", DateTime.now().getMillis()).put("version", 1); static final String judy = "Judy"; static final String jetson = "Jetson"; static final String judyJetsonId = "student:" + judy + ":" + jetson; static final DateTime judyJetsonDob = DateTime.now().minusYears(19).minusMonths(5).minusDays(3); static final Student judyJetson = new Student(judyJetsonId, judy, jetson, judyJetsonDob); - static final JsonObject jsonJudyJetson = JsonObject.empty().put(typeField, Student.class.getName()).put("firstName", judy).put("lastName", jetson).put("created", DateTime.now().getMillis()).put("version", 1); + static final JsonObject jsonJudyJetson = JsonObject.create().put(typeField, Student.class.getName()).put("firstName", judy).put("lastName", jetson).put("created", DateTime.now().getMillis()).put("version", 1); StudentService studentService; @BeforeClass public static void setupBeforeClass() { - Cluster cluster = CouchbaseCluster.create(MyCouchbaseConfig.NODE_LIST); - Bucket bucket = cluster.openBucket(MyCouchbaseConfig.BUCKET_NAME, MyCouchbaseConfig.BUCKET_PASSWORD); - bucket.upsert(JsonDocument.create(joeCollegeId, jsonJoeCollege)); - bucket.upsert(JsonDocument.create(judyJetsonId, jsonJudyJetson)); - bucket.close(); + final Cluster cluster = Cluster.connect(NODE_LIST, BUCKET_USERNAME, BUCKET_PASSWORD); + final Bucket bucket = cluster.bucket(MyCouchbaseConfig.BUCKET_NAME); + final Collection collection = bucket.defaultCollection(); + collection.upsert(joeCollegeId, JsonObject.create().put(joeCollegeId, jsonJoeCollege)); + collection.upsert(judyJetsonId, JsonObject.create().put(judyJetsonId, jsonJudyJetson)); cluster.disconnect(); } @@ -59,10 +62,10 @@ public abstract class StudentServiceLiveTest extends IntegrationTest { String id = "student:" + firstName + ":" + lastName; Student expectedStudent = new Student(id, firstName, lastName, dateOfBirth); studentService.create(expectedStudent); - Student actualStudent = studentService.findOne(id); - assertNotNull(actualStudent.getCreated()); - assertNotNull(actualStudent); - assertEquals(expectedStudent.getId(), actualStudent.getId()); + Optional actualStudent = studentService.findOne(id); + assertTrue(actualStudent.isPresent()); + assertNotNull(actualStudent.get().getCreated()); + assertEquals(expectedStudent.getId(), actualStudent.get().getId()); } @Test(expected = ConstraintViolationException.class) @@ -87,10 +90,10 @@ public abstract class StudentServiceLiveTest extends IntegrationTest { @Test public void whenFindingStudentByJohnSmithId_thenReturnsJohnSmith() { - Student actualStudent = studentService.findOne(joeCollegeId); - assertNotNull(actualStudent); - assertNotNull(actualStudent.getCreated()); - assertEquals(joeCollegeId, actualStudent.getId()); + Optional actualStudent = studentService.findOne(joeCollegeId); + assertTrue(actualStudent.isPresent()); + assertNotNull(actualStudent.get().getCreated()); + assertEquals(joeCollegeId, actualStudent.get().getId()); } @Test diff --git a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/MultiBucketCouchbaseConfig.java b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/MultiBucketCouchbaseConfig.java index 488819aaf5..bfa422037f 100644 --- a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/MultiBucketCouchbaseConfig.java +++ b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/MultiBucketCouchbaseConfig.java @@ -1,54 +1,47 @@ package com.baeldung.spring.data.couchbase2b; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import com.baeldung.spring.data.couchbase.model.Campus; + +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.data.couchbase.SimpleCouchbaseClientFactory; import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration; import org.springframework.data.couchbase.core.CouchbaseTemplate; +import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter; import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener; -import org.springframework.data.couchbase.core.query.Consistency; import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories; import org.springframework.data.couchbase.repository.config.RepositoryOperationsMapping; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; +import com.couchbase.client.core.env.PasswordAuthenticator; import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.env.ClusterEnvironment; @Configuration @EnableCouchbaseRepositories(basePackages = { "com.baeldung.spring.data.couchbase2b" }) public class MultiBucketCouchbaseConfig extends AbstractCouchbaseConfiguration { - public static final List NODE_LIST = Arrays.asList("localhost"); + public static final String NODE_LIST = "localhost"; public static final String DEFAULT_BUCKET_NAME = "baeldung"; - public static final String DEFAULT_BUCKET_PASSWORD = ""; + public static final String DEFAULT_BUCKET_USERNAME = "baeldung"; + public static final String DEFAULT_BUCKET_PASSWORD = "baeldung"; - @Override - protected List getBootstrapHosts() { - return NODE_LIST; - } - - @Override - protected String getBucketName() { - return DEFAULT_BUCKET_NAME; - } - - @Override - protected String getBucketPassword() { - return DEFAULT_BUCKET_PASSWORD; - } + @Autowired + private MappingCouchbaseConverter mappingCouchbaseConverter; @Bean - public Bucket campusBucket() throws Exception { - return couchbaseCluster().openBucket("baeldung2", ""); + public Bucket campusBucket() { + return couchbaseCluster(ClusterEnvironment.create()).bucket("baeldung2"); } @Bean(name = "campusTemplate") - public CouchbaseTemplate campusTemplate() throws Exception { - CouchbaseTemplate template = new CouchbaseTemplate(couchbaseClusterInfo(), campusBucket(), mappingCouchbaseConverter(), translationService()); - template.setDefaultConsistency(getDefaultConsistency()); - return template; + public CouchbaseTemplate campusTemplate() { + return new CouchbaseTemplate(new SimpleCouchbaseClientFactory(NODE_LIST, + PasswordAuthenticator.create(DEFAULT_BUCKET_USERNAME, DEFAULT_BUCKET_PASSWORD), DEFAULT_BUCKET_NAME), mappingCouchbaseConverter); } @Override @@ -60,11 +53,6 @@ public class MultiBucketCouchbaseConfig extends AbstractCouchbaseConfiguration { } } - @Override - protected Consistency getDefaultConsistency() { - return Consistency.READ_YOUR_OWN_WRITES; - } - @Bean public LocalValidatorFactoryBean localValidatorFactoryBean() { return new LocalValidatorFactoryBean(); @@ -74,4 +62,24 @@ public class MultiBucketCouchbaseConfig extends AbstractCouchbaseConfiguration { public ValidatingCouchbaseEventListener validatingCouchbaseEventListener() { return new ValidatingCouchbaseEventListener(localValidatorFactoryBean()); } + + @Override + public String getConnectionString() { + return NODE_LIST; + } + + @Override + public String getUserName() { + return DEFAULT_BUCKET_USERNAME; + } + + @Override + public String getPassword() { + return DEFAULT_BUCKET_PASSWORD; + } + + @Override + public String getBucketName() { + return DEFAULT_BUCKET_NAME; + } } diff --git a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/service/CampusServiceImplLiveTest.java b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/service/CampusServiceImplLiveTest.java index e94c09e6cd..08adbfd016 100644 --- a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/service/CampusServiceImplLiveTest.java +++ b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/service/CampusServiceImplLiveTest.java @@ -5,9 +5,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import java.util.Optional; import java.util.Set; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import com.baeldung.spring.data.couchbase.model.Campus; import com.baeldung.spring.data.couchbase2b.MultiBucketLiveTest; @@ -46,7 +47,7 @@ public class CampusServiceImplLiveTest extends MultiBucketLiveTest { private final Point NewYorkCity = new Point(74.0059, 40.7128); @PostConstruct - private void loadCampuses() throws Exception { + private void loadCampuses() { campusRepo.save(Brown); campusRepo.save(Columbia); campusRepo.save(Cornell); @@ -58,7 +59,7 @@ public class CampusServiceImplLiveTest extends MultiBucketLiveTest { } @Test - public final void givenNameHarvard_whenFindByName_thenReturnsHarvard() throws Exception { + public final void givenNameHarvard_whenFindByName_thenReturnsHarvard() { Set campuses = campusService.findByName(Harvard.getName()); assertNotNull(campuses); assertFalse(campuses.isEmpty()); @@ -67,14 +68,14 @@ public class CampusServiceImplLiveTest extends MultiBucketLiveTest { } @Test - public final void givenHarvardId_whenFind_thenReturnsHarvard() throws Exception { - Campus actual = campusService.find(Harvard.getId()); - assertNotNull(actual); - assertEquals(Harvard, actual); + public final void givenHarvardId_whenFind_thenReturnsHarvard() { + Optional actual = campusService.find(Harvard.getId()); + assertTrue(actual.isPresent()); + assertEquals(Harvard, actual.get()); } @Test - public final void whenFindAll_thenReturnsAll() throws Exception { + public final void whenFindAll_thenReturnsAll() { Set campuses = campusService.findAll(); assertTrue(campuses.contains(Brown)); assertTrue(campuses.contains(Columbia)); @@ -87,7 +88,7 @@ public class CampusServiceImplLiveTest extends MultiBucketLiveTest { } @Test - public final void whenFindByLocationNearBoston_thenResultContainsHarvard() throws Exception { + public final void whenFindByLocationNearBoston_thenResultContainsHarvard() { Set campuses = campusService.findByLocationNear(Boston, new Distance(1, Metrics.NEUTRAL)); assertFalse(campuses.isEmpty()); assertTrue(campuses.contains(Harvard)); @@ -95,7 +96,7 @@ public class CampusServiceImplLiveTest extends MultiBucketLiveTest { } @Test - public final void whenFindByLocationNearNewYorkCity_thenResultContainsColumbia() throws Exception { + public final void whenFindByLocationNearNewYorkCity_thenResultContainsColumbia() { Set campuses = campusService.findByLocationNear(NewYorkCity, new Distance(1, Metrics.NEUTRAL)); assertFalse(campuses.isEmpty()); assertTrue(campuses.contains(Columbia)); diff --git a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/service/PersonServiceImplLiveTest.java b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/service/PersonServiceImplLiveTest.java index 3f98c1950a..28477e9d14 100644 --- a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/service/PersonServiceImplLiveTest.java +++ b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/service/PersonServiceImplLiveTest.java @@ -1,11 +1,15 @@ package com.baeldung.spring.data.couchbase2b.service; +import static com.baeldung.spring.data.couchbase2b.MultiBucketCouchbaseConfig.DEFAULT_BUCKET_PASSWORD; +import static com.baeldung.spring.data.couchbase2b.MultiBucketCouchbaseConfig.DEFAULT_BUCKET_USERNAME; +import static com.baeldung.spring.data.couchbase2b.MultiBucketCouchbaseConfig.NODE_LIST; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.List; +import java.util.Optional; import com.baeldung.spring.data.couchbase.model.Person; import com.baeldung.spring.data.couchbase2b.MultiBucketLiveTest; @@ -17,9 +21,8 @@ import org.springframework.beans.factory.annotation.Autowired; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; -import com.couchbase.client.java.CouchbaseCluster; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.json.JsonObject; +import com.couchbase.client.java.Collection; +import com.couchbase.client.java.json.JsonObject; public class PersonServiceImplLiveTest extends MultiBucketLiveTest { @@ -28,33 +31,33 @@ public class PersonServiceImplLiveTest extends MultiBucketLiveTest { static final String smith = "Smith"; static final String johnSmithId = "person:" + john + ":" + smith; static final Person johnSmith = new Person(johnSmithId, john, smith); - static final JsonObject jsonJohnSmith = JsonObject.empty().put(typeField, Person.class.getName()).put("firstName", john).put("lastName", smith).put("created", DateTime.now().getMillis()); + static final JsonObject jsonJohnSmith = JsonObject.create().put(typeField, Person.class.getName()).put("firstName", john).put("lastName", smith).put("created", DateTime.now().getMillis()); static final String foo = "Foo"; static final String bar = "Bar"; static final String foobarId = "person:" + foo + ":" + bar; static final Person foobar = new Person(foobarId, foo, bar); - static final JsonObject jsonFooBar = JsonObject.empty().put(typeField, Person.class.getName()).put("firstName", foo).put("lastName", bar).put("created", DateTime.now().getMillis()); + static final JsonObject jsonFooBar = JsonObject.create().put(typeField, Person.class.getName()).put("firstName", foo).put("lastName", bar).put("created", DateTime.now().getMillis()); @Autowired private PersonServiceImpl personService; @BeforeClass public static void setupBeforeClass() { - final Cluster cluster = CouchbaseCluster.create(MultiBucketCouchbaseConfig.NODE_LIST); - final Bucket bucket = cluster.openBucket(MultiBucketCouchbaseConfig.DEFAULT_BUCKET_NAME, MultiBucketCouchbaseConfig.DEFAULT_BUCKET_PASSWORD); - bucket.upsert(JsonDocument.create(johnSmithId, jsonJohnSmith)); - bucket.upsert(JsonDocument.create(foobarId, jsonFooBar)); - bucket.close(); + final Cluster cluster = Cluster.connect(NODE_LIST, DEFAULT_BUCKET_USERNAME, DEFAULT_BUCKET_PASSWORD); + final Bucket bucket = cluster.bucket(MultiBucketCouchbaseConfig.DEFAULT_BUCKET_NAME); + final Collection collection = bucket.defaultCollection(); + collection.upsert(johnSmithId, JsonObject.create().put(johnSmithId, jsonJohnSmith)); + collection.upsert(foobarId, JsonObject.create().put(foobarId, jsonFooBar)); cluster.disconnect(); } @Test public void whenFindingPersonByJohnSmithId_thenReturnsJohnSmith() { - final Person actualPerson = personService.findOne(johnSmithId); - assertNotNull(actualPerson); - assertNotNull(actualPerson.getCreated()); - assertEquals(johnSmith, actualPerson); + final Optional actualPerson = personService.findOne(johnSmithId); + assertTrue(actualPerson.isPresent()); + assertNotNull(actualPerson.get().getCreated()); + assertEquals(johnSmith, actualPerson.get()); } @Test diff --git a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/service/StudentServiceImplLiveTest.java b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/service/StudentServiceImplLiveTest.java index 004258a37e..98cbd39788 100644 --- a/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/service/StudentServiceImplLiveTest.java +++ b/persistence-modules/spring-data-couchbase-2/src/test/java/com/baeldung/spring/data/couchbase2b/service/StudentServiceImplLiveTest.java @@ -1,13 +1,17 @@ package com.baeldung.spring.data.couchbase2b.service; +import static com.baeldung.spring.data.couchbase2b.MultiBucketCouchbaseConfig.DEFAULT_BUCKET_PASSWORD; +import static com.baeldung.spring.data.couchbase2b.MultiBucketCouchbaseConfig.DEFAULT_BUCKET_USERNAME; +import static com.baeldung.spring.data.couchbase2b.MultiBucketCouchbaseConfig.NODE_LIST; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.List; +import java.util.Optional; -import javax.validation.ConstraintViolationException; +import jakarta.validation.ConstraintViolationException; import com.baeldung.spring.data.couchbase.model.Student; import com.baeldung.spring.data.couchbase2b.MultiBucketCouchbaseConfig; @@ -19,9 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; -import com.couchbase.client.java.CouchbaseCluster; -import com.couchbase.client.java.document.JsonDocument; -import com.couchbase.client.java.document.json.JsonObject; +import com.couchbase.client.java.Collection; +import com.couchbase.client.java.json.JsonObject; public class StudentServiceImplLiveTest extends MultiBucketLiveTest { @@ -31,25 +34,25 @@ public class StudentServiceImplLiveTest extends MultiBucketLiveTest { static final String joeCollegeId = "student:" + joe + ":" + college; static final DateTime joeCollegeDob = DateTime.now().minusYears(21); static final Student joeCollege = new Student(joeCollegeId, joe, college, joeCollegeDob); - static final JsonObject jsonJoeCollege = JsonObject.empty().put(typeField, Student.class.getName()).put("firstName", joe).put("lastName", college).put("created", DateTime.now().getMillis()).put("version", 1); + static final JsonObject jsonJoeCollege = JsonObject.create().put(typeField, Student.class.getName()).put("firstName", joe).put("lastName", college).put("created", DateTime.now().getMillis()).put("version", 1); static final String judy = "Judy"; static final String jetson = "Jetson"; static final String judyJetsonId = "student:" + judy + ":" + jetson; static final DateTime judyJetsonDob = DateTime.now().minusYears(19).minusMonths(5).minusDays(3); static final Student judyJetson = new Student(judyJetsonId, judy, jetson, judyJetsonDob); - static final JsonObject jsonJudyJetson = JsonObject.empty().put(typeField, Student.class.getName()).put("firstName", judy).put("lastName", jetson).put("created", DateTime.now().getMillis()).put("version", 1); + static final JsonObject jsonJudyJetson = JsonObject.create().put(typeField, Student.class.getName()).put("firstName", judy).put("lastName", jetson).put("created", DateTime.now().getMillis()).put("version", 1); @Autowired StudentServiceImpl studentService; @BeforeClass public static void setupBeforeClass() { - Cluster cluster = CouchbaseCluster.create(MultiBucketCouchbaseConfig.NODE_LIST); - Bucket bucket = cluster.openBucket(MultiBucketCouchbaseConfig.DEFAULT_BUCKET_NAME, MultiBucketCouchbaseConfig.DEFAULT_BUCKET_PASSWORD); - bucket.upsert(JsonDocument.create(joeCollegeId, jsonJoeCollege)); - bucket.upsert(JsonDocument.create(judyJetsonId, jsonJudyJetson)); - bucket.close(); + Cluster cluster = Cluster.connect(NODE_LIST, DEFAULT_BUCKET_USERNAME, DEFAULT_BUCKET_PASSWORD); + Bucket bucket = cluster.bucket(MultiBucketCouchbaseConfig.DEFAULT_BUCKET_NAME); + final Collection collection = bucket.defaultCollection(); + collection.upsert(joeCollegeId, JsonObject.create().put(joeCollegeId, jsonJoeCollege)); + collection.upsert(judyJetsonId, JsonObject.create().put(judyJetsonId, jsonJudyJetson)); cluster.disconnect(); } @@ -61,10 +64,10 @@ public class StudentServiceImplLiveTest extends MultiBucketLiveTest { String id = "student:" + firstName + ":" + lastName; Student expectedStudent = new Student(id, firstName, lastName, dateOfBirth); studentService.create(expectedStudent); - Student actualStudent = studentService.findOne(id); - assertNotNull(actualStudent.getCreated()); - assertNotNull(actualStudent); - assertEquals(expectedStudent.getId(), actualStudent.getId()); + Optional actualStudent = studentService.findOne(id); + assertTrue(actualStudent.isPresent()); + assertNotNull(actualStudent.get().getCreated()); + assertEquals(expectedStudent.getId(), actualStudent.get().getId()); } @Test(expected = ConstraintViolationException.class) @@ -89,10 +92,10 @@ public class StudentServiceImplLiveTest extends MultiBucketLiveTest { @Test public void whenFindingStudentByJohnSmithId_thenReturnsJohnSmith() { - Student actualStudent = studentService.findOne(joeCollegeId); - assertNotNull(actualStudent); - assertNotNull(actualStudent.getCreated()); - assertEquals(joeCollegeId, actualStudent.getId()); + Optional actualStudent = studentService.findOne(joeCollegeId); + assertTrue(actualStudent.isPresent()); + assertNotNull(actualStudent.get().getCreated()); + assertEquals(joeCollegeId, actualStudent.get().getId()); } @Test diff --git a/persistence-modules/spring-data-eclipselink/pom.xml b/persistence-modules/spring-data-eclipselink/pom.xml index c3c530d2d7..34d8a1a6f8 100644 --- a/persistence-modules/spring-data-eclipselink/pom.xml +++ b/persistence-modules/spring-data-eclipselink/pom.xml @@ -64,9 +64,11 @@ - 1.5.9.RELEASE - 2.7.0 + 3.0.4 + 4.0.1 2.1.214 + 2.0.7 + 1.4.6 \ No newline at end of file diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/JpaConfiguration.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/JpaConfiguration.java index 60ff7909be..4d3f3aa8fc 100644 --- a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/JpaConfiguration.java +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/JpaConfiguration.java @@ -21,8 +21,8 @@ import java.util.Map; @Configuration public class JpaConfiguration extends JpaBaseConfiguration { - protected JpaConfiguration(DataSource dataSource, JpaProperties properties, ObjectProvider jtaTransactionManager, ObjectProvider transactionManagerCustomizers) { - super(dataSource, properties, jtaTransactionManager, transactionManagerCustomizers); + protected JpaConfiguration(DataSource dataSource, JpaProperties properties, ObjectProvider jtaTransactionManager) { + super(dataSource, properties, jtaTransactionManager); } @Override diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/model/Person.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/model/Person.java index 75161875bd..cc4956e2fc 100644 --- a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/model/Person.java +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/model/Person.java @@ -1,9 +1,9 @@ package com.baeldung.eclipselink.springdata.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; /** * Created by adam. diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Address.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Address.java index b62889208c..474926977c 100644 --- a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Address.java +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Address.java @@ -1,6 +1,6 @@ package com.baeldung.eclipselink.springdata.pessimisticlocking; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; @Embeddable public class Address { diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Course.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Course.java index 8d90659f3e..97b0f612d3 100644 --- a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Course.java +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Course.java @@ -1,9 +1,9 @@ package com.baeldung.eclipselink.springdata.pessimisticlocking; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.JoinTable; -import javax.persistence.ManyToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToOne; @Entity public class Course { diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Customer.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Customer.java index f06a676de8..c2689a25a7 100644 --- a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Customer.java +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Customer.java @@ -1,9 +1,9 @@ package com.baeldung.eclipselink.springdata.pessimisticlocking; -import javax.persistence.CollectionTable; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.CollectionTable; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; import java.util.List; @Entity diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Employee.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Employee.java index d09b123225..67c8fbf660 100644 --- a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Employee.java +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Employee.java @@ -1,6 +1,6 @@ package com.baeldung.eclipselink.springdata.pessimisticlocking; -import javax.persistence.Entity; +import jakarta.persistence.Entity; import java.math.BigDecimal; @Entity diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Individual.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Individual.java index 7edaaace54..05fd7a890d 100644 --- a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Individual.java +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Individual.java @@ -1,9 +1,9 @@ package com.baeldung.eclipselink.springdata.pessimisticlocking; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Inheritance; -import javax.persistence.InheritanceType; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; @Entity @Inheritance(strategy = InheritanceType.JOINED) diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Student.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Student.java index f613aab0f6..f8db1179fc 100644 --- a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Student.java +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Student.java @@ -1,8 +1,8 @@ package com.baeldung.eclipselink.springdata.pessimisticlocking; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.OneToMany; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; import java.util.List; @Entity diff --git a/persistence-modules/spring-data-eclipselink/src/test/java/com/baeldung/eclipselink/springdata/pessimisticlocking/PessimisticLockScopesIntegrationTest.java b/persistence-modules/spring-data-eclipselink/src/test/java/com/baeldung/eclipselink/springdata/pessimisticlocking/PessimisticLockScopesIntegrationTest.java index 6ee40fac9a..596229fc2d 100644 --- a/persistence-modules/spring-data-eclipselink/src/test/java/com/baeldung/eclipselink/springdata/pessimisticlocking/PessimisticLockScopesIntegrationTest.java +++ b/persistence-modules/spring-data-eclipselink/src/test/java/com/baeldung/eclipselink/springdata/pessimisticlocking/PessimisticLockScopesIntegrationTest.java @@ -1,14 +1,12 @@ package com.baeldung.eclipselink.springdata.pessimisticlocking; -import org.junit.Assert; -import org.junit.BeforeClass; 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.test.context.junit4.SpringRunner; -import javax.persistence.*; +import jakarta.persistence.*; import java.math.BigDecimal; import java.util.Arrays; import java.util.HashMap; diff --git a/persistence-modules/spring-data-jpa-annotations/README.md b/persistence-modules/spring-data-jpa-annotations/README.md index 5a5440b1ed..d7e6189ae5 100644 --- a/persistence-modules/spring-data-jpa-annotations/README.md +++ b/persistence-modules/spring-data-jpa-annotations/README.md @@ -10,6 +10,7 @@ This module contains articles about annotations used in Spring Data JPA - [Programmatic Transaction Management in Spring](https://www.baeldung.com/spring-programmatic-transaction-management) - [JPA Entity Lifecycle Events](https://www.baeldung.com/jpa-entity-lifecycle-events) - [Overriding Column Definition With @AttributeOverride](https://www.baeldung.com/jpa-attributeoverride) +- [A Spring Custom Annotation for a Better DAO](http://www.baeldung.com/spring-annotation-bean-pre-processor) ### Eclipse Config After importing the project into Eclipse, you may see the following error: diff --git a/spring-core-3/src/main/java/com/baeldung/customannotation/CustomAnnotationConfiguration.java b/persistence-modules/spring-data-jpa-annotations/src/main/java/com/baeldung/customannotation/CustomAnnotationConfiguration.java similarity index 100% rename from spring-core-3/src/main/java/com/baeldung/customannotation/CustomAnnotationConfiguration.java rename to persistence-modules/spring-data-jpa-annotations/src/main/java/com/baeldung/customannotation/CustomAnnotationConfiguration.java diff --git a/spring-core-3/src/main/java/com/baeldung/customannotation/DataAccess.java b/persistence-modules/spring-data-jpa-annotations/src/main/java/com/baeldung/customannotation/DataAccess.java similarity index 100% rename from spring-core-3/src/main/java/com/baeldung/customannotation/DataAccess.java rename to persistence-modules/spring-data-jpa-annotations/src/main/java/com/baeldung/customannotation/DataAccess.java diff --git a/spring-core-3/src/main/java/com/baeldung/customannotation/DataAccessAnnotationProcessor.java b/persistence-modules/spring-data-jpa-annotations/src/main/java/com/baeldung/customannotation/DataAccessAnnotationProcessor.java similarity index 100% rename from spring-core-3/src/main/java/com/baeldung/customannotation/DataAccessAnnotationProcessor.java rename to persistence-modules/spring-data-jpa-annotations/src/main/java/com/baeldung/customannotation/DataAccessAnnotationProcessor.java diff --git a/spring-core-3/src/main/java/com/baeldung/customannotation/DataAccessFieldCallback.java b/persistence-modules/spring-data-jpa-annotations/src/main/java/com/baeldung/customannotation/DataAccessFieldCallback.java similarity index 100% rename from spring-core-3/src/main/java/com/baeldung/customannotation/DataAccessFieldCallback.java rename to persistence-modules/spring-data-jpa-annotations/src/main/java/com/baeldung/customannotation/DataAccessFieldCallback.java diff --git a/spring-core-3/src/main/java/com/baeldung/customannotation/GenericDAO.java b/persistence-modules/spring-data-jpa-annotations/src/main/java/com/baeldung/customannotation/GenericDAO.java similarity index 100% rename from spring-core-3/src/main/java/com/baeldung/customannotation/GenericDAO.java rename to persistence-modules/spring-data-jpa-annotations/src/main/java/com/baeldung/customannotation/GenericDAO.java diff --git a/spring-core-3/src/test/java/com/baeldung/customannotation/Account.java b/persistence-modules/spring-data-jpa-annotations/src/test/java/com/baeldung/customannotation/Account.java similarity index 100% rename from spring-core-3/src/test/java/com/baeldung/customannotation/Account.java rename to persistence-modules/spring-data-jpa-annotations/src/test/java/com/baeldung/customannotation/Account.java diff --git a/spring-core-3/src/test/java/com/baeldung/customannotation/BeanWithGenericDAO.java b/persistence-modules/spring-data-jpa-annotations/src/test/java/com/baeldung/customannotation/BeanWithGenericDAO.java similarity index 100% rename from spring-core-3/src/test/java/com/baeldung/customannotation/BeanWithGenericDAO.java rename to persistence-modules/spring-data-jpa-annotations/src/test/java/com/baeldung/customannotation/BeanWithGenericDAO.java diff --git a/spring-core-3/src/test/java/com/baeldung/customannotation/DataAccessAnnotationIntegrationTest.java b/persistence-modules/spring-data-jpa-annotations/src/test/java/com/baeldung/customannotation/DataAccessAnnotationIntegrationTest.java similarity index 100% rename from spring-core-3/src/test/java/com/baeldung/customannotation/DataAccessAnnotationIntegrationTest.java rename to persistence-modules/spring-data-jpa-annotations/src/test/java/com/baeldung/customannotation/DataAccessAnnotationIntegrationTest.java diff --git a/spring-core-3/src/test/java/com/baeldung/customannotation/DataAccessFieldCallbackIntegrationTest.java b/persistence-modules/spring-data-jpa-annotations/src/test/java/com/baeldung/customannotation/DataAccessFieldCallbackIntegrationTest.java similarity index 100% rename from spring-core-3/src/test/java/com/baeldung/customannotation/DataAccessFieldCallbackIntegrationTest.java rename to persistence-modules/spring-data-jpa-annotations/src/test/java/com/baeldung/customannotation/DataAccessFieldCallbackIntegrationTest.java diff --git a/spring-core-3/src/test/java/com/baeldung/customannotation/Person.java b/persistence-modules/spring-data-jpa-annotations/src/test/java/com/baeldung/customannotation/Person.java similarity index 100% rename from spring-core-3/src/test/java/com/baeldung/customannotation/Person.java rename to persistence-modules/spring-data-jpa-annotations/src/test/java/com/baeldung/customannotation/Person.java diff --git a/persistence-modules/spring-data-jpa-filtering/src/main/java/com/baeldung/entity/Customer.java b/persistence-modules/spring-data-jpa-filtering/src/main/java/com/baeldung/entity/Customer.java index efcae73853..5af96d7822 100644 --- a/persistence-modules/spring-data-jpa-filtering/src/main/java/com/baeldung/entity/Customer.java +++ b/persistence-modules/spring-data-jpa-filtering/src/main/java/com/baeldung/entity/Customer.java @@ -1,8 +1,11 @@ package com.baeldung.entity; +import org.hibernate.annotations.Type; + import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; +import java.util.UUID; @Entity public class Customer { @@ -13,11 +16,20 @@ public class Customer { private String name; private String email; + @Type(type = "org.hibernate.type.UUIDCharType") + private UUID uuid; + public Customer(String name, String email) { this.name = name; this.email = email; } + public Customer(String name, String email, UUID uuid) { + this.name = name; + this.email = email; + this.uuid = uuid; + } + public String getName() { return name; } @@ -34,4 +46,7 @@ public class Customer { this.email = email; } + public UUID getUuid() { + return this.uuid; + } } diff --git a/persistence-modules/spring-data-jpa-filtering/src/main/java/com/baeldung/repository/CustomerRepository.java b/persistence-modules/spring-data-jpa-filtering/src/main/java/com/baeldung/repository/CustomerRepository.java index 65b22bbd84..5f9710b839 100644 --- a/persistence-modules/spring-data-jpa-filtering/src/main/java/com/baeldung/repository/CustomerRepository.java +++ b/persistence-modules/spring-data-jpa-filtering/src/main/java/com/baeldung/repository/CustomerRepository.java @@ -6,6 +6,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import java.util.List; +import java.util.UUID; public interface CustomerRepository extends JpaRepository { @@ -16,4 +17,5 @@ public interface CustomerRepository extends JpaRepository { @Query("SELECT c FROM Customer c WHERE (:name is null or c.name = :name) and (:email is null or c.email = :email)") List findCustomerByNameAndEmail(@Param("name") String name, @Param("email") String email); + List findCustomerByUuid(@Param("uuid") UUID uuid); } diff --git a/persistence-modules/spring-data-jpa-filtering/src/test/java/com/baeldung/repository/CustomerRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-filtering/src/test/java/com/baeldung/repository/CustomerRepositoryIntegrationTest.java index 5d6457ce30..27208507f1 100644 --- a/persistence-modules/spring-data-jpa-filtering/src/test/java/com/baeldung/repository/CustomerRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-filtering/src/test/java/com/baeldung/repository/CustomerRepositoryIntegrationTest.java @@ -12,6 +12,7 @@ import org.springframework.test.context.junit4.SpringRunner; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import java.util.List; +import java.util.UUID; import static org.junit.Assert.assertEquals; @@ -30,6 +31,7 @@ public class CustomerRepositoryIntegrationTest { entityManager.persist(new Customer("A", "A@example.com")); entityManager.persist(new Customer("D", null)); entityManager.persist(new Customer("D", "D@example.com")); + entityManager.persist(new Customer("C", null, UUID.fromString("c7c19ff4-8636-4b99-9591-c3327652f191"))); } @Test @@ -57,6 +59,20 @@ public class CustomerRepositoryIntegrationTest { assertEquals(2, customers.size()); } + @Test + public void givenUUIDIsPresent_whenQueryMethod_thenFetchedCorrectly() { + List customers = repository.findCustomerByUuid(UUID.fromString("c7c19ff4-8636-4b99-9591-c3327652f191")); + + assertEquals(1, customers.size()); + } + + @Test + public void givenNullUuid_whenQueryMethod_thenFetchedCorrectly() { + List customers = repository.findCustomerByUuid(null); + + assertEquals(3, customers.size()); + } + @After public void cleanUp() { repository.deleteAll(); diff --git a/persistence-modules/spring-data-jpa-repo-2/README.md b/persistence-modules/spring-data-jpa-repo-2/README.md index 23134ec02d..dc94ba41d0 100644 --- a/persistence-modules/spring-data-jpa-repo-2/README.md +++ b/persistence-modules/spring-data-jpa-repo-2/README.md @@ -9,4 +9,5 @@ - [Difference Between JPA and Spring Data JPA](https://www.baeldung.com/spring-data-jpa-vs-jpa) - [Differences Between Spring Data JPA findFirst() and findTop()](https://www.baeldung.com/spring-data-jpa-findfirst-vs-findtop) - [Difference Between findBy and findAllBy in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-find-by-vs-find-all-by) +- [Unidirectional One-to-Many and Cascading Delete in JPA](https://www.baeldung.com/spring-jpa-unidirectional-one-to-many-and-cascading-delete) - More articles: [[<-- prev]](../spring-data-jpa-repo) diff --git a/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/Article.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/Article.java new file mode 100644 index 0000000000..97f79515cc --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/Article.java @@ -0,0 +1,46 @@ +package com.baeldung.spring.data.persistence.unidirectionalcascadingdelete; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +@Entity +public class Article { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + private String name; + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + private Set comments = new HashSet<>(); + + public Set getComments() { + return comments; + } + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setId(long id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setComments(Set comments) { + this.comments = comments; + } +} diff --git a/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/ArticleRepository.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/ArticleRepository.java new file mode 100644 index 0000000000..7cf88c73b1 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/ArticleRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.spring.data.persistence.unidirectionalcascadingdelete; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ArticleRepository extends JpaRepository { + +} diff --git a/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/ArticleService.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/ArticleService.java new file mode 100644 index 0000000000..b0f9bdb05e --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/ArticleService.java @@ -0,0 +1,17 @@ +package com.baeldung.spring.data.persistence.unidirectionalcascadingdelete; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ArticleService { + + @Autowired + private ArticleRepository articleRepository; + + public void deleteArticle(Article article) { + articleRepository.delete(article); + + } + +} diff --git a/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/CascadingDeleteApplication.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/CascadingDeleteApplication.java new file mode 100644 index 0000000000..1c417d9cc9 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/CascadingDeleteApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.data.persistence.unidirectionalcascadingdelete; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CascadingDeleteApplication { + public static void main(String[] args) { + SpringApplication.run(CascadingDeleteApplication.class, args); + } + +} diff --git a/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/Comment.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/Comment.java new file mode 100644 index 0000000000..334ac01ea5 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/Comment.java @@ -0,0 +1,45 @@ +package com.baeldung.spring.data.persistence.unidirectionalcascadingdelete; + +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Comment { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + + private String description; + private Date date; + + public void setId(long id) { + this.id = id; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setDate(Date total) { + this.date = total; + } + + public long getId() { + return id; + } + + public String getDescription() { + return description; + } + + public Date getDate() { + return date; + } + +} + diff --git a/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/CommentRepository.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/CommentRepository.java new file mode 100644 index 0000000000..cadb1d7173 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/unidirectionalcascadingdelete/CommentRepository.java @@ -0,0 +1,8 @@ +package com.baeldung.spring.data.persistence.unidirectionalcascadingdelete; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CommentRepository extends JpaRepository { +} diff --git a/persistence-modules/spring-data-jpa-repo-2/src/test/java/com/baeldung/spring/data/persistence/deletionCascading/ArticleRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-repo-2/src/test/java/com/baeldung/spring/data/persistence/deletionCascading/ArticleRepositoryIntegrationTest.java new file mode 100644 index 0000000000..6ff8d57b6e --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-2/src/test/java/com/baeldung/spring/data/persistence/deletionCascading/ArticleRepositoryIntegrationTest.java @@ -0,0 +1,75 @@ +package com.baeldung.spring.data.persistence.deletionCascading; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.transaction.Transactional; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.baeldung.spring.data.persistence.unidirectionalcascadingdelete.Article; +import com.baeldung.spring.data.persistence.unidirectionalcascadingdelete.ArticleRepository; +import com.baeldung.spring.data.persistence.unidirectionalcascadingdelete.ArticleService; +import com.baeldung.spring.data.persistence.unidirectionalcascadingdelete.CascadingDeleteApplication; +import com.baeldung.spring.data.persistence.unidirectionalcascadingdelete.Comment; +import com.baeldung.spring.data.persistence.unidirectionalcascadingdelete.CommentRepository; + +@SpringBootTest(classes = CascadingDeleteApplication.class) +@Transactional +public class ArticleRepositoryIntegrationTest { + + @Autowired + private ArticleRepository articleRepository; + + @Autowired + private CommentRepository commentRepository; + + @Autowired + private ArticleService articleService; + + @Test + @Transactional + public void givenAnArticleAndItsComments_whenDeleteArticle_thenCommentsDeletedAutomatically() { + + Set comments = new HashSet<>(); + Article article = new Article(); + article.setName("introduction to Spring"); + + Comment comment1 = new Comment(); + comment1.setDescription("Explain types of Autowired"); + comment1.setDate(Date.from(Instant.now())); + + Comment comment2 = new Comment(); + comment2.setDescription("Good article"); + comment2.setDate(Date.from(Instant.now() + .minus(10, ChronoUnit.MINUTES))); + + comments.add(comment1); + comments.add(comment2); + + article.setComments(comments); + articleRepository.save(article); + + List
articles = articleRepository.findAll(); + assertThat(articles.size()).isEqualTo(1); + Article retrivedArticle = articles.get(0); + + List fetchedComments = commentRepository.findAll(); + assertThat(fetchedComments.size()).isEqualTo(2); + + articleService.deleteArticle(retrivedArticle); + assertThat(articleRepository.findAll()).isEmpty(); + + assertThat(commentRepository.findAll()).isEmpty(); + + } +} + diff --git a/persistence-modules/spring-data-jpa-repo-3/README.md b/persistence-modules/spring-data-jpa-repo-3/README.md index dc33900736..d3782eb1e6 100644 --- a/persistence-modules/spring-data-jpa-repo-3/README.md +++ b/persistence-modules/spring-data-jpa-repo-3/README.md @@ -4,4 +4,5 @@ This module contains articles about Spring Data JPA. ### Relevant Articles: - [New CRUD Repository Interfaces in Spring Data 3](https://www.baeldung.com/spring-data-3-crud-repository-interfaces) +- [How to Persist a List of String in JPA?](https://www.baeldung.com/java-jpa-persist-string-list) - More articles: [[<-- prev]](../spring-data-jpa-repo-2) diff --git a/persistence-modules/spring-data-jpa-repo-3/pom.xml b/persistence-modules/spring-data-jpa-repo-3/pom.xml index 8cd8ca7f61..d406d25c05 100644 --- a/persistence-modules/spring-data-jpa-repo-3/pom.xml +++ b/persistence-modules/spring-data-jpa-repo-3/pom.xml @@ -24,6 +24,7 @@ h2 runtime + org.springframework.boot spring-boot-starter-test @@ -31,5 +32,4 @@ - diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/entity/Library.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/entity/Library.java new file mode 100644 index 0000000000..04c0ad5e0a --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/entity/Library.java @@ -0,0 +1,66 @@ +package com.baeldung.spring.data.jpa.listrepositories.entity; + +import jakarta.persistence.*; + +import java.util.ArrayList; +import java.util.List; + +@Entity(name = "library") +public class Library { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; + + @Convert(converter = StringListConverter.class) + @Column(name = "addresses", nullable = false) + private List addresses = new ArrayList<>(); + + @ElementCollection(targetClass = String.class, fetch = FetchType.EAGER) + @CollectionTable(name = "book", joinColumns = @JoinColumn(name = "library_id")) + @Column(name = "book", nullable = false) + private List books = new ArrayList<>(); + + public Library() { + } + + public Library(String name, List addresses, List books) { + this.name = name; + this.addresses = addresses; + this.books = books; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getAddresses() { + return addresses; + } + + public void setAddresses(List addresses) { + this.addresses = addresses; + } + + public List getBooks() { + return books; + } + + public void setBooks(List books) { + this.books = books; + } +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/entity/StringListConverter.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/entity/StringListConverter.java new file mode 100644 index 0000000000..ffc097ee18 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/entity/StringListConverter.java @@ -0,0 +1,25 @@ +package com.baeldung.spring.data.jpa.listrepositories.entity; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +import java.util.Arrays; +import java.util.List; + + +import static java.util.Collections.*; + +@Converter +public class StringListConverter implements AttributeConverter, String> { + private static final String SPLIT_CHAR = ";"; + + @Override + public String convertToDatabaseColumn(List stringList) { + return stringList != null ? String.join(SPLIT_CHAR, stringList) : ""; + } + + @Override + public List convertToEntityAttribute(String string) { + return string != null ? Arrays.asList(string.split(SPLIT_CHAR)) : emptyList(); + } +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/repository/LibraryRepository.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/repository/LibraryRepository.java new file mode 100644 index 0000000000..71deb04b3e --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/repository/LibraryRepository.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.data.jpa.listrepositories.repository; + +import com.baeldung.spring.data.jpa.listrepositories.entity.Library; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface LibraryRepository extends CrudRepository { + @Query("SELECT l FROM library l JOIN FETCH l.books WHERE l.id = (:id)") + Library findById(@Param("id") long id); +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/Application.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/Application.java new file mode 100644 index 0000000000..94e54889f6 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/Application.java @@ -0,0 +1,15 @@ +package com.baeldung.spring.data.jpa.naturalid; + +import com.baeldung.spring.data.jpa.naturalid.repository.NaturalIdRepositoryImpl; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(SpringBootApplication.class, args); + } +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/HotelRoomsService.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/HotelRoomsService.java new file mode 100644 index 0000000000..c8cd1fada4 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/HotelRoomsService.java @@ -0,0 +1,37 @@ +package com.baeldung.spring.data.jpa.naturalid; + +import com.baeldung.spring.data.jpa.naturalid.entity.ConferenceRoom; +import com.baeldung.spring.data.jpa.naturalid.entity.GuestRoom; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; + +import org.hibernate.Session; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class HotelRoomsService { + + private final EntityManager entityManager; + + public HotelRoomsService(EntityManagerFactory entityManagerFactory) { + this.entityManager = entityManagerFactory.createEntityManager(); + } + + public Optional conferenceRoom(String name) { + Session session = entityManager.unwrap(Session.class); + return session.bySimpleNaturalId(ConferenceRoom.class) + .loadOptional(name); + } + + public Optional guestRoom(int roomNumber, int floor) { + Session session = entityManager.unwrap(Session.class); + return session.byNaturalId(GuestRoom.class) + .using("roomNumber", roomNumber) + .using("floor", floor) + .loadOptional(); + } + +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/NaturalIdRepositoryConfig.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/NaturalIdRepositoryConfig.java new file mode 100644 index 0000000000..94b96ca86c --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/NaturalIdRepositoryConfig.java @@ -0,0 +1,11 @@ +package com.baeldung.spring.data.jpa.naturalid; + +import com.baeldung.spring.data.jpa.naturalid.repository.NaturalIdRepositoryImpl; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@Configuration +@EnableJpaRepositories(repositoryBaseClass = NaturalIdRepositoryImpl.class) +public class NaturalIdRepositoryConfig { +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/entity/ConferenceRoom.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/entity/ConferenceRoom.java new file mode 100644 index 0000000000..6ff7e48a3d --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/entity/ConferenceRoom.java @@ -0,0 +1,49 @@ +package com.baeldung.spring.data.jpa.naturalid.entity; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +import org.hibernate.annotations.NaturalId; + +@Entity +public class ConferenceRoom { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NaturalId + private String name; + + private int capacity; + + public ConferenceRoom(String name, int capacity) { + this.name = name; + this.capacity = capacity; + } + + protected ConferenceRoom() { + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public int getCapacity() { + return capacity; + } + + public void setCapacity(int capacity) { + this.capacity = capacity; + } + + @Override + public String toString() { + return "HotelRoom{" + "id=" + id + ", name='" + name + '\'' + ", capacity=" + capacity + '}'; + } +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/entity/GuestRoom.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/entity/GuestRoom.java new file mode 100644 index 0000000000..1219178625 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/entity/GuestRoom.java @@ -0,0 +1,67 @@ +package com.baeldung.spring.data.jpa.naturalid.entity; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +import org.hibernate.annotations.NaturalId; + +@Entity +public class GuestRoom { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NaturalId + private Integer roomNumber; + + @NaturalId + private Integer floor; + + private String name; + private int capacity; + + public GuestRoom(int roomNumber, int floor, String name, int capacity) { + this.roomNumber = roomNumber; + this.floor = floor; + this.name = name; + this.capacity = capacity; + } + + protected GuestRoom() { + } + + public Long getId() { + return id; + } + + public Integer getRoomNumber() { + return roomNumber; + } + + public Integer getFloor() { + return floor; + } + + public int getCapacity() { + return capacity; + } + + public void setCapacity(int capacity) { + this.capacity = capacity; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "GuestRoom{" + "id=" + id + ", roomNumber=" + roomNumber + ", floor=" + floor + ", name=" + name + ", capacity=" + capacity + '}'; + } +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/repository/ConferenceRoomRepository.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/repository/ConferenceRoomRepository.java new file mode 100644 index 0000000000..d12695f40f --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/repository/ConferenceRoomRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.spring.data.jpa.naturalid.repository; + +import com.baeldung.spring.data.jpa.naturalid.entity.ConferenceRoom; + +import org.springframework.stereotype.Repository; + +@Repository +public interface ConferenceRoomRepository extends NaturalIdRepository { +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/repository/GuestRoomJpaRepository.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/repository/GuestRoomJpaRepository.java new file mode 100644 index 0000000000..dd761d6660 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/repository/GuestRoomJpaRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.spring.data.jpa.naturalid.repository; + +import com.baeldung.spring.data.jpa.naturalid.entity.GuestRoom; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface GuestRoomJpaRepository extends JpaRepository { +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/repository/NaturalIdRepository.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/repository/NaturalIdRepository.java new file mode 100644 index 0000000000..5fe710c0a5 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/repository/NaturalIdRepository.java @@ -0,0 +1,11 @@ +package com.baeldung.spring.data.jpa.naturalid.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.NoRepositoryBean; + +import java.util.Optional; + +@NoRepositoryBean +public interface NaturalIdRepository extends JpaRepository { + Optional naturalId(ID naturalId); +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/repository/NaturalIdRepositoryImpl.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/repository/NaturalIdRepositoryImpl.java new file mode 100644 index 0000000000..2c6e62e189 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/naturalid/repository/NaturalIdRepositoryImpl.java @@ -0,0 +1,29 @@ +package com.baeldung.spring.data.jpa.naturalid.repository; + +import jakarta.persistence.EntityManager; + +import org.hibernate.Session; +import org.springframework.data.jpa.repository.support.JpaEntityInformation; +import org.springframework.data.jpa.repository.support.SimpleJpaRepository; +import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.transaction.annotation.Transactional; + +import java.io.Serializable; +import java.util.Optional; + +public class NaturalIdRepositoryImpl extends SimpleJpaRepository implements NaturalIdRepository { + private final EntityManager entityManager; + + public NaturalIdRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) { + super(entityInformation, entityManager); + this.entityManager = entityManager; + } + + @Override + public Optional naturalId(ID naturalId) { + return entityManager.unwrap(Session.class) + .bySimpleNaturalId(this.getDomainClass()) + .loadOptional(naturalId); + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/resources/application.properties b/persistence-modules/spring-data-jpa-repo-3/src/main/resources/application.properties index 8b13789179..5a1841e2ad 100644 --- a/persistence-modules/spring-data-jpa-repo-3/src/main/resources/application.properties +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/resources/application.properties @@ -1 +1,2 @@ - +logging.level.org.hibernate.SQL=DEBUG +logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE diff --git a/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/listrepositories/repository/LibraryIntegrationTest.java b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/listrepositories/repository/LibraryIntegrationTest.java new file mode 100644 index 0000000000..7bd1b90407 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/listrepositories/repository/LibraryIntegrationTest.java @@ -0,0 +1,32 @@ +package com.baeldung.spring.data.jpa.listrepositories.repository; + +import com.baeldung.spring.data.jpa.listrepositories.entity.Library; +import jakarta.transaction.Transactional; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.Arrays; + +@SpringBootTest +public class LibraryIntegrationTest { + + @Autowired + private LibraryRepository libraryRepository; + + @Test + @Transactional + public void givenLibrary_whenGetAddressesAndGetBooks_thenGetListOfItems(){ + Library library = new Library(); + library.setAddresses(Arrays.asList("Address 1", "Address 2")); + library.setBooks(Arrays.asList("Book 1", "Book 2")); + + libraryRepository.save(library); + Library lib = libraryRepository.findById(library.getId().longValue()); + + Assertions.assertEquals(2, lib.getAddresses().size()); + Assertions.assertEquals(2, lib.getBooks().size()); + } + +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/naturalid/NaturalIdIntegrationTest.java b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/naturalid/NaturalIdIntegrationTest.java new file mode 100644 index 0000000000..96cc805082 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/naturalid/NaturalIdIntegrationTest.java @@ -0,0 +1,56 @@ +package com.baeldung.spring.data.jpa.naturalid; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.baeldung.spring.data.jpa.naturalid.entity.ConferenceRoom; +import com.baeldung.spring.data.jpa.naturalid.entity.GuestRoom; +import com.baeldung.spring.data.jpa.naturalid.repository.ConferenceRoomRepository; +import com.baeldung.spring.data.jpa.naturalid.repository.GuestRoomJpaRepository; + +@SpringBootTest +class NaturalIdIntegrationTest { + + @Autowired + private HotelRoomsService service; + + @Autowired + private GuestRoomJpaRepository guestRoomJpaRepository; + @Autowired + private ConferenceRoomRepository conferenceRoomRepository; + + @Test + void whenWeFindByNaturalKey_thenEntityIsReturnedCorrectly() { + guestRoomJpaRepository.save(new GuestRoom(23, 3, "B-423", 4)); + + Optional result = service.guestRoom(23, 3); + + assertThat(result).isPresent() + .hasValueSatisfying(room -> "B-423".equals(room.getName())); + } + + @Test + void whenWeFindBySimpleNaturalKey_thenEntityIsReturnedCorrectly() { + conferenceRoomRepository.save(new ConferenceRoom("Colorado", 100)); + + Optional result = service.conferenceRoom("Colorado"); + + assertThat(result).isPresent() + .hasValueSatisfying(room -> "Colorado".equals(room.getName())); + } + + @Test + void givenNaturalIdRepository_whenWeFindBySimpleNaturalKey_thenEntityIsReturnedCorrectly() { + conferenceRoomRepository.save(new ConferenceRoom("Nevada", 200)); + + Optional result = conferenceRoomRepository.naturalId("Nevada"); + + assertThat(result).isPresent() + .hasValueSatisfying(room -> "Nevada".equals(room.getName())); + } +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java index 76cdf41d81..8f86e8ce49 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java @@ -2,6 +2,8 @@ package com.baeldung.derivedquery.repository; import com.baeldung.derivedquery.entity.User; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.time.ZonedDateTime; import java.util.Collection; @@ -49,9 +51,12 @@ public interface UserRepository extends JpaRepository { List findByAgeIn(Collection ages); - List findByNameOrBirthDate(String name, ZonedDateTime birthDate); + @Query(value = "select * from users where (name = :nameParam OR birth_date <> :birthDateParam)", nativeQuery = true) + List findByNameOrBirthDate(@Param(value = "nameParam") String nameParam, @Param(value = "birthDateParam") ZonedDateTime birthDateParam); - List findByNameOrBirthDateAndActive(String name, ZonedDateTime birthDate, Boolean active); + @Query(value = "select * from users where (name = :nameParam OR birth_date <> :birthDateParam) and active = :activeParam", nativeQuery = true) + List findByNameOrBirthDateAndActive(@Param(value = "nameParam") String nameParam, @Param(value = "birthDateParam") ZonedDateTime birthDateParam, + @Param(value = "activeParam") Boolean activeParam); List findByNameOrderByName(String name); diff --git a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryIntegrationTest.java index 2a6e166b88..75e0db253f 100644 --- a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryIntegrationTest.java @@ -161,7 +161,7 @@ public class UserRepositoryIntegrationTest { @Test public void whenByNameOrBirthDateAndActive() { - assertEquals(3, userRepository.findByNameOrBirthDateAndActive(USER_NAME_ADAM, BIRTHDATE, false).size()); + assertEquals(2, userRepository.findByNameOrBirthDateAndActive(USER_NAME_ADAM, BIRTHDATE, false).size()); } @Test diff --git a/persistence-modules/spring-jooq/pom.xml b/persistence-modules/spring-jooq/pom.xml index 9848c726c5..d12a921212 100644 --- a/persistence-modules/spring-jooq/pom.xml +++ b/persistence-modules/spring-jooq/pom.xml @@ -195,11 +195,11 @@ - 3.14.15 + 3.16.18 1.0.0 1.5 1.0.0 - 1.4.200 + 2.1.214 \ No newline at end of file diff --git a/persistence-modules/spring-jpa-2/README.md b/persistence-modules/spring-jpa-2/README.md index f9f259cdfa..c1068b6a39 100644 --- a/persistence-modules/spring-jpa-2/README.md +++ b/persistence-modules/spring-jpa-2/README.md @@ -7,4 +7,5 @@ - [The DAO with Spring and Hibernate](https://www.baeldung.com/persistence-layer-with-spring-and-hibernate) - [Simplify the DAO with Spring and Java Generics](https://www.baeldung.com/simplifying-the-data-access-layer-with-spring-and-java-generics) - [Multitenancy With Spring Data JPA](https://www.baeldung.com/multitenancy-with-spring-data-jpa) +- [Remove Entity with Many-to-Many Relationship in JPA](https://www.baeldung.com/jpa-remove-entity-many-to-many) - More articles: [[<-- prev]](/spring-jpa) diff --git a/persistence-modules/spring-jpa-2/pom.xml b/persistence-modules/spring-jpa-2/pom.xml index 19bc9cba14..974dd41df9 100644 --- a/persistence-modules/spring-jpa-2/pom.xml +++ b/persistence-modules/spring-jpa-2/pom.xml @@ -101,7 +101,7 @@ - 5.1.5.RELEASE + 5.2.0.RELEASE 2.2.6.RELEASE 9.0.0.M26 diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Application.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Application.java new file mode 100644 index 0000000000..7b8551ee0c --- /dev/null +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Application.java @@ -0,0 +1,12 @@ +package com.baeldung.manytomanyremoval; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Author.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Author.java new file mode 100644 index 0000000000..d9906a21cd --- /dev/null +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Author.java @@ -0,0 +1,62 @@ +package com.baeldung.manytomanyremoval; + +import javax.persistence.*; +import java.util.HashSet; +import java.util.Set; + +@Entity +@Table(name = "author") +public class Author { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "name") + private String name; + + @ManyToMany(mappedBy = "authors") + private Set books = new HashSet<>(); + + // standard getters and setters + + public Author() { + } + + public Author(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set getBooks() { + return books; + } + + public void setBooks(Set books) { + this.books = books; + } + + @PreRemove + private void removeBookAssociations() { + for (Book book : this.books) { + book.getAuthors().remove(this); + } + } + +} diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Book.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Book.java new file mode 100644 index 0000000000..4b49acd000 --- /dev/null +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Book.java @@ -0,0 +1,65 @@ +package com.baeldung.manytomanyremoval; + + +import javax.persistence.*; +import java.util.HashSet; +import java.util.Set; + +@Entity +@Table(name = "book") +public class Book { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "title") + private String title; + + @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @JoinTable(name = "book_author", + joinColumns = @JoinColumn(name = "book_id"), + inverseJoinColumns = @JoinColumn(name = "author_id") + ) + private Set authors = new HashSet<>(); + + // standard getters and setters + + public Book() { + } + + public Book(String title) { + this.title = 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; + } + + public Set getAuthors() { + return authors; + } + + public void removeAuthor(Author author) { + this.authors.remove(author); + author.getBooks().remove(this); + } + + public void addAuthor(Author author) { + authors.add(author); + author.getBooks().add(this); + } + +} diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Category.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Category.java new file mode 100644 index 0000000000..f7202f544c --- /dev/null +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Category.java @@ -0,0 +1,41 @@ +package com.baeldung.manytomanyremoval; + +import javax.persistence.*; + +@Entity +@Table(name = "category") +public class Category { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "name") + private String name; + + // getters and setters + + public Category() { + } + + public Category(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Post.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Post.java new file mode 100644 index 0000000000..d229a9d0d7 --- /dev/null +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Post.java @@ -0,0 +1,59 @@ +package com.baeldung.manytomanyremoval; + + +import javax.persistence.*; +import java.util.HashSet; +import java.util.Set; + +@Entity +@Table(name = "post") +public class Post { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "title") + private String title; + + @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}) + @JoinTable(name = "post_category", + joinColumns = @JoinColumn(name = "post_id"), + inverseJoinColumns = @JoinColumn(name = "category_id") + ) + private Set categories = new HashSet<>(); + + // getters and setters + + public Post(String title) { + this.title = title; + } + + public Post() { + } + + 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; + } + + public Set getCategories() { + return categories; + } + + public void setCategories(Set categories) { + this.categories = categories; + } +} diff --git a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/BidirectionalRemovalUnitTest.java b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/BidirectionalRemovalUnitTest.java new file mode 100644 index 0000000000..f214fcdc2a --- /dev/null +++ b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/BidirectionalRemovalUnitTest.java @@ -0,0 +1,78 @@ +package com.baeldung.manytomanyremoval; + +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.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = TestContextConfig.class) +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@Transactional +class BidirectionalRemovalUnitTest { + + @Autowired + private EntityManager entityManager; + + @BeforeEach + void init() { + Author author1 = new Author("Erich Gamma"); + Author author2 = new Author("John Vlissides"); + Author author3 = new Author("Ralph Johnson"); + Author author4 = new Author("Richard Helm"); + + Book book = new Book(); + book.setTitle("GOF Java"); + book.addAuthor(author1); + book.addAuthor(author2); + book.addAuthor(author3); + book.addAuthor(author4); + entityManager.persist(book); + + Book book2 = new Book(); + book2.setTitle("A Lost Age"); + book2.addAuthor(author3); + entityManager.persist(book2); + } + + @Test + void givenEntities_whenRemoveFromOwner_thenRemoveAssociation() { + Author author = (Author) entityManager + .createQuery("SELECT author from Author author where author.name = ?1") + .setParameter(1, "Ralph Johnson") + .getSingleResult(); + + Book book1 = entityManager.find(Book.class, 1L); + Book book2 = entityManager.find(Book.class, 2L); + + book1.removeAuthor(author); + entityManager.persist(book1); + + Assertions.assertEquals(3, book1.getAuthors().size()); + Assertions.assertEquals(1, book2.getAuthors().size()); + } + + @Transactional + @Test + void givenEntities_whenRemoveFromNotOwner_thenRemoveAssociation() { + Author author = (Author) entityManager + .createQuery("SELECT author from Author author where author.name = ?1") + .setParameter(1, "Ralph Johnson") + .getSingleResult(); + Book book1 = entityManager.find(Book.class, 1L); + Book book2 = entityManager.find(Book.class, 2L); + + entityManager.remove(author); + + Assertions.assertEquals(3, book1.getAuthors().size()); + Assertions.assertEquals(0, book2.getAuthors().size()); + } +} + diff --git a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/TestContextConfig.java b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/TestContextConfig.java new file mode 100644 index 0000000000..6a840824de --- /dev/null +++ b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/TestContextConfig.java @@ -0,0 +1,12 @@ +package com.baeldung.manytomanyremoval; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +@Configuration +@PropertySource("classpath:/manytomanyremoval/test.properties") +@ComponentScan("com.baeldung.manytomanyremoval") +public class TestContextConfig { + +} diff --git a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/UnidirectionalRemovalUnitTest.java b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/UnidirectionalRemovalUnitTest.java new file mode 100644 index 0000000000..b23b589fb7 --- /dev/null +++ b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/UnidirectionalRemovalUnitTest.java @@ -0,0 +1,55 @@ +package com.baeldung.manytomanyremoval; + +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.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = TestContextConfig.class) +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@Transactional +class UnidirectionalRemovalUnitTest { + + @Autowired + private EntityManager entityManager; + + @BeforeEach + void init() { + Category category1 = new Category("JPA"); + Category category2 = new Category("Persistence"); + + Post post1 = new Post("Many-to-Many Relationship"); + post1.getCategories().add(category1); + post1.getCategories().add(category2); + + Post post2 = new Post("Entity Manager"); + post2.getCategories().add(category1); + + entityManager.persist(post1); + entityManager.persist(post2); + + Assertions.assertEquals(2, post1.getCategories().size()); + Assertions.assertEquals(1, post2.getCategories().size()); + } + + @Test + void givenEntities_whenRemove_thenRemoveAssociation() { + Post post1 = entityManager.find(Post.class, 1L); + Post post2 = entityManager.find(Post.class, 2L); + Category category = entityManager.find(Category.class, 1L); + + post1.getCategories().remove(category); + + Assertions.assertEquals(1, post1.getCategories().size()); + Assertions.assertEquals(1, post2.getCategories().size()); + } + +} diff --git a/persistence-modules/spring-jpa-2/src/test/resources/manytomanyremoval/test.properties b/persistence-modules/spring-jpa-2/src/test/resources/manytomanyremoval/test.properties new file mode 100644 index 0000000000..83479cd453 --- /dev/null +++ b/persistence-modules/spring-jpa-2/src/test/resources/manytomanyremoval/test.properties @@ -0,0 +1,11 @@ +spring.datasource.url=jdbc:h2:mem:mydb;MODE=LEGACY; +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password= + +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.hbm2ddl.auto=none +spring.jpa.show-sql=true +spring.jpa.hibernate.dialect=org.hibernate.dialect.H2Dialect +spring.jpa.hibernate.ddl-auto=create-drop + diff --git a/pom.xml b/pom.xml index 31495958e7..7d9a8eb21a 100644 --- a/pom.xml +++ b/pom.xml @@ -222,6 +222,9 @@ maven-war-plugin ${maven-war-plugin.version} + + false + @@ -328,35 +331,43 @@ parent-boot-2 parent-spring-4 parent-spring-5 + parent-spring-6 parent-java - checker-plugin - - core-java-modules - couchbase + checker-framework + + + core-java-modules/core-java-8 + core-java-modules/core-java-8-2 + core-java-modules/core-java-8-datetime + core-java-modules/core-java-8-datetime-2 + core-java-modules/core-java-sun + core-java-modules/core-java-security + core-java-modules/core-java-nio-2 + core-java-modules/core-java-serialization + core-java-modules/core-java-lang + core-java-modules/core-java-lang-math-3 + core-java-modules/core-java-collections-conversions-2 + core-java-modules/core-java-streams-2 + gradle-modules/gradle/maven-to-gradle - java-jdi - - jetbrains - jhipster-5 - jmh language-interop - libraries-3 - libraries-data-db - lombok-modules + libraries-jdk8 + + lombok-modules/lombok-custom muleesb - osgi - persistence-modules - web-modules + persistence-modules/deltaspike + persistence-modules/hibernate-ogm + persistence-modules/java-cassandra @@ -399,35 +410,21 @@ parent-boot-2 parent-spring-4 parent-spring-5 + parent-spring-6 parent-java spring-4 - spring-aop - spring-bom spring-cloud-modules - - spring-exceptions - spring-integration - spring-jenkins-pipeline - - spring-remoting-modules - spring-security-modules - spring-shell spring-soap - spring-spel spring-static-resources spring-swagger-codegen - spring-vault spring-web-modules - spring-websockets - static-analysis testing-modules - vertx-modules video-tutorials xml xml-2 @@ -470,6 +467,7 @@ parent-boot-2 parent-spring-4 parent-spring-5 + parent-spring-6 parent-java apache-spark @@ -478,15 +476,6 @@ jenkins-modules jhipster-modules - jhipster-5 - jws - - libraries - libraries-4 - libraries-5 - libraries-6 - - vaadin @@ -520,34 +509,42 @@ parent-boot-2 parent-spring-4 parent-spring-5 + parent-spring-6 parent-java - checker-plugin - + checker-framework + + + core-java-modules/core-java-8 + core-java-modules/core-java-8-2 + core-java-modules/core-java-8-datetime + core-java-modules/core-java-8-datetime-2 + core-java-modules/core-java-sun + core-java-modules/core-java-security + core-java-modules/core-java-nio-2 + core-java-modules/core-java-serialization + core-java-modules/core-java-lang + core-java-modules/core-java-lang-math-3 + core-java-modules/core-java-collections-conversions-2 + core-java-modules/core-java-streams-2 - core-java-modules - couchbase gradle-modules/gradle/maven-to-gradle - java-jdi - - jhipster-5 - jmh language-interop - libraries-3 - libraries-data-db - lombok-modules + libraries-jdk8 + + lombok-modules/lombok-custom muleesb - osgi - persistence-modules - web-modules + persistence-modules/deltaspike + persistence-modules/hibernate-ogm + persistence-modules/java-cassandra @@ -582,34 +579,21 @@ parent-boot-2 parent-spring-4 parent-spring-5 + parent-spring-6 parent-java spring-4 - spring-bom spring-cloud-modules - - spring-exceptions - spring-integration - spring-jenkins-pipeline - - spring-remoting-modules - spring-security-modules - spring-shell spring-soap - spring-spel spring-static-resources spring-swagger-codegen - spring-vault spring-web-modules - spring-websockets - static-analysis testing-modules - vertx-modules video-tutorials xml xml-2 @@ -644,6 +628,7 @@ parent-boot-2 parent-spring-4 parent-spring-5 + parent-spring-6 parent-java apache-spark @@ -652,15 +637,6 @@ jenkins-modules jhipster-modules - jhipster-5 - jws - - libraries - libraries-4 - libraries-5 - libraries-6 - - vaadin @@ -726,6 +702,8 @@ + lombok-modules + osgi spring-katharsis logging-modules spring-boot-modules @@ -749,6 +727,7 @@ javafx spring-batch + spring-batch-2 spring-boot-rest spring-drools spring-exceptions @@ -756,7 +735,9 @@ spring-core spring-core-4 spring-integration + spring-remoting-modules libraries-security + libraries-data-db performance-tests security-modules @@ -769,7 +750,6 @@ server-modules apache-cxf-modules - spring-aop jmeter spring-aop-2 @@ -785,15 +765,8 @@ couchbase core-groovy-modules - core-java-modules/core-java-9 - core-java-modules/core-java-9-improvements - core-java-modules/core-java-9-jigsaw + core-java-modules - core-java-modules/core-java-9-streams - core-java-modules/core-java-10 - core-java-modules/core-java-11 - core-java-modules/core-java-11-2 - core-java-modules/core-java-11-3 @@ -801,50 +774,27 @@ - core-java-modules/core-java-collections-set - core-java-modules/core-java-collections-list-4 - core-java-modules/core-java-collections-array-list - core-java-modules/core-java-collections-maps-4 - core-java-modules/core-java-collections-maps-5 - core-java-modules/core-java-concurrency-simple - core-java-modules/core-java-date-operations-1 - core-java-modules/core-java-datetime-conversion - core-java-modules/core-java-datetime-string - core-java-modules/core-java-io-conversions-2 - core-java-modules/core-java-jpms - core-java-modules/core-java-os - core-java-modules/core-java-streams-4 - core-java-modules/core-java-string-algorithms-3 - core-java-modules/core-java-string-operations-3 - core-java-modules/core-java-string-operations-4 - core-java-modules/core-java-string-operations-5 - core-java-modules/core-java-time-measurements - core-java-modules/core-java-networking-3 - core-java-modules/core-java-strings - core-java-modules/core-java-httpclient custom-pmd - spring-core-6 data-structures ddd-contexts jackson-modules + jmh deeplearning4j docker-modules drools guava-modules kubernetes-modules libraries-concurrency + jhipster-6 libraries-testing maven-modules optaplanner - persistence-modules/sirix - persistence-modules/spring-data-cassandra-2 - persistence-modules/spring-data-jpa-repo-3 + persistence-modules quarkus-modules spring-reactive-modules spring-swagger-codegen/custom-validations-opeanpi-codegen testing-modules/testing-assertions - persistence-modules/fauna - persistence-modules/spring-data-rest + testing-modules/mockito-simple rule-engines-modules @@ -855,6 +805,8 @@ tablesaw geotools + jws + akka-modules @@ -866,7 +818,6 @@ apache-olingo apache-poi-2 - apache-rocketmq apache-thrift apache-tika @@ -877,9 +828,8 @@ axon bazel - code-generation + google-auto-project ddd - discord4j disruptor dozer dubbo @@ -891,13 +841,14 @@ hystrix jackson-simple java-blockchain - + java-jdi java-rmi java-spi javax-sound javaxval javaxval-2 javax-validation-advanced + jetbrains jgit jib @@ -905,8 +856,13 @@ jsoup ksqldb jsf + + libraries libraries-2 - libraries-7 + libraries-4 + libraries-5 + libraries-6 + libraries-apache-commons libraries-apache-commons-collections libraries-apache-commons-io @@ -919,6 +875,7 @@ libraries-primitive libraries-rpc libraries-server + libraries-transform lucene mapstruct @@ -931,7 +888,6 @@ protobuffer reactor-core rsocket - slack @@ -939,10 +895,10 @@ spring-5-webflux spring-5-webflux-2 spring-activiti - spring-batch-2 + spring-actuator spring-core-2 spring-core-3 - spring-core-5 + spring-credhub spring-di-3 spring-cucumber @@ -956,15 +912,22 @@ spring-scheduling spring-state-machine + spring-shell + spring-spel spring-threads + spring-vault + spring-websockets + static-analysis tensorflow-java + vertx-modules xstream webrtc - persistence-modules/java-mongodb - + messaging-modules - persistence-modules/questdb + vaadin + libraries-3 + web-modules @@ -998,6 +961,8 @@ + lombok-modules + osgi spring-katharsis logging-modules spring-boot-modules @@ -1021,6 +986,7 @@ javafx spring-batch + spring-batch-2 spring-boot-rest spring-drools spring-exceptions @@ -1028,7 +994,9 @@ spring-core spring-core-4 spring-integration + spring-remoting-modules libraries-security + libraries-data-db performance-tests security-modules @@ -1052,15 +1020,9 @@ couchbase core-groovy-modules - core-java-modules/core-java-9 - core-java-modules/core-java-9-improvements - core-java-modules/core-java-9-jigsaw + + core-java-modules - core-java-modules/core-java-9-streams - core-java-modules/core-java-10 - core-java-modules/core-java-11 - core-java-modules/core-java-11-2 - core-java-modules/core-java-11-3 @@ -1068,34 +1030,13 @@ - core-java-modules/core-java-collections-set - core-java-modules/core-java-collections-list-4 - core-java-modules/core-java-collections-array-list - core-java-modules/core-java-collections-maps-4 - core-java-modules/core-java-collections-maps-5 - core-java-modules/core-java-concurrency-simple - core-java-modules/core-java-date-operations-1 - core-java-modules/core-java-datetime-conversion - core-java-modules/core-java-datetime-string - core-java-modules/core-java-io-conversions-2 - core-java-modules/core-java-jpms - core-java-modules/core-java-os - core-java-modules/core-java-streams-4 - core-java-modules/core-java-string-algorithms-3 - core-java-modules/core-java-string-operations-3 - core-java-modules/core-java-string-operations-4 - core-java-modules/core-java-string-operations-5 - core-java-modules/core-java-time-measurements - core-java-modules/core-java-networking-3 - core-java-modules/core-java-strings - core-java-modules/core-java-httpclient spring-aop spring-aop-2 custom-pmd - spring-core-6 data-structures ddd-contexts jackson-modules + jmh deeplearning4j jmeter docker-modules @@ -1103,18 +1044,16 @@ guava-modules kubernetes-modules libraries-concurrency + jhipster-6 libraries-testing maven-modules optaplanner - persistence-modules/sirix - persistence-modules/spring-data-cassandra-2 - persistence-modules/spring-data-jpa-repo-3 + persistence-modules quarkus-modules spring-reactive-modules spring-swagger-codegen/custom-validations-opeanpi-codegen testing-modules/testing-assertions - persistence-modules/fauna - persistence-modules/spring-data-rest + testing-modules/mockito-simple rule-engines-modules @@ -1125,6 +1064,8 @@ tablesaw geotools + jws + akka-modules @@ -1135,7 +1076,6 @@ apache-olingo apache-poi-2 - apache-rocketmq apache-thrift apache-tika @@ -1146,9 +1086,8 @@ axon bazel - code-generation + google-auto-project ddd - discord4j disruptor dozer @@ -1162,13 +1101,14 @@ hystrix jackson-simple java-blockchain - + java-jdi java-rmi java-spi javax-sound javaxval javaxval-2 javax-validation-advanced + jetbrains jgit jib @@ -1177,7 +1117,11 @@ jsf ksqldb - libraries-7 + libraries + libraries-2 + libraries-4 + libraries-5 + libraries-6 libraries-apache-commons libraries-apache-commons-collections libraries-apache-commons-io @@ -1187,9 +1131,11 @@ libraries-http libraries-http-2 libraries-io + libraries-ai libraries-primitive libraries-rpc libraries-server + libraries-transform lucene mapstruct @@ -1202,7 +1148,6 @@ protobuffer reactor-core rsocket - slack @@ -1211,10 +1156,9 @@ spring-5-webflux spring-5-webflux-2 spring-activiti - spring-batch-2 spring-core-2 spring-core-3 - spring-core-5 + spring-credhub spring-di-3 spring-cucumber @@ -1227,15 +1171,22 @@ spring-scheduling spring-state-machine + spring-shell + spring-spel spring-threads + spring-vault + spring-websockets + static-analysis tensorflow-java + vertx-modules xstream webrtc - persistence-modules/java-mongodb - libraries-2 + messaging-modules - persistence-modules/questdb + vaadin + libraries-3 + web-modules @@ -1253,6 +1204,7 @@ parent-boot-2 parent-spring-4 parent-spring-5 + parent-spring-6 parent-java @@ -1288,6 +1240,7 @@ 1.12.13 + 1.7.32 1.2.7 @@ -1306,7 +1259,7 @@ 2.6 3.12.0 1.5.0 - 3.0.0 + 3.3.2 4.0.1 1.2 2.3.3 diff --git a/discord4j/.gitignore b/saas-modules/discord4j/.gitignore similarity index 100% rename from discord4j/.gitignore rename to saas-modules/discord4j/.gitignore diff --git a/discord4j/README.md b/saas-modules/discord4j/README.md similarity index 100% rename from discord4j/README.md rename to saas-modules/discord4j/README.md diff --git a/discord4j/pom.xml b/saas-modules/discord4j/pom.xml similarity index 89% rename from discord4j/pom.xml rename to saas-modules/discord4j/pom.xml index 3ea85c05c7..ff398dd1a3 100644 --- a/discord4j/pom.xml +++ b/saas-modules/discord4j/pom.xml @@ -3,17 +3,14 @@ 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 discord4j - 0.0.1-SNAPSHOT discord4j Demo Discord bot using Discord4J + Spring Boot com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../parent-boot-2 + saas-modules + 1.0.0-SNAPSHOT diff --git a/discord4j/src/main/java/com/baeldung/discordbot/BotConfiguration.java b/saas-modules/discord4j/src/main/java/com/baeldung/discordbot/BotConfiguration.java similarity index 100% rename from discord4j/src/main/java/com/baeldung/discordbot/BotConfiguration.java rename to saas-modules/discord4j/src/main/java/com/baeldung/discordbot/BotConfiguration.java diff --git a/discord4j/src/main/java/com/baeldung/discordbot/DiscordBotApplication.java b/saas-modules/discord4j/src/main/java/com/baeldung/discordbot/DiscordBotApplication.java similarity index 100% rename from discord4j/src/main/java/com/baeldung/discordbot/DiscordBotApplication.java rename to saas-modules/discord4j/src/main/java/com/baeldung/discordbot/DiscordBotApplication.java diff --git a/discord4j/src/main/java/com/baeldung/discordbot/events/EventListener.java b/saas-modules/discord4j/src/main/java/com/baeldung/discordbot/events/EventListener.java similarity index 100% rename from discord4j/src/main/java/com/baeldung/discordbot/events/EventListener.java rename to saas-modules/discord4j/src/main/java/com/baeldung/discordbot/events/EventListener.java diff --git a/discord4j/src/main/java/com/baeldung/discordbot/events/MessageCreateListener.java b/saas-modules/discord4j/src/main/java/com/baeldung/discordbot/events/MessageCreateListener.java similarity index 100% rename from discord4j/src/main/java/com/baeldung/discordbot/events/MessageCreateListener.java rename to saas-modules/discord4j/src/main/java/com/baeldung/discordbot/events/MessageCreateListener.java diff --git a/discord4j/src/main/java/com/baeldung/discordbot/events/MessageListener.java b/saas-modules/discord4j/src/main/java/com/baeldung/discordbot/events/MessageListener.java similarity index 100% rename from discord4j/src/main/java/com/baeldung/discordbot/events/MessageListener.java rename to saas-modules/discord4j/src/main/java/com/baeldung/discordbot/events/MessageListener.java diff --git a/discord4j/src/main/java/com/baeldung/discordbot/events/MessageUpdateListener.java b/saas-modules/discord4j/src/main/java/com/baeldung/discordbot/events/MessageUpdateListener.java similarity index 100% rename from discord4j/src/main/java/com/baeldung/discordbot/events/MessageUpdateListener.java rename to saas-modules/discord4j/src/main/java/com/baeldung/discordbot/events/MessageUpdateListener.java diff --git a/discord4j/src/main/resources/application.yml b/saas-modules/discord4j/src/main/resources/application.yml similarity index 100% rename from discord4j/src/main/resources/application.yml rename to saas-modules/discord4j/src/main/resources/application.yml diff --git a/discord4j/src/test/java/com/baeldung/discordbot/DiscordBotLiveTest.java b/saas-modules/discord4j/src/test/java/com/baeldung/discordbot/DiscordBotLiveTest.java similarity index 100% rename from discord4j/src/test/java/com/baeldung/discordbot/DiscordBotLiveTest.java rename to saas-modules/discord4j/src/test/java/com/baeldung/discordbot/DiscordBotLiveTest.java diff --git a/saas-modules/pom.xml b/saas-modules/pom.xml index 7e8adebdd9..16ed50918c 100644 --- a/saas-modules/pom.xml +++ b/saas-modules/pom.xml @@ -16,11 +16,13 @@ + discord4j jira-rest-integration + sentry-servlet + slack stripe twilio twitter4j - sentry-servlet diff --git a/slack/README.md b/saas-modules/slack/README.md similarity index 100% rename from slack/README.md rename to saas-modules/slack/README.md diff --git a/slack/pom.xml b/saas-modules/slack/pom.xml similarity index 97% rename from slack/pom.xml rename to saas-modules/slack/pom.xml index 690bf5132c..326167c055 100644 --- a/slack/pom.xml +++ b/saas-modules/slack/pom.xml @@ -11,7 +11,7 @@ com.baeldung - parent-modules + saas-modules 1.0.0-SNAPSHOT diff --git a/slack/src/main/java/com/baeldung/examples/slack/DiskSpaceErrorChecker.java b/saas-modules/slack/src/main/java/com/baeldung/examples/slack/DiskSpaceErrorChecker.java similarity index 100% rename from slack/src/main/java/com/baeldung/examples/slack/DiskSpaceErrorChecker.java rename to saas-modules/slack/src/main/java/com/baeldung/examples/slack/DiskSpaceErrorChecker.java diff --git a/slack/src/main/java/com/baeldung/examples/slack/ErrorChecker.java b/saas-modules/slack/src/main/java/com/baeldung/examples/slack/ErrorChecker.java similarity index 100% rename from slack/src/main/java/com/baeldung/examples/slack/ErrorChecker.java rename to saas-modules/slack/src/main/java/com/baeldung/examples/slack/ErrorChecker.java diff --git a/slack/src/main/java/com/baeldung/examples/slack/ErrorReporter.java b/saas-modules/slack/src/main/java/com/baeldung/examples/slack/ErrorReporter.java similarity index 100% rename from slack/src/main/java/com/baeldung/examples/slack/ErrorReporter.java rename to saas-modules/slack/src/main/java/com/baeldung/examples/slack/ErrorReporter.java diff --git a/slack/src/main/java/com/baeldung/examples/slack/MainClass.java b/saas-modules/slack/src/main/java/com/baeldung/examples/slack/MainClass.java similarity index 100% rename from slack/src/main/java/com/baeldung/examples/slack/MainClass.java rename to saas-modules/slack/src/main/java/com/baeldung/examples/slack/MainClass.java diff --git a/slack/src/main/java/com/baeldung/examples/slack/SlackChannelErrorReporter.java b/saas-modules/slack/src/main/java/com/baeldung/examples/slack/SlackChannelErrorReporter.java similarity index 100% rename from slack/src/main/java/com/baeldung/examples/slack/SlackChannelErrorReporter.java rename to saas-modules/slack/src/main/java/com/baeldung/examples/slack/SlackChannelErrorReporter.java diff --git a/slack/src/main/java/com/baeldung/examples/slack/SlackUserErrorReporter.java b/saas-modules/slack/src/main/java/com/baeldung/examples/slack/SlackUserErrorReporter.java similarity index 100% rename from slack/src/main/java/com/baeldung/examples/slack/SlackUserErrorReporter.java rename to saas-modules/slack/src/main/java/com/baeldung/examples/slack/SlackUserErrorReporter.java diff --git a/slack/src/main/resources/logback.xml b/saas-modules/slack/src/main/resources/logback.xml similarity index 100% rename from slack/src/main/resources/logback.xml rename to saas-modules/slack/src/main/resources/logback.xml diff --git a/security-modules/pom.xml b/security-modules/pom.xml index ed88ef842e..d0edced4e0 100644 --- a/security-modules/pom.xml +++ b/security-modules/pom.xml @@ -17,7 +17,7 @@ apache-shiro cas cloud-foundry-uaa - + java-ee-8-security-api jee-7-security jjwt jwt diff --git a/spring-actuator/pom.xml b/spring-actuator/pom.xml new file mode 100644 index 0000000000..48dae45940 --- /dev/null +++ b/spring-actuator/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + spring-actuator + spring-actuator + war + Demo project for Spring Boot Actuator without Spring Boot + + + com.baeldung + parent-spring-6 + 0.0.1-SNAPSHOT + ../parent-spring-6 + + + + + jakarta.servlet + jakarta.servlet-api + 5.0.0 + provided + + + org.springframework + spring-webmvc + + + org.springframework + spring-test + test + + + org.springframework.boot + spring-boot-actuator-autoconfigure + ${spring-boot.version} + + + + org.eclipse.jetty + jetty-servlet + ${jetty.version} + + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.3.2 + + + + org.eclipse.jetty + jetty-maven-plugin + ${jetty.version} + + + + + + org.eclipse.jetty + jetty-maven-plugin + + + + + + 3.0.6 + 11.0.15 + + + diff --git a/spring-actuator/src/main/java/com/baeldung/spring/actuator/ActuatorConfiguration.java b/spring-actuator/src/main/java/com/baeldung/spring/actuator/ActuatorConfiguration.java new file mode 100644 index 0000000000..857db1a0d5 --- /dev/null +++ b/spring-actuator/src/main/java/com/baeldung/spring/actuator/ActuatorConfiguration.java @@ -0,0 +1,26 @@ +package com.baeldung.spring.actuator; + +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.actuate.info.InfoContributor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ActuatorConfiguration { + + @Bean + public HealthIndicator sampleHealthIndicator() { + return Health.up() + .withDetail("info", "Sample Health") + ::build; + } + + @Bean + public InfoContributor provideSampleInfos() { + return builder -> + builder + .withDetail("app-title", "Actuator Sample Application"); + + } +} diff --git a/spring-actuator/src/main/java/com/baeldung/spring/actuator/AppConfig.java b/spring-actuator/src/main/java/com/baeldung/spring/actuator/AppConfig.java new file mode 100644 index 0000000000..e080cc10e2 --- /dev/null +++ b/spring-actuator/src/main/java/com/baeldung/spring/actuator/AppConfig.java @@ -0,0 +1,11 @@ +package com.baeldung.spring.actuator; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.PropertySource; + +@EnableAutoConfiguration +@PropertySource("classpath:application.properties") +@ComponentScan(basePackageClasses = AppConfig.class) +public class AppConfig { +} diff --git a/spring-actuator/src/main/java/com/baeldung/spring/actuator/Start.java b/spring-actuator/src/main/java/com/baeldung/spring/actuator/Start.java new file mode 100644 index 0000000000..66899d1479 --- /dev/null +++ b/spring-actuator/src/main/java/com/baeldung/spring/actuator/Start.java @@ -0,0 +1,64 @@ +package com.baeldung.spring.actuator; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.ContextLoaderListener; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import org.springframework.web.servlet.DispatcherServlet; + +public class Start { + + private static final Logger logger = LoggerFactory.getLogger(Start.class); + private static final int DEFAULT_PORT = 8080; + private static final String CONTEXT_PATH = "/"; + private static final String CONFIG_LOCATION = AppConfig.class.getName(); + private static final String MAPPING_URL = "/*"; + + /* + * This application runs a Jetty webcontainer that runs the + * Spring Dispatcher Servlet. + */ + public static void main(String[] args) throws Exception { + new Start().startJetty(getPortFromArgs(args)); + } + + private static int getPortFromArgs(String[] args) { + if (args.length > 0) { + try { + return Integer.parseInt(args[0]); + } catch (NumberFormatException ignore) { + } + } + logger.info("No server port configured, falling back to {}", DEFAULT_PORT); + return DEFAULT_PORT; + } + + private void startJetty(int port) throws Exception { + logger.info("Starting server at port {}", port); + Server server = new Server(port); + server.setHandler(getServletContextHandler(getContext())); + server.start(); + logger.info("Server started at port {}", port); + server.join(); + } + + private static ServletContextHandler getServletContextHandler(WebApplicationContext context) { + ServletContextHandler contextHandler = new ServletContextHandler(); + contextHandler.setErrorHandler(null); + contextHandler.setContextPath(CONTEXT_PATH); + contextHandler.addServlet(new ServletHolder(new DispatcherServlet(context)), MAPPING_URL); + contextHandler.addEventListener(new ContextLoaderListener(context)); + return contextHandler; + } + + private static WebApplicationContext getContext() { + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.setConfigLocation(CONFIG_LOCATION); + return context; + } + +} diff --git a/spring-actuator/src/main/java/com/baeldung/spring/actuator/WebMvcConfiguration.java b/spring-actuator/src/main/java/com/baeldung/spring/actuator/WebMvcConfiguration.java new file mode 100644 index 0000000000..8da2166114 --- /dev/null +++ b/spring-actuator/src/main/java/com/baeldung/spring/actuator/WebMvcConfiguration.java @@ -0,0 +1,23 @@ +package com.baeldung.spring.actuator; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebMvcConfiguration { + + @Bean + public WebMvcConfigurer webMvcConfigurer() { + return new WebMvcConfigurer() { + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry + .addViewController("/") + .setViewName("redirect:/actuator"); + } + }; + } + +} diff --git a/spring-actuator/src/main/resources/application.properties b/spring-actuator/src/main/resources/application.properties new file mode 100644 index 0000000000..db3cdb647b --- /dev/null +++ b/spring-actuator/src/main/resources/application.properties @@ -0,0 +1,2 @@ +management.endpoints.web.exposure.include=* +management.endpoint.health.show-details=always diff --git a/spring-batch-2/pom.xml b/spring-batch-2/pom.xml index 12d31aca14..378191c91c 100644 --- a/spring-batch-2/pom.xml +++ b/spring-batch-2/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-boot-3 @@ -51,8 +51,9 @@ - 4.3.0 - 3.1.1 + 5.0.0 + 4.2.0 + com.baeldung.batch.SpringBootBatchProcessingApplication \ No newline at end of file diff --git a/spring-batch-2/src/main/java/com/baeldung/batch/BatchConfiguration.java b/spring-batch-2/src/main/java/com/baeldung/batch/BatchConfiguration.java index 0c053dd86c..770b6330dd 100644 --- a/spring-batch-2/src/main/java/com/baeldung/batch/BatchConfiguration.java +++ b/spring-batch-2/src/main/java/com/baeldung/batch/BatchConfiguration.java @@ -4,31 +4,24 @@ import javax.sql.DataSource; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.launch.support.RunIdIncrementer; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider; import org.springframework.batch.item.database.JdbcBatchItemWriter; import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder; import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; +import org.springframework.transaction.PlatformTransactionManager; @Configuration -@EnableBatchProcessing public class BatchConfiguration { - - @Autowired - public JobBuilderFactory jobBuilderFactory; - - @Autowired - public StepBuilderFactory stepBuilderFactory; @Value("${file.input}") private String fileInput; @@ -59,8 +52,8 @@ public class BatchConfiguration { } @Bean - public Job importUserJob(JobCompletionNotificationListener listener, Step step1) { - return jobBuilderFactory.get("importUserJob") + public Job importUserJob(JobRepository jobRepository, JobCompletionNotificationListener listener, Step step1) { + return new JobBuilder("importUserJob", jobRepository) .incrementer(new RunIdIncrementer()) .listener(listener) .flow(step1) @@ -69,9 +62,9 @@ public class BatchConfiguration { } @Bean - public Step step1(JdbcBatchItemWriter writer) { - return stepBuilderFactory.get("step1") - . chunk(10) + public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager, JdbcBatchItemWriter writer) { + return new StepBuilder("step1", jobRepository) + . chunk(10, transactionManager) .reader(reader()) .processor(processor()) .writer(writer) diff --git a/spring-batch-2/src/main/java/com/baeldung/batch/CoffeeItemProcessor.java b/spring-batch-2/src/main/java/com/baeldung/batch/CoffeeItemProcessor.java index b154b80453..bd4173e9ed 100644 --- a/spring-batch-2/src/main/java/com/baeldung/batch/CoffeeItemProcessor.java +++ b/spring-batch-2/src/main/java/com/baeldung/batch/CoffeeItemProcessor.java @@ -10,7 +10,7 @@ public class CoffeeItemProcessor implements ItemProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(CoffeeItemProcessor.class); @Override - public Coffee process(final Coffee coffee) throws Exception { + public Coffee process(final Coffee coffee) { String brand = coffee.getBrand().toUpperCase(); String origin = coffee.getOrigin().toUpperCase(); String chracteristics = coffee.getCharacteristics().toUpperCase(); diff --git a/spring-batch-2/src/main/java/com/baeldung/batch/JobCompletionNotificationListener.java b/spring-batch-2/src/main/java/com/baeldung/batch/JobCompletionNotificationListener.java index ca1de40aea..b61faeb13b 100644 --- a/spring-batch-2/src/main/java/com/baeldung/batch/JobCompletionNotificationListener.java +++ b/spring-batch-2/src/main/java/com/baeldung/batch/JobCompletionNotificationListener.java @@ -4,13 +4,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.listener.JobExecutionListenerSupport; +import org.springframework.batch.core.JobExecutionListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; @Component -public class JobCompletionNotificationListener extends JobExecutionListenerSupport { +public class JobCompletionNotificationListener implements JobExecutionListener { private static final Logger LOGGER = LoggerFactory.getLogger(JobCompletionNotificationListener.class); diff --git a/spring-batch-2/src/main/java/com/baeldung/batchscheduler/SpringBatchScheduler.java b/spring-batch-2/src/main/java/com/baeldung/batchscheduler/SpringBatchScheduler.java index c830a41855..dcb2bc5199 100644 --- a/spring-batch-2/src/main/java/com/baeldung/batchscheduler/SpringBatchScheduler.java +++ b/spring-batch-2/src/main/java/com/baeldung/batchscheduler/SpringBatchScheduler.java @@ -7,15 +7,16 @@ import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParametersBuilder; import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder; import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; @@ -24,17 +25,16 @@ import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.support.ScheduledMethodRunnable; +import org.springframework.transaction.PlatformTransactionManager; import java.util.Date; import java.util.IdentityHashMap; -import java.util.List; import java.util.Map; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @Configuration -@EnableBatchProcessing @EnableScheduling public class SpringBatchScheduler { @@ -46,21 +46,21 @@ public class SpringBatchScheduler { private final Map> scheduledTasks = new IdentityHashMap<>(); - @Autowired - private JobBuilderFactory jobBuilderFactory; - - @Autowired - private StepBuilderFactory stepBuilderFactory; - @Autowired private JobLauncher jobLauncher; + @Autowired + private JobRepository jobRepository; + + @Autowired + private PlatformTransactionManager transactionManager; + @Scheduled(fixedRate = 2000) public void launchJob() throws Exception { Date date = new Date(); logger.debug("scheduler starts at " + date); if (enabled.get()) { - JobExecution jobExecution = jobLauncher.run(job(), new JobParametersBuilder().addDate("launchDate", date) + JobExecution jobExecution = jobLauncher.run(job(jobRepository, transactionManager), new JobParametersBuilder().addDate("launchDate", date) .toJobParameters()); batchRunCounter.incrementAndGet(); logger.debug("Batch job ends with status as " + jobExecution.getStatus()); @@ -106,17 +106,16 @@ public class SpringBatchScheduler { } @Bean - public Job job() { - return jobBuilderFactory - .get("job") - .start(readBooks()) + public Job job(JobRepository jobRepository, PlatformTransactionManager transactionManager) { + return new JobBuilder("job", jobRepository) + .start(readBooks(jobRepository, transactionManager)) .build(); } @Bean - protected Step readBooks() { - return stepBuilderFactory.get("readBooks") - . chunk(2) + protected Step readBooks(JobRepository jobRepository, PlatformTransactionManager transactionManager) { + return new StepBuilder("readBooks", jobRepository) + . chunk(2, transactionManager) .reader(reader()) .writer(writer()) .build(); @@ -128,7 +127,7 @@ public class SpringBatchScheduler { .resource(new ClassPathResource("books.csv")) .delimited() .names(new String[] { "id", "name" }) - .fieldSetMapper(new BeanWrapperFieldSetMapper() { + .fieldSetMapper(new BeanWrapperFieldSetMapper<>() { { setTargetType(Book.class); } @@ -138,15 +137,10 @@ public class SpringBatchScheduler { @Bean public ItemWriter writer() { - return new ItemWriter() { - - @Override - public void write(List items) throws Exception { - logger.debug("writer..." + items.size()); - for (Book item : items) { - logger.debug(item.toString()); - } - + return items -> { + logger.debug("writer..." + items.size()); + for (Book item : items) { + logger.debug(item.toString()); } }; } diff --git a/spring-batch-2/src/test/java/com/baeldung/batch/SpringBootBatchIntegrationTest.java b/spring-batch-2/src/test/java/com/baeldung/batch/SpringBootBatchIntegrationTest.java index ba2b8a6a13..21fd7bf4b1 100644 --- a/spring-batch-2/src/test/java/com/baeldung/batch/SpringBootBatchIntegrationTest.java +++ b/spring-batch-2/src/test/java/com/baeldung/batch/SpringBootBatchIntegrationTest.java @@ -1,11 +1,10 @@ package com.baeldung.batch; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; -import org.junit.After; -import org.junit.Test; -import org.junit.runner.RunWith; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; @@ -13,16 +12,17 @@ import org.springframework.batch.test.JobLauncherTestUtils; import org.springframework.batch.test.JobRepositoryTestUtils; import org.springframework.batch.test.context.SpringBatchTest; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.PropertySource; import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; @SpringBatchTest -@SpringBootTest @DirtiesContext +@SpringJUnitConfig(BatchConfiguration.class) @PropertySource("classpath:application.properties") -@RunWith(SpringRunner.class) +@EnableAutoConfiguration public class SpringBootBatchIntegrationTest { @Autowired @@ -31,7 +31,10 @@ public class SpringBootBatchIntegrationTest { @Autowired private JobRepositoryTestUtils jobRepositoryTestUtils; - @After + @MockBean + private JobCompletionNotificationListener jobCompletionNotificationListener; + + @AfterEach public void cleanUp() { jobRepositoryTestUtils.removeJobExecutions(); } @@ -42,8 +45,8 @@ public class SpringBootBatchIntegrationTest { JobInstance jobInstance = jobExecution.getJobInstance(); ExitStatus jobExitStatus = jobExecution.getExitStatus(); - assertThat(jobInstance.getJobName(), is("importUserJob")); - assertThat(jobExitStatus.getExitCode(), is("COMPLETED")); + assertEquals("importUserJob", jobInstance.getJobName()); + assertEquals("COMPLETED", jobExitStatus.getExitCode()); } } diff --git a/spring-batch-2/src/test/java/com/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java b/spring-batch-2/src/test/java/com/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java index 61e5a1dd74..297e8d989f 100644 --- a/spring-batch-2/src/test/java/com/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java +++ b/spring-batch-2/src/test/java/com/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java @@ -1,28 +1,20 @@ package com.baeldung.batchscheduler; -import com.baeldung.batchscheduler.SpringBatchScheduler; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.batch.test.context.SpringBatchTest; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.PropertySource; import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor; import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.junit4.SpringRunner; import static org.awaitility.Awaitility.await; import static java.util.concurrent.TimeUnit.*; +import static org.junit.jupiter.api.Assertions.assertEquals; -@SpringBatchTest @SpringBootTest @DirtiesContext @PropertySource("classpath:application.properties") -@RunWith(SpringRunner.class) public class SpringBatchSchedulerIntegrationTest { @Autowired @@ -31,37 +23,36 @@ public class SpringBatchSchedulerIntegrationTest { @Test public void stopJobsWhenSchedulerDisabled() { SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); - await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter() + await().untilAsserted(() -> assertEquals(2, schedulerBean.getBatchRunCounter() .get())); schedulerBean.stop(); await().atLeast(3, SECONDS); - Assert.assertEquals(2, schedulerBean.getBatchRunCounter() - .get()); + assertEquals(2, schedulerBean.getBatchRunCounter().get()); } @Test - public void stopJobSchedulerWhenSchedulerDestroyed() throws Exception { + public void stopJobSchedulerWhenSchedulerDestroyed() { ScheduledAnnotationBeanPostProcessor bean = context.getBean(ScheduledAnnotationBeanPostProcessor.class); SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); - await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter() + await().untilAsserted(() -> assertEquals(2, schedulerBean.getBatchRunCounter() .get())); bean.postProcessBeforeDestruction(schedulerBean, "SpringBatchScheduler"); await().atLeast(3, SECONDS); - Assert.assertEquals(2, schedulerBean.getBatchRunCounter() + assertEquals(2, schedulerBean.getBatchRunCounter() .get()); } @Test - public void stopJobSchedulerWhenFutureTasksCancelled() throws Exception { + public void stopJobSchedulerWhenFutureTasksCancelled() { SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); - await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter() + await().untilAsserted(() -> assertEquals(2, schedulerBean.getBatchRunCounter() .get())); schedulerBean.cancelFutureSchedulerTasks(); await().atLeast(3, SECONDS); - Assert.assertEquals(2, schedulerBean.getBatchRunCounter() + assertEquals(2, schedulerBean.getBatchRunCounter() .get()); } diff --git a/spring-batch/pom.xml b/spring-batch/pom.xml index e9d3afa376..810ddcdcdd 100644 --- a/spring-batch/pom.xml +++ b/spring-batch/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-boot-3 @@ -22,25 +22,15 @@ jackson-datatype-jsr310 ${jackson-datatype.version} - - - javax.xml.bind - jaxb-api - ${jaxb.version} - + jakarta.xml.bind + jakarta.xml.bind-api + 4.0.0 org.glassfish.jaxb jaxb-runtime ${jaxb.version} - - - - - org.xerial - sqlite-jdbc - ${sqlite.version} org.springframework @@ -53,20 +43,9 @@ - - org.springframework - spring-jdbc - ${spring.version} - - - org.springframework.batch - spring-batch-core - ${spring.batch.version} - org.springframework.batch spring-batch-test - ${spring.batch.version} com.opencsv @@ -78,19 +57,29 @@ spring-boot-starter-batch - org.hsqldb - hsqldb - runtime + org.apache.httpcomponents + httpclient + ${http-client.version} + + + org.codehaus.jettison + jettison + ${jettison.version} + + + com.h2database + h2 - 5.3.0 - 4.3.0 - 3.15.1 - 4.1 - 2.3.1 - 2.12.3 + 6.0.6 + 5.7.1 + 4.0.2 + 2.14.2 + 4.5.14 + 1.5.3 + com.baeldung.batchtesting.SpringBatchApplication \ No newline at end of file diff --git a/spring-batch/repository.sqlite b/spring-batch/repository.sqlite index b6a954554c..ddf5d0c16f 100644 Binary files a/spring-batch/repository.sqlite and b/spring-batch/repository.sqlite differ diff --git a/spring-batch/src/main/java/com/baeldung/batch/App.java b/spring-batch/src/main/java/com/baeldung/batch/App.java index c2db446965..c5823590d8 100644 --- a/spring-batch/src/main/java/com/baeldung/batch/App.java +++ b/spring-batch/src/main/java/com/baeldung/batch/App.java @@ -18,20 +18,19 @@ public class App { public static void main(final String[] args) { // Spring Java config final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - context.register(SpringConfig.class); + context.getEnvironment().addActiveProfile("spring"); context.register(SpringBatchConfig.class); context.register(SpringBatchRetryConfig.class); context.refresh(); // Spring xml config - // ApplicationContext context = new ClassPathXmlApplicationContext("spring-batch.xml"); + // ApplicationContext context = new ClassPathXmlApplicationContext("spring-batch-intro.xml"); runJob(context, "firstBatchJob"); runJob(context, "skippingBatchJob"); runJob(context, "skipPolicyBatchJob"); runJob(context, "retryBatchJob"); - } private static void runJob(AnnotationConfigApplicationContext context, String batchJobName) { diff --git a/spring-batch/src/main/java/com/baeldung/batch/SpringBatchConfig.java b/spring-batch/src/main/java/com/baeldung/batch/SpringBatchConfig.java index 5546df22fc..5d999c68e7 100644 --- a/spring-batch/src/main/java/com/baeldung/batch/SpringBatchConfig.java +++ b/spring-batch/src/main/java/com/baeldung/batch/SpringBatchConfig.java @@ -1,5 +1,7 @@ package com.baeldung.batch; +import javax.sql.DataSource; + import com.baeldung.batch.model.Transaction; import com.baeldung.batch.service.CustomItemProcessor; import com.baeldung.batch.service.CustomSkipPolicy; @@ -7,10 +9,15 @@ import com.baeldung.batch.service.MissingUsernameException; import com.baeldung.batch.service.NegativeAmountException; import com.baeldung.batch.service.RecordFieldSetMapper; import com.baeldung.batch.service.SkippingItemProcessor; + import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.job.builder.JobBuilder; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.core.launch.support.TaskExecutorJobLauncher; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; +import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; @@ -19,24 +26,23 @@ import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.mapping.DefaultLineMapper; import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; import org.springframework.batch.item.xml.StaxEventItemWriter; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.batch.support.transaction.ResourcelessTransactionManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.core.io.Resource; +import org.springframework.core.io.WritableResource; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.oxm.Marshaller; import org.springframework.oxm.jaxb.Jaxb2Marshaller; +import org.springframework.transaction.PlatformTransactionManager; -import java.text.ParseException; - +@Configuration @Profile("spring") public class SpringBatchConfig { - @Autowired - private JobBuilderFactory jobBuilderFactory; - - @Autowired - private StepBuilderFactory stepBuilderFactory; @Value("input/record.csv") private Resource inputCsv; @@ -45,9 +51,9 @@ public class SpringBatchConfig { private Resource invalidInputCsv; @Value("file:xml/output.xml") - private Resource outputXml; + private WritableResource outputXml; - public ItemReader itemReader(Resource inputData) throws UnexpectedInputException, ParseException { + public ItemReader itemReader(Resource inputData) throws UnexpectedInputException { FlatFileItemReader reader = new FlatFileItemReader<>(); DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer(); String[] tokens = {"username", "userid", "transactiondate", "amount"}; @@ -88,10 +94,10 @@ public class SpringBatchConfig { } @Bean - protected Step step1(@Qualifier("itemProcessor") ItemProcessor processor, ItemWriter writer) throws ParseException { - return stepBuilderFactory - .get("step1") - . chunk(10) + protected Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("itemProcessor") ItemProcessor processor, ItemWriter writer) { + return new StepBuilder("step1", jobRepository) + . chunk(10, transactionManager) .reader(itemReader(inputCsv)) .processor(processor) .writer(writer) @@ -99,16 +105,15 @@ public class SpringBatchConfig { } @Bean(name = "firstBatchJob") - public Job job(@Qualifier("step1") Step step1) { - return jobBuilderFactory.get("firstBatchJob").start(step1).build(); + public Job job(JobRepository jobRepository, @Qualifier("step1") Step step1) { + return new JobBuilder("firstBatchJob", jobRepository).preventRestart().start(step1).build(); } @Bean - public Step skippingStep(@Qualifier("skippingItemProcessor") ItemProcessor processor, - ItemWriter writer) throws ParseException { - return stepBuilderFactory - .get("skippingStep") - .chunk(10) + public Step skippingStep(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("skippingItemProcessor") ItemProcessor processor, ItemWriter writer) { + return new StepBuilder("skippingStep", jobRepository) + .chunk(10, transactionManager) .reader(itemReader(invalidInputCsv)) .processor(processor) .writer(writer) @@ -120,19 +125,18 @@ public class SpringBatchConfig { } @Bean(name = "skippingBatchJob") - public Job skippingJob(@Qualifier("skippingStep") Step skippingStep) { - return jobBuilderFactory - .get("skippingBatchJob") + public Job skippingJob(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("skippingStep") Step skippingStep) { + return new JobBuilder("skippingBatchJob", jobRepository) .start(skippingStep) + .preventRestart() .build(); } @Bean - public Step skipPolicyStep(@Qualifier("skippingItemProcessor") ItemProcessor processor, - ItemWriter writer) throws ParseException { - return stepBuilderFactory - .get("skipPolicyStep") - .chunk(10) + public Step skipPolicyStep(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("skippingItemProcessor") ItemProcessor processor, + ItemWriter writer) { + return new StepBuilder("skipPolicyStep", jobRepository) + .chunk(10, transactionManager) .reader(itemReader(invalidInputCsv)) .processor(processor) .writer(writer) @@ -142,11 +146,44 @@ public class SpringBatchConfig { } @Bean(name = "skipPolicyBatchJob") - public Job skipPolicyBatchJob(@Qualifier("skipPolicyStep") Step skipPolicyStep) { - return jobBuilderFactory - .get("skipPolicyBatchJob") + public Job skipPolicyBatchJob(JobRepository jobRepository, @Qualifier("skipPolicyStep") Step skipPolicyStep) { + return new JobBuilder("skipPolicyBatchJob", jobRepository) .start(skipPolicyStep) + .preventRestart() .build(); } + public DataSource dataSource() { + EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); + return builder.setType(EmbeddedDatabaseType.H2) + .addScript("classpath:org/springframework/batch/core/schema-drop-h2.sql") + .addScript("classpath:org/springframework/batch/core/schema-h2.sql") + .build(); + } + + @Bean(name = "transactionManager") + public PlatformTransactionManager getTransactionManager() { + return new ResourcelessTransactionManager(); + } + + @Bean(name = "jobRepository") + public JobRepository getJobRepository() throws Exception { + JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); + factory.setDataSource(dataSource()); + factory.setTransactionManager(getTransactionManager()); + // JobRepositoryFactoryBean's methods Throws Generic Exception, + // it would have been better to have a specific one + factory.afterPropertiesSet(); + return factory.getObject(); + } + + @Bean(name = "jobLauncher") + public JobLauncher getJobLauncher() throws Exception { + TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher(); + // TaskExecutorJobLauncher's methods Throws Generic Exception, + // it would have been better to have a specific one + jobLauncher.setJobRepository(getJobRepository()); + jobLauncher.afterPropertiesSet(); + return jobLauncher; + } } diff --git a/spring-batch/src/main/java/com/baeldung/batch/SpringBatchRetryConfig.java b/spring-batch/src/main/java/com/baeldung/batch/SpringBatchRetryConfig.java index a329df3016..4b6246c074 100644 --- a/spring-batch/src/main/java/com/baeldung/batch/SpringBatchRetryConfig.java +++ b/spring-batch/src/main/java/com/baeldung/batch/SpringBatchRetryConfig.java @@ -1,17 +1,18 @@ package com.baeldung.batch; +import com.baeldung.batch.model.Transaction; +import com.baeldung.batch.service.RecordFieldSetMapper; +import com.baeldung.batch.service.RetryItemProcessor; + import org.apache.http.client.config.RequestConfig; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; -import com.baeldung.batch.model.Transaction; -import com.baeldung.batch.service.RecordFieldSetMapper; -import com.baeldung.batch.service.RetryItemProcessor; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.job.builder.JobBuilder; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; @@ -19,38 +20,30 @@ import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.mapping.DefaultLineMapper; import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; import org.springframework.batch.item.xml.StaxEventItemWriter; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; +import org.springframework.core.io.WritableResource; import org.springframework.dao.DeadlockLoserDataAccessException; import org.springframework.oxm.Marshaller; import org.springframework.oxm.jaxb.Jaxb2Marshaller; - -import java.text.ParseException; +import org.springframework.transaction.PlatformTransactionManager; @Configuration -@EnableBatchProcessing public class SpringBatchRetryConfig { - + private static final String[] tokens = { "username", "userid", "transactiondate", "amount" }; private static final int TWO_SECONDS = 2000; - @Autowired - private JobBuilderFactory jobBuilderFactory; - - @Autowired - private StepBuilderFactory stepBuilderFactory; - @Value("input/recordRetry.csv") private Resource inputCsv; @Value("file:xml/retryOutput.xml") - private Resource outputXml; + private WritableResource outputXml; - public ItemReader itemReader(Resource inputData) throws ParseException { + public ItemReader itemReader(Resource inputData) { DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer(); tokenizer.setNames(tokens); DefaultLineMapper lineMapper = new DefaultLineMapper<>(); @@ -93,10 +86,11 @@ public class SpringBatchRetryConfig { } @Bean - public Step retryStep(@Qualifier("retryItemProcessor") ItemProcessor processor, - ItemWriter writer) throws ParseException { - return stepBuilderFactory.get("retryStep") - .chunk(10) + public Step retryStep( + JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("retryItemProcessor") ItemProcessor processor, + ItemWriter writer) { + return new StepBuilder("retryStep", jobRepository) + .chunk(10, transactionManager) .reader(itemReader(inputCsv)) .processor(processor) .writer(writer) @@ -108,9 +102,8 @@ public class SpringBatchRetryConfig { } @Bean(name = "retryBatchJob") - public Job retryJob(@Qualifier("retryStep") Step retryStep) { - return jobBuilderFactory - .get("retryBatchJob") + public Job retryJob(JobRepository jobRepository, @Qualifier("retryStep") Step retryStep) { + return new JobBuilder("retryBatchJob", jobRepository) .start(retryStep) .build(); } diff --git a/spring-batch/src/main/java/com/baeldung/batch/SpringConfig.java b/spring-batch/src/main/java/com/baeldung/batch/SpringConfig.java deleted file mode 100644 index dc6c242996..0000000000 --- a/spring-batch/src/main/java/com/baeldung/batch/SpringConfig.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.baeldung.batch; - -import java.net.MalformedURLException; - -import javax.sql.DataSource; - -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.core.launch.support.SimpleJobLauncher; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; -import org.springframework.batch.support.transaction.ResourcelessTransactionManager; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.core.io.Resource; -import org.springframework.jdbc.datasource.DriverManagerDataSource; -import org.springframework.jdbc.datasource.init.DataSourceInitializer; -import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; -import org.springframework.transaction.PlatformTransactionManager; - -@Configuration -@EnableBatchProcessing -@Profile("spring") -public class SpringConfig { - - @Value("org/springframework/batch/core/schema-drop-sqlite.sql") - private Resource dropReopsitoryTables; - - @Value("org/springframework/batch/core/schema-sqlite.sql") - private Resource dataReopsitorySchema; - - @Bean - public DataSource dataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName("org.sqlite.JDBC"); - dataSource.setUrl("jdbc:sqlite:repository.sqlite"); - return dataSource; - } - - @Bean - public DataSourceInitializer dataSourceInitializer(DataSource dataSource) throws MalformedURLException { - ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); - - databasePopulator.addScript(dropReopsitoryTables); - databasePopulator.addScript(dataReopsitorySchema); - databasePopulator.setIgnoreFailedDrops(true); - - DataSourceInitializer initializer = new DataSourceInitializer(); - initializer.setDataSource(dataSource); - initializer.setDatabasePopulator(databasePopulator); - - return initializer; - } - - private JobRepository getJobRepository() throws Exception { - JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); - factory.setDataSource(dataSource()); - factory.setTransactionManager(getTransactionManager()); - // JobRepositoryFactoryBean's methods Throws Generic Exception, - // it would have been better to have a specific one - factory.afterPropertiesSet(); - return (JobRepository) factory.getObject(); - } - - private PlatformTransactionManager getTransactionManager() { - return new ResourcelessTransactionManager(); - } - - public JobLauncher getJobLauncher() throws Exception { - SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); - // SimpleJobLauncher's methods Throws Generic Exception, - // it would have been better to have a specific one - jobLauncher.setJobRepository(getJobRepository()); - jobLauncher.afterPropertiesSet(); - return jobLauncher; - } - -} \ No newline at end of file diff --git a/spring-batch/src/main/java/com/baeldung/batch/model/Transaction.java b/spring-batch/src/main/java/com/baeldung/batch/model/Transaction.java index ffb6d59a79..c4ca36c1bc 100644 --- a/spring-batch/src/main/java/com/baeldung/batch/model/Transaction.java +++ b/spring-batch/src/main/java/com/baeldung/batch/model/Transaction.java @@ -1,10 +1,11 @@ package com.baeldung.batch.model; +import java.time.LocalDateTime; + import com.baeldung.batch.service.adapter.LocalDateTimeAdapter; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import java.time.LocalDateTime; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @SuppressWarnings("restriction") @XmlRootElement(name = "transactionRecord") diff --git a/spring-batch/src/main/java/com/baeldung/batch/partitioner/CustomMultiResourcePartitioner.java b/spring-batch/src/main/java/com/baeldung/batch/partitioner/CustomMultiResourcePartitioner.java index 4fade76ffc..1ff74ce192 100644 --- a/spring-batch/src/main/java/com/baeldung/batch/partitioner/CustomMultiResourcePartitioner.java +++ b/spring-batch/src/main/java/com/baeldung/batch/partitioner/CustomMultiResourcePartitioner.java @@ -60,7 +60,7 @@ public class CustomMultiResourcePartitioner implements Partitioner { */ @Override public Map partition(int gridSize) { - Map map = new HashMap(gridSize); + Map map = new HashMap<>(gridSize); int i = 0, k = 1; for (Resource resource : resources) { ExecutionContext context = new ExecutionContext(); diff --git a/spring-batch/src/main/java/com/baeldung/batch/partitioner/SpringbatchPartitionConfig.java b/spring-batch/src/main/java/com/baeldung/batch/partitioner/SpringBatchPartitionConfig.java similarity index 77% rename from spring-batch/src/main/java/com/baeldung/batch/partitioner/SpringbatchPartitionConfig.java rename to spring-batch/src/main/java/com/baeldung/batch/partitioner/SpringBatchPartitionConfig.java index b08c95af53..ceacb36e4d 100644 --- a/spring-batch/src/main/java/com/baeldung/batch/partitioner/SpringbatchPartitionConfig.java +++ b/spring-batch/src/main/java/com/baeldung/batch/partitioner/SpringBatchPartitionConfig.java @@ -5,13 +5,13 @@ import com.baeldung.batch.service.RecordFieldSetMapper; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepScope; +import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.core.launch.support.SimpleJobLauncher; +import org.springframework.batch.core.launch.support.TaskExecutorJobLauncher; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; +import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.item.UnexpectedInputException; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.mapping.DefaultLineMapper; @@ -36,42 +36,35 @@ import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; import java.io.IOException; -import java.net.MalformedURLException; import java.text.ParseException; @Configuration @EnableBatchProcessing -public class SpringbatchPartitionConfig { +public class SpringBatchPartitionConfig { @Autowired - ResourcePatternResolver resoursePatternResolver; - - @Autowired - private JobBuilderFactory jobs; - - @Autowired - private StepBuilderFactory steps; + private ResourcePatternResolver resourcePatternResolver; @Bean(name = "partitionerJob") - public Job partitionerJob() throws UnexpectedInputException, MalformedURLException, ParseException { - return jobs.get("partitionerJob") - .start(partitionStep()) + public Job partitionerJob(JobRepository jobRepository, PlatformTransactionManager transactionManager) throws UnexpectedInputException, ParseException { + return new JobBuilder("partitionerJob", jobRepository) + .start(partitionStep(jobRepository, transactionManager)) .build(); } @Bean - public Step partitionStep() throws UnexpectedInputException, MalformedURLException, ParseException { - return steps.get("partitionStep") + public Step partitionStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) throws UnexpectedInputException, ParseException { + return new StepBuilder("partitionStep", jobRepository) .partitioner("slaveStep", partitioner()) - .step(slaveStep()) + .step(slaveStep(jobRepository, transactionManager)) .taskExecutor(taskExecutor()) .build(); } @Bean - public Step slaveStep() throws UnexpectedInputException, MalformedURLException, ParseException { - return steps.get("slaveStep") - .chunk(1) + public Step slaveStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) throws UnexpectedInputException, ParseException { + return new StepBuilder("slaveStep", jobRepository) + .chunk(1, transactionManager) .reader(itemReader(null)) .writer(itemWriter(marshaller(), null)) .build(); @@ -82,7 +75,7 @@ public class SpringbatchPartitionConfig { CustomMultiResourcePartitioner partitioner = new CustomMultiResourcePartitioner(); Resource[] resources; try { - resources = resoursePatternResolver.getResources("file:src/main/resources/input/partitioner/*.csv"); + resources = resourcePatternResolver.getResources("file:src/main/resources/input/partitioner/*.csv"); } catch (IOException e) { throw new RuntimeException("I/O problems when resolving the input file pattern.", e); } @@ -108,7 +101,7 @@ public class SpringbatchPartitionConfig { @Bean(destroyMethod = "") @StepScope - public StaxEventItemWriter itemWriter(Marshaller marshaller, @Value("#{stepExecutionContext[opFileName]}") String filename) throws MalformedURLException { + public StaxEventItemWriter itemWriter(Marshaller marshaller, @Value("#{stepExecutionContext[opFileName]}") String filename) { StaxEventItemWriter itemWriter = new StaxEventItemWriter<>(); itemWriter.setMarshaller(marshaller); itemWriter.setRootTagName("transactionRecord"); @@ -133,7 +126,8 @@ public class SpringbatchPartitionConfig { return taskExecutor; } - private JobRepository getJobRepository() throws Exception { + @Bean(name = "jobRepository") + public JobRepository getJobRepository() throws Exception { JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); factory.setDataSource(dataSource()); factory.setTransactionManager(getTransactionManager()); @@ -143,20 +137,23 @@ public class SpringbatchPartitionConfig { return factory.getObject(); } - private DataSource dataSource() { + @Bean(name = "dataSource") + public DataSource dataSource() { EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); - return builder.setType(EmbeddedDatabaseType.HSQL) + return builder.setType(EmbeddedDatabaseType.H2) .addScript("classpath:org/springframework/batch/core/schema-drop-h2.sql") .addScript("classpath:org/springframework/batch/core/schema-h2.sql") .build(); } - private PlatformTransactionManager getTransactionManager() { + @Bean(name = "transactionManager") + public PlatformTransactionManager getTransactionManager() { return new ResourcelessTransactionManager(); } + @Bean(name = "jobLauncher") public JobLauncher getJobLauncher() throws Exception { - SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); + TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher(); // SimpleJobLauncher's methods Throws Generic Exception, // it would have been better to have a specific one jobLauncher.setJobRepository(getJobRepository()); diff --git a/spring-batch/src/main/java/com/baeldung/batch/partitioner/SpringbatchPartitionerApp.java b/spring-batch/src/main/java/com/baeldung/batch/partitioner/SpringBatchPartitionerApp.java similarity index 89% rename from spring-batch/src/main/java/com/baeldung/batch/partitioner/SpringbatchPartitionerApp.java rename to spring-batch/src/main/java/com/baeldung/batch/partitioner/SpringBatchPartitionerApp.java index e755e21ca9..a1661e750e 100644 --- a/spring-batch/src/main/java/com/baeldung/batch/partitioner/SpringbatchPartitionerApp.java +++ b/spring-batch/src/main/java/com/baeldung/batch/partitioner/SpringBatchPartitionerApp.java @@ -8,14 +8,14 @@ import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.context.annotation.AnnotationConfigApplicationContext; -public class SpringbatchPartitionerApp { +public class SpringBatchPartitionerApp { - private static final Logger LOGGER = LoggerFactory.getLogger(SpringbatchPartitionerApp.class); + private static final Logger LOGGER = LoggerFactory.getLogger(SpringBatchPartitionerApp.class); public static void main(final String[] args) { // Spring Java config final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - context.register(SpringbatchPartitionConfig.class); + context.register(SpringBatchPartitionConfig.class); context.refresh(); final JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher"); diff --git a/spring-batch/src/main/java/com/baeldung/batch/service/CustomSkipPolicy.java b/spring-batch/src/main/java/com/baeldung/batch/service/CustomSkipPolicy.java index 25401de022..af6fe20529 100644 --- a/spring-batch/src/main/java/com/baeldung/batch/service/CustomSkipPolicy.java +++ b/spring-batch/src/main/java/com/baeldung/batch/service/CustomSkipPolicy.java @@ -9,19 +9,13 @@ public class CustomSkipPolicy implements SkipPolicy { private static final int INVALID_TX_AMOUNT_LIMIT = -1000; @Override - public boolean shouldSkip(Throwable throwable, int skipCount) throws SkipLimitExceededException { - + public boolean shouldSkip(Throwable throwable, long skipCount) throws SkipLimitExceededException { if (throwable instanceof MissingUsernameException && skipCount < MAX_SKIP_COUNT) { return true; } - if (throwable instanceof NegativeAmountException && skipCount < MAX_SKIP_COUNT ) { - NegativeAmountException ex = (NegativeAmountException) throwable; - if(ex.getAmount() < INVALID_TX_AMOUNT_LIMIT){ - return false; - } else{ - return true; - } + if (throwable instanceof NegativeAmountException ex && skipCount < MAX_SKIP_COUNT ) { + return ex.getAmount() >= INVALID_TX_AMOUNT_LIMIT; } return false; diff --git a/spring-batch/src/main/java/com/baeldung/batch/service/RecordFieldSetMapper.java b/spring-batch/src/main/java/com/baeldung/batch/service/RecordFieldSetMapper.java index 09478e9a30..97c77d9e6a 100644 --- a/spring-batch/src/main/java/com/baeldung/batch/service/RecordFieldSetMapper.java +++ b/spring-batch/src/main/java/com/baeldung/batch/service/RecordFieldSetMapper.java @@ -10,7 +10,7 @@ import java.time.format.DateTimeFormatter; public class RecordFieldSetMapper implements FieldSetMapper { - public Transaction mapFieldSet(FieldSet fieldSet) throws BindException { + public Transaction mapFieldSet(FieldSet fieldSet) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyy"); diff --git a/spring-batch/src/main/java/com/baeldung/batch/service/RetryItemProcessor.java b/spring-batch/src/main/java/com/baeldung/batch/service/RetryItemProcessor.java index c380e2c0ab..aa49680b2a 100644 --- a/spring-batch/src/main/java/com/baeldung/batch/service/RetryItemProcessor.java +++ b/spring-batch/src/main/java/com/baeldung/batch/service/RetryItemProcessor.java @@ -5,15 +5,13 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import com.baeldung.batch.model.Transaction; -import org.codehaus.jettison.json.JSONException; + import org.codehaus.jettison.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.item.ItemProcessor; import org.springframework.beans.factory.annotation.Autowired; -import java.io.IOException; - public class RetryItemProcessor implements ItemProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(RetryItemProcessor.class); @@ -22,7 +20,7 @@ public class RetryItemProcessor implements ItemProcessor { private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; diff --git a/spring-batch/src/main/java/com/baeldung/batch/springboot/SpringBootBatchConfig.java b/spring-batch/src/main/java/com/baeldung/batch/springboot/SpringBootBatchConfig.java index 57531ebc39..6c463de5dc 100644 --- a/spring-batch/src/main/java/com/baeldung/batch/springboot/SpringBootBatchConfig.java +++ b/spring-batch/src/main/java/com/baeldung/batch/springboot/SpringBootBatchConfig.java @@ -5,8 +5,9 @@ import com.baeldung.batch.service.*; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.job.builder.JobBuilder; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; @@ -15,27 +16,21 @@ import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.mapping.DefaultLineMapper; import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; import org.springframework.batch.item.xml.StaxEventItemWriter; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.core.io.Resource; +import org.springframework.core.io.WritableResource; import org.springframework.oxm.Marshaller; import org.springframework.oxm.jaxb.Jaxb2Marshaller; - -import java.text.ParseException; +import org.springframework.transaction.PlatformTransactionManager; @Configuration @EnableBatchProcessing @Profile("spring-boot") public class SpringBootBatchConfig { - @Autowired - private JobBuilderFactory jobBuilderFactory; - - @Autowired - private StepBuilderFactory stepBuilderFactory; @Value("input/record.csv") private Resource inputCsv; @@ -44,9 +39,9 @@ public class SpringBootBatchConfig { private Resource invalidInputCsv; @Value("file:xml/output.xml") - private Resource outputXml; + private WritableResource outputXml; - public ItemReader itemReader(Resource inputData) throws UnexpectedInputException, ParseException { + public ItemReader itemReader(Resource inputData) throws UnexpectedInputException { FlatFileItemReader reader = new FlatFileItemReader<>(); DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer(); String[] tokens = {"username", "userid", "transactiondate", "amount"}; @@ -86,11 +81,10 @@ public class SpringBootBatchConfig { return marshaller3; } - @Bean - protected Step step1(@Qualifier("itemProcessor") ItemProcessor processor, ItemWriter itemWriter3) throws ParseException { - return stepBuilderFactory - .get("step1") - . chunk(10) + @Bean(name = "step1") + protected Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("itemProcessor") ItemProcessor processor, ItemWriter itemWriter3) { + return new StepBuilder("step1", jobRepository) + . chunk(10, transactionManager) .reader(itemReader(inputCsv)) .processor(processor) .writer(itemWriter3) @@ -98,16 +92,15 @@ public class SpringBootBatchConfig { } @Bean(name = "firstBatchJob") - public Job job(@Qualifier("step1") Step step1) { - return jobBuilderFactory.get("firstBatchJob").start(step1).build(); + public Job job(@Qualifier("step1") Step step1, JobRepository jobRepository) { + return new JobBuilder("firstBatchJob", jobRepository).start(step1).build(); } @Bean - public Step skippingStep(@Qualifier("skippingItemProcessor") ItemProcessor processor, - ItemWriter itemWriter3) throws ParseException { - return stepBuilderFactory - .get("skippingStep") - .chunk(10) + public Step skippingStep(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("skippingItemProcessor") ItemProcessor processor, + ItemWriter itemWriter3) { + return new StepBuilder("skippingStep", jobRepository) + .chunk(10, transactionManager) .reader(itemReader(invalidInputCsv)) .processor(processor) .writer(itemWriter3) @@ -119,19 +112,17 @@ public class SpringBootBatchConfig { } @Bean(name = "skippingBatchJob") - public Job skippingJob(@Qualifier("skippingStep") Step skippingStep) { - return jobBuilderFactory - .get("skippingBatchJob") + public Job skippingJob(JobRepository jobRepository, @Qualifier("skippingStep") Step skippingStep) { + return new JobBuilder("skippingBatchJob", jobRepository) .start(skippingStep) .build(); } - @Bean - public Step skipPolicyStep(@Qualifier("skippingItemProcessor") ItemProcessor processor, - ItemWriter itemWriter3) throws ParseException { - return stepBuilderFactory - .get("skipPolicyStep") - .chunk(10) + @Bean(name = "skipPolicyStep") + public Step skipPolicyStep(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("skippingItemProcessor") ItemProcessor processor, + ItemWriter itemWriter3) { + return new StepBuilder("skipPolicyStep", jobRepository) + .chunk(10, transactionManager) .reader(itemReader(invalidInputCsv)) .processor(processor) .writer(itemWriter3) @@ -141,11 +132,9 @@ public class SpringBootBatchConfig { } @Bean(name = "skipPolicyBatchJob") - public Job skipPolicyBatchJob(@Qualifier("skipPolicyStep") Step skipPolicyStep) { - return jobBuilderFactory - .get("skipPolicyBatchJob") + public Job skipPolicyBatchJob(JobRepository jobRepository, @Qualifier("skipPolicyStep") Step skipPolicyStep) { + return new JobBuilder("skipPolicyBatchJob", jobRepository) .start(skipPolicyStep) .build(); } - } diff --git a/spring-batch/src/main/java/com/baeldung/batchtesting/SpringBatchConfiguration.java b/spring-batch/src/main/java/com/baeldung/batchtesting/SpringBatchConfiguration.java index 664db3fbba..547074ff84 100644 --- a/spring-batch/src/main/java/com/baeldung/batchtesting/SpringBatchConfiguration.java +++ b/spring-batch/src/main/java/com/baeldung/batchtesting/SpringBatchConfiguration.java @@ -1,7 +1,5 @@ package com.baeldung.batchtesting; -import java.io.IOException; - import com.baeldung.batchtesting.model.Book; import com.baeldung.batchtesting.model.BookDetails; import com.baeldung.batchtesting.model.BookRecord; @@ -12,10 +10,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepScope; +import org.springframework.batch.core.job.builder.JobBuilder; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.file.FlatFileItemReader; @@ -25,27 +23,19 @@ import org.springframework.batch.item.json.JacksonJsonObjectMarshaller; import org.springframework.batch.item.json.JsonFileItemWriter; import org.springframework.batch.item.json.builder.JsonFileItemWriterBuilder; import org.springframework.batch.item.support.ListItemWriter; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.FileSystemResource; - +import org.springframework.transaction.PlatformTransactionManager; @Configuration -@EnableBatchProcessing public class SpringBatchConfiguration { private static Logger LOGGER = LoggerFactory.getLogger(SpringBatchConfiguration.class); private static final String[] TOKENS = { "bookname", "bookauthor", "bookformat", "isbn", "publishyear" }; - @Autowired - private JobBuilderFactory jobBuilderFactory; - - @Autowired - private StepBuilderFactory stepBuilderFactory; - @Bean @StepScope public FlatFileItemReader csvItemReader(@Value("#{jobParameters['file.input']}") String input) { @@ -65,7 +55,7 @@ public class SpringBatchConfiguration { @Bean @StepScope - public JsonFileItemWriter jsonItemWriter(@Value("#{jobParameters['file.output']}") String output) throws IOException { + public JsonFileItemWriter jsonItemWriter(@Value("#{jobParameters['file.output']}") String output) { JsonFileItemWriterBuilder builder = new JsonFileItemWriterBuilder<>(); JacksonJsonObjectMarshaller marshaller = new JacksonJsonObjectMarshaller<>(); LOGGER.info("Configuring writer to output {}", output); @@ -81,7 +71,7 @@ public class SpringBatchConfiguration { @Bean @StepScope public ListItemWriter listItemWriter() { - return new ListItemWriter(); + return new ListItemWriter<>(); } @Bean @@ -96,12 +86,11 @@ public class SpringBatchConfiguration { return new BookDetailsItemProcessor(); } - @Bean - public Step step1(ItemReader csvItemReader, ItemWriter jsonItemWriter) throws IOException { + @Bean(name = "step1") + public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager, ItemReader csvItemReader, ItemWriter jsonItemWriter) { // @formatter:off - return stepBuilderFactory - .get("step1") - . chunk(3) + return new StepBuilder("step1", jobRepository) + . chunk(3, transactionManager) .reader(csvItemReader) .processor(bookItemProcessor()) .writer(jsonItemWriter) @@ -109,12 +98,11 @@ public class SpringBatchConfiguration { // @formatter:on } - @Bean - public Step step2(ItemReader csvItemReader, ItemWriter listItemWriter) { + @Bean(name = "step2") + public Step step2(JobRepository jobRepository, PlatformTransactionManager transactionManager, ItemReader csvItemReader, ItemWriter listItemWriter) { // @formatter:off - return stepBuilderFactory - .get("step2") - . chunk(3) + return new StepBuilder("step2", jobRepository) + . chunk(3, transactionManager) .reader(csvItemReader) .processor(bookDetailsItemProcessor()) .writer(listItemWriter) @@ -123,15 +111,13 @@ public class SpringBatchConfiguration { } @Bean(name = "transformBooksRecords") - public Job transformBookRecords(Step step1, Step step2) throws IOException { + public Job transformBookRecords(JobRepository jobRepository, Step step1, Step step2) { // @formatter:off - return jobBuilderFactory - .get("transformBooksRecords") + return new JobBuilder("transformBooksRecords", jobRepository) .flow(step1) .next(step2) .end() .build(); // @formatter:on } - } diff --git a/spring-batch/src/main/java/com/baeldung/batchtesting/service/BookDetailsItemProcessor.java b/spring-batch/src/main/java/com/baeldung/batchtesting/service/BookDetailsItemProcessor.java index 514a383108..4e4d1e9075 100644 --- a/spring-batch/src/main/java/com/baeldung/batchtesting/service/BookDetailsItemProcessor.java +++ b/spring-batch/src/main/java/com/baeldung/batchtesting/service/BookDetailsItemProcessor.java @@ -11,7 +11,7 @@ public class BookDetailsItemProcessor implements ItemProcessor { private static Logger LOGGER = LoggerFactory.getLogger(BookItemProcessor.class); @Override - public Book process(BookRecord item) throws Exception { + public Book process(BookRecord item) { Book book = new Book(); book.setAuthor(item.getBookAuthor()); book.setName(item.getBookName()); diff --git a/spring-batch/src/main/java/com/baeldung/batchtesting/service/BookRecordFieldSetMapper.java b/spring-batch/src/main/java/com/baeldung/batchtesting/service/BookRecordFieldSetMapper.java index d9e8ee1158..e4760da20f 100644 --- a/spring-batch/src/main/java/com/baeldung/batchtesting/service/BookRecordFieldSetMapper.java +++ b/spring-batch/src/main/java/com/baeldung/batchtesting/service/BookRecordFieldSetMapper.java @@ -9,7 +9,7 @@ import org.springframework.validation.BindException; public class BookRecordFieldSetMapper implements FieldSetMapper { @Override - public BookRecord mapFieldSet(FieldSet fieldSet) throws BindException { + public BookRecord mapFieldSet(FieldSet fieldSet) { BookRecord bookRecord = new BookRecord(); bookRecord.setBookName(fieldSet.readString("bookname")); bookRecord.setBookAuthor(fieldSet.readString("bookauthor")); diff --git a/spring-batch/src/main/java/com/baeldung/taskletsvschunks/chunks/LineReader.java b/spring-batch/src/main/java/com/baeldung/taskletsvschunks/chunks/LineReader.java index 6ffa730c19..d8ba2c9728 100644 --- a/spring-batch/src/main/java/com/baeldung/taskletsvschunks/chunks/LineReader.java +++ b/spring-batch/src/main/java/com/baeldung/taskletsvschunks/chunks/LineReader.java @@ -21,9 +21,9 @@ public class LineReader implements ItemReader, StepExecutionListener { } @Override - public Line read() throws Exception { + public Line read() { Line line = fu.readLine(); - if (line != null) logger.debug("Read line: " + line.toString()); + if (line != null) logger.debug("Read line: " + line); return line; } diff --git a/spring-batch/src/main/java/com/baeldung/taskletsvschunks/chunks/LinesWriter.java b/spring-batch/src/main/java/com/baeldung/taskletsvschunks/chunks/LinesWriter.java index 9f292b24b9..bcf648820c 100644 --- a/spring-batch/src/main/java/com/baeldung/taskletsvschunks/chunks/LinesWriter.java +++ b/spring-batch/src/main/java/com/baeldung/taskletsvschunks/chunks/LinesWriter.java @@ -7,10 +7,9 @@ import org.slf4j.LoggerFactory; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.StepExecutionListener; +import org.springframework.batch.item.Chunk; import org.springframework.batch.item.ItemWriter; -import java.util.List; - public class LinesWriter implements ItemWriter, StepExecutionListener { private final Logger logger = LoggerFactory.getLogger(LinesWriter.class); @@ -30,7 +29,7 @@ public class LinesWriter implements ItemWriter, StepExecutionListener { } @Override - public void write(List lines) throws Exception { + public void write(Chunk lines) { for (Line line : lines) { fu.writeLine(line); logger.debug("Wrote line " + line.toString()); diff --git a/spring-batch/src/main/java/com/baeldung/taskletsvschunks/config/ChunksConfig.java b/spring-batch/src/main/java/com/baeldung/taskletsvschunks/config/ChunksConfig.java index c8b05848f9..16c6b1191f 100644 --- a/spring-batch/src/main/java/com/baeldung/taskletsvschunks/config/ChunksConfig.java +++ b/spring-batch/src/main/java/com/baeldung/taskletsvschunks/config/ChunksConfig.java @@ -6,67 +6,19 @@ import com.baeldung.taskletsvschunks.chunks.LinesWriter; import com.baeldung.taskletsvschunks.model.Line; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.core.launch.support.SimpleJobLauncher; +import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; +import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.support.transaction.ResourcelessTransactionManager; -import org.springframework.batch.test.JobLauncherTestUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.PlatformTransactionManager; -import javax.sql.DataSource; - @Configuration -@EnableBatchProcessing public class ChunksConfig { - @Autowired private JobBuilderFactory jobs; - - @Autowired private StepBuilderFactory steps; - - @Bean - public JobLauncherTestUtils jobLauncherTestUtils() { - return new JobLauncherTestUtils(); - } - - @Bean - public JobRepository jobRepository() throws Exception { - JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); - factory.setDataSource(dataSource()); - factory.setTransactionManager(transactionManager()); - return factory.getObject(); - } - - @Bean - public DataSource dataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName("org.sqlite.JDBC"); - dataSource.setUrl("jdbc:sqlite:repository.sqlite"); - return dataSource; - } - - @Bean - public PlatformTransactionManager transactionManager() { - return new ResourcelessTransactionManager(); - } - - @Bean - public JobLauncher jobLauncher() throws Exception { - SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); - jobLauncher.setJobRepository(jobRepository()); - return jobLauncher; - } - @Bean public ItemReader itemReader() { return new LineReader(); @@ -82,20 +34,19 @@ public class ChunksConfig { return new LinesWriter(); } - @Bean - protected Step processLines(ItemReader reader, ItemProcessor processor, ItemWriter writer) { - return steps.get("processLines"). chunk(2) + @Bean(name = "processLines") + protected Step processLines(JobRepository jobRepository, PlatformTransactionManager transactionManager, ItemReader reader, ItemProcessor processor, ItemWriter writer) { + return new StepBuilder("processLines", jobRepository). chunk(2, transactionManager) .reader(reader) .processor(processor) .writer(writer) .build(); } - @Bean - public Job job() { - return jobs - .get("chunksJob") - .start(processLines(itemReader(), itemProcessor(), itemWriter())) + @Bean(name = "chunksJob") + public Job job(JobRepository jobRepository, PlatformTransactionManager transactionManager) { + return new JobBuilder("chunksJob", jobRepository) + .start(processLines(jobRepository, transactionManager, itemReader(), itemProcessor(), itemWriter())) .build(); } diff --git a/spring-batch/src/main/java/com/baeldung/taskletsvschunks/config/TaskletsConfig.java b/spring-batch/src/main/java/com/baeldung/taskletsvschunks/config/TaskletsConfig.java index 5f2f49928c..ab9d506229 100644 --- a/spring-batch/src/main/java/com/baeldung/taskletsvschunks/config/TaskletsConfig.java +++ b/spring-batch/src/main/java/com/baeldung/taskletsvschunks/config/TaskletsConfig.java @@ -5,64 +5,16 @@ import com.baeldung.taskletsvschunks.tasklets.LinesReader; import com.baeldung.taskletsvschunks.tasklets.LinesWriter; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.core.launch.support.SimpleJobLauncher; +import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; -import org.springframework.batch.support.transaction.ResourcelessTransactionManager; -import org.springframework.batch.test.JobLauncherTestUtils; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.PlatformTransactionManager; -import javax.sql.DataSource; - @Configuration -@EnableBatchProcessing public class TaskletsConfig { - @Autowired private JobBuilderFactory jobs; - - @Autowired private StepBuilderFactory steps; - - @Bean - public JobLauncherTestUtils jobLauncherTestUtils() { - return new JobLauncherTestUtils(); - } - - @Bean - public JobRepository jobRepository() throws Exception { - JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); - factory.setDataSource(dataSource()); - factory.setTransactionManager(transactionManager()); - return factory.getObject(); - } - - @Bean - public DataSource dataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName("org.sqlite.JDBC"); - dataSource.setUrl("jdbc:sqlite:repository.sqlite"); - return dataSource; - } - - @Bean - public PlatformTransactionManager transactionManager() { - return new ResourcelessTransactionManager(); - } - - @Bean - public JobLauncher jobLauncher() throws Exception { - SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); - jobLauncher.setJobRepository(jobRepository()); - return jobLauncher; - } - @Bean public LinesReader linesReader() { return new LinesReader(); @@ -79,36 +31,32 @@ public class TaskletsConfig { } @Bean - protected Step readLines() { - return steps - .get("readLines") - .tasklet(linesReader()) + protected Step readLines(JobRepository jobRepository, PlatformTransactionManager transactionManager) { + return new StepBuilder("readLines", jobRepository) + .tasklet(linesReader(), transactionManager) .build(); } @Bean - protected Step processLines() { - return steps - .get("processLines") - .tasklet(linesProcessor()) + protected Step processLines(JobRepository jobRepository, PlatformTransactionManager transactionManager) { + return new StepBuilder("processLines", jobRepository) + .tasklet(linesProcessor(), transactionManager) .build(); } @Bean - protected Step writeLines() { - return steps - .get("writeLines") - .tasklet(linesWriter()) + protected Step writeLines(JobRepository jobRepository, PlatformTransactionManager transactionManager) { + return new StepBuilder("writeLines", jobRepository) + .tasklet(linesWriter(), transactionManager) .build(); } @Bean - public Job job() { - return jobs - .get("taskletsJob") - .start(readLines()) - .next(processLines()) - .next(writeLines()) + public Job job(JobRepository jobRepository, PlatformTransactionManager transactionManager) { + return new JobBuilder("taskletsJob", jobRepository) + .start(readLines(jobRepository, transactionManager)) + .next(processLines(jobRepository, transactionManager)) + .next(writeLines(jobRepository, transactionManager)) .build(); } diff --git a/spring-batch/src/main/java/com/baeldung/taskletsvschunks/tasklets/LinesReader.java b/spring-batch/src/main/java/com/baeldung/taskletsvschunks/tasklets/LinesReader.java index b1f58be4a4..70f1a1b05d 100644 --- a/spring-batch/src/main/java/com/baeldung/taskletsvschunks/tasklets/LinesReader.java +++ b/spring-batch/src/main/java/com/baeldung/taskletsvschunks/tasklets/LinesReader.java @@ -24,7 +24,7 @@ public class LinesReader implements Tasklet, StepExecutionListener { @Override public void beforeStep(StepExecution stepExecution) { - lines = new ArrayList(); + lines = new ArrayList<>(); fu = new FileUtils("taskletsvschunks/input/tasklets-vs-chunks.csv"); logger.debug("Lines Reader initialized."); } diff --git a/spring-batch/src/main/java/org/baeldung/conditionalflow/ConditionalFlowApplication.java b/spring-batch/src/main/java/org/baeldung/conditionalflow/ConditionalFlowApplication.java index c977d6ecab..8a8f62ae31 100644 --- a/spring-batch/src/main/java/org/baeldung/conditionalflow/ConditionalFlowApplication.java +++ b/spring-batch/src/main/java/org/baeldung/conditionalflow/ConditionalFlowApplication.java @@ -15,7 +15,7 @@ public class ConditionalFlowApplication implements CommandLineRunner { } @Override - public void run(String... args) throws Exception { + public void run(String... args) { logger.info("Running conditional flow application..."); } } diff --git a/spring-batch/src/main/java/org/baeldung/conditionalflow/config/NumberInfoConfig.java b/spring-batch/src/main/java/org/baeldung/conditionalflow/config/NumberInfoConfig.java index 906a6e1d28..4954d9ffcd 100644 --- a/spring-batch/src/main/java/org/baeldung/conditionalflow/config/NumberInfoConfig.java +++ b/spring-batch/src/main/java/org/baeldung/conditionalflow/config/NumberInfoConfig.java @@ -6,39 +6,49 @@ import org.baeldung.conditionalflow.step.*; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.job.builder.JobBuilder; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.core.launch.support.TaskExecutorJobLauncher; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; +import org.springframework.batch.core.step.builder.StepBuilder; +import org.springframework.batch.support.transaction.ResourcelessTransactionManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.transaction.PlatformTransactionManager; import static org.baeldung.conditionalflow.NumberInfoDecider.NOTIFY; +import javax.sql.DataSource; + @Configuration @EnableBatchProcessing public class NumberInfoConfig { @Bean @Qualifier("NotificationStep") - public Step notificationStep(StepBuilderFactory sbf) { - return sbf.get("Notify step") - .tasklet(new NotifierTasklet()) + public Step notificationStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) { + return new StepBuilder("Notify step", jobRepository) + .tasklet(new NotifierTasklet(), transactionManager) .build(); } - public Step numberGeneratorStep(StepBuilderFactory sbf, int[] values, String prepend) { - return sbf.get("Number generator") - . chunk(1) + public Step numberGeneratorStep(JobRepository jobRepositories, PlatformTransactionManager transactionManager, int[] values, String prepend) { + return new StepBuilder("Number generator", jobRepositories) + . chunk(1, transactionManager) .reader(new NumberInfoGenerator(values)) .processor(new NumberInfoClassifier()) .writer(new PrependingStdoutWriter<>(prepend)) .build(); } - public Step numberGeneratorStepDecider(StepBuilderFactory sbf, int[] values, String prepend) { - return sbf.get("Number generator decider") - . chunk(1) + public Step numberGeneratorStepDecider(JobRepository jobRepositories, PlatformTransactionManager transactionManager, int[] values, String prepend) { + return new StepBuilder("Number generator decider", jobRepositories) + . chunk(1, transactionManager) .reader(new NumberInfoGenerator(values)) .processor(new NumberInfoClassifierWithDecider()) .writer(new PrependingStdoutWriter<>(prepend)) @@ -47,10 +57,10 @@ public class NumberInfoConfig { @Bean @Qualifier("first_job") - public Job numberGeneratorNonNotifierJob(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory, @Qualifier("NotificationStep") Step notificationStep) { + public Job numberGeneratorNonNotifierJob(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("NotificationStep") Step notificationStep) { int[] nonNotifierData = { -1, -2, -3 }; - Step step = numberGeneratorStep(stepBuilderFactory, nonNotifierData, "First Dataset Processor"); - return jobBuilderFactory.get("Number generator - first dataset") + Step step = numberGeneratorStep(jobRepository, transactionManager, nonNotifierData, "First Dataset Processor"); + return new JobBuilder("Number generator - first dataset", jobRepository) .start(step) .on(NOTIFY) .to(notificationStep) @@ -63,10 +73,10 @@ public class NumberInfoConfig { @Bean @Qualifier("second_job") - public Job numberGeneratorNotifierJob(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory, @Qualifier("NotificationStep") Step notificationStep) { + public Job numberGeneratorNotifierJob(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("NotificationStep") Step notificationStep) { int[] billableData = { 11, -2, -3 }; - Step dataProviderStep = numberGeneratorStep(stepBuilderFactory, billableData, "Second Dataset Processor"); - return jobBuilderFactory.get("Number generator - second dataset") + Step dataProviderStep = numberGeneratorStep(jobRepository, transactionManager, billableData, "Second Dataset Processor"); + return new JobBuilder("Number generator - second dataset", jobRepository) .start(dataProviderStep) .on(NOTIFY) .to(notificationStep) @@ -77,10 +87,10 @@ public class NumberInfoConfig { @Bean @Qualifier("third_job") @Primary - public Job numberGeneratorNotifierJobWithDecider(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory, @Qualifier("NotificationStep") Step notificationStep) { + public Job numberGeneratorNotifierJobWithDecider(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("NotificationStep") Step notificationStep) { int[] billableData = { 11, -2, -3 }; - Step dataProviderStep = numberGeneratorStepDecider(stepBuilderFactory, billableData, "Third Dataset Processor"); - return jobBuilderFactory.get("Number generator - third dataset") + Step dataProviderStep = numberGeneratorStepDecider(jobRepository, transactionManager, billableData, "Third Dataset Processor"); + return new JobBuilder("Number generator - third dataset", jobRepository) .start(dataProviderStep) .next(new NumberInfoDecider()) .on(NOTIFY) @@ -88,4 +98,39 @@ public class NumberInfoConfig { .end() .build(); } + + @Bean(name = "jobRepository") + public JobRepository getJobRepository() throws Exception { + JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); + factory.setDataSource(dataSource()); + factory.setTransactionManager(getTransactionManager()); + // JobRepositoryFactoryBean's methods Throws Generic Exception, + // it would have been better to have a specific one + factory.afterPropertiesSet(); + return factory.getObject(); + } + + @Bean(name = "dataSource") + public DataSource dataSource() { + EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); + return builder.setType(EmbeddedDatabaseType.H2) + .addScript("classpath:org/springframework/batch/core/schema-drop-h2.sql") + .addScript("classpath:org/springframework/batch/core/schema-h2.sql") + .build(); + } + + @Bean(name = "transactionManager") + public PlatformTransactionManager getTransactionManager() { + return new ResourcelessTransactionManager(); + } + + @Bean(name = "jobLauncher") + public JobLauncher getJobLauncher() throws Exception { + TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher(); + // SimpleJobLauncher's methods Throws Generic Exception, + // it would have been better to have a specific one + jobLauncher.setJobRepository(getJobRepository()); + jobLauncher.afterPropertiesSet(); + return jobLauncher; + } } diff --git a/spring-batch/src/main/java/org/baeldung/conditionalflow/step/NotifierTasklet.java b/spring-batch/src/main/java/org/baeldung/conditionalflow/step/NotifierTasklet.java index 0d1db66fe9..99ec151cba 100644 --- a/spring-batch/src/main/java/org/baeldung/conditionalflow/step/NotifierTasklet.java +++ b/spring-batch/src/main/java/org/baeldung/conditionalflow/step/NotifierTasklet.java @@ -7,9 +7,8 @@ import org.springframework.batch.repeat.RepeatStatus; public class NotifierTasklet implements Tasklet { @Override - public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception { - System.err.println("[" + chunkContext.getStepContext() - .getJobName() + "] contains interesting data!!"); + public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) { + System.err.println("[" + chunkContext.getStepContext().getJobName() + "] contains interesting data!!"); return RepeatStatus.FINISHED; } } diff --git a/spring-batch/src/main/java/org/baeldung/conditionalflow/step/NumberInfoClassifier.java b/spring-batch/src/main/java/org/baeldung/conditionalflow/step/NumberInfoClassifier.java index fdb28263e7..71d88e3f0a 100644 --- a/spring-batch/src/main/java/org/baeldung/conditionalflow/step/NumberInfoClassifier.java +++ b/spring-batch/src/main/java/org/baeldung/conditionalflow/step/NumberInfoClassifier.java @@ -29,7 +29,7 @@ public class NumberInfoClassifier extends ItemListenerSupport implements ItemProcessor { @Override - public Integer process(NumberInfo numberInfo) throws Exception { + public Integer process(NumberInfo numberInfo) { return Integer.valueOf(numberInfo.getNumber()); } } diff --git a/spring-batch/src/main/java/org/baeldung/conditionalflow/step/PrependingStdoutWriter.java b/spring-batch/src/main/java/org/baeldung/conditionalflow/step/PrependingStdoutWriter.java index 9ffea1e798..abadb78e93 100644 --- a/spring-batch/src/main/java/org/baeldung/conditionalflow/step/PrependingStdoutWriter.java +++ b/spring-batch/src/main/java/org/baeldung/conditionalflow/step/PrependingStdoutWriter.java @@ -1,7 +1,6 @@ package org.baeldung.conditionalflow.step; -import java.util.List; - +import org.springframework.batch.item.Chunk; import org.springframework.batch.item.ItemWriter; public class PrependingStdoutWriter implements ItemWriter { @@ -12,8 +11,8 @@ public class PrependingStdoutWriter implements ItemWriter { } @Override - public void write(List list) { - for (T listItem : list) { + public void write(Chunk chunk) { + for (T listItem : chunk) { System.out.println(prependText + " " + listItem.toString()); } } diff --git a/spring-batch/src/main/resources/output/output1.xml b/spring-batch/src/main/resources/output/output1.xml index 838d04882a..78bc7349e8 100644 --- a/spring-batch/src/main/resources/output/output1.xml +++ b/spring-batch/src/main/resources/output/output1.xml @@ -1,21 +1,21 @@ - - 10000.0 - 2015-10-31 00:00:00 - 1234 - devendra - - - 12321.0 - 2015-12-03 00:00:00 - 2134 - john - - - 23411.0 - 2015-02-02 00:00:00 - 2134 - robin - + + 10000.0 + 2015-10-31 00:00:00 + 1234 + devendra + + + 12321.0 + 2015-12-03 00:00:00 + 2134 + john + + + 23411.0 + 2015-02-02 00:00:00 + 2134 + robin + \ No newline at end of file diff --git a/spring-batch/src/main/resources/output/output2.xml b/spring-batch/src/main/resources/output/output2.xml index 838d04882a..78bc7349e8 100644 --- a/spring-batch/src/main/resources/output/output2.xml +++ b/spring-batch/src/main/resources/output/output2.xml @@ -1,21 +1,21 @@ - - 10000.0 - 2015-10-31 00:00:00 - 1234 - devendra - - - 12321.0 - 2015-12-03 00:00:00 - 2134 - john - - - 23411.0 - 2015-02-02 00:00:00 - 2134 - robin - + + 10000.0 + 2015-10-31 00:00:00 + 1234 + devendra + + + 12321.0 + 2015-12-03 00:00:00 + 2134 + john + + + 23411.0 + 2015-02-02 00:00:00 + 2134 + robin + \ No newline at end of file diff --git a/spring-batch/src/main/resources/output/output3.xml b/spring-batch/src/main/resources/output/output3.xml index 838d04882a..78bc7349e8 100644 --- a/spring-batch/src/main/resources/output/output3.xml +++ b/spring-batch/src/main/resources/output/output3.xml @@ -1,21 +1,21 @@ - - 10000.0 - 2015-10-31 00:00:00 - 1234 - devendra - - - 12321.0 - 2015-12-03 00:00:00 - 2134 - john - - - 23411.0 - 2015-02-02 00:00:00 - 2134 - robin - + + 10000.0 + 2015-10-31 00:00:00 + 1234 + devendra + + + 12321.0 + 2015-12-03 00:00:00 + 2134 + john + + + 23411.0 + 2015-02-02 00:00:00 + 2134 + robin + \ No newline at end of file diff --git a/spring-batch/src/main/resources/output/output4.xml b/spring-batch/src/main/resources/output/output4.xml index 838d04882a..78bc7349e8 100644 --- a/spring-batch/src/main/resources/output/output4.xml +++ b/spring-batch/src/main/resources/output/output4.xml @@ -1,21 +1,21 @@ - - 10000.0 - 2015-10-31 00:00:00 - 1234 - devendra - - - 12321.0 - 2015-12-03 00:00:00 - 2134 - john - - - 23411.0 - 2015-02-02 00:00:00 - 2134 - robin - + + 10000.0 + 2015-10-31 00:00:00 + 1234 + devendra + + + 12321.0 + 2015-12-03 00:00:00 + 2134 + john + + + 23411.0 + 2015-02-02 00:00:00 + 2134 + robin + \ No newline at end of file diff --git a/spring-batch/src/main/resources/output/output5.xml b/spring-batch/src/main/resources/output/output5.xml index 838d04882a..78bc7349e8 100644 --- a/spring-batch/src/main/resources/output/output5.xml +++ b/spring-batch/src/main/resources/output/output5.xml @@ -1,21 +1,21 @@ - - 10000.0 - 2015-10-31 00:00:00 - 1234 - devendra - - - 12321.0 - 2015-12-03 00:00:00 - 2134 - john - - - 23411.0 - 2015-02-02 00:00:00 - 2134 - robin - + + 10000.0 + 2015-10-31 00:00:00 + 1234 + devendra + + + 12321.0 + 2015-12-03 00:00:00 + 2134 + john + + + 23411.0 + 2015-02-02 00:00:00 + 2134 + robin + \ No newline at end of file diff --git a/spring-batch/src/main/resources/spring-batch-intro.xml b/spring-batch/src/main/resources/spring-batch-intro.xml index 2a7c1e7c4a..bb11ea0efd 100644 --- a/spring-batch/src/main/resources/spring-batch-intro.xml +++ b/spring-batch/src/main/resources/spring-batch-intro.xml @@ -17,7 +17,7 @@ + value="username,userid,transactiondate,amount" /> @@ -33,11 +33,11 @@ - + - + com.baeldung.batch.model.Transaction diff --git a/spring-batch/src/main/resources/spring.xml b/spring-batch/src/main/resources/spring.xml index dea261c5e6..fc7e867941 100644 --- a/spring-batch/src/main/resources/spring.xml +++ b/spring-batch/src/main/resources/spring.xml @@ -9,8 +9,8 @@ - - + + @@ -18,8 +18,8 @@ - + location="org/springframework/batch/core/schema-drop-h2.sql" /> + @@ -31,7 +31,6 @@ class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"> - { - assertThat(stepExecution.getWriteCount(), is(8)); + assertEquals(8L, stepExecution.getWriteCount()); }); } diff --git a/spring-batch/src/test/java/com/baeldung/batchtesting/SpringBatchStepScopeIntegrationTest.java b/spring-batch/src/test/java/com/baeldung/batchtesting/SpringBatchStepScopeIntegrationTest.java index 4655117b85..311bd828cb 100644 --- a/spring-batch/src/test/java/com/baeldung/batchtesting/SpringBatchStepScopeIntegrationTest.java +++ b/spring-batch/src/test/java/com/baeldung/batchtesting/SpringBatchStepScopeIntegrationTest.java @@ -1,22 +1,21 @@ package com.baeldung.batchtesting; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.springframework.batch.test.AssertFile.assertFileEquals; -import java.util.Arrays; +import java.util.List; -import com.baeldung.batchtesting.SpringBatchConfiguration; import com.baeldung.batchtesting.model.Book; import com.baeldung.batchtesting.model.BookRecord; -import org.junit.After; -import org.junit.Test; -import org.junit.runner.RunWith; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParametersBuilder; import org.springframework.batch.core.StepExecution; +import org.springframework.batch.item.Chunk; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.json.JsonFileItemWriter; -import org.springframework.batch.test.AssertFile; import org.springframework.batch.test.JobRepositoryTestUtils; import org.springframework.batch.test.MetaDataInstanceFactory; import org.springframework.batch.test.StepScopeTestUtils; @@ -24,21 +23,12 @@ import org.springframework.batch.test.context.SpringBatchTest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.core.io.FileSystemResource; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestExecutionListeners; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; -import org.springframework.test.context.support.DirtiesContextTestExecutionListener; -@RunWith(SpringRunner.class) @SpringBatchTest @EnableAutoConfiguration @ContextConfiguration(classes = { SpringBatchConfiguration.class }) -@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class }) -@DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class SpringBatchStepScopeIntegrationTest { private static final String TEST_OUTPUT = "src/test/resources/output/actual-output.json"; @@ -62,7 +52,7 @@ public class SpringBatchStepScopeIntegrationTest { return paramsBuilder.toJobParameters(); } - @After + @AfterEach public void cleanUp() { jobRepositoryTestUtils.removeJobExecutions(); } @@ -80,11 +70,11 @@ public class SpringBatchStepScopeIntegrationTest { while ((bookRecord = itemReader.read()) != null) { // then - assertThat(bookRecord.getBookName(), is("Foundation")); - assertThat(bookRecord.getBookAuthor(), is("Asimov I.")); - assertThat(bookRecord.getBookISBN(), is("ISBN 12839")); - assertThat(bookRecord.getBookFormat(), is("hardcover")); - assertThat(bookRecord.getPublishingYear(), is("2018")); + assertEquals("Foundation", bookRecord.getBookName()); + assertEquals("Asimov I.", bookRecord.getBookAuthor()); + assertEquals("ISBN 12839", bookRecord.getBookISBN()); + assertEquals("hardcover", bookRecord.getBookFormat()); + assertEquals("2018", bookRecord.getPublishingYear()); } itemReader.close(); return null; @@ -106,12 +96,12 @@ public class SpringBatchStepScopeIntegrationTest { StepScopeTestUtils.doInStepScope(stepExecution, () -> { jsonItemWriter.open(stepExecution.getExecutionContext()); - jsonItemWriter.write(Arrays.asList(demoBook)); + jsonItemWriter.write(new Chunk<>(List.of(demoBook))); jsonItemWriter.close(); return null; }); // then - AssertFile.assertFileEquals(expectedResult, actualResult); + assertFileEquals(expectedResult, actualResult); } } diff --git a/spring-batch/src/test/java/com/baeldung/taskletsvschunks/chunks/ChunksIntegrationTest.java b/spring-batch/src/test/java/com/baeldung/taskletsvschunks/chunks/ChunksIntegrationTest.java index 1132e4d5e2..109342076b 100644 --- a/spring-batch/src/test/java/com/baeldung/taskletsvschunks/chunks/ChunksIntegrationTest.java +++ b/spring-batch/src/test/java/com/baeldung/taskletsvschunks/chunks/ChunksIntegrationTest.java @@ -1,25 +1,29 @@ package com.baeldung.taskletsvschunks.chunks; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.baeldung.taskletsvschunks.config.ChunksConfig; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; + +import org.junit.jupiter.api.Test; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.test.JobLauncherTestUtils; +import org.springframework.batch.test.context.SpringBatchTest; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = ChunksConfig.class) +@SpringBatchTest +@EnableAutoConfiguration +@ContextConfiguration(classes = ChunksConfig.class) public class ChunksIntegrationTest { - @Autowired private JobLauncherTestUtils jobLauncherTestUtils; + @Autowired + private JobLauncherTestUtils jobLauncherTestUtils; @Test public void givenChunksJob_WhenJobEnds_ThenStatusCompleted() throws Exception { JobExecution jobExecution = jobLauncherTestUtils.launchJob(); - Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); } } \ No newline at end of file diff --git a/spring-batch/src/test/java/com/baeldung/taskletsvschunks/tasklets/TaskletsIntegrationTest.java b/spring-batch/src/test/java/com/baeldung/taskletsvschunks/tasklets/TaskletsIntegrationTest.java index 2e1ad031aa..103b1a2096 100644 --- a/spring-batch/src/test/java/com/baeldung/taskletsvschunks/tasklets/TaskletsIntegrationTest.java +++ b/spring-batch/src/test/java/com/baeldung/taskletsvschunks/tasklets/TaskletsIntegrationTest.java @@ -1,25 +1,29 @@ package com.baeldung.taskletsvschunks.tasklets; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.baeldung.taskletsvschunks.config.TaskletsConfig; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; + +import org.junit.jupiter.api.Test; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.test.JobLauncherTestUtils; +import org.springframework.batch.test.context.SpringBatchTest; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -@RunWith(SpringJUnit4ClassRunner.class) +@SpringBatchTest +@EnableAutoConfiguration @ContextConfiguration(classes = TaskletsConfig.class) public class TaskletsIntegrationTest { - @Autowired private JobLauncherTestUtils jobLauncherTestUtils; + @Autowired + private JobLauncherTestUtils jobLauncherTestUtils; @Test public void givenTaskletsJob_WhenJobEnds_ThenStatusCompleted() throws Exception { JobExecution jobExecution = jobLauncherTestUtils.launchJob(); - Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); } } \ No newline at end of file diff --git a/spring-batch/src/test/java/org/baeldung/conditionalflow/DeciderJobIntegrationTest.java b/spring-batch/src/test/java/org/baeldung/conditionalflow/DeciderJobIntegrationTest.java index e73cb17494..a50ad0455c 100644 --- a/spring-batch/src/test/java/org/baeldung/conditionalflow/DeciderJobIntegrationTest.java +++ b/spring-batch/src/test/java/org/baeldung/conditionalflow/DeciderJobIntegrationTest.java @@ -1,8 +1,10 @@ package org.baeldung.conditionalflow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + import org.baeldung.conditionalflow.config.NumberInfoConfig; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.StepExecution; @@ -10,26 +12,16 @@ import org.springframework.batch.test.JobLauncherTestUtils; import org.springframework.batch.test.context.SpringBatchTest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestExecutionListeners; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; -import org.springframework.test.context.support.DirtiesContextTestExecutionListener; import java.util.Collection; import java.util.Iterator; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -@RunWith(SpringRunner.class) @SpringBatchTest @EnableAutoConfiguration @ContextConfiguration(classes = { NumberInfoConfig.class }) -@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class }) -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class DeciderJobIntegrationTest { + @Autowired private JobLauncherTestUtils jobLauncherTestUtils; @@ -39,8 +31,7 @@ public class DeciderJobIntegrationTest { Collection actualStepExecutions = jobExecution.getStepExecutions(); ExitStatus actualJobExitStatus = jobExecution.getExitStatus(); - assertEquals("COMPLETED", actualJobExitStatus.getExitCode() - .toString()); + assertEquals("COMPLETED", actualJobExitStatus.getExitCode()); assertEquals(2, actualStepExecutions.size()); boolean notifyStepDidRun = false; Iterator iterator = actualStepExecutions.iterator(); diff --git a/spring-batch/src/test/java/org/baeldung/conditionalflow/model/NumberInfoUnitTest.java b/spring-batch/src/test/java/org/baeldung/conditionalflow/model/NumberInfoUnitTest.java index dc396b38da..bdecee5621 100644 --- a/spring-batch/src/test/java/org/baeldung/conditionalflow/model/NumberInfoUnitTest.java +++ b/spring-batch/src/test/java/org/baeldung/conditionalflow/model/NumberInfoUnitTest.java @@ -5,10 +5,10 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.test.context.junit.jupiter.SpringExtension; -@RunWith(SpringJUnit4ClassRunner.class) +@ExtendWith(SpringExtension.class) class NumberInfoUnitTest { @Test diff --git a/spring-batch/src/test/resources/output/actual-output.json b/spring-batch/src/test/resources/output/actual-output.json index 1fd6cfcf37..32ad8b7ead 100644 --- a/spring-batch/src/test/resources/output/actual-output.json +++ b/spring-batch/src/test/resources/output/actual-output.json @@ -1,3 +1,10 @@ [ - {"author":"Grisham J.","name":"The Firm"} + {"author":"Asimov I.","name":"Foundation"}, + {"author":"Strugatski A.","name":"Roadside Picnic"}, + {"author":"Murakami H.","name":"Norwegian Wood"}, + {"author":"Brown D.","name":"Davinci Code"}, + {"author":"Dick K. P.","name":"Ubik"}, + {"author":"King S.","name":"JFK"}, + {"author":"Sagan C.","name":"Contact"}, + {"author":"Huxley A.","name":"Brave New World"} ] diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 6d542f40dd..2fe146e065 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -63,10 +63,6 @@ spring-boot-nashorn spring-boot-parent spring-boot-performance - spring-boot-properties - spring-boot-properties-2 - spring-boot-properties-3 - spring-boot-properties-migrator-demo spring-boot-property-exp spring-boot-request-params spring-boot-runtime @@ -89,10 +85,15 @@ spring-boot-redis spring-boot-cassandre spring-boot-react - spring-boot-3 + spring-boot-3-native spring-boot-3-observation spring-boot-3-test-pitfalls + spring-boot-resilience4j + spring-boot-properties + spring-boot-properties-2 + spring-boot-properties-3 + spring-boot-properties-migrator-demo diff --git a/spring-boot-modules/spring-boot-3-native/pom.xml b/spring-boot-modules/spring-boot-3-native/pom.xml index 5382b8413c..1e93c3d8ed 100644 --- a/spring-boot-modules/spring-boot-3-native/pom.xml +++ b/spring-boot-modules/spring-boot-3-native/pom.xml @@ -56,10 +56,15 @@ -agentlib:native-image-agent=config-output-dir=target/native-image - - true - + + + process-aot + + process-aot + + + --> diff --git a/spring-boot-modules/spring-boot-3-observation/README.md b/spring-boot-modules/spring-boot-3-observation/README.md index edfb23ce2b..6d8c02af67 100644 --- a/spring-boot-modules/spring-boot-3-observation/README.md +++ b/spring-boot-modules/spring-boot-3-observation/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Observability with Spring Boot 3](https://www.baeldung.com/spring-boot-3-observability) +- [Intercept SQL Logging with P6Spy](https://www.baeldung.com/java-p6spy-intercept-sql-logging) diff --git a/spring-boot-modules/spring-boot-3-observation/pom.xml b/spring-boot-modules/spring-boot-3-observation/pom.xml index ed613ee98e..ddd81e3ca4 100644 --- a/spring-boot-modules/spring-boot-3-observation/pom.xml +++ b/spring-boot-modules/spring-boot-3-observation/pom.xml @@ -54,6 +54,25 @@ org.springframework.boot spring-boot-starter-aop + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.github.gavlyukovskiy + p6spy-spring-boot-starter + 1.9.0 + + + com.h2database + h2 + runtime + org.springframework.boot spring-boot-devtools @@ -63,4 +82,8 @@ + + com.baeldung.samples.SimpleObservationApplication + + diff --git a/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/SampleP6SpyApplication.java b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/SampleP6SpyApplication.java new file mode 100644 index 0000000000..000ffea9c9 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/SampleP6SpyApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.p6spy; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SampleP6SpyApplication { + + public static void main(String[] args) { + SpringApplication.run(SampleP6SpyApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/controllers/JDBCController.java b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/controllers/JDBCController.java new file mode 100644 index 0000000000..d09e839165 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/controllers/JDBCController.java @@ -0,0 +1,54 @@ +package com.baeldung.p6spy.controllers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("jdbc") +public class JDBCController { + + @Autowired + private DataSource dataSource; + + @RequestMapping("/commit") + public List> select() { + List> results = new ArrayList<>(); + try { + Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement(); + statement.executeQuery("SELECT * FROM student"); + connection.commit(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + return results; + } + + @RequestMapping("/rollback") + public List> rollback() { + List> results = new ArrayList<>(); + try (Connection connection = dataSource.getConnection()) { + connection.rollback(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + return results; + } + + @RequestMapping("/query-error") + public void error() { + try (Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement()) { + statement.execute("SELECT UNDEFINED()"); + } catch (Exception ignored) { + } + } +} diff --git a/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/controllers/StudentController.java b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/controllers/StudentController.java new file mode 100644 index 0000000000..d60fd8b52e --- /dev/null +++ b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/controllers/StudentController.java @@ -0,0 +1,29 @@ +package com.baeldung.p6spy.controllers; + +import com.baeldung.p6spy.repository.Student; +import com.baeldung.p6spy.repository.StudentRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("student") +public class StudentController { + + @Autowired + private StudentRepository repository; + + @RequestMapping("/save") + public Long save() { + return repository.save(new Student("Pablo", "Picasso")).getId(); + } + + @RequestMapping("/find/{name}") + public List getAll(@PathVariable String name) { + return repository.findAllByFirstName(name); + } + +} diff --git a/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/repository/Student.java b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/repository/Student.java new file mode 100644 index 0000000000..881f9409b8 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/repository/Student.java @@ -0,0 +1,53 @@ +package com.baeldung.p6spy.repository; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +@Entity +public class Student { + + @Id + @GeneratedValue + private Long id; + + private String firstName; + private String lastName; + + public Student() { + } + + public Student(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + 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; + } + + @Override + public String toString() { + return "Student{" + "id=" + id + ", firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + '}'; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/repository/StudentRepository.java b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/repository/StudentRepository.java new file mode 100644 index 0000000000..90d2c22877 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/p6spy/repository/StudentRepository.java @@ -0,0 +1,11 @@ +package com.baeldung.p6spy.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface StudentRepository extends JpaRepository { + List findAllByFirstName(String firstName); +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3-observation/src/main/resources/spy.properties b/spring-boot-modules/spring-boot-3-observation/src/main/resources/spy.properties new file mode 100644 index 0000000000..c14d381836 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-observation/src/main/resources/spy.properties @@ -0,0 +1,36 @@ +# specifies the appender to use for logging +# Please note: reload means forgetting all the previously set +# settings (even those set during runtime - via JMX) +# and starting with the clean table +# (only the properties read from the configuration file) +# (default is com.p6spy.engine.spy.appender.FileLogger) +#appender=com.p6spy.engine.spy.appender.Slf4JLogger +#appender=com.p6spy.engine.spy.appender.StdoutLogger +appender=com.p6spy.engine.spy.appender.FileLogger + +# name of logfile to use, note Windows users should make sure to use forward slashes in their pathname (e:/test/spy.log) +# (used for com.p6spy.engine.spy.appender.FileLogger only) +# (default is spy.log) +logfile=database.log + +# append to the p6spy log file. if this is set to false the +# log file is truncated every time. (file logger only) +# (default is true) +append=true + +# class to use for formatting log messages (default is: com.p6spy.engine.spy.appender.SingleLineFormat) +logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat + +# Custom log message format used ONLY IF logMessageFormat is set to com.p6spy.engine.spy.appender.CustomLineFormat +# default is %(currentTime)|%(executionTime)|%(category)|connection%(connectionId)|%(sqlSingleLine) +# Available placeholders are: +# %(connectionId) the id of the connection +# %(currentTime) the current time expressing in milliseconds +# %(executionTime) the time in milliseconds that the operation took to complete +# %(category) the category of the operation +# %(effectiveSql) the SQL statement as submitted to the driver +# %(effectiveSqlSingleLine) the SQL statement as submitted to the driver, with all new lines removed +# %(sql) the SQL statement with all bind variables replaced with actual values +# %(sqlSingleLine) the SQL statement with all bind variables replaced with actual values, with all new lines removed +customLogMessageFormat=%(currentTime)|%(executionTime)|%(category)|%(sqlSingleLine) + diff --git a/spring-boot-modules/spring-boot-3-observation/src/test/java/com/baeldung/p6spy/JDBCControllerIntegrationTest.java b/spring-boot-modules/spring-boot-3-observation/src/test/java/com/baeldung/p6spy/JDBCControllerIntegrationTest.java new file mode 100644 index 0000000000..433641fcb0 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-observation/src/test/java/com/baeldung/p6spy/JDBCControllerIntegrationTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://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. + */ + +package com.baeldung.p6spy; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.web.client.RestTemplate; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +class JDBCControllerIntegrationTest { + + private final RestTemplate restTemplate = new RestTemplate(); + @Value("http://localhost:${local.server.port}/jdbc") + private String localhost; + + @Test + void testJdbcCommitRESTMethod_isSuccessful() { + Assertions.assertTrue(restTemplate.getForEntity(localhost + "/commit", String.class) + .getStatusCode().is2xxSuccessful()); + } + + @Test + void jdbcRollbackRESTMethod_isSuccessful() { + Assertions.assertTrue(restTemplate.getForEntity(localhost + "/rollback", String.class) + .getStatusCode().is2xxSuccessful()); + } + + @Test + void jdbcQueryErrorRESTMethod_isSuccessful() { + Assertions.assertTrue(restTemplate.getForEntity(localhost + "/query-error", String.class) + .getStatusCode().is2xxSuccessful()); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3-observation/src/test/java/com/baeldung/p6spy/SampleP6SpyApplicationIntegrationTest.java b/spring-boot-modules/spring-boot-3-observation/src/test/java/com/baeldung/p6spy/SampleP6SpyApplicationIntegrationTest.java new file mode 100644 index 0000000000..ba6dd43195 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-observation/src/test/java/com/baeldung/p6spy/SampleP6SpyApplicationIntegrationTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://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. + */ + +package com.baeldung.p6spy; + +import com.github.gavlyukovskiy.boot.jdbc.decorator.DecoratedDataSource; +import com.github.gavlyukovskiy.boot.jdbc.decorator.p6spy.P6SpyDataSourceDecorator; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import javax.sql.DataSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@ExtendWith(SpringExtension.class) +@SpringBootTest +class SampleP6SpyApplicationIntegrationTest { + + @Autowired + private DataSource dataSource; + + @Test + void whenP6SpyEnabled_datasourceIsDecorated() { + assertThat(dataSource).isInstanceOf(DecoratedDataSource.class); + } + + @Test + void whenP6SpyEnabled_decoratingChainContainsP6Spy() { + DecoratedDataSource decoratedDataSource = (DecoratedDataSource) dataSource; + assertThat(decoratedDataSource.getDecoratingChain().get(0).getDataSourceDecorator()).isInstanceOf(P6SpyDataSourceDecorator.class); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3-observation/src/test/resources/spy.properties b/spring-boot-modules/spring-boot-3-observation/src/test/resources/spy.properties new file mode 100644 index 0000000000..ea4525df98 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-observation/src/test/resources/spy.properties @@ -0,0 +1,3 @@ +# specifies the appender to use for logging. +# used to avoid the creation of logging file with tests. +appender=com.p6spy.engine.spy.appender.StdoutLogger \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3-url-matching/README.md b/spring-boot-modules/spring-boot-3-url-matching/README.md new file mode 100644 index 0000000000..577849c0e1 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-url-matching/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [URL Matching in Spring Boot 3](https://www.baeldung.com/spring-boot-3-url-matching) diff --git a/spring-boot-modules/spring-boot-3-url-matching/pom.xml b/spring-boot-modules/spring-boot-3-url-matching/pom.xml new file mode 100644 index 0000000000..ca8213e1cf --- /dev/null +++ b/spring-boot-modules/spring-boot-3-url-matching/pom.xml @@ -0,0 +1,101 @@ + + + 4.0.0 + spring-boot-3 + 0.0.1-SNAPSHOT + spring-boot-3 + URL Matching in Spring Boot + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-hateoas + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-test + + + org.springframework + spring-test + 6.0.6 + test + + + javax.servlet + javax.servlet-api + 3.1.0 + provided + + + org.springframework.boot + spring-boot-starter-webflux + + + io.projectreactor + reactor-core + 3.5.4 + + + io.projectreactor + reactor-test + 3.5.4 + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + 3.0.0-M7 + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/URLMatchingApplication.java b/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/URLMatchingApplication.java new file mode 100644 index 0000000000..914f2e1e53 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/URLMatchingApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.sample; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; + +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +public class URLMatchingApplication { + public static void main(String[] args) { + SpringApplication.run(URLMatchingApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/config/WebConfig.java b/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/config/WebConfig.java new file mode 100644 index 0000000000..d4b70c63fa --- /dev/null +++ b/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/config/WebConfig.java @@ -0,0 +1,31 @@ +package com.baeldung.sample.config; + +import com.baeldung.sample.filters.TrailingSlashRedirectFilterReactive; +import jakarta.servlet.Filter; +import org.springframework.web.server.WebFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.baeldung.sample.filters.TrailingSlashRedirectFilter; + + + +@Configuration +public class WebConfig { + @Bean + public WebFilter trailingSlashRedirectReactiveFilter() { + return new TrailingSlashRedirectFilterReactive(); + } + @Bean + public Filter trailingSlashRedirectFilter() { + return new TrailingSlashRedirectFilter(); + } + @Bean + public FilterRegistrationBean trailingSlashFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(trailingSlashRedirectFilter()); + registrationBean.addUrlPatterns("/*"); + return registrationBean; + } +} diff --git a/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/filters/TrailingSlashRedirectFilter.java b/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/filters/TrailingSlashRedirectFilter.java new file mode 100644 index 0000000000..6db83b73f2 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/filters/TrailingSlashRedirectFilter.java @@ -0,0 +1,52 @@ +package com.baeldung.sample.filters; + +import java.io.IOException; +import jakarta.servlet.http.HttpServletRequestWrapper; +import org.springframework.stereotype.Component; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; + +@Component +public class TrailingSlashRedirectFilter implements Filter { + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + HttpServletRequest httpRequest = (HttpServletRequest) request; + String path = httpRequest.getRequestURI(); + + if (path.endsWith("/")) { + String newPath = path.substring(0, path.length() - 1); + HttpServletRequest newRequest = new CustomHttpServletRequestWrapper(httpRequest, newPath); + chain.doFilter(newRequest, response); + } else { + chain.doFilter(request, response); + } + } + + private static class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper { + + private final String newPath; + + public CustomHttpServletRequestWrapper(HttpServletRequest request, String newPath) { + super(request); + this.newPath = newPath; + } + + @Override + public String getRequestURI() { + return newPath; + } + + @Override + public StringBuffer getRequestURL() { + StringBuffer url = new StringBuffer(); + url.append(getScheme()).append("://").append(getServerName()).append(":").append(getServerPort()) + .append(newPath); + return url; + } + } +} diff --git a/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/filters/TrailingSlashRedirectFilterReactive.java b/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/filters/TrailingSlashRedirectFilterReactive.java new file mode 100644 index 0000000000..f983d81441 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/filters/TrailingSlashRedirectFilterReactive.java @@ -0,0 +1,27 @@ +package com.baeldung.sample.filters; + +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; + +import reactor.core.publisher.Mono; + +@Component +public class TrailingSlashRedirectFilterReactive implements WebFilter { + + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + ServerHttpRequest request = exchange.getRequest(); + String path = request.getPath().value(); + + if (path.endsWith("/")) { + String newPath = path.substring(0, path.length() - 1); + ServerHttpRequest newRequest = request.mutate().path(newPath).build(); + return chain.filter(exchange.mutate().request(newRequest).build()); + } + + return chain.filter(exchange); + } +} diff --git a/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/resources/GreetingsController.java b/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/resources/GreetingsController.java new file mode 100644 index 0000000000..5c98ed764e --- /dev/null +++ b/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/resources/GreetingsController.java @@ -0,0 +1,19 @@ +package com.baeldung.sample.resources; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class GreetingsController { + + @GetMapping("/some/greeting") + public String greeting() { + return "Hello"; + } + + @GetMapping("/some/greeting/") + public String greetingTrailingSlash() { + return "Hello with slash"; + } + +} diff --git a/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/resources/GreetingsControllerReactive.java b/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/resources/GreetingsControllerReactive.java new file mode 100644 index 0000000000..fde353ac43 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-url-matching/src/main/java/com/baeldung/sample/resources/GreetingsControllerReactive.java @@ -0,0 +1,20 @@ +package com.baeldung.sample.resources; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Mono; + +@RestController +public class GreetingsControllerReactive { + + @GetMapping("/some/reactive/greeting") + public Mono greeting() { + return Mono.just("Hello reactive"); + } + + @GetMapping("/some/reactive/greeting/") + public Mono greetingTrailingSlash() { + return Mono.just("Hello with slash reactive"); + } +} diff --git a/spring-boot-modules/spring-boot-3-url-matching/src/main/resources/application.yml b/spring-boot-modules/spring-boot-3-url-matching/src/main/resources/application.yml new file mode 100644 index 0000000000..8d047336f6 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-url-matching/src/main/resources/application.yml @@ -0,0 +1,7 @@ +spring: + mvc: + throw-exception-if-no-handler-found: true + jackson: + deserialization: + FAIL_ON_UNKNOWN_PROPERTIES: true + property-naming-strategy: SNAKE_CASE diff --git a/spring-boot-modules/spring-boot-3-url-matching/src/test/java/com/baeldung/sample/resources/GreetingsControllerApiIntegrationTest.java b/spring-boot-modules/spring-boot-3-url-matching/src/test/java/com/baeldung/sample/resources/GreetingsControllerApiIntegrationTest.java new file mode 100644 index 0000000000..754ef4aafe --- /dev/null +++ b/spring-boot-modules/spring-boot-3-url-matching/src/test/java/com/baeldung/sample/resources/GreetingsControllerApiIntegrationTest.java @@ -0,0 +1,45 @@ +package com.baeldung.sample.resources; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +@WebMvcTest(controllers = GreetingsController.class) +class GreetingsControllerApiIntegrationTest { + + private static final String BASEURL = "/some"; + private static final String DEFAULT_MEDIA_TYPE = MediaType.APPLICATION_JSON_VALUE; + + @Autowired + MockMvc mvc; + + @Test + public void testGreeting() throws Exception { + mvc.perform(get(BASEURL + "/greeting").accept(DEFAULT_MEDIA_TYPE)) + .andExpect(status().isOk()) + .andExpect(content().string("Hello")); + } + + @Test + @Disabled("Disabled while TrailingSlashRedirectFilter is in use.") + public void testGreetingTrailingSlash() throws Exception { + mvc.perform(get(BASEURL + "/greeting/").accept(DEFAULT_MEDIA_TYPE)) + .andExpect(status().isOk()) + .andExpect(content().string("Hello with slash")); + } + + @Test + public void testGreetingTrailingSlashWithFilter() throws Exception { + mvc.perform(get(BASEURL + "/greeting/").accept(DEFAULT_MEDIA_TYPE)) + .andExpect(status().isOk()) + .andExpect(content().string("Hello")); + } + +} diff --git a/spring-boot-modules/spring-boot-3-url-matching/src/test/java/com/baeldung/sample/resources/GreetingsControllerReactiveApiIntegrationTest.java b/spring-boot-modules/spring-boot-3-url-matching/src/test/java/com/baeldung/sample/resources/GreetingsControllerReactiveApiIntegrationTest.java new file mode 100644 index 0000000000..9d5e439a74 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-url-matching/src/test/java/com/baeldung/sample/resources/GreetingsControllerReactiveApiIntegrationTest.java @@ -0,0 +1,46 @@ +package com.baeldung.sample.resources; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.test.web.reactive.server.WebTestClient; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@WebFluxTest +public class GreetingsControllerReactiveApiIntegrationTest { + private static final String BASEURL = "/some/reactive"; + @Autowired + private WebTestClient webClient; + @Test + public void testGreeting() { + webClient.get().uri( BASEURL + "/greeting") + .exchange() + .expectStatus().isOk() + .expectBody().consumeWith(result -> { + String responseBody = new String(result.getResponseBody()); + assertTrue(responseBody.contains("Hello reactive")); + }); + } + @Test + @Disabled("Disabled while TrailingSlashRedirectFilter is in use.") + public void testGreetingTrailingSlash() { + webClient.get().uri(BASEURL + "/greeting/") + .exchange() + .expectStatus().isOk() + .expectBody().consumeWith(result -> { + String responseBody = new String(result.getResponseBody()); + assertTrue(responseBody.contains("Hello with slash reactive")); + }); + } + @Test + public void testGreetingTrailingSlashWithFilter() { + webClient.get().uri(BASEURL + "/greeting/") + .exchange() + .expectStatus().isOk() + .expectBody().consumeWith(result -> { + String responseBody = new String(result.getResponseBody()); + assertTrue(responseBody.contains("Hello reactive")); + }); + } +} diff --git a/spring-boot-modules/spring-boot-3/README.md b/spring-boot-modules/spring-boot-3/README.md index 5fa884a053..e99eb79127 100644 --- a/spring-boot-modules/spring-boot-3/README.md +++ b/spring-boot-modules/spring-boot-3/README.md @@ -4,3 +4,6 @@ - [Spring Boot 3 and Spring Framework 6.0 – What’s New](https://www.baeldung.com/spring-boot-3-spring-6-new) - [Singleton Design Pattern vs Singleton Beans in Spring Boot](https://www.baeldung.com/spring-boot-singleton-vs-beans) - [Migrate Application From Spring Boot 2 to Spring Boot 3](https://www.baeldung.com/spring-boot-3-migration) +- [Using Java Records with JPA](https://www.baeldung.com/spring-jpa-java-records) +- [HTTP Interface in Spring 6](https://www.baeldung.com/spring-6-http-interface) +- [Working with Virtual Threads in Spring 6](https://www.baeldung.com/spring-6-virtual-threads) diff --git a/spring-boot-modules/spring-boot-3/pom.xml b/spring-boot-modules/spring-boot-3/pom.xml index 685df233ba..8fe995ca91 100644 --- a/spring-boot-modules/spring-boot-3/pom.xml +++ b/spring-boot-modules/spring-boot-3/pom.xml @@ -32,6 +32,20 @@ org.springframework.boot spring-boot-starter-data-jpa + + org.springframework.boot + spring-boot-starter-webflux + + + org.mock-server + mockserver-netty + ${mockserver.version} + + + org.mock-server + mockserver-client-java + ${mockserver.version} + com.h2database h2 @@ -102,6 +116,7 @@ org.springframework.boot spring-boot-maven-plugin + com.baeldung.virtualthreads.VirtualThreadsApp org.projectlombok @@ -117,15 +132,23 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-compiler-plugin + + --enable-preview + + + 19 1.5.2.Final 2.0.0 3.0.0-M7 com.baeldung.sample.TodoApplication - + 5.14.0 \ No newline at end of file diff --git a/spring-core-6/src/main/java/com/baeldung/httpinterface/Book.java b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/httpinterface/Book.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/httpinterface/Book.java rename to spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/httpinterface/Book.java diff --git a/spring-core-6/src/main/java/com/baeldung/httpinterface/BooksClient.java b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/httpinterface/BooksClient.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/httpinterface/BooksClient.java rename to spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/httpinterface/BooksClient.java diff --git a/spring-core-6/src/main/java/com/baeldung/httpinterface/BooksService.java b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/httpinterface/BooksService.java similarity index 85% rename from spring-core-6/src/main/java/com/baeldung/httpinterface/BooksService.java rename to spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/httpinterface/BooksService.java index a9cf6ec58a..a70d412dd2 100644 --- a/spring-core-6/src/main/java/com/baeldung/httpinterface/BooksService.java +++ b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/httpinterface/BooksService.java @@ -15,12 +15,12 @@ interface BooksService { List getBooks(); @GetExchange("/books/{id}") - Book getBook(@PathVariable long id); + Book getBook(@PathVariable("id") long id); @PostExchange("/books") Book saveBook(@RequestBody Book book); @DeleteExchange("/books/{id}") - ResponseEntity deleteBook(@PathVariable long id); + ResponseEntity deleteBook(@PathVariable("id") long id); } diff --git a/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/virtualthreads/VirtualThreadsApp.java b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/virtualthreads/VirtualThreadsApp.java new file mode 100644 index 0000000000..159fa1c243 --- /dev/null +++ b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/virtualthreads/VirtualThreadsApp.java @@ -0,0 +1,13 @@ +package com.baeldung.virtualthreads; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class VirtualThreadsApp { + + public static void main(String[] args) { + SpringApplication.run(VirtualThreadsApp.class, args); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/virtualthreads/config/ThreadConfig.java b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/virtualthreads/config/ThreadConfig.java new file mode 100644 index 0000000000..7231ec0b94 --- /dev/null +++ b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/virtualthreads/config/ThreadConfig.java @@ -0,0 +1,33 @@ +package com.baeldung.virtualthreads.config; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.AsyncTaskExecutor; +import org.springframework.core.task.support.TaskExecutorAdapter; +import org.springframework.scheduling.annotation.EnableAsync; + +import java.util.concurrent.Executors; + +@EnableAsync +@Configuration +@ConditionalOnProperty( + value = "spring.thread-executor", + havingValue = "virtual" +) +public class ThreadConfig { + + @Bean + public AsyncTaskExecutor applicationTaskExecutor() { + return new TaskExecutorAdapter(Executors.newVirtualThreadPerTaskExecutor()); + } + + @Bean + public TomcatProtocolHandlerCustomizer protocolHandlerVirtualThreadExecutorCustomizer() { + return protocolHandler -> { + protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor()); + }; + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/virtualthreads/controller/LoadTestController.java b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/virtualthreads/controller/LoadTestController.java new file mode 100644 index 0000000000..d99d3824a0 --- /dev/null +++ b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/virtualthreads/controller/LoadTestController.java @@ -0,0 +1,23 @@ +package com.baeldung.virtualthreads.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; + +@RestController +@RequestMapping("/load") +public class LoadTestController { + + private static final Logger LOG = LoggerFactory.getLogger(LoadTestController.class); + + @GetMapping + public void doSomething() throws InterruptedException { + LOG.info("hey, I'm doing something"); + Thread.sleep(1000); + } + +} diff --git a/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/virtualthreads/controller/ThreadController.java b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/virtualthreads/controller/ThreadController.java new file mode 100644 index 0000000000..73b28ce9f0 --- /dev/null +++ b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/virtualthreads/controller/ThreadController.java @@ -0,0 +1,16 @@ +package com.baeldung.virtualthreads.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/thread") +public class ThreadController { + + @GetMapping("/name") + public String getThreadName() { + return Thread.currentThread().toString(); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3/src/main/resources/application.yml b/spring-boot-modules/spring-boot-3/src/main/resources/application.yml index 9a966a5bbd..5f9031bc9e 100644 --- a/spring-boot-modules/spring-boot-3/src/main/resources/application.yml +++ b/spring-boot-modules/spring-boot-3/src/main/resources/application.yml @@ -14,8 +14,10 @@ spring: properties: hibernate: dialect: org.hibernate.dialect.H2Dialect + thread-executor: standard + # Custom Properties cors: allow: origins: ${CORS_ALLOWED_ORIGINS:*} - credentials: ${CORS_ALLOW_CREDENTIALS:false} + credentials: ${CORS_ALLOW_CREDENTIALS:false} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3/src/test/HTTP Load Request .jmx b/spring-boot-modules/spring-boot-3/src/test/HTTP Load Request .jmx new file mode 100644 index 0000000000..bbd02cecbe --- /dev/null +++ b/spring-boot-modules/spring-boot-3/src/test/HTTP Load Request .jmx @@ -0,0 +1,125 @@ + + + + + + false + true + false + + + + + + + + stoptest + + false + -1 + + 1000 + 10 + true + 100 + + true + + + + + + + localhost + 8080 + + + /load + GET + true + false + true + false + + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + + diff --git a/core-java-modules/core-java/src/test/resources/newFile1.txt b/spring-boot-modules/spring-boot-3/src/test/java/com/baeldung/httpinterface/BooksServiceMockServerUnitTest.java similarity index 100% rename from core-java-modules/core-java/src/test/resources/newFile1.txt rename to spring-boot-modules/spring-boot-3/src/test/java/com/baeldung/httpinterface/BooksServiceMockServerUnitTest.java diff --git a/core-java-modules/core-java/src/test/resources/newFile2.txt b/spring-boot-modules/spring-boot-3/src/test/java/com/baeldung/httpinterface/BooksServiceMockitoUnitTest.java similarity index 100% rename from core-java-modules/core-java/src/test/resources/newFile2.txt rename to spring-boot-modules/spring-boot-3/src/test/java/com/baeldung/httpinterface/BooksServiceMockitoUnitTest.java diff --git a/spring-core-6/src/test/java/com/baeldung/httpinterface/MyServiceException.java b/spring-boot-modules/spring-boot-3/src/test/java/com/baeldung/httpinterface/MyServiceException.java similarity index 100% rename from spring-core-6/src/test/java/com/baeldung/httpinterface/MyServiceException.java rename to spring-boot-modules/spring-boot-3/src/test/java/com/baeldung/httpinterface/MyServiceException.java diff --git a/spring-boot-modules/spring-boot-annotations-2/README.md b/spring-boot-modules/spring-boot-annotations-2/README.md index bea5d2fec6..541fa2fd73 100644 --- a/spring-boot-modules/spring-boot-annotations-2/README.md +++ b/spring-boot-modules/spring-boot-annotations-2/README.md @@ -7,4 +7,8 @@ This module contains articles about Spring Boot annotations - [Spring Conditional Annotations](https://www.baeldung.com/spring-conditional-annotations) - [Guide to @SpringBootConfiguration in Spring Boot](https://www.baeldung.com/springbootconfiguration-annotation) - [Spring @Primary Annotation](http://www.baeldung.com/spring-primary) +- [Spring Bean Names](https://www.baeldung.com/spring-bean-names) +- [AliasFor Annotation in Spring](https://www.baeldung.com/spring-aliasfor-annotation) +- [A Quick Guide to the Spring @Lazy Annotation](https://www.baeldung.com/spring-lazy-annotation) +- [Instantiating Multiple Beans of the Same Class with Spring Annotations](https://www.baeldung.com/spring-same-class-multiple-beans) - More articles: [[<-- prev]](/spring-boot-modules/spring-boot-annotations) diff --git a/spring-boot-modules/spring-boot-annotations-2/pom.xml b/spring-boot-modules/spring-boot-annotations-2/pom.xml index 99d1c4587b..71fc7ff388 100644 --- a/spring-boot-modules/spring-boot-annotations-2/pom.xml +++ b/spring-boot-modules/spring-boot-annotations-2/pom.xml @@ -28,6 +28,11 @@ mockito-inline test + + org.springframework.boot + spring-boot-starter-test + test + \ No newline at end of file diff --git a/spring-core-5/src/main/java/com/baeldung/aliasfor/MyMapping.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/aliasfor/MyMapping.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/aliasfor/MyMapping.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/aliasfor/MyMapping.java diff --git a/spring-core-5/src/main/java/com/baeldung/aliasfor/MyMappingController.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/aliasfor/MyMappingController.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/aliasfor/MyMappingController.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/aliasfor/MyMappingController.java diff --git a/spring-core-5/src/main/java/com/baeldung/lazy/AppConfig.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/lazy/AppConfig.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/lazy/AppConfig.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/lazy/AppConfig.java diff --git a/spring-core-5/src/main/java/com/baeldung/lazy/City.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/lazy/City.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/lazy/City.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/lazy/City.java diff --git a/spring-core-5/src/main/java/com/baeldung/lazy/Country.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/lazy/Country.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/lazy/Country.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/lazy/Country.java diff --git a/spring-core-5/src/main/java/com/baeldung/lazy/Region.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/lazy/Region.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/lazy/Region.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/lazy/Region.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/Person.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution1/Person.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/Person.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution1/Person.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/PersonConfig.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution1/PersonConfig.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/PersonConfig.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution1/PersonConfig.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/SpringApp1.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution1/SpringApp1.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution1/SpringApp1.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution1/SpringApp1.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/Person.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution2/Person.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/Person.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution2/Person.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonConfig.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonConfig.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonConfig.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonConfig.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonOne.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonOne.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonOne.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonOne.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonTwo.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonTwo.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonTwo.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution2/PersonTwo.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/SpringApp2.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution2/SpringApp2.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution2/SpringApp2.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution2/SpringApp2.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/Human.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution3/Human.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/Human.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution3/Human.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/MultiBeanFactory.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution3/MultiBeanFactory.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/MultiBeanFactory.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution3/MultiBeanFactory.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/Person.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution3/Person.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/Person.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution3/Person.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/PersonConfig.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution3/PersonConfig.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/PersonConfig.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution3/PersonConfig.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/PersonFactoryPostProcessor.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution3/PersonFactoryPostProcessor.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/PersonFactoryPostProcessor.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution3/PersonFactoryPostProcessor.java diff --git a/spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/SpringApp3.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution3/SpringApp3.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/multibeaninstantiation/solution3/SpringApp3.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/multibeaninstantiation/solution3/SpringApp3.java diff --git a/spring-core-5/src/main/java/com/baeldung/springbean/naming/component/Animal.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/component/Animal.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/springbean/naming/component/Animal.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/component/Animal.java diff --git a/spring-core-5/src/main/java/com/baeldung/springbean/naming/component/Cat.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/component/Cat.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/springbean/naming/component/Cat.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/component/Cat.java diff --git a/spring-core-5/src/main/java/com/baeldung/springbean/naming/component/CustomComponent.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/component/CustomComponent.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/springbean/naming/component/CustomComponent.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/component/CustomComponent.java diff --git a/spring-core-5/src/main/java/com/baeldung/springbean/naming/component/Dog.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/component/Dog.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/springbean/naming/component/Dog.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/component/Dog.java diff --git a/spring-core-5/src/main/java/com/baeldung/springbean/naming/configuration/AuditConfiguration.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/configuration/AuditConfiguration.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/springbean/naming/configuration/AuditConfiguration.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/configuration/AuditConfiguration.java diff --git a/spring-core-5/src/main/java/com/baeldung/springbean/naming/configuration/MyConfiguration.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/configuration/MyConfiguration.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/springbean/naming/configuration/MyConfiguration.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/configuration/MyConfiguration.java diff --git a/spring-core-5/src/main/java/com/baeldung/springbean/naming/controller/MessagingController.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/controller/MessagingController.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/springbean/naming/controller/MessagingController.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/controller/MessagingController.java diff --git a/spring-core-5/src/main/java/com/baeldung/springbean/naming/service/AuditService.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/service/AuditService.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/springbean/naming/service/AuditService.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/service/AuditService.java diff --git a/spring-core-5/src/main/java/com/baeldung/springbean/naming/service/LoggingService.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/service/LoggingService.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/springbean/naming/service/LoggingService.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/service/LoggingService.java diff --git a/spring-core-5/src/main/java/com/baeldung/springbean/naming/service/MessagingService.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/service/MessagingService.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/springbean/naming/service/MessagingService.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/service/MessagingService.java diff --git a/spring-core-5/src/main/java/com/baeldung/springbean/naming/service/MessagingServiceImpl.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/service/MessagingServiceImpl.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/springbean/naming/service/MessagingServiceImpl.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/service/MessagingServiceImpl.java diff --git a/spring-core-5/src/main/java/com/baeldung/springbean/naming/service/PetShow.java b/spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/service/PetShow.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/springbean/naming/service/PetShow.java rename to spring-boot-modules/spring-boot-annotations-2/src/main/java/com/baeldung/springbean/naming/service/PetShow.java diff --git a/spring-core-5/src/test/java/com/baeldung/aliasfor/AliasForUnitTest.java b/spring-boot-modules/spring-boot-annotations-2/src/test/java/com/baeldung/aliasfor/AliasForUnitTest.java similarity index 100% rename from spring-core-5/src/test/java/com/baeldung/aliasfor/AliasForUnitTest.java rename to spring-boot-modules/spring-boot-annotations-2/src/test/java/com/baeldung/aliasfor/AliasForUnitTest.java diff --git a/spring-core-5/src/test/java/com/baeldung/lazy/LazyAnnotationUnitTest.java b/spring-boot-modules/spring-boot-annotations-2/src/test/java/com/baeldung/lazy/LazyAnnotationUnitTest.java similarity index 100% rename from spring-core-5/src/test/java/com/baeldung/lazy/LazyAnnotationUnitTest.java rename to spring-boot-modules/spring-boot-annotations-2/src/test/java/com/baeldung/lazy/LazyAnnotationUnitTest.java diff --git a/spring-core-5/src/test/java/com/baeldung/springbean/naming/SpringBeanNamingUnitTest.java b/spring-boot-modules/spring-boot-annotations-2/src/test/java/com/baeldung/springbean/naming/SpringBeanNamingUnitTest.java similarity index 100% rename from spring-core-5/src/test/java/com/baeldung/springbean/naming/SpringBeanNamingUnitTest.java rename to spring-boot-modules/spring-boot-annotations-2/src/test/java/com/baeldung/springbean/naming/SpringBeanNamingUnitTest.java diff --git a/spring-boot-modules/spring-boot-aws/README.md b/spring-boot-modules/spring-boot-aws/README.md index 7d843af9ea..06725c209d 100644 --- a/spring-boot-modules/spring-boot-aws/README.md +++ b/spring-boot-modules/spring-boot-aws/README.md @@ -1 +1,2 @@ ### Relevant Articles: +- [Run a Spring Boot Application in AWS Lambda](https://www.baeldung.com/spring-boot-aws-lambda) diff --git a/spring-boot-modules/spring-boot-cli/README.md b/spring-boot-modules/spring-boot-cli/README.md index 79e259c855..4ed50d3f56 100644 --- a/spring-boot-modules/spring-boot-cli/README.md +++ b/spring-boot-modules/spring-boot-cli/README.md @@ -4,3 +4,4 @@ This module contains articles about Spring Boot CLI ### Relevant Articles: - [Introduction to Spring Boot CLI](https://www.baeldung.com/spring-boot-cli) +- [Encode Passwords With Spring Boot CLI](https://www.baeldung.com/spring-boot-cli-encode-passwords) diff --git a/spring-boot-modules/spring-boot-cli/pom.xml b/spring-boot-modules/spring-boot-cli/pom.xml new file mode 100644 index 0000000000..d2c50590ab --- /dev/null +++ b/spring-boot-modules/spring-boot-cli/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + spring-boot-cli + spring-boot-cli + jar + + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-cli/src/main/java/com/baeldung/Application.java b/spring-boot-modules/spring-boot-cli/src/main/java/com/baeldung/Application.java new file mode 100644 index 0000000000..c0490d50c6 --- /dev/null +++ b/spring-boot-modules/spring-boot-cli/src/main/java/com/baeldung/Application.java @@ -0,0 +1,12 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-cli/src/main/java/com/baeldung/controller/LoginController.java b/spring-boot-modules/spring-boot-cli/src/main/java/com/baeldung/controller/LoginController.java new file mode 100644 index 0000000000..b678f63623 --- /dev/null +++ b/spring-boot-modules/spring-boot-cli/src/main/java/com/baeldung/controller/LoginController.java @@ -0,0 +1,13 @@ +package com.baeldung.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class LoginController { + + @GetMapping("/") + public String hello() { + return "Hello World!"; + } +} diff --git a/spring-boot-modules/spring-boot-cli/src/main/resources/application.properties b/spring-boot-modules/spring-boot-cli/src/main/resources/application.properties new file mode 100644 index 0000000000..4b341094a1 --- /dev/null +++ b/spring-boot-modules/spring-boot-cli/src/main/resources/application.properties @@ -0,0 +1,3 @@ +spring.security.user.name=baeldung +# Encoded password with SpringBoot CLI, the decoded password is baeldungPassword +spring.security.user.password={bcrypt}$2y$10$R8VIwFiQ7aUST17YqMaWJuxjkCYqk3jjPlSxyDLLzqCTOwFuJNq2a \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-cli/src/test/java/com/baeldung/encoding/PasswordEncodingUnitTest.java b/spring-boot-modules/spring-boot-cli/src/test/java/com/baeldung/encoding/PasswordEncodingUnitTest.java new file mode 100644 index 0000000000..8939029f71 --- /dev/null +++ b/spring-boot-modules/spring-boot-cli/src/test/java/com/baeldung/encoding/PasswordEncodingUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.encoding; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +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.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@AutoConfigureMockMvc +public class PasswordEncodingUnitTest { + private final static String userName = "baeldung"; + private final static String passwordDecoded = "baeldungPassword"; + + private MockMvc mvc; + + @Autowired + private WebApplicationContext webApplicationContext; + + @Before + public void setup() { + mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) + .apply(springSecurity()) + .build(); + } + + @Test + public void givenRequestWithWrongPassword_shouldFailWith401() throws Exception { + mvc.perform(get("/").with(httpBasic(userName, "wrongPassword"))) + .andExpect(status().isUnauthorized()); + + } + + @Test + public void givenRequestWithCorrectDecodedPassword_houldSucceedWith200() throws Exception { + mvc.perform(get("/").with(httpBasic(userName, passwordDecoded))) + .andExpect(status().isOk()); + + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-data-3/README.md b/spring-boot-modules/spring-boot-data-3/README.md index 3959894853..7130d25118 100644 --- a/spring-boot-modules/spring-boot-data-3/README.md +++ b/spring-boot-modules/spring-boot-data-3/README.md @@ -1,2 +1,4 @@ ### Relevant Articles: - [Spring Data JPA – Run an App Without a Database](https://www.baeldung.com/spring-data-jpa-run-app-without-db) +- [Integrate AWS Secrets Manager in Spring Boot](https://www.baeldung.com/spring-boot-integrate-aws-secrets-manager) +- [Fix Spring Data JPA Exception: No Property Found for Type](https://www.baeldung.com/spring-data-jpa-exception-no-property-found-for-type) diff --git a/spring-boot-modules/spring-boot-data-3/pom.xml b/spring-boot-modules/spring-boot-data-3/pom.xml index cf53c25697..4903d2ea26 100644 --- a/spring-boot-modules/spring-boot-data-3/pom.xml +++ b/spring-boot-modules/spring-boot-data-3/pom.xml @@ -25,15 +25,29 @@ spring-boot-starter-data-jpa - com.mysql - mysql-connector-j + com.amazonaws.secretsmanager + aws-secretsmanager-jdbc + ${aws.secrets.manager.jdbc} + + + mysql + mysql-connector-java runtime + + com.h2database + h2 + org.springframework.boot spring-boot-starter-test test + + io.awspring.cloud + spring-cloud-starter-aws-secrets-manager-config + ${aws.secrets.manager.config} + @@ -45,4 +59,9 @@ + + 2.4.4 + 1.0.11 + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/nopropertyfound/NoPropertyFoundApplication.java b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/nopropertyfound/NoPropertyFoundApplication.java new file mode 100644 index 0000000000..276df9535b --- /dev/null +++ b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/nopropertyfound/NoPropertyFoundApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.nopropertyfound; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class NoPropertyFoundApplication { + + public static void main(String[] args) { + SpringApplication.run(NoPropertyFoundApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/nopropertyfound/config/DbConfig.java b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/nopropertyfound/config/DbConfig.java new file mode 100644 index 0000000000..9a589e55a3 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/nopropertyfound/config/DbConfig.java @@ -0,0 +1,20 @@ +package com.baeldung.nopropertyfound.config; + +import javax.sql.DataSource; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class DbConfig { + + @Bean + @ConfigurationProperties(prefix = "h2.datasource") + public DataSource dataSource() { + return DataSourceBuilder.create() + .build(); + } + +} diff --git a/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/nopropertyfound/model/Person.java b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/nopropertyfound/model/Person.java new file mode 100644 index 0000000000..3392d3ec67 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/nopropertyfound/model/Person.java @@ -0,0 +1,41 @@ +package com.baeldung.nopropertyfound.model; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Person { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + private String firstName; + private String lastName; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + +} diff --git a/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/nopropertyfound/repository/PersonRepository.java b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/nopropertyfound/repository/PersonRepository.java new file mode 100644 index 0000000000..900c391c93 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/nopropertyfound/repository/PersonRepository.java @@ -0,0 +1,15 @@ +package com.baeldung.nopropertyfound.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.baeldung.nopropertyfound.model.Person; + +@Repository +public interface PersonRepository extends JpaRepository { + + // findByFirsttName will cause Spring Data to throw PropertyReferenceException + // Person findByFirsttName(String firstName); + Person findByFirstName(String firstName); + +} diff --git a/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/startdbwithawssecretsmanager/StartWithAWSSecretsManagerApplication.java b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/startdbwithawssecretsmanager/StartWithAWSSecretsManagerApplication.java new file mode 100644 index 0000000000..0bcbef7729 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/startdbwithawssecretsmanager/StartWithAWSSecretsManagerApplication.java @@ -0,0 +1,29 @@ +package com.baeldung.startdbwithawssecretsmanager; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Profile; + +import javax.annotation.PostConstruct; + +@SpringBootApplication +@Profile("aws") +public class StartWithAWSSecretsManagerApplication { + @Value("${api-key1}") + private String apiKeyValue1; + + @Value("${api-key2}") + private String apiKeyValue2; + + @PostConstruct + private void postConstruct() { + System.out.println(apiKeyValue1); + System.out.println(apiKeyValue2); + } + + public static void main(String[] args) { + SpringApplication.run(StartWithAWSSecretsManagerApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/startdbwithawssecretsmanager/controller/UserController.java b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/startdbwithawssecretsmanager/controller/UserController.java new file mode 100644 index 0000000000..08745db3f0 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/startdbwithawssecretsmanager/controller/UserController.java @@ -0,0 +1,38 @@ +package com.baeldung.startdbwithawssecretsmanager.controller; + +import com.baeldung.startdbwithawssecretsmanager.model.UserEntity; +import com.baeldung.startdbwithawssecretsmanager.repository.UserRepository; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +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.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("users") +public class UserController { + + private final UserRepository userRepository; + + public UserController(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @GetMapping(value = "/{id}", produces = "application/json") + public @ResponseBody UserEntity getUser(@PathVariable Long id) { + return userRepository.findById(id).get(); + } + + @PostMapping + public UserEntity createUser(@RequestBody UserEntity userEntity) { + return userRepository.save(userEntity); + } + + @DeleteMapping(value = "/{id}") + public void removeUser(@PathVariable Long id) { + userRepository.deleteById(id); + } +} diff --git a/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/startdbwithawssecretsmanager/model/UserEntity.java b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/startdbwithawssecretsmanager/model/UserEntity.java new file mode 100644 index 0000000000..285e7094dd --- /dev/null +++ b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/startdbwithawssecretsmanager/model/UserEntity.java @@ -0,0 +1,40 @@ +package com.baeldung.startdbwithawssecretsmanager.model; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class UserEntity { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String name; + + public UserEntity() { + } + + public UserEntity(Long id, String name) { + this.id = id; + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/startdbwithawssecretsmanager/repository/UserRepository.java b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/startdbwithawssecretsmanager/repository/UserRepository.java new file mode 100644 index 0000000000..e2abfe88e6 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-3/src/main/java/com/baeldung/startdbwithawssecretsmanager/repository/UserRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.startdbwithawssecretsmanager.repository; + +import com.baeldung.startdbwithawssecretsmanager.model.UserEntity; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserRepository + extends CrudRepository { +} diff --git a/spring-boot-modules/spring-boot-data-3/src/main/resources/application-aws.properties b/spring-boot-modules/spring-boot-data-3/src/main/resources/application-aws.properties new file mode 100644 index 0000000000..07c4b0a4d6 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-3/src/main/resources/application-aws.properties @@ -0,0 +1,9 @@ +spring.datasource.driver-class-name=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver +spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect +spring.datasource.url=jdbc-secretsmanager:mysql://database-1.cwhqvgjbpgfw.eu-central-1.rds.amazonaws.com:3306/test +spring.datasource.username=rds/credentials + +#Overwriting application.properties configuration back to default. +spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=true + +spring.config.import=aws-secretsmanager:test/secret/ diff --git a/spring-boot-modules/spring-boot-data-3/src/main/resources/application.properties b/spring-boot-modules/spring-boot-data-3/src/main/resources/application.properties index cbe044134f..71f39e0ee3 100644 --- a/spring-boot-modules/spring-boot-data-3/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-data-3/src/main/resources/application.properties @@ -4,4 +4,9 @@ spring.datasource.username=root spring.datasource.password=root spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect spring.jpa.hibernate.ddl-auto=none -spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false \ No newline at end of file +spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false + +h2.datasource.url=jdbc:h2:mem:testdb +h2.datasource.driver-class-name=org.h2.Driver +h2.datasource.username=sa +h2.datasource.password= diff --git a/spring-boot-modules/spring-boot-data-3/src/main/resources/data.sql b/spring-boot-modules/spring-boot-data-3/src/main/resources/data.sql new file mode 100644 index 0000000000..5623bbfadf --- /dev/null +++ b/spring-boot-modules/spring-boot-data-3/src/main/resources/data.sql @@ -0,0 +1,3 @@ +INSERT INTO person (first_name, last_name) VALUES('Azhrioun', 'Abderrahim'); +INSERT INTO person (first_name, last_name) VALUES('Brian', 'Wheeler'); +INSERT INTO person (first_name, last_name) VALUES('Dave', 'Anderson'); \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-data-3/src/main/resources/schema.sql b/spring-boot-modules/spring-boot-data-3/src/main/resources/schema.sql new file mode 100644 index 0000000000..738ef25298 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-3/src/main/resources/schema.sql @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS person; +CREATE TABLE person( + id INT AUTO_INCREMENT PRIMARY KEY, + first_name VARCHAR(200), + last_name VARCHAR(200) +) \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-data-3/src/test/java/com/baeldung/nopropertyfound/PersonRepositoryIntegrationTest.java b/spring-boot-modules/spring-boot-data-3/src/test/java/com/baeldung/nopropertyfound/PersonRepositoryIntegrationTest.java new file mode 100644 index 0000000000..2a9d1a46f2 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-3/src/test/java/com/baeldung/nopropertyfound/PersonRepositoryIntegrationTest.java @@ -0,0 +1,28 @@ +package com.baeldung.nopropertyfound; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +import com.baeldung.nopropertyfound.model.Person; +import com.baeldung.nopropertyfound.repository.PersonRepository; + +@DataJpaTest +class PersonRepositoryIntegrationTest { + + @Autowired + private PersonRepository personRepository; + + @Test + void givenQueryMethod_whenUsingValidProperty_thenCorrect() { + + Person person = personRepository.findByFirstName("Azhrioun"); + + assertNotNull(person); + assertEquals("Abderrahim", person.getLastName()); + } + +} diff --git a/spring-boot-modules/spring-boot-environment/README.md b/spring-boot-modules/spring-boot-environment/README.md index 687322938e..c3e1866491 100644 --- a/spring-boot-modules/spring-boot-environment/README.md +++ b/spring-boot-modules/spring-boot-environment/README.md @@ -7,3 +7,4 @@ This module contains articles about configuring the Spring Boot `Environment` - [Spring Properties File Outside jar](https://www.baeldung.com/spring-properties-file-outside-jar) - [Get the Running Port in Spring Boot](https://www.baeldung.com/spring-boot-running-port) - [Environment Variable Prefixes in Spring Boot 2.5](https://www.baeldung.com/spring-boot-env-variable-prefixes) + - [Spring Profiles](http://www.baeldung.com/spring-profiles) diff --git a/spring-boot-modules/spring-boot-environment/pom.xml b/spring-boot-modules/spring-boot-environment/pom.xml index 3ea591f561..013156fa7f 100644 --- a/spring-boot-modules/spring-boot-environment/pom.xml +++ b/spring-boot-modules/spring-boot-environment/pom.xml @@ -133,8 +133,23 @@ + + dev + + true + + + dev + + + + prod + + prod + + - + 2.2 3.1.7 diff --git a/spring-core-2/src/main/java/com/baeldung/profiles/DatasourceConfig.java b/spring-boot-modules/spring-boot-environment/src/main/java/com/baeldung/profiles/DatasourceConfig.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/profiles/DatasourceConfig.java rename to spring-boot-modules/spring-boot-environment/src/main/java/com/baeldung/profiles/DatasourceConfig.java diff --git a/spring-core-2/src/main/java/com/baeldung/profiles/DevDatasourceConfig.java b/spring-boot-modules/spring-boot-environment/src/main/java/com/baeldung/profiles/DevDatasourceConfig.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/profiles/DevDatasourceConfig.java rename to spring-boot-modules/spring-boot-environment/src/main/java/com/baeldung/profiles/DevDatasourceConfig.java diff --git a/spring-core-2/src/main/java/com/baeldung/profiles/ProductionDatasourceConfig.java b/spring-boot-modules/spring-boot-environment/src/main/java/com/baeldung/profiles/ProductionDatasourceConfig.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/profiles/ProductionDatasourceConfig.java rename to spring-boot-modules/spring-boot-environment/src/main/java/com/baeldung/profiles/ProductionDatasourceConfig.java diff --git a/spring-core-2/src/main/java/com/baeldung/profiles/ProfileManager.java b/spring-boot-modules/spring-boot-environment/src/main/java/com/baeldung/profiles/ProfileManager.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/profiles/ProfileManager.java rename to spring-boot-modules/spring-boot-environment/src/main/java/com/baeldung/profiles/ProfileManager.java diff --git a/spring-core-2/src/main/java/com/baeldung/profiles/SpringProfilesConfig.java b/spring-boot-modules/spring-boot-environment/src/main/java/com/baeldung/profiles/SpringProfilesConfig.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/profiles/SpringProfilesConfig.java rename to spring-boot-modules/spring-boot-environment/src/main/java/com/baeldung/profiles/SpringProfilesConfig.java diff --git a/spring-boot-modules/spring-boot-environment/src/main/resources/application.properties b/spring-boot-modules/spring-boot-environment/src/main/resources/application.properties index 4ffb414e92..8333184f1e 100644 --- a/spring-boot-modules/spring-boot-environment/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-environment/src/main/resources/application.properties @@ -4,4 +4,34 @@ management.metrics.enable.jvm=true management.endpoint.restart.enabled=true spring.datasource.tomcat.jmx-enabled=false management.endpoint.shutdown.enabled=true -spring.config.import=file:./additional.properties,optional:file:/Users/home/config/jdbc.properties \ No newline at end of file +spring.config.import=file:./additional.properties,optional:file:/Users/home/config/jdbc.properties + +#--- +spring.profiles.active=@spring.profiles.active@ + +my.prop=used-always-in-all-profiles + +#--- +spring.config.activate.on-profile=dev +#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +#spring.datasource.url=jdbc:mysql://localhost:3306/db +#spring.datasource.username=root +#spring.datasource.password=root + +#--- +spring.config.activate.on-profile=production +#spring.datasource.driver-class-name=org.h2.Driver +#spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +#spring.datasource.username=sa +#spring.datasource.password=sa + +#--- +spring.profiles.group.production=proddb,prodquartz + +#--- +spring.config.activate.on-profile=proddb +db=url_to_production_db + +#--- +spring.config.activate.on-profile=prodquartz +quartz=url_to_quartz_scheduler \ No newline at end of file diff --git a/spring-core-2/src/main/resources/springProfiles-config.xml b/spring-boot-modules/spring-boot-environment/src/main/resources/springProfiles-config.xml similarity index 100% rename from spring-core-2/src/main/resources/springProfiles-config.xml rename to spring-boot-modules/spring-boot-environment/src/main/resources/springProfiles-config.xml diff --git a/spring-core-2/src/test/java/com/baeldung/profiles/DevProfileWithAnnotationIntegrationTest.java b/spring-boot-modules/spring-boot-environment/src/test/java/com/baeldung/profiles/DevProfileWithAnnotationIntegrationTest.java similarity index 100% rename from spring-core-2/src/test/java/com/baeldung/profiles/DevProfileWithAnnotationIntegrationTest.java rename to spring-boot-modules/spring-boot-environment/src/test/java/com/baeldung/profiles/DevProfileWithAnnotationIntegrationTest.java diff --git a/spring-core-2/src/test/java/com/baeldung/profiles/ProductionProfileWithAnnotationIntegrationTest.java b/spring-boot-modules/spring-boot-environment/src/test/java/com/baeldung/profiles/ProductionProfileWithAnnotationIntegrationTest.java similarity index 100% rename from spring-core-2/src/test/java/com/baeldung/profiles/ProductionProfileWithAnnotationIntegrationTest.java rename to spring-boot-modules/spring-boot-environment/src/test/java/com/baeldung/profiles/ProductionProfileWithAnnotationIntegrationTest.java diff --git a/spring-core-2/src/test/java/com/baeldung/profiles/SpringProfilesWithMavenPropertiesIntegrationTest.java b/spring-boot-modules/spring-boot-environment/src/test/java/com/baeldung/profiles/SpringProfilesWithMavenPropertiesIntegrationTest.java similarity index 100% rename from spring-core-2/src/test/java/com/baeldung/profiles/SpringProfilesWithMavenPropertiesIntegrationTest.java rename to spring-boot-modules/spring-boot-environment/src/test/java/com/baeldung/profiles/SpringProfilesWithMavenPropertiesIntegrationTest.java diff --git a/spring-core-2/src/test/java/com/baeldung/profiles/SpringProfilesWithXMLIntegrationTest.java b/spring-boot-modules/spring-boot-environment/src/test/java/com/baeldung/profiles/SpringProfilesWithXMLIntegrationTest.java similarity index 100% rename from spring-core-2/src/test/java/com/baeldung/profiles/SpringProfilesWithXMLIntegrationTest.java rename to spring-boot-modules/spring-boot-environment/src/test/java/com/baeldung/profiles/SpringProfilesWithXMLIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-gradle-2/.gitignore b/spring-boot-modules/spring-boot-gradle-2/.gitignore new file mode 100644 index 0000000000..c2065bc262 --- /dev/null +++ b/spring-boot-modules/spring-boot-gradle-2/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/spring-boot-modules/spring-boot-gradle-2/build.gradle b/spring-boot-modules/spring-boot-gradle-2/build.gradle new file mode 100644 index 0000000000..abfbca3123 --- /dev/null +++ b/spring-boot-modules/spring-boot-gradle-2/build.gradle @@ -0,0 +1,34 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.0.6' + id 'io.spring.dependency-management' version '1.1.0' +} + +group = 'com.baeldung' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '17' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} + +tasks.named('test') { + useJUnitPlatform() +} + +tasks.named("bootJar"){ + launchScript{ + enabled = true + } + archiveFileName = "bael-6094.${archiveExtension.get()}" +} + + +tasks.named("bootBuildImage") { + imageName = 'bael-6094:latest' +} diff --git a/spring-boot-modules/spring-boot-gradle-2/gradle/wrapper/gradle-wrapper.jar b/spring-boot-modules/spring-boot-gradle-2/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..943f0cbfa7 Binary files /dev/null and b/spring-boot-modules/spring-boot-gradle-2/gradle/wrapper/gradle-wrapper.jar differ diff --git a/spring-boot-modules/spring-boot-gradle-2/gradle/wrapper/gradle-wrapper.properties b/spring-boot-modules/spring-boot-gradle-2/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..37aef8d3f0 --- /dev/null +++ b/spring-boot-modules/spring-boot-gradle-2/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/spring-boot-modules/spring-boot-gradle-2/gradlew b/spring-boot-modules/spring-boot-gradle-2/gradlew new file mode 100644 index 0000000000..65dcd68d65 --- /dev/null +++ b/spring-boot-modules/spring-boot-gradle-2/gradlew @@ -0,0 +1,244 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/spring-boot-modules/spring-boot-gradle-2/gradlew.bat b/spring-boot-modules/spring-boot-gradle-2/gradlew.bat new file mode 100644 index 0000000000..93e3f59f13 --- /dev/null +++ b/spring-boot-modules/spring-boot-gradle-2/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/spring-boot-modules/spring-boot-gradle-2/settings.gradle b/spring-boot-modules/spring-boot-gradle-2/settings.gradle new file mode 100644 index 0000000000..16004624dd --- /dev/null +++ b/spring-boot-modules/spring-boot-gradle-2/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'spring-boot-gradle-2' diff --git a/spring-boot-modules/spring-boot-gradle-2/src/main/java/com/baeldung/gradle/SpringBootGradle2Application.java b/spring-boot-modules/spring-boot-gradle-2/src/main/java/com/baeldung/gradle/SpringBootGradle2Application.java new file mode 100644 index 0000000000..9d5be0bcbc --- /dev/null +++ b/spring-boot-modules/spring-boot-gradle-2/src/main/java/com/baeldung/gradle/SpringBootGradle2Application.java @@ -0,0 +1,21 @@ +package com.baeldung.gradle; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@SpringBootApplication +@RestController +public class SpringBootGradle2Application { + + public static void main(String[] args) { + SpringApplication.run(SpringBootGradle2Application.class, args); + } + + @GetMapping("/hello") + public String hello() { + return "Hello World!"; + } + +} diff --git a/spring-boot-modules/spring-boot-gradle-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-gradle-2/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/spring-boot-modules/spring-boot-gradle-2/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/spring-boot-modules/spring-boot-gradle-2/src/test/java/com/baeldung/gradle/SpringBootGradle2ApplicationTests.java b/spring-boot-modules/spring-boot-gradle-2/src/test/java/com/baeldung/gradle/SpringBootGradle2ApplicationTests.java new file mode 100644 index 0000000000..dd3031c1d5 --- /dev/null +++ b/spring-boot-modules/spring-boot-gradle-2/src/test/java/com/baeldung/gradle/SpringBootGradle2ApplicationTests.java @@ -0,0 +1,33 @@ +package com.baeldung.gradle; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +//@SpringBootTest +//class { +// +// @Test +// void contextLoads() { +// } +// +//} + +@SpringBootTest +@AutoConfigureMockMvc +public class SpringBootGradle2ApplicationTests { + + @Autowired + private MockMvc mockMvc; + + @Test + public void givenHelloEndPoint_whenCallingHello_ThenGettingHelloWorld() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/hello")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.content().string("Hello World!")); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak-2/README.md b/spring-boot-modules/spring-boot-keycloak-2/README.md index d372132a6a..e4f8b1904b 100644 --- a/spring-boot-modules/spring-boot-keycloak-2/README.md +++ b/spring-boot-modules/spring-boot-keycloak-2/README.md @@ -4,3 +4,4 @@ This module contains articles about Keycloak in Spring Boot projects. ## Relevant articles: - [Disabling Keycloak Security in Spring Boot](https://www.baeldung.com/spring-keycloak-security-disable) +- [Search Users With Keycloak in Java](https://www.baeldung.com/java-keycloak-search-users) diff --git a/spring-boot-modules/spring-boot-keycloak-2/pom.xml b/spring-boot-modules/spring-boot-keycloak-2/pom.xml index 8b1eec2e4e..572986e8c4 100644 --- a/spring-boot-modules/spring-boot-keycloak-2/pom.xml +++ b/spring-boot-modules/spring-boot-keycloak-2/pom.xml @@ -16,6 +16,10 @@ 0.0.1-SNAPSHOT ../../parent-boot-2 + + + 21.0.1 + @@ -39,6 +43,41 @@ spring-boot-starter-test test + + + + org.keycloak + keycloak-admin-client + ${keycloak.version} + + + + org.keycloak + keycloak-core + provided + ${keycloak.version} + + + org.keycloak + keycloak-server-spi + ${keycloak.version} + provided + + + + org.keycloak + keycloak-server-spi-private + provided + ${keycloak.version} + + + org.keycloak + keycloak-services + provided + ${keycloak.version} + + + diff --git a/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/keycloak/adminclient/AdminClientService.java b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/keycloak/adminclient/AdminClientService.java new file mode 100644 index 0000000000..bacca9bdea --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/keycloak/adminclient/AdminClientService.java @@ -0,0 +1,90 @@ +package com.baeldung.keycloak.adminclient; + +import java.util.List; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; + +import org.keycloak.admin.client.Keycloak; +import org.keycloak.representations.idm.UserRepresentation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class AdminClientService { + + private static final Logger logger = LoggerFactory.getLogger(AdminClientService.class); + private static final String REALM_NAME = "master"; + + @Autowired + private Keycloak keycloak; + + @PostConstruct + public void searchUsers() { + logger.info("Searching users in Keycloak {}", keycloak.serverInfo() + .getInfo() + .getSystemInfo() + .getVersion()); + searchByUsername("user1", true); + searchByUsername("user", false); + searchByUsername("1", false); + searchByEmail("user2@test.com", true); + searchByAttributes("DOB:2000-01-05"); + searchByGroup("c67643fb-514e-488a-a4b4-5c0bdf2e7477"); + searchByRole("user"); + } + + private void searchByUsername(String username, boolean exact) { + logger.info("Searching by username: {} (exact {})", username, exact); + List users = keycloak.realm(REALM_NAME) + .users() + .searchByUsername(username, exact); + logger.info("Users found by username {}", users.stream() + .map(user -> user.getUsername()) + .collect(Collectors.toList())); + } + + private void searchByEmail(String email, boolean exact) { + logger.info("Searching by email: {} (exact {})", email, exact); + List users = keycloak.realm(REALM_NAME) + .users() + .searchByEmail(email, exact); + logger.info("Users found by email {}", users.stream() + .map(user -> user.getEmail()) + .collect(Collectors.toList())); + } + + private void searchByAttributes(String query) { + logger.info("Searching by attributes: {}", query); + List users = keycloak.realm(REALM_NAME) + .users() + .searchByAttributes(query); + logger.info("Users found by attributes {}", users.stream() + .map(user -> user.getUsername() + " " + user.getAttributes()) + .collect(Collectors.toList())); + } + + private void searchByGroup(String groupId) { + logger.info("Searching by group: {}", groupId); + List users = keycloak.realm(REALM_NAME) + .groups() + .group(groupId) + .members(); + logger.info("Users found by group {}", users.stream() + .map(user -> user.getUsername()) + .collect(Collectors.toList())); + } + + private void searchByRole(String roleName) { + logger.info("Searching by role: {}", roleName); + List users = keycloak.realm(REALM_NAME) + .roles() + .get(roleName) + .getUserMembers(); + logger.info("Users found by role {}", users.stream() + .map(user -> user.getUsername()) + .collect(Collectors.toList())); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/keycloak/adminclient/App.java b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/keycloak/adminclient/App.java new file mode 100644 index 0000000000..a863bde2e3 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/keycloak/adminclient/App.java @@ -0,0 +1,30 @@ +package com.baeldung.keycloak.adminclient; + +import org.keycloak.OAuth2Constants; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.admin.client.KeycloakBuilder; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication(scanBasePackages = { "com.baeldung.keycloak.adminclient" }) +@PropertySource("classpath:application-adminclient.properties") +public class App { + + public static void main(String[] args) { + SpringApplication.run(App.class, args); + } + + @Bean + Keycloak keycloak() { + return KeycloakBuilder.builder() + .serverUrl("http://localhost:8080") + .realm("master") + .clientId("admin-cli") + .grantType(OAuth2Constants.PASSWORD) + .username("admin") + .password("password") + .build(); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/keycloak/customendpoint/KeycloakUserApiProvider.java b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/keycloak/customendpoint/KeycloakUserApiProvider.java new file mode 100644 index 0000000000..c34514104b --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/keycloak/customendpoint/KeycloakUserApiProvider.java @@ -0,0 +1,52 @@ +package com.baeldung.keycloak.customendpoint; + +import java.util.Optional; +import java.util.stream.Stream; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.ws.rs.GET; +import javax.ws.rs.NotFoundException; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.keycloak.models.GroupModel; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; +import org.keycloak.models.utils.ModelToRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.services.resource.RealmResourceProvider; + +public class KeycloakUserApiProvider implements RealmResourceProvider { + private final KeycloakSession session; + + public KeycloakUserApiProvider(KeycloakSession session) { + this.session = session; + } + + public void close() { + } + + public Object getResource() { + return this; + } + + @GET + @Produces({ MediaType.APPLICATION_JSON }) + public Stream searchUsersByGroupAndRoleName(@QueryParam("groupName") @NotNull String groupName, @QueryParam("roleName") @NotBlank String roleName) { + RealmModel realm = session.getContext().getRealm(); + + Optional groupByName = session.groups() + .getGroupsStream(realm) + .filter(group -> group.getName().equals(groupName)) + .findAny(); + + GroupModel group = groupByName.orElseThrow(() -> new NotFoundException("Group not found with name " + groupName)); + + return session.users() + .getGroupMembersStream(realm, group) + .filter(user -> user.getRealmRoleMappingsStream().anyMatch(role -> role.getName().equals(roleName))) + .map(user -> ModelToRepresentation.toBriefRepresentation(user)); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/keycloak/customendpoint/KeycloakUserApiProviderFactory.java b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/keycloak/customendpoint/KeycloakUserApiProviderFactory.java new file mode 100644 index 0000000000..34eda94d6a --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/keycloak/customendpoint/KeycloakUserApiProviderFactory.java @@ -0,0 +1,33 @@ +package com.baeldung.keycloak.customendpoint; + +import org.keycloak.Config.Scope; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.services.resource.RealmResourceProvider; +import org.keycloak.services.resource.RealmResourceProviderFactory; + +public class KeycloakUserApiProviderFactory implements RealmResourceProviderFactory { + public static final String ID = "users-by-group-and-role-name"; + + @Override + public RealmResourceProvider create(KeycloakSession session) { + return new KeycloakUserApiProvider(session); + } + + @Override + public void init(Scope config) { + } + + @Override + public void postInit(KeycloakSessionFactory factory) { + } + + @Override + public void close() { + } + + @Override + public String getId() { + return ID; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak-2/src/main/resources/META-INF/services/org.keycloak.services.resource.RealmResourceProviderFactory b/spring-boot-modules/spring-boot-keycloak-2/src/main/resources/META-INF/services/org.keycloak.services.resource.RealmResourceProviderFactory new file mode 100644 index 0000000000..f11a60fd2b --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak-2/src/main/resources/META-INF/services/org.keycloak.services.resource.RealmResourceProviderFactory @@ -0,0 +1 @@ +com.baeldung.keycloak.customendpoint.KeycloakUserApiProviderFactory \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak-2/src/main/resources/application-adminclient.properties b/spring-boot-modules/spring-boot-keycloak-2/src/main/resources/application-adminclient.properties new file mode 100644 index 0000000000..bafddced85 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak-2/src/main/resources/application-adminclient.properties @@ -0,0 +1 @@ +server.port=8081 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/README.md b/spring-boot-modules/spring-boot-libraries-2/README.md index 0da16a8204..5c6b93469d 100644 --- a/spring-boot-modules/spring-boot-libraries-2/README.md +++ b/spring-boot-modules/spring-boot-libraries-2/README.md @@ -9,4 +9,6 @@ This module contains articles about various Spring Boot libraries - [An Introduction to Kong](https://www.baeldung.com/kong) - [Scanning Java Annotations At Runtime](https://www.baeldung.com/java-scan-annotations-runtime) - [Guide to Resilience4j With Spring Boot](https://www.baeldung.com/spring-boot-resilience4j) -More articles: [[prev -->]](/spring-boot-modules/spring-boot-libraries) +- [Using OpenAI ChatGPT APIs in Spring Boot](https://www.baeldung.com/spring-boot-chatgpt-api-openai) +- [Introduction to Spring Modulith](https://www.baeldung.com/spring-modulith) +- More articles: [[prev -->]](/spring-boot-modules/spring-boot-libraries) diff --git a/spring-boot-modules/spring-boot-libraries-2/pom.xml b/spring-boot-modules/spring-boot-libraries-2/pom.xml index 4409db0672..6d9401f4bc 100644 --- a/spring-boot-modules/spring-boot-libraries-2/pom.xml +++ b/spring-boot-modules/spring-boot-libraries-2/pom.xml @@ -11,6 +11,18 @@ 1.0.0-SNAPSHOT + + + + org.springframework.experimental + spring-modulith-bom + 0.5.1 + import + pom + + + + org.springframework.boot @@ -87,6 +99,15 @@ 2.34.0 test + + org.springframework.experimental + spring-modulith-api + + + org.springframework.experimental + spring-modulith-starter-test + test + diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/Application.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/Application.java new file mode 100644 index 0000000000..a8c3e48661 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/Application.java @@ -0,0 +1,21 @@ +package com.baeldung.modulith; + +import com.baeldung.modulith.product.ProductService; +import com.baeldung.modulith.product.internal.Product; +import org.jobrunr.autoconfigure.JobRunrAutoConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableAsync; + +@EnableAsync +@SpringBootApplication +@EnableAutoConfiguration(exclude = { JobRunrAutoConfiguration.class}) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args) + .getBean(ProductService.class) + .create(new Product("baeldung", "course", 10)); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/notification/NotificationDTO.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/notification/NotificationDTO.java new file mode 100644 index 0000000000..a8fb346daa --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/notification/NotificationDTO.java @@ -0,0 +1,39 @@ +package com.baeldung.modulith.notification; + +import java.util.Date; + +public class NotificationDTO { + private Date date; + private String format; + private String productName; + + public NotificationDTO(Date date, String format, String productName) { + this.date = date; + this.format = format; + this.productName = productName; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } +} diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/notification/NotificationService.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/notification/NotificationService.java new file mode 100644 index 0000000000..7789798bbe --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/notification/NotificationService.java @@ -0,0 +1,42 @@ +package com.baeldung.modulith.notification; + +import com.baeldung.modulith.notification.internal.Notification; +import com.baeldung.modulith.notification.internal.NotificationType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.modulith.ApplicationModuleListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +@Service +public class NotificationService { + + private static final Logger LOG = LoggerFactory.getLogger(NotificationService.class); + + public void createNotification(NotificationDTO notificationDTO) { + Notification notification = toEntity(notificationDTO); + LOG.info("Received notification by module dependency for product {} in date {} by {}.", notification.getProductName() + , notification.getDate(), notification.getFormat()); + } + + @Async + @ApplicationModuleListener + public void notificationEvent(NotificationDTO event) { + Notification notification = toEntity(event); + LOG.info("Received notification by event for product {} in date {} by {}.", notification.getProductName() + , notification.getDate(), notification.getFormat()); + } + + private Notification toEntity(NotificationDTO notificationDTO) { + Notification notification = new Notification(); + notification.setDate(notificationDTO.getDate()); + if (notificationDTO.getFormat().equals("SMS")) { + notification.setFormat(NotificationType.SMS); + } + if (notificationDTO.getFormat().equals("EMAIL")) { + notification.setFormat(NotificationType.EMAIL); + } + notification.setProductName(notificationDTO.getProductName()); + return notification; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/notification/internal/Notification.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/notification/internal/Notification.java new file mode 100644 index 0000000000..0b1ce85d26 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/notification/internal/Notification.java @@ -0,0 +1,37 @@ +package com.baeldung.modulith.notification.internal; + +import java.util.Date; + +public class Notification { + private Date date; + private NotificationType format; + private String productName; + + public Notification() { + + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public NotificationType getFormat() { + return format; + } + + public void setFormat(NotificationType format) { + this.format = format; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } +} diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/notification/internal/NotificationType.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/notification/internal/NotificationType.java new file mode 100644 index 0000000000..45870e52b9 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/notification/internal/NotificationType.java @@ -0,0 +1,5 @@ +package com.baeldung.modulith.notification.internal; + +public enum NotificationType { + EMAIL, SMS +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/product/ProductService.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/product/ProductService.java new file mode 100644 index 0000000000..46d87fc539 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/product/ProductService.java @@ -0,0 +1,26 @@ +package com.baeldung.modulith.product; + +import com.baeldung.modulith.notification.NotificationDTO; +import com.baeldung.modulith.notification.NotificationService; +import com.baeldung.modulith.product.internal.Product; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; + +import java.util.Date; + +@Service +public class ProductService { + + private final ApplicationEventPublisher events; + private final NotificationService notificationService; + + public ProductService(ApplicationEventPublisher events, NotificationService notificationService) { + this.events = events; + this.notificationService = notificationService; + } + + public void create(Product product) { + notificationService.createNotification(new NotificationDTO(new Date(), "SMS", product.getName())); + events.publishEvent(new NotificationDTO(new Date(), "SMS", product.getName())); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/product/internal/Product.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/product/internal/Product.java new file mode 100644 index 0000000000..d989906b63 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/modulith/product/internal/Product.java @@ -0,0 +1,38 @@ +package com.baeldung.modulith.product.internal; + +public class Product { + + private String name; + private String description; + private int price; + + public Product(String name, String description, int price) { + this.name = name; + this.description = description; + this.price = price; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public int getPrice() { + return price; + } + + public void setPrice(int price) { + this.price = price; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/config/OpenAIRestTemplateConfig.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/config/OpenAIRestTemplateConfig.java new file mode 100644 index 0000000000..b832ee4264 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/config/OpenAIRestTemplateConfig.java @@ -0,0 +1,25 @@ +package com.baeldung.openapi.config; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class OpenAIRestTemplateConfig { + + @Value("${openai.api.key}") + private String openaiApiKey; + + @Bean + @Qualifier("openaiRestTemplate") + public RestTemplate openaiRestTemplate() { + RestTemplate restTemplate = new RestTemplate(); + restTemplate.getInterceptors().add((request, body, execution) -> { + request.getHeaders().add("Authorization", "Bearer " + openaiApiKey); + return execution.execute(request, body); + }); + return restTemplate; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/controller/ChatController.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/controller/ChatController.java new file mode 100644 index 0000000000..129d233582 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/controller/ChatController.java @@ -0,0 +1,48 @@ +package com.baeldung.openapi.controller; + +import com.baeldung.openapi.dto.ChatRequest; +import com.baeldung.openapi.dto.ChatResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@RestController +public class ChatController { + + @Qualifier("openaiRestTemplate") + @Autowired + private RestTemplate restTemplate; + + @Value("${openai.model}") + private String model; + + @Value("${openai.api.url}") + private String apiUrl; + + /** + * Creates a chat request and sends it to the OpenAI API + * Returns the first message from the API response + * + * @param prompt the prompt to send to the API + * @return first message from the API response + */ + @GetMapping("/chat") + public String chat(@RequestParam String prompt) { + ChatRequest request = new ChatRequest(model, prompt); + + ChatResponse response = restTemplate.postForObject( + apiUrl, + request, + ChatResponse.class); + + if (response == null || response.getChoices() == null || response.getChoices().isEmpty()) { + return "No response"; + } + + return response.getChoices().get(0).getMessage().getContent(); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/dto/ChatRequest.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/dto/ChatRequest.java new file mode 100644 index 0000000000..1e32b937ce --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/dto/ChatRequest.java @@ -0,0 +1,32 @@ +package com.baeldung.openapi.dto; + +import java.util.ArrayList; +import java.util.List; + +public class ChatRequest { + private String model; + private List messages; + + public ChatRequest(String model, String prompt) { + this.model = model; + + this.messages = new ArrayList<>(); + this.messages.add(new Message("user", prompt)); + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public List getMessages() { + return messages; + } + + public void setMessages(List messages) { + this.messages = messages; + } +} diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/dto/ChatResponse.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/dto/ChatResponse.java new file mode 100644 index 0000000000..937e2d87db --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/dto/ChatResponse.java @@ -0,0 +1,38 @@ +package com.baeldung.openapi.dto; + +import java.util.List; + +public class ChatResponse { + + private List choices; + + public static class Choice { + + private int index; + private Message message; + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public Message getMessage() { + return message; + } + + public void setMessage(Message message) { + this.message = message; + } + } + + public List getChoices() { + return choices; + } + + public void setChoices(List choices) { + this.choices = choices; + } +} diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/dto/Message.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/dto/Message.java new file mode 100644 index 0000000000..242cf4e89f --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/openapi/dto/Message.java @@ -0,0 +1,31 @@ +package com.baeldung.openapi.dto; + +public class Message { + + private String role; + private String content; + + Message(String role, String content) { + this.role = role; + this.content = content; + } + + Message() { + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-libraries-2/src/main/resources/application.properties index a18eda349a..47b2973fca 100644 --- a/spring-boot-modules/spring-boot-libraries-2/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/resources/application.properties @@ -47,4 +47,8 @@ resilience4j.ratelimiter.instances.rateLimiterApi.limit-refresh-period=60s resilience4j.ratelimiter.instances.rateLimiterApi.timeout-duration=0s resilience4j.ratelimiter.instances.rateLimiterApi.allow-health-indicator-to-fail=true resilience4j.ratelimiter.instances.rateLimiterApi.subscribe-for-events=true -resilience4j.ratelimiter.instances.rateLimiterApi.event-consumer-buffer-size=50 \ No newline at end of file +resilience4j.ratelimiter.instances.rateLimiterApi.event-consumer-buffer-size=50 + +openai.model=gpt-3.5-turbo +openai.api.url=https://api.openai.com/v1/chat/completions +openai.api.key=your-api-key \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/modulith/ApplicationModularityUnitTest.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/modulith/ApplicationModularityUnitTest.java new file mode 100644 index 0000000000..40d644b1e0 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/modulith/ApplicationModularityUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.modulith; + +import org.junit.jupiter.api.Test; +import org.springframework.modulith.core.ApplicationModules; +import org.springframework.modulith.docs.Documenter; + +class ApplicationModularityUnitTest { + + ApplicationModules modules = ApplicationModules.of(Application.class); + + @Test + void verifiesModularStructure() { + modules.verify(); + } + + @Test + void createModuleDocumentation() { + new Documenter(modules) + .writeDocumentation() + .writeIndividualModulesAsPlantUml(); + } + + @Test + void createApplicationModuleModel() { + modules.forEach(System.out::println); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/controller/AuthorsController.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/controller/AuthorsController.java new file mode 100644 index 0000000000..019bd5ad9d --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/controller/AuthorsController.java @@ -0,0 +1,34 @@ +package com.baeldung.springboot.swagger.controller; + +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.springboot.swagger.model.Author; +import com.baeldung.springboot.swagger.service.AuthorService; +import com.baeldung.springboot.swagger.views.Views; +import com.fasterxml.jackson.annotation.JsonView; + +@RestController +@RequestMapping("/authors") +public class AuthorsController { + + @Autowired + AuthorService authorService; + + @JsonView(Views.Public.class) + @GetMapping + public List getAllAuthors() { + return authorService.getAllAuthors(); + } + + @PostMapping + public void addAuthor(@RequestBody @JsonView(Views.Public.class) Author author){ + authorService.addAuthors(author); + } +} diff --git a/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/model/Author.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/model/Author.java new file mode 100644 index 0000000000..2e30998059 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/model/Author.java @@ -0,0 +1,28 @@ +package com.baeldung.springboot.swagger.model; + +import com.baeldung.springboot.swagger.views.Views; +import com.fasterxml.jackson.annotation.JsonView; + +public class Author { + + @JsonView(Views.Private.class) + private Integer id; + + @JsonView(Views.Public.class) + private String name; + + @JsonView(Views.Public.class) + private String email; + + public Author() { + } + + public Author(String name, String email) { + this.name = name; + this.email = email; + } + + public void setId(Integer id) { + this.id = id; + } +} diff --git a/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/service/AuthorService.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/service/AuthorService.java new file mode 100644 index 0000000000..bf1f637889 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/service/AuthorService.java @@ -0,0 +1,23 @@ +package com.baeldung.springboot.swagger.service; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.baeldung.springboot.swagger.model.Author; + +@Service +public class AuthorService { + private List authors = new ArrayList<>(); + + public List getAllAuthors(){ + return authors; + } + + public void addAuthors(Author author){ + author.setId(authors.size()+1); + authors.add(author); + } + +} diff --git a/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/views/Views.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/views/Views.java new file mode 100644 index 0000000000..df638a5647 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/views/Views.java @@ -0,0 +1,9 @@ +package com.baeldung.springboot.swagger.views; + +public class Views { + public static class Public { + } + + public static class Private { + } +} diff --git a/spring-boot-modules/spring-boot-properties-2/pom.xml b/spring-boot-modules/spring-boot-properties-2/pom.xml index 442cb24c7a..4b1daca34d 100644 --- a/spring-boot-modules/spring-boot-properties-2/pom.xml +++ b/spring-boot-modules/spring-boot-properties-2/pom.xml @@ -10,9 +10,10 @@ Spring Boot Properties Module - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -24,6 +25,15 @@ org.springframework.boot spring-boot-starter-web + + commons-lang + commons-lang + 2.6 + + + com.baeldung.properties.yaml.YamlApplication + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/ValuesApp.java b/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/ValuesApp.java index 67547199a6..282ce4658e 100644 --- a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/ValuesApp.java +++ b/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/ValuesApp.java @@ -7,11 +7,12 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; -import javax.annotation.PostConstruct; import java.util.Arrays; import java.util.List; import java.util.Map; +import jakarta.annotation.PostConstruct; + @Configuration @PropertySource(name = "myProperties", value = "values.properties") public class ValuesApp { diff --git a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/defaults/ValuesWithDefaultsApp.java b/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/defaults/ValuesWithDefaultsApp.java index 2a2b535be7..f1720d2fb3 100644 --- a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/defaults/ValuesWithDefaultsApp.java +++ b/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/defaults/ValuesWithDefaultsApp.java @@ -1,6 +1,6 @@ package com.baeldung.properties.value.defaults; -import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang.ArrayUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -8,10 +8,11 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.util.Assert; -import javax.annotation.PostConstruct; import java.util.Arrays; import java.util.List; +import jakarta.annotation.PostConstruct; + /** * Demonstrates setting defaults for @Value annotation. Note that there are no properties * defined in the specified property source. We also assume that the user here @@ -60,10 +61,10 @@ public class ValuesWithDefaultsApp { // arrays List stringListValues = Arrays.asList("one", "two", "three"); - Assert.isTrue(Arrays.asList(stringArrayWithDefaults).containsAll(stringListValues), "unexpected value for stringArrayWithDefaults"); + Assert.isTrue(Arrays.asList(stringArrayWithDefaults).containsAll(stringListValues), "unexpected value for stringArrayWithDefaults"); List intListValues = Arrays.asList(1, 2, 3); - Assert.isTrue(Arrays.asList(ArrayUtils.toObject(intArrayWithDefaults)).containsAll(intListValues), "unexpected value for intArrayWithDefaults"); + Assert.isTrue(Arrays.asList(ArrayUtils.toObject(intArrayWithDefaults)).containsAll(intListValues), "unexpected value for intArrayWithDefaults"); // SpEL Assert.isTrue(spelWithDefaultValue.equals("my default system property value"), "unexpected value for spelWithDefaultValue"); diff --git a/spring-boot-modules/spring-boot-properties-3/README.md b/spring-boot-modules/spring-boot-properties-3/README.md index 77c6815649..4bc4a2325f 100644 --- a/spring-boot-modules/spring-boot-properties-3/README.md +++ b/spring-boot-modules/spring-boot-properties-3/README.md @@ -10,3 +10,6 @@ - [Load Spring Boot Properties From a JSON File](https://www.baeldung.com/spring-boot-json-properties) - [IntelliJ – Cannot Resolve Spring Boot Configuration Properties Error](https://www.baeldung.com/intellij-resolve-spring-boot-configuration-properties) - [Log Properties in a Spring Boot Application](https://www.baeldung.com/spring-boot-log-properties) +- [Using Environment Variables in Spring Boot’s application.properties](https://www.baeldung.com/spring-boot-properties-env-variables) +- [Loading Multiple YAML Configuration Files in Spring Boot](https://www.baeldung.com/spring-boot-load-multiple-yaml-configuration-files) +- More articles: [[<-- prev]](../spring-boot-properties-2) diff --git a/spring-boot-modules/spring-boot-properties-3/pom.xml b/spring-boot-modules/spring-boot-properties-3/pom.xml index 3de85c7175..ed6e08add0 100644 --- a/spring-boot-modules/spring-boot-properties-3/pom.xml +++ b/spring-boot-modules/spring-boot-properties-3/pom.xml @@ -9,9 +9,10 @@ Spring Boot Properties Module - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -31,7 +32,6 @@ org.springframework.boot spring-boot-starter-web - RELEASE @@ -44,4 +44,8 @@ + + com.baeldung.boot.properties.DemoApplication + + \ No newline at end of file diff --git a/spring-core-6/src/main/java/com/baeldung/envvariables/BaeldungProperties.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/envvariables/BaeldungProperties.java similarity index 86% rename from spring-core-6/src/main/java/com/baeldung/envvariables/BaeldungProperties.java rename to spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/envvariables/BaeldungProperties.java index a41ac7a509..0e6e05a3c2 100644 --- a/spring-core-6/src/main/java/com/baeldung/envvariables/BaeldungProperties.java +++ b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/envvariables/BaeldungProperties.java @@ -1,20 +1,20 @@ -package com.baeldung.envvariables.valueinjection; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -@Component -@ConfigurationProperties(prefix = "baeldung") -public class BaeldungProperties { - - private String presentation; - - public String getPresentation() { - return presentation; - } - - public void setPresentation(String presentation) { - this.presentation = presentation; - } - -} +package com.baeldung.envvariables; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "baeldung") +public class BaeldungProperties { + + private String presentation; + + public String getPresentation() { + return presentation; + } + + public void setPresentation(String presentation) { + this.presentation = presentation; + } + +} diff --git a/spring-core-6/src/main/java/com/baeldung/envvariables/MyController.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/envvariables/MyController.java similarity index 94% rename from spring-core-6/src/main/java/com/baeldung/envvariables/MyController.java rename to spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/envvariables/MyController.java index 503ee47157..6afe9f2de1 100644 --- a/spring-core-6/src/main/java/com/baeldung/envvariables/MyController.java +++ b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/envvariables/MyController.java @@ -1,60 +1,60 @@ -package com.baeldung.envvariables.valueinjection; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.env.Environment; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class MyController { - - @Value("${environment.name}") - private String environmentName; - - @Value("${java.home.and.environment}") - private String javaHomeAndEnvironmentName; - - @Value("${thispropertydoesnotexist}") - private String nonExistentProperty; - - @Value("${baeldung.presentation}") - private String baeldungPresentation; - - @Autowired - private Environment environment; - - @Autowired - private BaeldungProperties baeldungProperties; - - @GetMapping("/environment_name") - String getEnvironmentName_FromEnvironmentVariables() { - return environmentName; - } - - @GetMapping("/java_home_and_environment") - String getJavaHomeAndEnvironmentName_FromEnvironmentVariables() { - return javaHomeAndEnvironmentName; - } - - @GetMapping("non_existent_property") - String getNonexistentProperty_FromEnvironmentVariables() { - return nonExistentProperty; - } - - @GetMapping("baeldung_presentation_from_value") - String getBaeldungPresentation_FromValue() { - return baeldungPresentation; - } - - @GetMapping("baeldung_presentation_from_environment") - String getBaeldungPresentation_FromEnvironment() { - return environment.getProperty("baeldung.presentation"); - } - - @GetMapping("baeldung_configuration_properties") - String getBaeldungPresentation_FromConfigurationProperties() { - return baeldungProperties.getPresentation(); - } - -} +package com.baeldung.envvariables; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class MyController { + + @Value("${environment.name}") + private String environmentName; + + @Value("${java.home.and.environment}") + private String javaHomeAndEnvironmentName; + + @Value("${thispropertydoesnotexist}") + private String nonExistentProperty; + + @Value("${baeldung.presentation}") + private String baeldungPresentation; + + @Autowired + private Environment environment; + + @Autowired + private BaeldungProperties baeldungProperties; + + @GetMapping("/environment_name") + String getEnvironmentName_FromEnvironmentVariables() { + return environmentName; + } + + @GetMapping("/java_home_and_environment") + String getJavaHomeAndEnvironmentName_FromEnvironmentVariables() { + return javaHomeAndEnvironmentName; + } + + @GetMapping("non_existent_property") + String getNonexistentProperty_FromEnvironmentVariables() { + return nonExistentProperty; + } + + @GetMapping("baeldung_presentation_from_value") + String getBaeldungPresentation_FromValue() { + return baeldungPresentation; + } + + @GetMapping("baeldung_presentation_from_environment") + String getBaeldungPresentation_FromEnvironment() { + return environment.getProperty("baeldung.presentation"); + } + + @GetMapping("baeldung_configuration_properties") + String getBaeldungPresentation_FromConfigurationProperties() { + return baeldungProperties.getPresentation(); + } + +} diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/error/KebabCasingDemoApplication.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/error/KebabCasingDemoApplication.java new file mode 100644 index 0000000000..7b97f97ffa --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/error/KebabCasingDemoApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.error; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class KebabCasingDemoApplication { + public static void main(String[] args) { + SpringApplication.run(KebabCasingDemoApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/error/configuration/MainConfiguration.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/error/configuration/MainConfiguration.java new file mode 100644 index 0000000000..3c5fbc3006 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/error/configuration/MainConfiguration.java @@ -0,0 +1,18 @@ +package com.baeldung.error.configuration; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "profile.profileProperties") +public class MainConfiguration { + private String name; + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } +} diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/log/EnvironmentPropertiesPrinter.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/log/EnvironmentPropertiesPrinter.java index 321593b31b..26f6867296 100644 --- a/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/log/EnvironmentPropertiesPrinter.java +++ b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/log/EnvironmentPropertiesPrinter.java @@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; @Component public class EnvironmentPropertiesPrinter { diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/multipleyaml/MultipleYamlApplication.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/multipleyaml/MultipleYamlApplication.java new file mode 100644 index 0000000000..9dc754b24b --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/multipleyaml/MultipleYamlApplication.java @@ -0,0 +1,27 @@ +package com.baeldung.properties.multipleyaml; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MultipleYamlApplication implements CommandLineRunner { + + @Autowired + private MultipleYamlConfiguration config; + + public static void main(String[] args) { + SpringApplication springApp = new SpringApplication(MultipleYamlApplication.class); + + // Code from first example, uncomment to use multiple profiles + // springApp.setAdditionalProfiles("students", "teachers"); + + springApp.run(args); + } + + public void run(String... args) throws Exception { + System.out.println("Students: " + config.getStudents()); + System.out.println("Teachers: " + config.getTeachers()); + } +} diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/multipleyaml/MultipleYamlConfiguration.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/multipleyaml/MultipleYamlConfiguration.java new file mode 100644 index 0000000000..c46a321e24 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/multipleyaml/MultipleYamlConfiguration.java @@ -0,0 +1,35 @@ +package com.baeldung.properties.multipleyaml; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.context.annotation.PropertySources; + +import java.util.List; + +@Configuration +@ConfigurationProperties +@PropertySources({ + @PropertySource(value = "classpath:application-teachers.yml", factory = MultipleYamlPropertySourceFactory.class), + @PropertySource(value = "classpath:application-students.yml", factory = MultipleYamlPropertySourceFactory.class)}) +public class MultipleYamlConfiguration { + + List teachers; + List students; + + public void setTeachers(List teachers) { + this.teachers = teachers; + } + + public void setStudents(List students) { + this.students = students; + } + + public List getTeachers() { + return teachers; + } + + public List getStudents() { + return students; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/multipleyaml/MultipleYamlPropertySourceFactory.java b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/multipleyaml/MultipleYamlPropertySourceFactory.java new file mode 100644 index 0000000000..c09bd3c8b9 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/properties/multipleyaml/MultipleYamlPropertySourceFactory.java @@ -0,0 +1,23 @@ +package com.baeldung.properties.multipleyaml; + +import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; +import org.springframework.core.env.PropertiesPropertySource; +import org.springframework.core.env.PropertySource; +import org.springframework.core.io.support.EncodedResource; +import org.springframework.core.io.support.PropertySourceFactory; + +import java.io.IOException; +import java.util.Properties; + +public class MultipleYamlPropertySourceFactory implements PropertySourceFactory { + + @Override + public PropertySource createPropertySource(String name, EncodedResource encodedResource) throws IOException { + YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean(); + factory.setResources(encodedResource.getResource()); + + Properties properties = factory.getObject(); + + return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties); + } +} diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application-students.yml b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application-students.yml new file mode 100644 index 0000000000..f4aaf8ae4d --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application-students.yml @@ -0,0 +1,3 @@ +students: + - Jane + - Michael \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application-teachers.yml b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application-teachers.yml new file mode 100644 index 0000000000..f0d2080164 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application-teachers.yml @@ -0,0 +1,3 @@ +teachers: + - Margo + - Javier \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.properties b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.properties index a079837942..e80c2ecc27 100644 --- a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.properties @@ -26,4 +26,18 @@ spring.config.activate.on-profile=multidocument-prod spring.datasource.password=password spring.datasource.url=jdbc:h2:prod spring.datasource.username=prodUser -bael.property=prodValue \ No newline at end of file +bael.property=prodValue +#--- +environment.name=${OS} +java.home.and.environment=${JAVA_HOME}+${OS} +not.existing.system.property=${thispropertydoesnotexist} +baeldung.presentation=${HELLO_BAELDUNG}. Java is installed in the folder: ${JAVA_HOME} +#--- +#camelCasing +#profile.applicationProperties.name="Baeldung" +#PascalCasing +#profile.ApplicationProperties.name="Baeldung" +#SnakingCasing +#profile.application_properties.name="Baeldung" +#KebabCasing +profile.application-properties.name="Baeldung" \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.yml b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.yml index 2e28da5ad3..2c44065028 100644 --- a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.yml +++ b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.yml @@ -2,6 +2,10 @@ bael: root-level-property: defaultRootLevelValue spring: profiles: +# Multiple profiles for MultipleYamlApplication first example +# include: +# - teachers +# - students group: multidocument-integration: multidocument-integration-extension --- diff --git a/spring-core-6/src/test/java/com/baeldung/envvariables/MyControllerIntegrationTest.java b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/envvariables/MyControllerIntegrationTest.java similarity index 95% rename from spring-core-6/src/test/java/com/baeldung/envvariables/MyControllerIntegrationTest.java rename to spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/envvariables/MyControllerIntegrationTest.java index b3ee2c7c46..527acd5dfc 100644 --- a/spring-core-6/src/test/java/com/baeldung/envvariables/MyControllerIntegrationTest.java +++ b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/envvariables/MyControllerIntegrationTest.java @@ -1,36 +1,36 @@ -package com.baeldung.envvariables.valueinjection; - -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(classes = MyController.class) -@AutoConfigureMockMvc -public class MyControllerIntegrationTest { - - @Autowired - private MockMvc mockMvc; - - /** NB : these tests are commented out because they are environment dependent - * If you want to run one of them on your machine, follow the instruction above it - * - * expects the value of your system environment property 'OS' (it is already defined at least in Windows_NT) - @Test void givenExistingSystemProperty_whenInjected_thenHasSystemPropertyValue() throws Exception { - mockMvc.perform(get("/environment_name")) - .andExpect(content().string(equalTo("Windows_NT"))); - } - - * expects the value of the JAVA_HOME environment variable (you need to define it if you haven't yet), with a + and the 'OS' environment property in the end - @Test void givenCombinationOfSystemPropertyAndEnvironmentVariable_whenInjected_thenHasExpectedValue() throws Exception { - mockMvc.perform(get("/java_home_and_environment")) - .andExpect(content().string(equalTo("C:\\Program Files\\Java\\jdk-11.0.14+Windows_NT"))); - } - - * expects the content to be ${thispropertydoesnotexist} ; if you have defined an environment property called thispropertydoesnotexist, it would fail - @Test void givenNonExistentProperty_whenInjected_thenKeepsTheStringValue() throws Exception { - mockMvc.perform(get("/non_existent_property")) - .andExpect(content().string(equalTo("${thispropertydoesnotexist}"))); - } - */ -} +package com.baeldung.envvariables; + +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(classes = MyController.class) +@AutoConfigureMockMvc +public class MyControllerIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + /** NB : these tests are commented out because they are environment dependent + * If you want to run one of them on your machine, follow the instruction above it + * + * expects the value of your system environment property 'OS' (it is already defined at least in Windows_NT) + @Test void givenExistingSystemProperty_whenInjected_thenHasSystemPropertyValue() throws Exception { + mockMvc.perform(get("/environment_name")) + .andExpect(content().string(equalTo("Windows_NT"))); + } + + * expects the value of the JAVA_HOME environment variable (you need to define it if you haven't yet), with a + and the 'OS' environment property in the end + @Test void givenCombinationOfSystemPropertyAndEnvironmentVariable_whenInjected_thenHasExpectedValue() throws Exception { + mockMvc.perform(get("/java_home_and_environment")) + .andExpect(content().string(equalTo("C:\\Program Files\\Java\\jdk-11.0.14+Windows_NT"))); + } + + * expects the content to be ${thispropertydoesnotexist} ; if you have defined an environment property called thispropertydoesnotexist, it would fail + @Test void givenNonExistentProperty_whenInjected_thenKeepsTheStringValue() throws Exception { + mockMvc.perform(get("/non_existent_property")) + .andExpect(content().string(equalTo("${thispropertydoesnotexist}"))); + } + */ +} 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 95dc06b155..21ed0f59f4 100644 --- a/spring-boot-modules/spring-boot-properties-migrator-demo/pom.xml +++ b/spring-boot-modules/spring-boot-properties-migrator-demo/pom.xml @@ -7,10 +7,10 @@ 1.0-SNAPSHOT - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT - ../pom.xml + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -49,8 +49,8 @@ - 8 - 8 + 17 + 17 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties/pom.xml b/spring-boot-modules/spring-boot-properties/pom.xml index 378864a1df..4ad5aeed1d 100644 --- a/spring-boot-modules/spring-boot-properties/pom.xml +++ b/spring-boot-modules/spring-boot-properties/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-properties 0.0.1-SNAPSHOT @@ -10,9 +10,10 @@ Spring Boot Properties Module - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -74,6 +75,25 @@ + + org.springframework.boot + spring-boot-maven-plugin + + + build-info + + build-info + + + + ${java.version} + ${project.description} + 123 + + + + + org.apache.maven.plugins maven-resources-plugin @@ -122,7 +142,7 @@ - 2021.0.3 + 2022.0.1 1.10 @ diff --git a/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ConfigProperties.java b/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ConfigProperties.java index 47df784885..faf5678398 100644 --- a/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ConfigProperties.java +++ b/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ConfigProperties.java @@ -3,10 +3,10 @@ package com.baeldung.configurationproperties; import java.util.List; import java.util.Map; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; import org.hibernate.validator.constraints.Length; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ImmutableCredentials.java b/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ImmutableCredentials.java index a58e4143e5..72c45afbb2 100644 --- a/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ImmutableCredentials.java +++ b/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ImmutableCredentials.java @@ -1,10 +1,8 @@ package com.baeldung.configurationproperties; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.ConstructorBinding; @ConfigurationProperties(prefix = "mail.credentials") -@ConstructorBinding public class ImmutableCredentials { private final String authMethod; diff --git a/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/buildproperties/BuildInfoServiceIntegrationTest.java b/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/buildproperties/BuildInfoServiceIntegrationTest.java index 2cb27e1844..9ed27f412c 100644 --- a/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/buildproperties/BuildInfoServiceIntegrationTest.java +++ b/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/buildproperties/BuildInfoServiceIntegrationTest.java @@ -4,12 +4,9 @@ import static org.junit.Assert.assertThat; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) class BuildInfoServiceIntegrationTest { diff --git a/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/buildproperties/BuildPropertiesUnitTest.java b/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/buildproperties/BuildPropertiesUnitTest.java new file mode 100644 index 0000000000..bb8ec78cc1 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/buildproperties/BuildPropertiesUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.buildproperties; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.info.BuildProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@SpringBootTest +@ExtendWith(SpringExtension.class) +public class BuildPropertiesUnitTest { + @Autowired + private BuildProperties buildProperties; + + @Test + void givenBuildPropertiesBean_WhenFetchDefaultBuildProperties_ThenGetValidValues() { + Assertions.assertEquals("spring-boot-properties", buildProperties.getArtifact()); + Assertions.assertEquals("com.baeldung", buildProperties.getGroup()); + Assertions.assertEquals("0.0.1-SNAPSHOT", buildProperties.getVersion()); + } + + @Test + void givenBuildPropertiesBean_WhenFetchCustomBuildProprties_ThenGetValidValues() { + Assertions.assertEquals("123", buildProperties.get("custom.value")); + Assertions.assertNotNull(buildProperties.get("java.version")); + Assertions.assertEquals("Spring Boot Properties Module", buildProperties.get("description")); + } +} diff --git a/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadManualTest.java b/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadManualTest.java index 88e22af4ba..ecb547a0a0 100644 --- a/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadManualTest.java +++ b/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadManualTest.java @@ -1,28 +1,27 @@ package com.baeldung.properties.reloading; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.baeldung.properties.reloading.beans.ConfigurationPropertiesRefreshConfigBean; import com.baeldung.properties.reloading.beans.EnvironmentConfigBean; import com.baeldung.properties.reloading.beans.PropertiesConfigBean; import com.baeldung.properties.reloading.beans.ValueRefreshConfigBean; import java.io.FileOutputStream; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = SpringBootPropertiesTestApplication.class) public class PropertiesReloadManualTest { @@ -50,7 +49,7 @@ public class PropertiesReloadManualTest { ValueRefreshConfigBean singletonValueRefreshConfigBean; - @Before + @BeforeEach public void setUp() throws Exception { mvc = MockMvcBuilders .webAppContextSetup(webApplicationContext) @@ -61,7 +60,7 @@ public class PropertiesReloadManualTest { callRefresh(); } - @After + @AfterEach public void tearDown() throws Exception { createConfig("extra.properties", "application.theme.color", "blue"); createConfig("extra2.properties", "application.theme.background", "red"); @@ -69,76 +68,76 @@ public class PropertiesReloadManualTest { @Test public void givenEnvironmentReader_whenColorChanged_thenExpectChangeValue() throws Exception { - Assert.assertEquals("blue", environmentConfigBean.getColor()); + assertEquals("blue", environmentConfigBean.getColor()); createConfig("extra.properties", "application.theme.color", "red"); Thread.sleep(refreshDelay); - Assert.assertEquals("red", environmentConfigBean.getColor()); + assertEquals("red", environmentConfigBean.getColor()); } @Test public void givenEnvironmentReader_whenBackgroundChanged_thenExpectChangeValue() throws Exception { - Assert.assertEquals("red", environmentConfigBean.getBackgroundColor()); + assertEquals("red", environmentConfigBean.getBackgroundColor()); createConfig("extra2.properties", "application.theme.background", "blue"); Thread.sleep(refreshDelay); - Assert.assertEquals("blue", environmentConfigBean.getBackgroundColor()); + assertEquals("blue", environmentConfigBean.getBackgroundColor()); } @Test public void givenPropertiesReader_whenColorChanged_thenExpectChangeValue() throws Exception { - Assert.assertEquals("blue", propertiesConfigBean.getColor()); + assertEquals("blue", propertiesConfigBean.getColor()); createConfig("extra.properties", "application.theme.color", "red"); Thread.sleep(refreshDelay); - Assert.assertEquals("red", propertiesConfigBean.getColor()); + assertEquals("red", propertiesConfigBean.getColor()); } @Test public void givenRefreshScopedValueReader_whenColorChangedAndRefreshCalled_thenExpectChangeValue() throws Exception { - Assert.assertEquals("blue", valueRefreshConfigBean.getColor()); + assertEquals("blue", valueRefreshConfigBean.getColor()); createConfig("extra.properties", "application.theme.color", "red"); Thread.sleep(refreshDelay); - Assert.assertEquals("blue", valueRefreshConfigBean.getColor()); + assertEquals("blue", valueRefreshConfigBean.getColor()); callRefresh(); - Assert.assertEquals("red", valueRefreshConfigBean.getColor()); + assertEquals("red", valueRefreshConfigBean.getColor()); } @Test public void givenSingletonRefreshScopedValueReader_whenColorChangedAndRefreshCalled_thenExpectOldValue() throws Exception { - Assert.assertEquals("blue", singletonValueRefreshConfigBean.getColor()); + assertEquals("blue", singletonValueRefreshConfigBean.getColor()); createConfig("extra.properties", "application.theme.color", "red"); Thread.sleep(refreshDelay); - Assert.assertEquals("blue", singletonValueRefreshConfigBean.getColor()); + assertEquals("blue", singletonValueRefreshConfigBean.getColor()); callRefresh(); - Assert.assertEquals("blue", singletonValueRefreshConfigBean.getColor()); + assertEquals("blue", singletonValueRefreshConfigBean.getColor()); } @Test public void givenRefreshScopedConfigurationPropertiesReader_whenColorChangedAndRefreshCalled_thenExpectChangeValue() throws Exception { - Assert.assertEquals("blue", configurationPropertiesRefreshConfigBean.getColor()); + assertEquals("blue", configurationPropertiesRefreshConfigBean.getColor()); createConfig("extra.properties", "application.theme.color", "red"); Thread.sleep(refreshDelay); - Assert.assertEquals("blue", configurationPropertiesRefreshConfigBean.getColor()); + assertEquals("blue", configurationPropertiesRefreshConfigBean.getColor()); callRefresh(); - Assert.assertEquals("red", configurationPropertiesRefreshConfigBean.getColor()); + assertEquals("red", configurationPropertiesRefreshConfigBean.getColor()); } public void callRefresh() throws Exception { @@ -148,7 +147,7 @@ public class PropertiesReloadManualTest { .accept(MediaType.APPLICATION_JSON_VALUE)) .andReturn(); MockHttpServletResponse response = mvcResult.getResponse(); - Assert.assertEquals(response.getStatus(), 200); + assertEquals(200, response.getStatus()); } public void createConfig(String file, String key, String value) throws Exception { diff --git a/spring-boot-modules/spring-boot-redis/pom.xml b/spring-boot-modules/spring-boot-redis/pom.xml index 42aa1321d5..5b85ad00ca 100644 --- a/spring-boot-modules/spring-boot-redis/pom.xml +++ b/spring-boot-modules/spring-boot-redis/pom.xml @@ -2,20 +2,19 @@ 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 3.0.2 - - com.baelding spring-boot-redis 0.0.1-SNAPSHOT spring-boot-redis Demo project for Spring Boot with Spring Data Redis - - 15 - + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 + + org.springframework.boot @@ -38,6 +37,12 @@ it.ozimov embedded-redis + + + org.slf4j + slf4j-simple + + 0.7.3 test @@ -66,4 +71,8 @@ + + 15 + + diff --git a/spring-boot-modules/spring-boot-resilience4j/README.md b/spring-boot-modules/spring-boot-resilience4j/README.md new file mode 100644 index 0000000000..e6c73674ce --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Resilience4j Events Endpoints](https://www.baeldung.com/resilience4j-events-endpoints) \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-resilience4j/pom.xml b/spring-boot-modules/spring-boot-resilience4j/pom.xml new file mode 100644 index 0000000000..609bc7fc49 --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + com.example + spring-boot-resilience4j + 0.0.1-SNAPSHOT + spring-boot-resilience4j + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-actuator + + + io.github.resilience4j + resilience4j-spring-boot2 + 2.0.2 + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.14.2 + + + org.springframework.boot + spring-boot-starter-test + test + + + com.github.tomakehurst + wiremock-jre8 + 2.35.0 + test + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ApiExceptionHandler.java b/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ApiExceptionHandler.java new file mode 100644 index 0000000000..4e14d5c532 --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ApiExceptionHandler.java @@ -0,0 +1,29 @@ +package com.baeldung.resilience4j.eventendpoints; + +import io.github.resilience4j.bulkhead.BulkheadFullException; +import io.github.resilience4j.circuitbreaker.CallNotPermittedException; +import io.github.resilience4j.ratelimiter.RequestNotPermitted; +import java.util.concurrent.TimeoutException; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ControllerAdvice +public class ApiExceptionHandler { + @ExceptionHandler({CallNotPermittedException.class}) + @ResponseStatus(HttpStatus.SERVICE_UNAVAILABLE) + public void handleCallNotPermittedException() {} + + @ExceptionHandler({TimeoutException.class}) + @ResponseStatus(HttpStatus.REQUEST_TIMEOUT) + public void handleTimeoutException() {} + + @ExceptionHandler({BulkheadFullException.class}) + @ResponseStatus(HttpStatus.BANDWIDTH_LIMIT_EXCEEDED) + public void handleBulkheadFullException() {} + + @ExceptionHandler({RequestNotPermitted.class}) + @ResponseStatus(HttpStatus.TOO_MANY_REQUESTS) + public void handleRequestNotPermitted() {} +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ExternalAPICaller.java b/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ExternalAPICaller.java new file mode 100644 index 0000000000..a860e7e3cc --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ExternalAPICaller.java @@ -0,0 +1,28 @@ +package com.baeldung.resilience4j.eventendpoints; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +@Component +public class ExternalAPICaller { + private final RestTemplate restTemplate; + + @Autowired + public ExternalAPICaller(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + public String callApi() { + return restTemplate.getForObject("/api/external", String.class); + } + + public String callApiWithDelay() { + String result = restTemplate.getForObject("/api/external", String.class); + try { + Thread.sleep(5000); + } catch (InterruptedException ignore) { + } + return result; + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ExternalApiCallerConfig.java b/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ExternalApiCallerConfig.java new file mode 100644 index 0000000000..7145e58877 --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ExternalApiCallerConfig.java @@ -0,0 +1,14 @@ +package com.baeldung.resilience4j.eventendpoints; + +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 ExternalApiCallerConfig { + @Bean + public RestTemplate restTemplate() { + return new RestTemplateBuilder().rootUri("http://localhost:9090").build(); + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ResilientApp.java b/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ResilientApp.java new file mode 100644 index 0000000000..35b999a9de --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ResilientApp.java @@ -0,0 +1,12 @@ +package com.baeldung.resilience4j.eventendpoints; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication() +public class ResilientApp { + + public static void main(String[] args) { + SpringApplication.run(ResilientApp.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ResilientAppController.java b/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ResilientAppController.java new file mode 100644 index 0000000000..ccd0108c2f --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/main/java/com/baeldung/resilience4j/eventendpoints/ResilientAppController.java @@ -0,0 +1,58 @@ +package com.baeldung.resilience4j.eventendpoints; + +import io.github.resilience4j.bulkhead.annotation.Bulkhead; +import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker; +import io.github.resilience4j.ratelimiter.annotation.RateLimiter; +import io.github.resilience4j.retry.annotation.Retry; +import io.github.resilience4j.timelimiter.annotation.TimeLimiter; +import java.util.concurrent.CompletableFuture; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/") +public class ResilientAppController { + + private final ExternalAPICaller externalAPICaller; + + @Autowired + public ResilientAppController(ExternalAPICaller externalApi) { + this.externalAPICaller = externalApi; + } + + @GetMapping("/circuit-breaker") + @CircuitBreaker(name = "externalService") + public String circuitBreakerApi() { + return externalAPICaller.callApi(); + } + + @GetMapping("/retry") + @Retry(name = "externalService", fallbackMethod = "fallbackAfterRetry") + public String retryApi() { + return externalAPICaller.callApi(); + } + + @GetMapping("/bulkhead") + @Bulkhead(name = "externalService") + public String bulkheadApi() { + return externalAPICaller.callApi(); + } + + @GetMapping("/rate-limiter") + @RateLimiter(name = "externalService") + public String rateLimitApi() { + return externalAPICaller.callApi(); + } + + @GetMapping("/time-limiter") + @TimeLimiter(name = "externalService") + public CompletableFuture timeLimiterApi() { + return CompletableFuture.supplyAsync(externalAPICaller::callApiWithDelay); + } + + public String fallbackAfterRetry(Exception ex) { + return "all retries have exhausted"; + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/main/resources/application.yml b/spring-boot-modules/spring-boot-resilience4j/src/main/resources/application.yml new file mode 100644 index 0000000000..81904f56d9 --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/main/resources/application.yml @@ -0,0 +1,60 @@ +management: + endpoints: + web: + exposure: + include: '*' + +resilience4j.circuitbreaker: + configs: + default: + registerHealthIndicator: true + slidingWindowSize: 10 + minimumNumberOfCalls: 5 + permittedNumberOfCallsInHalfOpenState: 3 + automaticTransitionFromOpenToHalfOpenEnabled: true + waitDurationInOpenState: 5s + failureRateThreshold: 50 + eventConsumerBufferSize: 50 + instances: + externalService: + baseConfig: default + +resilience4j.retry: + configs: + default: + maxAttempts: 3 + waitDuration: 100 + instances: + externalService: + baseConfig: default + +resilience4j.timelimiter: + configs: + default: + cancelRunningFuture: true + timeoutDuration: 2s + instances: + externalService: + baseConfig: default + +resilience4j.bulkhead: + configs: + default: + max-concurrent-calls: 3 + max-wait-duration: 1 + instances: + externalService: + baseConfig: default + +resilience4j.ratelimiter: + configs: + default: + limit-for-period: 5 + limit-refresh-period: 60s + timeout-duration: 0s + allow-health-indicator-to-fail: true + subscribe-for-events: true + event-consumer-buffer-size: 50 + instances: + externalService: + baseConfig: default \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/ResilientAppControllerIntegrationTest.java b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/ResilientAppControllerIntegrationTest.java new file mode 100644 index 0000000000..d1951218de --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/ResilientAppControllerIntegrationTest.java @@ -0,0 +1,319 @@ +package com.baeldung.resilience4j.eventendpoints; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.springframework.http.HttpStatus.*; + +import com.baeldung.resilience4j.eventendpoints.model.*; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JSR310Module; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import com.github.tomakehurst.wiremock.junit5.WireMockExtension; +import java.net.URI; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Map; +import java.util.concurrent.*; +import java.util.stream.IntStream; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class ResilientAppControllerIntegrationTest { + + private final Logger LOGGER = LoggerFactory.getLogger(getClass()); + + @Autowired private TestRestTemplate restTemplate; + + @LocalServerPort private Integer port; + + private static final ObjectMapper objectMapper = + new ObjectMapper().registerModule(new JSR310Module()); + + @RegisterExtension + static WireMockExtension EXTERNAL_SERVICE = + WireMockExtension.newInstance() + .options(WireMockConfiguration.wireMockConfig().port(9090)) + .build(); + + @Test + void testCircuitBreakerEvents() throws Exception { + EXTERNAL_SERVICE.stubFor(WireMock.get("/api/external").willReturn(serverError())); + + IntStream.rangeClosed(1, 5) + .forEach( + i -> { + ResponseEntity response = + restTemplate.getForEntity("/api/circuit-breaker", String.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); + }); + + // Fetch the events generated by the above calls + List circuitBreakerEvents = getCircuitBreakerEvents(); + assertThat(circuitBreakerEvents.size()).isEqualTo(7); + + // The first 5 events are the error events corresponding to the above server error responses + IntStream.rangeClosed(0, 4) + .forEach( + i -> { + assertThat(circuitBreakerEvents.get(i).getCircuitBreakerName()) + .isEqualTo("externalService"); + assertThat(circuitBreakerEvents.get(i).getType()).isEqualTo("ERROR"); + assertThat(circuitBreakerEvents.get(i).getCreationTime()).isNotNull(); + assertThat(circuitBreakerEvents.get(i).getErrorMessage()).isNotNull(); + assertThat(circuitBreakerEvents.get(i).getDurationInMs()).isNotNull(); + assertThat(circuitBreakerEvents.get(i).getStateTransition()).isNull(); + }); + + // Following event signals the configured failure rate exceeded + CircuitBreakerEvent failureRateExceededEvent = circuitBreakerEvents.get(5); + assertThat(failureRateExceededEvent.getCircuitBreakerName()).isEqualTo("externalService"); + assertThat(failureRateExceededEvent.getType()).isEqualTo("FAILURE_RATE_EXCEEDED"); + assertThat(failureRateExceededEvent.getCreationTime()).isNotNull(); + assertThat(failureRateExceededEvent.getErrorMessage()).isNull(); + assertThat(failureRateExceededEvent.getDurationInMs()).isNull(); + assertThat(failureRateExceededEvent.getStateTransition()).isNull(); + + // Following event signals the state transition from CLOSED TO OPEN + CircuitBreakerEvent stateTransitionEvent = circuitBreakerEvents.get(6); + assertThat(stateTransitionEvent.getCircuitBreakerName()).isEqualTo("externalService"); + assertThat(stateTransitionEvent.getType()).isEqualTo("STATE_TRANSITION"); + assertThat(stateTransitionEvent.getCreationTime()).isNotNull(); + assertThat(stateTransitionEvent.getErrorMessage()).isNull(); + assertThat(stateTransitionEvent.getDurationInMs()).isNull(); + assertThat(stateTransitionEvent.getStateTransition()).isEqualTo("CLOSED_TO_OPEN"); + + IntStream.rangeClosed(1, 5) + .forEach( + i -> { + ResponseEntity response = + restTemplate.getForEntity("/api/circuit-breaker", String.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE); + }); + + /// Fetch the events generated by the above calls + List updatedCircuitBreakerEvents = getCircuitBreakerEvents(); + assertThat(updatedCircuitBreakerEvents.size()).isEqualTo(12); + + // Newly added events will be of type NOT_PERMITTED since the Circuit Breaker is in OPEN state + IntStream.rangeClosed(7, 11) + .forEach( + i -> { + assertThat(updatedCircuitBreakerEvents.get(i).getCircuitBreakerName()) + .isEqualTo("externalService"); + assertThat(updatedCircuitBreakerEvents.get(i).getType()).isEqualTo("NOT_PERMITTED"); + assertThat(updatedCircuitBreakerEvents.get(i).getCreationTime()).isNotNull(); + assertThat(updatedCircuitBreakerEvents.get(i).getErrorMessage()).isNull(); + assertThat(updatedCircuitBreakerEvents.get(i).getDurationInMs()).isNull(); + assertThat(updatedCircuitBreakerEvents.get(i).getStateTransition()).isNull(); + }); + + EXTERNAL_SERVICE.verify(5, getRequestedFor(urlEqualTo("/api/external"))); + } + + private List getCircuitBreakerEvents() throws Exception { + String jsonEventsList = + IOUtils.toString( + new URI("http://localhost:" + port + "/actuator/circuitbreakerevents"), + Charset.forName("UTF-8")); + CircuitBreakerEvents circuitBreakerEvents = + objectMapper.readValue(jsonEventsList, CircuitBreakerEvents.class); + return circuitBreakerEvents.getCircuitBreakerEvents(); + } + + @Test + void testRetryEvents() throws Exception { + EXTERNAL_SERVICE.stubFor(WireMock.get("/api/external").willReturn(ok())); + ResponseEntity response1 = restTemplate.getForEntity("/api/retry", String.class); + EXTERNAL_SERVICE.verify(1, getRequestedFor(urlEqualTo("/api/external"))); + + EXTERNAL_SERVICE.resetRequests(); + + EXTERNAL_SERVICE.stubFor(WireMock.get("/api/external").willReturn(serverError())); + ResponseEntity response2 = restTemplate.getForEntity("/api/retry", String.class); + assertThat(response2.getBody()).isEqualTo("all retries have exhausted"); + EXTERNAL_SERVICE.verify(3, getRequestedFor(urlEqualTo("/api/external"))); + + List retryEvents = getRetryEvents(); + assertThat(retryEvents.size()).isEqualTo(3); + + // First 2 events should be retry events + IntStream.rangeClosed(0, 1) + .forEach( + i -> { + assertThat(retryEvents.get(i).getRetryName()).isEqualTo("externalService"); + assertThat(retryEvents.get(i).getType()).isEqualTo("RETRY"); + assertThat(retryEvents.get(i).getCreationTime()).isNotNull(); + assertThat(retryEvents.get(i).getErrorMessage()).isNotNull(); + assertThat(retryEvents.get(i).getNumberOfAttempts()).isEqualTo(i + 1); + }); + + // Last event should be an error event because the configured num of retries is reached + RetryEvent errorRetryEvent = retryEvents.get(2); + assertThat(errorRetryEvent.getRetryName()).isEqualTo("externalService"); + assertThat(errorRetryEvent.getType()).isEqualTo("ERROR"); + assertThat(errorRetryEvent.getCreationTime()).isNotNull(); + assertThat(errorRetryEvent.getErrorMessage()).isNotNull(); + assertThat(errorRetryEvent.getNumberOfAttempts()).isEqualTo(3); + } + + private List getRetryEvents() throws Exception { + String jsonEventsList = + IOUtils.toString( + new URI("http://localhost:" + port + "/actuator/retryevents"), + Charset.forName("UTF-8")); + RetryEvents retryEvents = objectMapper.readValue(jsonEventsList, RetryEvents.class); + return retryEvents.getRetryEvents(); + } + + @Test + void testTimeLimiterEvents() throws Exception { + EXTERNAL_SERVICE.stubFor(WireMock.get("/api/external").willReturn(ok())); + ResponseEntity response = restTemplate.getForEntity("/api/time-limiter", String.class); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.REQUEST_TIMEOUT); + EXTERNAL_SERVICE.verify(1, getRequestedFor(urlEqualTo("/api/external"))); + + List timeLimiterEvents = getTimeLimiterEvents(); + assertThat(timeLimiterEvents.size()).isEqualTo(1); + TimeLimiterEvent timeoutEvent = timeLimiterEvents.get(0); + assertThat(timeoutEvent.getTimeLimiterName()).isEqualTo("externalService"); + assertThat(timeoutEvent.getType()).isEqualTo("TIMEOUT"); + assertThat(timeoutEvent.getCreationTime()).isNotNull(); + } + + private List getTimeLimiterEvents() throws Exception { + String jsonEventsList = + IOUtils.toString( + new URI("http://localhost:" + port + "/actuator/timelimiterevents"), + Charset.forName("UTF-8")); + TimeLimiterEvents timeLimiterEvents = + objectMapper.readValue(jsonEventsList, TimeLimiterEvents.class); + return timeLimiterEvents.getTimeLimiterEvents(); + } + + @Test + void testBulkheadEvents() throws Exception { + EXTERNAL_SERVICE.stubFor(WireMock.get("/api/external").willReturn(ok())); + Map responseStatusCount = new ConcurrentHashMap<>(); + ExecutorService executorService = Executors.newFixedThreadPool(5); + CountDownLatch latch = new CountDownLatch(5); + + IntStream.rangeClosed(1, 5) + .forEach( + i -> + executorService.execute( + () -> { + ResponseEntity response = + restTemplate.getForEntity("/api/bulkhead", String.class); + int statusCode = response.getStatusCodeValue(); + responseStatusCount.merge(statusCode, 1, Integer::sum); + latch.countDown(); + })); + latch.await(); + executorService.shutdown(); + + assertEquals(2, responseStatusCount.keySet().size()); + LOGGER.info("Response statuses: " + responseStatusCount.keySet()); + assertTrue(responseStatusCount.containsKey(BANDWIDTH_LIMIT_EXCEEDED.value())); + assertTrue(responseStatusCount.containsKey(OK.value())); + EXTERNAL_SERVICE.verify(3, getRequestedFor(urlEqualTo("/api/external"))); + + List bulkheadEvents = getBulkheadEvents(); + + // Based on the configuration, the first 3 calls should be permitted, so we should see the + // CALL_PERMITTED events + IntStream.rangeClosed(0, 2) + .forEach( + i -> { + assertThat(bulkheadEvents.get(i).getBulkheadName()).isEqualTo("externalService"); + assertThat(bulkheadEvents.get(i).getType()).isEqualTo("CALL_PERMITTED"); + assertThat(bulkheadEvents.get(i).getCreationTime()).isNotNull(); + }); + + // For the other 2 calls made we should see the CALL_REJECTED events + IntStream.rangeClosed(3, 4) + .forEach( + i -> { + assertThat(bulkheadEvents.get(i).getBulkheadName()).isEqualTo("externalService"); + assertThat(bulkheadEvents.get(i).getType()).isEqualTo("CALL_REJECTED"); + assertThat(bulkheadEvents.get(i).getCreationTime()).isNotNull(); + }); + } + + private List getBulkheadEvents() throws Exception { + String jsonEventsList = + IOUtils.toString( + new URI("http://localhost:" + port + "/actuator/bulkheadevents"), + Charset.forName("UTF-8")); + BulkheadEvents bulkheadEvents = objectMapper.readValue(jsonEventsList, BulkheadEvents.class); + return bulkheadEvents.getBulkheadEvents(); + } + + @Test + void testRateLimiterEvents() throws Exception { + EXTERNAL_SERVICE.stubFor(WireMock.get("/api/external").willReturn(ok())); + Map responseStatusCount = new ConcurrentHashMap<>(); + + IntStream.rangeClosed(1, 50) + .forEach( + i -> { + ResponseEntity response = + restTemplate.getForEntity("/api/rate-limiter", String.class); + int statusCode = response.getStatusCodeValue(); + responseStatusCount.put( + statusCode, responseStatusCount.getOrDefault(statusCode, 0) + 1); + }); + + assertEquals(2, responseStatusCount.keySet().size()); + assertTrue(responseStatusCount.containsKey(TOO_MANY_REQUESTS.value())); + assertTrue(responseStatusCount.containsKey(OK.value())); + EXTERNAL_SERVICE.verify(5, getRequestedFor(urlEqualTo("/api/external"))); + + List rateLimiterEvents = getRateLimiterEvents(); + assertThat(rateLimiterEvents.size()).isEqualTo(50); + + // First allowed calls in the rate limit is 5, so we should see for those SUCCESSFUL_ACQUIRE + // events + IntStream.rangeClosed(0, 4) + .forEach( + i -> { + assertThat(rateLimiterEvents.get(i).getRateLimiterName()) + .isEqualTo("externalService"); + assertThat(rateLimiterEvents.get(i).getType()).isEqualTo("SUCCESSFUL_ACQUIRE"); + assertThat(rateLimiterEvents.get(i).getCreationTime()).isNotNull(); + }); + + // the rest should be FAILED_ACQUIRE events since the rate limiter kicks in + IntStream.rangeClosed(5, rateLimiterEvents.size() - 1) + .forEach( + i -> { + assertThat(rateLimiterEvents.get(i).getRateLimiterName()) + .isEqualTo("externalService"); + assertThat(rateLimiterEvents.get(i).getType()).isEqualTo("FAILED_ACQUIRE"); + assertThat(rateLimiterEvents.get(i).getCreationTime()).isNotNull(); + }); + } + + private List getRateLimiterEvents() throws Exception { + String jsonEventsList = + IOUtils.toString( + new URI("http://localhost:" + port + "/actuator/ratelimiterevents"), + Charset.forName("UTF-8")); + RateLimiterEvents rateLimiterEvents = + objectMapper.readValue(jsonEventsList, RateLimiterEvents.class); + return rateLimiterEvents.getRateLimiterEvents(); + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/BulkheadEvent.java b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/BulkheadEvent.java new file mode 100644 index 0000000000..6d25006bbb --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/BulkheadEvent.java @@ -0,0 +1,50 @@ +package com.baeldung.resilience4j.eventendpoints.model; + +import java.time.ZonedDateTime; +import java.util.Objects; + +public class BulkheadEvent { + + private String bulkheadName; + private String type; + private ZonedDateTime creationTime; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BulkheadEvent that = (BulkheadEvent) o; + return Objects.equals(bulkheadName, that.bulkheadName) + && Objects.equals(type, that.type) + && Objects.equals(creationTime, that.creationTime); + } + + @Override + public int hashCode() { + return Objects.hash(bulkheadName, type, creationTime); + } + + public String getBulkheadName() { + return bulkheadName; + } + + public void setBulkheadName(String bulkheadName) { + this.bulkheadName = bulkheadName; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public ZonedDateTime getCreationTime() { + return creationTime; + } + + public void setCreationTime(ZonedDateTime creationTime) { + this.creationTime = creationTime; + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/BulkheadEvents.java b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/BulkheadEvents.java new file mode 100644 index 0000000000..7d8b6b2a5f --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/BulkheadEvents.java @@ -0,0 +1,16 @@ +package com.baeldung.resilience4j.eventendpoints.model; + +import java.util.List; + +public class BulkheadEvents { + + private List bulkheadEvents; + + public List getBulkheadEvents() { + return bulkheadEvents; + } + + public void setBulkheadEvents(List bulkheadEvents) { + this.bulkheadEvents = bulkheadEvents; + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/CircuitBreakerEvent.java b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/CircuitBreakerEvent.java new file mode 100644 index 0000000000..0a07c9b495 --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/CircuitBreakerEvent.java @@ -0,0 +1,81 @@ +package com.baeldung.resilience4j.eventendpoints.model; + +import java.time.ZonedDateTime; +import java.util.Objects; + +public class CircuitBreakerEvent { + + private String circuitBreakerName; + private String type; + private ZonedDateTime creationTime; + private String errorMessage; + private Integer durationInMs; + private String stateTransition; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CircuitBreakerEvent that = (CircuitBreakerEvent) o; + return Objects.equals(circuitBreakerName, that.circuitBreakerName) + && Objects.equals(type, that.type) + && Objects.equals(creationTime, that.creationTime) + && Objects.equals(errorMessage, that.errorMessage) + && Objects.equals(durationInMs, that.durationInMs) + && Objects.equals(stateTransition, that.stateTransition); + } + + @Override + public int hashCode() { + return Objects.hash( + circuitBreakerName, type, creationTime, errorMessage, durationInMs, stateTransition); + } + + public String getCircuitBreakerName() { + return circuitBreakerName; + } + + public void setCircuitBreakerName(String circuitBreakerName) { + this.circuitBreakerName = circuitBreakerName; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public ZonedDateTime getCreationTime() { + return creationTime; + } + + public void setCreationTime(ZonedDateTime creationTime) { + this.creationTime = creationTime; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public Integer getDurationInMs() { + return durationInMs; + } + + public void setDurationInMs(Integer durationInMs) { + this.durationInMs = durationInMs; + } + + public String getStateTransition() { + return stateTransition; + } + + public void setStateTransition(String stateTransition) { + this.stateTransition = stateTransition; + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/CircuitBreakerEvents.java b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/CircuitBreakerEvents.java new file mode 100644 index 0000000000..c3ec741d05 --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/CircuitBreakerEvents.java @@ -0,0 +1,16 @@ +package com.baeldung.resilience4j.eventendpoints.model; + +import java.util.List; + +public class CircuitBreakerEvents { + + private List circuitBreakerEvents; + + public List getCircuitBreakerEvents() { + return circuitBreakerEvents; + } + + public void setCircuitBreakerEvents(List circuitBreakerEvents) { + this.circuitBreakerEvents = circuitBreakerEvents; + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/RateLimiterEvent.java b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/RateLimiterEvent.java new file mode 100644 index 0000000000..ccc0f5a9b3 --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/RateLimiterEvent.java @@ -0,0 +1,50 @@ +package com.baeldung.resilience4j.eventendpoints.model; + +import java.time.ZonedDateTime; +import java.util.Objects; + +public class RateLimiterEvent { + + private String rateLimiterName; + private String type; + private ZonedDateTime creationTime; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RateLimiterEvent that = (RateLimiterEvent) o; + return Objects.equals(rateLimiterName, that.rateLimiterName) + && Objects.equals(type, that.type) + && Objects.equals(creationTime, that.creationTime); + } + + @Override + public int hashCode() { + return Objects.hash(rateLimiterName, type, creationTime); + } + + public String getRateLimiterName() { + return rateLimiterName; + } + + public void setRateLimiterName(String rateLimiterName) { + this.rateLimiterName = rateLimiterName; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public ZonedDateTime getCreationTime() { + return creationTime; + } + + public void setCreationTime(ZonedDateTime creationTime) { + this.creationTime = creationTime; + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/RateLimiterEvents.java b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/RateLimiterEvents.java new file mode 100644 index 0000000000..c0cfcdf0d7 --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/RateLimiterEvents.java @@ -0,0 +1,16 @@ +package com.baeldung.resilience4j.eventendpoints.model; + +import java.util.List; + +public class RateLimiterEvents { + + private List rateLimiterEvents; + + public List getRateLimiterEvents() { + return rateLimiterEvents; + } + + public void setRateLimiterEvents(List rateLimiterEvents) { + this.rateLimiterEvents = rateLimiterEvents; + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/RetryEvent.java b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/RetryEvent.java new file mode 100644 index 0000000000..a17d45c679 --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/RetryEvent.java @@ -0,0 +1,70 @@ +package com.baeldung.resilience4j.eventendpoints.model; + +import java.time.ZonedDateTime; +import java.util.Objects; + +public class RetryEvent { + + private String retryName; + private String type; + private ZonedDateTime creationTime; + private String errorMessage; + private Integer numberOfAttempts; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RetryEvent that = (RetryEvent) o; + return Objects.equals(retryName, that.retryName) + && Objects.equals(type, that.type) + && Objects.equals(creationTime, that.creationTime) + && Objects.equals(errorMessage, that.errorMessage) + && Objects.equals(numberOfAttempts, that.numberOfAttempts); + } + + @Override + public int hashCode() { + return Objects.hash(retryName, type, creationTime, errorMessage, numberOfAttempts); + } + + public String getRetryName() { + return retryName; + } + + public void setRetryName(String retryName) { + this.retryName = retryName; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public ZonedDateTime getCreationTime() { + return creationTime; + } + + public void setCreationTime(ZonedDateTime creationTime) { + this.creationTime = creationTime; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public Integer getNumberOfAttempts() { + return numberOfAttempts; + } + + public void setNumberOfAttempts(Integer numberOfAttempts) { + this.numberOfAttempts = numberOfAttempts; + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/RetryEvents.java b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/RetryEvents.java new file mode 100644 index 0000000000..e5bb73ff0c --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/RetryEvents.java @@ -0,0 +1,16 @@ +package com.baeldung.resilience4j.eventendpoints.model; + +import java.util.List; + +public class RetryEvents { + + private List retryEvents; + + public List getRetryEvents() { + return retryEvents; + } + + public void setRetryEvents(List retryEvents) { + this.retryEvents = retryEvents; + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/TimeLimiterEvent.java b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/TimeLimiterEvent.java new file mode 100644 index 0000000000..07f891c401 --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/TimeLimiterEvent.java @@ -0,0 +1,50 @@ +package com.baeldung.resilience4j.eventendpoints.model; + +import java.time.ZonedDateTime; +import java.util.Objects; + +public class TimeLimiterEvent { + + private String timeLimiterName; + private String type; + private ZonedDateTime creationTime; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TimeLimiterEvent that = (TimeLimiterEvent) o; + return Objects.equals(timeLimiterName, that.timeLimiterName) + && Objects.equals(type, that.type) + && Objects.equals(creationTime, that.creationTime); + } + + @Override + public int hashCode() { + return Objects.hash(timeLimiterName, type, creationTime); + } + + public String getTimeLimiterName() { + return timeLimiterName; + } + + public void setTimeLimiterName(String timeLimiterName) { + this.timeLimiterName = timeLimiterName; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public ZonedDateTime getCreationTime() { + return creationTime; + } + + public void setCreationTime(ZonedDateTime creationTime) { + this.creationTime = creationTime; + } +} diff --git a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/TimeLimiterEvents.java b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/TimeLimiterEvents.java new file mode 100644 index 0000000000..739ff91916 --- /dev/null +++ b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/model/TimeLimiterEvents.java @@ -0,0 +1,16 @@ +package com.baeldung.resilience4j.eventendpoints.model; + +import java.util.List; + +public class TimeLimiterEvents { + + private List timeLimiterEvents; + + public List getTimeLimiterEvents() { + return timeLimiterEvents; + } + + public void setTimeLimiterEvents(List timeLimiterEvents) { + this.timeLimiterEvents = timeLimiterEvents; + } +} diff --git a/spring-boot-modules/spring-boot-springdoc/pom.xml b/spring-boot-modules/spring-boot-springdoc/pom.xml index 8cd94179cf..e21efc35d2 100644 --- a/spring-boot-modules/spring-boot-springdoc/pom.xml +++ b/spring-boot-modules/spring-boot-springdoc/pom.xml @@ -146,7 +146,7 @@ org.springdoc springdoc-openapi-maven-plugin - 1.4 + ${springdoc-openapi-maven-plugin.version} integration-test @@ -167,9 +167,10 @@ - 1.6.8 + 1.7.0 1.5.6 ${project.build.directory}/generated-snippets + 1.4 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger-2/README.md b/spring-boot-modules/spring-boot-swagger-2/README.md index 1b43b09e39..99e4c4cca5 100644 --- a/spring-boot-modules/spring-boot-swagger-2/README.md +++ b/spring-boot-modules/spring-boot-swagger-2/README.md @@ -5,3 +5,4 @@ - [Swagger @ApiParam vs @ApiModelProperty](https://www.baeldung.com/swagger-apiparam-vs-apimodelproperty) - [Map Date Types With OpenAPI Generator](https://www.baeldung.com/openapi-map-date-types) - [API First Development with Spring Boot and OpenAPI 3.0](https://www.baeldung.com/spring-boot-openapi-api-first-development) +- [Change Swagger-UI URL prefix](https://www.baeldung.com/spring-boot-custom-swagger-url) diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml b/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml index de2c8c68c4..e7950fe393 100644 --- a/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml +++ b/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml @@ -1,75 +1,72 @@ - 4.0.0 - spring-boot-swagger-keycloak - 0.1.0-SNAPSHOT - spring-boot-swagger-keycloak - jar - Module For Spring Boot Swagger UI with Keycloak + 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-swagger-keycloak + 0.1.0-SNAPSHOT + spring-boot-swagger-keycloak + jar + Module For Spring Boot Swagger UI with Keycloak - - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT - + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 + - - - - org.keycloak.bom - keycloak-adapter-bom - ${keycloak.version} - pom - import - - - org.apache.logging.log4j - log4j-bom - ${log4j2.version} - import - pom - - - + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + - - - org.springframework.boot - spring-boot-starter-web - - - io.springfox - springfox-boot-starter - ${springfox.version} - - - - org.keycloak - keycloak-spring-boot-starter - - - - org.springframework.boot - spring-boot-starter-security - - + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-oauth2-resource-server + + + + org.springframework.boot + spring-boot-starter-security + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + ${springdoc.version} + + + javax.annotation + javax.annotation-api + ${javax.version} + + - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + + + org.springframework.boot + spring-boot-maven-plugin + + + - - 2.4.5 - 3.0.0 - 15.0.2 - 2.17.1 - + + 2.1.0 + 2.17.1 + 1.3.2 + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/GlobalSecurityConfig.java b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/GlobalSecurityConfig.java index 985cbf7d06..5c24368ce6 100644 --- a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/GlobalSecurityConfig.java +++ b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/GlobalSecurityConfig.java @@ -1,59 +1,40 @@ package com.baeldung.swaggerkeycloak; -import org.keycloak.adapters.springsecurity.KeycloakConfiguration; -import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; -import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; -import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; import org.springframework.security.core.session.SessionRegistryImpl; +import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; -@KeycloakConfiguration +@Configuration +@EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) -public class GlobalSecurityConfig extends KeycloakWebSecurityConfigurerAdapter { +public class GlobalSecurityConfig { - @Override + @Bean protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); } - // otherwise, we'll get an error 'permitAll only works with HttpSecurity.authorizeRequests()' - @Override - protected void configure(HttpSecurity http) throws Exception { - super.configure(http); - http - .csrf().disable() - .authorizeRequests() - // we can set up authorization here alternatively to @Secured methods - .antMatchers(HttpMethod.OPTIONS).permitAll() - .antMatchers("/api/**").authenticated() - // force authentication for all requests (and use global method security) - .anyRequest().permitAll(); + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.csrf() + .disable() + .authorizeRequests() + .requestMatchers(HttpMethod.OPTIONS) + .permitAll() + .requestMatchers("/api/**") + .authenticated() + .anyRequest() + .permitAll(); + http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); + return http.build(); } - /* - * re-configure Spring Security to use - * registers the KeycloakAuthenticationProvider with the authentication manager - */ - @Autowired - void configureGlobal(AuthenticationManagerBuilder auth) { - KeycloakAuthenticationProvider provider = keycloakAuthenticationProvider(); - provider.setGrantedAuthoritiesMapper(authoritiesMapper()); - auth.authenticationProvider(provider); - } - - GrantedAuthoritiesMapper authoritiesMapper() { - SimpleAuthorityMapper mapper = new SimpleAuthorityMapper(); - mapper.setPrefix("ROLE_"); // Spring Security adds a prefix to the authority/role names (we use the default here) - mapper.setConvertToUpperCase(true); // convert names to uppercase - mapper.setDefaultAuthority("ROLE_ANONYMOUS"); // set a default authority - return mapper; - } - -} +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/KeycloakConfigResolverConfig.java b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/KeycloakConfigResolverConfig.java deleted file mode 100644 index bca764a17d..0000000000 --- a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/KeycloakConfigResolverConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.baeldung.swaggerkeycloak; - -import org.keycloak.adapters.KeycloakConfigResolver; -import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class KeycloakConfigResolverConfig { - - /* - * re-configure keycloak adapter for Spring Boot environment, - * i.e. to read config from application.yml - * (otherwise, we need a keycloak.json file) - */ - @Bean - public KeycloakConfigResolver configResolver() { - return new KeycloakSpringBootConfigResolver(); - } - - - -} diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/OpenAPISecurityConfig.java b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/OpenAPISecurityConfig.java index d3ab26e1ee..8d75a1a885 100644 --- a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/OpenAPISecurityConfig.java +++ b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/OpenAPISecurityConfig.java @@ -1,22 +1,17 @@ package com.baeldung.swaggerkeycloak; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; -import springfox.documentation.builders.OAuth2SchemeBuilder; -import springfox.documentation.service.AuthorizationScope; -import springfox.documentation.service.SecurityReference; -import springfox.documentation.service.SecurityScheme; -import springfox.documentation.spi.service.contexts.SecurityContext; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger.web.SecurityConfiguration; -import springfox.documentation.swagger.web.SecurityConfigurationBuilder; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.security.OAuthFlow; +import io.swagger.v3.oas.models.security.OAuthFlows; +import io.swagger.v3.oas.models.security.Scopes; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; @Configuration public class OpenAPISecurityConfig { @@ -25,59 +20,35 @@ public class OpenAPISecurityConfig { String authServerUrl; @Value("${keycloak.realm}") String realm; - @Value("${keycloak.resource}") - private String clientId; - @Value("${keycloak.credentials.secret}") - private String clientSecret; - @Autowired - void addSecurity(Docket docket) { - docket - .securitySchemes(Collections.singletonList(authenticationScheme())) - .securityContexts(Collections.singletonList(securityContext())); - } - - private SecurityScheme authenticationScheme() { - return new OAuth2SchemeBuilder("implicit") - .name("my_oAuth_security_schema") - .authorizationUrl(authServerUrl + "/realms/" + realm) - .scopes(authorizationScopes()) - .build(); - } - - private List authorizationScopes() { - return Arrays.asList( - new AuthorizationScope("read_access", "read data"), - new AuthorizationScope("write_access", "modify data") - ); - } - - private SecurityContext securityContext() { - return SecurityContext. - builder(). - securityReferences(readAccessAuth()) - .operationSelector(operationContext -> HttpMethod.GET.equals(operationContext.httpMethod())) - .build(); - } - - private List readAccessAuth() { - AuthorizationScope[] authorizationScopes = new AuthorizationScope[] { authorizationScopes().get(0) }; - return Collections.singletonList( - new SecurityReference("my_oAuth_security_schema", authorizationScopes) - ); - } + private static final String OAUTH_SCHEME_NAME = "my_oAuth_security_schema"; @Bean - public SecurityConfiguration security() { - return SecurityConfigurationBuilder.builder() - .clientId(clientId) - .clientSecret(clientSecret) - .realm(realm) - .appName(clientId) - .scopeSeparator(",") - .additionalQueryStringParams(null) - .useBasicAuthenticationWithAccessCodeGrant(false) - .build(); + public OpenAPI openAPI() { + return new OpenAPI().components(new Components() + .addSecuritySchemes(OAUTH_SCHEME_NAME, createOAuthScheme())) + .addSecurityItem(new SecurityRequirement().addList(OAUTH_SCHEME_NAME)) + .info(new Info().title("Todos Management Service") + .description("A service providing todos.") + .version("1.0")); + } + + private SecurityScheme createOAuthScheme() { + OAuthFlows flows = createOAuthFlows(); + return new SecurityScheme().type(SecurityScheme.Type.OAUTH2) + .flows(flows); + } + + private OAuthFlows createOAuthFlows() { + OAuthFlow flow = createAuthorizationCodeFlow(); + return new OAuthFlows().implicit(flow); + } + + private OAuthFlow createAuthorizationCodeFlow() { + return new OAuthFlow() + .authorizationUrl(authServerUrl + "/realms/" + realm + "/protocol/openid-connect/auth") + .scopes(new Scopes().addString("read_access", "read data") + .addString("write_access", "modify data")); } } diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/SwaggerUIConfig.java b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/SwaggerUIConfig.java deleted file mode 100644 index 1207fe5b9e..0000000000 --- a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/SwaggerUIConfig.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.baeldung.swaggerkeycloak; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.oas.annotations.EnableOpenApi; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; - -import static springfox.documentation.builders.RequestHandlerSelectors.basePackage; - -@EnableOpenApi -@Configuration -class SwaggerUIConfig { - - @Bean - Docket api() { - return new Docket(DocumentationType.OAS_30) - .useDefaultResponseMessages(false) - .select() - .apis(basePackage(TodosApplication.class.getPackage().getName())) - .paths(PathSelectors.any()) - .build() - .apiInfo(apiInfo()); - } - - private ApiInfo apiInfo() { - return new ApiInfoBuilder().title("Todos Management Service") - .description("A service providing todos.") - .version("1.0") - .build(); - } - -} diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/TodosController.java b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/TodosController.java index 6b70072ce3..6d48a0c67d 100644 --- a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/TodosController.java +++ b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/java/com/baeldung/swaggerkeycloak/TodosController.java @@ -1,14 +1,15 @@ package com.baeldung.swaggerkeycloak; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + import javax.annotation.PostConstruct; import java.time.LocalDate; import java.util.Collection; @@ -28,13 +29,10 @@ public class TodosController { } @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) - @ApiOperation("Read all todos") - @ApiResponses({ - @ApiResponse(code = 200, message = "The todos were found and returned.") - }) + @Operation(description = "Read all todos") + @ApiResponses({ @ApiResponse(responseCode = "200", description = "The todos were found and returned.") }) @PreAuthorize("hasAuthority('SCOPE_read_access')") public Collection readAll() { return todos.values(); } - } diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/META-INF/resources/webjars/springfox-swagger-ui/favicon-16x16.png b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/META-INF/resources/webjars/springfox-swagger-ui/favicon-16x16.png deleted file mode 100644 index 8b194e617a..0000000000 Binary files a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/META-INF/resources/webjars/springfox-swagger-ui/favicon-16x16.png and /dev/null differ diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/META-INF/resources/webjars/springfox-swagger-ui/favicon-32x32.png b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/META-INF/resources/webjars/springfox-swagger-ui/favicon-32x32.png deleted file mode 100644 index 249737fe44..0000000000 Binary files a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/META-INF/resources/webjars/springfox-swagger-ui/favicon-32x32.png and /dev/null differ diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/META-INF/resources/webjars/springfox-swagger-ui/oauth2-redirect.html b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/META-INF/resources/webjars/springfox-swagger-ui/oauth2-redirect.html deleted file mode 100644 index 64b171f7de..0000000000 --- a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/META-INF/resources/webjars/springfox-swagger-ui/oauth2-redirect.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - Swagger UI: OAuth2 Redirect - - - - - diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/META-INF/resources/webjars/springfox-swagger-ui/swagger-ui.css b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/META-INF/resources/webjars/springfox-swagger-ui/swagger-ui.css deleted file mode 100644 index e43a572a13..0000000000 --- a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/META-INF/resources/webjars/springfox-swagger-ui/swagger-ui.css +++ /dev/null @@ -1,4 +0,0 @@ -.swagger-ui{color:#3b4151; - /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */font-family:sans-serif}.swagger-ui html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;line-height:1.15}.swagger-ui body{margin:0}.swagger-ui article,.swagger-ui aside,.swagger-ui footer,.swagger-ui header,.swagger-ui nav,.swagger-ui section{display:block}.swagger-ui h1{font-size:2em;margin:.67em 0}.swagger-ui figcaption,.swagger-ui figure,.swagger-ui main{display:block}.swagger-ui figure{margin:1em 40px}.swagger-ui hr{box-sizing:content-box;height:0;overflow:visible}.swagger-ui pre{font-family:monospace,monospace;font-size:1em}.swagger-ui a{-webkit-text-decoration-skip:objects;background-color:transparent}.swagger-ui abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.swagger-ui b,.swagger-ui strong{font-weight:inherit;font-weight:bolder}.swagger-ui code,.swagger-ui kbd,.swagger-ui samp{font-family:monospace,monospace;font-size:1em}.swagger-ui dfn{font-style:italic}.swagger-ui mark{background-color:#ff0;color:#000}.swagger-ui small{font-size:80%}.swagger-ui sub,.swagger-ui sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.swagger-ui sub{bottom:-.25em}.swagger-ui sup{top:-.5em}.swagger-ui audio,.swagger-ui video{display:inline-block}.swagger-ui audio:not([controls]){display:none;height:0}.swagger-ui img{border-style:none}.swagger-ui svg:not(:root){overflow:hidden}.swagger-ui button,.swagger-ui input,.swagger-ui optgroup,.swagger-ui select,.swagger-ui textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}.swagger-ui button,.swagger-ui input{overflow:visible}.swagger-ui button,.swagger-ui select{text-transform:none}.swagger-ui [type=reset],.swagger-ui [type=submit],.swagger-ui button,.swagger-ui html [type=button]{-webkit-appearance:button}.swagger-ui [type=button]::-moz-focus-inner,.swagger-ui [type=reset]::-moz-focus-inner,.swagger-ui [type=submit]::-moz-focus-inner,.swagger-ui button::-moz-focus-inner{border-style:none;padding:0}.swagger-ui [type=button]:-moz-focusring,.swagger-ui [type=reset]:-moz-focusring,.swagger-ui [type=submit]:-moz-focusring,.swagger-ui button:-moz-focusring{outline:1px dotted ButtonText}.swagger-ui fieldset{padding:.35em .75em .625em}.swagger-ui legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}.swagger-ui progress{display:inline-block;vertical-align:baseline}.swagger-ui textarea{overflow:auto}.swagger-ui [type=checkbox],.swagger-ui [type=radio]{box-sizing:border-box;padding:0}.swagger-ui [type=number]::-webkit-inner-spin-button,.swagger-ui [type=number]::-webkit-outer-spin-button{height:auto}.swagger-ui [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.swagger-ui [type=search]::-webkit-search-cancel-button,.swagger-ui [type=search]::-webkit-search-decoration{-webkit-appearance:none}.swagger-ui ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.swagger-ui details,.swagger-ui menu{display:block}.swagger-ui summary{display:list-item}.swagger-ui canvas{display:inline-block}.swagger-ui [hidden],.swagger-ui template{display:none}.swagger-ui .debug *{outline:1px solid gold}.swagger-ui .debug-white *{outline:1px solid #fff}.swagger-ui .debug-black *{outline:1px solid #000}.swagger-ui .debug-grid{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTRDOTY4N0U2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTRDOTY4N0Q2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3NjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3NzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsBS+GMAAAAjSURBVHjaYvz//z8DLsD4gcGXiYEAGBIKGBne//fFpwAgwAB98AaF2pjlUQAAAABJRU5ErkJggg==) repeat 0 0}.swagger-ui .debug-grid-16{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODYyRjhERDU2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODYyRjhERDQ2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QTY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3QjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvCS01IAAABMSURBVHjaYmR4/5+BFPBfAMFm/MBgx8RAGWCn1AAmSg34Q6kBDKMGMDCwICeMIemF/5QawEipAWwUhwEjMDvbAWlWkvVBwu8vQIABAEwBCph8U6c0AAAAAElFTkSuQmCC) repeat 0 0}.swagger-ui .debug-grid-8-solid{background:#fff url(data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAAAAD/4QMxaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzExMSA3OS4xNTgzMjUsIDIwMTUvMDkvMTAtMDE6MTA6MjAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIxMjI0OTczNjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIxMjI0OTc0NjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QjEyMjQ5NzE2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QjEyMjQ5NzI2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAbGhopHSlBJiZBQi8vL0JHPz4+P0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHAR0pKTQmND8oKD9HPzU/R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0f/wAARCAAIAAgDASIAAhEBAxEB/8QAWQABAQAAAAAAAAAAAAAAAAAAAAYBAQEAAAAAAAAAAAAAAAAAAAIEEAEBAAMBAAAAAAAAAAAAAAABADECA0ERAAEDBQAAAAAAAAAAAAAAAAARITFBUWESIv/aAAwDAQACEQMRAD8AoOnTV1QTD7JJshP3vSM3P//Z) repeat 0 0}.swagger-ui .debug-grid-16-solid{background:#fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzY3MkJEN0U2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzY3MkJEN0Y2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3RDY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pve6J3kAAAAzSURBVHjaYvz//z8D0UDsMwMjSRoYP5Gq4SPNbRjVMEQ1fCRDg+in/6+J1AJUxsgAEGAA31BAJMS0GYEAAAAASUVORK5CYII=) repeat 0 0}.swagger-ui .border-box,.swagger-ui a,.swagger-ui article,.swagger-ui body,.swagger-ui code,.swagger-ui dd,.swagger-ui div,.swagger-ui dl,.swagger-ui dt,.swagger-ui fieldset,.swagger-ui footer,.swagger-ui form,.swagger-ui h1,.swagger-ui h2,.swagger-ui h3,.swagger-ui h4,.swagger-ui h5,.swagger-ui h6,.swagger-ui header,.swagger-ui html,.swagger-ui input[type=email],.swagger-ui input[type=number],.swagger-ui input[type=password],.swagger-ui input[type=tel],.swagger-ui input[type=text],.swagger-ui input[type=url],.swagger-ui legend,.swagger-ui li,.swagger-ui main,.swagger-ui ol,.swagger-ui p,.swagger-ui pre,.swagger-ui section,.swagger-ui table,.swagger-ui td,.swagger-ui textarea,.swagger-ui th,.swagger-ui tr,.swagger-ui ul{box-sizing:border-box}.swagger-ui .aspect-ratio{height:0;position:relative}.swagger-ui .aspect-ratio--16x9{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1{padding-bottom:100%}.swagger-ui .aspect-ratio--object{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:100}@media screen and (min-width:30em){.swagger-ui .aspect-ratio-ns{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-ns{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-ns{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-ns{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-ns{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-ns{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-ns{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-ns{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-ns{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-ns{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-ns{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-ns{padding-bottom:100%}.swagger-ui .aspect-ratio--object-ns{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:100}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .aspect-ratio-m{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-m{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-m{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-m{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-m{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-m{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-m{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-m{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-m{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-m{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-m{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-m{padding-bottom:100%}.swagger-ui .aspect-ratio--object-m{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:100}}@media screen and (min-width:60em){.swagger-ui .aspect-ratio-l{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-l{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-l{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-l{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-l{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-l{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-l{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-l{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-l{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-l{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-l{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-l{padding-bottom:100%}.swagger-ui .aspect-ratio--object-l{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:100}}.swagger-ui img{max-width:100%}.swagger-ui .cover{background-size:cover!important}.swagger-ui .contain{background-size:contain!important}@media screen and (min-width:30em){.swagger-ui .cover-ns{background-size:cover!important}.swagger-ui .contain-ns{background-size:contain!important}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .cover-m{background-size:cover!important}.swagger-ui .contain-m{background-size:contain!important}}@media screen and (min-width:60em){.swagger-ui .cover-l{background-size:cover!important}.swagger-ui .contain-l{background-size:contain!important}}.swagger-ui .bg-center{background-position:50%;background-repeat:no-repeat}.swagger-ui .bg-top{background-position:top;background-repeat:no-repeat}.swagger-ui .bg-right{background-position:100%;background-repeat:no-repeat}.swagger-ui .bg-bottom{background-position:bottom;background-repeat:no-repeat}.swagger-ui .bg-left{background-position:0;background-repeat:no-repeat}@media screen and (min-width:30em){.swagger-ui .bg-center-ns{background-position:50%;background-repeat:no-repeat}.swagger-ui .bg-top-ns{background-position:top;background-repeat:no-repeat}.swagger-ui .bg-right-ns{background-position:100%;background-repeat:no-repeat}.swagger-ui .bg-bottom-ns{background-position:bottom;background-repeat:no-repeat}.swagger-ui .bg-left-ns{background-position:0;background-repeat:no-repeat}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .bg-center-m{background-position:50%;background-repeat:no-repeat}.swagger-ui .bg-top-m{background-position:top;background-repeat:no-repeat}.swagger-ui .bg-right-m{background-position:100%;background-repeat:no-repeat}.swagger-ui .bg-bottom-m{background-position:bottom;background-repeat:no-repeat}.swagger-ui .bg-left-m{background-position:0;background-repeat:no-repeat}}@media screen and (min-width:60em){.swagger-ui .bg-center-l{background-position:50%;background-repeat:no-repeat}.swagger-ui .bg-top-l{background-position:top;background-repeat:no-repeat}.swagger-ui .bg-right-l{background-position:100%;background-repeat:no-repeat}.swagger-ui .bg-bottom-l{background-position:bottom;background-repeat:no-repeat}.swagger-ui .bg-left-l{background-position:0;background-repeat:no-repeat}}.swagger-ui .outline{outline:1px solid}.swagger-ui .outline-transparent{outline:1px solid transparent}.swagger-ui .outline-0{outline:0}@media screen and (min-width:30em){.swagger-ui .outline-ns{outline:1px solid}.swagger-ui .outline-transparent-ns{outline:1px solid transparent}.swagger-ui .outline-0-ns{outline:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .outline-m{outline:1px solid}.swagger-ui .outline-transparent-m{outline:1px solid transparent}.swagger-ui .outline-0-m{outline:0}}@media screen and (min-width:60em){.swagger-ui .outline-l{outline:1px solid}.swagger-ui .outline-transparent-l{outline:1px solid transparent}.swagger-ui .outline-0-l{outline:0}}.swagger-ui .ba{border-style:solid;border-width:1px}.swagger-ui .bt{border-top-style:solid;border-top-width:1px}.swagger-ui .br{border-right-style:solid;border-right-width:1px}.swagger-ui .bb{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl{border-left-style:solid;border-left-width:1px}.swagger-ui .bn{border-style:none;border-width:0}@media screen and (min-width:30em){.swagger-ui .ba-ns{border-style:solid;border-width:1px}.swagger-ui .bt-ns{border-top-style:solid;border-top-width:1px}.swagger-ui .br-ns{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-ns{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-ns{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-ns{border-style:none;border-width:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .ba-m{border-style:solid;border-width:1px}.swagger-ui .bt-m{border-top-style:solid;border-top-width:1px}.swagger-ui .br-m{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-m{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-m{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-m{border-style:none;border-width:0}}@media screen and (min-width:60em){.swagger-ui .ba-l{border-style:solid;border-width:1px}.swagger-ui .bt-l{border-top-style:solid;border-top-width:1px}.swagger-ui .br-l{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-l{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-l{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-l{border-style:none;border-width:0}}.swagger-ui .b--black{border-color:#000}.swagger-ui .b--near-black{border-color:#111}.swagger-ui .b--dark-gray{border-color:#333}.swagger-ui .b--mid-gray{border-color:#555}.swagger-ui .b--gray{border-color:#777}.swagger-ui .b--silver{border-color:#999}.swagger-ui .b--light-silver{border-color:#aaa}.swagger-ui .b--moon-gray{border-color:#ccc}.swagger-ui .b--light-gray{border-color:#eee}.swagger-ui .b--near-white{border-color:#f4f4f4}.swagger-ui .b--white{border-color:#fff}.swagger-ui .b--white-90{border-color:hsla(0,0%,100%,.9)}.swagger-ui .b--white-80{border-color:hsla(0,0%,100%,.8)}.swagger-ui .b--white-70{border-color:hsla(0,0%,100%,.7)}.swagger-ui .b--white-60{border-color:hsla(0,0%,100%,.6)}.swagger-ui .b--white-50{border-color:hsla(0,0%,100%,.5)}.swagger-ui .b--white-40{border-color:hsla(0,0%,100%,.4)}.swagger-ui .b--white-30{border-color:hsla(0,0%,100%,.3)}.swagger-ui .b--white-20{border-color:hsla(0,0%,100%,.2)}.swagger-ui .b--white-10{border-color:hsla(0,0%,100%,.1)}.swagger-ui .b--white-05{border-color:hsla(0,0%,100%,.05)}.swagger-ui .b--white-025{border-color:hsla(0,0%,100%,.025)}.swagger-ui .b--white-0125{border-color:hsla(0,0%,100%,.013)}.swagger-ui .b--black-90{border-color:rgba(0,0,0,.9)}.swagger-ui .b--black-80{border-color:rgba(0,0,0,.8)}.swagger-ui .b--black-70{border-color:rgba(0,0,0,.7)}.swagger-ui .b--black-60{border-color:rgba(0,0,0,.6)}.swagger-ui .b--black-50{border-color:rgba(0,0,0,.5)}.swagger-ui .b--black-40{border-color:rgba(0,0,0,.4)}.swagger-ui .b--black-30{border-color:rgba(0,0,0,.3)}.swagger-ui .b--black-20{border-color:rgba(0,0,0,.2)}.swagger-ui .b--black-10{border-color:rgba(0,0,0,.1)}.swagger-ui .b--black-05{border-color:rgba(0,0,0,.05)}.swagger-ui .b--black-025{border-color:rgba(0,0,0,.025)}.swagger-ui .b--black-0125{border-color:rgba(0,0,0,.013)}.swagger-ui .b--dark-red{border-color:#e7040f}.swagger-ui .b--red{border-color:#ff4136}.swagger-ui .b--light-red{border-color:#ff725c}.swagger-ui .b--orange{border-color:#ff6300}.swagger-ui .b--gold{border-color:#ffb700}.swagger-ui .b--yellow{border-color:gold}.swagger-ui .b--light-yellow{border-color:#fbf1a9}.swagger-ui .b--purple{border-color:#5e2ca5}.swagger-ui .b--light-purple{border-color:#a463f2}.swagger-ui .b--dark-pink{border-color:#d5008f}.swagger-ui .b--hot-pink{border-color:#ff41b4}.swagger-ui .b--pink{border-color:#ff80cc}.swagger-ui .b--light-pink{border-color:#ffa3d7}.swagger-ui .b--dark-green{border-color:#137752}.swagger-ui .b--green{border-color:#19a974}.swagger-ui .b--light-green{border-color:#9eebcf}.swagger-ui .b--navy{border-color:#001b44}.swagger-ui .b--dark-blue{border-color:#00449e}.swagger-ui .b--blue{border-color:#357edd}.swagger-ui .b--light-blue{border-color:#96ccff}.swagger-ui .b--lightest-blue{border-color:#cdecff}.swagger-ui .b--washed-blue{border-color:#f6fffe}.swagger-ui .b--washed-green{border-color:#e8fdf5}.swagger-ui .b--washed-yellow{border-color:#fffceb}.swagger-ui .b--washed-red{border-color:#ffdfdf}.swagger-ui .b--transparent{border-color:transparent}.swagger-ui .b--inherit{border-color:inherit}.swagger-ui .br0{border-radius:0}.swagger-ui .br1{border-radius:.125rem}.swagger-ui .br2{border-radius:.25rem}.swagger-ui .br3{border-radius:.5rem}.swagger-ui .br4{border-radius:1rem}.swagger-ui .br-100{border-radius:100%}.swagger-ui .br-pill{border-radius:9999px}.swagger-ui .br--bottom{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right{border-bottom-left-radius:0;border-top-left-radius:0}.swagger-ui .br--left{border-bottom-right-radius:0;border-top-right-radius:0}@media screen and (min-width:30em){.swagger-ui .br0-ns{border-radius:0}.swagger-ui .br1-ns{border-radius:.125rem}.swagger-ui .br2-ns{border-radius:.25rem}.swagger-ui .br3-ns{border-radius:.5rem}.swagger-ui .br4-ns{border-radius:1rem}.swagger-ui .br-100-ns{border-radius:100%}.swagger-ui .br-pill-ns{border-radius:9999px}.swagger-ui .br--bottom-ns{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-ns{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-ns{border-bottom-left-radius:0;border-top-left-radius:0}.swagger-ui .br--left-ns{border-bottom-right-radius:0;border-top-right-radius:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .br0-m{border-radius:0}.swagger-ui .br1-m{border-radius:.125rem}.swagger-ui .br2-m{border-radius:.25rem}.swagger-ui .br3-m{border-radius:.5rem}.swagger-ui .br4-m{border-radius:1rem}.swagger-ui .br-100-m{border-radius:100%}.swagger-ui .br-pill-m{border-radius:9999px}.swagger-ui .br--bottom-m{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-m{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-m{border-bottom-left-radius:0;border-top-left-radius:0}.swagger-ui .br--left-m{border-bottom-right-radius:0;border-top-right-radius:0}}@media screen and (min-width:60em){.swagger-ui .br0-l{border-radius:0}.swagger-ui .br1-l{border-radius:.125rem}.swagger-ui .br2-l{border-radius:.25rem}.swagger-ui .br3-l{border-radius:.5rem}.swagger-ui .br4-l{border-radius:1rem}.swagger-ui .br-100-l{border-radius:100%}.swagger-ui .br-pill-l{border-radius:9999px}.swagger-ui .br--bottom-l{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-l{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-l{border-bottom-left-radius:0;border-top-left-radius:0}.swagger-ui .br--left-l{border-bottom-right-radius:0;border-top-right-radius:0}}.swagger-ui .b--dotted{border-style:dotted}.swagger-ui .b--dashed{border-style:dashed}.swagger-ui .b--solid{border-style:solid}.swagger-ui .b--none{border-style:none}@media screen and (min-width:30em){.swagger-ui .b--dotted-ns{border-style:dotted}.swagger-ui .b--dashed-ns{border-style:dashed}.swagger-ui .b--solid-ns{border-style:solid}.swagger-ui .b--none-ns{border-style:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .b--dotted-m{border-style:dotted}.swagger-ui .b--dashed-m{border-style:dashed}.swagger-ui .b--solid-m{border-style:solid}.swagger-ui .b--none-m{border-style:none}}@media screen and (min-width:60em){.swagger-ui .b--dotted-l{border-style:dotted}.swagger-ui .b--dashed-l{border-style:dashed}.swagger-ui .b--solid-l{border-style:solid}.swagger-ui .b--none-l{border-style:none}}.swagger-ui .bw0{border-width:0}.swagger-ui .bw1{border-width:.125rem}.swagger-ui .bw2{border-width:.25rem}.swagger-ui .bw3{border-width:.5rem}.swagger-ui .bw4{border-width:1rem}.swagger-ui .bw5{border-width:2rem}.swagger-ui .bt-0{border-top-width:0}.swagger-ui .br-0{border-right-width:0}.swagger-ui .bb-0{border-bottom-width:0}.swagger-ui .bl-0{border-left-width:0}@media screen and (min-width:30em){.swagger-ui .bw0-ns{border-width:0}.swagger-ui .bw1-ns{border-width:.125rem}.swagger-ui .bw2-ns{border-width:.25rem}.swagger-ui .bw3-ns{border-width:.5rem}.swagger-ui .bw4-ns{border-width:1rem}.swagger-ui .bw5-ns{border-width:2rem}.swagger-ui .bt-0-ns{border-top-width:0}.swagger-ui .br-0-ns{border-right-width:0}.swagger-ui .bb-0-ns{border-bottom-width:0}.swagger-ui .bl-0-ns{border-left-width:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .bw0-m{border-width:0}.swagger-ui .bw1-m{border-width:.125rem}.swagger-ui .bw2-m{border-width:.25rem}.swagger-ui .bw3-m{border-width:.5rem}.swagger-ui .bw4-m{border-width:1rem}.swagger-ui .bw5-m{border-width:2rem}.swagger-ui .bt-0-m{border-top-width:0}.swagger-ui .br-0-m{border-right-width:0}.swagger-ui .bb-0-m{border-bottom-width:0}.swagger-ui .bl-0-m{border-left-width:0}}@media screen and (min-width:60em){.swagger-ui .bw0-l{border-width:0}.swagger-ui .bw1-l{border-width:.125rem}.swagger-ui .bw2-l{border-width:.25rem}.swagger-ui .bw3-l{border-width:.5rem}.swagger-ui .bw4-l{border-width:1rem}.swagger-ui .bw5-l{border-width:2rem}.swagger-ui .bt-0-l{border-top-width:0}.swagger-ui .br-0-l{border-right-width:0}.swagger-ui .bb-0-l{border-bottom-width:0}.swagger-ui .bl-0-l{border-left-width:0}}.swagger-ui .shadow-1{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}@media screen and (min-width:30em){.swagger-ui .shadow-1-ns{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2-ns{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3-ns{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4-ns{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5-ns{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .shadow-1-m{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2-m{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3-m{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4-m{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5-m{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}@media screen and (min-width:60em){.swagger-ui .shadow-1-l{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2-l{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3-l{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4-l{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5-l{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}.swagger-ui .pre{overflow-x:auto;overflow-y:hidden;overflow:scroll}.swagger-ui .top-0{top:0}.swagger-ui .right-0{right:0}.swagger-ui .bottom-0{bottom:0}.swagger-ui .left-0{left:0}.swagger-ui .top-1{top:1rem}.swagger-ui .right-1{right:1rem}.swagger-ui .bottom-1{bottom:1rem}.swagger-ui .left-1{left:1rem}.swagger-ui .top-2{top:2rem}.swagger-ui .right-2{right:2rem}.swagger-ui .bottom-2{bottom:2rem}.swagger-ui .left-2{left:2rem}.swagger-ui .top--1{top:-1rem}.swagger-ui .right--1{right:-1rem}.swagger-ui .bottom--1{bottom:-1rem}.swagger-ui .left--1{left:-1rem}.swagger-ui .top--2{top:-2rem}.swagger-ui .right--2{right:-2rem}.swagger-ui .bottom--2{bottom:-2rem}.swagger-ui .left--2{left:-2rem}.swagger-ui .absolute--fill{bottom:0;left:0;right:0;top:0}@media screen and (min-width:30em){.swagger-ui .top-0-ns{top:0}.swagger-ui .left-0-ns{left:0}.swagger-ui .right-0-ns{right:0}.swagger-ui .bottom-0-ns{bottom:0}.swagger-ui .top-1-ns{top:1rem}.swagger-ui .left-1-ns{left:1rem}.swagger-ui .right-1-ns{right:1rem}.swagger-ui .bottom-1-ns{bottom:1rem}.swagger-ui .top-2-ns{top:2rem}.swagger-ui .left-2-ns{left:2rem}.swagger-ui .right-2-ns{right:2rem}.swagger-ui .bottom-2-ns{bottom:2rem}.swagger-ui .top--1-ns{top:-1rem}.swagger-ui .right--1-ns{right:-1rem}.swagger-ui .bottom--1-ns{bottom:-1rem}.swagger-ui .left--1-ns{left:-1rem}.swagger-ui .top--2-ns{top:-2rem}.swagger-ui .right--2-ns{right:-2rem}.swagger-ui .bottom--2-ns{bottom:-2rem}.swagger-ui .left--2-ns{left:-2rem}.swagger-ui .absolute--fill-ns{bottom:0;left:0;right:0;top:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .top-0-m{top:0}.swagger-ui .left-0-m{left:0}.swagger-ui .right-0-m{right:0}.swagger-ui .bottom-0-m{bottom:0}.swagger-ui .top-1-m{top:1rem}.swagger-ui .left-1-m{left:1rem}.swagger-ui .right-1-m{right:1rem}.swagger-ui .bottom-1-m{bottom:1rem}.swagger-ui .top-2-m{top:2rem}.swagger-ui .left-2-m{left:2rem}.swagger-ui .right-2-m{right:2rem}.swagger-ui .bottom-2-m{bottom:2rem}.swagger-ui .top--1-m{top:-1rem}.swagger-ui .right--1-m{right:-1rem}.swagger-ui .bottom--1-m{bottom:-1rem}.swagger-ui .left--1-m{left:-1rem}.swagger-ui .top--2-m{top:-2rem}.swagger-ui .right--2-m{right:-2rem}.swagger-ui .bottom--2-m{bottom:-2rem}.swagger-ui .left--2-m{left:-2rem}.swagger-ui .absolute--fill-m{bottom:0;left:0;right:0;top:0}}@media screen and (min-width:60em){.swagger-ui .top-0-l{top:0}.swagger-ui .left-0-l{left:0}.swagger-ui .right-0-l{right:0}.swagger-ui .bottom-0-l{bottom:0}.swagger-ui .top-1-l{top:1rem}.swagger-ui .left-1-l{left:1rem}.swagger-ui .right-1-l{right:1rem}.swagger-ui .bottom-1-l{bottom:1rem}.swagger-ui .top-2-l{top:2rem}.swagger-ui .left-2-l{left:2rem}.swagger-ui .right-2-l{right:2rem}.swagger-ui .bottom-2-l{bottom:2rem}.swagger-ui .top--1-l{top:-1rem}.swagger-ui .right--1-l{right:-1rem}.swagger-ui .bottom--1-l{bottom:-1rem}.swagger-ui .left--1-l{left:-1rem}.swagger-ui .top--2-l{top:-2rem}.swagger-ui .right--2-l{right:-2rem}.swagger-ui .bottom--2-l{bottom:-2rem}.swagger-ui .left--2-l{left:-2rem}.swagger-ui .absolute--fill-l{bottom:0;left:0;right:0;top:0}}.swagger-ui .cf:after,.swagger-ui .cf:before{content:" ";display:table}.swagger-ui .cf:after{clear:both}.swagger-ui .cf{*zoom:1}.swagger-ui .cl{clear:left}.swagger-ui .cr{clear:right}.swagger-ui .cb{clear:both}.swagger-ui .cn{clear:none}@media screen and (min-width:30em){.swagger-ui .cl-ns{clear:left}.swagger-ui .cr-ns{clear:right}.swagger-ui .cb-ns{clear:both}.swagger-ui .cn-ns{clear:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .cl-m{clear:left}.swagger-ui .cr-m{clear:right}.swagger-ui .cb-m{clear:both}.swagger-ui .cn-m{clear:none}}@media screen and (min-width:60em){.swagger-ui .cl-l{clear:left}.swagger-ui .cr-l{clear:right}.swagger-ui .cb-l{clear:both}.swagger-ui .cn-l{clear:none}}.swagger-ui .flex{display:flex}.swagger-ui .inline-flex{display:inline-flex}.swagger-ui .flex-auto{flex:1 1 auto;min-height:0;min-width:0}.swagger-ui .flex-none{flex:none}.swagger-ui .flex-column{flex-direction:column}.swagger-ui .flex-row{flex-direction:row}.swagger-ui .flex-wrap{flex-wrap:wrap}.swagger-ui .flex-nowrap{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse{flex-direction:column-reverse}.swagger-ui .flex-row-reverse{flex-direction:row-reverse}.swagger-ui .items-start{align-items:flex-start}.swagger-ui .items-end{align-items:flex-end}.swagger-ui .items-center{align-items:center}.swagger-ui .items-baseline{align-items:baseline}.swagger-ui .items-stretch{align-items:stretch}.swagger-ui .self-start{align-self:flex-start}.swagger-ui .self-end{align-self:flex-end}.swagger-ui .self-center{align-self:center}.swagger-ui .self-baseline{align-self:baseline}.swagger-ui .self-stretch{align-self:stretch}.swagger-ui .justify-start{justify-content:flex-start}.swagger-ui .justify-end{justify-content:flex-end}.swagger-ui .justify-center{justify-content:center}.swagger-ui .justify-between{justify-content:space-between}.swagger-ui .justify-around{justify-content:space-around}.swagger-ui .content-start{align-content:flex-start}.swagger-ui .content-end{align-content:flex-end}.swagger-ui .content-center{align-content:center}.swagger-ui .content-between{align-content:space-between}.swagger-ui .content-around{align-content:space-around}.swagger-ui .content-stretch{align-content:stretch}.swagger-ui .order-0{order:0}.swagger-ui .order-1{order:1}.swagger-ui .order-2{order:2}.swagger-ui .order-3{order:3}.swagger-ui .order-4{order:4}.swagger-ui .order-5{order:5}.swagger-ui .order-6{order:6}.swagger-ui .order-7{order:7}.swagger-ui .order-8{order:8}.swagger-ui .order-last{order:99999}.swagger-ui .flex-grow-0{flex-grow:0}.swagger-ui .flex-grow-1{flex-grow:1}.swagger-ui .flex-shrink-0{flex-shrink:0}.swagger-ui .flex-shrink-1{flex-shrink:1}@media screen and (min-width:30em){.swagger-ui .flex-ns{display:flex}.swagger-ui .inline-flex-ns{display:inline-flex}.swagger-ui .flex-auto-ns{flex:1 1 auto;min-height:0;min-width:0}.swagger-ui .flex-none-ns{flex:none}.swagger-ui .flex-column-ns{flex-direction:column}.swagger-ui .flex-row-ns{flex-direction:row}.swagger-ui .flex-wrap-ns{flex-wrap:wrap}.swagger-ui .flex-nowrap-ns{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-ns{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-ns{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-ns{flex-direction:row-reverse}.swagger-ui .items-start-ns{align-items:flex-start}.swagger-ui .items-end-ns{align-items:flex-end}.swagger-ui .items-center-ns{align-items:center}.swagger-ui .items-baseline-ns{align-items:baseline}.swagger-ui .items-stretch-ns{align-items:stretch}.swagger-ui .self-start-ns{align-self:flex-start}.swagger-ui .self-end-ns{align-self:flex-end}.swagger-ui .self-center-ns{align-self:center}.swagger-ui .self-baseline-ns{align-self:baseline}.swagger-ui .self-stretch-ns{align-self:stretch}.swagger-ui .justify-start-ns{justify-content:flex-start}.swagger-ui .justify-end-ns{justify-content:flex-end}.swagger-ui .justify-center-ns{justify-content:center}.swagger-ui .justify-between-ns{justify-content:space-between}.swagger-ui .justify-around-ns{justify-content:space-around}.swagger-ui .content-start-ns{align-content:flex-start}.swagger-ui .content-end-ns{align-content:flex-end}.swagger-ui .content-center-ns{align-content:center}.swagger-ui .content-between-ns{align-content:space-between}.swagger-ui .content-around-ns{align-content:space-around}.swagger-ui .content-stretch-ns{align-content:stretch}.swagger-ui .order-0-ns{order:0}.swagger-ui .order-1-ns{order:1}.swagger-ui .order-2-ns{order:2}.swagger-ui .order-3-ns{order:3}.swagger-ui .order-4-ns{order:4}.swagger-ui .order-5-ns{order:5}.swagger-ui .order-6-ns{order:6}.swagger-ui .order-7-ns{order:7}.swagger-ui .order-8-ns{order:8}.swagger-ui .order-last-ns{order:99999}.swagger-ui .flex-grow-0-ns{flex-grow:0}.swagger-ui .flex-grow-1-ns{flex-grow:1}.swagger-ui .flex-shrink-0-ns{flex-shrink:0}.swagger-ui .flex-shrink-1-ns{flex-shrink:1}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .flex-m{display:flex}.swagger-ui .inline-flex-m{display:inline-flex}.swagger-ui .flex-auto-m{flex:1 1 auto;min-height:0;min-width:0}.swagger-ui .flex-none-m{flex:none}.swagger-ui .flex-column-m{flex-direction:column}.swagger-ui .flex-row-m{flex-direction:row}.swagger-ui .flex-wrap-m{flex-wrap:wrap}.swagger-ui .flex-nowrap-m{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-m{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-m{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-m{flex-direction:row-reverse}.swagger-ui .items-start-m{align-items:flex-start}.swagger-ui .items-end-m{align-items:flex-end}.swagger-ui .items-center-m{align-items:center}.swagger-ui .items-baseline-m{align-items:baseline}.swagger-ui .items-stretch-m{align-items:stretch}.swagger-ui .self-start-m{align-self:flex-start}.swagger-ui .self-end-m{align-self:flex-end}.swagger-ui .self-center-m{align-self:center}.swagger-ui .self-baseline-m{align-self:baseline}.swagger-ui .self-stretch-m{align-self:stretch}.swagger-ui .justify-start-m{justify-content:flex-start}.swagger-ui .justify-end-m{justify-content:flex-end}.swagger-ui .justify-center-m{justify-content:center}.swagger-ui .justify-between-m{justify-content:space-between}.swagger-ui .justify-around-m{justify-content:space-around}.swagger-ui .content-start-m{align-content:flex-start}.swagger-ui .content-end-m{align-content:flex-end}.swagger-ui .content-center-m{align-content:center}.swagger-ui .content-between-m{align-content:space-between}.swagger-ui .content-around-m{align-content:space-around}.swagger-ui .content-stretch-m{align-content:stretch}.swagger-ui .order-0-m{order:0}.swagger-ui .order-1-m{order:1}.swagger-ui .order-2-m{order:2}.swagger-ui .order-3-m{order:3}.swagger-ui .order-4-m{order:4}.swagger-ui .order-5-m{order:5}.swagger-ui .order-6-m{order:6}.swagger-ui .order-7-m{order:7}.swagger-ui .order-8-m{order:8}.swagger-ui .order-last-m{order:99999}.swagger-ui .flex-grow-0-m{flex-grow:0}.swagger-ui .flex-grow-1-m{flex-grow:1}.swagger-ui .flex-shrink-0-m{flex-shrink:0}.swagger-ui .flex-shrink-1-m{flex-shrink:1}}@media screen and (min-width:60em){.swagger-ui .flex-l{display:flex}.swagger-ui .inline-flex-l{display:inline-flex}.swagger-ui .flex-auto-l{flex:1 1 auto;min-height:0;min-width:0}.swagger-ui .flex-none-l{flex:none}.swagger-ui .flex-column-l{flex-direction:column}.swagger-ui .flex-row-l{flex-direction:row}.swagger-ui .flex-wrap-l{flex-wrap:wrap}.swagger-ui .flex-nowrap-l{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-l{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-l{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-l{flex-direction:row-reverse}.swagger-ui .items-start-l{align-items:flex-start}.swagger-ui .items-end-l{align-items:flex-end}.swagger-ui .items-center-l{align-items:center}.swagger-ui .items-baseline-l{align-items:baseline}.swagger-ui .items-stretch-l{align-items:stretch}.swagger-ui .self-start-l{align-self:flex-start}.swagger-ui .self-end-l{align-self:flex-end}.swagger-ui .self-center-l{align-self:center}.swagger-ui .self-baseline-l{align-self:baseline}.swagger-ui .self-stretch-l{align-self:stretch}.swagger-ui .justify-start-l{justify-content:flex-start}.swagger-ui .justify-end-l{justify-content:flex-end}.swagger-ui .justify-center-l{justify-content:center}.swagger-ui .justify-between-l{justify-content:space-between}.swagger-ui .justify-around-l{justify-content:space-around}.swagger-ui .content-start-l{align-content:flex-start}.swagger-ui .content-end-l{align-content:flex-end}.swagger-ui .content-center-l{align-content:center}.swagger-ui .content-between-l{align-content:space-between}.swagger-ui .content-around-l{align-content:space-around}.swagger-ui .content-stretch-l{align-content:stretch}.swagger-ui .order-0-l{order:0}.swagger-ui .order-1-l{order:1}.swagger-ui .order-2-l{order:2}.swagger-ui .order-3-l{order:3}.swagger-ui .order-4-l{order:4}.swagger-ui .order-5-l{order:5}.swagger-ui .order-6-l{order:6}.swagger-ui .order-7-l{order:7}.swagger-ui .order-8-l{order:8}.swagger-ui .order-last-l{order:99999}.swagger-ui .flex-grow-0-l{flex-grow:0}.swagger-ui .flex-grow-1-l{flex-grow:1}.swagger-ui .flex-shrink-0-l{flex-shrink:0}.swagger-ui .flex-shrink-1-l{flex-shrink:1}}.swagger-ui .dn{display:none}.swagger-ui .di{display:inline}.swagger-ui .db{display:block}.swagger-ui .dib{display:inline-block}.swagger-ui .dit{display:inline-table}.swagger-ui .dt{display:table}.swagger-ui .dtc{display:table-cell}.swagger-ui .dt-row{display:table-row}.swagger-ui .dt-row-group{display:table-row-group}.swagger-ui .dt-column{display:table-column}.swagger-ui .dt-column-group{display:table-column-group}.swagger-ui .dt--fixed{table-layout:fixed;width:100%}@media screen and (min-width:30em){.swagger-ui .dn-ns{display:none}.swagger-ui .di-ns{display:inline}.swagger-ui .db-ns{display:block}.swagger-ui .dib-ns{display:inline-block}.swagger-ui .dit-ns{display:inline-table}.swagger-ui .dt-ns{display:table}.swagger-ui .dtc-ns{display:table-cell}.swagger-ui .dt-row-ns{display:table-row}.swagger-ui .dt-row-group-ns{display:table-row-group}.swagger-ui .dt-column-ns{display:table-column}.swagger-ui .dt-column-group-ns{display:table-column-group}.swagger-ui .dt--fixed-ns{table-layout:fixed;width:100%}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .dn-m{display:none}.swagger-ui .di-m{display:inline}.swagger-ui .db-m{display:block}.swagger-ui .dib-m{display:inline-block}.swagger-ui .dit-m{display:inline-table}.swagger-ui .dt-m{display:table}.swagger-ui .dtc-m{display:table-cell}.swagger-ui .dt-row-m{display:table-row}.swagger-ui .dt-row-group-m{display:table-row-group}.swagger-ui .dt-column-m{display:table-column}.swagger-ui .dt-column-group-m{display:table-column-group}.swagger-ui .dt--fixed-m{table-layout:fixed;width:100%}}@media screen and (min-width:60em){.swagger-ui .dn-l{display:none}.swagger-ui .di-l{display:inline}.swagger-ui .db-l{display:block}.swagger-ui .dib-l{display:inline-block}.swagger-ui .dit-l{display:inline-table}.swagger-ui .dt-l{display:table}.swagger-ui .dtc-l{display:table-cell}.swagger-ui .dt-row-l{display:table-row}.swagger-ui .dt-row-group-l{display:table-row-group}.swagger-ui .dt-column-l{display:table-column}.swagger-ui .dt-column-group-l{display:table-column-group}.swagger-ui .dt--fixed-l{table-layout:fixed;width:100%}}.swagger-ui .fl{_display:inline;float:left}.swagger-ui .fr{_display:inline;float:right}.swagger-ui .fn{float:none}@media screen and (min-width:30em){.swagger-ui .fl-ns{_display:inline;float:left}.swagger-ui .fr-ns{_display:inline;float:right}.swagger-ui .fn-ns{float:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .fl-m{_display:inline;float:left}.swagger-ui .fr-m{_display:inline;float:right}.swagger-ui .fn-m{float:none}}@media screen and (min-width:60em){.swagger-ui .fl-l{_display:inline;float:left}.swagger-ui .fr-l{_display:inline;float:right}.swagger-ui .fn-l{float:none}}.swagger-ui .sans-serif{font-family:-apple-system,BlinkMacSystemFont,avenir next,avenir,helvetica,helvetica neue,ubuntu,roboto,noto,segoe ui,arial,sans-serif}.swagger-ui .serif{font-family:georgia,serif}.swagger-ui .system-sans-serif{font-family:sans-serif}.swagger-ui .system-serif{font-family:serif}.swagger-ui .code,.swagger-ui code{font-family:Consolas,monaco,monospace}.swagger-ui .courier{font-family:Courier Next,courier,monospace}.swagger-ui .helvetica{font-family:helvetica neue,helvetica,sans-serif}.swagger-ui .avenir{font-family:avenir next,avenir,sans-serif}.swagger-ui .athelas{font-family:athelas,georgia,serif}.swagger-ui .georgia{font-family:georgia,serif}.swagger-ui .times{font-family:times,serif}.swagger-ui .bodoni{font-family:Bodoni MT,serif}.swagger-ui .calisto{font-family:Calisto MT,serif}.swagger-ui .garamond{font-family:garamond,serif}.swagger-ui .baskerville{font-family:baskerville,serif}.swagger-ui .i{font-style:italic}.swagger-ui .fs-normal{font-style:normal}@media screen and (min-width:30em){.swagger-ui .i-ns{font-style:italic}.swagger-ui .fs-normal-ns{font-style:normal}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .i-m{font-style:italic}.swagger-ui .fs-normal-m{font-style:normal}}@media screen and (min-width:60em){.swagger-ui .i-l{font-style:italic}.swagger-ui .fs-normal-l{font-style:normal}}.swagger-ui .normal{font-weight:400}.swagger-ui .b{font-weight:700}.swagger-ui .fw1{font-weight:100}.swagger-ui .fw2{font-weight:200}.swagger-ui .fw3{font-weight:300}.swagger-ui .fw4{font-weight:400}.swagger-ui .fw5{font-weight:500}.swagger-ui .fw6{font-weight:600}.swagger-ui .fw7{font-weight:700}.swagger-ui .fw8{font-weight:800}.swagger-ui .fw9{font-weight:900}@media screen and (min-width:30em){.swagger-ui .normal-ns{font-weight:400}.swagger-ui .b-ns{font-weight:700}.swagger-ui .fw1-ns{font-weight:100}.swagger-ui .fw2-ns{font-weight:200}.swagger-ui .fw3-ns{font-weight:300}.swagger-ui .fw4-ns{font-weight:400}.swagger-ui .fw5-ns{font-weight:500}.swagger-ui .fw6-ns{font-weight:600}.swagger-ui .fw7-ns{font-weight:700}.swagger-ui .fw8-ns{font-weight:800}.swagger-ui .fw9-ns{font-weight:900}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .normal-m{font-weight:400}.swagger-ui .b-m{font-weight:700}.swagger-ui .fw1-m{font-weight:100}.swagger-ui .fw2-m{font-weight:200}.swagger-ui .fw3-m{font-weight:300}.swagger-ui .fw4-m{font-weight:400}.swagger-ui .fw5-m{font-weight:500}.swagger-ui .fw6-m{font-weight:600}.swagger-ui .fw7-m{font-weight:700}.swagger-ui .fw8-m{font-weight:800}.swagger-ui .fw9-m{font-weight:900}}@media screen and (min-width:60em){.swagger-ui .normal-l{font-weight:400}.swagger-ui .b-l{font-weight:700}.swagger-ui .fw1-l{font-weight:100}.swagger-ui .fw2-l{font-weight:200}.swagger-ui .fw3-l{font-weight:300}.swagger-ui .fw4-l{font-weight:400}.swagger-ui .fw5-l{font-weight:500}.swagger-ui .fw6-l{font-weight:600}.swagger-ui .fw7-l{font-weight:700}.swagger-ui .fw8-l{font-weight:800}.swagger-ui .fw9-l{font-weight:900}}.swagger-ui .input-reset{-webkit-appearance:none;-moz-appearance:none}.swagger-ui .button-reset::-moz-focus-inner,.swagger-ui .input-reset::-moz-focus-inner{border:0;padding:0}.swagger-ui .h1{height:1rem}.swagger-ui .h2{height:2rem}.swagger-ui .h3{height:4rem}.swagger-ui .h4{height:8rem}.swagger-ui .h5{height:16rem}.swagger-ui .h-25{height:25%}.swagger-ui .h-50{height:50%}.swagger-ui .h-75{height:75%}.swagger-ui .h-100{height:100%}.swagger-ui .min-h-100{min-height:100%}.swagger-ui .vh-25{height:25vh}.swagger-ui .vh-50{height:50vh}.swagger-ui .vh-75{height:75vh}.swagger-ui .vh-100{height:100vh}.swagger-ui .min-vh-100{min-height:100vh}.swagger-ui .h-auto{height:auto}.swagger-ui .h-inherit{height:inherit}@media screen and (min-width:30em){.swagger-ui .h1-ns{height:1rem}.swagger-ui .h2-ns{height:2rem}.swagger-ui .h3-ns{height:4rem}.swagger-ui .h4-ns{height:8rem}.swagger-ui .h5-ns{height:16rem}.swagger-ui .h-25-ns{height:25%}.swagger-ui .h-50-ns{height:50%}.swagger-ui .h-75-ns{height:75%}.swagger-ui .h-100-ns{height:100%}.swagger-ui .min-h-100-ns{min-height:100%}.swagger-ui .vh-25-ns{height:25vh}.swagger-ui .vh-50-ns{height:50vh}.swagger-ui .vh-75-ns{height:75vh}.swagger-ui .vh-100-ns{height:100vh}.swagger-ui .min-vh-100-ns{min-height:100vh}.swagger-ui .h-auto-ns{height:auto}.swagger-ui .h-inherit-ns{height:inherit}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .h1-m{height:1rem}.swagger-ui .h2-m{height:2rem}.swagger-ui .h3-m{height:4rem}.swagger-ui .h4-m{height:8rem}.swagger-ui .h5-m{height:16rem}.swagger-ui .h-25-m{height:25%}.swagger-ui .h-50-m{height:50%}.swagger-ui .h-75-m{height:75%}.swagger-ui .h-100-m{height:100%}.swagger-ui .min-h-100-m{min-height:100%}.swagger-ui .vh-25-m{height:25vh}.swagger-ui .vh-50-m{height:50vh}.swagger-ui .vh-75-m{height:75vh}.swagger-ui .vh-100-m{height:100vh}.swagger-ui .min-vh-100-m{min-height:100vh}.swagger-ui .h-auto-m{height:auto}.swagger-ui .h-inherit-m{height:inherit}}@media screen and (min-width:60em){.swagger-ui .h1-l{height:1rem}.swagger-ui .h2-l{height:2rem}.swagger-ui .h3-l{height:4rem}.swagger-ui .h4-l{height:8rem}.swagger-ui .h5-l{height:16rem}.swagger-ui .h-25-l{height:25%}.swagger-ui .h-50-l{height:50%}.swagger-ui .h-75-l{height:75%}.swagger-ui .h-100-l{height:100%}.swagger-ui .min-h-100-l{min-height:100%}.swagger-ui .vh-25-l{height:25vh}.swagger-ui .vh-50-l{height:50vh}.swagger-ui .vh-75-l{height:75vh}.swagger-ui .vh-100-l{height:100vh}.swagger-ui .min-vh-100-l{min-height:100vh}.swagger-ui .h-auto-l{height:auto}.swagger-ui .h-inherit-l{height:inherit}}.swagger-ui .tracked{letter-spacing:.1em}.swagger-ui .tracked-tight{letter-spacing:-.05em}.swagger-ui .tracked-mega{letter-spacing:.25em}@media screen and (min-width:30em){.swagger-ui .tracked-ns{letter-spacing:.1em}.swagger-ui .tracked-tight-ns{letter-spacing:-.05em}.swagger-ui .tracked-mega-ns{letter-spacing:.25em}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .tracked-m{letter-spacing:.1em}.swagger-ui .tracked-tight-m{letter-spacing:-.05em}.swagger-ui .tracked-mega-m{letter-spacing:.25em}}@media screen and (min-width:60em){.swagger-ui .tracked-l{letter-spacing:.1em}.swagger-ui .tracked-tight-l{letter-spacing:-.05em}.swagger-ui .tracked-mega-l{letter-spacing:.25em}}.swagger-ui .lh-solid{line-height:1}.swagger-ui .lh-title{line-height:1.25}.swagger-ui .lh-copy{line-height:1.5}@media screen and (min-width:30em){.swagger-ui .lh-solid-ns{line-height:1}.swagger-ui .lh-title-ns{line-height:1.25}.swagger-ui .lh-copy-ns{line-height:1.5}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .lh-solid-m{line-height:1}.swagger-ui .lh-title-m{line-height:1.25}.swagger-ui .lh-copy-m{line-height:1.5}}@media screen and (min-width:60em){.swagger-ui .lh-solid-l{line-height:1}.swagger-ui .lh-title-l{line-height:1.25}.swagger-ui .lh-copy-l{line-height:1.5}}.swagger-ui .link{text-decoration:none}.swagger-ui .link,.swagger-ui .link:active,.swagger-ui .link:focus,.swagger-ui .link:hover,.swagger-ui .link:link,.swagger-ui .link:visited{transition:color .15s ease-in}.swagger-ui .link:focus{outline:1px dotted currentColor}.swagger-ui .list{list-style-type:none}.swagger-ui .mw-100{max-width:100%}.swagger-ui .mw1{max-width:1rem}.swagger-ui .mw2{max-width:2rem}.swagger-ui .mw3{max-width:4rem}.swagger-ui .mw4{max-width:8rem}.swagger-ui .mw5{max-width:16rem}.swagger-ui .mw6{max-width:32rem}.swagger-ui .mw7{max-width:48rem}.swagger-ui .mw8{max-width:64rem}.swagger-ui .mw9{max-width:96rem}.swagger-ui .mw-none{max-width:none}@media screen and (min-width:30em){.swagger-ui .mw-100-ns{max-width:100%}.swagger-ui .mw1-ns{max-width:1rem}.swagger-ui .mw2-ns{max-width:2rem}.swagger-ui .mw3-ns{max-width:4rem}.swagger-ui .mw4-ns{max-width:8rem}.swagger-ui .mw5-ns{max-width:16rem}.swagger-ui .mw6-ns{max-width:32rem}.swagger-ui .mw7-ns{max-width:48rem}.swagger-ui .mw8-ns{max-width:64rem}.swagger-ui .mw9-ns{max-width:96rem}.swagger-ui .mw-none-ns{max-width:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .mw-100-m{max-width:100%}.swagger-ui .mw1-m{max-width:1rem}.swagger-ui .mw2-m{max-width:2rem}.swagger-ui .mw3-m{max-width:4rem}.swagger-ui .mw4-m{max-width:8rem}.swagger-ui .mw5-m{max-width:16rem}.swagger-ui .mw6-m{max-width:32rem}.swagger-ui .mw7-m{max-width:48rem}.swagger-ui .mw8-m{max-width:64rem}.swagger-ui .mw9-m{max-width:96rem}.swagger-ui .mw-none-m{max-width:none}}@media screen and (min-width:60em){.swagger-ui .mw-100-l{max-width:100%}.swagger-ui .mw1-l{max-width:1rem}.swagger-ui .mw2-l{max-width:2rem}.swagger-ui .mw3-l{max-width:4rem}.swagger-ui .mw4-l{max-width:8rem}.swagger-ui .mw5-l{max-width:16rem}.swagger-ui .mw6-l{max-width:32rem}.swagger-ui .mw7-l{max-width:48rem}.swagger-ui .mw8-l{max-width:64rem}.swagger-ui .mw9-l{max-width:96rem}.swagger-ui .mw-none-l{max-width:none}}.swagger-ui .w1{width:1rem}.swagger-ui .w2{width:2rem}.swagger-ui .w3{width:4rem}.swagger-ui .w4{width:8rem}.swagger-ui .w5{width:16rem}.swagger-ui .w-10{width:10%}.swagger-ui .w-20{width:20%}.swagger-ui .w-25{width:25%}.swagger-ui .w-30{width:30%}.swagger-ui .w-33{width:33%}.swagger-ui .w-34{width:34%}.swagger-ui .w-40{width:40%}.swagger-ui .w-50{width:50%}.swagger-ui .w-60{width:60%}.swagger-ui .w-70{width:70%}.swagger-ui .w-75{width:75%}.swagger-ui .w-80{width:80%}.swagger-ui .w-90{width:90%}.swagger-ui .w-100{width:100%}.swagger-ui .w-third{width:33.3333333333%}.swagger-ui .w-two-thirds{width:66.6666666667%}.swagger-ui .w-auto{width:auto}@media screen and (min-width:30em){.swagger-ui .w1-ns{width:1rem}.swagger-ui .w2-ns{width:2rem}.swagger-ui .w3-ns{width:4rem}.swagger-ui .w4-ns{width:8rem}.swagger-ui .w5-ns{width:16rem}.swagger-ui .w-10-ns{width:10%}.swagger-ui .w-20-ns{width:20%}.swagger-ui .w-25-ns{width:25%}.swagger-ui .w-30-ns{width:30%}.swagger-ui .w-33-ns{width:33%}.swagger-ui .w-34-ns{width:34%}.swagger-ui .w-40-ns{width:40%}.swagger-ui .w-50-ns{width:50%}.swagger-ui .w-60-ns{width:60%}.swagger-ui .w-70-ns{width:70%}.swagger-ui .w-75-ns{width:75%}.swagger-ui .w-80-ns{width:80%}.swagger-ui .w-90-ns{width:90%}.swagger-ui .w-100-ns{width:100%}.swagger-ui .w-third-ns{width:33.3333333333%}.swagger-ui .w-two-thirds-ns{width:66.6666666667%}.swagger-ui .w-auto-ns{width:auto}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .w1-m{width:1rem}.swagger-ui .w2-m{width:2rem}.swagger-ui .w3-m{width:4rem}.swagger-ui .w4-m{width:8rem}.swagger-ui .w5-m{width:16rem}.swagger-ui .w-10-m{width:10%}.swagger-ui .w-20-m{width:20%}.swagger-ui .w-25-m{width:25%}.swagger-ui .w-30-m{width:30%}.swagger-ui .w-33-m{width:33%}.swagger-ui .w-34-m{width:34%}.swagger-ui .w-40-m{width:40%}.swagger-ui .w-50-m{width:50%}.swagger-ui .w-60-m{width:60%}.swagger-ui .w-70-m{width:70%}.swagger-ui .w-75-m{width:75%}.swagger-ui .w-80-m{width:80%}.swagger-ui .w-90-m{width:90%}.swagger-ui .w-100-m{width:100%}.swagger-ui .w-third-m{width:33.3333333333%}.swagger-ui .w-two-thirds-m{width:66.6666666667%}.swagger-ui .w-auto-m{width:auto}}@media screen and (min-width:60em){.swagger-ui .w1-l{width:1rem}.swagger-ui .w2-l{width:2rem}.swagger-ui .w3-l{width:4rem}.swagger-ui .w4-l{width:8rem}.swagger-ui .w5-l{width:16rem}.swagger-ui .w-10-l{width:10%}.swagger-ui .w-20-l{width:20%}.swagger-ui .w-25-l{width:25%}.swagger-ui .w-30-l{width:30%}.swagger-ui .w-33-l{width:33%}.swagger-ui .w-34-l{width:34%}.swagger-ui .w-40-l{width:40%}.swagger-ui .w-50-l{width:50%}.swagger-ui .w-60-l{width:60%}.swagger-ui .w-70-l{width:70%}.swagger-ui .w-75-l{width:75%}.swagger-ui .w-80-l{width:80%}.swagger-ui .w-90-l{width:90%}.swagger-ui .w-100-l{width:100%}.swagger-ui .w-third-l{width:33.3333333333%}.swagger-ui .w-two-thirds-l{width:66.6666666667%}.swagger-ui .w-auto-l{width:auto}}.swagger-ui .overflow-visible{overflow:visible}.swagger-ui .overflow-hidden{overflow:hidden}.swagger-ui .overflow-scroll{overflow:scroll}.swagger-ui .overflow-auto{overflow:auto}.swagger-ui .overflow-x-visible{overflow-x:visible}.swagger-ui .overflow-x-hidden{overflow-x:hidden}.swagger-ui .overflow-x-scroll{overflow-x:scroll}.swagger-ui .overflow-x-auto{overflow-x:auto}.swagger-ui .overflow-y-visible{overflow-y:visible}.swagger-ui .overflow-y-hidden{overflow-y:hidden}.swagger-ui .overflow-y-scroll{overflow-y:scroll}.swagger-ui .overflow-y-auto{overflow-y:auto}@media screen and (min-width:30em){.swagger-ui .overflow-visible-ns{overflow:visible}.swagger-ui .overflow-hidden-ns{overflow:hidden}.swagger-ui .overflow-scroll-ns{overflow:scroll}.swagger-ui .overflow-auto-ns{overflow:auto}.swagger-ui .overflow-x-visible-ns{overflow-x:visible}.swagger-ui .overflow-x-hidden-ns{overflow-x:hidden}.swagger-ui .overflow-x-scroll-ns{overflow-x:scroll}.swagger-ui .overflow-x-auto-ns{overflow-x:auto}.swagger-ui .overflow-y-visible-ns{overflow-y:visible}.swagger-ui .overflow-y-hidden-ns{overflow-y:hidden}.swagger-ui .overflow-y-scroll-ns{overflow-y:scroll}.swagger-ui .overflow-y-auto-ns{overflow-y:auto}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .overflow-visible-m{overflow:visible}.swagger-ui .overflow-hidden-m{overflow:hidden}.swagger-ui .overflow-scroll-m{overflow:scroll}.swagger-ui .overflow-auto-m{overflow:auto}.swagger-ui .overflow-x-visible-m{overflow-x:visible}.swagger-ui .overflow-x-hidden-m{overflow-x:hidden}.swagger-ui .overflow-x-scroll-m{overflow-x:scroll}.swagger-ui .overflow-x-auto-m{overflow-x:auto}.swagger-ui .overflow-y-visible-m{overflow-y:visible}.swagger-ui .overflow-y-hidden-m{overflow-y:hidden}.swagger-ui .overflow-y-scroll-m{overflow-y:scroll}.swagger-ui .overflow-y-auto-m{overflow-y:auto}}@media screen and (min-width:60em){.swagger-ui .overflow-visible-l{overflow:visible}.swagger-ui .overflow-hidden-l{overflow:hidden}.swagger-ui .overflow-scroll-l{overflow:scroll}.swagger-ui .overflow-auto-l{overflow:auto}.swagger-ui .overflow-x-visible-l{overflow-x:visible}.swagger-ui .overflow-x-hidden-l{overflow-x:hidden}.swagger-ui .overflow-x-scroll-l{overflow-x:scroll}.swagger-ui .overflow-x-auto-l{overflow-x:auto}.swagger-ui .overflow-y-visible-l{overflow-y:visible}.swagger-ui .overflow-y-hidden-l{overflow-y:hidden}.swagger-ui .overflow-y-scroll-l{overflow-y:scroll}.swagger-ui .overflow-y-auto-l{overflow-y:auto}}.swagger-ui .static{position:static}.swagger-ui .relative{position:relative}.swagger-ui .absolute{position:absolute}.swagger-ui .fixed{position:fixed}@media screen and (min-width:30em){.swagger-ui .static-ns{position:static}.swagger-ui .relative-ns{position:relative}.swagger-ui .absolute-ns{position:absolute}.swagger-ui .fixed-ns{position:fixed}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .static-m{position:static}.swagger-ui .relative-m{position:relative}.swagger-ui .absolute-m{position:absolute}.swagger-ui .fixed-m{position:fixed}}@media screen and (min-width:60em){.swagger-ui .static-l{position:static}.swagger-ui .relative-l{position:relative}.swagger-ui .absolute-l{position:absolute}.swagger-ui .fixed-l{position:fixed}}.swagger-ui .o-100{opacity:1}.swagger-ui .o-90{opacity:.9}.swagger-ui .o-80{opacity:.8}.swagger-ui .o-70{opacity:.7}.swagger-ui .o-60{opacity:.6}.swagger-ui .o-50{opacity:.5}.swagger-ui .o-40{opacity:.4}.swagger-ui .o-30{opacity:.3}.swagger-ui .o-20{opacity:.2}.swagger-ui .o-10{opacity:.1}.swagger-ui .o-05{opacity:.05}.swagger-ui .o-025{opacity:.025}.swagger-ui .o-0{opacity:0}.swagger-ui .rotate-45{transform:rotate(45deg)}.swagger-ui .rotate-90{transform:rotate(90deg)}.swagger-ui .rotate-135{transform:rotate(135deg)}.swagger-ui .rotate-180{transform:rotate(180deg)}.swagger-ui .rotate-225{transform:rotate(225deg)}.swagger-ui .rotate-270{transform:rotate(270deg)}.swagger-ui .rotate-315{transform:rotate(315deg)}@media screen and (min-width:30em){.swagger-ui .rotate-45-ns{transform:rotate(45deg)}.swagger-ui .rotate-90-ns{transform:rotate(90deg)}.swagger-ui .rotate-135-ns{transform:rotate(135deg)}.swagger-ui .rotate-180-ns{transform:rotate(180deg)}.swagger-ui .rotate-225-ns{transform:rotate(225deg)}.swagger-ui .rotate-270-ns{transform:rotate(270deg)}.swagger-ui .rotate-315-ns{transform:rotate(315deg)}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .rotate-45-m{transform:rotate(45deg)}.swagger-ui .rotate-90-m{transform:rotate(90deg)}.swagger-ui .rotate-135-m{transform:rotate(135deg)}.swagger-ui .rotate-180-m{transform:rotate(180deg)}.swagger-ui .rotate-225-m{transform:rotate(225deg)}.swagger-ui .rotate-270-m{transform:rotate(270deg)}.swagger-ui .rotate-315-m{transform:rotate(315deg)}}@media screen and (min-width:60em){.swagger-ui .rotate-45-l{transform:rotate(45deg)}.swagger-ui .rotate-90-l{transform:rotate(90deg)}.swagger-ui .rotate-135-l{transform:rotate(135deg)}.swagger-ui .rotate-180-l{transform:rotate(180deg)}.swagger-ui .rotate-225-l{transform:rotate(225deg)}.swagger-ui .rotate-270-l{transform:rotate(270deg)}.swagger-ui .rotate-315-l{transform:rotate(315deg)}}.swagger-ui .black-90{color:rgba(0,0,0,.9)}.swagger-ui .black-80{color:rgba(0,0,0,.8)}.swagger-ui .black-70{color:rgba(0,0,0,.7)}.swagger-ui .black-60{color:rgba(0,0,0,.6)}.swagger-ui .black-50{color:rgba(0,0,0,.5)}.swagger-ui .black-40{color:rgba(0,0,0,.4)}.swagger-ui .black-30{color:rgba(0,0,0,.3)}.swagger-ui .black-20{color:rgba(0,0,0,.2)}.swagger-ui .black-10{color:rgba(0,0,0,.1)}.swagger-ui .black-05{color:rgba(0,0,0,.05)}.swagger-ui .white-90{color:hsla(0,0%,100%,.9)}.swagger-ui .white-80{color:hsla(0,0%,100%,.8)}.swagger-ui .white-70{color:hsla(0,0%,100%,.7)}.swagger-ui .white-60{color:hsla(0,0%,100%,.6)}.swagger-ui .white-50{color:hsla(0,0%,100%,.5)}.swagger-ui .white-40{color:hsla(0,0%,100%,.4)}.swagger-ui .white-30{color:hsla(0,0%,100%,.3)}.swagger-ui .white-20{color:hsla(0,0%,100%,.2)}.swagger-ui .white-10{color:hsla(0,0%,100%,.1)}.swagger-ui .black{color:#000}.swagger-ui .near-black{color:#111}.swagger-ui .dark-gray{color:#333}.swagger-ui .mid-gray{color:#555}.swagger-ui .gray{color:#777}.swagger-ui .silver{color:#999}.swagger-ui .light-silver{color:#aaa}.swagger-ui .moon-gray{color:#ccc}.swagger-ui .light-gray{color:#eee}.swagger-ui .near-white{color:#f4f4f4}.swagger-ui .white{color:#fff}.swagger-ui .dark-red{color:#e7040f}.swagger-ui .red{color:#ff4136}.swagger-ui .light-red{color:#ff725c}.swagger-ui .orange{color:#ff6300}.swagger-ui .gold{color:#ffb700}.swagger-ui .yellow{color:gold}.swagger-ui .light-yellow{color:#fbf1a9}.swagger-ui .purple{color:#5e2ca5}.swagger-ui .light-purple{color:#a463f2}.swagger-ui .dark-pink{color:#d5008f}.swagger-ui .hot-pink{color:#ff41b4}.swagger-ui .pink{color:#ff80cc}.swagger-ui .light-pink{color:#ffa3d7}.swagger-ui .dark-green{color:#137752}.swagger-ui .green{color:#19a974}.swagger-ui .light-green{color:#9eebcf}.swagger-ui .navy{color:#001b44}.swagger-ui .dark-blue{color:#00449e}.swagger-ui .blue{color:#357edd}.swagger-ui .light-blue{color:#96ccff}.swagger-ui .lightest-blue{color:#cdecff}.swagger-ui .washed-blue{color:#f6fffe}.swagger-ui .washed-green{color:#e8fdf5}.swagger-ui .washed-yellow{color:#fffceb}.swagger-ui .washed-red{color:#ffdfdf}.swagger-ui .color-inherit{color:inherit}.swagger-ui .bg-black-90{background-color:rgba(0,0,0,.9)}.swagger-ui .bg-black-80{background-color:rgba(0,0,0,.8)}.swagger-ui .bg-black-70{background-color:rgba(0,0,0,.7)}.swagger-ui .bg-black-60{background-color:rgba(0,0,0,.6)}.swagger-ui .bg-black-50{background-color:rgba(0,0,0,.5)}.swagger-ui .bg-black-40{background-color:rgba(0,0,0,.4)}.swagger-ui .bg-black-30{background-color:rgba(0,0,0,.3)}.swagger-ui .bg-black-20{background-color:rgba(0,0,0,.2)}.swagger-ui .bg-black-10{background-color:rgba(0,0,0,.1)}.swagger-ui .bg-black-05{background-color:rgba(0,0,0,.05)}.swagger-ui .bg-white-90{background-color:hsla(0,0%,100%,.9)}.swagger-ui .bg-white-80{background-color:hsla(0,0%,100%,.8)}.swagger-ui .bg-white-70{background-color:hsla(0,0%,100%,.7)}.swagger-ui .bg-white-60{background-color:hsla(0,0%,100%,.6)}.swagger-ui .bg-white-50{background-color:hsla(0,0%,100%,.5)}.swagger-ui .bg-white-40{background-color:hsla(0,0%,100%,.4)}.swagger-ui .bg-white-30{background-color:hsla(0,0%,100%,.3)}.swagger-ui .bg-white-20{background-color:hsla(0,0%,100%,.2)}.swagger-ui .bg-white-10{background-color:hsla(0,0%,100%,.1)}.swagger-ui .bg-black{background-color:#000}.swagger-ui .bg-near-black{background-color:#111}.swagger-ui .bg-dark-gray{background-color:#333}.swagger-ui .bg-mid-gray{background-color:#555}.swagger-ui .bg-gray{background-color:#777}.swagger-ui .bg-silver{background-color:#999}.swagger-ui .bg-light-silver{background-color:#aaa}.swagger-ui .bg-moon-gray{background-color:#ccc}.swagger-ui .bg-light-gray{background-color:#eee}.swagger-ui .bg-near-white{background-color:#f4f4f4}.swagger-ui .bg-white{background-color:#fff}.swagger-ui .bg-transparent{background-color:transparent}.swagger-ui .bg-dark-red{background-color:#e7040f}.swagger-ui .bg-red{background-color:#ff4136}.swagger-ui .bg-light-red{background-color:#ff725c}.swagger-ui .bg-orange{background-color:#ff6300}.swagger-ui .bg-gold{background-color:#ffb700}.swagger-ui .bg-yellow{background-color:gold}.swagger-ui .bg-light-yellow{background-color:#fbf1a9}.swagger-ui .bg-purple{background-color:#5e2ca5}.swagger-ui .bg-light-purple{background-color:#a463f2}.swagger-ui .bg-dark-pink{background-color:#d5008f}.swagger-ui .bg-hot-pink{background-color:#ff41b4}.swagger-ui .bg-pink{background-color:#ff80cc}.swagger-ui .bg-light-pink{background-color:#ffa3d7}.swagger-ui .bg-dark-green{background-color:#137752}.swagger-ui .bg-green{background-color:#19a974}.swagger-ui .bg-light-green{background-color:#9eebcf}.swagger-ui .bg-navy{background-color:#001b44}.swagger-ui .bg-dark-blue{background-color:#00449e}.swagger-ui .bg-blue{background-color:#357edd}.swagger-ui .bg-light-blue{background-color:#96ccff}.swagger-ui .bg-lightest-blue{background-color:#cdecff}.swagger-ui .bg-washed-blue{background-color:#f6fffe}.swagger-ui .bg-washed-green{background-color:#e8fdf5}.swagger-ui .bg-washed-yellow{background-color:#fffceb}.swagger-ui .bg-washed-red{background-color:#ffdfdf}.swagger-ui .bg-inherit{background-color:inherit}.swagger-ui .hover-black:focus,.swagger-ui .hover-black:hover{color:#000}.swagger-ui .hover-near-black:focus,.swagger-ui .hover-near-black:hover{color:#111}.swagger-ui .hover-dark-gray:focus,.swagger-ui .hover-dark-gray:hover{color:#333}.swagger-ui .hover-mid-gray:focus,.swagger-ui .hover-mid-gray:hover{color:#555}.swagger-ui .hover-gray:focus,.swagger-ui .hover-gray:hover{color:#777}.swagger-ui .hover-silver:focus,.swagger-ui .hover-silver:hover{color:#999}.swagger-ui .hover-light-silver:focus,.swagger-ui .hover-light-silver:hover{color:#aaa}.swagger-ui .hover-moon-gray:focus,.swagger-ui .hover-moon-gray:hover{color:#ccc}.swagger-ui .hover-light-gray:focus,.swagger-ui .hover-light-gray:hover{color:#eee}.swagger-ui .hover-near-white:focus,.swagger-ui .hover-near-white:hover{color:#f4f4f4}.swagger-ui .hover-white:focus,.swagger-ui .hover-white:hover{color:#fff}.swagger-ui .hover-black-90:focus,.swagger-ui .hover-black-90:hover{color:rgba(0,0,0,.9)}.swagger-ui .hover-black-80:focus,.swagger-ui .hover-black-80:hover{color:rgba(0,0,0,.8)}.swagger-ui .hover-black-70:focus,.swagger-ui .hover-black-70:hover{color:rgba(0,0,0,.7)}.swagger-ui .hover-black-60:focus,.swagger-ui .hover-black-60:hover{color:rgba(0,0,0,.6)}.swagger-ui .hover-black-50:focus,.swagger-ui .hover-black-50:hover{color:rgba(0,0,0,.5)}.swagger-ui .hover-black-40:focus,.swagger-ui .hover-black-40:hover{color:rgba(0,0,0,.4)}.swagger-ui .hover-black-30:focus,.swagger-ui .hover-black-30:hover{color:rgba(0,0,0,.3)}.swagger-ui .hover-black-20:focus,.swagger-ui .hover-black-20:hover{color:rgba(0,0,0,.2)}.swagger-ui .hover-black-10:focus,.swagger-ui .hover-black-10:hover{color:rgba(0,0,0,.1)}.swagger-ui .hover-white-90:focus,.swagger-ui .hover-white-90:hover{color:hsla(0,0%,100%,.9)}.swagger-ui .hover-white-80:focus,.swagger-ui .hover-white-80:hover{color:hsla(0,0%,100%,.8)}.swagger-ui .hover-white-70:focus,.swagger-ui .hover-white-70:hover{color:hsla(0,0%,100%,.7)}.swagger-ui .hover-white-60:focus,.swagger-ui .hover-white-60:hover{color:hsla(0,0%,100%,.6)}.swagger-ui .hover-white-50:focus,.swagger-ui .hover-white-50:hover{color:hsla(0,0%,100%,.5)}.swagger-ui .hover-white-40:focus,.swagger-ui .hover-white-40:hover{color:hsla(0,0%,100%,.4)}.swagger-ui .hover-white-30:focus,.swagger-ui .hover-white-30:hover{color:hsla(0,0%,100%,.3)}.swagger-ui .hover-white-20:focus,.swagger-ui .hover-white-20:hover{color:hsla(0,0%,100%,.2)}.swagger-ui .hover-white-10:focus,.swagger-ui .hover-white-10:hover{color:hsla(0,0%,100%,.1)}.swagger-ui .hover-inherit:focus,.swagger-ui .hover-inherit:hover{color:inherit}.swagger-ui .hover-bg-black:focus,.swagger-ui .hover-bg-black:hover{background-color:#000}.swagger-ui .hover-bg-near-black:focus,.swagger-ui .hover-bg-near-black:hover{background-color:#111}.swagger-ui .hover-bg-dark-gray:focus,.swagger-ui .hover-bg-dark-gray:hover{background-color:#333}.swagger-ui .hover-bg-mid-gray:focus,.swagger-ui .hover-bg-mid-gray:hover{background-color:#555}.swagger-ui .hover-bg-gray:focus,.swagger-ui .hover-bg-gray:hover{background-color:#777}.swagger-ui .hover-bg-silver:focus,.swagger-ui .hover-bg-silver:hover{background-color:#999}.swagger-ui .hover-bg-light-silver:focus,.swagger-ui .hover-bg-light-silver:hover{background-color:#aaa}.swagger-ui .hover-bg-moon-gray:focus,.swagger-ui .hover-bg-moon-gray:hover{background-color:#ccc}.swagger-ui .hover-bg-light-gray:focus,.swagger-ui .hover-bg-light-gray:hover{background-color:#eee}.swagger-ui .hover-bg-near-white:focus,.swagger-ui .hover-bg-near-white:hover{background-color:#f4f4f4}.swagger-ui .hover-bg-white:focus,.swagger-ui .hover-bg-white:hover{background-color:#fff}.swagger-ui .hover-bg-transparent:focus,.swagger-ui .hover-bg-transparent:hover{background-color:transparent}.swagger-ui .hover-bg-black-90:focus,.swagger-ui .hover-bg-black-90:hover{background-color:rgba(0,0,0,.9)}.swagger-ui .hover-bg-black-80:focus,.swagger-ui .hover-bg-black-80:hover{background-color:rgba(0,0,0,.8)}.swagger-ui .hover-bg-black-70:focus,.swagger-ui .hover-bg-black-70:hover{background-color:rgba(0,0,0,.7)}.swagger-ui .hover-bg-black-60:focus,.swagger-ui .hover-bg-black-60:hover{background-color:rgba(0,0,0,.6)}.swagger-ui .hover-bg-black-50:focus,.swagger-ui .hover-bg-black-50:hover{background-color:rgba(0,0,0,.5)}.swagger-ui .hover-bg-black-40:focus,.swagger-ui .hover-bg-black-40:hover{background-color:rgba(0,0,0,.4)}.swagger-ui .hover-bg-black-30:focus,.swagger-ui .hover-bg-black-30:hover{background-color:rgba(0,0,0,.3)}.swagger-ui .hover-bg-black-20:focus,.swagger-ui .hover-bg-black-20:hover{background-color:rgba(0,0,0,.2)}.swagger-ui .hover-bg-black-10:focus,.swagger-ui .hover-bg-black-10:hover{background-color:rgba(0,0,0,.1)}.swagger-ui .hover-bg-white-90:focus,.swagger-ui .hover-bg-white-90:hover{background-color:hsla(0,0%,100%,.9)}.swagger-ui .hover-bg-white-80:focus,.swagger-ui .hover-bg-white-80:hover{background-color:hsla(0,0%,100%,.8)}.swagger-ui .hover-bg-white-70:focus,.swagger-ui .hover-bg-white-70:hover{background-color:hsla(0,0%,100%,.7)}.swagger-ui .hover-bg-white-60:focus,.swagger-ui .hover-bg-white-60:hover{background-color:hsla(0,0%,100%,.6)}.swagger-ui .hover-bg-white-50:focus,.swagger-ui .hover-bg-white-50:hover{background-color:hsla(0,0%,100%,.5)}.swagger-ui .hover-bg-white-40:focus,.swagger-ui .hover-bg-white-40:hover{background-color:hsla(0,0%,100%,.4)}.swagger-ui .hover-bg-white-30:focus,.swagger-ui .hover-bg-white-30:hover{background-color:hsla(0,0%,100%,.3)}.swagger-ui .hover-bg-white-20:focus,.swagger-ui .hover-bg-white-20:hover{background-color:hsla(0,0%,100%,.2)}.swagger-ui .hover-bg-white-10:focus,.swagger-ui .hover-bg-white-10:hover{background-color:hsla(0,0%,100%,.1)}.swagger-ui .hover-dark-red:focus,.swagger-ui .hover-dark-red:hover{color:#e7040f}.swagger-ui .hover-red:focus,.swagger-ui .hover-red:hover{color:#ff4136}.swagger-ui .hover-light-red:focus,.swagger-ui .hover-light-red:hover{color:#ff725c}.swagger-ui .hover-orange:focus,.swagger-ui .hover-orange:hover{color:#ff6300}.swagger-ui .hover-gold:focus,.swagger-ui .hover-gold:hover{color:#ffb700}.swagger-ui .hover-yellow:focus,.swagger-ui .hover-yellow:hover{color:gold}.swagger-ui .hover-light-yellow:focus,.swagger-ui .hover-light-yellow:hover{color:#fbf1a9}.swagger-ui .hover-purple:focus,.swagger-ui .hover-purple:hover{color:#5e2ca5}.swagger-ui .hover-light-purple:focus,.swagger-ui .hover-light-purple:hover{color:#a463f2}.swagger-ui .hover-dark-pink:focus,.swagger-ui .hover-dark-pink:hover{color:#d5008f}.swagger-ui .hover-hot-pink:focus,.swagger-ui .hover-hot-pink:hover{color:#ff41b4}.swagger-ui .hover-pink:focus,.swagger-ui .hover-pink:hover{color:#ff80cc}.swagger-ui .hover-light-pink:focus,.swagger-ui .hover-light-pink:hover{color:#ffa3d7}.swagger-ui .hover-dark-green:focus,.swagger-ui .hover-dark-green:hover{color:#137752}.swagger-ui .hover-green:focus,.swagger-ui .hover-green:hover{color:#19a974}.swagger-ui .hover-light-green:focus,.swagger-ui .hover-light-green:hover{color:#9eebcf}.swagger-ui .hover-navy:focus,.swagger-ui .hover-navy:hover{color:#001b44}.swagger-ui .hover-dark-blue:focus,.swagger-ui .hover-dark-blue:hover{color:#00449e}.swagger-ui .hover-blue:focus,.swagger-ui .hover-blue:hover{color:#357edd}.swagger-ui .hover-light-blue:focus,.swagger-ui .hover-light-blue:hover{color:#96ccff}.swagger-ui .hover-lightest-blue:focus,.swagger-ui .hover-lightest-blue:hover{color:#cdecff}.swagger-ui .hover-washed-blue:focus,.swagger-ui .hover-washed-blue:hover{color:#f6fffe}.swagger-ui .hover-washed-green:focus,.swagger-ui .hover-washed-green:hover{color:#e8fdf5}.swagger-ui .hover-washed-yellow:focus,.swagger-ui .hover-washed-yellow:hover{color:#fffceb}.swagger-ui .hover-washed-red:focus,.swagger-ui .hover-washed-red:hover{color:#ffdfdf}.swagger-ui .hover-bg-dark-red:focus,.swagger-ui .hover-bg-dark-red:hover{background-color:#e7040f}.swagger-ui .hover-bg-red:focus,.swagger-ui .hover-bg-red:hover{background-color:#ff4136}.swagger-ui .hover-bg-light-red:focus,.swagger-ui .hover-bg-light-red:hover{background-color:#ff725c}.swagger-ui .hover-bg-orange:focus,.swagger-ui .hover-bg-orange:hover{background-color:#ff6300}.swagger-ui .hover-bg-gold:focus,.swagger-ui .hover-bg-gold:hover{background-color:#ffb700}.swagger-ui .hover-bg-yellow:focus,.swagger-ui .hover-bg-yellow:hover{background-color:gold}.swagger-ui .hover-bg-light-yellow:focus,.swagger-ui .hover-bg-light-yellow:hover{background-color:#fbf1a9}.swagger-ui .hover-bg-purple:focus,.swagger-ui .hover-bg-purple:hover{background-color:#5e2ca5}.swagger-ui .hover-bg-light-purple:focus,.swagger-ui .hover-bg-light-purple:hover{background-color:#a463f2}.swagger-ui .hover-bg-dark-pink:focus,.swagger-ui .hover-bg-dark-pink:hover{background-color:#d5008f}.swagger-ui .hover-bg-hot-pink:focus,.swagger-ui .hover-bg-hot-pink:hover{background-color:#ff41b4}.swagger-ui .hover-bg-pink:focus,.swagger-ui .hover-bg-pink:hover{background-color:#ff80cc}.swagger-ui .hover-bg-light-pink:focus,.swagger-ui .hover-bg-light-pink:hover{background-color:#ffa3d7}.swagger-ui .hover-bg-dark-green:focus,.swagger-ui .hover-bg-dark-green:hover{background-color:#137752}.swagger-ui .hover-bg-green:focus,.swagger-ui .hover-bg-green:hover{background-color:#19a974}.swagger-ui .hover-bg-light-green:focus,.swagger-ui .hover-bg-light-green:hover{background-color:#9eebcf}.swagger-ui .hover-bg-navy:focus,.swagger-ui .hover-bg-navy:hover{background-color:#001b44}.swagger-ui .hover-bg-dark-blue:focus,.swagger-ui .hover-bg-dark-blue:hover{background-color:#00449e}.swagger-ui .hover-bg-blue:focus,.swagger-ui .hover-bg-blue:hover{background-color:#357edd}.swagger-ui .hover-bg-light-blue:focus,.swagger-ui .hover-bg-light-blue:hover{background-color:#96ccff}.swagger-ui .hover-bg-lightest-blue:focus,.swagger-ui .hover-bg-lightest-blue:hover{background-color:#cdecff}.swagger-ui .hover-bg-washed-blue:focus,.swagger-ui .hover-bg-washed-blue:hover{background-color:#f6fffe}.swagger-ui .hover-bg-washed-green:focus,.swagger-ui .hover-bg-washed-green:hover{background-color:#e8fdf5}.swagger-ui .hover-bg-washed-yellow:focus,.swagger-ui .hover-bg-washed-yellow:hover{background-color:#fffceb}.swagger-ui .hover-bg-washed-red:focus,.swagger-ui .hover-bg-washed-red:hover{background-color:#ffdfdf}.swagger-ui .hover-bg-inherit:focus,.swagger-ui .hover-bg-inherit:hover{background-color:inherit}.swagger-ui .pa0{padding:0}.swagger-ui .pa1{padding:.25rem}.swagger-ui .pa2{padding:.5rem}.swagger-ui .pa3{padding:1rem}.swagger-ui .pa4{padding:2rem}.swagger-ui .pa5{padding:4rem}.swagger-ui .pa6{padding:8rem}.swagger-ui .pa7{padding:16rem}.swagger-ui .pl0{padding-left:0}.swagger-ui .pl1{padding-left:.25rem}.swagger-ui .pl2{padding-left:.5rem}.swagger-ui .pl3{padding-left:1rem}.swagger-ui .pl4{padding-left:2rem}.swagger-ui .pl5{padding-left:4rem}.swagger-ui .pl6{padding-left:8rem}.swagger-ui .pl7{padding-left:16rem}.swagger-ui .pr0{padding-right:0}.swagger-ui .pr1{padding-right:.25rem}.swagger-ui .pr2{padding-right:.5rem}.swagger-ui .pr3{padding-right:1rem}.swagger-ui .pr4{padding-right:2rem}.swagger-ui .pr5{padding-right:4rem}.swagger-ui .pr6{padding-right:8rem}.swagger-ui .pr7{padding-right:16rem}.swagger-ui .pb0{padding-bottom:0}.swagger-ui .pb1{padding-bottom:.25rem}.swagger-ui .pb2{padding-bottom:.5rem}.swagger-ui .pb3{padding-bottom:1rem}.swagger-ui .pb4{padding-bottom:2rem}.swagger-ui .pb5{padding-bottom:4rem}.swagger-ui .pb6{padding-bottom:8rem}.swagger-ui .pb7{padding-bottom:16rem}.swagger-ui .pt0{padding-top:0}.swagger-ui .pt1{padding-top:.25rem}.swagger-ui .pt2{padding-top:.5rem}.swagger-ui .pt3{padding-top:1rem}.swagger-ui .pt4{padding-top:2rem}.swagger-ui .pt5{padding-top:4rem}.swagger-ui .pt6{padding-top:8rem}.swagger-ui .pt7{padding-top:16rem}.swagger-ui .pv0{padding-bottom:0;padding-top:0}.swagger-ui .pv1{padding-bottom:.25rem;padding-top:.25rem}.swagger-ui .pv2{padding-bottom:.5rem;padding-top:.5rem}.swagger-ui .pv3{padding-bottom:1rem;padding-top:1rem}.swagger-ui .pv4{padding-bottom:2rem;padding-top:2rem}.swagger-ui .pv5{padding-bottom:4rem;padding-top:4rem}.swagger-ui .pv6{padding-bottom:8rem;padding-top:8rem}.swagger-ui .pv7{padding-bottom:16rem;padding-top:16rem}.swagger-ui .ph0{padding-left:0;padding-right:0}.swagger-ui .ph1{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0{margin:0}.swagger-ui .ma1{margin:.25rem}.swagger-ui .ma2{margin:.5rem}.swagger-ui .ma3{margin:1rem}.swagger-ui .ma4{margin:2rem}.swagger-ui .ma5{margin:4rem}.swagger-ui .ma6{margin:8rem}.swagger-ui .ma7{margin:16rem}.swagger-ui .ml0{margin-left:0}.swagger-ui .ml1{margin-left:.25rem}.swagger-ui .ml2{margin-left:.5rem}.swagger-ui .ml3{margin-left:1rem}.swagger-ui .ml4{margin-left:2rem}.swagger-ui .ml5{margin-left:4rem}.swagger-ui .ml6{margin-left:8rem}.swagger-ui .ml7{margin-left:16rem}.swagger-ui .mr0{margin-right:0}.swagger-ui .mr1{margin-right:.25rem}.swagger-ui .mr2{margin-right:.5rem}.swagger-ui .mr3{margin-right:1rem}.swagger-ui .mr4{margin-right:2rem}.swagger-ui .mr5{margin-right:4rem}.swagger-ui .mr6{margin-right:8rem}.swagger-ui .mr7{margin-right:16rem}.swagger-ui .mb0{margin-bottom:0}.swagger-ui .mb1{margin-bottom:.25rem}.swagger-ui .mb2{margin-bottom:.5rem}.swagger-ui .mb3{margin-bottom:1rem}.swagger-ui .mb4{margin-bottom:2rem}.swagger-ui .mb5{margin-bottom:4rem}.swagger-ui .mb6{margin-bottom:8rem}.swagger-ui .mb7{margin-bottom:16rem}.swagger-ui .mt0{margin-top:0}.swagger-ui .mt1{margin-top:.25rem}.swagger-ui .mt2{margin-top:.5rem}.swagger-ui .mt3{margin-top:1rem}.swagger-ui .mt4{margin-top:2rem}.swagger-ui .mt5{margin-top:4rem}.swagger-ui .mt6{margin-top:8rem}.swagger-ui .mt7{margin-top:16rem}.swagger-ui .mv0{margin-bottom:0;margin-top:0}.swagger-ui .mv1{margin-bottom:.25rem;margin-top:.25rem}.swagger-ui .mv2{margin-bottom:.5rem;margin-top:.5rem}.swagger-ui .mv3{margin-bottom:1rem;margin-top:1rem}.swagger-ui .mv4{margin-bottom:2rem;margin-top:2rem}.swagger-ui .mv5{margin-bottom:4rem;margin-top:4rem}.swagger-ui .mv6{margin-bottom:8rem;margin-top:8rem}.swagger-ui .mv7{margin-bottom:16rem;margin-top:16rem}.swagger-ui .mh0{margin-left:0;margin-right:0}.swagger-ui .mh1{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7{margin-left:16rem;margin-right:16rem}@media screen and (min-width:30em){.swagger-ui .pa0-ns{padding:0}.swagger-ui .pa1-ns{padding:.25rem}.swagger-ui .pa2-ns{padding:.5rem}.swagger-ui .pa3-ns{padding:1rem}.swagger-ui .pa4-ns{padding:2rem}.swagger-ui .pa5-ns{padding:4rem}.swagger-ui .pa6-ns{padding:8rem}.swagger-ui .pa7-ns{padding:16rem}.swagger-ui .pl0-ns{padding-left:0}.swagger-ui .pl1-ns{padding-left:.25rem}.swagger-ui .pl2-ns{padding-left:.5rem}.swagger-ui .pl3-ns{padding-left:1rem}.swagger-ui .pl4-ns{padding-left:2rem}.swagger-ui .pl5-ns{padding-left:4rem}.swagger-ui .pl6-ns{padding-left:8rem}.swagger-ui .pl7-ns{padding-left:16rem}.swagger-ui .pr0-ns{padding-right:0}.swagger-ui .pr1-ns{padding-right:.25rem}.swagger-ui .pr2-ns{padding-right:.5rem}.swagger-ui .pr3-ns{padding-right:1rem}.swagger-ui .pr4-ns{padding-right:2rem}.swagger-ui .pr5-ns{padding-right:4rem}.swagger-ui .pr6-ns{padding-right:8rem}.swagger-ui .pr7-ns{padding-right:16rem}.swagger-ui .pb0-ns{padding-bottom:0}.swagger-ui .pb1-ns{padding-bottom:.25rem}.swagger-ui .pb2-ns{padding-bottom:.5rem}.swagger-ui .pb3-ns{padding-bottom:1rem}.swagger-ui .pb4-ns{padding-bottom:2rem}.swagger-ui .pb5-ns{padding-bottom:4rem}.swagger-ui .pb6-ns{padding-bottom:8rem}.swagger-ui .pb7-ns{padding-bottom:16rem}.swagger-ui .pt0-ns{padding-top:0}.swagger-ui .pt1-ns{padding-top:.25rem}.swagger-ui .pt2-ns{padding-top:.5rem}.swagger-ui .pt3-ns{padding-top:1rem}.swagger-ui .pt4-ns{padding-top:2rem}.swagger-ui .pt5-ns{padding-top:4rem}.swagger-ui .pt6-ns{padding-top:8rem}.swagger-ui .pt7-ns{padding-top:16rem}.swagger-ui .pv0-ns{padding-bottom:0;padding-top:0}.swagger-ui .pv1-ns{padding-bottom:.25rem;padding-top:.25rem}.swagger-ui .pv2-ns{padding-bottom:.5rem;padding-top:.5rem}.swagger-ui .pv3-ns{padding-bottom:1rem;padding-top:1rem}.swagger-ui .pv4-ns{padding-bottom:2rem;padding-top:2rem}.swagger-ui .pv5-ns{padding-bottom:4rem;padding-top:4rem}.swagger-ui .pv6-ns{padding-bottom:8rem;padding-top:8rem}.swagger-ui .pv7-ns{padding-bottom:16rem;padding-top:16rem}.swagger-ui .ph0-ns{padding-left:0;padding-right:0}.swagger-ui .ph1-ns{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-ns{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-ns{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-ns{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-ns{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-ns{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-ns{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-ns{margin:0}.swagger-ui .ma1-ns{margin:.25rem}.swagger-ui .ma2-ns{margin:.5rem}.swagger-ui .ma3-ns{margin:1rem}.swagger-ui .ma4-ns{margin:2rem}.swagger-ui .ma5-ns{margin:4rem}.swagger-ui .ma6-ns{margin:8rem}.swagger-ui .ma7-ns{margin:16rem}.swagger-ui .ml0-ns{margin-left:0}.swagger-ui .ml1-ns{margin-left:.25rem}.swagger-ui .ml2-ns{margin-left:.5rem}.swagger-ui .ml3-ns{margin-left:1rem}.swagger-ui .ml4-ns{margin-left:2rem}.swagger-ui .ml5-ns{margin-left:4rem}.swagger-ui .ml6-ns{margin-left:8rem}.swagger-ui .ml7-ns{margin-left:16rem}.swagger-ui .mr0-ns{margin-right:0}.swagger-ui .mr1-ns{margin-right:.25rem}.swagger-ui .mr2-ns{margin-right:.5rem}.swagger-ui .mr3-ns{margin-right:1rem}.swagger-ui .mr4-ns{margin-right:2rem}.swagger-ui .mr5-ns{margin-right:4rem}.swagger-ui .mr6-ns{margin-right:8rem}.swagger-ui .mr7-ns{margin-right:16rem}.swagger-ui .mb0-ns{margin-bottom:0}.swagger-ui .mb1-ns{margin-bottom:.25rem}.swagger-ui .mb2-ns{margin-bottom:.5rem}.swagger-ui .mb3-ns{margin-bottom:1rem}.swagger-ui .mb4-ns{margin-bottom:2rem}.swagger-ui .mb5-ns{margin-bottom:4rem}.swagger-ui .mb6-ns{margin-bottom:8rem}.swagger-ui .mb7-ns{margin-bottom:16rem}.swagger-ui .mt0-ns{margin-top:0}.swagger-ui .mt1-ns{margin-top:.25rem}.swagger-ui .mt2-ns{margin-top:.5rem}.swagger-ui .mt3-ns{margin-top:1rem}.swagger-ui .mt4-ns{margin-top:2rem}.swagger-ui .mt5-ns{margin-top:4rem}.swagger-ui .mt6-ns{margin-top:8rem}.swagger-ui .mt7-ns{margin-top:16rem}.swagger-ui .mv0-ns{margin-bottom:0;margin-top:0}.swagger-ui .mv1-ns{margin-bottom:.25rem;margin-top:.25rem}.swagger-ui .mv2-ns{margin-bottom:.5rem;margin-top:.5rem}.swagger-ui .mv3-ns{margin-bottom:1rem;margin-top:1rem}.swagger-ui .mv4-ns{margin-bottom:2rem;margin-top:2rem}.swagger-ui .mv5-ns{margin-bottom:4rem;margin-top:4rem}.swagger-ui .mv6-ns{margin-bottom:8rem;margin-top:8rem}.swagger-ui .mv7-ns{margin-bottom:16rem;margin-top:16rem}.swagger-ui .mh0-ns{margin-left:0;margin-right:0}.swagger-ui .mh1-ns{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-ns{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-ns{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-ns{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-ns{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-ns{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-ns{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .pa0-m{padding:0}.swagger-ui .pa1-m{padding:.25rem}.swagger-ui .pa2-m{padding:.5rem}.swagger-ui .pa3-m{padding:1rem}.swagger-ui .pa4-m{padding:2rem}.swagger-ui .pa5-m{padding:4rem}.swagger-ui .pa6-m{padding:8rem}.swagger-ui .pa7-m{padding:16rem}.swagger-ui .pl0-m{padding-left:0}.swagger-ui .pl1-m{padding-left:.25rem}.swagger-ui .pl2-m{padding-left:.5rem}.swagger-ui .pl3-m{padding-left:1rem}.swagger-ui .pl4-m{padding-left:2rem}.swagger-ui .pl5-m{padding-left:4rem}.swagger-ui .pl6-m{padding-left:8rem}.swagger-ui .pl7-m{padding-left:16rem}.swagger-ui .pr0-m{padding-right:0}.swagger-ui .pr1-m{padding-right:.25rem}.swagger-ui .pr2-m{padding-right:.5rem}.swagger-ui .pr3-m{padding-right:1rem}.swagger-ui .pr4-m{padding-right:2rem}.swagger-ui .pr5-m{padding-right:4rem}.swagger-ui .pr6-m{padding-right:8rem}.swagger-ui .pr7-m{padding-right:16rem}.swagger-ui .pb0-m{padding-bottom:0}.swagger-ui .pb1-m{padding-bottom:.25rem}.swagger-ui .pb2-m{padding-bottom:.5rem}.swagger-ui .pb3-m{padding-bottom:1rem}.swagger-ui .pb4-m{padding-bottom:2rem}.swagger-ui .pb5-m{padding-bottom:4rem}.swagger-ui .pb6-m{padding-bottom:8rem}.swagger-ui .pb7-m{padding-bottom:16rem}.swagger-ui .pt0-m{padding-top:0}.swagger-ui .pt1-m{padding-top:.25rem}.swagger-ui .pt2-m{padding-top:.5rem}.swagger-ui .pt3-m{padding-top:1rem}.swagger-ui .pt4-m{padding-top:2rem}.swagger-ui .pt5-m{padding-top:4rem}.swagger-ui .pt6-m{padding-top:8rem}.swagger-ui .pt7-m{padding-top:16rem}.swagger-ui .pv0-m{padding-bottom:0;padding-top:0}.swagger-ui .pv1-m{padding-bottom:.25rem;padding-top:.25rem}.swagger-ui .pv2-m{padding-bottom:.5rem;padding-top:.5rem}.swagger-ui .pv3-m{padding-bottom:1rem;padding-top:1rem}.swagger-ui .pv4-m{padding-bottom:2rem;padding-top:2rem}.swagger-ui .pv5-m{padding-bottom:4rem;padding-top:4rem}.swagger-ui .pv6-m{padding-bottom:8rem;padding-top:8rem}.swagger-ui .pv7-m{padding-bottom:16rem;padding-top:16rem}.swagger-ui .ph0-m{padding-left:0;padding-right:0}.swagger-ui .ph1-m{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-m{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-m{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-m{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-m{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-m{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-m{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-m{margin:0}.swagger-ui .ma1-m{margin:.25rem}.swagger-ui .ma2-m{margin:.5rem}.swagger-ui .ma3-m{margin:1rem}.swagger-ui .ma4-m{margin:2rem}.swagger-ui .ma5-m{margin:4rem}.swagger-ui .ma6-m{margin:8rem}.swagger-ui .ma7-m{margin:16rem}.swagger-ui .ml0-m{margin-left:0}.swagger-ui .ml1-m{margin-left:.25rem}.swagger-ui .ml2-m{margin-left:.5rem}.swagger-ui .ml3-m{margin-left:1rem}.swagger-ui .ml4-m{margin-left:2rem}.swagger-ui .ml5-m{margin-left:4rem}.swagger-ui .ml6-m{margin-left:8rem}.swagger-ui .ml7-m{margin-left:16rem}.swagger-ui .mr0-m{margin-right:0}.swagger-ui .mr1-m{margin-right:.25rem}.swagger-ui .mr2-m{margin-right:.5rem}.swagger-ui .mr3-m{margin-right:1rem}.swagger-ui .mr4-m{margin-right:2rem}.swagger-ui .mr5-m{margin-right:4rem}.swagger-ui .mr6-m{margin-right:8rem}.swagger-ui .mr7-m{margin-right:16rem}.swagger-ui .mb0-m{margin-bottom:0}.swagger-ui .mb1-m{margin-bottom:.25rem}.swagger-ui .mb2-m{margin-bottom:.5rem}.swagger-ui .mb3-m{margin-bottom:1rem}.swagger-ui .mb4-m{margin-bottom:2rem}.swagger-ui .mb5-m{margin-bottom:4rem}.swagger-ui .mb6-m{margin-bottom:8rem}.swagger-ui .mb7-m{margin-bottom:16rem}.swagger-ui .mt0-m{margin-top:0}.swagger-ui .mt1-m{margin-top:.25rem}.swagger-ui .mt2-m{margin-top:.5rem}.swagger-ui .mt3-m{margin-top:1rem}.swagger-ui .mt4-m{margin-top:2rem}.swagger-ui .mt5-m{margin-top:4rem}.swagger-ui .mt6-m{margin-top:8rem}.swagger-ui .mt7-m{margin-top:16rem}.swagger-ui .mv0-m{margin-bottom:0;margin-top:0}.swagger-ui .mv1-m{margin-bottom:.25rem;margin-top:.25rem}.swagger-ui .mv2-m{margin-bottom:.5rem;margin-top:.5rem}.swagger-ui .mv3-m{margin-bottom:1rem;margin-top:1rem}.swagger-ui .mv4-m{margin-bottom:2rem;margin-top:2rem}.swagger-ui .mv5-m{margin-bottom:4rem;margin-top:4rem}.swagger-ui .mv6-m{margin-bottom:8rem;margin-top:8rem}.swagger-ui .mv7-m{margin-bottom:16rem;margin-top:16rem}.swagger-ui .mh0-m{margin-left:0;margin-right:0}.swagger-ui .mh1-m{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-m{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-m{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-m{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-m{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-m{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-m{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:60em){.swagger-ui .pa0-l{padding:0}.swagger-ui .pa1-l{padding:.25rem}.swagger-ui .pa2-l{padding:.5rem}.swagger-ui .pa3-l{padding:1rem}.swagger-ui .pa4-l{padding:2rem}.swagger-ui .pa5-l{padding:4rem}.swagger-ui .pa6-l{padding:8rem}.swagger-ui .pa7-l{padding:16rem}.swagger-ui .pl0-l{padding-left:0}.swagger-ui .pl1-l{padding-left:.25rem}.swagger-ui .pl2-l{padding-left:.5rem}.swagger-ui .pl3-l{padding-left:1rem}.swagger-ui .pl4-l{padding-left:2rem}.swagger-ui .pl5-l{padding-left:4rem}.swagger-ui .pl6-l{padding-left:8rem}.swagger-ui .pl7-l{padding-left:16rem}.swagger-ui .pr0-l{padding-right:0}.swagger-ui .pr1-l{padding-right:.25rem}.swagger-ui .pr2-l{padding-right:.5rem}.swagger-ui .pr3-l{padding-right:1rem}.swagger-ui .pr4-l{padding-right:2rem}.swagger-ui .pr5-l{padding-right:4rem}.swagger-ui .pr6-l{padding-right:8rem}.swagger-ui .pr7-l{padding-right:16rem}.swagger-ui .pb0-l{padding-bottom:0}.swagger-ui .pb1-l{padding-bottom:.25rem}.swagger-ui .pb2-l{padding-bottom:.5rem}.swagger-ui .pb3-l{padding-bottom:1rem}.swagger-ui .pb4-l{padding-bottom:2rem}.swagger-ui .pb5-l{padding-bottom:4rem}.swagger-ui .pb6-l{padding-bottom:8rem}.swagger-ui .pb7-l{padding-bottom:16rem}.swagger-ui .pt0-l{padding-top:0}.swagger-ui .pt1-l{padding-top:.25rem}.swagger-ui .pt2-l{padding-top:.5rem}.swagger-ui .pt3-l{padding-top:1rem}.swagger-ui .pt4-l{padding-top:2rem}.swagger-ui .pt5-l{padding-top:4rem}.swagger-ui .pt6-l{padding-top:8rem}.swagger-ui .pt7-l{padding-top:16rem}.swagger-ui .pv0-l{padding-bottom:0;padding-top:0}.swagger-ui .pv1-l{padding-bottom:.25rem;padding-top:.25rem}.swagger-ui .pv2-l{padding-bottom:.5rem;padding-top:.5rem}.swagger-ui .pv3-l{padding-bottom:1rem;padding-top:1rem}.swagger-ui .pv4-l{padding-bottom:2rem;padding-top:2rem}.swagger-ui .pv5-l{padding-bottom:4rem;padding-top:4rem}.swagger-ui .pv6-l{padding-bottom:8rem;padding-top:8rem}.swagger-ui .pv7-l{padding-bottom:16rem;padding-top:16rem}.swagger-ui .ph0-l{padding-left:0;padding-right:0}.swagger-ui .ph1-l{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-l{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-l{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-l{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-l{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-l{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-l{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-l{margin:0}.swagger-ui .ma1-l{margin:.25rem}.swagger-ui .ma2-l{margin:.5rem}.swagger-ui .ma3-l{margin:1rem}.swagger-ui .ma4-l{margin:2rem}.swagger-ui .ma5-l{margin:4rem}.swagger-ui .ma6-l{margin:8rem}.swagger-ui .ma7-l{margin:16rem}.swagger-ui .ml0-l{margin-left:0}.swagger-ui .ml1-l{margin-left:.25rem}.swagger-ui .ml2-l{margin-left:.5rem}.swagger-ui .ml3-l{margin-left:1rem}.swagger-ui .ml4-l{margin-left:2rem}.swagger-ui .ml5-l{margin-left:4rem}.swagger-ui .ml6-l{margin-left:8rem}.swagger-ui .ml7-l{margin-left:16rem}.swagger-ui .mr0-l{margin-right:0}.swagger-ui .mr1-l{margin-right:.25rem}.swagger-ui .mr2-l{margin-right:.5rem}.swagger-ui .mr3-l{margin-right:1rem}.swagger-ui .mr4-l{margin-right:2rem}.swagger-ui .mr5-l{margin-right:4rem}.swagger-ui .mr6-l{margin-right:8rem}.swagger-ui .mr7-l{margin-right:16rem}.swagger-ui .mb0-l{margin-bottom:0}.swagger-ui .mb1-l{margin-bottom:.25rem}.swagger-ui .mb2-l{margin-bottom:.5rem}.swagger-ui .mb3-l{margin-bottom:1rem}.swagger-ui .mb4-l{margin-bottom:2rem}.swagger-ui .mb5-l{margin-bottom:4rem}.swagger-ui .mb6-l{margin-bottom:8rem}.swagger-ui .mb7-l{margin-bottom:16rem}.swagger-ui .mt0-l{margin-top:0}.swagger-ui .mt1-l{margin-top:.25rem}.swagger-ui .mt2-l{margin-top:.5rem}.swagger-ui .mt3-l{margin-top:1rem}.swagger-ui .mt4-l{margin-top:2rem}.swagger-ui .mt5-l{margin-top:4rem}.swagger-ui .mt6-l{margin-top:8rem}.swagger-ui .mt7-l{margin-top:16rem}.swagger-ui .mv0-l{margin-bottom:0;margin-top:0}.swagger-ui .mv1-l{margin-bottom:.25rem;margin-top:.25rem}.swagger-ui .mv2-l{margin-bottom:.5rem;margin-top:.5rem}.swagger-ui .mv3-l{margin-bottom:1rem;margin-top:1rem}.swagger-ui .mv4-l{margin-bottom:2rem;margin-top:2rem}.swagger-ui .mv5-l{margin-bottom:4rem;margin-top:4rem}.swagger-ui .mv6-l{margin-bottom:8rem;margin-top:8rem}.swagger-ui .mv7-l{margin-bottom:16rem;margin-top:16rem}.swagger-ui .mh0-l{margin-left:0;margin-right:0}.swagger-ui .mh1-l{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-l{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-l{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-l{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-l{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-l{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-l{margin-left:16rem;margin-right:16rem}}.swagger-ui .na1{margin:-.25rem}.swagger-ui .na2{margin:-.5rem}.swagger-ui .na3{margin:-1rem}.swagger-ui .na4{margin:-2rem}.swagger-ui .na5{margin:-4rem}.swagger-ui .na6{margin:-8rem}.swagger-ui .na7{margin:-16rem}.swagger-ui .nl1{margin-left:-.25rem}.swagger-ui .nl2{margin-left:-.5rem}.swagger-ui .nl3{margin-left:-1rem}.swagger-ui .nl4{margin-left:-2rem}.swagger-ui .nl5{margin-left:-4rem}.swagger-ui .nl6{margin-left:-8rem}.swagger-ui .nl7{margin-left:-16rem}.swagger-ui .nr1{margin-right:-.25rem}.swagger-ui .nr2{margin-right:-.5rem}.swagger-ui .nr3{margin-right:-1rem}.swagger-ui .nr4{margin-right:-2rem}.swagger-ui .nr5{margin-right:-4rem}.swagger-ui .nr6{margin-right:-8rem}.swagger-ui .nr7{margin-right:-16rem}.swagger-ui .nb1{margin-bottom:-.25rem}.swagger-ui .nb2{margin-bottom:-.5rem}.swagger-ui .nb3{margin-bottom:-1rem}.swagger-ui .nb4{margin-bottom:-2rem}.swagger-ui .nb5{margin-bottom:-4rem}.swagger-ui .nb6{margin-bottom:-8rem}.swagger-ui .nb7{margin-bottom:-16rem}.swagger-ui .nt1{margin-top:-.25rem}.swagger-ui .nt2{margin-top:-.5rem}.swagger-ui .nt3{margin-top:-1rem}.swagger-ui .nt4{margin-top:-2rem}.swagger-ui .nt5{margin-top:-4rem}.swagger-ui .nt6{margin-top:-8rem}.swagger-ui .nt7{margin-top:-16rem}@media screen and (min-width:30em){.swagger-ui .na1-ns{margin:-.25rem}.swagger-ui .na2-ns{margin:-.5rem}.swagger-ui .na3-ns{margin:-1rem}.swagger-ui .na4-ns{margin:-2rem}.swagger-ui .na5-ns{margin:-4rem}.swagger-ui .na6-ns{margin:-8rem}.swagger-ui .na7-ns{margin:-16rem}.swagger-ui .nl1-ns{margin-left:-.25rem}.swagger-ui .nl2-ns{margin-left:-.5rem}.swagger-ui .nl3-ns{margin-left:-1rem}.swagger-ui .nl4-ns{margin-left:-2rem}.swagger-ui .nl5-ns{margin-left:-4rem}.swagger-ui .nl6-ns{margin-left:-8rem}.swagger-ui .nl7-ns{margin-left:-16rem}.swagger-ui .nr1-ns{margin-right:-.25rem}.swagger-ui .nr2-ns{margin-right:-.5rem}.swagger-ui .nr3-ns{margin-right:-1rem}.swagger-ui .nr4-ns{margin-right:-2rem}.swagger-ui .nr5-ns{margin-right:-4rem}.swagger-ui .nr6-ns{margin-right:-8rem}.swagger-ui .nr7-ns{margin-right:-16rem}.swagger-ui .nb1-ns{margin-bottom:-.25rem}.swagger-ui .nb2-ns{margin-bottom:-.5rem}.swagger-ui .nb3-ns{margin-bottom:-1rem}.swagger-ui .nb4-ns{margin-bottom:-2rem}.swagger-ui .nb5-ns{margin-bottom:-4rem}.swagger-ui .nb6-ns{margin-bottom:-8rem}.swagger-ui .nb7-ns{margin-bottom:-16rem}.swagger-ui .nt1-ns{margin-top:-.25rem}.swagger-ui .nt2-ns{margin-top:-.5rem}.swagger-ui .nt3-ns{margin-top:-1rem}.swagger-ui .nt4-ns{margin-top:-2rem}.swagger-ui .nt5-ns{margin-top:-4rem}.swagger-ui .nt6-ns{margin-top:-8rem}.swagger-ui .nt7-ns{margin-top:-16rem}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .na1-m{margin:-.25rem}.swagger-ui .na2-m{margin:-.5rem}.swagger-ui .na3-m{margin:-1rem}.swagger-ui .na4-m{margin:-2rem}.swagger-ui .na5-m{margin:-4rem}.swagger-ui .na6-m{margin:-8rem}.swagger-ui .na7-m{margin:-16rem}.swagger-ui .nl1-m{margin-left:-.25rem}.swagger-ui .nl2-m{margin-left:-.5rem}.swagger-ui .nl3-m{margin-left:-1rem}.swagger-ui .nl4-m{margin-left:-2rem}.swagger-ui .nl5-m{margin-left:-4rem}.swagger-ui .nl6-m{margin-left:-8rem}.swagger-ui .nl7-m{margin-left:-16rem}.swagger-ui .nr1-m{margin-right:-.25rem}.swagger-ui .nr2-m{margin-right:-.5rem}.swagger-ui .nr3-m{margin-right:-1rem}.swagger-ui .nr4-m{margin-right:-2rem}.swagger-ui .nr5-m{margin-right:-4rem}.swagger-ui .nr6-m{margin-right:-8rem}.swagger-ui .nr7-m{margin-right:-16rem}.swagger-ui .nb1-m{margin-bottom:-.25rem}.swagger-ui .nb2-m{margin-bottom:-.5rem}.swagger-ui .nb3-m{margin-bottom:-1rem}.swagger-ui .nb4-m{margin-bottom:-2rem}.swagger-ui .nb5-m{margin-bottom:-4rem}.swagger-ui .nb6-m{margin-bottom:-8rem}.swagger-ui .nb7-m{margin-bottom:-16rem}.swagger-ui .nt1-m{margin-top:-.25rem}.swagger-ui .nt2-m{margin-top:-.5rem}.swagger-ui .nt3-m{margin-top:-1rem}.swagger-ui .nt4-m{margin-top:-2rem}.swagger-ui .nt5-m{margin-top:-4rem}.swagger-ui .nt6-m{margin-top:-8rem}.swagger-ui .nt7-m{margin-top:-16rem}}@media screen and (min-width:60em){.swagger-ui .na1-l{margin:-.25rem}.swagger-ui .na2-l{margin:-.5rem}.swagger-ui .na3-l{margin:-1rem}.swagger-ui .na4-l{margin:-2rem}.swagger-ui .na5-l{margin:-4rem}.swagger-ui .na6-l{margin:-8rem}.swagger-ui .na7-l{margin:-16rem}.swagger-ui .nl1-l{margin-left:-.25rem}.swagger-ui .nl2-l{margin-left:-.5rem}.swagger-ui .nl3-l{margin-left:-1rem}.swagger-ui .nl4-l{margin-left:-2rem}.swagger-ui .nl5-l{margin-left:-4rem}.swagger-ui .nl6-l{margin-left:-8rem}.swagger-ui .nl7-l{margin-left:-16rem}.swagger-ui .nr1-l{margin-right:-.25rem}.swagger-ui .nr2-l{margin-right:-.5rem}.swagger-ui .nr3-l{margin-right:-1rem}.swagger-ui .nr4-l{margin-right:-2rem}.swagger-ui .nr5-l{margin-right:-4rem}.swagger-ui .nr6-l{margin-right:-8rem}.swagger-ui .nr7-l{margin-right:-16rem}.swagger-ui .nb1-l{margin-bottom:-.25rem}.swagger-ui .nb2-l{margin-bottom:-.5rem}.swagger-ui .nb3-l{margin-bottom:-1rem}.swagger-ui .nb4-l{margin-bottom:-2rem}.swagger-ui .nb5-l{margin-bottom:-4rem}.swagger-ui .nb6-l{margin-bottom:-8rem}.swagger-ui .nb7-l{margin-bottom:-16rem}.swagger-ui .nt1-l{margin-top:-.25rem}.swagger-ui .nt2-l{margin-top:-.5rem}.swagger-ui .nt3-l{margin-top:-1rem}.swagger-ui .nt4-l{margin-top:-2rem}.swagger-ui .nt5-l{margin-top:-4rem}.swagger-ui .nt6-l{margin-top:-8rem}.swagger-ui .nt7-l{margin-top:-16rem}}.swagger-ui .collapse{border-collapse:collapse;border-spacing:0}.swagger-ui .striped--light-silver:nth-child(odd){background-color:#aaa}.swagger-ui .striped--moon-gray:nth-child(odd){background-color:#ccc}.swagger-ui .striped--light-gray:nth-child(odd){background-color:#eee}.swagger-ui .striped--near-white:nth-child(odd){background-color:#f4f4f4}.swagger-ui .stripe-light:nth-child(odd){background-color:hsla(0,0%,100%,.1)}.swagger-ui .stripe-dark:nth-child(odd){background-color:rgba(0,0,0,.1)}.swagger-ui .strike{text-decoration:line-through}.swagger-ui .underline{text-decoration:underline}.swagger-ui .no-underline{text-decoration:none}@media screen and (min-width:30em){.swagger-ui .strike-ns{text-decoration:line-through}.swagger-ui .underline-ns{text-decoration:underline}.swagger-ui .no-underline-ns{text-decoration:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .strike-m{text-decoration:line-through}.swagger-ui .underline-m{text-decoration:underline}.swagger-ui .no-underline-m{text-decoration:none}}@media screen and (min-width:60em){.swagger-ui .strike-l{text-decoration:line-through}.swagger-ui .underline-l{text-decoration:underline}.swagger-ui .no-underline-l{text-decoration:none}}.swagger-ui .tl{text-align:left}.swagger-ui .tr{text-align:right}.swagger-ui .tc{text-align:center}.swagger-ui .tj{text-align:justify}@media screen and (min-width:30em){.swagger-ui .tl-ns{text-align:left}.swagger-ui .tr-ns{text-align:right}.swagger-ui .tc-ns{text-align:center}.swagger-ui .tj-ns{text-align:justify}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .tl-m{text-align:left}.swagger-ui .tr-m{text-align:right}.swagger-ui .tc-m{text-align:center}.swagger-ui .tj-m{text-align:justify}}@media screen and (min-width:60em){.swagger-ui .tl-l{text-align:left}.swagger-ui .tr-l{text-align:right}.swagger-ui .tc-l{text-align:center}.swagger-ui .tj-l{text-align:justify}}.swagger-ui .ttc{text-transform:capitalize}.swagger-ui .ttl{text-transform:lowercase}.swagger-ui .ttu{text-transform:uppercase}.swagger-ui .ttn{text-transform:none}@media screen and (min-width:30em){.swagger-ui .ttc-ns{text-transform:capitalize}.swagger-ui .ttl-ns{text-transform:lowercase}.swagger-ui .ttu-ns{text-transform:uppercase}.swagger-ui .ttn-ns{text-transform:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .ttc-m{text-transform:capitalize}.swagger-ui .ttl-m{text-transform:lowercase}.swagger-ui .ttu-m{text-transform:uppercase}.swagger-ui .ttn-m{text-transform:none}}@media screen and (min-width:60em){.swagger-ui .ttc-l{text-transform:capitalize}.swagger-ui .ttl-l{text-transform:lowercase}.swagger-ui .ttu-l{text-transform:uppercase}.swagger-ui .ttn-l{text-transform:none}}.swagger-ui .f-6,.swagger-ui .f-headline{font-size:6rem}.swagger-ui .f-5,.swagger-ui .f-subheadline{font-size:5rem}.swagger-ui .f1{font-size:3rem}.swagger-ui .f2{font-size:2.25rem}.swagger-ui .f3{font-size:1.5rem}.swagger-ui .f4{font-size:1.25rem}.swagger-ui .f5{font-size:1rem}.swagger-ui .f6{font-size:.875rem}.swagger-ui .f7{font-size:.75rem}@media screen and (min-width:30em){.swagger-ui .f-6-ns,.swagger-ui .f-headline-ns{font-size:6rem}.swagger-ui .f-5-ns,.swagger-ui .f-subheadline-ns{font-size:5rem}.swagger-ui .f1-ns{font-size:3rem}.swagger-ui .f2-ns{font-size:2.25rem}.swagger-ui .f3-ns{font-size:1.5rem}.swagger-ui .f4-ns{font-size:1.25rem}.swagger-ui .f5-ns{font-size:1rem}.swagger-ui .f6-ns{font-size:.875rem}.swagger-ui .f7-ns{font-size:.75rem}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .f-6-m,.swagger-ui .f-headline-m{font-size:6rem}.swagger-ui .f-5-m,.swagger-ui .f-subheadline-m{font-size:5rem}.swagger-ui .f1-m{font-size:3rem}.swagger-ui .f2-m{font-size:2.25rem}.swagger-ui .f3-m{font-size:1.5rem}.swagger-ui .f4-m{font-size:1.25rem}.swagger-ui .f5-m{font-size:1rem}.swagger-ui .f6-m{font-size:.875rem}.swagger-ui .f7-m{font-size:.75rem}}@media screen and (min-width:60em){.swagger-ui .f-6-l,.swagger-ui .f-headline-l{font-size:6rem}.swagger-ui .f-5-l,.swagger-ui .f-subheadline-l{font-size:5rem}.swagger-ui .f1-l{font-size:3rem}.swagger-ui .f2-l{font-size:2.25rem}.swagger-ui .f3-l{font-size:1.5rem}.swagger-ui .f4-l{font-size:1.25rem}.swagger-ui .f5-l{font-size:1rem}.swagger-ui .f6-l{font-size:.875rem}.swagger-ui .f7-l{font-size:.75rem}}.swagger-ui .measure{max-width:30em}.swagger-ui .measure-wide{max-width:34em}.swagger-ui .measure-narrow{max-width:20em}.swagger-ui .indent{margin-bottom:0;margin-top:0;text-indent:1em}.swagger-ui .small-caps{font-feature-settings:"smcp";font-variant:small-caps}.swagger-ui .truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media screen and (min-width:30em){.swagger-ui .measure-ns{max-width:30em}.swagger-ui .measure-wide-ns{max-width:34em}.swagger-ui .measure-narrow-ns{max-width:20em}.swagger-ui .indent-ns{margin-bottom:0;margin-top:0;text-indent:1em}.swagger-ui .small-caps-ns{font-feature-settings:"smcp";font-variant:small-caps}.swagger-ui .truncate-ns{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .measure-m{max-width:30em}.swagger-ui .measure-wide-m{max-width:34em}.swagger-ui .measure-narrow-m{max-width:20em}.swagger-ui .indent-m{margin-bottom:0;margin-top:0;text-indent:1em}.swagger-ui .small-caps-m{font-feature-settings:"smcp";font-variant:small-caps}.swagger-ui .truncate-m{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}@media screen and (min-width:60em){.swagger-ui .measure-l{max-width:30em}.swagger-ui .measure-wide-l{max-width:34em}.swagger-ui .measure-narrow-l{max-width:20em}.swagger-ui .indent-l{margin-bottom:0;margin-top:0;text-indent:1em}.swagger-ui .small-caps-l{font-feature-settings:"smcp";font-variant:small-caps}.swagger-ui .truncate-l{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}.swagger-ui .overflow-container{overflow-y:scroll}.swagger-ui .center{margin-left:auto;margin-right:auto}.swagger-ui .mr-auto{margin-right:auto}.swagger-ui .ml-auto{margin-left:auto}@media screen and (min-width:30em){.swagger-ui .center-ns{margin-left:auto;margin-right:auto}.swagger-ui .mr-auto-ns{margin-right:auto}.swagger-ui .ml-auto-ns{margin-left:auto}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .center-m{margin-left:auto;margin-right:auto}.swagger-ui .mr-auto-m{margin-right:auto}.swagger-ui .ml-auto-m{margin-left:auto}}@media screen and (min-width:60em){.swagger-ui .center-l{margin-left:auto;margin-right:auto}.swagger-ui .mr-auto-l{margin-right:auto}.swagger-ui .ml-auto-l{margin-left:auto}}.swagger-ui .clip{clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);position:fixed!important;_position:absolute!important}@media screen and (min-width:30em){.swagger-ui .clip-ns{clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);position:fixed!important;_position:absolute!important}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .clip-m{clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);position:fixed!important;_position:absolute!important}}@media screen and (min-width:60em){.swagger-ui .clip-l{clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);position:fixed!important;_position:absolute!important}}.swagger-ui .ws-normal{white-space:normal}.swagger-ui .nowrap{white-space:nowrap}.swagger-ui .pre{white-space:pre}@media screen and (min-width:30em){.swagger-ui .ws-normal-ns{white-space:normal}.swagger-ui .nowrap-ns{white-space:nowrap}.swagger-ui .pre-ns{white-space:pre}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .ws-normal-m{white-space:normal}.swagger-ui .nowrap-m{white-space:nowrap}.swagger-ui .pre-m{white-space:pre}}@media screen and (min-width:60em){.swagger-ui .ws-normal-l{white-space:normal}.swagger-ui .nowrap-l{white-space:nowrap}.swagger-ui .pre-l{white-space:pre}}.swagger-ui .v-base{vertical-align:baseline}.swagger-ui .v-mid{vertical-align:middle}.swagger-ui .v-top{vertical-align:top}.swagger-ui .v-btm{vertical-align:bottom}@media screen and (min-width:30em){.swagger-ui .v-base-ns{vertical-align:baseline}.swagger-ui .v-mid-ns{vertical-align:middle}.swagger-ui .v-top-ns{vertical-align:top}.swagger-ui .v-btm-ns{vertical-align:bottom}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .v-base-m{vertical-align:baseline}.swagger-ui .v-mid-m{vertical-align:middle}.swagger-ui .v-top-m{vertical-align:top}.swagger-ui .v-btm-m{vertical-align:bottom}}@media screen and (min-width:60em){.swagger-ui .v-base-l{vertical-align:baseline}.swagger-ui .v-mid-l{vertical-align:middle}.swagger-ui .v-top-l{vertical-align:top}.swagger-ui .v-btm-l{vertical-align:bottom}}.swagger-ui .dim{opacity:1;transition:opacity .15s ease-in}.swagger-ui .dim:focus,.swagger-ui .dim:hover{opacity:.5;transition:opacity .15s ease-in}.swagger-ui .dim:active{opacity:.8;transition:opacity .15s ease-out}.swagger-ui .glow{transition:opacity .15s ease-in}.swagger-ui .glow:focus,.swagger-ui .glow:hover{opacity:1;transition:opacity .15s ease-in}.swagger-ui .hide-child .child{opacity:0;transition:opacity .15s ease-in}.swagger-ui .hide-child:active .child,.swagger-ui .hide-child:focus .child,.swagger-ui .hide-child:hover .child{opacity:1;transition:opacity .15s ease-in}.swagger-ui .underline-hover:focus,.swagger-ui .underline-hover:hover{text-decoration:underline}.swagger-ui .grow{-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden;backface-visibility:hidden;transform:translateZ(0);transition:transform .25s ease-out}.swagger-ui .grow:focus,.swagger-ui .grow:hover{transform:scale(1.05)}.swagger-ui .grow:active{transform:scale(.9)}.swagger-ui .grow-large{-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden;backface-visibility:hidden;transform:translateZ(0);transition:transform .25s ease-in-out}.swagger-ui .grow-large:focus,.swagger-ui .grow-large:hover{transform:scale(1.2)}.swagger-ui .grow-large:active{transform:scale(.95)}.swagger-ui .pointer:hover{cursor:pointer}.swagger-ui .shadow-hover{cursor:pointer;position:relative;transition:all .5s cubic-bezier(.165,.84,.44,1)}.swagger-ui .shadow-hover:after{border-radius:inherit;box-shadow:0 0 16px 2px rgba(0,0,0,.2);content:"";height:100%;left:0;opacity:0;position:absolute;top:0;transition:opacity .5s cubic-bezier(.165,.84,.44,1);width:100%;z-index:-1}.swagger-ui .shadow-hover:focus:after,.swagger-ui .shadow-hover:hover:after{opacity:1}.swagger-ui .bg-animate,.swagger-ui .bg-animate:focus,.swagger-ui .bg-animate:hover{transition:background-color .15s ease-in-out}.swagger-ui .z-0{z-index:0}.swagger-ui .z-1{z-index:1}.swagger-ui .z-2{z-index:2}.swagger-ui .z-3{z-index:3}.swagger-ui .z-4{z-index:4}.swagger-ui .z-5{z-index:5}.swagger-ui .z-999{z-index:999}.swagger-ui .z-9999{z-index:9999}.swagger-ui .z-max{z-index:2147483647}.swagger-ui .z-inherit{z-index:inherit}.swagger-ui .z-initial{z-index:auto}.swagger-ui .z-unset{z-index:unset}.swagger-ui .nested-copy-line-height ol,.swagger-ui .nested-copy-line-height p,.swagger-ui .nested-copy-line-height ul{line-height:1.5}.swagger-ui .nested-headline-line-height h1,.swagger-ui .nested-headline-line-height h2,.swagger-ui .nested-headline-line-height h3,.swagger-ui .nested-headline-line-height h4,.swagger-ui .nested-headline-line-height h5,.swagger-ui .nested-headline-line-height h6{line-height:1.25}.swagger-ui .nested-list-reset ol,.swagger-ui .nested-list-reset ul{list-style-type:none;margin-left:0;padding-left:0}.swagger-ui .nested-copy-indent p+p{margin-bottom:0;margin-top:0;text-indent:.1em}.swagger-ui .nested-copy-seperator p+p{margin-top:1.5em}.swagger-ui .nested-img img{display:block;max-width:100%;width:100%}.swagger-ui .nested-links a{color:#357edd;transition:color .15s ease-in}.swagger-ui .nested-links a:focus,.swagger-ui .nested-links a:hover{color:#96ccff;transition:color .15s ease-in}.swagger-ui .wrapper{box-sizing:border-box;margin:0 auto;max-width:1460px;padding:0 20px;width:100%}.swagger-ui .opblock-tag-section{display:flex;flex-direction:column}.swagger-ui .try-out.btn-group{display:flex;flex:0.1 2 auto;padding:0}.swagger-ui .try-out__btn{margin-left:1.25rem}.swagger-ui .opblock-tag{align-items:center;border-bottom:1px solid rgba(59,65,81,.3);cursor:pointer;display:flex;padding:10px 20px 10px 10px;transition:all .2s}.swagger-ui .opblock-tag:hover{background:rgba(0,0,0,.02)}.swagger-ui .opblock-tag{color:#3b4151;font-family:sans-serif;font-size:24px;margin:0 0 5px}.swagger-ui .opblock-tag.no-desc span{flex:1}.swagger-ui .opblock-tag svg{transition:all .4s}.swagger-ui .opblock-tag small{color:#3b4151;flex:1;font-family:sans-serif;font-size:14px;font-weight:400;padding:0 10px}.swagger-ui .parameter__type{color:#3b4151;font-family:monospace;font-size:12px;font-weight:600;padding:5px 0}.swagger-ui .parameter-controls{margin-top:.75em}.swagger-ui .examples__title{display:block;font-size:1.1em;font-weight:700;margin-bottom:.75em}.swagger-ui .examples__section{margin-top:1.5em}.swagger-ui .examples__section-header{font-size:.9rem;font-weight:700;margin-bottom:.5rem}.swagger-ui .examples-select{display:inline-block;margin-bottom:.75em}.swagger-ui .examples-select .examples-select-element{width:100%}.swagger-ui .examples-select__section-label{font-size:.9rem;font-weight:700;margin-right:.5rem}.swagger-ui .example__section{margin-top:1.5em}.swagger-ui .example__section-header{font-size:.9rem;font-weight:700;margin-bottom:.5rem}.swagger-ui .view-line-link{cursor:pointer;margin:0 5px;position:relative;top:3px;transition:all .5s;width:20px}.swagger-ui .opblock{border:1px solid #000;border-radius:4px;box-shadow:0 0 3px rgba(0,0,0,.19);margin:0 0 15px}.swagger-ui .opblock .tab-header{display:flex;flex:1}.swagger-ui .opblock .tab-header .tab-item{cursor:pointer;padding:0 40px}.swagger-ui .opblock .tab-header .tab-item:first-of-type{padding:0 40px 0 0}.swagger-ui .opblock .tab-header .tab-item.active h4 span{position:relative}.swagger-ui .opblock .tab-header .tab-item.active h4 span:after{background:gray;bottom:-15px;content:"";height:4px;left:50%;position:absolute;transform:translateX(-50%);width:120%}.swagger-ui .opblock.is-open .opblock-summary{border-bottom:1px solid #000}.swagger-ui .opblock .opblock-section-header{align-items:center;background:hsla(0,0%,100%,.8);box-shadow:0 1px 2px rgba(0,0,0,.1);display:flex;min-height:50px;padding:8px 20px}.swagger-ui .opblock .opblock-section-header>label{align-items:center;color:#3b4151;display:flex;font-family:sans-serif;font-size:12px;font-weight:700;margin:0 0 0 auto}.swagger-ui .opblock .opblock-section-header>label>span{padding:0 10px 0 0}.swagger-ui .opblock .opblock-section-header h4{color:#3b4151;flex:1;font-family:sans-serif;font-size:14px;margin:0}.swagger-ui .opblock .opblock-summary-method{background:#000;border-radius:3px;color:#fff;font-family:sans-serif;font-size:14px;font-weight:700;min-width:80px;padding:6px 0;text-align:center;text-shadow:0 1px 0 rgba(0,0,0,.1)}.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{align-items:center;color:#3b4151;display:flex;font-family:monospace;font-size:16px;font-weight:600;padding:0 10px;word-break:break-word}@media (max-width:768px){.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{font-size:12px}}.swagger-ui .opblock .opblock-summary-path{flex-shrink:0;max-width:calc(100% - 110px - 15rem)}.swagger-ui .opblock .opblock-summary-path__deprecated{text-decoration:line-through}.swagger-ui .opblock .opblock-summary-operation-id{font-size:14px}.swagger-ui .opblock .opblock-summary-description{color:#3b4151;flex:1 1 auto;font-family:sans-serif;font-size:13px;word-break:break-word}.swagger-ui .opblock .opblock-summary{align-items:center;cursor:pointer;display:flex;padding:5px}.swagger-ui .opblock .opblock-summary .view-line-link{cursor:pointer;margin:0;position:relative;top:2px;transition:all .5s;width:0}.swagger-ui .opblock .opblock-summary:hover .view-line-link{margin:0 5px;width:18px}.swagger-ui .opblock.opblock-post{background:rgba(73,204,144,.1);border-color:#49cc90}.swagger-ui .opblock.opblock-post .opblock-summary-method{background:#49cc90}.swagger-ui .opblock.opblock-post .opblock-summary{border-color:#49cc90}.swagger-ui .opblock.opblock-post .tab-header .tab-item.active h4 span:after{background:#49cc90}.swagger-ui .opblock.opblock-put{background:rgba(252,161,48,.1);border-color:#fca130}.swagger-ui .opblock.opblock-put .opblock-summary-method{background:#fca130}.swagger-ui .opblock.opblock-put .opblock-summary{border-color:#fca130}.swagger-ui .opblock.opblock-put .tab-header .tab-item.active h4 span:after{background:#fca130}.swagger-ui .opblock.opblock-delete{background:rgba(249,62,62,.1);border-color:#f93e3e}.swagger-ui .opblock.opblock-delete .opblock-summary-method{background:#f93e3e}.swagger-ui .opblock.opblock-delete .opblock-summary{border-color:#f93e3e}.swagger-ui .opblock.opblock-delete .tab-header .tab-item.active h4 span:after{background:#f93e3e}.swagger-ui .opblock.opblock-get{background:rgba(97,175,254,.1);border-color:#61affe}.swagger-ui .opblock.opblock-get .opblock-summary-method{background:#61affe}.swagger-ui .opblock.opblock-get .opblock-summary{border-color:#61affe}.swagger-ui .opblock.opblock-get .tab-header .tab-item.active h4 span:after{background:#61affe}.swagger-ui .opblock.opblock-patch{background:rgba(80,227,194,.1);border-color:#50e3c2}.swagger-ui .opblock.opblock-patch .opblock-summary-method{background:#50e3c2}.swagger-ui .opblock.opblock-patch .opblock-summary{border-color:#50e3c2}.swagger-ui .opblock.opblock-patch .tab-header .tab-item.active h4 span:after{background:#50e3c2}.swagger-ui .opblock.opblock-head{background:rgba(144,18,254,.1);border-color:#9012fe}.swagger-ui .opblock.opblock-head .opblock-summary-method{background:#9012fe}.swagger-ui .opblock.opblock-head .opblock-summary{border-color:#9012fe}.swagger-ui .opblock.opblock-head .tab-header .tab-item.active h4 span:after{background:#9012fe}.swagger-ui .opblock.opblock-options{background:rgba(13,90,167,.1);border-color:#0d5aa7}.swagger-ui .opblock.opblock-options .opblock-summary-method{background:#0d5aa7}.swagger-ui .opblock.opblock-options .opblock-summary{border-color:#0d5aa7}.swagger-ui .opblock.opblock-options .tab-header .tab-item.active h4 span:after{background:#0d5aa7}.swagger-ui .opblock.opblock-deprecated{background:hsla(0,0%,92%,.1);border-color:#ebebeb;opacity:.6}.swagger-ui .opblock.opblock-deprecated .opblock-summary-method{background:#ebebeb}.swagger-ui .opblock.opblock-deprecated .opblock-summary{border-color:#ebebeb}.swagger-ui .opblock.opblock-deprecated .tab-header .tab-item.active h4 span:after{background:#ebebeb}.swagger-ui .opblock .opblock-schemes{padding:8px 20px}.swagger-ui .opblock .opblock-schemes .schemes-title{padding:0 10px 0 0}.swagger-ui .filter .operation-filter-input{border:2px solid #d8dde7;margin:20px 0;padding:10px;width:100%}.swagger-ui .download-url-wrapper .failed,.swagger-ui .filter .failed{color:red}.swagger-ui .download-url-wrapper .loading,.swagger-ui .filter .loading{color:#aaa}.swagger-ui .model-example{margin-top:1em}.swagger-ui .tab{display:flex;list-style:none;padding:0}.swagger-ui .tab li{color:#3b4151;cursor:pointer;font-family:sans-serif;font-size:12px;min-width:60px;padding:0}.swagger-ui .tab li:first-of-type{padding-left:0;padding-right:12px;position:relative}.swagger-ui .tab li:first-of-type:after{background:rgba(0,0,0,.2);content:"";height:100%;position:absolute;right:6px;top:0;width:1px}.swagger-ui .tab li.active{font-weight:700}.swagger-ui .tab li button.tablinks{background:none;border:0;color:inherit;font-family:inherit;font-weight:inherit;padding:0}.swagger-ui .opblock-description-wrapper,.swagger-ui .opblock-external-docs-wrapper,.swagger-ui .opblock-title_normal{color:#3b4151;font-family:sans-serif;font-size:12px;margin:0 0 5px;padding:15px 20px}.swagger-ui .opblock-description-wrapper h4,.swagger-ui .opblock-external-docs-wrapper h4,.swagger-ui .opblock-title_normal h4{color:#3b4151;font-family:sans-serif;font-size:12px;margin:0 0 5px}.swagger-ui .opblock-description-wrapper p,.swagger-ui .opblock-external-docs-wrapper p,.swagger-ui .opblock-title_normal p{color:#3b4151;font-family:sans-serif;font-size:14px;margin:0}.swagger-ui .opblock-external-docs-wrapper h4{padding-left:0}.swagger-ui .execute-wrapper{padding:20px;text-align:right}.swagger-ui .execute-wrapper .btn{padding:8px 40px;width:100%}.swagger-ui .body-param-options{display:flex;flex-direction:column}.swagger-ui .body-param-options .body-param-edit{padding:10px 0}.swagger-ui .body-param-options label{padding:8px 0}.swagger-ui .body-param-options label select{margin:3px 0 0}.swagger-ui .responses-inner{padding:20px}.swagger-ui .responses-inner h4,.swagger-ui .responses-inner h5{color:#3b4151;font-family:sans-serif;font-size:12px;margin:10px 0 5px}.swagger-ui .responses-inner .curl{white-space:normal}.swagger-ui .response-col_status{color:#3b4151;font-family:sans-serif;font-size:14px}.swagger-ui .response-col_status .response-undocumented{color:#909090;font-family:monospace;font-size:11px;font-weight:600}.swagger-ui .response-col_links{color:#3b4151;font-family:sans-serif;font-size:14px;max-width:40em;padding-left:2em}.swagger-ui .response-col_links .response-undocumented{color:#909090;font-family:monospace;font-size:11px;font-weight:600}.swagger-ui .response-col_links .operation-link{margin-bottom:1.5em}.swagger-ui .response-col_links .operation-link .description{margin-bottom:.5em}.swagger-ui .opblock-body .opblock-loading-animation{display:block;margin:3em auto}.swagger-ui .opblock-body pre.microlight{word-wrap:break-word;background:#333;border-radius:4px;color:#fff;font-family:monospace;font-size:12px;font-weight:600;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;margin:0;padding:10px;white-space:pre-wrap;word-break:break-all;word-break:break-word}.swagger-ui .opblock-body pre.microlight .headerline{display:block}.swagger-ui .highlight-code{position:relative}.swagger-ui .highlight-code>.microlight{max-height:400px;min-height:6em;overflow-y:auto}.swagger-ui .highlight-code>.microlight code{white-space:pre-wrap!important;word-break:break-all}.swagger-ui .curl-command{position:relative}.swagger-ui .download-contents{align-items:center;background:#7d8293;border-radius:4px;bottom:10px;color:#fff;cursor:pointer;display:flex;font-family:sans-serif;font-size:14px;font-weight:600;height:30px;justify-content:center;padding:5px;position:absolute;right:10px;text-align:center}.swagger-ui .scheme-container{background:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.15);margin:0 0 20px;padding:30px 0}.swagger-ui .scheme-container .schemes{align-items:flex-end;display:flex}.swagger-ui .scheme-container .schemes>label{color:#3b4151;display:flex;flex-direction:column;font-family:sans-serif;font-size:12px;font-weight:700;margin:-20px 15px 0 0}.swagger-ui .scheme-container .schemes>label select{min-width:130px;text-transform:uppercase}.swagger-ui .loading-container{align-items:center;display:flex;flex-direction:column;justify-content:center;margin-top:1em;min-height:1px;padding:40px 0 60px}.swagger-ui .loading-container .loading{position:relative}.swagger-ui .loading-container .loading:after{color:#3b4151;content:"loading";font-family:sans-serif;font-size:10px;font-weight:700;left:50%;position:absolute;text-transform:uppercase;top:50%;transform:translate(-50%,-50%)}.swagger-ui .loading-container .loading:before{-webkit-animation:rotation 1s linear infinite,opacity .5s;animation:rotation 1s linear infinite,opacity .5s;-webkit-backface-visibility:hidden;backface-visibility:hidden;border:2px solid rgba(85,85,85,.1);border-radius:100%;border-top-color:rgba(0,0,0,.6);content:"";display:block;height:60px;left:50%;margin:-30px;opacity:1;position:absolute;top:50%;width:60px}@-webkit-keyframes rotation{to{transform:rotate(1turn)}}@keyframes rotation{to{transform:rotate(1turn)}}.swagger-ui .response-controls{display:flex;padding-top:1em}.swagger-ui .response-control-media-type{margin-right:1em}.swagger-ui .response-control-media-type--accept-controller select{border-color:green}.swagger-ui .response-control-media-type__accept-message{color:green;font-size:.7em}.swagger-ui .response-control-examples__title,.swagger-ui .response-control-media-type__title{display:block;font-size:.7em;margin-bottom:.2em}@-webkit-keyframes blinker{50%{opacity:0}}@keyframes blinker{50%{opacity:0}}.swagger-ui .hidden{display:none}.swagger-ui .no-margin{border:none;height:auto;margin:0;padding:0}.swagger-ui .float-right{float:right}.swagger-ui .svg-assets{height:0;position:absolute;width:0}.swagger-ui section h3{color:#3b4151;font-family:sans-serif}.swagger-ui a.nostyle{display:inline}.swagger-ui a.nostyle,.swagger-ui a.nostyle:visited{color:inherit;cursor:pointer;text-decoration:inherit}.swagger-ui .fallback{color:#aaa;padding:1em}.swagger-ui .version-pragma{height:100%;padding:5em 0}.swagger-ui .version-pragma__message{display:flex;font-size:1.2em;height:100%;justify-content:center;line-height:1.5em;padding:0 .6em;text-align:center}.swagger-ui .version-pragma__message>div{flex:1;max-width:55ch}.swagger-ui .version-pragma__message code{background-color:#dedede;padding:4px 4px 2px;white-space:pre}.swagger-ui .opblock-link{font-weight:400}.swagger-ui .opblock-link.shown{font-weight:700}.swagger-ui span.token-string{color:#555}.swagger-ui span.token-not-formatted{color:#555;font-weight:700}.swagger-ui .btn{background:transparent;border:2px solid gray;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.1);color:#3b4151;font-family:sans-serif;font-size:14px;font-weight:700;padding:5px 23px;transition:all .3s}.swagger-ui .btn.btn-sm{font-size:12px;padding:4px 23px}.swagger-ui .btn[disabled]{cursor:not-allowed;opacity:.3}.swagger-ui .btn:hover{box-shadow:0 0 5px rgba(0,0,0,.3)}.swagger-ui .btn.cancel{background-color:transparent;border-color:#ff6060;color:#ff6060;font-family:sans-serif}.swagger-ui .btn.authorize{background-color:transparent;border-color:#49cc90;color:#49cc90;display:inline;line-height:1}.swagger-ui .btn.authorize span{float:left;padding:4px 20px 0 0}.swagger-ui .btn.authorize svg{fill:#49cc90}.swagger-ui .btn.execute{background-color:#4990e2;border-color:#4990e2;color:#fff}.swagger-ui .btn-group{display:flex;padding:30px}.swagger-ui .btn-group .btn{flex:1}.swagger-ui .btn-group .btn:first-child{border-radius:4px 0 0 4px}.swagger-ui .btn-group .btn:last-child{border-radius:0 4px 4px 0}.swagger-ui .authorization__btn{background:none;border:none;padding:0 10px}.swagger-ui .authorization__btn.locked{opacity:1}.swagger-ui .authorization__btn.unlocked{opacity:.4}.swagger-ui .model-box-control,.swagger-ui .models-control,.swagger-ui .opblock-summary-control{all:inherit;border-bottom:0;cursor:pointer;flex:1;padding:0}.swagger-ui .model-box-control:focus,.swagger-ui .models-control:focus,.swagger-ui .opblock-summary-control:focus{outline:auto}.swagger-ui .expand-methods,.swagger-ui .expand-operation{background:none;border:none}.swagger-ui .expand-methods svg,.swagger-ui .expand-operation svg{height:20px;width:20px}.swagger-ui .expand-methods{padding:0 10px}.swagger-ui .expand-methods:hover svg{fill:#404040}.swagger-ui .expand-methods svg{fill:#707070;transition:all .3s}.swagger-ui button{cursor:pointer}.swagger-ui button.invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;background:#feebeb;border-color:#f93e3e}.swagger-ui .copy-to-clipboard{align-items:center;background:#7d8293;border:none;border-radius:4px;bottom:10px;display:flex;height:30px;justify-content:center;position:absolute;right:100px;width:30px}.swagger-ui .copy-to-clipboard button{background:url('data:image/svg+xml;charset=utf-8,') 50% no-repeat;border:none;flex-grow:1;flex-shrink:1;height:25px}.swagger-ui .curl-command .copy-to-clipboard{bottom:5px;height:20px;right:10px;width:20px}.swagger-ui .curl-command .copy-to-clipboard button{height:18px}.swagger-ui select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#f7f7f7 url('data:image/svg+xml;charset=utf-8,') right 10px center no-repeat;background-size:20px;border:2px solid #41444e;border-radius:4px;box-shadow:0 1px 2px 0 rgba(0,0,0,.25);color:#3b4151;font-family:sans-serif;font-size:14px;font-weight:700;padding:5px 40px 5px 10px}.swagger-ui select[multiple]{background:#f7f7f7;margin:5px 0;padding:5px}.swagger-ui select.invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;background:#feebeb;border-color:#f93e3e}.swagger-ui .opblock-body select{min-width:230px}@media (max-width:768px){.swagger-ui .opblock-body select{min-width:180px}}.swagger-ui label{color:#3b4151;font-family:sans-serif;font-size:12px;font-weight:700;margin:0 0 5px}@media (max-width:768px){.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text]{max-width:175px}}.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text],.swagger-ui textarea{background:#fff;border:1px solid #d9d9d9;border-radius:4px;margin:5px 0;min-width:100px;padding:8px 10px}.swagger-ui input[type=email].invalid,.swagger-ui input[type=file].invalid,.swagger-ui input[type=password].invalid,.swagger-ui input[type=search].invalid,.swagger-ui input[type=text].invalid,.swagger-ui textarea.invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;background:#feebeb;border-color:#f93e3e}.swagger-ui input[disabled],.swagger-ui select[disabled],.swagger-ui textarea[disabled]{background-color:#fafafa;color:#888;cursor:not-allowed}.swagger-ui select[disabled]{border-color:#888}.swagger-ui textarea[disabled]{background-color:#41444e;color:#fff}@-webkit-keyframes shake{10%,90%{transform:translate3d(-1px,0,0)}20%,80%{transform:translate3d(2px,0,0)}30%,50%,70%{transform:translate3d(-4px,0,0)}40%,60%{transform:translate3d(4px,0,0)}}@keyframes shake{10%,90%{transform:translate3d(-1px,0,0)}20%,80%{transform:translate3d(2px,0,0)}30%,50%,70%{transform:translate3d(-4px,0,0)}40%,60%{transform:translate3d(4px,0,0)}}.swagger-ui textarea{background:hsla(0,0%,100%,.8);border:none;border-radius:4px;color:#3b4151;font-family:monospace;font-size:12px;font-weight:600;min-height:280px;outline:none;padding:10px;width:100%}.swagger-ui textarea:focus{border:2px solid #61affe}.swagger-ui textarea.curl{background:#41444e;border-radius:4px;color:#fff;font-family:monospace;font-size:12px;font-weight:600;margin:0;min-height:100px;padding:10px;resize:none}.swagger-ui .checkbox{color:#303030;padding:5px 0 10px;transition:opacity .5s}.swagger-ui .checkbox label{display:flex}.swagger-ui .checkbox p{color:#3b4151;font-family:monospace;font-style:italic;font-weight:400!important;font-weight:600;margin:0!important}.swagger-ui .checkbox input[type=checkbox]{display:none}.swagger-ui .checkbox input[type=checkbox]+label>.item{background:#e8e8e8;border-radius:1px;box-shadow:0 0 0 2px #e8e8e8;cursor:pointer;display:inline-block;flex:none;height:16px;margin:0 8px 0 0;padding:5px;position:relative;top:3px;width:16px}.swagger-ui .checkbox input[type=checkbox]+label>.item:active{transform:scale(.9)}.swagger-ui .checkbox input[type=checkbox]:checked+label>.item{background:#e8e8e8 url('data:image/svg+xml;charset=utf-8,') 50% no-repeat}.swagger-ui .dialog-ux{bottom:0;left:0;position:fixed;right:0;top:0;z-index:9999}.swagger-ui .dialog-ux .backdrop-ux{background:rgba(0,0,0,.8);bottom:0;left:0;position:fixed;right:0;top:0}.swagger-ui .dialog-ux .modal-ux{background:#fff;border:1px solid #ebebeb;border-radius:4px;box-shadow:0 10px 30px 0 rgba(0,0,0,.2);left:50%;max-width:650px;min-width:300px;position:absolute;top:50%;transform:translate(-50%,-50%);width:100%;z-index:9999}.swagger-ui .dialog-ux .modal-ux-content{max-height:540px;overflow-y:auto;padding:20px}.swagger-ui .dialog-ux .modal-ux-content p{color:#41444e;color:#3b4151;font-family:sans-serif;font-size:12px;margin:0 0 5px}.swagger-ui .dialog-ux .modal-ux-content h4{color:#3b4151;font-family:sans-serif;font-size:18px;font-weight:600;margin:15px 0 0}.swagger-ui .dialog-ux .modal-ux-header{align-items:center;border-bottom:1px solid #ebebeb;display:flex;padding:12px 0}.swagger-ui .dialog-ux .modal-ux-header .close-modal{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:none;padding:0 10px}.swagger-ui .dialog-ux .modal-ux-header h3{color:#3b4151;flex:1;font-family:sans-serif;font-size:20px;font-weight:600;margin:0;padding:0 20px}.swagger-ui .model{color:#3b4151;font-family:monospace;font-size:12px;font-weight:300;font-weight:600}.swagger-ui .model .deprecated span,.swagger-ui .model .deprecated td{color:#a0a0a0!important}.swagger-ui .model .deprecated>td:first-of-type{text-decoration:line-through}.swagger-ui .model-toggle{cursor:pointer;display:inline-block;font-size:10px;margin:auto .3em;position:relative;top:6px;transform:rotate(90deg);transform-origin:50% 50%;transition:transform .15s ease-in}.swagger-ui .model-toggle.collapsed{transform:rotate(0deg)}.swagger-ui .model-toggle:after{background:url('data:image/svg+xml;charset=utf-8,') 50% no-repeat;background-size:100%;content:"";display:block;height:20px;width:20px}.swagger-ui .model-jump-to-path{cursor:pointer;position:relative}.swagger-ui .model-jump-to-path .view-line-link{cursor:pointer;position:absolute;top:-.4em}.swagger-ui .model-title{position:relative}.swagger-ui .model-title:hover .model-hint{visibility:visible}.swagger-ui .model-hint{background:rgba(0,0,0,.7);border-radius:4px;color:#ebebeb;padding:.1em .5em;position:absolute;top:-1.8em;visibility:hidden;white-space:nowrap}.swagger-ui .model p{margin:0 0 1em}.swagger-ui .model .property{color:#999;font-style:italic}.swagger-ui .model .property.primitive{color:#6b6b6b}.swagger-ui table.model tr.description{color:#666;font-weight:400}.swagger-ui table.model tr.description td:first-child,.swagger-ui table.model tr.property-row.required td:first-child{font-weight:700}.swagger-ui table.model tr.property-row td{vertical-align:top}.swagger-ui table.model tr.property-row td:first-child{padding-right:.2em}.swagger-ui table.model tr.property-row .star{color:red}.swagger-ui table.model tr.extension{color:#777}.swagger-ui table.model tr.extension td:last-child{vertical-align:top}.swagger-ui section.models{border:1px solid rgba(59,65,81,.3);border-radius:4px;margin:30px 0}.swagger-ui section.models .pointer{cursor:pointer}.swagger-ui section.models.is-open{padding:0 0 20px}.swagger-ui section.models.is-open h4{border-bottom:1px solid rgba(59,65,81,.3);margin:0 0 5px}.swagger-ui section.models h4{align-items:center;color:#606060;cursor:pointer;display:flex;font-family:sans-serif;font-size:16px;margin:0;padding:10px 20px 10px 10px;transition:all .2s}.swagger-ui section.models h4 svg{transition:all .4s}.swagger-ui section.models h4 span{flex:1}.swagger-ui section.models h4:hover{background:rgba(0,0,0,.02)}.swagger-ui section.models h5{color:#707070;font-family:sans-serif;font-size:16px;margin:0 0 10px}.swagger-ui section.models .model-jump-to-path{position:relative;top:5px}.swagger-ui section.models .model-container{background:rgba(0,0,0,.05);border-radius:4px;margin:0 20px 15px;position:relative;transition:all .5s}.swagger-ui section.models .model-container:hover{background:rgba(0,0,0,.07)}.swagger-ui section.models .model-container:first-of-type{margin:20px}.swagger-ui section.models .model-container:last-of-type{margin:0 20px}.swagger-ui section.models .model-container .models-jump-to-path{opacity:.65;position:absolute;right:5px;top:8px}.swagger-ui section.models .model-box{background:none}.swagger-ui .model-box{background:rgba(0,0,0,.1);border-radius:4px;display:inline-block;padding:10px}.swagger-ui .model-box .model-jump-to-path{position:relative;top:4px}.swagger-ui .model-box.deprecated{opacity:.5}.swagger-ui .model-title{color:#505050;font-family:sans-serif;font-size:16px}.swagger-ui .model-title img{bottom:0;margin-left:1em;position:relative}.swagger-ui .model-deprecated-warning{color:#f93e3e;font-family:sans-serif;font-size:16px;font-weight:600;margin-right:1em}.swagger-ui span>span.model .brace-close{padding:0 0 0 10px}.swagger-ui .prop-name{display:inline-block;margin-right:1em}.swagger-ui .prop-type{color:#55a}.swagger-ui .prop-enum{display:block}.swagger-ui .prop-format{color:#606060}.swagger-ui .servers>label{color:#3b4151;font-family:sans-serif;font-size:12px;margin:-20px 15px 0 0}.swagger-ui .servers>label select{max-width:100%;min-width:130px}.swagger-ui .servers h4.message{padding-bottom:2em}.swagger-ui .servers table tr{width:30em}.swagger-ui .servers table td{display:inline-block;max-width:15em;padding-bottom:10px;padding-top:10px;vertical-align:middle}.swagger-ui .servers table td:first-of-type{padding-right:1em}.swagger-ui .servers table td input{height:100%;width:100%}.swagger-ui .servers .computed-url{margin:2em 0}.swagger-ui .servers .computed-url code{display:inline-block;font-size:16px;margin:0 1em;padding:4px}.swagger-ui .servers-title{font-size:12px;font-weight:700}.swagger-ui .operation-servers h4.message{margin-bottom:2em}.swagger-ui table{border-collapse:collapse;padding:0 10px;width:100%}.swagger-ui table.model tbody tr td{padding:0;vertical-align:top}.swagger-ui table.model tbody tr td:first-of-type{padding:0 0 0 2em;width:174px}.swagger-ui table.headers td{color:#3b4151;font-family:monospace;font-size:12px;font-weight:300;font-weight:600;vertical-align:middle}.swagger-ui table.headers .header-example{color:#999;font-style:italic}.swagger-ui table tbody tr td{padding:10px 0 0;vertical-align:top}.swagger-ui table tbody tr td:first-of-type{min-width:6em;padding:10px 0}.swagger-ui table thead tr td,.swagger-ui table thead tr th{border-bottom:1px solid rgba(59,65,81,.2);color:#3b4151;font-family:sans-serif;font-size:12px;font-weight:700;padding:12px 0;text-align:left}.swagger-ui .parameters-col_description{margin-bottom:2em;width:99%}.swagger-ui .parameters-col_description input[type=text]{max-width:340px;width:100%}.swagger-ui .parameters-col_description select{border-width:1px}.swagger-ui .parameter__name{color:#3b4151;font-family:sans-serif;font-size:16px;font-weight:400;margin-right:.75em}.swagger-ui .parameter__name.required{font-weight:700}.swagger-ui .parameter__name.required span{color:red}.swagger-ui .parameter__name.required:after{color:rgba(255,0,0,.6);content:"required";font-size:10px;padding:5px;position:relative;top:-6px}.swagger-ui .parameter__extension,.swagger-ui .parameter__in{color:gray;font-family:monospace;font-size:12px;font-style:italic;font-weight:600}.swagger-ui .parameter__deprecated{color:red;font-family:monospace;font-size:12px;font-style:italic;font-weight:600}.swagger-ui .parameter__empty_value_toggle{display:block;font-size:13px;padding-bottom:12px;padding-top:5px}.swagger-ui .parameter__empty_value_toggle input{margin-right:7px}.swagger-ui .parameter__empty_value_toggle.disabled{opacity:.7}.swagger-ui .table-container{padding:20px}.swagger-ui .response-col_description{width:99%}.swagger-ui .response-col_links{min-width:6em}.swagger-ui .response__extension{color:gray;font-family:monospace;font-size:12px;font-style:italic;font-weight:600}.swagger-ui .topbar{background-color:#1b1b1b;padding:10px 0}.swagger-ui .topbar .topbar-wrapper,.swagger-ui .topbar a{align-items:center;display:flex}.swagger-ui .topbar a{color:#fff;flex:1;font-family:sans-serif;font-size:1.5em;font-weight:700;max-width:300px;text-decoration:none}.swagger-ui .topbar a span{margin:0;padding:0 10px}.swagger-ui .topbar .download-url-wrapper{display:flex;flex:3;justify-content:flex-end}.swagger-ui .topbar .download-url-wrapper input[type=text]{border:2px solid #62a03f;border-radius:4px 0 0 4px;margin:0;outline:none;width:100%}.swagger-ui .topbar .download-url-wrapper .select-label{align-items:center;color:#f0f0f0;display:flex;margin:0;max-width:600px;width:100%}.swagger-ui .topbar .download-url-wrapper .select-label span{flex:1;font-size:16px;padding:0 10px 0 0;text-align:right}.swagger-ui .topbar .download-url-wrapper .select-label select{border:2px solid #62a03f;box-shadow:none;flex:2;outline:none;width:100%}.swagger-ui .topbar .download-url-wrapper .download-url-button{background:#62a03f;border:none;border-radius:0 4px 4px 0;color:#fff;font-family:sans-serif;font-size:16px;font-weight:700;padding:4px 30px}.swagger-ui .info{margin:50px 0}.swagger-ui .info.failed-config{margin-left:auto;margin-right:auto;max-width:880px;text-align:center}.swagger-ui .info hgroup.main{margin:0 0 20px}.swagger-ui .info hgroup.main a{font-size:12px}.swagger-ui .info pre{font-size:14px}.swagger-ui .info li,.swagger-ui .info p,.swagger-ui .info table{color:#3b4151;font-family:sans-serif;font-size:14px}.swagger-ui .info h1,.swagger-ui .info h2,.swagger-ui .info h3,.swagger-ui .info h4,.swagger-ui .info h5{color:#3b4151;font-family:sans-serif}.swagger-ui .info a{color:#4990e2;font-family:sans-serif;font-size:14px;transition:all .4s}.swagger-ui .info a:hover{color:#1f69c0}.swagger-ui .info>div{margin:0 0 5px}.swagger-ui .info .base-url{color:#3b4151;font-family:monospace;font-size:12px;font-weight:300!important;font-weight:600;margin:0}.swagger-ui .info .title{color:#3b4151;font-family:sans-serif;font-size:36px;margin:0}.swagger-ui .info .title small{background:#7d8492;border-radius:57px;display:inline-block;font-size:10px;margin:0 0 0 5px;padding:2px 4px;position:relative;top:-5px;vertical-align:super}.swagger-ui .info .title small.version-stamp{background-color:#89bf04}.swagger-ui .info .title small pre{color:#fff;font-family:sans-serif;margin:0;padding:0}.swagger-ui .auth-btn-wrapper{display:flex;justify-content:center;padding:10px 0}.swagger-ui .auth-btn-wrapper .btn-done{margin-right:1em}.swagger-ui .auth-wrapper{display:flex;flex:1;justify-content:flex-end}.swagger-ui .auth-wrapper .authorize{margin-right:10px;padding-right:20px}.swagger-ui .auth-container{border-bottom:1px solid #ebebeb;margin:0 0 10px;padding:10px 20px}.swagger-ui .auth-container:last-of-type{border:0;margin:0;padding:10px 20px}.swagger-ui .auth-container h4{margin:5px 0 15px!important}.swagger-ui .auth-container .wrapper{margin:0;padding:0}.swagger-ui .auth-container input[type=password],.swagger-ui .auth-container input[type=text]{min-width:230px}.swagger-ui .auth-container .errors{background-color:#fee;border-radius:4px;color:red;color:#3b4151;font-family:monospace;font-size:12px;font-weight:600;margin:1em;padding:10px}.swagger-ui .auth-container .errors b{margin-right:1em;text-transform:capitalize}.swagger-ui .scopes h2{color:#3b4151;font-family:sans-serif;font-size:14px}.swagger-ui .scopes h2 a{color:#4990e2;cursor:pointer;font-size:12px;padding-left:10px;text-decoration:underline}.swagger-ui .scope-def{padding:0 0 20px}.swagger-ui .errors-wrapper{-webkit-animation:scaleUp .5s;animation:scaleUp .5s;background:rgba(249,62,62,.1);border:2px solid #f93e3e;border-radius:4px;margin:20px;padding:10px 20px}.swagger-ui .errors-wrapper .error-wrapper{margin:0 0 10px}.swagger-ui .errors-wrapper .errors h4{color:#3b4151;font-family:monospace;font-size:14px;font-weight:600;margin:0}.swagger-ui .errors-wrapper .errors small{color:#606060}.swagger-ui .errors-wrapper .errors .message{white-space:pre-line}.swagger-ui .errors-wrapper .errors .message.thrown{max-width:100%}.swagger-ui .errors-wrapper .errors .error-line{cursor:pointer;text-decoration:underline}.swagger-ui .errors-wrapper hgroup{align-items:center;display:flex}.swagger-ui .errors-wrapper hgroup h4{color:#3b4151;flex:1;font-family:sans-serif;font-size:20px;margin:0}@-webkit-keyframes scaleUp{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes scaleUp{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}.swagger-ui .Resizer.vertical.disabled{display:none}.swagger-ui .markdown p,.swagger-ui .markdown pre,.swagger-ui .renderedMarkdown p,.swagger-ui .renderedMarkdown pre{margin:1em auto;word-break:break-all;word-break:break-word}.swagger-ui .markdown pre,.swagger-ui .renderedMarkdown pre{background:none;color:#000;font-weight:400;padding:0;white-space:pre-wrap}.swagger-ui .markdown code,.swagger-ui .renderedMarkdown code{background:rgba(0,0,0,.05);border-radius:4px;color:#9012fe;font-family:monospace;font-size:14px;font-weight:600;padding:5px 7px}.swagger-ui .markdown pre>code,.swagger-ui .renderedMarkdown pre>code{display:block} - -/*# sourceMappingURL=swagger-ui.css.map*/ \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/application.yml b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/application.yml index 5d3c8b3af5..7d1618b4e7 100644 --- a/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/application.yml +++ b/spring-boot-modules/spring-boot-swagger-keycloak/src/main/resources/application.yml @@ -1,8 +1,19 @@ +server: + port: 8081 + keycloak: - auth-server-url: https://api.example.com/auth # Keycloak server url - realm: todos-service-realm # Keycloak Realm - resource: todos-service-clients # Keycloak Client - principal-attribute: preferred_username - ssl-required: external - credentials: - secret: 00000000-0000-0000-0000-000000000000 + auth-server-url: http://localhost:8080 # Keycloak server url + realm: SpringBootKeycloak # Keycloak Realm + +spring: + security: + oauth2: + resourceserver: + jwt.issuer-uri: http://localhost:8080/realms/SpringBootKeycloak + +springdoc: + swagger-ui: + oauth: + client-id: login-app + + diff --git a/spring-boot-modules/spring-boot-testing/pom.xml b/spring-boot-modules/spring-boot-testing/pom.xml index f54a1964f9..ace6307761 100644 --- a/spring-boot-modules/spring-boot-testing/pom.xml +++ b/spring-boot-modules/spring-boot-testing/pom.xml @@ -148,7 +148,7 @@ com.baeldung.boot.Application 2.2.4 2.4-M1-groovy-4.0 - 2.0.0 + 2.1.0 3.10.1 0.7.2 2.5.0 diff --git a/spring-boot-modules/spring-boot-validation/README.md b/spring-boot-modules/spring-boot-validation/README.md index 93b6e7d2d1..f20f846b60 100644 --- a/spring-boot-modules/spring-boot-validation/README.md +++ b/spring-boot-modules/spring-boot-validation/README.md @@ -2,3 +2,4 @@ - [Spring Validation in the Service Layer](https://www.baeldung.com/spring-service-layer-validation) - [Validation in Spring Boot](https://www.baeldung.com/spring-boot-bean-validation) +- [Spring Null-Safety Annotations](https://www.baeldung.com/spring-null-safety-annotations) \ No newline at end of file diff --git a/spring-core-2/src/main/java/com/baeldung/nullibility/Person.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/nullibility/Person.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/nullibility/Person.java rename to spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/nullibility/Person.java diff --git a/spring-core-2/src/main/java/com/baeldung/nullibility/package-info.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/nullibility/package-info.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/nullibility/package-info.java rename to spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/nullibility/package-info.java diff --git a/spring-boot-modules/spring-caching/README.md b/spring-boot-modules/spring-caching/README.md index e10d6080e8..4994c22c0b 100644 --- a/spring-boot-modules/spring-caching/README.md +++ b/spring-boot-modules/spring-caching/README.md @@ -6,3 +6,4 @@ - [Using Multiple Cache Managers in Spring](https://www.baeldung.com/spring-multiple-cache-managers) - [Testing @Cacheable on Spring Data Repositories](https://www.baeldung.com/spring-data-testing-cacheable) - [Spring Boot Ehcache Example](https://www.baeldung.com/spring-boot-ehcache) +- [Get All Cached Keys with Caffeine Cache in Spring Boot](https://www.baeldung.com/spring-boot-caffeine-spring-get-all-keys) diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/allkeys/config/AllKeysConfig.java b/spring-boot-modules/spring-caching/src/main/java/com/baeldung/allkeys/config/AllKeysConfig.java new file mode 100644 index 0000000000..723a782a6a --- /dev/null +++ b/spring-boot-modules/spring-caching/src/main/java/com/baeldung/allkeys/config/AllKeysConfig.java @@ -0,0 +1,25 @@ +package com.baeldung.allkeys.config; + +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.caffeine.CaffeineCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.baeldung.allkeys.service.SlowServiceWithCache; + +@Configuration +@EnableCaching +public class AllKeysConfig { + + @Bean + SlowServiceWithCache slowServiceWithCache() { + return new SlowServiceWithCache(); + } + + @Bean + CacheManager cacheManager() { + return new CaffeineCacheManager(); + } + +} diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/allkeys/service/SlowServiceWithCache.java b/spring-boot-modules/spring-caching/src/main/java/com/baeldung/allkeys/service/SlowServiceWithCache.java new file mode 100644 index 0000000000..74223c4231 --- /dev/null +++ b/spring-boot-modules/spring-caching/src/main/java/com/baeldung/allkeys/service/SlowServiceWithCache.java @@ -0,0 +1,11 @@ +package com.baeldung.allkeys.service; + +import org.springframework.cache.annotation.CachePut; + +public class SlowServiceWithCache { + + @CachePut(cacheNames = "slowServiceCache", key = "#name") + public String save(String name, String details) { + return details; + } +} diff --git a/spring-boot-modules/spring-caching/src/test/java/com/baeldung/caching/allkeys/boot/GetAllCacheKeysIntegrationTest.java b/spring-boot-modules/spring-caching/src/test/java/com/baeldung/caching/allkeys/boot/GetAllCacheKeysIntegrationTest.java new file mode 100644 index 0000000000..2104eee8de --- /dev/null +++ b/spring-boot-modules/spring-caching/src/test/java/com/baeldung/caching/allkeys/boot/GetAllCacheKeysIntegrationTest.java @@ -0,0 +1,44 @@ +package com.baeldung.caching.allkeys.boot; + +import static org.assertj.core.api.Assertions.assertThat; + +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.cache.CacheManager; +import org.springframework.cache.caffeine.CaffeineCache; +import org.springframework.cache.caffeine.CaffeineCacheManager; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.allkeys.config.AllKeysConfig; +import com.baeldung.allkeys.service.SlowServiceWithCache; +import com.github.benmanes.caffeine.cache.Cache; + +@RunWith(SpringRunner.class) +@SpringBootTest +@ContextConfiguration(classes = AllKeysConfig.class) +public class GetAllCacheKeysIntegrationTest { + + @Autowired + private SlowServiceWithCache slowServiceWithCache; + @Autowired + private CacheManager cacheManager; + + @Test + public void givenCaffeineCacheCachingSlowCalls_whenCacheManagerProperlyCasted_thenAllKeysAreAccessible() { + slowServiceWithCache.save("first", "some-value-first"); + slowServiceWithCache.save("second", "other-value-second"); + + Cache caffeine = getNativeCaffeineCacheForSlowService(); + + assertThat(caffeine.asMap().keySet()).containsOnly("first", "second"); + } + + private Cache getNativeCaffeineCacheForSlowService() { + CaffeineCacheManager caffeineCacheManager = (CaffeineCacheManager) cacheManager; + CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache("slowServiceCache"); + return cache.getNativeCache(); + } +} \ No newline at end of file diff --git a/spring-boot-rest/pom.xml b/spring-boot-rest/pom.xml index fb5df4e68a..46563b725f 100644 --- a/spring-boot-rest/pom.xml +++ b/spring-boot-rest/pom.xml @@ -20,6 +20,12 @@ org.springframework.boot spring-boot-starter-web + + + tomcat-embed-el + org.apache.tomcat.embed + + com.fasterxml.jackson.dataformat @@ -42,37 +48,106 @@ org.springframework.boot spring-boot-starter-data-jpa + + + jakarta.xml.bind-api + jakarta.xml.bind + + + txw2 + org.glassfish.jaxb + + org.springframework.boot spring-boot-starter-data-rest + + + spring-boot-starter-web + org.springframework.boot + + org.springframework.boot spring-boot-starter-hateoas + + + spring-boot-starter-web + org.springframework.boot + + com.google.guava guava ${guava.version} + + + listenablefuture + com.google.guava + + + jsr305 + com.google.code.findbugs + + + error_prone_annotations + com.google.errorprone + + + j2objc-annotations + com.google.j2objc + + org.springframework.boot spring-boot-starter-test test + + + jakarta.xml.bind-api + jakarta.xml.bind + + net.sourceforge.htmlunit htmlunit test + + + commons-logging + commons-logging + + org.modelmapper modelmapper ${modelmapper.version} + + io.rest-assured + rest-assured + 3.3.0 + provided + + + hamcrest-library + org.hamcrest + + + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb-runtime.version} + @@ -89,6 +164,6 @@ 1.4.11.1 3.1.0 3.3.2 + 2.3.7 - - \ No newline at end of file + diff --git a/spring-boot-rest/src/main/java/com/baeldung/springpagination/repository/PostRepository.java b/spring-boot-rest/src/main/java/com/baeldung/springpagination/repository/PostRepository.java index acdc01df94..62f05f8262 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/springpagination/repository/PostRepository.java +++ b/spring-boot-rest/src/main/java/com/baeldung/springpagination/repository/PostRepository.java @@ -10,7 +10,7 @@ import org.springframework.data.repository.query.Param; import com.baeldung.springpagination.model.Post; import com.baeldung.springpagination.model.User; -public interface PostRepository extends JpaRepository, PagingAndSortingRepository { +public interface PostRepository extends JpaRepository { @Query("select u from Post u where u.userName=:userName") Page findByUser(@Param("userName") String userName, Pageable pageReq); diff --git a/spring-cloud-modules/pom.xml b/spring-cloud-modules/pom.xml index 68c7d45b7c..dafc5b628e 100644 --- a/spring-cloud-modules/pom.xml +++ b/spring-cloud-modules/pom.xml @@ -54,7 +54,8 @@ spring-cloud-bus spring-cloud-data-flow spring-cloud-sleuth - spring-cloud-open-telemetry + spring-cloud-open-telemetry + spring-cloud-azure diff --git a/spring-cloud-modules/spring-cloud-azure/README.md b/spring-cloud-modules/spring-cloud-azure/README.md new file mode 100644 index 0000000000..7f0e9815ae --- /dev/null +++ b/spring-cloud-modules/spring-cloud-azure/README.md @@ -0,0 +1,13 @@ +# Spring Cloud Azure + +# Relevant Articles +- [A Guide to Spring Cloud Azure Key Vault](https://www.baeldung.com/spring-cloud-azure-key-vault) +# Azure KeyVault: +In order to create the secrets, follow these steps: +- create an Azure account +- install the Azure Cli an run the following commands +- login on Azure -> _az-login_ +- create a resource group: _az group create --name spring_cloud_azure --location eastus_ +- create a keyvault storage: _az keyvault create --name new_keyvault --resource-group spring_cloud_azure --location eastus_ +- create the secrets: > az keyvault secret set --name my-database-secret --value my-database-secret-value --vault-name new_keyvault,> az keyvault secret set --name my-secret --value my-secret-value --vault-name new_keyvault +``` diff --git a/spring-cloud-modules/spring-cloud-azure/pom.xml b/spring-cloud-modules/spring-cloud-azure/pom.xml new file mode 100644 index 0000000000..86706c794f --- /dev/null +++ b/spring-cloud-modules/spring-cloud-azure/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + com.baeldung.spring.cloud + spring-cloud-azure + spring-cloud-azure + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + jar + Spring Cloud Azure Examples + 1.0.0-SNAPSHOT + + + com.baeldung.spring.cloud + spring-cloud-modules + 1.0.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-dependencies + 2.7.8 + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud-dependencies.version} + pom + import + + + + + + + + com.azure.spring + spring-cloud-azure-starter-keyvault-secrets + ${azure-key-vault-extension-version} + + + + + 2021.0.3 + 4.0.0 + + + \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/Application.java b/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/Application.java new file mode 100644 index 0000000000..8a44a502de --- /dev/null +++ b/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/Application.java @@ -0,0 +1,36 @@ +package com.baeldung.spring.cloud.azure.keyvault; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.baeldung.spring.cloud.azure.keyvault.service.KeyVaultClient; +import com.baeldung.spring.cloud.azure.keyvault.service.KeyVaultAutoconfiguredClient; + +@SpringBootApplication +public class Application implements CommandLineRunner { + + @Value("${database.secret.value}") + private String mySecret; + + private final KeyVaultClient keyVaultClient; + + public Application(@Qualifier(value = "KeyVaultAutoconfiguredClient") KeyVaultAutoconfiguredClient keyVaultAutoconfiguredClient) { + this.keyVaultClient = keyVaultAutoconfiguredClient; + } + + public static void main(String[] args) { + SpringApplication.run(Application.class); + + } + + @Override + public void run(String... args) throws Exception { + //KeyVaultSecret keyVaultSecret = keyVaultClient.getSecret("my-secret"); + //System.out.println("Hey, our secret is here ->" + keyVaultSecret.getValue()); + //System.out.println("Hey, our secret is here from application properties file ->" + mySecret); + } +} diff --git a/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/data/KeyVaultProperties.java b/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/data/KeyVaultProperties.java new file mode 100644 index 0000000000..edd7c01416 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/data/KeyVaultProperties.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.cloud.azure.keyvault.data; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.ConstructorBinding; + +@ConfigurationProperties("azure.keyvault") +@ConstructorBinding +public class KeyVaultProperties { + private String vaultUrl; + private String tenantId; + private String clientId; + private String clientSecret; + + public KeyVaultProperties(String vaultUrl, String tenantId, String clientId, String clientSecret) { + this.vaultUrl = vaultUrl; + this.tenantId = tenantId; + this.clientId = clientId; + this.clientSecret = clientSecret; + } + + public String getVaultUrl() { + return vaultUrl; + } + + public void setVaultUrl(String vaultUrl) { + this.vaultUrl = vaultUrl; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } +} diff --git a/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/service/KeyVaultAutoconfiguredClient.java b/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/service/KeyVaultAutoconfiguredClient.java new file mode 100644 index 0000000000..392c15c6b4 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/service/KeyVaultAutoconfiguredClient.java @@ -0,0 +1,19 @@ +package com.baeldung.spring.cloud.azure.keyvault.service; + +import org.springframework.stereotype.Component; + +import com.azure.security.keyvault.secrets.SecretClient; + +@Component("KeyVaultAutoconfiguredClient") +public class KeyVaultAutoconfiguredClient implements KeyVaultClient { + private final SecretClient secretClient; + + public KeyVaultAutoconfiguredClient(SecretClient secretClient) { + this.secretClient = secretClient; + } + + @Override + public SecretClient getSecretClient() { + return secretClient; + } +} diff --git a/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/service/KeyVaultClient.java b/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/service/KeyVaultClient.java new file mode 100644 index 0000000000..4f4148250e --- /dev/null +++ b/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/service/KeyVaultClient.java @@ -0,0 +1,21 @@ +package com.baeldung.spring.cloud.azure.keyvault.service; + +import java.util.NoSuchElementException; + +import com.azure.security.keyvault.secrets.SecretClient; +import com.azure.security.keyvault.secrets.models.KeyVaultSecret; + +public interface KeyVaultClient { + + SecretClient getSecretClient(); + + default KeyVaultSecret getSecret(String key) { + KeyVaultSecret secret; + try { + secret = getSecretClient().getSecret(key); + } catch (Exception ex) { + throw new NoSuchElementException(); + } + return secret; + } +} diff --git a/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/service/KeyVaultManuallyConfiguredClient.java b/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/service/KeyVaultManuallyConfiguredClient.java new file mode 100644 index 0000000000..33a85f6bb9 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-azure/src/main/java/com/baeldung/spring/cloud/azure/keyvault/service/KeyVaultManuallyConfiguredClient.java @@ -0,0 +1,31 @@ +package com.baeldung.spring.cloud.azure.keyvault.service; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.stereotype.Component; + +import com.azure.identity.ClientSecretCredentialBuilder; +import com.azure.security.keyvault.secrets.SecretClient; +import com.azure.security.keyvault.secrets.SecretClientBuilder; +import com.baeldung.spring.cloud.azure.keyvault.data.KeyVaultProperties; + +@EnableConfigurationProperties(KeyVaultProperties.class) +@Component("KeyVaultManuallyConfiguredClient") +public class KeyVaultManuallyConfiguredClient implements KeyVaultClient { + + private KeyVaultProperties keyVaultProperties; + + private SecretClient secretClient; + + @Override + public SecretClient getSecretClient() { + if (secretClient == null) { + secretClient = new SecretClientBuilder().vaultUrl(keyVaultProperties.getVaultUrl()) + .credential(new ClientSecretCredentialBuilder().tenantId(keyVaultProperties.getTenantId()) + .clientId(keyVaultProperties.getClientId()) + .clientSecret(keyVaultProperties.getClientSecret()) + .build()) + .buildClient(); + } + return secretClient; + } +} diff --git a/spring-cloud-modules/spring-cloud-azure/src/main/resources/application.yaml b/spring-cloud-modules/spring-cloud-azure/src/main/resources/application.yaml new file mode 100644 index 0000000000..4bea8d789b --- /dev/null +++ b/spring-cloud-modules/spring-cloud-azure/src/main/resources/application.yaml @@ -0,0 +1,21 @@ +spring: + cloud: + azure: + compatibility-verifier: + enabled: false + keyvault: + secret: + property-sources[0]: + name: key-vault-property-source-1 + endpoint: https://spring-cloud-azure.vault.azure.net/ + property-source-enabled: true + endpoint: https://spring-cloud-azure.vault.azure.net/ +azure: + keyvault: + vaultUrl: myVaultUrl + tenantId: myTenantId + clientId: myClientId + clientSecret: myClientSecret +database: + secret: + value: ${my-database-secret} \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-azure/src/test/java/com/baeldung/spring/cloud/azure/keyvault/KeyVaultAutoconfiguredClientIntegrationTest.java b/spring-cloud-modules/spring-cloud-azure/src/test/java/com/baeldung/spring/cloud/azure/keyvault/KeyVaultAutoconfiguredClientIntegrationTest.java new file mode 100644 index 0000000000..d480bc33d4 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-azure/src/test/java/com/baeldung/spring/cloud/azure/keyvault/KeyVaultAutoconfiguredClientIntegrationTest.java @@ -0,0 +1,26 @@ +package com.baeldung.spring.cloud.azure.keyvault; + +import java.util.NoSuchElementException; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.context.SpringBootTest; + +import com.baeldung.spring.cloud.azure.keyvault.service.KeyVaultAutoconfiguredClient; + +@SpringBootTest(classes = Application.class) +public class KeyVaultAutoconfiguredClientIntegrationTest { + + @Autowired + @Qualifier(value = "KeyVaultAutoconfiguredClient") + private KeyVaultAutoconfiguredClient keyVaultAutoconfiguredClient; + + @Test + void whenANotExistingKeyIsProvided_thenShouldReturnAnError() { + String secretKey = "mySecret"; + Assertions.assertThrows(NoSuchElementException.class, () -> keyVaultAutoconfiguredClient.getSecret(secretKey)); + } + +} diff --git a/spring-cloud-modules/spring-cloud-azure/src/test/resources/application.yaml b/spring-cloud-modules/spring-cloud-azure/src/test/resources/application.yaml new file mode 100644 index 0000000000..88c54b32eb --- /dev/null +++ b/spring-cloud-modules/spring-cloud-azure/src/test/resources/application.yaml @@ -0,0 +1,21 @@ +spring: + cloud: + azure: + compatibility-verifier: + enabled: false + keyvault: + secret: + endpoint: https://spring-cloud-azure.vault.azure.net/ + property-source-enabled: true + property-sources: + name: key-vault-property-source-1 + endpoint: https://spring-cloud-azure.vault.azure.net/ +azure: + keyvault: + vaultUrl: myVaultUrl + tenantId: myTenantId + clientId: myClientId + clientSecret: myClientSecret +database: + secret: + value: my-database-secret \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/exception/ProductControllerAdvice.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/exception/PriceControllerAdvice.java similarity index 93% rename from spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/exception/ProductControllerAdvice.java rename to spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/exception/PriceControllerAdvice.java index fe7789ecf5..4d01ab0f6d 100644 --- a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/exception/ProductControllerAdvice.java +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/exception/PriceControllerAdvice.java @@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice -public class ProductControllerAdvice { +public class PriceControllerAdvice { @ExceptionHandler(PriceNotFoundException.class) public ResponseEntity handlePriceNotFoundException(PriceNotFoundException exception) { diff --git a/spring-cloud-modules/spring-cloud-openfeign/README.md b/spring-cloud-modules/spring-cloud-openfeign/README.md index d1e52eb415..edda9a8f80 100644 --- a/spring-cloud-modules/spring-cloud-openfeign/README.md +++ b/spring-cloud-modules/spring-cloud-openfeign/README.md @@ -5,4 +5,10 @@ - [Provide an OAuth2 Token to a Feign Client](https://www.baeldung.com/spring-cloud-feign-oauth-token) - [Propagating Exceptions With OpenFeign and Spring](https://www.baeldung.com/spring-openfeign-propagate-exception) - [Feign Client Exception Handling](https://www.baeldung.com/java-feign-client-exception-handling) +- [File Upload With Open Feign](https://www.baeldung.com/java-feign-file-upload) +- [Feign Logging Configuration](https://www.baeldung.com/java-feign-logging) +- [Retrieve Original Message From Feign ErrorDecoder](https://www.baeldung.com/feign-retrieve-original-message) +- [RequestLine with Feign Client](https://www.baeldung.com/feign-requestline) +- [Propagating Exceptions With OpenFeign and Spring](https://www.baeldung.com/spring-openfeign-propagate-exception) +- [Post form-url-encoded Data with Spring Cloud Feign](https://www.baeldung.com/spring-cloud-post-form-url-encoded-data) - [Configuring Spring Cloud FeignClient URL](https://www.baeldung.com/spring-cloud-feignclient-url) diff --git a/spring-cloud-modules/spring-cloud-openfeign/pom.xml b/spring-cloud-modules/spring-cloud-openfeign/pom.xml index 88ad38517b..465be6b74f 100644 --- a/spring-cloud-modules/spring-cloud-openfeign/pom.xml +++ b/spring-cloud-modules/spring-cloud-openfeign/pom.xml @@ -61,10 +61,23 @@ spring-boot-starter-test test + + com.github.tomakehurst + wiremock-jre8 + ${wire.mock.version} + test + + + org.projectlombok + lombok + ${lombok.version} + provided + 2021.0.3 + 2.33.2 \ No newline at end of file diff --git a/feign/src/main/java/com/baeldung/core/client/FormClient.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/client/FormClient.java similarity index 90% rename from feign/src/main/java/com/baeldung/core/client/FormClient.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/client/FormClient.java index 074402aef3..f127ec3b8b 100644 --- a/feign/src/main/java/com/baeldung/core/client/FormClient.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/client/FormClient.java @@ -1,4 +1,4 @@ -package com.baeldung.core.client; +package com.baeldung.cloud.openfeign.client; import java.util.Map; @@ -11,7 +11,7 @@ import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -import com.baeldung.core.defaulterrorhandling.model.FormData; +import com.baeldung.cloud.openfeign.defaulterrorhandling.model.FormData; import feign.codec.Encoder; import feign.form.spring.SpringFormEncoder; diff --git a/feign/src/main/java/com/baeldung/core/client/UserClient.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/client/UserClient.java similarity index 75% rename from feign/src/main/java/com/baeldung/core/client/UserClient.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/client/UserClient.java index a16f924ad5..a9b78e5db8 100644 --- a/feign/src/main/java/com/baeldung/core/client/UserClient.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/client/UserClient.java @@ -1,9 +1,9 @@ -package com.baeldung.core.client; +package com.baeldung.cloud.openfeign.client; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; -import com.baeldung.core.config.FeignConfig; +import com.baeldung.cloud.openfeign.config.FeignConfig; @FeignClient(name = "user-client", url="https://jsonplaceholder.typicode.com", configuration = FeignConfig.class) public interface UserClient { diff --git a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/config/FeignConfig.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/config/FeignConfig.java new file mode 100644 index 0000000000..005084899b --- /dev/null +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/config/FeignConfig.java @@ -0,0 +1,13 @@ +package com.baeldung.cloud.openfeign.config; + +import org.springframework.context.annotation.Bean; + +import feign.Logger; + +public class FeignConfig { + + @Bean + Logger.Level feignLoggerLevel() { + return Logger.Level.FULL; + } +} \ No newline at end of file diff --git a/feign/src/main/java/com/baeldung/core/customizederrorhandling/client/ProductClient.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/client/ProductClient.java similarity index 63% rename from feign/src/main/java/com/baeldung/core/customizederrorhandling/client/ProductClient.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/client/ProductClient.java index 113051722b..470dd5c929 100644 --- a/feign/src/main/java/com/baeldung/core/customizederrorhandling/client/ProductClient.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/client/ProductClient.java @@ -1,14 +1,14 @@ -package com.baeldung.core.customizederrorhandling.client; +package com.baeldung.cloud.openfeign.customizederrorhandling.client; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import com.baeldung.core.customizederrorhandling.config.FeignConfig; -import com.baeldung.core.defaulterrorhandling.model.Product; +import com.baeldung.cloud.openfeign.customizederrorhandling.config.FeignConfig; +import com.baeldung.cloud.openfeign.defaulterrorhandling.model.Product; -@FeignClient(name = "product-client-2", url = "http://localhost:8081/product/", configuration = FeignConfig.class) +@FeignClient(name = "product-client-2", url = "http://localhost:8088/product/", configuration = FeignConfig.class) public interface ProductClient { @RequestMapping(value = "{id}", method = RequestMethod.GET) diff --git a/feign/src/main/java/com/baeldung/core/customizederrorhandling/config/CustomErrorDecoder.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/config/CustomErrorDecoder.java similarity index 65% rename from feign/src/main/java/com/baeldung/core/customizederrorhandling/config/CustomErrorDecoder.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/config/CustomErrorDecoder.java index 5466b61b3a..13e3a55dd7 100644 --- a/feign/src/main/java/com/baeldung/core/customizederrorhandling/config/CustomErrorDecoder.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/config/CustomErrorDecoder.java @@ -1,8 +1,9 @@ -package com.baeldung.core.customizederrorhandling.config; +package com.baeldung.cloud.openfeign.customizederrorhandling.config; -import com.baeldung.core.customizederrorhandling.exception.ProductNotFoundException; -import com.baeldung.core.customizederrorhandling.exception.ProductServiceNotAvailableException; -import com.baeldung.core.exception.BadRequestException; + +import com.baeldung.cloud.openfeign.customizederrorhandling.exception.ProductNotFoundException; +import com.baeldung.cloud.openfeign.customizederrorhandling.exception.ProductServiceNotAvailableException; +import com.baeldung.cloud.openfeign.exception.BadRequestException; import feign.Response; import feign.codec.ErrorDecoder; diff --git a/feign/src/main/java/com/baeldung/core/customizederrorhandling/config/FeignConfig.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/config/FeignConfig.java similarity index 81% rename from feign/src/main/java/com/baeldung/core/customizederrorhandling/config/FeignConfig.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/config/FeignConfig.java index 980b8b5b38..f013f48b64 100644 --- a/feign/src/main/java/com/baeldung/core/customizederrorhandling/config/FeignConfig.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/config/FeignConfig.java @@ -1,4 +1,4 @@ -package com.baeldung.core.customizederrorhandling.config; +package com.baeldung.cloud.openfeign.customizederrorhandling.config; import org.springframework.context.annotation.Bean; diff --git a/feign/src/main/java/com/baeldung/core/customizederrorhandling/controller/ProductController.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/controller/ProductController.java similarity index 76% rename from feign/src/main/java/com/baeldung/core/customizederrorhandling/controller/ProductController.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/controller/ProductController.java index 6d6f784e66..53458151f8 100644 --- a/feign/src/main/java/com/baeldung/core/customizederrorhandling/controller/ProductController.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/controller/ProductController.java @@ -1,4 +1,4 @@ -package com.baeldung.core.customizederrorhandling.controller; +package com.baeldung.cloud.openfeign.customizederrorhandling.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -6,8 +6,8 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.baeldung.core.customizederrorhandling.client.ProductClient; -import com.baeldung.core.defaulterrorhandling.model.Product; +import com.baeldung.cloud.openfeign.customizederrorhandling.client.ProductClient; +import com.baeldung.cloud.openfeign.defaulterrorhandling.model.Product; @RestController("product_controller2") @RequestMapping(value = "myapp2") diff --git a/feign/src/main/java/com/baeldung/core/customizederrorhandling/exception/ErrorResponse.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/exception/ErrorResponse.java similarity index 94% rename from feign/src/main/java/com/baeldung/core/customizederrorhandling/exception/ErrorResponse.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/exception/ErrorResponse.java index 6e739e5e40..d7ec783a8b 100644 --- a/feign/src/main/java/com/baeldung/core/customizederrorhandling/exception/ErrorResponse.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/exception/ErrorResponse.java @@ -1,4 +1,4 @@ -package com.baeldung.core.customizederrorhandling.exception; +package com.baeldung.cloud.openfeign.customizederrorhandling.exception; import java.util.Date; diff --git a/feign/src/main/java/com/baeldung/core/customizederrorhandling/exception/ProductExceptionHandler.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/exception/ProductExceptionHandler.java similarity index 95% rename from feign/src/main/java/com/baeldung/core/customizederrorhandling/exception/ProductExceptionHandler.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/exception/ProductExceptionHandler.java index c83d917570..80191ce427 100644 --- a/feign/src/main/java/com/baeldung/core/customizederrorhandling/exception/ProductExceptionHandler.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/exception/ProductExceptionHandler.java @@ -1,4 +1,4 @@ -package com.baeldung.core.customizederrorhandling.exception; +package com.baeldung.cloud.openfeign.customizederrorhandling.exception; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/feign/src/main/java/com/baeldung/core/customizederrorhandling/exception/ProductNotFoundException.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/exception/ProductNotFoundException.java similarity index 68% rename from feign/src/main/java/com/baeldung/core/customizederrorhandling/exception/ProductNotFoundException.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/exception/ProductNotFoundException.java index fa993ce700..337cb89f7b 100644 --- a/feign/src/main/java/com/baeldung/core/customizederrorhandling/exception/ProductNotFoundException.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/exception/ProductNotFoundException.java @@ -1,4 +1,4 @@ -package com.baeldung.core.customizederrorhandling.exception; +package com.baeldung.cloud.openfeign.customizederrorhandling.exception; public class ProductNotFoundException extends RuntimeException { diff --git a/feign/src/main/java/com/baeldung/core/customizederrorhandling/exception/ProductServiceNotAvailableException.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/exception/ProductServiceNotAvailableException.java similarity index 70% rename from feign/src/main/java/com/baeldung/core/customizederrorhandling/exception/ProductServiceNotAvailableException.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/exception/ProductServiceNotAvailableException.java index 887d2cd91d..ce30f8c310 100644 --- a/feign/src/main/java/com/baeldung/core/customizederrorhandling/exception/ProductServiceNotAvailableException.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/customizederrorhandling/exception/ProductServiceNotAvailableException.java @@ -1,4 +1,4 @@ -package com.baeldung.core.customizederrorhandling.exception; +package com.baeldung.cloud.openfeign.customizederrorhandling.exception; public class ProductServiceNotAvailableException extends RuntimeException { diff --git a/feign/src/main/java/com/baeldung/core/defaulterrorhandling/client/ProductClient.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClient.java similarity index 64% rename from feign/src/main/java/com/baeldung/core/defaulterrorhandling/client/ProductClient.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClient.java index 4eb435331d..ffbf258029 100644 --- a/feign/src/main/java/com/baeldung/core/defaulterrorhandling/client/ProductClient.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClient.java @@ -1,14 +1,14 @@ -package com.baeldung.core.defaulterrorhandling.client; +package com.baeldung.cloud.openfeign.defaulterrorhandling.client; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import com.baeldung.core.defaulterrorhandling.config.FeignConfig; -import com.baeldung.core.defaulterrorhandling.model.Product; +import com.baeldung.cloud.openfeign.defaulterrorhandling.config.FeignConfig; +import com.baeldung.cloud.openfeign.defaulterrorhandling.model.Product; -@FeignClient(name = "product-client", url = "http://localhost:8084/product/", configuration = FeignConfig.class) +@FeignClient(name = "product-client", url = "http://localhost:8088/product/", configuration = FeignConfig.class) public interface ProductClient { @RequestMapping(value = "{id}", method = RequestMethod.GET) diff --git a/feign/src/main/java/com/baeldung/core/defaulterrorhandling/config/FeignConfig.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/config/FeignConfig.java similarity index 74% rename from feign/src/main/java/com/baeldung/core/defaulterrorhandling/config/FeignConfig.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/config/FeignConfig.java index cef8cbb6d9..e10c33e311 100644 --- a/feign/src/main/java/com/baeldung/core/defaulterrorhandling/config/FeignConfig.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/config/FeignConfig.java @@ -1,4 +1,4 @@ -package com.baeldung.core.defaulterrorhandling.config; +package com.baeldung.cloud.openfeign.defaulterrorhandling.config; import org.springframework.context.annotation.Bean; diff --git a/feign/src/main/java/com/baeldung/core/defaulterrorhandling/controller/ProductController.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductController.java similarity index 76% rename from feign/src/main/java/com/baeldung/core/defaulterrorhandling/controller/ProductController.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductController.java index 80f571f29a..b9fe879fbd 100644 --- a/feign/src/main/java/com/baeldung/core/defaulterrorhandling/controller/ProductController.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductController.java @@ -1,4 +1,4 @@ -package com.baeldung.core.defaulterrorhandling.controller; +package com.baeldung.cloud.openfeign.defaulterrorhandling.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -6,8 +6,8 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.baeldung.core.defaulterrorhandling.client.ProductClient; -import com.baeldung.core.defaulterrorhandling.model.Product; +import com.baeldung.cloud.openfeign.defaulterrorhandling.client.ProductClient; +import com.baeldung.cloud.openfeign.defaulterrorhandling.model.Product; @RestController("product_controller1") @RequestMapping(value ="myapp1") diff --git a/feign/src/main/java/com/baeldung/core/defaulterrorhandling/model/FormData.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/model/FormData.java similarity index 67% rename from feign/src/main/java/com/baeldung/core/defaulterrorhandling/model/FormData.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/model/FormData.java index 6210451f2d..4b03a3e410 100644 --- a/feign/src/main/java/com/baeldung/core/defaulterrorhandling/model/FormData.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/model/FormData.java @@ -1,4 +1,4 @@ -package com.baeldung.core.defaulterrorhandling.model; +package com.baeldung.cloud.openfeign.defaulterrorhandling.model; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/feign/src/main/java/com/baeldung/core/defaulterrorhandling/model/Product.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/model/Product.java similarity index 82% rename from feign/src/main/java/com/baeldung/core/defaulterrorhandling/model/Product.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/model/Product.java index 35d860332e..25a1662c99 100644 --- a/feign/src/main/java/com/baeldung/core/defaulterrorhandling/model/Product.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/model/Product.java @@ -1,4 +1,4 @@ -package com.baeldung.core.defaulterrorhandling.model; +package com.baeldung.cloud.openfeign.defaulterrorhandling.model; public class Product { diff --git a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java index 802077a3d7..bedcd32569 100644 --- a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java @@ -1,6 +1,5 @@ package com.baeldung.cloud.openfeign.fileupload.config; -import org.springframework.beans.factory.ObjectFactory; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.context.annotation.Bean; @@ -13,12 +12,7 @@ import feign.form.spring.SpringFormEncoder; public class FeignSupportConfig { @Bean public Encoder multipartFormEncoder() { - return new SpringFormEncoder(new SpringEncoder(new ObjectFactory() { - @Override - public HttpMessageConverters getObject() { - return new HttpMessageConverters(new RestTemplate().getMessageConverters()); - } - })); + return new SpringFormEncoder(new SpringEncoder(() -> new HttpMessageConverters(new RestTemplate().getMessageConverters()))); } @Bean diff --git a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/RetreiveMessageErrorDecoder.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/RetreiveMessageErrorDecoder.java index 5ebd7b6887..4324467712 100644 --- a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/RetreiveMessageErrorDecoder.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/RetreiveMessageErrorDecoder.java @@ -12,9 +12,10 @@ import feign.codec.ErrorDecoder; public class RetreiveMessageErrorDecoder implements ErrorDecoder { private final ErrorDecoder errorDecoder = new Default(); + @Override public Exception decode(String methodKey, Response response) { - ExceptionMessage message = null; + ExceptionMessage message; try (InputStream bodyIs = response.body() .asInputStream()) { ObjectMapper mapper = new ObjectMapper(); diff --git a/feign/src/main/java/com/baeldung/core/fileupload/controller/FileController.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java similarity index 78% rename from feign/src/main/java/com/baeldung/core/fileupload/controller/FileController.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java index 7ba4746979..5c6d6076b8 100644 --- a/feign/src/main/java/com/baeldung/core/fileupload/controller/FileController.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java @@ -1,4 +1,4 @@ -package com.baeldung.core.fileupload.controller; +package com.baeldung.cloud.openfeign.fileupload.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; @@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import com.baeldung.core.fileupload.service.UploadService; +import com.baeldung.cloud.openfeign.fileupload.service.UploadService; @RestController public class FileController { @@ -16,7 +16,7 @@ public class FileController { @PostMapping(value = "/upload") public String handleFileUpload(@RequestPart(value = "file") MultipartFile file) { - return service.uploadFile(file); + return service.uploadFileWithFallbackFactory(file); } @PostMapping(value = "/upload-mannual-client") @@ -27,7 +27,7 @@ public class FileController { @PostMapping(value = "/upload-error") public String handleFileUploadError(@RequestPart(value = "file") MultipartFile file) { - return service.uploadFile(file); + return service.uploadFileWithFallbackFactory(file); } } \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/FileUploadClientFallbackFactory.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/FileUploadClientFallbackFactory.java index 105be15192..9b717d17f1 100644 --- a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/FileUploadClientFallbackFactory.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/FileUploadClientFallbackFactory.java @@ -11,20 +11,17 @@ import com.baeldung.cloud.openfeign.exception.NotFoundException; public class FileUploadClientFallbackFactory implements FallbackFactory { @Override public FileUploadClientWithFallbackFactory create(Throwable cause) { - return new FileUploadClientWithFallbackFactory() { - @Override - public String fileUpload(MultipartFile file) { - if (cause instanceof BadRequestException) { - return "Bad Request!!!"; - } - if (cause instanceof NotFoundException) { - return "Not Found!!!"; - } - if (cause instanceof Exception) { - return "Exception!!!"; - } - return "Successfully Uploaded file!!!"; + return file -> { + if (cause instanceof BadRequestException) { + return "Bad Request!!!"; } + if (cause instanceof NotFoundException) { + return "Not Found!!!"; + } + if (cause instanceof Exception) { + return "Exception!!!"; + } + return "Successfully Uploaded file!!!"; }; } } \ No newline at end of file diff --git a/feign/src/main/java/com/baeldung/core/fileupload/service/UploadClient.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java similarity index 85% rename from feign/src/main/java/com/baeldung/core/fileupload/service/UploadClient.java rename to spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java index 37b059d642..8f3ef7e421 100644 --- a/feign/src/main/java/com/baeldung/core/fileupload/service/UploadClient.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java @@ -1,4 +1,4 @@ -package com.baeldung.core.fileupload.service; +package com.baeldung.cloud.openfeign.fileupload.service; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.MediaType; @@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.multipart.MultipartFile; -import com.baeldung.core.fileupload.config.FeignSupportConfig; +import com.baeldung.cloud.openfeign.fileupload.config.FeignSupportConfig; @FeignClient(name = "file", url = "http://localhost:8081", configuration = FeignSupportConfig.class) public interface UploadClient { diff --git a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadResource.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadResource.java index 2d5090897d..26e658a7f0 100644 --- a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadResource.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadResource.java @@ -9,7 +9,7 @@ import feign.Response; public interface UploadResource { - @RequestLine("POST /upload-error") + @RequestLine("POST /upload-file") @Headers("Content-Type: multipart/form-data") Response uploadFile(@Param("file") MultipartFile file); diff --git a/feign/src/test/java/com/baeldung/core/client/FormClientUnitTest.java b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/client/FormClientUnitTest.java similarity index 95% rename from feign/src/test/java/com/baeldung/core/client/FormClientUnitTest.java rename to spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/client/FormClientUnitTest.java index b9c263b60b..f374e8e0bd 100644 --- a/feign/src/test/java/com/baeldung/core/client/FormClientUnitTest.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/client/FormClientUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.core.client; +package com.baeldung.cloud.openfeign.client; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; @@ -20,7 +20,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpStatus; import org.springframework.test.context.junit.jupiter.SpringExtension; -import com.baeldung.core.defaulterrorhandling.model.FormData; +import com.baeldung.cloud.openfeign.defaulterrorhandling.model.FormData; import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; diff --git a/feign/src/test/java/com/baeldung/core/customizederrorhandling/client/ProductClientUnitTest.java b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/customizederrorhandling/client/ProductClientUnitTest.java similarity index 81% rename from feign/src/test/java/com/baeldung/core/customizederrorhandling/client/ProductClientUnitTest.java rename to spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/customizederrorhandling/client/ProductClientUnitTest.java index ed5f18eb3f..385ce900f5 100644 --- a/feign/src/test/java/com/baeldung/core/customizederrorhandling/client/ProductClientUnitTest.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/customizederrorhandling/client/ProductClientUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.core.customizederrorhandling.client; +package com.baeldung.cloud.openfeign.customizederrorhandling.client; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; @@ -15,9 +15,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.core.ExampleApplication; -import com.baeldung.core.customizederrorhandling.exception.ProductNotFoundException; -import com.baeldung.core.customizederrorhandling.exception.ProductServiceNotAvailableException; +import com.baeldung.cloud.openfeign.ExampleApplication; +import com.baeldung.cloud.openfeign.customizederrorhandling.exception.ProductNotFoundException; +import com.baeldung.cloud.openfeign.customizederrorhandling.exception.ProductServiceNotAvailableException; import com.github.tomakehurst.wiremock.WireMockServer; @RunWith(SpringRunner.class) @@ -31,8 +31,8 @@ public class ProductClientUnitTest { @Before public void startWireMockServer() { - wireMockServer = new WireMockServer(8081); - configureFor("localhost", 8081); + wireMockServer = new WireMockServer(8088); + configureFor("localhost", 8088); wireMockServer.start(); } diff --git a/feign/src/test/java/com/baeldung/core/customizederrorhandling/controller/ProductControllerUnitTest.java b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/customizederrorhandling/controller/ProductControllerUnitTest.java similarity index 92% rename from feign/src/test/java/com/baeldung/core/customizederrorhandling/controller/ProductControllerUnitTest.java rename to spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/customizederrorhandling/controller/ProductControllerUnitTest.java index 04fd68d3e4..3d103d1333 100644 --- a/feign/src/test/java/com/baeldung/core/customizederrorhandling/controller/ProductControllerUnitTest.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/customizederrorhandling/controller/ProductControllerUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.core.customizederrorhandling.controller; +package com.baeldung.cloud.openfeign.customizederrorhandling.controller; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; @@ -21,8 +21,8 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; -import com.baeldung.core.customizederrorhandling.client.ProductClient; -import com.baeldung.core.customizederrorhandling.exception.ErrorResponse; +import com.baeldung.cloud.openfeign.customizederrorhandling.client.ProductClient; +import com.baeldung.cloud.openfeign.customizederrorhandling.exception.ErrorResponse; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; @@ -46,8 +46,8 @@ public class ProductControllerUnitTest { @Before public void startWireMockServer() { - wireMockServer = new WireMockServer(8081); - configureFor("localhost", 8081); + wireMockServer = new WireMockServer(8088); + configureFor("localhost", 8088); wireMockServer.start(); } diff --git a/feign/src/test/java/com/baeldung/core/defaulterrorhandling/client/ProductClientUnitTest.java b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClientUnitTest.java similarity index 90% rename from feign/src/test/java/com/baeldung/core/defaulterrorhandling/client/ProductClientUnitTest.java rename to spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClientUnitTest.java index 8a9fa94074..ed4cf75890 100644 --- a/feign/src/test/java/com/baeldung/core/defaulterrorhandling/client/ProductClientUnitTest.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClientUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.core.defaulterrorhandling.client; +package com.baeldung.cloud.openfeign.defaulterrorhandling.client; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; @@ -17,8 +17,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpStatus; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.core.ExampleApplication; -import com.baeldung.core.defaulterrorhandling.model.Product; +import com.baeldung.cloud.openfeign.ExampleApplication; +import com.baeldung.cloud.openfeign.defaulterrorhandling.model.Product; import com.github.tomakehurst.wiremock.WireMockServer; import feign.FeignException; @@ -34,8 +34,8 @@ public class ProductClientUnitTest { @Before public void startWireMockServer() { - wireMockServer = new WireMockServer(8084); - configureFor("localhost", 8084); + wireMockServer = new WireMockServer(8088); + configureFor("localhost", 8088); wireMockServer.start(); } diff --git a/feign/src/test/java/com/baeldung/core/defaulterrorhandling/controller/ProductControllerUnitTest.java b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductControllerUnitTest.java similarity index 95% rename from feign/src/test/java/com/baeldung/core/defaulterrorhandling/controller/ProductControllerUnitTest.java rename to spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductControllerUnitTest.java index 798ee9035c..7271aa2672 100644 --- a/feign/src/test/java/com/baeldung/core/defaulterrorhandling/controller/ProductControllerUnitTest.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductControllerUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.core.defaulterrorhandling.controller; +package com.baeldung.cloud.openfeign.defaulterrorhandling.controller; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; @@ -21,7 +21,7 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import com.baeldung.core.defaulterrorhandling.client.ProductClient; +import com.baeldung.cloud.openfeign.defaulterrorhandling.client.ProductClient; import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; diff --git a/feign/src/test/java/com/baeldung/core/defaulterrorhandling/controller/TestControllerAdvice.java b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/TestControllerAdvice.java similarity index 88% rename from feign/src/test/java/com/baeldung/core/defaulterrorhandling/controller/TestControllerAdvice.java rename to spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/TestControllerAdvice.java index dfd82ed07d..4f06a82a35 100644 --- a/feign/src/test/java/com/baeldung/core/defaulterrorhandling/controller/TestControllerAdvice.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/TestControllerAdvice.java @@ -1,4 +1,4 @@ -package com.baeldung.core.defaulterrorhandling.controller; +package com.baeldung.cloud.openfeign.defaulterrorhandling.controller; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-core-2/.gitignore b/spring-core-2/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/spring-core-2/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/spring-core-2/README.md b/spring-core-2/README.md index 2dae67ff49..80ae54b2a4 100644 --- a/spring-core-2/README.md +++ b/spring-core-2/README.md @@ -4,10 +4,11 @@ This module contains articles about core Spring functionality ## Relevant Articles: -- [Guide to Spring @Autowired](http://www.baeldung.com/spring-autowire) -- [Spring Profiles](http://www.baeldung.com/spring-profiles) - [Quick Guide to Spring Bean Scopes](http://www.baeldung.com/spring-bean-scopes) -- [@Order in Spring](http://www.baeldung.com/spring-order) - [Spring Events](https://www.baeldung.com/spring-events) -- [Spring Null-Safety Annotations](https://www.baeldung.com/spring-null-safety-annotations) +- [Solving Spring’s “not eligible for auto-proxying” Warning](https://www.baeldung.com/spring-not-eligible-for-auto-proxying) +- [Finding the Spring Version](https://www.baeldung.com/spring-find-version) +- [How Does the Spring Singleton Bean Serve Concurrent Requests?](https://www.baeldung.com/spring-singleton-concurrent-requests) +- [Reinitialize Singleton Bean in Spring Context](https://www.baeldung.com/spring-reinitialize-singleton-bean) +- [Getting the Current ApplicationContext in Spring](https://www.baeldung.com/spring-get-current-applicationcontext) - More articles: [[<-- prev]](/spring-core)[[next -->]](/spring-core-3) diff --git a/spring-core-2/pom.xml b/spring-core-2/pom.xml index 3cd9adf451..bab47cb70c 100644 --- a/spring-core-2/pom.xml +++ b/spring-core-2/pom.xml @@ -15,29 +15,15 @@ ../parent-boot-2 - - - - org.springframework - spring-framework-bom - ${org.springframework.version} - pom - import - - - org.springframework - spring-core - ${org.springframework.version} - - - org.springframework.boot - spring-boot-starter-thymeleaf - ${org.springframework.version} - - - - + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + com.fasterxml.jackson.core jackson-databind @@ -129,6 +115,11 @@ spring-test test + + org.springframework.boot + spring-boot-starter-test + test + net.javacrumbs.shedlock @@ -140,6 +131,10 @@ shedlock-provider-jdbc-template ${shedlock.version} + + org.projectlombok + lombok + @@ -162,28 +157,8 @@ - - - dev - - true - - - dev - - - - prod - - prod - - - - com.baeldung.sample.App - - 5.3.0 1.3.2 5.2.5.Final diff --git a/spring-core-6/src/main/java/com/baeldung/applicationcontext/ApplicationContextProvider.java b/spring-core-2/src/main/java/com/baeldung/applicationcontext/ApplicationContextProvider.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/applicationcontext/ApplicationContextProvider.java rename to spring-core-2/src/main/java/com/baeldung/applicationcontext/ApplicationContextProvider.java diff --git a/spring-core-6/src/main/java/com/baeldung/applicationcontext/ItemService.java b/spring-core-2/src/main/java/com/baeldung/applicationcontext/ItemService.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/applicationcontext/ItemService.java rename to spring-core-2/src/main/java/com/baeldung/applicationcontext/ItemService.java diff --git a/spring-core-6/src/main/java/com/baeldung/applicationcontext/MyBean.java b/spring-core-2/src/main/java/com/baeldung/applicationcontext/MyBean.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/applicationcontext/MyBean.java rename to spring-core-2/src/main/java/com/baeldung/applicationcontext/MyBean.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/DataCache.java b/spring-core-2/src/main/java/com/baeldung/component/autoproxying/DataCache.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/autoproxying/DataCache.java rename to spring-core-2/src/main/java/com/baeldung/component/autoproxying/DataCache.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/EligibleForAutoProxyRandomIntProcessor.java b/spring-core-2/src/main/java/com/baeldung/component/autoproxying/EligibleForAutoProxyRandomIntProcessor.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/autoproxying/EligibleForAutoProxyRandomIntProcessor.java rename to spring-core-2/src/main/java/com/baeldung/component/autoproxying/EligibleForAutoProxyRandomIntProcessor.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyRandomIntProcessor.java b/spring-core-2/src/main/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyRandomIntProcessor.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyRandomIntProcessor.java rename to spring-core-2/src/main/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyRandomIntProcessor.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomInt.java b/spring-core-2/src/main/java/com/baeldung/component/autoproxying/RandomInt.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomInt.java rename to spring-core-2/src/main/java/com/baeldung/component/autoproxying/RandomInt.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomIntGenerator.java b/spring-core-2/src/main/java/com/baeldung/component/autoproxying/RandomIntGenerator.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomIntGenerator.java rename to spring-core-2/src/main/java/com/baeldung/component/autoproxying/RandomIntGenerator.java diff --git a/spring-core-5/src/main/java/com/baeldung/concurrentrequest/ConcurrentRequestApplication.java b/spring-core-2/src/main/java/com/baeldung/concurrentrequest/ConcurrentRequestApplication.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/concurrentrequest/ConcurrentRequestApplication.java rename to spring-core-2/src/main/java/com/baeldung/concurrentrequest/ConcurrentRequestApplication.java diff --git a/spring-core-5/src/main/java/com/baeldung/concurrentrequest/Product.java b/spring-core-2/src/main/java/com/baeldung/concurrentrequest/Product.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/concurrentrequest/Product.java rename to spring-core-2/src/main/java/com/baeldung/concurrentrequest/Product.java diff --git a/spring-core-5/src/main/java/com/baeldung/concurrentrequest/ProductController.java b/spring-core-2/src/main/java/com/baeldung/concurrentrequest/ProductController.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/concurrentrequest/ProductController.java rename to spring-core-2/src/main/java/com/baeldung/concurrentrequest/ProductController.java diff --git a/spring-core-5/src/main/java/com/baeldung/concurrentrequest/ProductService.java b/spring-core-2/src/main/java/com/baeldung/concurrentrequest/ProductService.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/concurrentrequest/ProductService.java rename to spring-core-2/src/main/java/com/baeldung/concurrentrequest/ProductService.java diff --git a/spring-core-5/src/main/java/com/baeldung/concurrentrequest/Stock.java b/spring-core-2/src/main/java/com/baeldung/concurrentrequest/Stock.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/concurrentrequest/Stock.java rename to spring-core-2/src/main/java/com/baeldung/concurrentrequest/Stock.java diff --git a/spring-core-6/src/main/java/com/baeldung/reinitializebean/ReinitializeBeanApp.java b/spring-core-2/src/main/java/com/baeldung/reinitializebean/ReinitializeBeanApp.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/reinitializebean/ReinitializeBeanApp.java rename to spring-core-2/src/main/java/com/baeldung/reinitializebean/ReinitializeBeanApp.java diff --git a/spring-core-6/src/main/java/com/baeldung/reinitializebean/cache/ConfigManager.java b/spring-core-2/src/main/java/com/baeldung/reinitializebean/cache/ConfigManager.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/reinitializebean/cache/ConfigManager.java rename to spring-core-2/src/main/java/com/baeldung/reinitializebean/cache/ConfigManager.java diff --git a/spring-core-6/src/main/java/com/baeldung/reinitializebean/controller/ConfigController.java b/spring-core-2/src/main/java/com/baeldung/reinitializebean/controller/ConfigController.java similarity index 100% rename from spring-core-6/src/main/java/com/baeldung/reinitializebean/controller/ConfigController.java rename to spring-core-2/src/main/java/com/baeldung/reinitializebean/controller/ConfigController.java diff --git a/spring-core-5/src/main/java/com/baeldung/version/VersionObtainer.java b/spring-core-2/src/main/java/com/baeldung/version/VersionObtainer.java similarity index 96% rename from spring-core-5/src/main/java/com/baeldung/version/VersionObtainer.java rename to spring-core-2/src/main/java/com/baeldung/version/VersionObtainer.java index 392cc44a72..e0e28c6181 100644 --- a/spring-core-5/src/main/java/com/baeldung/version/VersionObtainer.java +++ b/spring-core-2/src/main/java/com/baeldung/version/VersionObtainer.java @@ -1,20 +1,20 @@ -package com.baeldung.version; - -import org.springframework.boot.system.JavaVersion; -import org.springframework.boot.system.SystemProperties; -import org.springframework.core.SpringVersion; - -public class VersionObtainer { - - public String getSpringVersion() { - return SpringVersion.getVersion(); - } - - public String getJavaVersion() { - return JavaVersion.getJavaVersion().toString(); - } - - public String getJdkVersion() { - return SystemProperties.get("java.version"); - } -} +package com.baeldung.version; + +import org.springframework.boot.system.JavaVersion; +import org.springframework.boot.system.SystemProperties; +import org.springframework.core.SpringVersion; + +public class VersionObtainer { + + public String getSpringVersion() { + return SpringVersion.getVersion(); + } + + public String getJavaVersion() { + return JavaVersion.getJavaVersion().toString(); + } + + public String getJdkVersion() { + return SystemProperties.get("java.version"); + } +} diff --git a/spring-core-2/src/main/resources/application.properties b/spring-core-2/src/main/resources/application.properties index d482330b83..97916eec19 100644 --- a/spring-core-2/src/main/resources/application.properties +++ b/spring-core-2/src/main/resources/application.properties @@ -1,28 +1 @@ -spring.profiles.active=@spring.profiles.active@ - -my.prop=used-always-in-all-profiles - -#--- -spring.config.activate.on-profile=dev -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -spring.datasource.url=jdbc:mysql://localhost:3306/db -spring.datasource.username=root -spring.datasource.password=root - -#--- -spring.config.activate.on-profile=production -spring.datasource.driver-class-name=org.h2.Driver -spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 -spring.datasource.username=sa -spring.datasource.password=sa - -#--- -spring.profiles.group.production=proddb,prodquartz - -#--- -spring.config.activate.on-profile=proddb -db=url_to_production_db - -#--- -spring.config.activate.on-profile=prodquartz -quartz=url_to_quartz_scheduler \ No newline at end of file +config.file.path=./spring-core-2/src/main/resources/config.properties \ No newline at end of file diff --git a/spring-core-6/src/main/resources/config.properties b/spring-core-2/src/main/resources/config.properties similarity index 100% rename from spring-core-6/src/main/resources/config.properties rename to spring-core-2/src/main/resources/config.properties diff --git a/spring-core-6/src/test/java/com/baeldung/applicationcontext/ApplicationContextProviderUnitTest.java b/spring-core-2/src/test/java/com/baeldung/applicationcontext/ApplicationContextProviderUnitTest.java similarity index 100% rename from spring-core-6/src/test/java/com/baeldung/applicationcontext/ApplicationContextProviderUnitTest.java rename to spring-core-2/src/test/java/com/baeldung/applicationcontext/ApplicationContextProviderUnitTest.java diff --git a/spring-core-6/src/test/java/com/baeldung/applicationcontext/MyBeanUnitTest.java b/spring-core-2/src/test/java/com/baeldung/applicationcontext/MyBeanUnitTest.java similarity index 100% rename from spring-core-6/src/test/java/com/baeldung/applicationcontext/MyBeanUnitTest.java rename to spring-core-2/src/test/java/com/baeldung/applicationcontext/MyBeanUnitTest.java diff --git a/spring-core-6/src/test/java/com/baeldung/applicationcontext/TestContextConfig.java b/spring-core-2/src/test/java/com/baeldung/applicationcontext/TestContextConfig.java similarity index 100% rename from spring-core-6/src/test/java/com/baeldung/applicationcontext/TestContextConfig.java rename to spring-core-2/src/test/java/com/baeldung/applicationcontext/TestContextConfig.java diff --git a/spring-core-5/src/test/java/com/baeldung/component/autoproxying/EligibleForAutoProxyingIntegrationTest.java b/spring-core-2/src/test/java/com/baeldung/component/autoproxying/EligibleForAutoProxyingIntegrationTest.java similarity index 100% rename from spring-core-5/src/test/java/com/baeldung/component/autoproxying/EligibleForAutoProxyingIntegrationTest.java rename to spring-core-2/src/test/java/com/baeldung/component/autoproxying/EligibleForAutoProxyingIntegrationTest.java diff --git a/spring-core-5/src/test/java/com/baeldung/component/autoproxying/MemoryLogAppender.java b/spring-core-2/src/test/java/com/baeldung/component/autoproxying/MemoryLogAppender.java similarity index 100% rename from spring-core-5/src/test/java/com/baeldung/component/autoproxying/MemoryLogAppender.java rename to spring-core-2/src/test/java/com/baeldung/component/autoproxying/MemoryLogAppender.java diff --git a/spring-core-5/src/test/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyingIntegrationTest.java b/spring-core-2/src/test/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyingIntegrationTest.java similarity index 100% rename from spring-core-5/src/test/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyingIntegrationTest.java rename to spring-core-2/src/test/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyingIntegrationTest.java diff --git a/spring-core-5/src/test/java/com/baeldung/concurrentrequest/ConcurrentRequestManualTest.java b/spring-core-2/src/test/java/com/baeldung/concurrentrequest/ConcurrentRequestManualTest.java similarity index 100% rename from spring-core-5/src/test/java/com/baeldung/concurrentrequest/ConcurrentRequestManualTest.java rename to spring-core-2/src/test/java/com/baeldung/concurrentrequest/ConcurrentRequestManualTest.java diff --git a/spring-core-5/src/test/java/com/baeldung/version/VersionObtainerUnitTest.java b/spring-core-2/src/test/java/com/baeldung/version/VersionObtainerUnitTest.java similarity index 96% rename from spring-core-5/src/test/java/com/baeldung/version/VersionObtainerUnitTest.java rename to spring-core-2/src/test/java/com/baeldung/version/VersionObtainerUnitTest.java index 6d77cd1403..af074d5783 100644 --- a/spring-core-5/src/test/java/com/baeldung/version/VersionObtainerUnitTest.java +++ b/spring-core-2/src/test/java/com/baeldung/version/VersionObtainerUnitTest.java @@ -1,30 +1,30 @@ -package com.baeldung.version; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest(classes = VersionObtainer.class) -public class VersionObtainerUnitTest { - - public VersionObtainer version = new VersionObtainer(); - - @Test - public void testGetSpringVersion() { - String res = version.getSpringVersion(); - assertThat(res).isNotEmpty(); - } - - @Test - public void testGetJdkVersion() { - String res = version.getJdkVersion(); - assertThat(res).isNotEmpty(); - } - - @Test - public void testGetJavaVersion() { - String res = version.getJavaVersion(); - assertThat(res).isNotEmpty(); - } -} +package com.baeldung.version; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = VersionObtainer.class) +public class VersionObtainerUnitTest { + + public VersionObtainer version = new VersionObtainer(); + + @Test + public void testGetSpringVersion() { + String res = version.getSpringVersion(); + assertThat(res).isNotEmpty(); + } + + @Test + public void testGetJdkVersion() { + String res = version.getJdkVersion(); + assertThat(res).isNotEmpty(); + } + + @Test + public void testGetJavaVersion() { + String res = version.getJavaVersion(); + assertThat(res).isNotEmpty(); + } +} diff --git a/spring-core-3/README.md b/spring-core-3/README.md index 7232ad71a1..ed88561e10 100644 --- a/spring-core-3/README.md +++ b/spring-core-3/README.md @@ -9,6 +9,6 @@ This module contains articles about core Spring functionality - [How to use the Spring FactoryBean?](https://www.baeldung.com/spring-factorybean) - [Design Patterns in the Spring Framework](https://www.baeldung.com/spring-framework-design-patterns) - [Difference Between BeanFactory and ApplicationContext](https://www.baeldung.com/spring-beanfactory-vs-applicationcontext) -- [A Spring Custom Annotation for a Better DAO](http://www.baeldung.com/spring-annotation-bean-pre-processor) - [Custom Scope in Spring](http://www.baeldung.com/spring-custom-scope) +- [The Spring ApplicationContext](https://www.baeldung.com/spring-application-context) - More articles: [[<-- prev]](/spring-core-2) [[next -->]](/spring-core-4) diff --git a/spring-core-4/src/main/java/com/baeldung/applicationcontext/AccountConfig.java b/spring-core-3/src/main/java/com/baeldung/applicationcontext/AccountConfig.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/applicationcontext/AccountConfig.java rename to spring-core-3/src/main/java/com/baeldung/applicationcontext/AccountConfig.java diff --git a/spring-core-4/src/main/java/com/baeldung/applicationcontext/AccountRepository.java b/spring-core-3/src/main/java/com/baeldung/applicationcontext/AccountRepository.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/applicationcontext/AccountRepository.java rename to spring-core-3/src/main/java/com/baeldung/applicationcontext/AccountRepository.java diff --git a/spring-core-4/src/main/java/com/baeldung/applicationcontext/AccountService.java b/spring-core-3/src/main/java/com/baeldung/applicationcontext/AccountService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/applicationcontext/AccountService.java rename to spring-core-3/src/main/java/com/baeldung/applicationcontext/AccountService.java diff --git a/spring-core-4/src/main/java/com/baeldung/applicationcontext/MyWebApplicationInitializer.java b/spring-core-3/src/main/java/com/baeldung/applicationcontext/MyWebApplicationInitializer.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/applicationcontext/MyWebApplicationInitializer.java rename to spring-core-3/src/main/java/com/baeldung/applicationcontext/MyWebApplicationInitializer.java diff --git a/spring-core-4/src/main/java/com/baeldung/applicationcontext/MyXmlWebApplicationInitializer.java b/spring-core-3/src/main/java/com/baeldung/applicationcontext/MyXmlWebApplicationInitializer.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/applicationcontext/MyXmlWebApplicationInitializer.java rename to spring-core-3/src/main/java/com/baeldung/applicationcontext/MyXmlWebApplicationInitializer.java diff --git a/spring-core-4/src/main/java/com/baeldung/applicationcontext/UserService.java b/spring-core-3/src/main/java/com/baeldung/applicationcontext/UserService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/applicationcontext/UserService.java rename to spring-core-3/src/main/java/com/baeldung/applicationcontext/UserService.java diff --git a/spring-core-4/src/test/java/com/baeldung/applicationcontext/ApplicationContextUnitTest.java b/spring-core-3/src/test/java/com/baeldung/applicationcontext/ApplicationContextUnitTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/applicationcontext/ApplicationContextUnitTest.java rename to spring-core-3/src/test/java/com/baeldung/applicationcontext/ApplicationContextUnitTest.java diff --git a/spring-core-4/src/test/resources/applicationcontext/account-bean-config.xml b/spring-core-3/src/test/resources/applicationcontext/account-bean-config.xml similarity index 100% rename from spring-core-4/src/test/resources/applicationcontext/account-bean-config.xml rename to spring-core-3/src/test/resources/applicationcontext/account-bean-config.xml diff --git a/spring-core-4/src/test/resources/applicationcontext/user-bean-config.xml b/spring-core-3/src/test/resources/applicationcontext/user-bean-config.xml similarity index 100% rename from spring-core-4/src/test/resources/applicationcontext/user-bean-config.xml rename to spring-core-3/src/test/resources/applicationcontext/user-bean-config.xml diff --git a/spring-core-4/src/test/resources/config/messages.properties b/spring-core-3/src/test/resources/config/messages.properties similarity index 100% rename from spring-core-4/src/test/resources/config/messages.properties rename to spring-core-3/src/test/resources/config/messages.properties diff --git a/spring-core-4/README.md b/spring-core-4/README.md index 3b2c3d4764..a0f5ac97f9 100644 --- a/spring-core-4/README.md +++ b/spring-core-4/README.md @@ -5,10 +5,5 @@ This module contains articles about core Spring functionality ## Relevant Articles: - [Creating Spring Beans Through Factory Methods](https://www.baeldung.com/spring-beans-factory-methods) -- [How to dynamically Autowire a Bean in Spring](https://www.baeldung.com/spring-dynamic-autowire) -- [Spring @Import Annotation](https://www.baeldung.com/spring-import-annotation) - [Spring BeanPostProcessor](https://www.baeldung.com/spring-beanpostprocessor) -- [Using @Autowired in Abstract Classes](https://www.baeldung.com/spring-autowired-abstract-class) -- [Constructor Injection in Spring with Lombok](https://www.baeldung.com/spring-injection-lombok) -- [The Spring ApplicationContext](https://www.baeldung.com/spring-application-context) -- More articles: [[<-- prev]](/spring-core-3) [[next -->]](/spring-core-5) +- More articles: [[<-- prev]](/spring-core-3) diff --git a/spring-core-5/README.md b/spring-core-5/README.md deleted file mode 100644 index ebf62ac24f..0000000000 --- a/spring-core-5/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## Spring Core - -This module contains articles about core Spring functionality. - -## Relevant Articles: - -- [Spring @Component Annotation](https://www.baeldung.com/spring-component-annotation) -- [Solving Spring’s “not eligible for auto-proxying” Warning](https://www.baeldung.com/spring-not-eligible-for-auto-proxying) -- [Spring Bean Names](https://www.baeldung.com/spring-bean-names) -- [AliasFor Annotation in Spring](https://www.baeldung.com/spring-aliasfor-annotation) -- [A Quick Guide to the Spring @Lazy Annotation](https://www.baeldung.com/spring-lazy-annotation) -- [Finding the Spring Version](https://www.baeldung.com/spring-find-version) -- [How Does the Spring Singleton Bean Serve Concurrent Requests?](https://www.baeldung.com/spring-singleton-concurrent-requests) -- More articles: [[<-- prev]](../spring-core-4) diff --git a/spring-core-6/README.md b/spring-core-6/README.md deleted file mode 100644 index e10db19a54..0000000000 --- a/spring-core-6/README.md +++ /dev/null @@ -1,7 +0,0 @@ - -### Relevant Articles: -- [Instantiating Multiple Beans of the Same Class with Spring Annotations](https://www.baeldung.com/spring-same-class-multiple-beans) -- [Using Environment Variables in Spring Boot’s application.properties](https://www.baeldung.com/spring-boot-properties-env-variables) -- [Reinitialize Singleton Bean in Spring Context](https://www.baeldung.com/spring-reinitialize-singleton-bean) -- [HTTP Interface in Spring 6](https://www.baeldung.com/spring-6-http-interface) -- [Getting the Current ApplicationContext in Spring](https://www.baeldung.com/spring-get-current-applicationcontext) diff --git a/spring-core-6/pom.xml b/spring-core-6/pom.xml deleted file mode 100644 index a3dda0374f..0000000000 --- a/spring-core-6/pom.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - 4.0.0 - com.baeldung - spring-core-6 - 0.0.1-SNAPSHOT - spring-core-6 - http://www.baeldung.com - - - org.springframework.boot - spring-boot-starter-parent - 3.0.1 - - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-webflux - - - org.mock-server - mockserver-netty - ${mockserver.version} - - - org.mock-server - mockserver-client-java - ${mockserver.version} - - - org.springframework.boot - spring-boot-starter-test - test - - - io.projectreactor - reactor-test - test - - - - - - - - maven-clean-plugin - 3.1.0 - - - maven-resources-plugin - 3.0.2 - - - maven-compiler-plugin - 3.8.0 - - - maven-surefire-plugin - 2.22.1 - - - maven-jar-plugin - 3.0.2 - - - maven-install-plugin - 2.5.2 - - - maven-deploy-plugin - 2.8.2 - - - maven-site-plugin - 3.7.1 - - - maven-project-info-reports-plugin - 3.0.0 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 17 - 17 - - - - - - - UTF-8 - 17 - 17 - 5.14.0 - - - \ No newline at end of file diff --git a/spring-core-6/src/main/resources/application.properties b/spring-core-6/src/main/resources/application.properties deleted file mode 100644 index 28a65dce32..0000000000 --- a/spring-core-6/src/main/resources/application.properties +++ /dev/null @@ -1,5 +0,0 @@ -environment.name=${OS} -java.home.and.environment=${JAVA_HOME}+${OS} -not.existing.system.property=${thispropertydoesnotexist} -baeldung.presentation=${HELLO_BAELDUNG}. Java is installed in the folder: ${JAVA_HOME} -config.file.path=./spring-core-6/src/main/resources/config.properties \ No newline at end of file diff --git a/spring-core-6/src/test/java/com/baeldung/httpinterface/BooksServiceMockServerTest.java b/spring-core-6/src/test/java/com/baeldung/httpinterface/BooksServiceMockServerTest.java deleted file mode 100644 index 22e00c16ae..0000000000 --- a/spring-core-6/src/test/java/com/baeldung/httpinterface/BooksServiceMockServerTest.java +++ /dev/null @@ -1,217 +0,0 @@ -package com.baeldung.httpinterface; - -import org.apache.http.HttpException; -import org.apache.http.HttpStatus; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.mockserver.client.MockServerClient; -import org.mockserver.integration.ClientAndServer; -import org.mockserver.configuration.Configuration; - -import java.io.IOException; -import java.net.ServerSocket; -import java.util.List; - -import org.mockserver.model.HttpRequest; -import org.mockserver.model.MediaType; -import org.mockserver.verify.VerificationTimes; -import org.slf4j.event.Level; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatusCode; -import org.springframework.http.ResponseEntity; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.web.reactive.function.client.WebClientResponseException; -import reactor.core.publisher.Mono; - -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockserver.integration.ClientAndServer.startClientAndServer; -import static org.mockserver.matchers.Times.exactly; -import static org.mockserver.model.HttpRequest.request; -import static org.mockserver.model.HttpResponse.response; -import static org.junit.jupiter.api.Assertions.assertEquals; - -class BooksServiceMockServerTest { - - private static final String SERVER_ADDRESS = "localhost"; - private static final String PATH = "/books"; - - private static int serverPort; - private static ClientAndServer mockServer; - private static String serviceUrl; - - @BeforeAll - static void startServer() throws IOException { - serverPort = getFreePort(); - serviceUrl = "http://" + SERVER_ADDRESS + ":" + serverPort; - - Configuration config = Configuration.configuration().logLevel(Level.WARN); - mockServer = startClientAndServer(config, serverPort); - - mockAllBooksRequest(); - mockBookByIdRequest(); - mockSaveBookRequest(); - mockDeleteBookRequest(); - } - - @AfterAll - static void stopServer() { - mockServer.stop(); - } - - @Test - void givenMockedGetResponse_whenGetBooksServiceMethodIsCalled_thenTwoBooksAreReturned() { - BooksClient booksClient = new BooksClient(WebClient.builder().baseUrl(serviceUrl).build()); - BooksService booksService = booksClient.getBooksService(); - - List books = booksService.getBooks(); - assertEquals(2, books.size()); - - mockServer.verify( - HttpRequest.request() - .withMethod(HttpMethod.GET.name()) - .withPath(PATH), - VerificationTimes.exactly(1) - ); - } - - @Test - void givenMockedGetResponse_whenGetExistingBookServiceMethodIsCalled_thenCorrectBookIsReturned() { - BooksClient booksClient = new BooksClient(WebClient.builder().baseUrl(serviceUrl).build()); - BooksService booksService = booksClient.getBooksService(); - - Book book = booksService.getBook(1); - assertEquals("Book_1", book.title()); - - mockServer.verify( - HttpRequest.request() - .withMethod(HttpMethod.GET.name()) - .withPath(PATH + "/1"), - VerificationTimes.exactly(1) - ); - } - - @Test - void givenMockedGetResponse_whenGetNonExistingBookServiceMethodIsCalled_thenCorrectBookIsReturned() { - BooksClient booksClient = new BooksClient(WebClient.builder().baseUrl(serviceUrl).build()); - BooksService booksService = booksClient.getBooksService(); - - assertThrows(WebClientResponseException.class, () -> booksService.getBook(9)); - } - - @Test - void givenCustomErrorHandlerIsSet_whenGetNonExistingBookServiceMethodIsCalled_thenCustomExceptionIsThrown() { - BooksClient booksClient = new BooksClient(WebClient.builder() - .defaultStatusHandler(HttpStatusCode::isError, resp -> - Mono.just(new MyServiceException("Custom exception"))) - .baseUrl(serviceUrl) - .build()); - - BooksService booksService = booksClient.getBooksService(); - assertThrows(MyServiceException.class, () -> booksService.getBook(9)); - } - - @Test - void givenMockedPostResponse_whenSaveBookServiceMethodIsCalled_thenCorrectBookIsReturned() { - BooksClient booksClient = new BooksClient(WebClient.builder().baseUrl(serviceUrl).build()); - BooksService booksService = booksClient.getBooksService(); - - Book book = booksService.saveBook(new Book(3, "Book_3", "Author_3", 2000)); - assertEquals("Book_3", book.title()); - - mockServer.verify( - HttpRequest.request() - .withMethod(HttpMethod.POST.name()) - .withPath(PATH), - VerificationTimes.exactly(1) - ); - } - - @Test - void givenMockedDeleteResponse_whenDeleteBookServiceMethodIsCalled_thenCorrectCodeIsReturned() { - BooksClient booksClient = new BooksClient(WebClient.builder().baseUrl(serviceUrl).build()); - BooksService booksService = booksClient.getBooksService(); - - ResponseEntity response = booksService.deleteBook(3); - assertEquals(HttpStatusCode.valueOf(200), response.getStatusCode()); - - mockServer.verify( - HttpRequest.request() - .withMethod(HttpMethod.DELETE.name()) - .withPath(PATH + "/3"), - VerificationTimes.exactly(1) - ); - } - - private static int getFreePort () throws IOException { - try (ServerSocket serverSocket = new ServerSocket(0)) { - return serverSocket.getLocalPort(); - } - } - - private static void mockAllBooksRequest() { - new MockServerClient(SERVER_ADDRESS, serverPort) - .when( - request() - .withPath(PATH) - .withMethod(HttpMethod.GET.name()), - exactly(1) - ) - .respond( - response() - .withStatusCode(HttpStatus.SC_OK) - .withContentType(MediaType.APPLICATION_JSON) - .withBody("[{\"id\":1,\"title\":\"Book_1\",\"author\":\"Author_1\",\"year\":1998},{\"id\":2,\"title\":\"Book_2\",\"author\":\"Author_2\",\"year\":1999}]") - ); - } - - private static void mockBookByIdRequest() { - new MockServerClient(SERVER_ADDRESS, serverPort) - .when( - request() - .withPath(PATH + "/1") - .withMethod(HttpMethod.GET.name()), - exactly(1) - ) - .respond( - response() - .withStatusCode(HttpStatus.SC_OK) - .withContentType(MediaType.APPLICATION_JSON) - .withBody("{\"id\":1,\"title\":\"Book_1\",\"author\":\"Author_1\",\"year\":1998}") - ); - } - - private static void mockSaveBookRequest() { - new MockServerClient(SERVER_ADDRESS, serverPort) - .when( - request() - .withPath(PATH) - .withMethod(HttpMethod.POST.name()) - .withContentType(MediaType.APPLICATION_JSON) - .withBody("{\"id\":3,\"title\":\"Book_3\",\"author\":\"Author_3\",\"year\":2000}"), - exactly(1) - ) - .respond( - response() - .withStatusCode(HttpStatus.SC_OK) - .withContentType(MediaType.APPLICATION_JSON) - .withBody("{\"id\":3,\"title\":\"Book_3\",\"author\":\"Author_3\",\"year\":2000}") - ); - } - - private static void mockDeleteBookRequest() { - new MockServerClient(SERVER_ADDRESS, serverPort) - .when( - request() - .withPath(PATH + "/3") - .withMethod(HttpMethod.DELETE.name()), - exactly(1) - ) - .respond( - response() - .withStatusCode(HttpStatus.SC_OK) - ); - } - -} diff --git a/spring-core-6/src/test/java/com/baeldung/httpinterface/BooksServiceMockitoTest.java b/spring-core-6/src/test/java/com/baeldung/httpinterface/BooksServiceMockitoTest.java deleted file mode 100644 index 7a82835ef3..0000000000 --- a/spring-core-6/src/test/java/com/baeldung/httpinterface/BooksServiceMockitoTest.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.baeldung.httpinterface; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Answers; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatusCode; -import org.springframework.http.ResponseEntity; -import org.springframework.web.reactive.function.client.WebClient; -import reactor.core.publisher.Mono; - -import static org.mockito.BDDMockito.*; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -@ExtendWith(MockitoExtension.class) -class BooksServiceMockitoTest { - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private WebClient webClient; - - @InjectMocks - private BooksClient booksClient; - - @Test - void givenMockedWebClientReturnsTwoBooks_whenGetBooksServiceMethodIsCalled_thenListOfTwoBooksIsReturned() { - given(webClient.method(HttpMethod.GET) - .uri(anyString(), anyMap()) - .retrieve() - .bodyToMono(new ParameterizedTypeReference>(){})) - .willReturn(Mono.just(List.of( - new Book(1,"Book_1", "Author_1", 1998), - new Book(2, "Book_2", "Author_2", 1999) - ))); - - BooksService booksService = booksClient.getBooksService(); - List books = booksService.getBooks(); - assertEquals(2, books.size()); - } - - @Test - void givenMockedWebClientReturnsBook_whenGetBookServiceMethodIsCalled_thenBookIsReturned() { - given(webClient.method(HttpMethod.GET) - .uri(anyString(), anyMap()) - .retrieve() - .bodyToMono(new ParameterizedTypeReference(){})) - .willReturn(Mono.just(new Book(1,"Book_1", "Author_1", 1998))); - - BooksService booksService = booksClient.getBooksService(); - Book book = booksService.getBook(1); - assertEquals("Book_1", book.title()); - } - - @Test - void givenMockedWebClientReturnsBook_whenSaveBookServiceMethodIsCalled_thenBookIsReturned() { - given(webClient.method(HttpMethod.POST) - .uri(anyString(), anyMap()) - .retrieve() - .bodyToMono(new ParameterizedTypeReference(){})) - .willReturn(Mono.just(new Book(3, "Book_3", "Author_3", 2000))); - - BooksService booksService = booksClient.getBooksService(); - Book book = booksService.saveBook(new Book(3, "Book_3", "Author_3", 2000)); - assertEquals("Book_3", book.title()); - } - - @Test - void givenMockedWebClientReturnsOk_whenDeleteBookServiceMethodIsCalled_thenOkCodeIsReturned() { - given(webClient.method(HttpMethod.DELETE) - .uri(anyString(), anyMap()) - .retrieve() - .toBodilessEntity() - .block(any()) - .getStatusCode()) - .willReturn(HttpStatusCode.valueOf(200)); - - BooksService booksService = booksClient.getBooksService(); - ResponseEntity response = booksService.deleteBook(3); - assertEquals(HttpStatusCode.valueOf(200), response.getStatusCode()); - } - -} diff --git a/spring-di-3/README.md b/spring-di-3/README.md index 3ddd720af5..ffb81fbe7d 100644 --- a/spring-di-3/README.md +++ b/spring-di-3/README.md @@ -7,4 +7,8 @@ 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) +- [Guide to Spring @Autowired](http://www.baeldung.com/spring-autowire) +- [@Order in Spring](http://www.baeldung.com/spring-order) +- [How to dynamically Autowire a Bean in Spring](https://www.baeldung.com/spring-dynamic-autowire) +- [Spring @Import Annotation](https://www.baeldung.com/spring-import-annotation) +- More articles: [[<-- prev]](../spring-di-2)[[more -->]](../spring-di-4) diff --git a/spring-core-2/src/main/java/com/baeldung/autowire/sample/App.java b/spring-di-3/src/main/java/com/baeldung/autowire/sample/App.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/autowire/sample/App.java rename to spring-di-3/src/main/java/com/baeldung/autowire/sample/App.java diff --git a/spring-core-2/src/main/java/com/baeldung/autowire/sample/AppConfig.java b/spring-di-3/src/main/java/com/baeldung/autowire/sample/AppConfig.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/autowire/sample/AppConfig.java rename to spring-di-3/src/main/java/com/baeldung/autowire/sample/AppConfig.java diff --git a/spring-core-2/src/main/java/com/baeldung/autowire/sample/BarFormatter.java b/spring-di-3/src/main/java/com/baeldung/autowire/sample/BarFormatter.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/autowire/sample/BarFormatter.java rename to spring-di-3/src/main/java/com/baeldung/autowire/sample/BarFormatter.java diff --git a/spring-core-2/src/main/java/com/baeldung/autowire/sample/FooDAO.java b/spring-di-3/src/main/java/com/baeldung/autowire/sample/FooDAO.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/autowire/sample/FooDAO.java rename to spring-di-3/src/main/java/com/baeldung/autowire/sample/FooDAO.java diff --git a/spring-core-2/src/main/java/com/baeldung/autowire/sample/FooFormatter.java b/spring-di-3/src/main/java/com/baeldung/autowire/sample/FooFormatter.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/autowire/sample/FooFormatter.java rename to spring-di-3/src/main/java/com/baeldung/autowire/sample/FooFormatter.java diff --git a/spring-core-2/src/main/java/com/baeldung/autowire/sample/FooService.java b/spring-di-3/src/main/java/com/baeldung/autowire/sample/FooService.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/autowire/sample/FooService.java rename to spring-di-3/src/main/java/com/baeldung/autowire/sample/FooService.java diff --git a/spring-core-2/src/main/java/com/baeldung/autowire/sample/Formatter.java b/spring-di-3/src/main/java/com/baeldung/autowire/sample/Formatter.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/autowire/sample/Formatter.java rename to spring-di-3/src/main/java/com/baeldung/autowire/sample/Formatter.java diff --git a/spring-core-2/src/main/java/com/baeldung/autowire/sample/FormatterType.java b/spring-di-3/src/main/java/com/baeldung/autowire/sample/FormatterType.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/autowire/sample/FormatterType.java rename to spring-di-3/src/main/java/com/baeldung/autowire/sample/FormatterType.java diff --git a/spring-core-4/src/main/java/com/baeldung/dynamic/autowire/BeanFactoryDynamicAutowireService.java b/spring-di-3/src/main/java/com/baeldung/dynamic/autowire/BeanFactoryDynamicAutowireService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/dynamic/autowire/BeanFactoryDynamicAutowireService.java rename to spring-di-3/src/main/java/com/baeldung/dynamic/autowire/BeanFactoryDynamicAutowireService.java diff --git a/spring-core-4/src/main/java/com/baeldung/dynamic/autowire/CustomMapFromListDynamicAutowireService.java b/spring-di-3/src/main/java/com/baeldung/dynamic/autowire/CustomMapFromListDynamicAutowireService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/dynamic/autowire/CustomMapFromListDynamicAutowireService.java rename to spring-di-3/src/main/java/com/baeldung/dynamic/autowire/CustomMapFromListDynamicAutowireService.java diff --git a/spring-core-4/src/main/java/com/baeldung/dynamic/autowire/DynamicAutowireConfig.java b/spring-di-3/src/main/java/com/baeldung/dynamic/autowire/DynamicAutowireConfig.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/dynamic/autowire/DynamicAutowireConfig.java rename to spring-di-3/src/main/java/com/baeldung/dynamic/autowire/DynamicAutowireConfig.java diff --git a/spring-core-4/src/main/java/com/baeldung/dynamic/autowire/GBRegionService.java b/spring-di-3/src/main/java/com/baeldung/dynamic/autowire/GBRegionService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/dynamic/autowire/GBRegionService.java rename to spring-di-3/src/main/java/com/baeldung/dynamic/autowire/GBRegionService.java diff --git a/spring-core-4/src/main/java/com/baeldung/dynamic/autowire/RegionService.java b/spring-di-3/src/main/java/com/baeldung/dynamic/autowire/RegionService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/dynamic/autowire/RegionService.java rename to spring-di-3/src/main/java/com/baeldung/dynamic/autowire/RegionService.java diff --git a/spring-core-4/src/main/java/com/baeldung/dynamic/autowire/USRegionService.java b/spring-di-3/src/main/java/com/baeldung/dynamic/autowire/USRegionService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/dynamic/autowire/USRegionService.java rename to spring-di-3/src/main/java/com/baeldung/dynamic/autowire/USRegionService.java diff --git a/spring-core-4/src/main/java/com/baeldung/importannotation/animal/AnimalConfiguration.java b/spring-di-3/src/main/java/com/baeldung/importannotation/animal/AnimalConfiguration.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/importannotation/animal/AnimalConfiguration.java rename to spring-di-3/src/main/java/com/baeldung/importannotation/animal/AnimalConfiguration.java diff --git a/spring-core-4/src/main/java/com/baeldung/importannotation/animal/AnimalScanConfiguration.java b/spring-di-3/src/main/java/com/baeldung/importannotation/animal/AnimalScanConfiguration.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/importannotation/animal/AnimalScanConfiguration.java rename to spring-di-3/src/main/java/com/baeldung/importannotation/animal/AnimalScanConfiguration.java diff --git a/spring-core-4/src/main/java/com/baeldung/importannotation/animal/Bird.java b/spring-di-3/src/main/java/com/baeldung/importannotation/animal/Bird.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/importannotation/animal/Bird.java rename to spring-di-3/src/main/java/com/baeldung/importannotation/animal/Bird.java diff --git a/spring-core-4/src/main/java/com/baeldung/importannotation/animal/BirdConfig.java b/spring-di-3/src/main/java/com/baeldung/importannotation/animal/BirdConfig.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/importannotation/animal/BirdConfig.java rename to spring-di-3/src/main/java/com/baeldung/importannotation/animal/BirdConfig.java diff --git a/spring-core-4/src/main/java/com/baeldung/importannotation/animal/Bug.java b/spring-di-3/src/main/java/com/baeldung/importannotation/animal/Bug.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/importannotation/animal/Bug.java rename to spring-di-3/src/main/java/com/baeldung/importannotation/animal/Bug.java diff --git a/spring-core-4/src/main/java/com/baeldung/importannotation/animal/BugConfig.java b/spring-di-3/src/main/java/com/baeldung/importannotation/animal/BugConfig.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/importannotation/animal/BugConfig.java rename to spring-di-3/src/main/java/com/baeldung/importannotation/animal/BugConfig.java diff --git a/spring-core-4/src/main/java/com/baeldung/importannotation/animal/Cat.java b/spring-di-3/src/main/java/com/baeldung/importannotation/animal/Cat.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/importannotation/animal/Cat.java rename to spring-di-3/src/main/java/com/baeldung/importannotation/animal/Cat.java diff --git a/spring-core-4/src/main/java/com/baeldung/importannotation/animal/CatConfig.java b/spring-di-3/src/main/java/com/baeldung/importannotation/animal/CatConfig.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/importannotation/animal/CatConfig.java rename to spring-di-3/src/main/java/com/baeldung/importannotation/animal/CatConfig.java diff --git a/spring-core-4/src/main/java/com/baeldung/importannotation/animal/Dog.java b/spring-di-3/src/main/java/com/baeldung/importannotation/animal/Dog.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/importannotation/animal/Dog.java rename to spring-di-3/src/main/java/com/baeldung/importannotation/animal/Dog.java diff --git a/spring-core-4/src/main/java/com/baeldung/importannotation/animal/DogConfig.java b/spring-di-3/src/main/java/com/baeldung/importannotation/animal/DogConfig.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/importannotation/animal/DogConfig.java rename to spring-di-3/src/main/java/com/baeldung/importannotation/animal/DogConfig.java diff --git a/spring-core-4/src/main/java/com/baeldung/importannotation/animal/MammalConfiguration.java b/spring-di-3/src/main/java/com/baeldung/importannotation/animal/MammalConfiguration.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/importannotation/animal/MammalConfiguration.java rename to spring-di-3/src/main/java/com/baeldung/importannotation/animal/MammalConfiguration.java diff --git a/spring-core-4/src/main/java/com/baeldung/importannotation/zoo/ZooApplication.java b/spring-di-3/src/main/java/com/baeldung/importannotation/zoo/ZooApplication.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/importannotation/zoo/ZooApplication.java rename to spring-di-3/src/main/java/com/baeldung/importannotation/zoo/ZooApplication.java diff --git a/spring-core-2/src/main/java/com/baeldung/order/Average.java b/spring-di-3/src/main/java/com/baeldung/order/Average.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/order/Average.java rename to spring-di-3/src/main/java/com/baeldung/order/Average.java diff --git a/spring-core-2/src/main/java/com/baeldung/order/Excellent.java b/spring-di-3/src/main/java/com/baeldung/order/Excellent.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/order/Excellent.java rename to spring-di-3/src/main/java/com/baeldung/order/Excellent.java diff --git a/spring-core-2/src/main/java/com/baeldung/order/Good.java b/spring-di-3/src/main/java/com/baeldung/order/Good.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/order/Good.java rename to spring-di-3/src/main/java/com/baeldung/order/Good.java diff --git a/spring-core-2/src/main/java/com/baeldung/order/Rating.java b/spring-di-3/src/main/java/com/baeldung/order/Rating.java similarity index 100% rename from spring-core-2/src/main/java/com/baeldung/order/Rating.java rename to spring-di-3/src/main/java/com/baeldung/order/Rating.java diff --git a/spring-core-2/src/test/java/com/baeldung/autowire/sample/FooServiceIntegrationTest.java b/spring-di-3/src/test/java/com/baeldung/autowire/sample/FooServiceIntegrationTest.java similarity index 100% rename from spring-core-2/src/test/java/com/baeldung/autowire/sample/FooServiceIntegrationTest.java rename to spring-di-3/src/test/java/com/baeldung/autowire/sample/FooServiceIntegrationTest.java diff --git a/spring-core-4/src/test/java/com/baeldung/dynamic/autowire/DynamicAutowireIntegrationTest.java b/spring-di-3/src/test/java/com/baeldung/dynamic/autowire/DynamicAutowireIntegrationTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/dynamic/autowire/DynamicAutowireIntegrationTest.java rename to spring-di-3/src/test/java/com/baeldung/dynamic/autowire/DynamicAutowireIntegrationTest.java diff --git a/spring-core-4/src/test/java/com/baeldung/importannotation/animal/AnimalConfigUnitTest.java b/spring-di-3/src/test/java/com/baeldung/importannotation/animal/AnimalConfigUnitTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/importannotation/animal/AnimalConfigUnitTest.java rename to spring-di-3/src/test/java/com/baeldung/importannotation/animal/AnimalConfigUnitTest.java diff --git a/spring-core-4/src/test/java/com/baeldung/importannotation/animal/BugConfigUnitTest.java b/spring-di-3/src/test/java/com/baeldung/importannotation/animal/BugConfigUnitTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/importannotation/animal/BugConfigUnitTest.java rename to spring-di-3/src/test/java/com/baeldung/importannotation/animal/BugConfigUnitTest.java diff --git a/spring-core-4/src/test/java/com/baeldung/importannotation/animal/ConfigUnitTest.java b/spring-di-3/src/test/java/com/baeldung/importannotation/animal/ConfigUnitTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/importannotation/animal/ConfigUnitTest.java rename to spring-di-3/src/test/java/com/baeldung/importannotation/animal/ConfigUnitTest.java diff --git a/spring-core-4/src/test/java/com/baeldung/importannotation/animal/MammalConfigUnitTest.java b/spring-di-3/src/test/java/com/baeldung/importannotation/animal/MammalConfigUnitTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/importannotation/animal/MammalConfigUnitTest.java rename to spring-di-3/src/test/java/com/baeldung/importannotation/animal/MammalConfigUnitTest.java diff --git a/spring-core-4/src/test/java/com/baeldung/importannotation/zoo/ZooApplicationUnitTest.java b/spring-di-3/src/test/java/com/baeldung/importannotation/zoo/ZooApplicationUnitTest.java similarity index 100% rename from spring-core-4/src/test/java/com/baeldung/importannotation/zoo/ZooApplicationUnitTest.java rename to spring-di-3/src/test/java/com/baeldung/importannotation/zoo/ZooApplicationUnitTest.java diff --git a/spring-core-2/src/test/java/com/baeldung/order/RatingRetrieverUnitTest.java b/spring-di-3/src/test/java/com/baeldung/order/RatingRetrieverUnitTest.java similarity index 100% rename from spring-core-2/src/test/java/com/baeldung/order/RatingRetrieverUnitTest.java rename to spring-di-3/src/test/java/com/baeldung/order/RatingRetrieverUnitTest.java diff --git a/spring-di-4/README.md b/spring-di-4/README.md new file mode 100644 index 0000000000..d4b0d94385 --- /dev/null +++ b/spring-di-4/README.md @@ -0,0 +1,9 @@ +## Spring Dependency Injection + +This module contains articles about dependency injection with Spring + +### Relevant Articles + +- [Using @Autowired in Abstract Classes](https://www.baeldung.com/spring-autowired-abstract-class) +- [Spring @Component Annotation](https://www.baeldung.com/spring-component-annotation) +- More articles: [[<-- prev]](../spring-di-3) diff --git a/spring-di-4/pom.xml b/spring-di-4/pom.xml new file mode 100644 index 0000000000..c6572495cb --- /dev/null +++ b/spring-di-4/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + spring-di-4 + 1.0-SNAPSHOT + spring-di-4 + + + 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-test + + + + \ No newline at end of file diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/AmbiguousBean.java b/spring-di-4/src/main/java/com/baeldung/component/inscope/AmbiguousBean.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/inscope/AmbiguousBean.java rename to spring-di-4/src/main/java/com/baeldung/component/inscope/AmbiguousBean.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/BeanExample.java b/spring-di-4/src/main/java/com/baeldung/component/inscope/BeanExample.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/inscope/BeanExample.java rename to spring-di-4/src/main/java/com/baeldung/component/inscope/BeanExample.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/BeanImplA.java b/spring-di-4/src/main/java/com/baeldung/component/inscope/BeanImplA.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/inscope/BeanImplA.java rename to spring-di-4/src/main/java/com/baeldung/component/inscope/BeanImplA.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/BeanImplB.java b/spring-di-4/src/main/java/com/baeldung/component/inscope/BeanImplB.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/inscope/BeanImplB.java rename to spring-di-4/src/main/java/com/baeldung/component/inscope/BeanImplB.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/ComponentApplication.java b/spring-di-4/src/main/java/com/baeldung/component/inscope/ComponentApplication.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/inscope/ComponentApplication.java rename to spring-di-4/src/main/java/com/baeldung/component/inscope/ComponentApplication.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/ComponentExample.java b/spring-di-4/src/main/java/com/baeldung/component/inscope/ComponentExample.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/inscope/ComponentExample.java rename to spring-di-4/src/main/java/com/baeldung/component/inscope/ComponentExample.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/ControllerExample.java b/spring-di-4/src/main/java/com/baeldung/component/inscope/ControllerExample.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/inscope/ControllerExample.java rename to spring-di-4/src/main/java/com/baeldung/component/inscope/ControllerExample.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/CustomComponent.java b/spring-di-4/src/main/java/com/baeldung/component/inscope/CustomComponent.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/inscope/CustomComponent.java rename to spring-di-4/src/main/java/com/baeldung/component/inscope/CustomComponent.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/CustomComponentExample.java b/spring-di-4/src/main/java/com/baeldung/component/inscope/CustomComponentExample.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/inscope/CustomComponentExample.java rename to spring-di-4/src/main/java/com/baeldung/component/inscope/CustomComponentExample.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/RepositoryExample.java b/spring-di-4/src/main/java/com/baeldung/component/inscope/RepositoryExample.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/inscope/RepositoryExample.java rename to spring-di-4/src/main/java/com/baeldung/component/inscope/RepositoryExample.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/ServiceExample.java b/spring-di-4/src/main/java/com/baeldung/component/inscope/ServiceExample.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/inscope/ServiceExample.java rename to spring-di-4/src/main/java/com/baeldung/component/inscope/ServiceExample.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/outsidescope/OutsideScopeBeanExample.java b/spring-di-4/src/main/java/com/baeldung/component/outsidescope/OutsideScopeBeanExample.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/outsidescope/OutsideScopeBeanExample.java rename to spring-di-4/src/main/java/com/baeldung/component/outsidescope/OutsideScopeBeanExample.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/outsidescope/OutsideScopeExample.java b/spring-di-4/src/main/java/com/baeldung/component/outsidescope/OutsideScopeExample.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/outsidescope/OutsideScopeExample.java rename to spring-di-4/src/main/java/com/baeldung/component/outsidescope/OutsideScopeExample.java diff --git a/spring-core-5/src/main/java/com/baeldung/component/scannedscope/ScannedScopeExample.java b/spring-di-4/src/main/java/com/baeldung/component/scannedscope/ScannedScopeExample.java similarity index 100% rename from spring-core-5/src/main/java/com/baeldung/component/scannedscope/ScannedScopeExample.java rename to spring-di-4/src/main/java/com/baeldung/component/scannedscope/ScannedScopeExample.java diff --git a/spring-core-4/src/main/java/com/baeldung/sampleabstract/BallService.java b/spring-di-4/src/main/java/com/baeldung/sampleabstract/BallService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/sampleabstract/BallService.java rename to spring-di-4/src/main/java/com/baeldung/sampleabstract/BallService.java diff --git a/spring-core-4/src/main/java/com/baeldung/sampleabstract/BasketballService.java b/spring-di-4/src/main/java/com/baeldung/sampleabstract/BasketballService.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/sampleabstract/BasketballService.java rename to spring-di-4/src/main/java/com/baeldung/sampleabstract/BasketballService.java diff --git a/spring-core-4/src/main/java/com/baeldung/sampleabstract/DemoApp.java b/spring-di-4/src/main/java/com/baeldung/sampleabstract/DemoApp.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/sampleabstract/DemoApp.java rename to spring-di-4/src/main/java/com/baeldung/sampleabstract/DemoApp.java diff --git a/spring-core-4/src/main/java/com/baeldung/sampleabstract/LogRepository.java b/spring-di-4/src/main/java/com/baeldung/sampleabstract/LogRepository.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/sampleabstract/LogRepository.java rename to spring-di-4/src/main/java/com/baeldung/sampleabstract/LogRepository.java diff --git a/spring-core-4/src/main/java/com/baeldung/sampleabstract/RuleRepository.java b/spring-di-4/src/main/java/com/baeldung/sampleabstract/RuleRepository.java similarity index 100% rename from spring-core-4/src/main/java/com/baeldung/sampleabstract/RuleRepository.java rename to spring-di-4/src/main/java/com/baeldung/sampleabstract/RuleRepository.java diff --git a/spring-core-5/src/main/resources/application.yml b/spring-di-4/src/main/resources/application.yml similarity index 100% rename from spring-core-5/src/main/resources/application.yml rename to spring-di-4/src/main/resources/application.yml diff --git a/spring-core-5/src/test/java/com/baeldung/component/inscope/ComponentUnitTest.java b/spring-di-4/src/test/java/com/baeldung/component/inscope/ComponentUnitTest.java similarity index 100% rename from spring-core-5/src/test/java/com/baeldung/component/inscope/ComponentUnitTest.java rename to spring-di-4/src/test/java/com/baeldung/component/inscope/ComponentUnitTest.java diff --git a/spring-core-5/src/test/resources/application.yml b/spring-di-4/src/test/resources/application.yml similarity index 100% rename from spring-core-5/src/test/resources/application.yml rename to spring-di-4/src/test/resources/application.yml diff --git a/spring-core-5/src/test/resources/logback-test.xml b/spring-di-4/src/test/resources/logback-test.xml similarity index 100% rename from spring-core-5/src/test/resources/logback-test.xml rename to spring-di-4/src/test/resources/logback-test.xml diff --git a/spring-drools/src/main/java/com/baeldung/spring/drools/service/TaxiFareCalculatorService.java b/spring-drools/src/main/java/com/baeldung/spring/drools/service/TaxiFareCalculatorService.java index c2c5b399df..8f6f49c29b 100644 --- a/spring-drools/src/main/java/com/baeldung/spring/drools/service/TaxiFareCalculatorService.java +++ b/spring-drools/src/main/java/com/baeldung/spring/drools/service/TaxiFareCalculatorService.java @@ -2,6 +2,8 @@ package com.baeldung.spring.drools.service; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -11,6 +13,8 @@ import com.baeldung.spring.drools.model.TaxiRide; @Service public class TaxiFareCalculatorService { + private static final Logger LOGGER = LoggerFactory.getLogger(TaxiFareCalculatorService.class); + @Autowired private KieContainer kContainer; @@ -20,7 +24,7 @@ public class TaxiFareCalculatorService { kieSession.insert(taxiRide); kieSession.fireAllRules(); kieSession.dispose(); - System.out.println("!! RIDE FARE !! " + rideFare.getTotalFare()); + LOGGER.debug("!! RIDE FARE !! " + rideFare.getTotalFare()); return rideFare.getTotalFare(); } } diff --git a/spring-kafka-2/README.md b/spring-kafka-2/README.md index 1f5e015f9e..60d7d8b607 100644 --- a/spring-kafka-2/README.md +++ b/spring-kafka-2/README.md @@ -5,3 +5,4 @@ This module contains articles about Spring with Kafka ### Relevant articles - [Implementing Retry In Kafka Consumer](https://www.baeldung.com/spring-retry-kafka-consumer) +- [Spring Kafka: Configure Multiple Listeners on Same Topic](https://www.baeldung.com/spring-kafka-multiple-listeners-same-topic) diff --git a/spring-kafka/pom.xml b/spring-kafka/pom.xml index 7b0bb0a8b7..c013be32e3 100644 --- a/spring-kafka/pom.xml +++ b/spring-kafka/pom.xml @@ -23,6 +23,16 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-actuator + 3.0.5 + + + io.micrometer + micrometer-registry-prometheus + 1.10.5 + org.springframework.kafka spring-kafka diff --git a/spring-kafka/src/main/java/com/baeldung/monitoring/LagAnalyzerApplication.java b/spring-kafka/src/main/java/com/baeldung/monitoring/LagAnalyzerApplication.java index 9275151d50..d305af8c87 100644 --- a/spring-kafka/src/main/java/com/baeldung/monitoring/LagAnalyzerApplication.java +++ b/spring-kafka/src/main/java/com/baeldung/monitoring/LagAnalyzerApplication.java @@ -10,6 +10,7 @@ public class LagAnalyzerApplication { public static void main(String[] args) { SpringApplication.run(LagAnalyzerApplication.class, args); - while (true) ; + while (true) + ; } } diff --git a/spring-kafka/src/main/java/com/baeldung/monitoring/service/LagAnalyzerService.java b/spring-kafka/src/main/java/com/baeldung/monitoring/service/LagAnalyzerService.java index b046f0b2c4..f8898b60d8 100644 --- a/spring-kafka/src/main/java/com/baeldung/monitoring/service/LagAnalyzerService.java +++ b/spring-kafka/src/main/java/com/baeldung/monitoring/service/LagAnalyzerService.java @@ -1,6 +1,7 @@ package com.baeldung.monitoring.service; import com.baeldung.monitoring.util.MonitoringUtil; + import org.apache.kafka.clients.admin.AdminClient; import org.apache.kafka.clients.admin.AdminClientConfig; import org.apache.kafka.clients.admin.ListConsumerGroupOffsetsResult; @@ -27,36 +28,38 @@ public class LagAnalyzerService { private final KafkaConsumer consumer; @Autowired - public LagAnalyzerService( - @Value("${monitor.kafka.bootstrap.config}") String bootstrapServerConfig) { + public LagAnalyzerService(@Value("${monitor.kafka.bootstrap.config}") String bootstrapServerConfig) { adminClient = getAdminClient(bootstrapServerConfig); consumer = getKafkaConsumer(bootstrapServerConfig); } - public Map analyzeLag( - String groupId) - throws ExecutionException, InterruptedException { + public Map analyzeLag(String groupId) + throws ExecutionException, InterruptedException { Map consumerGrpOffsets = getConsumerGrpOffsets(groupId); Map producerOffsets = getProducerOffsets(consumerGrpOffsets); Map lags = computeLags(consumerGrpOffsets, producerOffsets); for (Map.Entry lagEntry : lags.entrySet()) { - String topic = lagEntry.getKey().topic(); - int partition = lagEntry.getKey().partition(); + String topic = lagEntry.getKey() + .topic(); + int partition = lagEntry.getKey() + .partition(); Long lag = lagEntry.getValue(); - LOGGER.info("Time={} | Lag for topic = {}, partition = {} is {}", - MonitoringUtil.time(), - topic, - partition, - lag); + LOGGER.info("Time={} | Lag for topic = {}, partition = {}, groupId = {} is {}", + MonitoringUtil.time(), + topic, + partition, + groupId, + lag); } return lags; } public Map getConsumerGrpOffsets(String groupId) - throws ExecutionException, InterruptedException { + throws ExecutionException, InterruptedException { ListConsumerGroupOffsetsResult info = adminClient.listConsumerGroupOffsets(groupId); - Map metadataMap - = info.partitionsToOffsetAndMetadata().get(); + Map metadataMap = info + .partitionsToOffsetAndMetadata() + .get(); Map groupOffset = new HashMap<>(); for (Map.Entry entry : metadataMap.entrySet()) { TopicPartition key = entry.getKey(); @@ -66,8 +69,7 @@ public class LagAnalyzerService { return groupOffset; } - private Map getProducerOffsets( - Map consumerGrpOffset) { + private Map getProducerOffsets(Map consumerGrpOffset) { List topicPartitions = new LinkedList<>(); for (Map.Entry entry : consumerGrpOffset.entrySet()) { TopicPartition key = entry.getKey(); @@ -77,9 +79,9 @@ public class LagAnalyzerService { } public Map computeLags( - Map consumerGrpOffsets, - Map producerOffsets) { - Map lags = new HashMap<>(); + Map consumerGrpOffsets, + Map producerOffsets) { + Map lags = new HashMap<>(); for (Map.Entry entry : consumerGrpOffsets.entrySet()) { Long producerOffset = producerOffsets.get(entry.getKey()); Long consumerOffset = consumerGrpOffsets.get(entry.getKey()); @@ -91,15 +93,24 @@ public class LagAnalyzerService { private AdminClient getAdminClient(String bootstrapServerConfig) { Properties config = new Properties(); - config.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServerConfig); + config.put( + AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, + bootstrapServerConfig); return AdminClient.create(config); } - private KafkaConsumer getKafkaConsumer(String bootstrapServerConfig) { + private KafkaConsumer getKafkaConsumer( + String bootstrapServerConfig) { Properties properties = new Properties(); - properties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServerConfig); - properties.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); - properties.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + properties.setProperty( + ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, + bootstrapServerConfig); + properties.setProperty( + ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, + StringDeserializer.class.getName()); + properties.setProperty( + ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, + StringDeserializer.class.getName()); return new KafkaConsumer<>(properties); } } diff --git a/spring-kafka/src/main/java/com/baeldung/monitoring/service/LiveLagAnalyzerService.java b/spring-kafka/src/main/java/com/baeldung/monitoring/service/LiveLagAnalyzerService.java index a20b9e9a0c..7035bf73bd 100644 --- a/spring-kafka/src/main/java/com/baeldung/monitoring/service/LiveLagAnalyzerService.java +++ b/spring-kafka/src/main/java/com/baeldung/monitoring/service/LiveLagAnalyzerService.java @@ -15,8 +15,8 @@ public class LiveLagAnalyzerService { @Autowired public LiveLagAnalyzerService( - LagAnalyzerService lagAnalyzerService, - @Value(value = "${monitor.kafka.consumer.groupid}") String groupId) { + LagAnalyzerService lagAnalyzerService, + @Value(value = "${monitor.kafka.consumer.groupid}") String groupId) { this.lagAnalyzerService = lagAnalyzerService; this.groupId = groupId; } diff --git a/spring-kafka/src/main/java/com/baeldung/monitoring/simulation/ConsumerSimulator.java b/spring-kafka/src/main/java/com/baeldung/monitoring/simulation/ConsumerSimulator.java index 2d376432e5..171c17a282 100644 --- a/spring-kafka/src/main/java/com/baeldung/monitoring/simulation/ConsumerSimulator.java +++ b/spring-kafka/src/main/java/com/baeldung/monitoring/simulation/ConsumerSimulator.java @@ -7,10 +7,9 @@ import org.springframework.stereotype.Service; @Service public class ConsumerSimulator { - @KafkaListener( - topics = "${monitor.topic.name}", - containerFactory = "kafkaListenerContainerFactory", - autoStartup = "${monitor.consumer.simulate}") + @KafkaListener(topics = "${monitor.topic.name}", + containerFactory = "kafkaListenerContainerFactory", + autoStartup = "${monitor.consumer.simulate}") public void listenGroup(String message) throws InterruptedException { Thread.sleep(10L); } diff --git a/spring-kafka/src/main/java/com/baeldung/monitoring/simulation/KafkaConsumerConfig.java b/spring-kafka/src/main/java/com/baeldung/monitoring/simulation/KafkaConsumerConfig.java index a4a8847bcf..9d5160e713 100644 --- a/spring-kafka/src/main/java/com/baeldung/monitoring/simulation/KafkaConsumerConfig.java +++ b/spring-kafka/src/main/java/com/baeldung/monitoring/simulation/KafkaConsumerConfig.java @@ -2,53 +2,54 @@ package com.baeldung.monitoring.simulation; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.common.serialization.StringDeserializer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; import org.springframework.kafka.annotation.EnableKafka; import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; import org.springframework.kafka.core.ConsumerFactory; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.MicrometerConsumerListener; +import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; +import io.micrometer.core.instrument.MeterRegistry; + @EnableKafka -@Configuration +@Component public class KafkaConsumerConfig { @Value(value = "${monitor.kafka.bootstrap.config}") private String bootstrapAddress; @Value(value = "${monitor.kafka.consumer.groupid}") private String groupId; - @Value(value = "${monitor.kafka.consumer.groupid.simulate}") - private String simulateGroupId; - @Value(value = "${monitor.producer.simulate}") - private boolean enabled; - public ConsumerFactory consumerFactory(String groupId) { + @Autowired + private MeterRegistry meterRegistry; + + @Bean + public ConsumerFactory consumerFactory() { Map props = new HashMap<>(); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); - if (enabled) { - props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); - } else { - props.put(ConsumerConfig.GROUP_ID_CONFIG, simulateGroupId); - } props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, 0); - return new DefaultKafkaConsumerFactory<>(props); + props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); + DefaultKafkaConsumerFactory consumerFactory = new DefaultKafkaConsumerFactory<>(props); + consumerFactory.addListener(new MicrometerConsumerListener<>(this.meterRegistry)); + return consumerFactory; } @Bean - public ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() { - ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); - if (enabled) { - factory.setConsumerFactory(consumerFactory(groupId)); - } else { - factory.setConsumerFactory(consumerFactory(simulateGroupId)); - } - return factory; + public ConcurrentKafkaListenerContainerFactory + kafkaListenerContainerFactory(@Qualifier("consumerFactory") ConsumerFactory consumerFactory) { + ConcurrentKafkaListenerContainerFactory listenerContainerFactory = + new ConcurrentKafkaListenerContainerFactory<>(); + listenerContainerFactory.setConsumerFactory(consumerFactory); + return listenerContainerFactory; } } diff --git a/spring-kafka/src/main/java/com/baeldung/monitoring/simulation/ProducerSimulator.java b/spring-kafka/src/main/java/com/baeldung/monitoring/simulation/ProducerSimulator.java index 30476ff7ec..ad4a006809 100644 --- a/spring-kafka/src/main/java/com/baeldung/monitoring/simulation/ProducerSimulator.java +++ b/spring-kafka/src/main/java/com/baeldung/monitoring/simulation/ProducerSimulator.java @@ -23,10 +23,9 @@ public class ProducerSimulator { private final boolean enabled; @Autowired - public ProducerSimulator( - KafkaTemplate kafkaTemplate, - @Value(value = "${monitor.topic.name}") String topicName, - @Value(value = "${monitor.producer.simulate}") String enabled) { + public ProducerSimulator(KafkaTemplate kafkaTemplate, + @Value(value = "${monitor.topic.name}") String topicName, + @Value(value = "${monitor.producer.simulate}") String enabled) { this.kafkaTemplate = kafkaTemplate; this.topicName = topicName; this.enabled = BooleanUtils.toBoolean(enabled); @@ -37,7 +36,9 @@ public class ProducerSimulator { if (enabled) { if (endTime.after(new Date())) { String message = "msg-" + time(); - SendResult result = kafkaTemplate.send(topicName, message).get(); + SendResult result = kafkaTemplate + .send(topicName, message) + .get(); } } } diff --git a/spring-kafka/src/main/resources/application.properties b/spring-kafka/src/main/resources/application.properties index c57537e2af..1a639a43fc 100644 --- a/spring-kafka/src/main/resources/application.properties +++ b/spring-kafka/src/main/resources/application.properties @@ -1,3 +1,4 @@ +server.port=8081 spring.kafka.bootstrap-servers=localhost:9092 message.topic.name=baeldung long.message.topic.name=longMessage @@ -15,3 +16,12 @@ monitor.consumer.simulate=true monitor.kafka.consumer.groupid.simulate=baeldungGrpSimulate test.topic=testtopic1 + + +management.endpoints.web.base-path=/actuator +management.endpoints.web.exposure.include=* +management.endpoint.health.show-details=always +management.endpoint.metrics.enabled=true +management.endpoint.prometheus.enabled=true + +spring.jmx.enabled=false diff --git a/spring-reactive-modules/spring-5-reactive-3/README.md b/spring-reactive-modules/spring-5-reactive-3/README.md index 24a7c43ad3..38036f929b 100644 --- a/spring-reactive-modules/spring-5-reactive-3/README.md +++ b/spring-reactive-modules/spring-5-reactive-3/README.md @@ -5,4 +5,5 @@ This module contains articles about reactive Spring 5. - [Logging a Reactive Sequence](https://www.baeldung.com/spring-reactive-sequence-logging) - [Reading Flux Into a Single InputStream Using Spring Reactive WebClient](https://www.baeldung.com/spring-reactive-read-flux-into-inputstream) - [Spring Boot FeignClient vs. WebClient](https://www.baeldung.com/spring-boot-feignclient-vs-webclient) +- [Cancel an Ongoing Flux in Spring WebFlux](https://www.baeldung.com/spring-webflux-cancel-flux) - More articles: [[<-- prev]](../spring-5-reactive-2) diff --git a/spring-reactive-modules/spring-5-reactive-3/src/test/java/com/baeldung/cancelflux/CancelFluxUnitTest.java b/spring-reactive-modules/spring-5-reactive-3/src/test/java/com/baeldung/cancelflux/CancelFluxUnitTest.java new file mode 100644 index 0000000000..e360c2d5e4 --- /dev/null +++ b/spring-reactive-modules/spring-5-reactive-3/src/test/java/com/baeldung/cancelflux/CancelFluxUnitTest.java @@ -0,0 +1,123 @@ +package com.baeldung.cancelflux; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; + +import java.io.PrintStream; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; + +import reactor.core.Disposable; +import reactor.core.publisher.Flux; +import reactor.core.publisher.SignalType; +import reactor.test.StepVerifier; + +public class CancelFluxUnitTest { + + @Test + void givenOngoingFlux_whentakeUntil_thenFluxCancels() { + Flux sensorData = Flux.range(1, 10); + List result = new ArrayList<>(); + + sensorData.takeUntil(reading -> reading == 8) + .subscribe(result::add); + assertThat(result).containsExactly(1, 2, 3, 4, 5, 6, 7, 8); + } + + @Test + void givenOngoingFlux_whentakeWhile_thenFluxCancels() { + List result = new ArrayList<>(); + Flux sensorData = Flux.range(1, 10) + .takeWhile(reading -> reading < 8) + .doOnNext(result::add); + + sensorData.subscribe(); + assertThat(result).containsExactly(1, 2, 3, 4, 5, 6, 7); + } + + @Test + void givenOngoingFlux_whentake_thenFluxCancels() { + Flux sensorData = Flux.range(1, Integer.MAX_VALUE); + List result = new ArrayList<>(); + + sensorData.take(2) + .subscribe(result::add); + assertThat(result).containsExactly(1, 2); + } + + @Test + void givenAnOnGoingFlux_whenTakeDurationElapsed_thenCancelsFlux() { + Flux sensorData = Flux.interval(Duration.ZERO, Duration.ofSeconds(2)) + .map(i -> i.intValue() + 10) + .take(5); + + Flux canceledByTimeout = sensorData.take(Duration.ofSeconds(3)); + + StepVerifier.create(canceledByTimeout) + .expectNext(10, 11) + .expectComplete() + .verify(); + } + + @Test + void givenAnOnGoingFlux_whenDispose_thenCancelsFluxExplicitly() throws InterruptedException { + Flux flux = Flux.range(1, 10) + .delayElements(Duration.ofSeconds(1)); + + AtomicInteger count = new AtomicInteger(0); + Disposable disposable = flux.subscribe(i -> { + System.out.println("Received: " + i); + count.incrementAndGet(); + }, e -> System.err.println("Error: " + e.getMessage())); + + Thread.sleep(4500); + System.out.println("Will Dispose The flux Next"); + disposable.dispose(); + if (disposable.isDisposed()) { + System.out.println("Flux Disposed"); + } + assertEquals(4, count.get()); + } + + @Test + void givenAFluxIsCanceled_whenDoOnCancelAndDoFinally_thenMessagePrinted() throws InterruptedException { + + List result = new ArrayList<>(); + PrintStream mockPrintStream = mock(PrintStream.class); + System.setOut(mockPrintStream); + + Flux sensorData = Flux.interval(Duration.ofMillis(100)) + .doOnCancel(() -> System.out.println("Flux Canceled")) + .doFinally(signalType -> { + if (signalType == SignalType.CANCEL) { + System.out.println("Flux Completed due to Cancellation"); + } else { + System.out.println("Flux Completed due to Completion or Error"); + } + }) + .map(i -> ThreadLocalRandom.current() + .nextInt(1, 1001)) + .doOnNext(result::add); + + Disposable subscription = sensorData.subscribe(); + + Thread.sleep(1000); + subscription.dispose(); + + ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); + Mockito.verify(mockPrintStream, times(2)) + .println(captor.capture()); + + assertThat(captor.getAllValues()).contains("Flux Canceled", "Flux Completed due to Cancellation"); + } + +} diff --git a/spring-reactive-modules/spring-5-reactive-3/src/test/java/com/baeldung/databuffer/DataBufferToInputStreamUnitTest.java b/spring-reactive-modules/spring-5-reactive-3/src/test/java/com/baeldung/databuffer/DataBufferToInputStreamUnitTest.java index f30b4a8a3b..975a2d8698 100644 --- a/spring-reactive-modules/spring-5-reactive-3/src/test/java/com/baeldung/databuffer/DataBufferToInputStreamUnitTest.java +++ b/spring-reactive-modules/spring-5-reactive-3/src/test/java/com/baeldung/databuffer/DataBufferToInputStreamUnitTest.java @@ -17,9 +17,12 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.URI; import java.util.stream.Collectors; import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; class DataBufferToInputStreamUnitTest { private String getResponseStub() throws IOException { @@ -67,7 +70,7 @@ class DataBufferToInputStreamUnitTest { @Test public void testResponseAsInputStream() throws IOException, InterruptedException { - String mockUrl = Mockito.anyString(); + String mockUrl = "http://mockurl.com"; WebClient mockWebClient = getMockWebClient(); InputStream inputStream = DataBufferToInputStream.getResponseAsInputStream(mockWebClient, mockUrl); byte[] expectedBytes = IOUtils.toByteArray(getResponseStubAsInputStream()); diff --git a/spring-reactive-modules/spring-5-reactive-oauth/src/main/java/com/baeldung/webclient/manualrequest/web/ManualOauthRequestController.java b/spring-reactive-modules/spring-5-reactive-oauth/src/main/java/com/baeldung/webclient/manualrequest/web/ManualOauthRequestController.java index d54d811032..c449a5991e 100644 --- a/spring-reactive-modules/spring-5-reactive-oauth/src/main/java/com/baeldung/webclient/manualrequest/web/ManualOauthRequestController.java +++ b/spring-reactive-modules/spring-5-reactive-oauth/src/main/java/com/baeldung/webclient/manualrequest/web/ManualOauthRequestController.java @@ -1,12 +1,13 @@ package com.baeldung.webclient.manualrequest.web; +import java.util.Base64; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; -import org.springframework.util.Base64Utils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.reactive.function.BodyInserters; @@ -41,7 +42,8 @@ public class ManualOauthRequestController { logger.info("Creating web client..."); Mono resource = client.post() .uri(tokenUri) - .header(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString((clientId + ":" + clientSecret).getBytes())) + .header(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder() + .encodeToString((clientId + ":" + clientSecret).getBytes())) .body(BodyInserters.fromFormData(OAuth2ParameterNames.GRANT_TYPE, GrantType.CLIENT_CREDENTIALS.getValue())) .retrieve() .bodyToMono(JsonNode.class) diff --git a/spring-reactive-modules/spring-5-reactive-security/src/test/java/com/baeldung/reactive/authresolver/AuthResolverIntegrationTest.java b/spring-reactive-modules/spring-5-reactive-security/src/test/java/com/baeldung/reactive/authresolver/AuthResolverIntegrationTest.java index 691243b3ea..9e0855d086 100644 --- a/spring-reactive-modules/spring-5-reactive-security/src/test/java/com/baeldung/reactive/authresolver/AuthResolverIntegrationTest.java +++ b/spring-reactive-modules/spring-5-reactive-security/src/test/java/com/baeldung/reactive/authresolver/AuthResolverIntegrationTest.java @@ -1,5 +1,7 @@ package com.baeldung.reactive.authresolver; +import java.util.Base64; + import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; @@ -8,7 +10,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.util.Base64Utils; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = AuthResolverApplication.class) @@ -22,7 +23,7 @@ public class AuthResolverIntegrationTest { testClient .get() .uri("/customer/welcome") - .header("Authorization", "Basic " + Base64Utils.encodeToString("customer1:pass1".getBytes())) + .header("Authorization", "Basic " + Base64.getEncoder().encodeToString("customer1:pass1".getBytes())) .exchange() .expectStatus() .isOk(); @@ -33,7 +34,7 @@ public class AuthResolverIntegrationTest { testClient .get() .uri("/customer/welcome") - .header("Authorization", "Basic " + Base64Utils.encodeToString("employee1:pass1".getBytes())) + .header("Authorization", "Basic " + Base64.getEncoder().encodeToString("employee1:pass1".getBytes())) .exchange() .expectStatus() .isUnauthorized(); @@ -44,7 +45,7 @@ public class AuthResolverIntegrationTest { testClient .get() .uri("/employee/welcome") - .header("Authorization", "Basic " + Base64Utils.encodeToString("employee1:pass1".getBytes())) + .header("Authorization", "Basic " + Base64.getEncoder().encodeToString("employee1:pass1".getBytes())) .exchange() .expectStatus() .isOk(); @@ -55,7 +56,7 @@ public class AuthResolverIntegrationTest { testClient .get() .uri("/employee/welcome") - .header("Authorization", "Basic " + Base64Utils.encodeToString("customer1:pass1".getBytes())) + .header("Authorization", "Basic " + Base64.getEncoder().encodeToString("customer1:pass1".getBytes())) .exchange() .expectStatus() .isUnauthorized(); diff --git a/spring-reactive-modules/spring-reactive-exceptions/pom.xml b/spring-reactive-modules/spring-reactive-exceptions/pom.xml index 024a8332c2..940ae90de3 100644 --- a/spring-reactive-modules/spring-reactive-exceptions/pom.xml +++ b/spring-reactive-modules/spring-reactive-exceptions/pom.xml @@ -8,10 +8,11 @@ spring-reactive-exceptions A module to hold demo examples related to exception in Spring Reactive - - com.baeldung.spring.reactive - spring-reactive-modules - 1.0.0-SNAPSHOT + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -19,11 +20,13 @@ org.springframework.boot spring-boot-starter-webflux - + + org.springframework.boot + spring-boot-starter-web + org.projectlombok lombok - true org.springframework.boot @@ -35,6 +38,11 @@ reactor-test test + + org.springframework + spring-test + test + @@ -43,15 +51,11 @@ org.springframework.boot spring-boot-maven-plugin - - - org.projectlombok - lombok - - + com.baeldung.spring.reactive.customexception.CustomExceptionApplication + JAR - \ No newline at end of file + diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/CustomExceptionApplication.java b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/CustomExceptionApplication.java new file mode 100644 index 0000000000..336347a50b --- /dev/null +++ b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/CustomExceptionApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.reactive.customexception; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CustomExceptionApplication { + + public static void main(String[] args) { + SpringApplication.run(CustomExceptionApplication.class, args); + } + +} diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/config/ErrorDetailsSerializer.java b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/config/ErrorDetailsSerializer.java new file mode 100644 index 0000000000..232226bd2c --- /dev/null +++ b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/config/ErrorDetailsSerializer.java @@ -0,0 +1,21 @@ +package com.baeldung.spring.reactive.customexception.config; + +import java.io.IOException; + +import com.baeldung.spring.reactive.customexception.model.ErrorDetails; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +public class ErrorDetailsSerializer extends JsonSerializer { + @Override + public void serialize(ErrorDetails value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField("code", value.getErrorCode() + .toString()); + gen.writeStringField("message", value.getErrorMessage()); + gen.writeStringField("reference", value.getReferenceUrl()); + gen.writeEndObject(); + } +} + diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/config/ProblemDetailsSerializer.java b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/config/ProblemDetailsSerializer.java new file mode 100644 index 0000000000..2947058fac --- /dev/null +++ b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/config/ProblemDetailsSerializer.java @@ -0,0 +1,25 @@ +package com.baeldung.spring.reactive.customexception.config; + +import java.io.IOException; + +import org.springframework.http.ProblemDetail; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +public class ProblemDetailsSerializer extends JsonSerializer { + + @Override + public void serialize(ProblemDetail value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeObjectField("type", value.getType()); + gen.writeObjectField("title", value.getTitle()); + gen.writeObjectField("status", value.getStatus()); + gen.writeObjectField("detail", value.getDetail()); + gen.writeObjectField("instance", value.getInstance()); + gen.writeObjectField("errors", value.getProperties().get("errors")); + gen.writeEndObject(); + } +} + diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/controller/UserController.java b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/controller/UserController.java new file mode 100644 index 0000000000..c71180f750 --- /dev/null +++ b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/controller/UserController.java @@ -0,0 +1,57 @@ +package com.baeldung.spring.reactive.customexception.controller; + +import java.time.OffsetDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.spring.reactive.customexception.exception.CustomErrorException; +import com.baeldung.spring.reactive.customexception.exception.UserNotFoundException; +import com.baeldung.spring.reactive.customexception.model.CustomErrorResponse; +import com.baeldung.spring.reactive.customexception.model.ErrorDetails; +import com.baeldung.spring.reactive.customexception.model.User; + +import reactor.core.publisher.Mono; + +@RestController +public class UserController { + + private Map userMap = new HashMap<>(); + + @GetMapping("/v1/users/{userId}") + public Mono> getV1UserById(@PathVariable Long userId) { + return Mono.fromCallable(() -> { + User user = userMap.get(userId); + if (user == null) { + throw new UserNotFoundException("User not found with ID: " + userId); + } + return new ResponseEntity<>(user, HttpStatus.OK); + }); + } + + @GetMapping("/v2/users/{userId}") + public Mono> getV2UserById(@PathVariable Long userId) { + return Mono.fromCallable(() -> { + User user = userMap.get(userId); + if (user == null) { + CustomErrorResponse customErrorResponse = CustomErrorResponse + .builder() + .traceId(UUID.randomUUID().toString()) + .timestamp(OffsetDateTime.now().now()) + .status(HttpStatus.NOT_FOUND) + .errors(List.of(ErrorDetails.API_USER_NOT_FOUND)) + .build(); + throw new CustomErrorException("User not found", customErrorResponse); + } + return new ResponseEntity<>(user, HttpStatus.OK); + }); + } + +} diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/exception/CustomErrorException.java b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/exception/CustomErrorException.java new file mode 100644 index 0000000000..3ec4f6099e --- /dev/null +++ b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/exception/CustomErrorException.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.reactive.customexception.exception; + +import com.baeldung.spring.reactive.customexception.model.CustomErrorResponse; + +import lombok.Getter; + + +public class CustomErrorException extends RuntimeException { + @Getter + private CustomErrorResponse errorResponse; + + public CustomErrorException(String message, CustomErrorResponse errorResponse) { + super(message); + this.errorResponse = errorResponse; + } +} diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/exception/GlobalExceptionHandler.java b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000000..33d6655e79 --- /dev/null +++ b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/exception/GlobalExceptionHandler.java @@ -0,0 +1,34 @@ +package com.baeldung.spring.reactive.customexception.exception; + +import java.net.URI; +import java.util.List; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ProblemDetail; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.reactive.result.method.annotation.ResponseEntityExceptionHandler; + +import com.baeldung.spring.reactive.customexception.model.CustomErrorResponse; +import com.baeldung.spring.reactive.customexception.model.ErrorDetails; + +@RestControllerAdvice +public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { + @ExceptionHandler(UserNotFoundException.class) + protected ProblemDetail handleNotFound(RuntimeException ex) { + ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage()); + problemDetail.setTitle("User not found"); + problemDetail.setType(URI.create("https://example.com/problems/user-not-found")); + problemDetail.setProperty("errors", List.of(ErrorDetails.API_USER_NOT_FOUND)); + return problemDetail; + } + + @ExceptionHandler(CustomErrorException.class) + protected ResponseEntity handleCustomError(RuntimeException ex) { + CustomErrorException customErrorException = (CustomErrorException) ex; + return ResponseEntity.status(customErrorException.getErrorResponse().getStatus()) + .body(customErrorException.getErrorResponse()); + } + +} diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/exception/UserNotFoundException.java b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/exception/UserNotFoundException.java new file mode 100644 index 0000000000..7306491bad --- /dev/null +++ b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/exception/UserNotFoundException.java @@ -0,0 +1,9 @@ +package com.baeldung.spring.reactive.customexception.exception; + +public class UserNotFoundException extends RuntimeException { + + public UserNotFoundException(String message) { + super(message); + } + +} diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/model/CustomErrorResponse.java b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/model/CustomErrorResponse.java new file mode 100644 index 0000000000..2159725a2d --- /dev/null +++ b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/model/CustomErrorResponse.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.reactive.customexception.model; + +import java.time.OffsetDateTime; +import java.util.List; + +import org.springframework.http.HttpStatus; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class CustomErrorResponse { + private String traceId; + private OffsetDateTime timestamp; + private HttpStatus status; + private List errors; +} diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/model/Error.java b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/model/Error.java new file mode 100644 index 0000000000..2c3f5c4024 --- /dev/null +++ b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/model/Error.java @@ -0,0 +1,20 @@ +package com.baeldung.spring.reactive.customexception.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Error { + + private int code; + + private String message; + + protected String reference; + +} diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/model/ErrorDetails.java b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/model/ErrorDetails.java new file mode 100644 index 0000000000..a4ca566c71 --- /dev/null +++ b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/model/ErrorDetails.java @@ -0,0 +1,25 @@ +package com.baeldung.spring.reactive.customexception.model; + + +import com.baeldung.spring.reactive.customexception.config.ErrorDetailsSerializer; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import lombok.Getter; + +@JsonSerialize(using = ErrorDetailsSerializer.class) +public enum ErrorDetails { + + API_USER_NOT_FOUND(123, "User not found", "http://example.com/123"); + @Getter + private Integer errorCode; + @Getter + private String errorMessage; + @Getter + private String referenceUrl; + + ErrorDetails(Integer errorCode, String errorMessage, String referenceUrl) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + this.referenceUrl = referenceUrl; + } +} diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/model/User.java b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/model/User.java new file mode 100644 index 0000000000..218b1ddad5 --- /dev/null +++ b/spring-reactive-modules/spring-reactive-exceptions/src/main/java/com/baeldung/spring/reactive/customexception/model/User.java @@ -0,0 +1,20 @@ +package com.baeldung.spring.reactive.customexception.model; + +import java.time.LocalDate; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class User { + private Long id; + private String firstName; + private String lastName; + private String email; + private LocalDate dateOfBirth; +} diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/main/resources/application.yaml b/spring-reactive-modules/spring-reactive-exceptions/src/main/resources/application.yaml index 5f3c8b82a9..50bcbff433 100644 --- a/spring-reactive-modules/spring-reactive-exceptions/src/main/resources/application.yaml +++ b/spring-reactive-modules/spring-reactive-exceptions/src/main/resources/application.yaml @@ -2,4 +2,6 @@ spring: codec: max-in-memory-size: 500KB +server: + port: 8080 host: http://localhost:${server.port} diff --git a/spring-reactive-modules/spring-reactive-exceptions/src/test/java/com/baeldung/spring/reactive/customexception/controller/UserControllerUnitTest.java b/spring-reactive-modules/spring-reactive-exceptions/src/test/java/com/baeldung/spring/reactive/customexception/controller/UserControllerUnitTest.java new file mode 100644 index 0000000000..150d0b08a6 --- /dev/null +++ b/spring-reactive-modules/spring-reactive-exceptions/src/test/java/com/baeldung/spring/reactive/customexception/controller/UserControllerUnitTest.java @@ -0,0 +1,84 @@ +package com.baeldung.spring.reactive.customexception.controller; + +import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.regex.Pattern; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.ProblemDetail; +import org.springframework.test.web.reactive.server.WebTestClient; + +import com.baeldung.spring.reactive.customexception.exception.GlobalExceptionHandler; +import com.baeldung.spring.reactive.customexception.model.ErrorDetails; + +@SpringBootTest(webEnvironment = RANDOM_PORT) +class UserControllerUnitTest { + + @Autowired + private WebTestClient webClient; + + @InjectMocks + private UserController userController; + + @Autowired + private GlobalExceptionHandler globalExceptionHandler; + + @BeforeEach + void setupTests() { + // Given + webClient = WebTestClient.bindToController(userController) + .controllerAdvice(globalExceptionHandler) + .configureClient() + .build(); + } + + @Test + void givenGetUserV1Endpoint_whenHitWithInvalidUser_thenResponseShouldContainProblemDetailWithCustomAttributes() throws Exception { + // When + ProblemDetail problemDetail = webClient.get() + .uri("/v1/users/123") + .exchange() + .expectStatus() + .isNotFound() + .expectBody(ProblemDetail.class) + .returnResult() + .getResponseBody(); + // Then + assertNotNull(problemDetail); + assertNotNull(problemDetail.getProperties().get("errors")); + List errors = (List) problemDetail.getProperties().get("errors"); + assertEquals(ErrorDetails.API_USER_NOT_FOUND.getErrorCode().toString(), + errors.get(0).get("code")); + assertEquals(ErrorDetails.API_USER_NOT_FOUND.getErrorMessage().toString(), + errors.get(0).get("message")); + assertEquals(ErrorDetails.API_USER_NOT_FOUND.getReferenceUrl().toString(), + errors.get(0).get("reference")); + } + + @Test + void givenGetUserV2Endpoint_whenHitWithInvalidUser_thenResponseShouldContainCustomException() throws Exception { + // When + String regex = "^\\{\\s*\"traceId\":\\s*\"[^\"]*\",\\s*\"timestamp\":\\d+\\.\\d+,\\s*\"status\":\\s*\"[^\"]*\",\\s*\"errors\":\\s*\\[\\s*\\{\\s*\"code\":\\s*\"[^\"]*\",\\s*\"message\":\\s*\"[^\"]*\",\\s*\"reference\":\\s*\"[^\"]*\"\\s*\\}\\s*\\]\\s*\\}$"; + Pattern errorResponseSampleFormat = Pattern.compile(regex); + String errorResponse = webClient.get() + .uri("/v2/users/123") + .exchange() + .expectStatus() + .isNotFound() + .expectBody(String.class) + .returnResult() + .getResponseBody(); + // Then + assertTrue(errorResponseSampleFormat.matcher(errorResponse).matches()); + } + +} diff --git a/spring-reactive-modules/spring-reactor/pom.xml b/spring-reactive-modules/spring-reactor/pom.xml index c64d449553..22eaa898bd 100644 --- a/spring-reactive-modules/spring-reactor/pom.xml +++ b/spring-reactive-modules/spring-reactor/pom.xml @@ -10,10 +10,9 @@ http://maven.apache.org - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../parent-boot-2 + com.baeldung.spring.reactive + spring-reactive-modules + 1.0.0-SNAPSHOT diff --git a/spring-reactive-modules/spring-webflux-amqp/pom.xml b/spring-reactive-modules/spring-webflux-amqp/pom.xml index 3ceb33dc3b..8ab8277d08 100755 --- a/spring-reactive-modules/spring-webflux-amqp/pom.xml +++ b/spring-reactive-modules/spring-webflux-amqp/pom.xml @@ -11,10 +11,9 @@ Spring WebFlux AMQP Sample - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../parent-boot-2 + com.baeldung.spring.reactive + spring-reactive-modules + 1.0.0-SNAPSHOT diff --git a/spring-remoting-modules/pom.xml b/spring-remoting-modules/pom.xml index c0f12d2f97..41d77c2969 100644 --- a/spring-remoting-modules/pom.xml +++ b/spring-remoting-modules/pom.xml @@ -37,4 +37,22 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + 11 + 11 + + \ No newline at end of file diff --git a/spring-remoting-modules/remoting-hessian-burlap/remoting-hessian-burlap-client/pom.xml b/spring-remoting-modules/remoting-hessian-burlap/remoting-hessian-burlap-client/pom.xml index 63458ef278..1939e00386 100644 --- a/spring-remoting-modules/remoting-hessian-burlap/remoting-hessian-burlap-client/pom.xml +++ b/spring-remoting-modules/remoting-hessian-burlap/remoting-hessian-burlap-client/pom.xml @@ -58,6 +58,20 @@ + + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + + + + + 4.0.38 diff --git a/spring-remoting-modules/remoting-hessian-burlap/remoting-hessian-burlap-server/pom.xml b/spring-remoting-modules/remoting-hessian-burlap/remoting-hessian-burlap-server/pom.xml index d64e8c94c1..68a70f24b6 100644 --- a/spring-remoting-modules/remoting-hessian-burlap/remoting-hessian-burlap-server/pom.xml +++ b/spring-remoting-modules/remoting-hessian-burlap/remoting-hessian-burlap-server/pom.xml @@ -29,6 +29,20 @@ + + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + + + + + 4.0.38 diff --git a/spring-security-modules/pom.xml b/spring-security-modules/pom.xml index 223f0894d5..030f1ef876 100644 --- a/spring-security-modules/pom.xml +++ b/spring-security-modules/pom.xml @@ -33,6 +33,7 @@ spring-security-web-boot-2 spring-security-web-boot-3 spring-security-web-boot-4 + spring-security-web-boot-5 spring-security-web-digest-auth spring-security-web-login spring-security-web-login-2 diff --git a/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/authresolver/AuthResolverIntegrationTest.java b/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/authresolver/AuthResolverIntegrationTest.java index c87f8c1a3a..a0bc793a11 100644 --- a/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/authresolver/AuthResolverIntegrationTest.java +++ b/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/authresolver/AuthResolverIntegrationTest.java @@ -11,13 +11,14 @@ import org.springframework.security.web.FilterChainProxy; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.util.Base64Utils; import org.springframework.web.context.WebApplicationContext; import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import java.util.Base64; + @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = AuthResolverApplication.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @@ -44,7 +45,7 @@ public class AuthResolverIntegrationTest { this.mockMvc .perform(get("/customer/welcome") .header( - "Authorization", String.format("Basic %s", Base64Utils.encodeToString("customer1:pass1".getBytes())) + "Authorization", String.format("Basic %s", Base64.getEncoder().encodeToString("customer1:pass1".getBytes())) ) ) .andExpect(status().is2xxSuccessful()); @@ -55,7 +56,7 @@ public class AuthResolverIntegrationTest { this.mockMvc .perform(get("/customer/welcome") .header( - "Authorization", "Basic " + Base64Utils.encodeToString("employee1:pass1".getBytes())) + "Authorization", "Basic " + Base64.getEncoder().encodeToString("employee1:pass1".getBytes())) ) .andExpect(status().isUnauthorized()); } @@ -65,7 +66,7 @@ public class AuthResolverIntegrationTest { this.mockMvc .perform(get("/employee/welcome") .header( - "Authorization", "Basic " + Base64Utils.encodeToString("employee1:pass1".getBytes())) + "Authorization", "Basic " + Base64.getEncoder().encodeToString("employee1:pass1".getBytes())) ) .andExpect(status().is2xxSuccessful()); } @@ -75,7 +76,7 @@ public class AuthResolverIntegrationTest { this.mockMvc .perform(get("/employee/welcome") .header( - "Authorization", "Basic " + Base64Utils.encodeToString("customer1:pass1".getBytes())) + "Authorization", "Basic " + Base64.getEncoder().encodeToString("customer1:pass1".getBytes())) ) .andExpect(status().isUnauthorized()); } diff --git a/spring-security-modules/spring-security-saml/README.md b/spring-security-modules/spring-security-saml/README.md index 271b29632e..b6a11ed91b 100644 --- a/spring-security-modules/spring-security-saml/README.md +++ b/spring-security-modules/spring-security-saml/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [A Guide to SAML with Spring Security](https://www.baeldung.com/spring-security-saml) +- [SAML with Spring Boot and Spring Security](https://www.baeldung.com/spring-security-saml) diff --git a/spring-security-modules/spring-security-web-boot-2/README.md b/spring-security-modules/spring-security-web-boot-2/README.md index f5fc3a890d..c768ba924b 100644 --- a/spring-security-modules/spring-security-web-boot-2/README.md +++ b/spring-security-modules/spring-security-web-boot-2/README.md @@ -14,4 +14,5 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com - [Spring Security: Exploring JDBC Authentication](https://www.baeldung.com/spring-security-jdbc-authentication) - [Spring Security Custom Logout Handler](https://www.baeldung.com/spring-security-custom-logout-handler) - [Redirecting Logged-in Users with Spring Security](https://www.baeldung.com/spring-security-redirect-logged-in) -- More articles: [[<-- prev]](/spring-security-modules/spring-security-web-boot-1) + +More articles: [[<-- prev]](/spring-security-modules/spring-security-web-boot-1) [[next -->]](/spring-security-modules/spring-security-web-boot-3) diff --git a/spring-security-modules/spring-security-web-boot-3/README.md b/spring-security-modules/spring-security-web-boot-3/README.md index 400039dbfe..830abd2c99 100644 --- a/spring-security-modules/spring-security-web-boot-3/README.md +++ b/spring-security-modules/spring-security-web-boot-3/README.md @@ -14,4 +14,5 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com - [Content Security Policy with Spring Security](https://www.baeldung.com/spring-security-csp) - [Enable Logging for Spring Security](https://www.baeldung.com/spring-security-enable-logging) - [Authentication With Spring Security and MongoDB](https://www.baeldung.com/spring-security-authentication-mongodb) -- More articles: [[<-- prev]](/spring-security-modules/spring-security-web-boot-2) + +More articles: [[<-- prev]](/spring-security-modules/spring-security-web-boot-2) [[next -->]](/spring-security-modules/spring-security-web-boot-4) diff --git a/spring-security-modules/spring-security-web-boot-4/README.md b/spring-security-modules/spring-security-web-boot-4/README.md index 26b19e7b33..af8ed4e76a 100644 --- a/spring-security-modules/spring-security-web-boot-4/README.md +++ b/spring-security-modules/spring-security-web-boot-4/README.md @@ -8,5 +8,6 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com ### Relevant Articles: - [Spring Security: Upgrading the Deprecated WebSecurityConfigurerAdapter](https://www.baeldung.com/spring-deprecated-websecurityconfigureradapter) -- More articles: [[<-- prev]](/spring-security-modules/spring-security-web-boot-3) - [Spring @EnableMethodSecurity Annotation](https://www.baeldung.com/spring-enablemethodsecurity) + +More articles: [[<-- prev]](/spring-security-modules/spring-security-web-boot-3) diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/ApiKeySecretAuthApplication.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/ApiKeySecretAuthApplication.java new file mode 100644 index 0000000000..6dea68f07b --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/ApiKeySecretAuthApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.apikeyauthentication; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; + +@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, UserDetailsServiceAutoConfiguration.class}) +public class ApiKeySecretAuthApplication { + + public static void main(String[] args) { + SpringApplication.run(ApiKeySecretAuthApplication.class, args); + } +} diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/ApiKeyAuthentication.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/ApiKeyAuthentication.java new file mode 100644 index 0000000000..6f2a78bd4a --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/ApiKeyAuthentication.java @@ -0,0 +1,25 @@ +package com.baeldung.apikeyauthentication.configuration; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import java.util.Collection; + +public class ApiKeyAuthentication extends AbstractAuthenticationToken { + private final String apiKey; + + public ApiKeyAuthentication(String apiKey, Collection authorities) { + super(authorities); + this.apiKey = apiKey; + setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return null; + } + + @Override + public Object getPrincipal() { + return apiKey; + } +} diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationFilter.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationFilter.java new file mode 100644 index 0000000000..6c82f9c9ef --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationFilter.java @@ -0,0 +1,22 @@ +package com.baeldung.apikeyauthentication.configuration; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.GenericFilterBean; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +public class AuthenticationFilter extends GenericFilterBean { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) + throws IOException, ServletException { + Authentication authentication = AuthenticationService.getAuthentication((HttpServletRequest) request); + SecurityContextHolder.getContext().setAuthentication(authentication); + filterChain.doFilter(request, response); + } +} diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationService.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationService.java new file mode 100644 index 0000000000..14183f9f62 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/AuthenticationService.java @@ -0,0 +1,20 @@ +package com.baeldung.apikeyauthentication.configuration; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.AuthorityUtils; +import javax.servlet.http.HttpServletRequest; + +public class AuthenticationService { + + private static final String AUTH_TOKEN_HEADER_NAME = "X-API-KEY"; + private static final String AUTH_TOKEN = "Baeldung"; + + public static Authentication getAuthentication(HttpServletRequest request) { + String apiKey = request.getHeader(AUTH_TOKEN_HEADER_NAME); + if (apiKey != null && apiKey.equals(AUTH_TOKEN)) { + return new ApiKeyAuthentication(apiKey, AuthorityUtils.NO_AUTHORITIES); + } + + return null; + } +} diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/SecurityConfig.java new file mode 100644 index 0000000000..0ce58d1bf8 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/configuration/SecurityConfig.java @@ -0,0 +1,34 @@ +package com.baeldung.apikeyauthentication.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.csrf() + .disable() + .authorizeRequests() + .antMatchers("/**") + .authenticated() + .and() + .httpBasic() + .and() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .addFilterBefore(new AuthenticationFilter(), + UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } + +} diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/controller/ResourceController.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/controller/ResourceController.java new file mode 100644 index 0000000000..56164a14a0 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/apikeyauthentication/controller/ResourceController.java @@ -0,0 +1,12 @@ +package com.baeldung.apikeyauthentication.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ResourceController { + @GetMapping("/home") + public String homeEndpoint() { + return "Baeldung !"; + } +} diff --git a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/securityfilterchain/configuration/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/securityfilterchain/configuration/SecurityConfig.java index 4d3bec2ad2..5a8f4c1c02 100644 --- a/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/securityfilterchain/configuration/SecurityConfig.java +++ b/spring-security-modules/spring-security-web-boot-4/src/main/java/com/baeldung/securityfilterchain/configuration/SecurityConfig.java @@ -29,7 +29,7 @@ public class SecurityConfig { .antMatchers("/user/**") .hasAnyRole("USER", "ADMIN") .antMatchers("/login/**") - .anonymous() + .permitAll() .anyRequest() .authenticated() .and() diff --git a/spring-core-5/pom.xml b/spring-security-modules/spring-security-web-boot-5/pom.xml similarity index 50% rename from spring-core-5/pom.xml rename to spring-security-modules/spring-security-web-boot-5/pom.xml index 1c2e80be44..f4e2e3ad92 100644 --- a/spring-core-5/pom.xml +++ b/spring-security-modules/spring-security-web-boot-5/pom.xml @@ -3,43 +3,49 @@ 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-core-5 - spring-core-5 + spring-security-web-boot-5 + 0.0.1-SNAPSHOT + spring-security-web-boot-5 + jar + Spring Security Custom Auth Application com.baeldung - parent-spring-5 + parent-boot-2 0.0.1-SNAPSHOT - ../parent-spring-5 + ../../parent-boot-2 org.springframework.boot - spring-boot-starter - ${spring-boot-starter.version} + spring-boot-starter-web org.springframework.boot - spring-boot-starter-web - ${spring-boot-starter.version} + spring-boot-starter-security org.springframework.boot spring-boot-starter-test - ${spring-boot-starter.version} test - - org.projectlombok - lombok - ${lombok.version} - - - 5.3.3 - 2.4.2 - + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/SpringSecurityApplication.java b/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/SpringSecurityApplication.java new file mode 100644 index 0000000000..500b8fbef8 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/SpringSecurityApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.customauth; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringSecurityApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringSecurityApplication.class, args); + } +} diff --git a/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/authprovider/RequestHeaderAuthenticationProvider.java b/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/authprovider/RequestHeaderAuthenticationProvider.java new file mode 100644 index 0000000000..e9741f7a7a --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/authprovider/RequestHeaderAuthenticationProvider.java @@ -0,0 +1,36 @@ +package com.baeldung.customauth.authprovider; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; + +@Service +public class RequestHeaderAuthenticationProvider implements AuthenticationProvider { + + @Value("${api.auth.secret}") + private String apiAuthSecret; + + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + String authSecretKey = String.valueOf(authentication.getPrincipal()); + + if(StringUtils.isBlank(authSecretKey) || !authSecretKey.equals(apiAuthSecret)) { + throw new BadCredentialsException("Bad Request Header Credentials"); + } + + return new PreAuthenticatedAuthenticationToken(authentication.getPrincipal(), null, new ArrayList<>()); + } + + @Override + public boolean supports(Class authentication) { + return authentication.equals(PreAuthenticatedAuthenticationToken.class); + } +} diff --git a/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/configuration/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/configuration/SecurityConfig.java new file mode 100644 index 0000000000..53ab890792 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/configuration/SecurityConfig.java @@ -0,0 +1,68 @@ +package com.baeldung.customauth.configuration; + +import com.baeldung.customauth.authprovider.RequestHeaderAuthenticationProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter; +import org.springframework.security.web.header.HeaderWriterFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import javax.servlet.http.HttpServletResponse; +import java.util.Collections; + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + private final RequestHeaderAuthenticationProvider requestHeaderAuthenticationProvider; + + @Value("${api.auth.header.name}") + private String apiAuthHeaderName; + + @Autowired + public SecurityConfig( RequestHeaderAuthenticationProvider requestHeaderAuthenticationProvider){ + this.requestHeaderAuthenticationProvider = requestHeaderAuthenticationProvider; + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.cors().and().csrf() + .disable() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .addFilterAfter(requestHeaderAuthenticationFilter(), HeaderWriterFilter.class) + .authorizeHttpRequests() + .antMatchers(HttpMethod.GET,"/health").permitAll() + .antMatchers("/api/**").authenticated().and() + .exceptionHandling().authenticationEntryPoint((request, response, authException) -> + response.sendError(HttpServletResponse.SC_UNAUTHORIZED)); + + return http.build(); + } + + @Bean + public RequestHeaderAuthenticationFilter requestHeaderAuthenticationFilter() { + RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter(); + filter.setPrincipalRequestHeader(apiAuthHeaderName); + filter.setExceptionIfHeaderMissing(false); + filter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/api/**")); + filter.setAuthenticationManager(authenticationManager()); + + return filter; + } + + @Bean + protected AuthenticationManager authenticationManager() { + return new ProviderManager(Collections.singletonList(requestHeaderAuthenticationProvider)); + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/controller/ApiController.java b/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/controller/ApiController.java new file mode 100644 index 0000000000..89a66b6a0e --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/controller/ApiController.java @@ -0,0 +1,13 @@ +package com.baeldung.customauth.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ApiController { + + @GetMapping(path = "/api/hello") + public String hello(){ + return "hello"; + } +} diff --git a/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/controller/HealthCheckController.java b/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/controller/HealthCheckController.java new file mode 100644 index 0000000000..38d96b9b3d --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-5/src/main/java/com/baeldung/customauth/controller/HealthCheckController.java @@ -0,0 +1,13 @@ +package com.baeldung.customauth.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HealthCheckController { + + @GetMapping(path = "/health") + public String getHealthStatus(){ + return "OK"; + } +} diff --git a/spring-security-modules/spring-security-web-boot-5/src/main/resources/application.properties b/spring-security-modules/spring-security-web-boot-5/src/main/resources/application.properties new file mode 100644 index 0000000000..3a431720c2 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-5/src/main/resources/application.properties @@ -0,0 +1,5 @@ +spring.application.name=spring-security-app +server.servlet.context-path=/app +server.port=8085 +api.auth.header.name=x-auth-secret-key +logging.level.org.springframework.security=DEBUG \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-boot-5/src/test/java/com/baeldung/customauth/SpringContextTest.java b/spring-security-modules/spring-security-web-boot-5/src/test/java/com/baeldung/customauth/SpringContextTest.java new file mode 100644 index 0000000000..a63d9d2bce --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-5/src/test/java/com/baeldung/customauth/SpringContextTest.java @@ -0,0 +1,16 @@ +package com.baeldung.customauth; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + + +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = SpringSecurityApplication.class) +class SpringContextTest { + + @Test + void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-modules/spring-security-web-boot-5/src/test/java/com/baeldung/customauth/controller/ApiControllerIntegrationTest.java b/spring-security-modules/spring-security-web-boot-5/src/test/java/com/baeldung/customauth/controller/ApiControllerIntegrationTest.java new file mode 100644 index 0000000000..f04dcc30d4 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-5/src/test/java/com/baeldung/customauth/controller/ApiControllerIntegrationTest.java @@ -0,0 +1,68 @@ +package com.baeldung.customauth.controller; + +import com.baeldung.customauth.SpringSecurityApplication; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.*; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.net.URI; + +import static org.junit.jupiter.api.Assertions.assertEquals; + + +@SpringBootTest(classes = SpringSecurityApplication.class, + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@ExtendWith(SpringExtension.class) +class ApiControllerIntegrationTest { + + private final TestRestTemplate restTemplate = new TestRestTemplate(); + + private static final String API_ENDPOINT = "http://localhost:8080/app/api/hello"; + + @Test + void givenAuthHeaderSecretIsValid_whenApiControllerCalled_thenReturnOk() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.add("x-auth-secret-key", "test-secret"); + + ResponseEntity response = restTemplate.exchange(new URI(API_ENDPOINT), HttpMethod.GET, + new HttpEntity<>(headers), String.class); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals("hello", response.getBody()); + } + + @Test + void givenAAuthHeaderIsInvalid_whenApiControllerCalled_thenReturnUnAuthorised() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.add("x-auth-secret-key", "invalid"); + + ResponseEntity response = restTemplate.exchange(new URI(API_ENDPOINT), HttpMethod.GET, + new HttpEntity<>(headers), String.class); + + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + } + + @Test + void givenAuthHeaderNameIsInValid_whenApiControllerCalled_thenReturnUnAuthorised() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.add("x-auth-secret", "test-secret"); + + ResponseEntity response = restTemplate.exchange(new URI(API_ENDPOINT), HttpMethod.GET, + new HttpEntity<>(headers), String.class); + + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + } + + @Test + void givenAuthHeaderIsMissing_whenApiControllerCalled_thenReturnUnAuthorised() throws Exception { + HttpHeaders headers = new HttpHeaders(); + + ResponseEntity response = restTemplate.exchange(new URI(API_ENDPOINT), HttpMethod.GET, + new HttpEntity<>(headers), String.class); + + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + } +} diff --git a/spring-security-modules/spring-security-web-boot-5/src/test/java/com/baeldung/customauth/controller/HealthCheckControllerIntegrationTest.java b/spring-security-modules/spring-security-web-boot-5/src/test/java/com/baeldung/customauth/controller/HealthCheckControllerIntegrationTest.java new file mode 100644 index 0000000000..ea6fdcf292 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-5/src/test/java/com/baeldung/customauth/controller/HealthCheckControllerIntegrationTest.java @@ -0,0 +1,34 @@ +package com.baeldung.customauth.controller; + +import com.baeldung.customauth.SpringSecurityApplication; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.*; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.net.URI; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest(classes = SpringSecurityApplication.class, + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@ExtendWith(SpringExtension.class) +class HealthCheckControllerIntegrationTest { + + private final TestRestTemplate restTemplate = new TestRestTemplate(); + + private static final String HEALTH_CHECK_ENDPOINT = "http://localhost:8080/app/health"; + + @Test + void givenApplicationIsRunning_whenHealthCheckControllerCalled_thenReturnOk() throws Exception { + HttpHeaders headers = new HttpHeaders(); + + ResponseEntity response = restTemplate.exchange(new URI(HEALTH_CHECK_ENDPOINT), HttpMethod.GET, + new HttpEntity<>(headers), String.class); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals("OK", response.getBody()); + } +} diff --git a/spring-security-modules/spring-security-web-boot-5/src/test/resources/application.properties b/spring-security-modules/spring-security-web-boot-5/src/test/resources/application.properties new file mode 100644 index 0000000000..27e9cad28a --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-5/src/test/resources/application.properties @@ -0,0 +1,5 @@ +spring.application.name=spring-security-app +server.servlet.context-path=/app +server.port=8080 +api.auth.header.name=x-auth-secret-key +api.auth.secret=test-secret diff --git a/spring-shell/pom.xml b/spring-shell/pom.xml index 4e64436486..506884b413 100644 --- a/spring-shell/pom.xml +++ b/spring-shell/pom.xml @@ -19,12 +19,27 @@ org.springframework.shell spring-shell - ${org.springframework.shell.version} + ${spring-shell.version} + + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + + src/main/webapp + false + + + + + - 1.2.0.RELEASE + 1.2.0.RELEASE + 3.3.2 \ No newline at end of file diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml index 9add9ae494..9cd6f71892 100644 --- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml @@ -10,10 +10,10 @@ Demo project for Swagger Custom Validations Codegen - org.springframework.boot - spring-boot-starter-parent - 2.5.4 - + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 diff --git a/spring-swagger-codegen/spring-openapi-generator-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java b/spring-swagger-codegen/spring-openapi-generator-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java index 4c1dad6e7c..fea7b0532b 100644 --- a/spring-swagger-codegen/spring-openapi-generator-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java +++ b/spring-swagger-codegen/spring-openapi-generator-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java @@ -1,9 +1,9 @@ package com.baeldung.petstore.client.invoker.auth; import java.nio.charset.StandardCharsets; +import java.util.Base64; import org.springframework.http.HttpHeaders; -import org.springframework.util.Base64Utils; import org.springframework.util.MultiValueMap; @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2020-03-15T06:14:01.568992-05:00[America/Chicago]") @@ -33,6 +33,7 @@ public class HttpBasicAuth implements Authentication { return; } String str = (username == null ? "" : username) + ":" + (password == null ? "" : password); - headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString(str.getBytes(StandardCharsets.UTF_8))); + headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder() + .encodeToString(str.getBytes(StandardCharsets.UTF_8))); } } diff --git a/spring-swagger-codegen/spring-swagger-codegen-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java b/spring-swagger-codegen/spring-swagger-codegen-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java index 16c88a4bc6..23c1dbc4c2 100644 --- a/spring-swagger-codegen/spring-swagger-codegen-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java +++ b/spring-swagger-codegen/spring-swagger-codegen-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java @@ -1,10 +1,9 @@ package com.baeldung.petstore.client.invoker.auth; -import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; +import java.util.Base64; import org.springframework.http.HttpHeaders; -import org.springframework.util.Base64Utils; import org.springframework.util.MultiValueMap; @javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaClientCodegen", date = "2017-08-29T12:04:37.072+02:00") @@ -34,6 +33,7 @@ public class HttpBasicAuth implements Authentication { return; } String str = (username == null ? "" : username) + ":" + (password == null ? "" : password); - headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString(str.getBytes(StandardCharsets.UTF_8))); + headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder() + .encodeToString(str.getBytes(StandardCharsets.UTF_8))); } } diff --git a/spring-vault/pom.xml b/spring-vault/pom.xml index faf4b33e08..7b89db2302 100644 --- a/spring-vault/pom.xml +++ b/spring-vault/pom.xml @@ -54,7 +54,8 @@ - 2.3.2 + 3.0.2 + 17 \ No newline at end of file diff --git a/spring-vault/src/main/java/com/baeldung/springvault/VaultEnvironmentConfig.java b/spring-vault/src/main/java/com/baeldung/springvault/VaultEnvironmentConfig.java index 4f5777e94c..91c1062131 100644 --- a/spring-vault/src/main/java/com/baeldung/springvault/VaultEnvironmentConfig.java +++ b/spring-vault/src/main/java/com/baeldung/springvault/VaultEnvironmentConfig.java @@ -3,10 +3,6 @@ package com.baeldung.springvault; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.authentication.TokenAuthentication; -import org.springframework.vault.client.VaultEndpoint; -import org.springframework.vault.config.AbstractVaultConfiguration; import org.springframework.vault.config.EnvironmentVaultConfiguration; /** diff --git a/spring-vault/src/test/java/com/baeldung/springvault/SpringContextLiveTest.java b/spring-vault/src/test/java/com/baeldung/springvault/SpringContextLiveTest.java index 6e2a61ca40..4b7a4e2c1c 100644 --- a/spring-vault/src/test/java/com/baeldung/springvault/SpringContextLiveTest.java +++ b/spring-vault/src/test/java/com/baeldung/springvault/SpringContextLiveTest.java @@ -1,6 +1,5 @@ package com.baeldung.springvault; -import com.baeldung.springvault.SpringVaultApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/encoding/service/HttpBinServiceUnitTest.java b/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/encoding/service/HttpBinServiceLiveTest.java similarity index 96% rename from spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/encoding/service/HttpBinServiceUnitTest.java rename to spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/encoding/service/HttpBinServiceLiveTest.java index c45f1991e5..47c7815a4a 100644 --- a/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/encoding/service/HttpBinServiceUnitTest.java +++ b/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/encoding/service/HttpBinServiceLiveTest.java @@ -8,7 +8,7 @@ import org.springframework.boot.test.context.SpringBootTest; import static org.junit.jupiter.api.Assertions.*; @SpringBootTest -class HttpBinServiceUnitTest { +class HttpBinServiceLiveTest { @Autowired private HttpBinService httpBinService; diff --git a/spring-web-modules/spring-thymeleaf-5/README.md b/spring-web-modules/spring-thymeleaf-5/README.md index c06b47d240..7e2f8c37b4 100644 --- a/spring-web-modules/spring-thymeleaf-5/README.md +++ b/spring-web-modules/spring-thymeleaf-5/README.md @@ -10,4 +10,5 @@ This module contains articles about Spring with Thymeleaf - [Upload Image With Spring Boot and Thymeleaf](https://www.baeldung.com/spring-boot-thymeleaf-image-upload) - [Getting a URL Attribute Value in Thymeleaf](https://www.baeldung.com/thymeleaf-url-attribute-value) - [Expression Types in Thymeleaf](https://www.baeldung.com/java-thymeleaf-expression-types) +- [Difference Between th:text and th:value in Thymeleaf](https://www.baeldung.com/java-thymeleaf-text-vs-value) - [[<-- prev]](/spring-thymeleaf) diff --git a/spring-web-modules/spring-thymeleaf-5/src/main/java/com/baeldung/thymeleaf/attributes/AttributeController.java b/spring-web-modules/spring-thymeleaf-5/src/main/java/com/baeldung/thymeleaf/attributes/AttributeController.java new file mode 100644 index 0000000000..b7725fd992 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-5/src/main/java/com/baeldung/thymeleaf/attributes/AttributeController.java @@ -0,0 +1,30 @@ +package com.baeldung.thymeleaf.attributes; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/attributes") +public class AttributeController { + + private static final Logger logger = LoggerFactory.getLogger(AttributeController.class); + + @GetMapping + public String show(Model model) { + model.addAttribute("title", "Baeldung"); + model.addAttribute("email", "default@example.com"); + return "attributes/index"; + } + + @PostMapping + public String submit(String email) { + logger.info("Email: {}", email); + return "redirect:attributes"; + } + +} diff --git a/spring-web-modules/spring-thymeleaf-5/src/main/resources/templates/attributes/index.html b/spring-web-modules/spring-thymeleaf-5/src/main/resources/templates/attributes/index.html new file mode 100644 index 0000000000..ed55b61a8a --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-5/src/main/resources/templates/attributes/index.html @@ -0,0 +1,19 @@ + + + + + Difference Between th:text and th:value in Thymeleaf + + + +

+ +
+ + +
+ + + \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/.mvn/jvm.config b/spring-web-modules/spring-thymeleaf-attributes/.mvn/jvm.config new file mode 100644 index 0000000000..ef7bd4c43e --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/.mvn/jvm.config @@ -0,0 +1,4 @@ +--add-opens=java.base/java.util=ALL-UNNAMED +--add-opens=java.base/java.lang.reflect=ALL-UNNAMED +--add-opens=java.base/java.text=ALL-UNNAMED +--add-opens=java.desktop/java.awt.font=ALL-UNNAMED \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml new file mode 100644 index 0000000000..8d1b43f2c6 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml @@ -0,0 +1,95 @@ + + + + 4.0.0 + + com.baeldung.spring-thymeleaf-attributes.module + accessing-session-attributes + 0.0.1-SNAPSHOT + war + + + com.baeldung.spring-thymeleaf-attributes + spring-thymeleaf-attributes-modules + 0.0.1-SNAPSHOT + ../pom.xml + + + + + jakarta.servlet + jakarta.servlet-api + provided + + + org.springframework.boot + spring-boot-starter-web + + + org.thymeleaf + thymeleaf-spring6 + ${thymeleaf.spring6.version} + + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.engine.version} + test + + + org.mockito + mockito-core + ${mockito.version} + test + + + org.mockito + mockito-junit-jupiter + ${mockito.version} + test + + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.engine.version} + test + + + + + + + + src/main/resources + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + -Dfile.encoding="UTF-8" -Xdebug + -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 + + + + + + + + com.baeldung.accesing_session_attributes.SpringWebApplicationInitializer + UTF-8 + UTF-8 + UTF-8 + true + true + 5.9.3 + 5.3.1 + 3.1.1.RELEASE + + \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/SpringWebApplicationInitializer.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/SpringWebApplicationInitializer.java new file mode 100644 index 0000000000..fc40992020 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/SpringWebApplicationInitializer.java @@ -0,0 +1,22 @@ +package com.baeldung.accesing_session_attributes; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringWebApplicationInitializer { + + private Logger log = LoggerFactory.getLogger(getClass()); + + public SpringWebApplicationInitializer() { + super(); + String encoding = System.getProperty("file.encoding"); + log.info(encoding); + } + + public static void main(String[] args) { + SpringApplication.run(SpringWebApplicationInitializer.class, args); + } +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/AgeAnalysisService.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/AgeAnalysisService.java new file mode 100644 index 0000000000..3e9acf648f --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/AgeAnalysisService.java @@ -0,0 +1,11 @@ +package com.baeldung.accesing_session_attributes.business; + +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import com.baeldung.accesing_session_attributes.business.entities.NameAgeEntity; + +@Service +public interface AgeAnalysisService { + ResponseEntity getAgeAnalysisForName(String nameToAnalyze); +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/CountryAnalysisService.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/CountryAnalysisService.java new file mode 100644 index 0000000000..8b81f3fa8b --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/CountryAnalysisService.java @@ -0,0 +1,11 @@ +package com.baeldung.accesing_session_attributes.business; + +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import com.baeldung.accesing_session_attributes.business.entities.NameCountriesEntity; + +@Service +public interface CountryAnalysisService { + ResponseEntity getCountryAnalysisForName(String nameToAnalyze); +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/GenderAnalysisService.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/GenderAnalysisService.java new file mode 100644 index 0000000000..56cf8a6298 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/GenderAnalysisService.java @@ -0,0 +1,11 @@ +package com.baeldung.accesing_session_attributes.business; + +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import com.baeldung.accesing_session_attributes.business.entities.NameGenderEntity; + +@Service +public interface GenderAnalysisService { + ResponseEntity getGenderAnalysisForName(String nameToAnalyze); +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/NameAnalysisService.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/NameAnalysisService.java new file mode 100644 index 0000000000..78530c75b3 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/NameAnalysisService.java @@ -0,0 +1,15 @@ +package com.baeldung.accesing_session_attributes.business; + +import java.util.concurrent.CompletableFuture; + +import org.springframework.stereotype.Service; + +import com.baeldung.accesing_session_attributes.business.beans.NameRequest; +import com.baeldung.accesing_session_attributes.business.entities.NameAnalysisEntity; + +@Service +public interface NameAnalysisService { + public NameRequest getLastNameRequest(); + + public CompletableFuture searchForName(NameRequest nameRequest); +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/beans/NameRequest.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/beans/NameRequest.java new file mode 100644 index 0000000000..e58180b15e --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/beans/NameRequest.java @@ -0,0 +1,47 @@ +package com.baeldung.accesing_session_attributes.business.beans; + +public class NameRequest { + private String name; + + public NameRequest() { + super(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + NameRequest other = (NameRequest) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + return "NameRequestEntity [name=" + name + "]"; + } +} \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameAgeEntity.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameAgeEntity.java new file mode 100644 index 0000000000..9045df1146 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameAgeEntity.java @@ -0,0 +1,81 @@ +package com.baeldung.accesing_session_attributes.business.entities; + +/** + * https://api.agify.io/?name=michael + */ +public class NameAgeEntity { + private Integer age; + private Long count; + private String name; + + public NameAgeEntity() { + super(); + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Long getCount() { + return count; + } + + public void setCount(Long count) { + this.count = count; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((age == null) ? 0 : age.hashCode()); + result = prime * result + ((count == null) ? 0 : count.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + NameAgeEntity other = (NameAgeEntity) obj; + if (age == null) { + if (other.age != null) + return false; + } else if (!age.equals(other.age)) + return false; + if (count == null) { + if (other.count != null) + return false; + } else if (!count.equals(other.count)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + return "NameAgeEntity [age=" + age + ", count=" + count + ", name=" + name + "]"; + } + +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameAnalysisEntity.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameAnalysisEntity.java new file mode 100644 index 0000000000..0a19bfb6e5 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameAnalysisEntity.java @@ -0,0 +1,92 @@ +package com.baeldung.accesing_session_attributes.business.entities; + +public class NameAnalysisEntity { + private String name; + private NameAgeEntity age; + private NameCountriesEntity countries; + private NameGenderEntity gender; + + public NameAnalysisEntity() { + super(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public NameAgeEntity getAge() { + return age; + } + + public void setAge(NameAgeEntity age) { + this.age = age; + } + + public NameCountriesEntity getCountries() { + return countries; + } + + public void setCountries(NameCountriesEntity countries) { + this.countries = countries; + } + + public NameGenderEntity getGender() { + return gender; + } + + public void setGender(NameGenderEntity gender) { + this.gender = gender; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((age == null) ? 0 : age.hashCode()); + result = prime * result + ((countries == null) ? 0 : countries.hashCode()); + result = prime * result + ((gender == null) ? 0 : gender.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + NameAnalysisEntity other = (NameAnalysisEntity) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (age == null) { + if (other.age != null) + return false; + } else if (!age.equals(other.age)) + return false; + if (countries == null) { + if (other.countries != null) + return false; + } else if (!countries.equals(other.countries)) + return false; + if (gender == null) { + if (other.gender != null) + return false; + } else if (!gender.equals(other.gender)) + return false; + return true; + } + + @Override + public String toString() { + return "NameAnalysisEntity [name=" + name + ", age=" + age + ", countries=" + countries + ", gender=" + gender + "]"; + } +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameCountriesEntity.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameCountriesEntity.java new file mode 100644 index 0000000000..a6ca537cf9 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameCountriesEntity.java @@ -0,0 +1,68 @@ +package com.baeldung.accesing_session_attributes.business.entities; + +import java.util.List; + +/** + * https://api.nationalize.io/?name=michael + */ +public class NameCountriesEntity { + private String name; + private List country; + + public NameCountriesEntity() { + super(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getCountry() { + return country; + } + + public void setCountry(List country) { + this.country = country; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((country == null) ? 0 : country.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + NameCountriesEntity other = (NameCountriesEntity) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (country == null) { + if (other.country != null) + return false; + } else if (!country.equals(other.country)) + return false; + return true; + } + + @Override + public String toString() { + return "NameCountriesModel [name=" + name + ", country=" + country + "]"; + } + +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameCountryEntity.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameCountryEntity.java new file mode 100644 index 0000000000..9e566cc2a5 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameCountryEntity.java @@ -0,0 +1,72 @@ +package com.baeldung.accesing_session_attributes.business.entities; + +/** + * NameCountryModel + * + * https://www.countryflagicons.com/ + * + * STYLE: FLAT, SHINY + * size: 16, 24, 32, 48, 64 + * COUNTRYCODE: country_id + */ +public class NameCountryEntity { + private String country_id; + private Float probability; + + public NameCountryEntity() { + super(); + } + + public String getCountry_id() { + return country_id; + } + + public void setCountry_id(String country_id) { + this.country_id = country_id; + } + + public Float getProbability() { + return probability; + } + + public void setProbability(Float probability) { + this.probability = probability; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((country_id == null) ? 0 : country_id.hashCode()); + result = prime * result + ((probability == null) ? 0 : probability.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + NameCountryEntity other = (NameCountryEntity) obj; + if (country_id == null) { + if (other.country_id != null) + return false; + } else if (!country_id.equals(other.country_id)) + return false; + if (probability == null) { + if (other.probability != null) + return false; + } else if (!probability.equals(other.probability)) + return false; + return true; + } + + @Override + public String toString() { + return "NameCountryModel [country_id=" + country_id + ", probability=" + probability + "]"; + } + +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameGenderEntity.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameGenderEntity.java new file mode 100644 index 0000000000..357f36584a --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/NameGenderEntity.java @@ -0,0 +1,97 @@ +package com.baeldung.accesing_session_attributes.business.entities; + +/** + * NameGenderModel + * https://api.genderize.io/?name=victor + */ +public class NameGenderEntity { + private Long count; + private String gender; + private String name; + private Float probability; + + public NameGenderEntity() { + super(); + } + + public Long getCount() { + return count; + } + + public void setCount(Long count) { + this.count = count; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Float getProbability() { + return probability; + } + + public void setProbability(Float probability) { + this.probability = probability; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((count == null) ? 0 : count.hashCode()); + result = prime * result + ((gender == null) ? 0 : gender.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((probability == null) ? 0 : probability.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + NameGenderEntity other = (NameGenderEntity) obj; + if (count == null) { + if (other.count != null) + return false; + } else if (!count.equals(other.count)) + return false; + if (gender == null) { + if (other.gender != null) + return false; + } else if (!gender.equals(other.gender)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (probability == null) { + if (other.probability != null) + return false; + } else if (!probability.equals(other.probability)) + return false; + return true; + } + + @Override + public String toString() { + return "NameGenderModel [count=" + count + ", gender=" + gender + ", name=" + name + ", probability=" + probability + "]"; + } + +} \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/factories/NameAnalysisEntityFactory.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/factories/NameAnalysisEntityFactory.java new file mode 100644 index 0000000000..acbdb579d6 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/entities/factories/NameAnalysisEntityFactory.java @@ -0,0 +1,22 @@ +package com.baeldung.accesing_session_attributes.business.entities.factories; + +import org.springframework.stereotype.Service; + +import com.baeldung.accesing_session_attributes.business.entities.NameAgeEntity; +import com.baeldung.accesing_session_attributes.business.entities.NameAnalysisEntity; +import com.baeldung.accesing_session_attributes.business.entities.NameCountriesEntity; +import com.baeldung.accesing_session_attributes.business.entities.NameGenderEntity; + +@Service +public class NameAnalysisEntityFactory { + + public NameAnalysisEntity getInstance(String nameRequest, NameGenderEntity gender, NameAgeEntity age, NameCountriesEntity countries) { + NameAnalysisEntity nameAnalysis = new NameAnalysisEntity(); + nameAnalysis.setName(nameRequest); + nameAnalysis.setGender(gender); + nameAnalysis.setAge(age); + nameAnalysis.setCountries(countries); + return nameAnalysis; + } + +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/impl/AgeAnalysisServiceImpl.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/impl/AgeAnalysisServiceImpl.java new file mode 100644 index 0000000000..b8787dacb3 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/impl/AgeAnalysisServiceImpl.java @@ -0,0 +1,25 @@ +package com.baeldung.accesing_session_attributes.business.impl; + +import java.net.URI; +import java.text.MessageFormat; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import com.baeldung.accesing_session_attributes.business.AgeAnalysisService; +import com.baeldung.accesing_session_attributes.business.entities.NameAgeEntity; + +@Component +public class AgeAnalysisServiceImpl implements AgeAnalysisService { + @Value("${name-analysis-controller.name-age-api-url:https://api.agify.io/?name={0}}") + private String nameAgeApiUrl; + + @Override + public ResponseEntity getAgeAnalysisForName(String nameToAnalyze) { + RestTemplate restTemplate = new RestTemplate(); + return restTemplate.getForEntity(URI.create(MessageFormat.format(nameAgeApiUrl, nameToAnalyze)), NameAgeEntity.class); + } + +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/impl/CountryAnalysisServiceImpl.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/impl/CountryAnalysisServiceImpl.java new file mode 100644 index 0000000000..ec8c641e57 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/impl/CountryAnalysisServiceImpl.java @@ -0,0 +1,25 @@ +package com.baeldung.accesing_session_attributes.business.impl; + +import java.net.URI; +import java.text.MessageFormat; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import com.baeldung.accesing_session_attributes.business.CountryAnalysisService; +import com.baeldung.accesing_session_attributes.business.entities.NameCountriesEntity; + +@Component +public class CountryAnalysisServiceImpl implements CountryAnalysisService { + @Value("${name-analysis-controller.name-countries-api-url:https://api.nationalize.io/?name={0}}") + private String nameCountriesApiUrl; + + @Override + public ResponseEntity getCountryAnalysisForName(String nameToAnalyze) { + RestTemplate restTemplate = new RestTemplate(); + return restTemplate.getForEntity(URI.create(MessageFormat.format(nameCountriesApiUrl, nameToAnalyze)), NameCountriesEntity.class); + } + +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/impl/GenderAnalysisServiceImpl.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/impl/GenderAnalysisServiceImpl.java new file mode 100644 index 0000000000..ce33886096 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/impl/GenderAnalysisServiceImpl.java @@ -0,0 +1,25 @@ +package com.baeldung.accesing_session_attributes.business.impl; + +import java.net.URI; +import java.text.MessageFormat; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import com.baeldung.accesing_session_attributes.business.GenderAnalysisService; +import com.baeldung.accesing_session_attributes.business.entities.NameGenderEntity; + +@Component +public class GenderAnalysisServiceImpl implements GenderAnalysisService { + @Value("${name-analysis-controller.name-gender-api-url:https://api.genderize.io/?name={0}}") + private String nameGenderApiUrl; + + @Override + public ResponseEntity getGenderAnalysisForName(String nameToAnalyze) { + RestTemplate restTemplate = new RestTemplate(); + return restTemplate.getForEntity(URI.create(MessageFormat.format(nameGenderApiUrl, nameToAnalyze)), NameGenderEntity.class); + } + +} \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/impl/NameAnalysisServiceImpl.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/impl/NameAnalysisServiceImpl.java new file mode 100644 index 0000000000..334ba26893 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/business/impl/NameAnalysisServiceImpl.java @@ -0,0 +1,68 @@ +package com.baeldung.accesing_session_attributes.business.impl; + +import java.net.URLEncoder; +import java.util.concurrent.CompletableFuture; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import com.baeldung.accesing_session_attributes.business.AgeAnalysisService; +import com.baeldung.accesing_session_attributes.business.CountryAnalysisService; +import com.baeldung.accesing_session_attributes.business.GenderAnalysisService; +import com.baeldung.accesing_session_attributes.business.NameAnalysisService; +import com.baeldung.accesing_session_attributes.business.beans.NameRequest; +import com.baeldung.accesing_session_attributes.business.entities.NameAgeEntity; +import com.baeldung.accesing_session_attributes.business.entities.NameAnalysisEntity; +import com.baeldung.accesing_session_attributes.business.entities.NameCountriesEntity; +import com.baeldung.accesing_session_attributes.business.entities.NameGenderEntity; +import com.baeldung.accesing_session_attributes.business.entities.factories.NameAnalysisEntityFactory; + +@Component +public class NameAnalysisServiceImpl implements NameAnalysisService { + + private NameRequest lastNameRequest; + private AgeAnalysisService ageAnalysisService; + private CountryAnalysisService countryAnalysisService; + private GenderAnalysisService genderAnalysisService; + private NameAnalysisEntityFactory nameAnalysisEntityFactory; + + @Autowired + public NameAnalysisServiceImpl(AgeAnalysisService ageAnalysisService, CountryAnalysisService countryAnalysisService, GenderAnalysisService genderAnalysisService, NameAnalysisEntityFactory nameAnalysisEntityFactory) { + super(); + this.ageAnalysisService = ageAnalysisService; + this.countryAnalysisService = countryAnalysisService; + this.genderAnalysisService = genderAnalysisService; + this.nameAnalysisEntityFactory = nameAnalysisEntityFactory; + + lastNameRequest = new NameRequest(); + lastNameRequest.setName("Rigoberto"); + } + + public NameRequest getLastNameRequest() { + return lastNameRequest; + } + + public CompletableFuture searchForName(NameRequest nameRequest) { + this.lastNameRequest.setName(nameRequest.getName()); + return analyzeName(); + } + + @Async + private CompletableFuture analyzeName() { + try { + String nameToAnalyze = URLEncoder.encode(lastNameRequest.getName(), "UTF-8"); + + ResponseEntity ageRequestResponse = ageAnalysisService.getAgeAnalysisForName(nameToAnalyze); + ResponseEntity countriesRequestResponse = countryAnalysisService.getCountryAnalysisForName(nameToAnalyze); + ResponseEntity genderRequestResponse = genderAnalysisService.getGenderAnalysisForName(nameToAnalyze); + + NameAnalysisEntity nameAnalysis = nameAnalysisEntityFactory.getInstance(lastNameRequest.getName(), genderRequestResponse.getBody(), ageRequestResponse.getBody(), countriesRequestResponse.getBody()); + return CompletableFuture.completedFuture(nameAnalysis); + + } catch (Exception e) { + return CompletableFuture.failedFuture(e); + } + } +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/web/SpringWebConfig.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/web/SpringWebConfig.java new file mode 100644 index 0000000000..00b49ff392 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/web/SpringWebConfig.java @@ -0,0 +1,86 @@ +package com.baeldung.accesing_session_attributes.web; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ResourceBundleMessageSource; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.thymeleaf.spring6.SpringTemplateEngine; +import org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver; +import org.thymeleaf.spring6.view.ThymeleafViewResolver; +import org.thymeleaf.templatemode.TemplateMode; +import org.thymeleaf.web.servlet.JakartaServletWebApplication; + +@Configuration +@EnableWebMvc +public class SpringWebConfig implements WebMvcConfigurer, ApplicationContextAware { + + private WebApplicationContext webApplicationContext; + + public SpringWebConfig() { + super(); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.webApplicationContext = (WebApplicationContext) applicationContext; + } + + /* + * Dispatcher configuration for serving static resources + */ + @Override + public void addResourceHandlers(final ResourceHandlerRegistry registry) { + WebMvcConfigurer.super.addResourceHandlers(registry); + registry.addResourceHandler("/images/**") + .addResourceLocations("/images/"); + registry.addResourceHandler("/css/**") + .addResourceLocations("/css/"); + registry.addResourceHandler("/js/**") + .addResourceLocations("/js/"); + } + + @Bean + public ResourceBundleMessageSource messageSource() { + ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); + messageSource.addBasenames("name-analysis"); + return messageSource; + } + + @Bean + public SpringResourceTemplateResolver templateResolver() { + SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); + templateResolver.setApplicationContext(this.webApplicationContext); + templateResolver.setPrefix("/WEB-INF/templates/"); + templateResolver.setSuffix(".html"); + + templateResolver.setTemplateMode(TemplateMode.HTML); + templateResolver.setCacheable(true); + return templateResolver; + } + + @Bean + public SpringTemplateEngine templateEngine() { + SpringTemplateEngine templateEngine = new SpringTemplateEngine(); + templateEngine.setMessageSource(webApplicationContext); + templateEngine.setTemplateResolver(templateResolver()); + return templateEngine; + } + + @Bean + public ThymeleafViewResolver viewResolver() { + ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); + viewResolver.setTemplateEngine(templateEngine()); + return viewResolver; + } + + @Bean + public JakartaServletWebApplication jakartaServletWebApplication() { + return JakartaServletWebApplication.buildApplication(webApplicationContext.getServletContext()); + } +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/web/beans/SessionNameRequest.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/web/beans/SessionNameRequest.java new file mode 100644 index 0000000000..8637fb9b99 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/web/beans/SessionNameRequest.java @@ -0,0 +1,67 @@ +package com.baeldung.accesing_session_attributes.web.beans; + +import java.util.Date; + +import com.baeldung.accesing_session_attributes.business.beans.NameRequest; + +public class SessionNameRequest { + private Date requestDate; + private NameRequest nameRequest; + + public SessionNameRequest() { + super(); + } + + public Date getRequestDate() { + return requestDate; + } + + public void setRequestDate(Date requestDate) { + this.requestDate = requestDate; + } + + public NameRequest getNameRequest() { + return nameRequest; + } + + public void setNameRequest(NameRequest nameRequest) { + this.nameRequest = nameRequest; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((requestDate == null) ? 0 : requestDate.hashCode()); + result = prime * result + ((nameRequest == null) ? 0 : nameRequest.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SessionNameRequest other = (SessionNameRequest) obj; + if (requestDate == null) { + if (other.requestDate != null) + return false; + } else if (!requestDate.equals(other.requestDate)) + return false; + if (nameRequest == null) { + if (other.nameRequest != null) + return false; + } else if (!nameRequest.equals(other.nameRequest)) + return false; + return true; + } + + @Override + public String toString() { + return "SessionNameRequest [requestDate=" + requestDate + ", nameRequest=" + nameRequest + "]"; + } + +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/web/controllers/NameAnalysisController.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/web/controllers/NameAnalysisController.java new file mode 100644 index 0000000000..65aa0686a0 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/web/controllers/NameAnalysisController.java @@ -0,0 +1,143 @@ +package com.baeldung.accesing_session_attributes.web.controllers; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.thymeleaf.web.IWebSession; +import org.thymeleaf.web.servlet.IServletWebExchange; +import org.thymeleaf.web.servlet.JakartaServletWebApplication; + +import com.baeldung.accesing_session_attributes.business.NameAnalysisService; +import com.baeldung.accesing_session_attributes.business.beans.NameRequest; +import com.baeldung.accesing_session_attributes.business.entities.NameAnalysisEntity; +import com.baeldung.accesing_session_attributes.web.beans.SessionNameRequest; +import com.baeldung.accesing_session_attributes.web.factories.SessionNameRequestFactory; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +@Controller +public class NameAnalysisController { + + private NameAnalysisService nameAnalysisService; + private HttpServletRequest request; + private SessionNameRequestFactory sessionNameRequestFactory; + private HttpServletResponse response; + private JakartaServletWebApplication jakartaServletWebApplication; + + @Autowired + public NameAnalysisController(JakartaServletWebApplication jakartaServletWebApplication, HttpServletRequest request, HttpServletResponse response, NameAnalysisService nameAnalysisService, SessionNameRequestFactory sessionNameRequestFactory) { + super(); + this.jakartaServletWebApplication = jakartaServletWebApplication; + this.request = request; + this.response = response; + this.nameAnalysisService = nameAnalysisService; + this.sessionNameRequestFactory = sessionNameRequestFactory; + } + + @ModelAttribute("nameRequest") + public NameRequest nameRequest() { + return nameAnalysisService.getLastNameRequest(); + } + + @RequestMapping({ "/", "/name-analysis" }) + public String showNameAnalysis() { + return "name-analysis"; + } + + @RequestMapping(value = "/name-analysis", params = { "search" }) + public String performNameAnalysis(final NameRequest nameRequest, final BindingResult bindingResult) { + performNameRequest(nameRequest); + return "name-analysis"; + } + + @RequestMapping(value = "/name-analysis/clear") + public String clearNameAnalysis() { + clearAnalysis(); + return "redirect:/name-analysis"; + } + + @RequestMapping(value = "/name-analysis/remove-history-request", params = { "id" }) + public String removeRequest() { + try { + final Integer rowId = Integer.valueOf(request.getParameter("id")); + removeRequest(rowId); + + } catch (Exception e) { + e.printStackTrace(); + } + return "redirect:/name-analysis"; + } + + private void removeRequest(Integer rowId) { + IWebSession session = getIWebSession(); + Object requests = session.getAttributeValue("requests"); + if (rowId != null && requests != null && (requests instanceof List)) { + ((List) requests).remove(rowId.intValue()); + } + } + + private void performNameRequest(final NameRequest nameRequest) { + try { + CompletableFuture nameAnalysis = this.nameAnalysisService.searchForName(nameRequest); + NameAnalysisEntity nameAnalysisEntity = nameAnalysis.get(30, TimeUnit.SECONDS); + sessionRegisterRequest(nameRequest); + sessionRegisterAnalysis(nameAnalysisEntity); + sessionClearAnalysisError(); + } catch (Exception e) { + e.printStackTrace(); + sessionSetAnalysisError(nameRequest); + } + } + + private void sessionClearAnalysisError() { + IWebSession session = getIWebSession(); + session.setAttributeValue("analysisError", null); + } + + private void sessionSetAnalysisError(NameRequest nameRequest) { + IWebSession session = getIWebSession(); + session.setAttributeValue("analysisError", nameRequest); + } + + private void clearAnalysis() { + IWebSession session = getIWebSession(); + session.setAttributeValue("lastAnalysis", null); + } + + private void sessionRegisterAnalysis(NameAnalysisEntity analysis) { + IWebSession session = getIWebSession(); + session.setAttributeValue("lastAnalysis", analysis); + } + + private void sessionRegisterRequest(NameRequest nameRequest) { + IWebSession session = getIWebSession(); + session.setAttributeValue("lastRequest", nameRequest); + + SessionNameRequest sessionNameRequest = sessionNameRequestFactory.getInstance(nameRequest); + List requests = getRequestsFromSession(session); + requests.add(0, sessionNameRequest); + } + + private List getRequestsFromSession(IWebSession session) { + Object requests = session.getAttributeValue("requests"); + if (requests == null || !(requests instanceof List)) { + List sessionNameRequests = new ArrayList<>(); + session.setAttributeValue("requests", sessionNameRequests); + requests = sessionNameRequests; + } + return (List) requests; + } + + private IWebSession getIWebSession() { + IServletWebExchange webExchange = this.jakartaServletWebApplication.buildExchange(request, response); + return webExchange.getSession(); + } +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/web/factories/SessionNameRequestFactory.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/web/factories/SessionNameRequestFactory.java new file mode 100644 index 0000000000..a104047106 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/java/com/baeldung/accesing_session_attributes/web/factories/SessionNameRequestFactory.java @@ -0,0 +1,25 @@ +package com.baeldung.accesing_session_attributes.web.factories; + +import java.util.Date; + +import org.springframework.stereotype.Service; + +import com.baeldung.accesing_session_attributes.business.beans.NameRequest; +import com.baeldung.accesing_session_attributes.web.beans.SessionNameRequest; + +@Service +public class SessionNameRequestFactory { + + public SessionNameRequest getInstance(NameRequest nameRequest) { + + NameRequest cloned = new NameRequest(); + cloned.setName(nameRequest.getName()); + + SessionNameRequest sessionNameRequest = new SessionNameRequest(); + sessionNameRequest.setRequestDate(new Date()); + sessionNameRequest.setNameRequest(cloned); + + return sessionNameRequest; + } + +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/resources/application.properties b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/resources/application.properties new file mode 100644 index 0000000000..841ebcadee --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/resources/application.properties @@ -0,0 +1,3 @@ +spring.http.encoding.enabled=true +spring.devtools.add-properties=false +logging.level.web=DEBUG diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/resources/name-analysis.properties b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/resources/name-analysis.properties new file mode 100644 index 0000000000..d61cb651ea --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/resources/name-analysis.properties @@ -0,0 +1,20 @@ +history.header.actions=Actions +history.header.date=Date +history.header.name=Name +history.no-data=Without data +history.request.remove-row=Remove row +history.title=Requests History +name-analysis.form.button.analyze=Analyze +name-analysis.form.name=Name +name-analysis.title=Analyze name +result.clear=Borrar +result.column.age-count=Number of persons +result.column.age=Age +result.column.city=City +result.column.gender=Gender +result.column.name=Name +result.error=Error during analysis +result.header.value=Value +result.no-request-performed=Without data +result.title=Name analyzed +web.title=Baeldung - Accessing Session Attributes in Thymeleaf \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/resources/name-analysis_en_GB.properties b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/resources/name-analysis_en_GB.properties new file mode 100644 index 0000000000..d61cb651ea --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/resources/name-analysis_en_GB.properties @@ -0,0 +1,20 @@ +history.header.actions=Actions +history.header.date=Date +history.header.name=Name +history.no-data=Without data +history.request.remove-row=Remove row +history.title=Requests History +name-analysis.form.button.analyze=Analyze +name-analysis.form.name=Name +name-analysis.title=Analyze name +result.clear=Borrar +result.column.age-count=Number of persons +result.column.age=Age +result.column.city=City +result.column.gender=Gender +result.column.name=Name +result.error=Error during analysis +result.header.value=Value +result.no-request-performed=Without data +result.title=Name analyzed +web.title=Baeldung - Accessing Session Attributes in Thymeleaf \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/resources/name-analysis_es.properties b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/resources/name-analysis_es.properties new file mode 100644 index 0000000000..823f6b4540 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/resources/name-analysis_es.properties @@ -0,0 +1,20 @@ +history.header.actions=Acciones +history.header.date=Fecha +history.header.name=Nombre +history.no-data=Sin datos +history.request.remove-row=Eliminar fila +history.title=Historial +name-analysis.form.button.analyze=Analizar +name-analysis.form.name=Nombre +name-analysis.title=Analizar nombre +result.clear=Borrar +result.column.age-count=Ocurrencias +result.column.age=Edad +result.column.city=Ciudad +result.column.gender=Género +result.column.name=Nombre +result.error=Se produjo un error +result.header.value=Valor +result.no-request-performed=Sin datos +result.title=Nombre analizado +web.title=Baeldung - Acceso a los atributos de la sesión con Thymeleaf diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/webapp/WEB-INF/templates/name-analysis.html b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/webapp/WEB-INF/templates/name-analysis.html new file mode 100644 index 0000000000..7ee1034f7d --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/webapp/WEB-INF/templates/name-analysis.html @@ -0,0 +1,125 @@ + + + + + + Baeldung - Accessing Session Attributes in Thymeleaf + + + + + + + +
+
+
+
Analizar nombre
+
+
+
+
+ + +
+
+ +
+
+
+
+
+
+ +
+
Nombre analizado
+
+

Error durante el análisis

+

Sin búsquedas

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#Valor
NombreNombre buscado
Género[Masculino|Femenino] ({%})
Edad{Edad media del nombre}
Número de personas + {Número de personas}
CiudadCountry id ({%})
+
+ Borrar +
+
+
+
+
+ +
+
+
Historial
+
+

Sin datos

+ + + + + + + + + + + + + + + +
FechaNombreAcciones
[[${request.requestDate}]][[${request.nameRequest}]] + Remove row +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/webapp/css/bootstrap.min.css b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/webapp/css/bootstrap.min.css new file mode 100644 index 0000000000..596784f3fe --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/webapp/css/bootstrap.min.css @@ -0,0 +1,6 @@ +@charset "UTF-8";/*! + * Bootstrap v5.3.0-alpha1 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text:#0a58ca;--bs-secondary-text:#6c757d;--bs-success-text:#146c43;--bs-info-text:#087990;--bs-warning-text:#997404;--bs-danger-text:#b02a37;--bs-light-text:#6c757d;--bs-dark-text:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#f8f9fa;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#e9ecef;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(var(--bs-body-color-rgb), 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(var(--bs-body-color-rgb), 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(var(--bs-body-color-rgb), 0.075);--bs-emphasis-color:#000;--bs-form-control-bg:var(--bs-body-bg);--bs-form-control-disabled-bg:var(--bs-secondary-bg);--bs-highlight-bg:#fff3cd;--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}[data-bs-theme=dark]{--bs-body-color:#adb5bd;--bs-body-color-rgb:173,181,189;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#f8f9fa;--bs-emphasis-color-rgb:248,249,250;--bs-secondary-color:rgba(173, 181, 189, 0.75);--bs-secondary-color-rgb:173,181,189;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(173, 181, 189, 0.5);--bs-tertiary-color-rgb:173,181,189;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-emphasis-color:#fff;--bs-primary-text:#6ea8fe;--bs-secondary-text:#dee2e6;--bs-success-text:#75b798;--bs-info-text:#6edff6;--bs-warning-text:#ffda6a;--bs-danger-text:#ea868f;--bs-light-text:#f8f9fa;--bs-dark-text:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#212529;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#495057;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#055160;--bs-warning-border-subtle:#664d03;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:#fff;--bs-link-color:#6ea8fe;--bs-link-hover-color:#9ec5fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:158,197,254;--bs-code-color:#e685b5;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15)}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color,inherit)}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:var(--bs-secondary-color)}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color:var(--bs-body-color);--bs-table-bg:transparent;--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-body-color);--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:var(--bs-body-color);--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:var(--bs-body-color);--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:var(--bs-table-color);vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width) * 2) solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-striped-columns>:not(caption)>tr>:nth-child(2n){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#bacbe6;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#cbccce;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#bcd0c7;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#badce3;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#e6dbb9;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#dfc2c4;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#dfe0e1;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#373b3e;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + var(--bs-border-width));padding-bottom:calc(.375rem + var(--bs-border-width));margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + var(--bs-border-width));padding-bottom:calc(.5rem + var(--bs-border-width));font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + var(--bs-border-width));padding-bottom:calc(.25rem + var(--bs-border-width));font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--bs-secondary-color)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);background-color:var(--bs-form-control-bg);background-clip:padding-box;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--bs-body-color);background-color:var(--bs-form-control-bg);border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::-moz-placeholder{color:var(--bs-secondary-color);opacity:1}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-form-control-disabled-bg);opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:var(--bs-secondary-bg)}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:var(--bs-body-color);background-color:transparent;border:solid transparent;border-width:var(--bs-border-width) 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2));padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2))}textarea.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-control-color{width:3rem;height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);background-color:var(--bs-form-control-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:var(--bs-form-control-disabled-bg)}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--bs-body-color)}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.25rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23adb5bd' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{--bs-form-check-bg:var(--bs-form-control-bg);width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-tertiary-bg);border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-tertiary-bg);border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating::before:not(.form-control:disabled){position:absolute;top:var(--bs-border-width);left:var(--bs-border-width);width:calc(100% - (calc(calc(.375em + .1875rem) + calc(.75em + .375rem))));height:1.875em;content:"";background-color:var(--bs-form-control-bg);border-radius:.375rem}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(var(--bs-border-width) * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;width:100%;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:var(--bs-border-width) solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width) 0}.form-floating>.form-control:disabled~label{color:#6c757d}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);text-align:center;white-space:nowrap;background-color:var(--bs-tertiary-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:.375rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(var(--bs-border-width) * -1);border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-success-text)}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-success);border-radius:var(--bs-border-radius)}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:var(--bs-success);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-success);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:var(--bs-success)}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:var(--bs-success);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-success)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-success-text)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-success-text)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-danger-text)}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-danger);border-radius:var(--bs-border-radius)}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:var(--bs-danger);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-danger);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:var(--bs-danger)}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:var(--bs-danger);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-danger)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-danger-text)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-danger-text)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:0.5rem}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:0.25rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:0.375rem;--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(0.375rem - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0)}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:calc(var(--bs-border-width) * -1)}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:calc(var(--bs-border-width) * -1)}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:var(--bs-border-color);--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);--bs-nav-tabs-link-active-color:var(--bs-emphasis-color);--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:0.375rem;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius:0.375rem;--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark{--bs-navbar-color:rgba(255, 255, 255, 0.55);--bs-navbar-hover-color:rgba(255, 255, 255, 0.75);--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230a58ca'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color:#86b7fe;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:var(--bs-secondary-color);--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(var(--bs-border-width) * -1)}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:0.5rem}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:0.25rem}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:0.375rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:0.375rem;--bs-alert-link-color:inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:var(--bs-primary-text);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text)}.alert-secondary{--bs-alert-color:var(--bs-secondary-text);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text)}.alert-success{--bs-alert-color:var(--bs-success-text);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text)}.alert-info{--bs-alert-color:var(--bs-info-text);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text)}.alert-warning{--bs-alert-color:var(--bs-warning-text);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text)}.alert-danger{--bs-alert-color:var(--bs-danger-text);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text)}.alert-light{--bs-alert-color:var(--bs-light-text);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text)}.alert-dark{--bs-alert-color:var(--bs-dark-text);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle)}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle)}.list-group-item-primary.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-primary-text);--bs-list-group-active-border-color:var(--bs-primary-text)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle)}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle)}.list-group-item-secondary.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-secondary-text);--bs-list-group-active-border-color:var(--bs-secondary-text)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle)}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle)}.list-group-item-success.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-success-text);--bs-list-group-active-border-color:var(--bs-success-text)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle)}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle)}.list-group-item-info.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-info-text);--bs-list-group-active-border-color:var(--bs-info-text)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle)}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle)}.list-group-item-warning.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-warning-text);--bs-list-group-active-border-color:var(--bs-warning-text)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle)}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle)}.list-group-item-danger.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-danger-text);--bs-list-group-active-border-color:var(--bs-danger-text)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle)}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle)}.list-group-item-light.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-light-text);--bs-list-group-active-border-color:var(--bs-light-text)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle)}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle)}.list-group-item-dark.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-dark-text);--bs-list-group-active-border-color:var(--bs-dark-text)}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;--bs-btn-close-white-filter:invert(1) grayscale(100%) brightness(200%);box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{filter:var(--bs-btn-close-white-filter)}[data-bs-theme=dark] .btn-close{filter:var(--bs-btn-close-white-filter)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:0 0.125rem 0.25rem rgba(var(--bs-body-color-rgb), 0.075);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(-.5 * var(--bs-modal-header-padding-y)) calc(-.5 * var(--bs-modal-header-padding-x)) calc(-.5 * var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;padding:var(--bs-tooltip-arrow-height);margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:var(--bs-body-bg);--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: ;--bs-popover-header-bg:var(--bs-secondary-bg);--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}[data-bs-theme=dark] .carousel .carousel-control-next-icon,[data-bs-theme=dark] .carousel .carousel-control-prev-icon{filter:invert(1) grayscale(100)}[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target]{background-color:#000}[data-bs-theme=dark] .carousel .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:0 0.125rem 0.25rem rgba(var(--bs-body-color-rgb), 0.075);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:575.98px){.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}}@media (max-width:575.98px){.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:767.98px){.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}}@media (max-width:767.98px){.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:991.98px){.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}}@media (max-width:991.98px){.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1199.98px){.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}}@media (max-width:1199.98px){.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}}@media (max-width:1399.98px){.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(13,110,253,var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(108,117,125,var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(25,135,84,var(--bs-bg-opacity,1))!important}.text-bg-info{color:#000!important;background-color:RGBA(13,202,240,var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#000!important;background-color:RGBA(255,193,7,var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(220,53,69,var(--bs-bg-opacity,1))!important}.text-bg-light{color:#000!important;background-color:RGBA(248,249,250,var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(33,37,41,var(--bs-bg-opacity,1))!important}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-none{-o-object-fit:none!important;object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(var(--bs-body-color-rgb),.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(var(--bs-body-color-rgb),.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(var(--bs-body-color-rgb),.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{--bs-border-width:1px}.border-2{--bs-border-width:2px}.border-3{--bs-border-width:3px}.border-4{--bs-border-width:4px}.border-5{--bs-border-width:5px}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-body-secondary{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text)!important}.text-secondary-emphasis{color:var(--bs-secondary-text)!important}.text-success-emphasis{color:var(--bs-success-text)!important}.text-info-emphasis{color:var(--bs-info-text)!important}.text-warning-emphasis{color:var(--bs-warning-text)!important}.text-danger-emphasis{color:var(--bs-danger-text)!important}.text-light-emphasis{color:var(--bs-light-text)!important}.text-dark-emphasis{color:var(--bs-dark-text)!important}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-emphasis{--bs-bg-opacity:1;background-color:rgba(var(--bs-emphasis-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-2xl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-2xl)!important;border-top-right-radius:var(--bs-border-radius-2xl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-2xl)!important;border-bottom-right-radius:var(--bs-border-radius-2xl)!important}.rounded-end-circle{border-top-right-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-right-radius:0!important;border-bottom-left-radius:0!important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-bottom-left-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-bottom-left-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-bottom-left-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-2xl)!important;border-bottom-left-radius:var(--bs-border-radius-2xl)!important}.rounded-bottom-circle{border-bottom-right-radius:50%!important;border-bottom-left-radius:50%!important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-bottom-left-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-2xl)!important;border-top-left-radius:var(--bs-border-radius-2xl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-sm-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-sm-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-sm-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-sm-none{-o-object-fit:none!important;object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-sm-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-sm-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-sm-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-sm-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-sm-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-md-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-md-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-md-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-md-none{-o-object-fit:none!important;object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-md-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-md-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-md-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-md-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-md-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-lg-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-lg-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-lg-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-lg-none{-o-object-fit:none!important;object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-lg-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-lg-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-lg-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-lg-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-lg-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xl-none{-o-object-fit:none!important;object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xxl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xxl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xxl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xxl-none{-o-object-fit:none!important;object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xxl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xxl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xxl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xxl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xxl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/webapp/scripts/bootstrap.bundle.min.js b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/webapp/scripts/bootstrap.bundle.min.js new file mode 100644 index 0000000000..da8d852f49 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/main/webapp/scripts/bootstrap.bundle.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v5.3.0-alpha1 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t="transitionend",e=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),i=e=>{e.dispatchEvent(new Event(t))},n=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),s=t=>n(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(e(t)):null,o=t=>{if(!n(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},r=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),a=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?a(t.parentNode):null},l=()=>{},c=t=>{t.offsetHeight},h=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,d=[],u=()=>"rtl"===document.documentElement.dir,f=t=>{var e;e=()=>{const e=h();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(d.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of d)t()})),d.push(e)):e()},p=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,m=(e,n,s=!0)=>{if(!s)return void p(e);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(n)+5;let r=!1;const a=({target:i})=>{i===n&&(r=!0,n.removeEventListener(t,a),p(e))};n.addEventListener(t,a),setTimeout((()=>{r||i(n)}),o)},g=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},_=/[^.]*(?=\..*)\.|.*/,b=/\..*/,v=/::\d+$/,y={};let w=1;const A={mouseenter:"mouseover",mouseleave:"mouseout"},E=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function T(t,e){return e&&`${e}::${w++}`||t.uidEvent||w++}function C(t){const e=T(t);return t.uidEvent=e,y[e]=y[e]||{},y[e]}function O(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function x(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=D(t);return E.has(o)||(o=t),[n,s,o]}function k(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=x(e,i,n);if(e in A){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=C(t),c=l[a]||(l[a]={}),h=O(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=T(r,e.replace(_,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return N(s,{delegateTarget:r}),n.oneOff&&I.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return N(n,{delegateTarget:t}),i.oneOff&&I.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function L(t,e,i,n,s){const o=O(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function S(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&L(t,e,i,r.callable,r.delegationSelector)}function D(t){return t=t.replace(b,""),A[t]||t}const I={on(t,e,i,n){k(t,e,i,n,!1)},one(t,e,i,n){k(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=x(e,i,n),a=r!==e,l=C(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))S(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(v,"");a&&!e.includes(s)||L(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;L(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=h();let s=null,o=!0,r=!0,a=!1;e!==D(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());let l=new Event(e,{bubbles:o,cancelable:!0});return l=N(l,i),a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function N(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}const P=new Map,j={set(t,e,i){P.has(t)||P.set(t,new Map);const n=P.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>P.has(t)&&P.get(t).get(e)||null,remove(t,e){if(!P.has(t))return;const i=P.get(t);i.delete(e),0===i.size&&P.delete(t)}};function M(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function F(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const H={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${F(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${F(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=M(t.dataset[n])}return e},getDataAttribute:(t,e)=>M(t.getAttribute(`data-bs-${F(e)}`))};class ${static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=n(e)?H.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...n(e)?H.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[s,o]of Object.entries(e)){const e=t[s],r=n(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${s}" provided type "${r}" but expected type "${o}".`)}var i}}class W extends ${constructor(t,e){super(),(t=s(t))&&(this._element=t,this._config=this._getConfig(e),j.set(this._element,this.constructor.DATA_KEY,this))}dispose(){j.remove(this._element,this.constructor.DATA_KEY),I.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){m(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return j.get(s(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.0-alpha1"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let i=t.getAttribute("data-bs-target");if(!i||"#"===i){let e=t.getAttribute("href");if(!e||!e.includes("#")&&!e.startsWith("."))return null;e.includes("#")&&!e.startsWith("#")&&(e=`#${e.split("#")[1]}`),i=e&&"#"!==e?e.trim():null}return e(i)},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!r(t)&&o(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;I.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),r(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))};class q extends W{static get NAME(){return"alert"}close(){if(I.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),I.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(q,"close"),f(q);const V='[data-bs-toggle="button"]';class K extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=K.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}I.on(document,"click.bs.button.data-api",V,(t=>{t.preventDefault();const e=t.target.closest(V);K.getOrCreateInstance(e).toggle()})),f(K);const Q={endCallback:null,leftCallback:null,rightCallback:null},X={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class Y extends ${constructor(t,e){super(),this._element=t,t&&Y.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return Q}static get DefaultType(){return X}static get NAME(){return"swipe"}dispose(){I.off(this._element,".bs.swipe")}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),p(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&p(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(I.on(this._element,"pointerdown.bs.swipe",(t=>this._start(t))),I.on(this._element,"pointerup.bs.swipe",(t=>this._end(t))),this._element.classList.add("pointer-event")):(I.on(this._element,"touchstart.bs.swipe",(t=>this._start(t))),I.on(this._element,"touchmove.bs.swipe",(t=>this._move(t))),I.on(this._element,"touchend.bs.swipe",(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const U="next",G="prev",J="left",Z="right",tt="slid.bs.carousel",et="carousel",it="active",nt={ArrowLeft:Z,ArrowRight:J},st={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},ot={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class rt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===et&&this.cycle()}static get Default(){return st}static get DefaultType(){return ot}static get NAME(){return"carousel"}next(){this._slide(U)}nextWhenVisible(){!document.hidden&&o(this._element)&&this.next()}prev(){this._slide(G)}pause(){this._isSliding&&i(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?I.one(this._element,tt,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void I.one(this._element,tt,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?U:G;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&I.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(I.on(this._element,"mouseenter.bs.carousel",(()=>this.pause())),I.on(this._element,"mouseleave.bs.carousel",(()=>this._maybeEnableCycle()))),this._config.touch&&Y.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))I.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(J)),rightCallback:()=>this._slide(this._directionToOrder(Z)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new Y(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=nt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(".active",this._indicatorsElement);e.classList.remove(it),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(it),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===U,s=e||g(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>I.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r("slide.bs.carousel").defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",h=n?"carousel-item-next":"carousel-item-prev";s.classList.add(h),c(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,h),s.classList.add(it),i.classList.remove(it,h,l),this._isSliding=!1,r(tt)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(".active.carousel-item",this._element)}_getItems(){return z.find(".carousel-item",this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return u()?t===J?G:U:t===J?U:G}_orderToDirection(t){return u()?t===G?J:Z:t===G?Z:J}static jQueryInterface(t){return this.each((function(){const e=rt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}I.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(et))return;t.preventDefault();const i=rt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===H.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),I.on(window,"load.bs.carousel.data-api",(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)rt.getOrCreateInstance(e)})),f(rt);const at="show",lt="collapse",ct="collapsing",ht='[data-bs-toggle="collapse"]',dt={parent:null,toggle:!0},ut={parent:"(null|element)",toggle:"boolean"};class ft extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(ht);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return dt}static get DefaultType(){return ut}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>ft.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(I.trigger(this._element,"show.bs.collapse").defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(lt),this._element.classList.add(ct),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ct),this._element.classList.add(lt,at),this._element.style[e]="",I.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(I.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,c(this._element),this._element.classList.add(ct),this._element.classList.remove(lt,at);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ct),this._element.classList.add(lt),I.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(at)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=s(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(ht);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(":scope .collapse .collapse",this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=ft.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}I.on(document,"click.bs.collapse.data-api",ht,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))ft.getOrCreateInstance(t,{toggle:!1}).toggle()})),f(ft);var pt="top",mt="bottom",gt="right",_t="left",bt="auto",vt=[pt,mt,gt,_t],yt="start",wt="end",At="clippingParents",Et="viewport",Tt="popper",Ct="reference",Ot=vt.reduce((function(t,e){return t.concat([e+"-"+yt,e+"-"+wt])}),[]),xt=[].concat(vt,[bt]).reduce((function(t,e){return t.concat([e,e+"-"+yt,e+"-"+wt])}),[]),kt="beforeRead",Lt="read",St="afterRead",Dt="beforeMain",It="main",Nt="afterMain",Pt="beforeWrite",jt="write",Mt="afterWrite",Ft=[kt,Lt,St,Dt,It,Nt,Pt,jt,Mt];function Ht(t){return t?(t.nodeName||"").toLowerCase():null}function $t(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function Wt(t){return t instanceof $t(t).Element||t instanceof Element}function Bt(t){return t instanceof $t(t).HTMLElement||t instanceof HTMLElement}function zt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof $t(t).ShadowRoot||t instanceof ShadowRoot)}const Rt={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];Bt(s)&&Ht(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});Bt(n)&&Ht(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function qt(t){return t.split("-")[0]}var Vt=Math.max,Kt=Math.min,Qt=Math.round;function Xt(){var t=navigator.userAgentData;return null!=t&&t.brands?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Yt(){return!/^((?!chrome|android).)*safari/i.test(Xt())}function Ut(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&Bt(t)&&(s=t.offsetWidth>0&&Qt(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&Qt(n.height)/t.offsetHeight||1);var r=(Wt(t)?$t(t):window).visualViewport,a=!Yt()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function Gt(t){var e=Ut(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Jt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&zt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Zt(t){return $t(t).getComputedStyle(t)}function te(t){return["table","td","th"].indexOf(Ht(t))>=0}function ee(t){return((Wt(t)?t.ownerDocument:t.document)||window.document).documentElement}function ie(t){return"html"===Ht(t)?t:t.assignedSlot||t.parentNode||(zt(t)?t.host:null)||ee(t)}function ne(t){return Bt(t)&&"fixed"!==Zt(t).position?t.offsetParent:null}function se(t){for(var e=$t(t),i=ne(t);i&&te(i)&&"static"===Zt(i).position;)i=ne(i);return i&&("html"===Ht(i)||"body"===Ht(i)&&"static"===Zt(i).position)?e:i||function(t){var e=/firefox/i.test(Xt());if(/Trident/i.test(Xt())&&Bt(t)&&"fixed"===Zt(t).position)return null;var i=ie(t);for(zt(i)&&(i=i.host);Bt(i)&&["html","body"].indexOf(Ht(i))<0;){var n=Zt(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function oe(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function re(t,e,i){return Vt(t,Kt(e,i))}function ae(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function le(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const ce={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=qt(i.placement),l=oe(a),c=[_t,gt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return ae("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:le(t,vt))}(s.padding,i),d=Gt(o),u="y"===l?pt:_t,f="y"===l?mt:gt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=se(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=re(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Jt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function he(t){return t.split("-")[1]}var de={top:"auto",right:"auto",bottom:"auto",left:"auto"};function ue(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=_t,y=pt,w=window;if(c){var A=se(i),E="clientHeight",T="clientWidth";A===$t(i)&&"static"!==Zt(A=ee(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===pt||(s===_t||s===gt)&&o===wt)&&(y=mt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==_t&&(s!==pt&&s!==mt||o!==wt)||(v=gt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&de),x=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:Qt(e*n)/n||0,y:Qt(i*n)/n||0}}({x:f,y:m}):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const fe={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:qt(e.placement),variation:he(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,ue(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,ue(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var pe={passive:!0};const me={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=$t(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,pe)})),a&&l.addEventListener("resize",i.update,pe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,pe)})),a&&l.removeEventListener("resize",i.update,pe)}},data:{}};var ge={left:"right",right:"left",bottom:"top",top:"bottom"};function _e(t){return t.replace(/left|right|bottom|top/g,(function(t){return ge[t]}))}var be={start:"end",end:"start"};function ve(t){return t.replace(/start|end/g,(function(t){return be[t]}))}function ye(t){var e=$t(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function we(t){return Ut(ee(t)).left+ye(t).scrollLeft}function Ae(t){var e=Zt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ee(t){return["html","body","#document"].indexOf(Ht(t))>=0?t.ownerDocument.body:Bt(t)&&Ae(t)?t:Ee(ie(t))}function Te(t,e){var i;void 0===e&&(e=[]);var n=Ee(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=$t(n),r=s?[o].concat(o.visualViewport||[],Ae(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Te(ie(r)))}function Ce(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Oe(t,e,i){return e===Et?Ce(function(t,e){var i=$t(t),n=ee(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Yt();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+we(t),y:l}}(t,i)):Wt(e)?function(t,e){var i=Ut(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):Ce(function(t){var e,i=ee(t),n=ye(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=Vt(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=Vt(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+we(t),l=-n.scrollTop;return"rtl"===Zt(s||i).direction&&(a+=Vt(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(ee(t)))}function xe(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?qt(s):null,r=s?he(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case pt:e={x:a,y:i.y-n.height};break;case mt:e={x:a,y:i.y+i.height};break;case gt:e={x:i.x+i.width,y:l};break;case _t:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?oe(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case yt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case wt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ke(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?At:a,c=i.rootBoundary,h=void 0===c?Et:c,d=i.elementContext,u=void 0===d?Tt:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=ae("number"!=typeof g?g:le(g,vt)),b=u===Tt?Ct:Tt,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=Te(ie(t)),i=["absolute","fixed"].indexOf(Zt(t).position)>=0&&Bt(t)?se(t):t;return Wt(i)?e.filter((function(t){return Wt(t)&&Jt(t,i)&&"body"!==Ht(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=Oe(t,i,n);return e.top=Vt(s.top,e.top),e.right=Kt(s.right,e.right),e.bottom=Kt(s.bottom,e.bottom),e.left=Vt(s.left,e.left),e}),Oe(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(Wt(y)?y:y.contextElement||ee(t.elements.popper),l,h,r),A=Ut(t.elements.reference),E=xe({reference:A,element:v,strategy:"absolute",placement:s}),T=Ce(Object.assign({},v,E)),C=u===Tt?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===Tt&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[gt,mt].indexOf(t)>=0?1:-1,i=[pt,mt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function Le(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?xt:l,h=he(n),d=h?a?Ot:Ot.filter((function(t){return he(t)===h})):vt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ke(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[qt(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const Se={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=qt(g),b=l||(_!==g&&p?function(t){if(qt(t)===bt)return[];var e=_e(t);return[ve(t),e,ve(e)]}(g):[_e(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(qt(i)===bt?Le(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=ke(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),I=L?k?gt:_t:k?mt:pt;y[S]>w[S]&&(I=_e(I));var N=_e(I),P=[];if(o&&P.push(D[x]<=0),a&&P.push(D[I]<=0,D[N]<=0),P.every((function(t){return t}))){T=O,E=!1;break}A.set(O,P)}if(E)for(var j=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function De(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Ie(t){return[pt,gt,mt,_t].some((function(e){return t[e]>=0}))}const Ne={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ke(e,{elementContext:"reference"}),a=ke(e,{altBoundary:!0}),l=De(r,n),c=De(a,s,o),h=Ie(l),d=Ie(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Pe={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=xt.reduce((function(t,i){return t[i]=function(t,e,i){var n=qt(t),s=[_t,pt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[_t,gt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},je={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=xe({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},Me={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ke(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=qt(e.placement),b=he(e.placement),v=!b,y=oe(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?pt:_t,D="y"===y?mt:gt,I="y"===y?"height":"width",N=A[y],P=N+g[S],j=N-g[D],M=f?-T[I]/2:0,F=b===yt?E[I]:T[I],H=b===yt?-T[I]:-E[I],$=e.elements.arrow,W=f&&$?Gt($):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=re(0,E[I],W[I]),V=v?E[I]/2-M-q-z-O.mainAxis:F-q-z-O.mainAxis,K=v?-E[I]/2+M+q+R+O.mainAxis:H+q+R+O.mainAxis,Q=e.elements.arrow&&se(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=N+K-Y,G=re(f?Kt(P,N+V-Y-X):P,N,f?Vt(j,U):j);A[y]=G,k[y]=G-N}if(a){var J,Z="x"===y?pt:_t,tt="x"===y?mt:gt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[pt,_t].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=re(t,e,i);return n>i?i:n}(at,et,lt):re(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function Fe(t,e,i){void 0===i&&(i=!1);var n,s,o=Bt(e),r=Bt(e)&&function(t){var e=t.getBoundingClientRect(),i=Qt(e.width)/t.offsetWidth||1,n=Qt(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=ee(e),l=Ut(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==Ht(e)||Ae(a))&&(c=(n=e)!==$t(n)&&Bt(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:ye(n)),Bt(e)?((h=Ut(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=we(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function He(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var $e={placement:"bottom",modifiers:[],strategy:"absolute"};function We(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(H.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...p(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>o(t)));i.length&&g(i,e,t===Xe,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=ci.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(Ze);for(const i of e){const e=ci.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Qe,Xe].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Je)?this:z.prev(this,Je)[0]||z.next(this,Je)[0]||z.findOne(Je,t.delegateTarget.parentNode),o=ci.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}I.on(document,Ue,Je,ci.dataApiKeydownHandler),I.on(document,Ue,ti,ci.dataApiKeydownHandler),I.on(document,Ye,ci.clearMenus),I.on(document,"keyup.bs.dropdown.data-api",ci.clearMenus),I.on(document,Ye,Je,(function(t){t.preventDefault(),ci.getOrCreateInstance(this).toggle()})),f(ci);const hi=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",di=".sticky-top",ui="padding-right",fi="margin-right";class pi{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,ui,(e=>e+t)),this._setElementAttributes(hi,ui,(e=>e+t)),this._setElementAttributes(di,fi,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,ui),this._resetElementAttributes(hi,ui),this._resetElementAttributes(di,fi)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&H.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=H.getDataAttribute(t,e);null!==i?(H.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(n(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const mi="show",gi="mousedown.bs.backdrop",_i={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},bi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class vi extends ${constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return _i}static get DefaultType(){return bi}static get NAME(){return"backdrop"}show(t){if(!this._config.isVisible)return void p(t);this._append();const e=this._getElement();this._config.isAnimated&&c(e),e.classList.add(mi),this._emulateAnimation((()=>{p(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(mi),this._emulateAnimation((()=>{this.dispose(),p(t)}))):p(t)}dispose(){this._isAppended&&(I.off(this._element,gi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=s(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),I.on(t,gi,(()=>{p(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){m(t,this._getElement(),this._config.isAnimated)}}const yi=".bs.focustrap",wi="backward",Ai={autofocus:!0,trapElement:null},Ei={autofocus:"boolean",trapElement:"element"};class Ti extends ${constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return Ai}static get DefaultType(){return Ei}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),I.off(document,yi),I.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),I.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,I.off(document,yi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===wi?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?wi:"forward")}}const Ci="hidden.bs.modal",Oi="show.bs.modal",xi="modal-open",ki="show",Li="modal-static",Si={backdrop:!0,focus:!0,keyboard:!0},Di={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class Ii extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new pi,this._addEventListeners()}static get Default(){return Si}static get DefaultType(){return Di}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||I.trigger(this._element,Oi,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(xi),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(I.trigger(this._element,"hide.bs.modal").defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(ki),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){for(const t of[window,this._dialog])I.off(t,".bs.modal");this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new vi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ti({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),c(this._element),this._element.classList.add(ki),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,I.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){I.on(this._element,"keydown.dismiss.bs.modal",(t=>{if("Escape"===t.key)return this._config.keyboard?(t.preventDefault(),void this.hide()):void this._triggerBackdropTransition()})),I.on(window,"resize.bs.modal",(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),I.on(this._element,"mousedown.dismiss.bs.modal",(t=>{I.one(this._element,"click.dismiss.bs.modal",(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(xi),this._resetAdjustments(),this._scrollBar.reset(),I.trigger(this._element,Ci)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(I.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Li)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Li),this._queueCallback((()=>{this._element.classList.remove(Li),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=u()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=u()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Ii.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}I.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),I.one(e,Oi,(t=>{t.defaultPrevented||I.one(e,Ci,(()=>{o(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&Ii.getInstance(i).hide(),Ii.getOrCreateInstance(e).toggle(this)})),R(Ii),f(Ii);const Ni="show",Pi="showing",ji="hiding",Mi=".offcanvas.show",Fi="hidePrevented.bs.offcanvas",Hi="hidden.bs.offcanvas",$i={backdrop:!0,keyboard:!0,scroll:!1},Wi={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Bi extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return $i}static get DefaultType(){return Wi}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||I.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new pi).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Pi),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Ni),this._element.classList.remove(Pi),I.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(I.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(ji),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Ni,ji),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new pi).reset(),I.trigger(this._element,Hi)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new vi({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():I.trigger(this._element,Fi)}:null})}_initializeFocusTrap(){return new Ti({trapElement:this._element})}_addEventListeners(){I.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():I.trigger(this._element,Fi))}))}static jQueryInterface(t){return this.each((function(){const e=Bi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}I.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),r(this))return;I.one(e,Hi,(()=>{o(this)&&this.focus()}));const i=z.findOne(Mi);i&&i!==e&&Bi.getInstance(i).hide(),Bi.getOrCreateInstance(e).toggle(this)})),I.on(window,"load.bs.offcanvas.data-api",(()=>{for(const t of z.find(Mi))Bi.getOrCreateInstance(t).show()})),I.on(window,"resize.bs.offcanvas",(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&Bi.getOrCreateInstance(t).hide()})),R(Bi),f(Bi);const zi=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Ri=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,qi=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Vi=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!zi.has(i)||Boolean(Ri.test(t.nodeValue)||qi.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Ki={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Qi={allowList:Ki,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Xi={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Yi={entry:"(string|element|function|null)",selector:"(string|element)"};class Ui extends ${constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Qi}static get DefaultType(){return Xi}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Yi)}_setContent(t,e,i){const o=z.findOne(i,t);o&&((e=this._resolvePossibleFunction(e))?n(e)?this._putElementInTemplate(s(e),o):this._config.html?o.innerHTML=this._maybeSanitize(e):o.textContent=e:o.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Vi(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return p(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Gi=new Set(["sanitize","allowList","sanitizeFn"]),Ji="fade",Zi="show",tn=".modal",en="hide.bs.modal",nn="hover",sn="focus",on={AUTO:"auto",TOP:"top",RIGHT:u()?"left":"right",BOTTOM:"bottom",LEFT:u()?"right":"left"},rn={allowList:Ki,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,0],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},an={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class ln extends W{constructor(t,e){if(void 0===Ve)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return rn}static get DefaultType(){return an}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),I.off(this._element.closest(tn),en,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=I.trigger(this._element,this.constructor.eventName("show")),e=(a(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),I.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(Zi),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))I.on(t,"mouseover",l);this._queueCallback((()=>{I.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!I.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(Zi),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))I.off(t,"mouseover",l);this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),I.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(Ji,Zi),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(Ji),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Ui({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(Ji)}_isShown(){return this.tip&&this.tip.classList.contains(Zi)}_createPopper(t){const e=p(this._config.placement,[this,t,this._element]),i=on[e.toUpperCase()];return qe(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return p(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...p(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)I.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===nn?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===nn?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");I.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?sn:nn]=!0,e._enter()})),I.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?sn:nn]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},I.on(this._element.closest(tn),en,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=H.getDataAttributes(this._element);for(const t of Object.keys(e))Gi.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:s(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=ln.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}f(ln);const cn={...ln.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},hn={...ln.DefaultType,content:"(null|string|element|function)"};class dn extends ln{static get Default(){return cn}static get DefaultType(){return hn}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=dn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}f(dn);const un="click.bs.scrollspy",fn="active",pn="[href]",mn={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},gn={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class _n extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return mn}static get DefaultType(){return gn}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=s(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(I.off(this._config.target,un),I.on(this._config.target,un,pn,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(pn,this._config.target);for(const e of t){if(!e.hash||r(e))continue;const t=z.findOne(e.hash,this._element);o(t)&&(this._targetLinks.set(e.hash,e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(fn),this._activateParents(t),I.trigger(this._element,"activate.bs.scrollspy",{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(fn);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,".nav-link, .nav-item > .nav-link, .list-group-item"))t.classList.add(fn)}_clearActiveClass(t){t.classList.remove(fn);const e=z.find("[href].active",t);for(const t of e)t.classList.remove(fn)}static jQueryInterface(t){return this.each((function(){const e=_n.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}I.on(window,"load.bs.scrollspy.data-api",(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))_n.getOrCreateInstance(t)})),f(_n);const bn="ArrowLeft",vn="ArrowRight",yn="ArrowUp",wn="ArrowDown",An="active",En="fade",Tn="show",Cn='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',On=`.nav-link:not(.dropdown-toggle), .list-group-item:not(.dropdown-toggle), [role="tab"]:not(.dropdown-toggle), ${Cn}`;class xn extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),I.on(this._element,"keydown.bs.tab",(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?I.trigger(e,"hide.bs.tab",{relatedTarget:t}):null;I.trigger(t,"show.bs.tab",{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(An),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),I.trigger(t,"shown.bs.tab",{relatedTarget:e})):t.classList.add(Tn)}),t,t.classList.contains(En)))}_deactivate(t,e){t&&(t.classList.remove(An),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),I.trigger(t,"hidden.bs.tab",{relatedTarget:e})):t.classList.remove(Tn)}),t,t.classList.contains(En)))}_keydown(t){if(![bn,vn,yn,wn].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=[vn,wn].includes(t.key),i=g(this._getChildren().filter((t=>!r(t))),t.target,e,!0);i&&(i.focus({preventScroll:!0}),xn.getOrCreateInstance(i).show())}_getChildren(){return z.find(On,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`#${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",An),n(".dropdown-menu",Tn),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(An)}_getInnerElement(t){return t.matches(On)?t:z.findOne(On,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=xn.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}I.on(document,"click.bs.tab",Cn,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),r(this)||xn.getOrCreateInstance(this).show()})),I.on(window,"load.bs.tab",(()=>{for(const t of z.find('.active[data-bs-toggle="tab"], .active[data-bs-toggle="pill"], .active[data-bs-toggle="list"]'))xn.getOrCreateInstance(t)})),f(xn);const kn="hide",Ln="show",Sn="showing",Dn={animation:"boolean",autohide:"boolean",delay:"number"},In={animation:!0,autohide:!0,delay:5e3};class Nn extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return In}static get DefaultType(){return Dn}static get NAME(){return"toast"}show(){I.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(kn),c(this._element),this._element.classList.add(Ln,Sn),this._queueCallback((()=>{this._element.classList.remove(Sn),I.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(I.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(Sn),this._queueCallback((()=>{this._element.classList.add(kn),this._element.classList.remove(Sn,Ln),I.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(Ln),super.dispose()}isShown(){return this._element.classList.contains(Ln)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){I.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),I.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),I.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),I.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Nn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(Nn),f(Nn),{Alert:q,Button:K,Carousel:rt,Collapse:ft,Dropdown:ci,Modal:Ii,Offcanvas:Bi,Popover:dn,ScrollSpy:_n,Tab:xn,Toast:Nn,Tooltip:ln}})); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/test/java/com/baeldung/accesing_session_attributes/business/impl/NameAnalysisServiceImplUnitTest.java b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/test/java/com/baeldung/accesing_session_attributes/business/impl/NameAnalysisServiceImplUnitTest.java new file mode 100644 index 0000000000..d23d89a9bc --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/test/java/com/baeldung/accesing_session_attributes/business/impl/NameAnalysisServiceImplUnitTest.java @@ -0,0 +1,107 @@ +package com.baeldung.accesing_session_attributes.business.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.accesing_session_attributes.business.AgeAnalysisService; +import com.baeldung.accesing_session_attributes.business.CountryAnalysisService; +import com.baeldung.accesing_session_attributes.business.GenderAnalysisService; +import com.baeldung.accesing_session_attributes.business.NameAnalysisService; +import com.baeldung.accesing_session_attributes.business.beans.NameRequest; +import com.baeldung.accesing_session_attributes.business.entities.NameAgeEntity; +import com.baeldung.accesing_session_attributes.business.entities.NameAnalysisEntity; +import com.baeldung.accesing_session_attributes.business.entities.NameCountriesEntity; +import com.baeldung.accesing_session_attributes.business.entities.NameGenderEntity; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +@ExtendWith(SpringExtension.class) +@SpringBootTest +@ActiveProfiles({ "test" }) +public class NameAnalysisServiceImplUnitTest { + + @Autowired + private ObjectMapper om; + @MockBean + private AgeAnalysisService ageAnalysisService; + @MockBean + private CountryAnalysisService countryAnalysisService; + @MockBean + private GenderAnalysisService genderAnalysisService; + @Autowired + private NameAnalysisService toTest; + + @Test + void givenRigoberto_whenCallCompletesOk_thenNameAnalysisEntityReceived() + throws JsonMappingException, JsonProcessingException { + String nameToAnalyze = "Rigoberto"; + NameAgeEntity rigobertoAgeAnalysis = om.readValue("{\"age\":68,\"count\":683,\"name\":\"Rigoberto\"}", + NameAgeEntity.class); + NameCountriesEntity rigobertoCountriesAnalysis = om.readValue( + "{\"country\":[{\"country_id\":\"MX\",\"probability\":0.132},{\"country_id\":\"PA\",\"probability\":0.107},{\"country_id\":\"CR\",\"probability\":0.09},{\"country_id\":\"HN\",\"probability\":0.082},{\"country_id\":\"GT\",\"probability\":0.075}],\"name\":\"Rigoberto\"}", + NameCountriesEntity.class); + NameGenderEntity rigobertoGenderAnalysis = om.readValue( + "{\"count\":13927,\"gender\":\"male\",\"name\":\"Rigoberto\",\"probability\":1.0}", + NameGenderEntity.class); + Mockito.when(ageAnalysisService.getAgeAnalysisForName(nameToAnalyze)) + .thenReturn(ResponseEntity.ok(rigobertoAgeAnalysis)); + Mockito.when(countryAnalysisService.getCountryAnalysisForName(nameToAnalyze)) + .thenReturn(ResponseEntity.ok(rigobertoCountriesAnalysis)); + Mockito.when(genderAnalysisService.getGenderAnalysisForName(nameToAnalyze)) + .thenReturn(ResponseEntity.ok(rigobertoGenderAnalysis)); + + NameRequest rigobertoRequest = new NameRequest(); + rigobertoRequest.setName(nameToAnalyze); + CompletableFuture result = toTest.searchForName(rigobertoRequest); + + try { + NameAnalysisEntity analysisResult = result.get(); + assertEquals(nameToAnalyze, analysisResult.getName()); + assertEquals(rigobertoAgeAnalysis, analysisResult.getAge()); + assertEquals(rigobertoCountriesAnalysis, analysisResult.getCountries()); + assertEquals(rigobertoGenderAnalysis, analysisResult.getGender()); + + } catch (Exception e) { + fail("Not expected exception"); + } + } + + @Test + void whenNameAnalysisRequestFails_thenCompletableFutureException() { + String nameToAnalyze = "Rigoberto"; + Mockito.when(ageAnalysisService.getAgeAnalysisForName(nameToAnalyze)) + .thenThrow(new RuntimeException("Failed age analysis for name")); + Mockito.when(countryAnalysisService.getCountryAnalysisForName(nameToAnalyze)) + .thenThrow(new RuntimeException("Failed country analysis for name")); + Mockito.when(genderAnalysisService.getGenderAnalysisForName(nameToAnalyze)) + .thenThrow(new RuntimeException("Failed gender analysis for name")); + + NameRequest rigobertoRequest = new NameRequest(); + rigobertoRequest.setName(nameToAnalyze); + CompletableFuture result = toTest.searchForName(rigobertoRequest); + + try { + result.get(); + fail("Expected Execution Exception"); + + } catch (ExecutionException e) { + + } catch (InterruptedException e) { + fail("Expected Execution Exception"); + } + } +} diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/test/resources/application-test.properties b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/test/resources/application-test.properties new file mode 100644 index 0000000000..d61436a842 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/src/test/resources/application-test.properties @@ -0,0 +1,4 @@ +spring.http.encoding.enabled=true +spring.devtools.add-properties=false +logging.level.web=DEBUG +spring.thymeleaf.check-template-location=false \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/pom.xml b/spring-web-modules/spring-thymeleaf-attributes/pom.xml new file mode 100644 index 0000000000..41ea8b4dd1 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-attributes/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + + com.baeldung.spring-thymeleaf-attributes + spring-thymeleaf-attributes-modules + 0.0.1-SNAPSHOT + pom + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 + + + + + org.springframework.boot + spring-boot-devtools + + + + + accessing-session-attributes + + \ No newline at end of file diff --git a/spring-websockets/pom.xml b/spring-websockets/pom.xml index a28ef8749a..c13d1cff33 100644 --- a/spring-websockets/pom.xml +++ b/spring-websockets/pom.xml @@ -44,4 +44,8 @@ + + 3.3.2 + + \ No newline at end of file diff --git a/terraform/README.md b/terraform-modules/README.md similarity index 100% rename from terraform/README.md rename to terraform-modules/README.md diff --git a/terraform/best-practices/README.md b/terraform-modules/best-practices/README.md similarity index 100% rename from terraform/best-practices/README.md rename to terraform-modules/best-practices/README.md diff --git a/terraform/best-practices/ec2-simple/.gitignore b/terraform-modules/best-practices/ec2-simple/.gitignore similarity index 100% rename from terraform/best-practices/ec2-simple/.gitignore rename to terraform-modules/best-practices/ec2-simple/.gitignore diff --git a/terraform/best-practices/ec2-simple/SETUP.md b/terraform-modules/best-practices/ec2-simple/SETUP.md similarity index 100% rename from terraform/best-practices/ec2-simple/SETUP.md rename to terraform-modules/best-practices/ec2-simple/SETUP.md diff --git a/terraform/best-practices/ec2-simple/main.tf b/terraform-modules/best-practices/ec2-simple/main.tf similarity index 100% rename from terraform/best-practices/ec2-simple/main.tf rename to terraform-modules/best-practices/ec2-simple/main.tf diff --git a/terraform/best-practices/ec2-simple/providers.tf b/terraform-modules/best-practices/ec2-simple/providers.tf similarity index 100% rename from terraform/best-practices/ec2-simple/providers.tf rename to terraform-modules/best-practices/ec2-simple/providers.tf diff --git a/terraform/best-practices/ec2-simple/variables.tf b/terraform-modules/best-practices/ec2-simple/variables.tf similarity index 100% rename from terraform/best-practices/ec2-simple/variables.tf rename to terraform-modules/best-practices/ec2-simple/variables.tf diff --git a/terraform/best-practices/k8s-basic/.gitignore b/terraform-modules/best-practices/k8s-basic/.gitignore similarity index 100% rename from terraform/best-practices/k8s-basic/.gitignore rename to terraform-modules/best-practices/k8s-basic/.gitignore diff --git a/terraform/best-practices/k8s-basic/SETUP.md b/terraform-modules/best-practices/k8s-basic/SETUP.md similarity index 100% rename from terraform/best-practices/k8s-basic/SETUP.md rename to terraform-modules/best-practices/k8s-basic/SETUP.md diff --git a/terraform/best-practices/k8s-basic/main.tf b/terraform-modules/best-practices/k8s-basic/main.tf similarity index 100% rename from terraform/best-practices/k8s-basic/main.tf rename to terraform-modules/best-practices/k8s-basic/main.tf diff --git a/terraform/best-practices/k8s-basic/providers.tf b/terraform-modules/best-practices/k8s-basic/providers.tf similarity index 100% rename from terraform/best-practices/k8s-basic/providers.tf rename to terraform-modules/best-practices/k8s-basic/providers.tf diff --git a/terraform/best-practices/k8s-basic/variables.tf b/terraform-modules/best-practices/k8s-basic/variables.tf similarity index 100% rename from terraform/best-practices/k8s-basic/variables.tf rename to terraform-modules/best-practices/k8s-basic/variables.tf diff --git a/terraform/best-practices/k8s-modules/.gitignore b/terraform-modules/best-practices/k8s-modules/.gitignore similarity index 100% rename from terraform/best-practices/k8s-modules/.gitignore rename to terraform-modules/best-practices/k8s-modules/.gitignore diff --git a/terraform/best-practices/k8s-modules/SETUP.md b/terraform-modules/best-practices/k8s-modules/SETUP.md similarity index 100% rename from terraform/best-practices/k8s-modules/SETUP.md rename to terraform-modules/best-practices/k8s-modules/SETUP.md diff --git a/terraform/best-practices/k8s-modules/main.tf b/terraform-modules/best-practices/k8s-modules/main.tf similarity index 100% rename from terraform/best-practices/k8s-modules/main.tf rename to terraform-modules/best-practices/k8s-modules/main.tf diff --git a/terraform/best-practices/k8s-modules/modules/SvcCustomer/main.tf b/terraform-modules/best-practices/k8s-modules/modules/SvcCustomer/main.tf similarity index 100% rename from terraform/best-practices/k8s-modules/modules/SvcCustomer/main.tf rename to terraform-modules/best-practices/k8s-modules/modules/SvcCustomer/main.tf diff --git a/terraform/best-practices/k8s-modules/modules/SvcCustomer/outputs.tf b/terraform-modules/best-practices/k8s-modules/modules/SvcCustomer/outputs.tf similarity index 100% rename from terraform/best-practices/k8s-modules/modules/SvcCustomer/outputs.tf rename to terraform-modules/best-practices/k8s-modules/modules/SvcCustomer/outputs.tf diff --git a/terraform/best-practices/k8s-modules/modules/SvcCustomer/variables.tf b/terraform-modules/best-practices/k8s-modules/modules/SvcCustomer/variables.tf similarity index 100% rename from terraform/best-practices/k8s-modules/modules/SvcCustomer/variables.tf rename to terraform-modules/best-practices/k8s-modules/modules/SvcCustomer/variables.tf diff --git a/terraform/best-practices/k8s-modules/modules/SvcFeedback/main.tf b/terraform-modules/best-practices/k8s-modules/modules/SvcFeedback/main.tf similarity index 100% rename from terraform/best-practices/k8s-modules/modules/SvcFeedback/main.tf rename to terraform-modules/best-practices/k8s-modules/modules/SvcFeedback/main.tf diff --git a/terraform/best-practices/k8s-modules/modules/SvcFeedback/outputs.tf b/terraform-modules/best-practices/k8s-modules/modules/SvcFeedback/outputs.tf similarity index 100% rename from terraform/best-practices/k8s-modules/modules/SvcFeedback/outputs.tf rename to terraform-modules/best-practices/k8s-modules/modules/SvcFeedback/outputs.tf diff --git a/terraform/best-practices/k8s-modules/modules/SvcFeedback/variables.tf b/terraform-modules/best-practices/k8s-modules/modules/SvcFeedback/variables.tf similarity index 100% rename from terraform/best-practices/k8s-modules/modules/SvcFeedback/variables.tf rename to terraform-modules/best-practices/k8s-modules/modules/SvcFeedback/variables.tf diff --git a/terraform/best-practices/k8s-modules/modules/ingress/www.petshop.com.br/main.tf b/terraform-modules/best-practices/k8s-modules/modules/ingress/www.petshop.com.br/main.tf similarity index 100% rename from terraform/best-practices/k8s-modules/modules/ingress/www.petshop.com.br/main.tf rename to terraform-modules/best-practices/k8s-modules/modules/ingress/www.petshop.com.br/main.tf diff --git a/terraform/best-practices/k8s-modules/modules/ingress/www.petshop.com.br/outputs.tf b/terraform-modules/best-practices/k8s-modules/modules/ingress/www.petshop.com.br/outputs.tf similarity index 100% rename from terraform/best-practices/k8s-modules/modules/ingress/www.petshop.com.br/outputs.tf rename to terraform-modules/best-practices/k8s-modules/modules/ingress/www.petshop.com.br/outputs.tf diff --git a/terraform/best-practices/k8s-modules/modules/ingress/www.petshop.com.br/variables.tf b/terraform-modules/best-practices/k8s-modules/modules/ingress/www.petshop.com.br/variables.tf similarity index 100% rename from terraform/best-practices/k8s-modules/modules/ingress/www.petshop.com.br/variables.tf rename to terraform-modules/best-practices/k8s-modules/modules/ingress/www.petshop.com.br/variables.tf diff --git a/terraform/best-practices/k8s-modules/provider.tf b/terraform-modules/best-practices/k8s-modules/provider.tf similarity index 100% rename from terraform/best-practices/k8s-modules/provider.tf rename to terraform-modules/best-practices/k8s-modules/provider.tf diff --git a/terraform/hello-terraform/.gitignore b/terraform-modules/hello-terraform/.gitignore similarity index 100% rename from terraform/hello-terraform/.gitignore rename to terraform-modules/hello-terraform/.gitignore diff --git a/terraform/hello-terraform/main.tf b/terraform-modules/hello-terraform/main.tf similarity index 100% rename from terraform/hello-terraform/main.tf rename to terraform-modules/hello-terraform/main.tf diff --git a/testing-modules/gatling-java/README.md b/testing-modules/gatling-java/README.md index 71848ecfdc..4bc07b1910 100644 --- a/testing-modules/gatling-java/README.md +++ b/testing-modules/gatling-java/README.md @@ -1,7 +1,7 @@ ### Relevant Articles: -Load testing Rest End point using Gatling +- [Load Testing Rest Endpoint Using Gatling](https://www.baeldung.com/gatling-load-testing-rest-endpoint) ### Running a simualtion - To run the simulation from command prompt use mvn gatling:test \ No newline at end of file + To run the simulation from command prompt use mvn gatling:test diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/DivisibilityUnitTest.java b/testing-modules/junit-4/src/test/java/com/baeldung/junit/DivisibilityUnitTest.java similarity index 90% rename from core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/DivisibilityUnitTest.java rename to testing-modules/junit-4/src/test/java/com/baeldung/junit/DivisibilityUnitTest.java index b8fe701f57..3bdc8787f5 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/DivisibilityUnitTest.java +++ b/testing-modules/junit-4/src/test/java/com/baeldung/junit/DivisibilityUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.junit4vstestng; +package com.baeldung.junit; import static org.junit.Assert.assertEquals; diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/RegistrationUnitTest.java b/testing-modules/junit-4/src/test/java/com/baeldung/junit/RegistrationUnitTest.java similarity index 89% rename from core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/RegistrationUnitTest.java rename to testing-modules/junit-4/src/test/java/com/baeldung/junit/RegistrationUnitTest.java index 08a9f1e1c4..b52c565a9d 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/RegistrationUnitTest.java +++ b/testing-modules/junit-4/src/test/java/com/baeldung/junit/RegistrationUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.junit4vstestng; +package com.baeldung.junit; import org.junit.Test; import org.slf4j.Logger; diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/SignInUnitTest.java b/testing-modules/junit-4/src/test/java/com/baeldung/junit/SignInUnitTest.java similarity index 89% rename from core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/SignInUnitTest.java rename to testing-modules/junit-4/src/test/java/com/baeldung/junit/SignInUnitTest.java index a49fb454ea..145eb0d835 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/SignInUnitTest.java +++ b/testing-modules/junit-4/src/test/java/com/baeldung/junit/SignInUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.junit4vstestng; +package com.baeldung.junit; import org.junit.Test; import org.slf4j.Logger; diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/StringCaseUnitTest.java b/testing-modules/junit-4/src/test/java/com/baeldung/junit/StringCaseUnitTest.java similarity index 91% rename from core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/StringCaseUnitTest.java rename to testing-modules/junit-4/src/test/java/com/baeldung/junit/StringCaseUnitTest.java index 16a881f7e7..a76fe97161 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/StringCaseUnitTest.java +++ b/testing-modules/junit-4/src/test/java/com/baeldung/junit/StringCaseUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.junit4vstestng; +package com.baeldung.junit; import static org.junit.Assert.assertEquals; diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/ParametrizedUnitTest.java b/testing-modules/junit-4/src/test/java/com/baeldung/junitparams/ParametrizedUnitTest.java similarity index 92% rename from core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/ParametrizedUnitTest.java rename to testing-modules/junit-4/src/test/java/com/baeldung/junitparams/ParametrizedUnitTest.java index b46d4e895d..4e5a59eb22 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/ParametrizedUnitTest.java +++ b/testing-modules/junit-4/src/test/java/com/baeldung/junitparams/ParametrizedUnitTest.java @@ -1,7 +1,6 @@ -package com.baeldung.junit4vstestng; +package com.baeldung.junitparams; import org.junit.Assert; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/SuiteUnitTest.java b/testing-modules/junit-4/src/test/java/com/baeldung/runfromjava/SuiteUnitTest.java similarity index 61% rename from core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/SuiteUnitTest.java rename to testing-modules/junit-4/src/test/java/com/baeldung/runfromjava/SuiteUnitTest.java index 3e02309636..67093b8a62 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/junit4vstestng/SuiteUnitTest.java +++ b/testing-modules/junit-4/src/test/java/com/baeldung/runfromjava/SuiteUnitTest.java @@ -1,7 +1,9 @@ -package com.baeldung.junit4vstestng; +package com.baeldung.runfromjava; import org.junit.runner.RunWith; import org.junit.runners.Suite; +import com.baeldung.junit.RegistrationUnitTest; +import com.baeldung.junit.SignInUnitTest; @RunWith(Suite.class) @Suite.SuiteClasses({ RegistrationUnitTest.class, SignInUnitTest.class }) diff --git a/testing-modules/junit-5-advanced/README.md b/testing-modules/junit-5-advanced/README.md index 9b3a5fa299..a89bcd2de2 100644 --- a/testing-modules/junit-5-advanced/README.md +++ b/testing-modules/junit-5-advanced/README.md @@ -8,3 +8,4 @@ - [Parallel Test Execution for JUnit 5](https://www.baeldung.com/junit-5-parallel-tests) - [JUnit – Testing Methods That Call System.exit()](https://www.baeldung.com/junit-system-exit) - [Single Assert Call for Multiple Properties in Java Unit Testing](https://www.baeldung.com/java-testing-single-assert-multiple-properties) +- [Creating a Test Suite With JUnit](https://www.baeldung.com/java-junit-test-suite) diff --git a/testing-modules/junit-5-advanced/pom.xml b/testing-modules/junit-5-advanced/pom.xml index bfc490b03e..5a65b0f6f3 100644 --- a/testing-modules/junit-5-advanced/pom.xml +++ b/testing-modules/junit-5-advanced/pom.xml @@ -33,6 +33,19 @@ ${assertj.version} test + + org.junit.platform + junit-platform-suite + ${junit-platform.version} + test + + + org.junit.platform + junit-platform-runner + ${junit-platform.version} + test + + @@ -45,6 +58,9 @@ -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar true + + **/testsuite/**/*UnitTest.java + @@ -53,6 +69,7 @@ 1.49 3.24.2 + 1.9.2 \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassOneUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassOneUnitTest.java new file mode 100644 index 0000000000..4ce092796e --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassOneUnitTest.java @@ -0,0 +1,13 @@ +package com.baeldung.testsuite; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ClassOneUnitTest { + + @Test + public void whenTrue_thenTrue() { + Assertions.assertTrue(true); + } + +} diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassThreeUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassThreeUnitTest.java new file mode 100644 index 0000000000..b686ef5773 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassThreeUnitTest.java @@ -0,0 +1,13 @@ +package com.baeldung.testsuite; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +public class ClassThreeUnitTest { + @Test + @Tag("slow") + public void whenTrue_thenTrue() { + Assertions.assertTrue(true); + } +} diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/package-info.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/package-info.java new file mode 100644 index 0000000000..53c8ea5e8a --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/package-info.java @@ -0,0 +1,4 @@ +/** + * Dummy tests - showing Junit Suite functionality + */ +package com.baeldung.testsuite; \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/subpackage/ClassTwoUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/subpackage/ClassTwoUnitTest.java new file mode 100644 index 0000000000..bb63fcda63 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/subpackage/ClassTwoUnitTest.java @@ -0,0 +1,11 @@ +package com.baeldung.testsuite.subpackage; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ClassTwoUnitTest { + @Test + public void whenTrue_thenTrue() { + Assertions.assertTrue(true); + } +} diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitClassNamePatternsSuite.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitClassNamePatternsSuite.java new file mode 100644 index 0000000000..aa17e26069 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitClassNamePatternsSuite.java @@ -0,0 +1,14 @@ +package com.baeldung.testsuite.suites; + +import org.junit.platform.suite.api.ExcludeClassNamePatterns; +import org.junit.platform.suite.api.IncludeClassNamePatterns; +import org.junit.platform.suite.api.SelectPackages; +import org.junit.platform.suite.api.Suite; + +@Suite +@SelectPackages("com.baeldung.testsuite") +@IncludeClassNamePatterns("com.baeldung.testsuite.Class.*UnitTest") +@ExcludeClassNamePatterns("com.baeldung.testsuite.ClassTwoUnitTest") +public class JUnitClassNamePatternsSuite { + // runs ClassOneUnitTest and ClassThreeUnitTest +} \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitExcludePackagesSuite.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitExcludePackagesSuite.java new file mode 100644 index 0000000000..47cd993f8a --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitExcludePackagesSuite.java @@ -0,0 +1,12 @@ +package com.baeldung.testsuite.suites; + +import org.junit.platform.suite.api.ExcludePackages; +import org.junit.platform.suite.api.SelectPackages; +import org.junit.platform.suite.api.Suite; + +@Suite +@SelectPackages("com.baeldung.testsuite") +@ExcludePackages("com.baeldung.testsuite.subpackage") +public class JUnitExcludePackagesSuite { + // runs ClassOneUnitTest and ClassThreeUnitTest +} \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitRunWithSuite.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitRunWithSuite.java new file mode 100644 index 0000000000..ad098fb305 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitRunWithSuite.java @@ -0,0 +1,16 @@ +package com.baeldung.testsuite.suites; + +import com.baeldung.testsuite.ClassOneUnitTest; +import com.baeldung.testsuite.subpackage.ClassTwoUnitTest; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.SuiteDisplayName; +import org.junit.runner.RunWith; + +@RunWith(JUnitPlatform.class) +@SuiteDisplayName("My Test Suite") +@SelectClasses({ClassOneUnitTest.class, ClassTwoUnitTest.class}) +public class JUnitRunWithSuite { + // runs ClassOneUnitTest and ClassTwoUnitTest + // equivalent to JUnitSelectClassesSuite +} \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectClassesSuite.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectClassesSuite.java new file mode 100644 index 0000000000..dc2b78ac53 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectClassesSuite.java @@ -0,0 +1,14 @@ +package com.baeldung.testsuite.suites; + +import com.baeldung.testsuite.ClassOneUnitTest; +import com.baeldung.testsuite.subpackage.ClassTwoUnitTest; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; +import org.junit.platform.suite.api.SuiteDisplayName; + +@Suite +@SuiteDisplayName("My Test Suite") +@SelectClasses({ClassOneUnitTest.class, ClassTwoUnitTest.class}) +public class JUnitSelectClassesSuite { + // runs ClassOneUnitTest and ClassTwoUnitTest +} \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectPackagesSuite.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectPackagesSuite.java new file mode 100644 index 0000000000..26562a18d7 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectPackagesSuite.java @@ -0,0 +1,10 @@ +package com.baeldung.testsuite.suites; + +import org.junit.platform.suite.api.SelectPackages; +import org.junit.platform.suite.api.Suite; + +@Suite +@SelectPackages({"com.baeldung.testsuite", "com.baeldung.testsuitetwo"}) +public class JUnitSelectPackagesSuite { + // runs ClassOneUnitTest, ClassTwoUnitTest and ClassThreeUnitTest +} \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitTestExcludeTagsSuite.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitTestExcludeTagsSuite.java new file mode 100644 index 0000000000..5ae32fc0b5 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitTestExcludeTagsSuite.java @@ -0,0 +1,12 @@ +package com.baeldung.testsuite.suites; + +import org.junit.platform.suite.api.ExcludeTags; +import org.junit.platform.suite.api.SelectPackages; +import org.junit.platform.suite.api.Suite; + +@Suite +@SelectPackages("com.baeldung.testsuite") +@ExcludeTags("slow") +public class JUnitTestExcludeTagsSuite { + // runs ClassOneUnitTest, ClassTwoUnitTest +} \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitTestIncludePackagesSuite.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitTestIncludePackagesSuite.java new file mode 100644 index 0000000000..b5442aff35 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitTestIncludePackagesSuite.java @@ -0,0 +1,12 @@ +package com.baeldung.testsuite.suites; + +import org.junit.platform.suite.api.IncludePackages; +import org.junit.platform.suite.api.SelectPackages; +import org.junit.platform.suite.api.Suite; + +@Suite +@SelectPackages("com.baeldung.testsuite") +@IncludePackages("com.baeldung.testsuite.subpackage") +public class JUnitTestIncludePackagesSuite { + // runs ClassTwoUnitTest +} \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitTestIncludeTagsSuite.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitTestIncludeTagsSuite.java new file mode 100644 index 0000000000..1cfce4bd7a --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitTestIncludeTagsSuite.java @@ -0,0 +1,12 @@ +package com.baeldung.testsuite.suites; + +import org.junit.platform.suite.api.IncludeTags; +import org.junit.platform.suite.api.SelectPackages; +import org.junit.platform.suite.api.Suite; + +@Suite +@SelectPackages("com.baeldung.testsuite") +@IncludeTags("slow") +public class JUnitTestIncludeTagsSuite { + // runs ClassTwoUnitTest +} \ No newline at end of file diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/extensions/tempdir/TemporaryDirectoryWithCleanupUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/extensions/tempdir/TemporaryDirectoryWithCleanupUnitTest.java new file mode 100644 index 0000000000..739212ec04 --- /dev/null +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/extensions/tempdir/TemporaryDirectoryWithCleanupUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.extensions.tempdir; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.io.TempDir; + +import java.nio.file.Path; + +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.io.CleanupMode.NEVER; + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class TemporaryDirectoryWithCleanupUnitTest { + + private Path theTempDirToBeChecked = null; + + @Test + @Order(1) + void whenTestMethodWithTempDirNeverCleanup_thenSetInstanceVariable(@TempDir(cleanup = NEVER) Path tempDir) { + theTempDirToBeChecked = tempDir; + System.out.println(tempDir.toFile().getAbsolutePath()); + } + + @Test + @Order(2) + void whenTestMethodWithTempDirNeverCleanup_thenTempDirShouldNotBeRemoved() { + assertNotNull(theTempDirToBeChecked); + assertTrue(theTempDirToBeChecked.toFile().isDirectory()); + } + +} \ No newline at end of file diff --git a/testing-modules/junit5-annotations/README.md b/testing-modules/junit5-annotations/README.md index 49d596607c..53e409151b 100644 --- a/testing-modules/junit5-annotations/README.md +++ b/testing-modules/junit5-annotations/README.md @@ -9,3 +9,4 @@ This module contains articles about JUnit 5 Annotations - [Guide to JUnit 5 Parameterized Tests](https://www.baeldung.com/parameterized-tests-junit-5) - [Writing Templates for Test Cases Using JUnit 5](https://www.baeldung.com/junit5-test-templates) - [JUnit 5 @Nested Test Classes](https://www.baeldung.com/junit-5-nested-test-classes) +- [A Guide to @Timeout Annotation in JUnit 5](https://www.baeldung.com/java-junit-5-timeout-annotation) diff --git a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/conditional/ConditionalAnnotationsUnitTest.java b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/conditional/ConditionalAnnotationsUnitTest.java index 0d4013116f..f4d0807dc3 100644 --- a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/conditional/ConditionalAnnotationsUnitTest.java +++ b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/conditional/ConditionalAnnotationsUnitTest.java @@ -2,18 +2,7 @@ package com.baeldung.junit5.conditional; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.DisabledForJreRange; -import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable; -import org.junit.jupiter.api.condition.DisabledIfSystemProperty; -import org.junit.jupiter.api.condition.DisabledOnJre; -import org.junit.jupiter.api.condition.DisabledOnOs; -import org.junit.jupiter.api.condition.EnabledForJreRange; -import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; -import org.junit.jupiter.api.condition.EnabledIfSystemProperty; -import org.junit.jupiter.api.condition.EnabledOnJre; -import org.junit.jupiter.api.condition.EnabledOnOs; -import org.junit.jupiter.api.condition.JRE; -import org.junit.jupiter.api.condition.OS; +import org.junit.jupiter.api.condition.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,6 +33,18 @@ public class ConditionalAnnotationsUnitTest { LOGGER.debug("runs with java 10 and 11"); } + @Test + @EnabledInNativeImage + void shouldOnlyRunWithinNativeImage() { + LOGGER.debug("Should run only within native images."); + } + + @Test + @DisabledInNativeImage + void shouldNeverRunWithinNativeImage() { + LOGGER.debug("Shouldn't run within native images."); + } + @Test @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_13) public void shouldOnlyRunOnJava8UntilJava13() { diff --git a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/timeout/TimeoutUnitTest.java b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/timeout/TimeoutUnitTest.java new file mode 100644 index 0000000000..b952dcf09f --- /dev/null +++ b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/timeout/TimeoutUnitTest.java @@ -0,0 +1,79 @@ +package com.baeldung.junit5.timeout; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.concurrent.TimeUnit; + + +@Timeout(5) +class TimeoutUnitTest { + + @Test + @Timeout(1) + void shouldFailAfterOneSecond() { + slowMethod(); + } + + @Test + @Timeout(value = 5, unit = TimeUnit.MINUTES, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) + void shouldUseADifferentThread() { + System.out.println(Thread.currentThread().getName()); + slowMethod(); + } + + @Test + void shouldFailAfterDefaultTimeoutOfFiveSeconds() { + slowMethod(); + } + + @Test + @Timeout(value = 2, unit = TimeUnit.MINUTES) + void shouldFailAfterTwoMinutes() { + slowMethod(); + } + + @Timeout(1) + @ParameterizedTest + @ValueSource(ints = {1, 2, 3, 4, 5}) + void eachTestShouldFailAfterOneSecond(int input) { + slowMethod(); + } + + @Nested + class NestedClassWithoutTimeout { + @Test + void shouldFailAfterParentsDefaultTimeoutOfFiveSeconds() { + slowMethod(); + } + } + + @Nested + @Timeout(3) + class NestedClassWithTimeout { + + @Test + void shouldFailAfterNestedClassTimeoutOfThreeSeconds() { + slowMethod(); + } + + @Test + @Timeout(1) + void shouldFailAfterOneSecond() { + slowMethod(); + } + } + + private void slowMethod() { + try { +// Thread.sleep(10_000); +// just for demonstration purposes +// tests cannot fail on the pipeline, bue we need failing examples in the article + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/testing-modules/mockito-simple/pom.xml b/testing-modules/mockito-simple/pom.xml index 3bfca2db2a..30928cfe35 100644 --- a/testing-modules/mockito-simple/pom.xml +++ b/testing-modules/mockito-simple/pom.xml @@ -55,9 +55,8 @@ - 5.3.20 - - 4.6.1 + 6.0.8 + 5.3.1 \ No newline at end of file diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/domain/service/MessageService.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/domain/service/MessageService.java deleted file mode 100644 index d156c59571..0000000000 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/domain/service/MessageService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.domain.service; - -import com.baeldung.domain.model.Message; -import org.springframework.stereotype.Service; - -@Service -public class MessageService { - - public Message deliverMessage (Message message) { - - return message; - } -} diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/repository/MailClient.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/repository/MailClient.java deleted file mode 100644 index d10169ef7a..0000000000 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/repository/MailClient.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.baeldung.junit5.mockito.repository; - -import com.baeldung.junit5.mockito.User; - -public interface MailClient { - - void sendUserRegistrationMail(User user); - -} diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/service/UserService.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/service/UserService.java deleted file mode 100644 index 326d019b4a..0000000000 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/service/UserService.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.baeldung.junit5.mockito.service; - -import com.baeldung.junit5.mockito.User; - -public interface UserService { - - User register(User user); - -} diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/AuthenticationStatus.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/AuthenticationStatus.java index 8307b4323b..0ba8a70021 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/AuthenticationStatus.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/AuthenticationStatus.java @@ -1,7 +1,5 @@ package com.baeldung.mockito.argumentcaptor; public enum AuthenticationStatus { - AUTHENTICATED, - NOT_AUTHENTICATED, - ERROR + AUTHENTICATED, NOT_AUTHENTICATED, ERROR } diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/Credentials.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/Credentials.java index d5d60bb6fc..598c7c93fa 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/Credentials.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/Credentials.java @@ -10,5 +10,16 @@ public class Credentials { this.password = password; this.key = key; } -} + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String getKey() { + return key; + } +} diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/Format.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/Format.java index 4c10375159..50363d7c17 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/Format.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/Format.java @@ -1,6 +1,5 @@ package com.baeldung.mockito.argumentcaptor; public enum Format { - TEXT_ONLY, - HTML + TEXT_ONLY, HTML } diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/ServiceStatus.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/ServiceStatus.java index 65def5af64..3951174b30 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/ServiceStatus.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentcaptor/ServiceStatus.java @@ -1,7 +1,5 @@ package com.baeldung.mockito.argumentcaptor; public enum ServiceStatus { - UP, - DOWN, - AUTHENTICATED + UP, DOWN, AUTHENTICATED } diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/app/api/Flower.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/Flower.java similarity index 90% rename from testing-modules/mockito-simple/src/main/java/com/baeldung/app/api/Flower.java rename to testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/Flower.java index dc1c36e3ff..8bfd0d1b02 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/app/api/Flower.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/Flower.java @@ -1,4 +1,4 @@ -package com.baeldung.app.api; +package com.baeldung.mockito.argumentmatchers; public class Flower { diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/domain/model/Message.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/Message.java similarity index 94% rename from testing-modules/mockito-simple/src/main/java/com/baeldung/domain/model/Message.java rename to testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/Message.java index a516d5619b..60ddc5ac04 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/domain/model/Message.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/Message.java @@ -1,4 +1,4 @@ -package com.baeldung.domain.model; +package com.baeldung.mockito.argumentmatchers; import java.util.Date; import java.util.UUID; diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/app/api/MessageDTO.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/MessageDTO.java similarity index 90% rename from testing-modules/mockito-simple/src/main/java/com/baeldung/app/api/MessageDTO.java rename to testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/MessageDTO.java index 1d9da244b0..7dce0ab75b 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/app/api/MessageDTO.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/MessageDTO.java @@ -1,6 +1,7 @@ -package com.baeldung.app.api; +package com.baeldung.mockito.argumentmatchers; public class MessageDTO { + private String from; private String to; private String text; diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/app/rest/FlowerController.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/controller/FlowerController.java similarity index 67% rename from testing-modules/mockito-simple/src/main/java/com/baeldung/app/rest/FlowerController.java rename to testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/controller/FlowerController.java index 10f602088c..e0c7cfb62e 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/app/rest/FlowerController.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/controller/FlowerController.java @@ -1,13 +1,14 @@ -package com.baeldung.app.rest; +package com.baeldung.mockito.argumentmatchers.controller; -import com.baeldung.app.api.Flower; -import com.baeldung.domain.service.FlowerService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import com.baeldung.mockito.argumentmatchers.Flower; +import com.baeldung.mockito.argumentmatchers.service.FlowerService; + @Controller @RequestMapping("/flowers") public class FlowerController { @@ -16,12 +17,12 @@ public class FlowerController { private FlowerService flowerService; @PostMapping("/isAFlower") - public String isAFlower (@RequestBody String flower) { + public String isAFlower(@RequestBody String flower) { return flowerService.analyze(flower); } @PostMapping("/isABigFlower") - public Boolean isABigFlower (@RequestBody Flower flower) { + public Boolean isABigFlower(@RequestBody Flower flower) { return flowerService.isABigFlower(flower.getName(), flower.getPetals()); } } diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/app/rest/MessageController.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/controller/MessageController.java similarity index 73% rename from testing-modules/mockito-simple/src/main/java/com/baeldung/app/rest/MessageController.java rename to testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/controller/MessageController.java index 6911197197..4a6cb3f5d6 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/app/rest/MessageController.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/controller/MessageController.java @@ -1,14 +1,15 @@ -package com.baeldung.app.rest; +package com.baeldung.mockito.argumentmatchers.controller; -import com.baeldung.app.api.MessageDTO; -import com.baeldung.domain.model.Message; -import com.baeldung.domain.service.MessageService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import com.baeldung.mockito.argumentmatchers.Message; +import com.baeldung.mockito.argumentmatchers.MessageDTO; +import com.baeldung.mockito.argumentmatchers.service.MessageService; + import java.time.Instant; import java.util.Date; import java.util.UUID; @@ -21,7 +22,7 @@ public class MessageController { private MessageService messageService; @PostMapping - public Message createMessage (@RequestBody MessageDTO messageDTO) { + public Message createMessage(@RequestBody MessageDTO messageDTO) { Message message = new Message(); message.setText(messageDTO.getText()); message.setFrom(messageDTO.getFrom()); diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/domain/service/FlowerService.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/service/FlowerService.java similarity index 75% rename from testing-modules/mockito-simple/src/main/java/com/baeldung/domain/service/FlowerService.java rename to testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/service/FlowerService.java index 74a9308890..f654638fd3 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/domain/service/FlowerService.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/service/FlowerService.java @@ -1,4 +1,4 @@ -package com.baeldung.domain.service; +package com.baeldung.mockito.argumentmatchers.service; import org.springframework.stereotype.Service; @@ -11,15 +11,15 @@ public class FlowerService { private List flowers = Arrays.asList("Poppy", "Ageratum", "Carnation", "Diascia", "Lantana"); public String analyze(String name) { - if(flowers.contains(name)) { + if (flowers.contains(name)) { return "flower"; } return null; } public boolean isABigFlower(String name, int petals) { - if(flowers.contains(name)) { - if(petals > 10) { + if (flowers.contains(name)) { + if (petals > 10) { return true; } } diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/service/MessageService.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/service/MessageService.java new file mode 100644 index 0000000000..3f9265db0e --- /dev/null +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/argumentmatchers/service/MessageService.java @@ -0,0 +1,14 @@ +package com.baeldung.mockito.argumentmatchers.service; + +import org.springframework.stereotype.Service; + +import com.baeldung.mockito.argumentmatchers.Message; + +@Service +public class MessageService { + + public Message deliverMessage(Message message) { + + return message; + } +} diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/User.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/User.java similarity index 92% rename from testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/User.java rename to testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/User.java index 4276fd62b9..4457d59b02 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/User.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/User.java @@ -1,34 +1,39 @@ -package com.baeldung.junit5.mockito; +package com.baeldung.mockito.junit5; public class User { - + private Integer id; private String name; private int age; - + public User() { } - + public User(String name, int age) { this.name = name; this.age = age; } - + public Integer getId() { return id; } + public void setId(Integer id) { this.id = id; } + public String getName() { return name; } + public void setName(String name) { this.name = name; } + public int getAge() { return age; } + public void setAge(int age) { this.age = age; } diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/repository/MailClient.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/repository/MailClient.java new file mode 100644 index 0000000000..258de77cd5 --- /dev/null +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/repository/MailClient.java @@ -0,0 +1,9 @@ +package com.baeldung.mockito.junit5.repository; + +import com.baeldung.mockito.junit5.User; + +public interface MailClient { + + void sendUserRegistrationMail(User user); + +} diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/repository/SettingRepository.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/repository/SettingRepository.java similarity index 65% rename from testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/repository/SettingRepository.java rename to testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/repository/SettingRepository.java index 23ae8fa35c..094be12770 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/repository/SettingRepository.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/repository/SettingRepository.java @@ -1,7 +1,7 @@ -package com.baeldung.junit5.mockito.repository; +package com.baeldung.mockito.junit5.repository; public interface SettingRepository { - + int getUserMinAge(); int getUserNameMinLength(); diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/repository/UserRepository.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/repository/UserRepository.java similarity index 56% rename from testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/repository/UserRepository.java rename to testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/repository/UserRepository.java index e1b84c774b..9bc1b0d38c 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/repository/UserRepository.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/repository/UserRepository.java @@ -1,10 +1,11 @@ -package com.baeldung.junit5.mockito.repository; +package com.baeldung.mockito.junit5.repository; -import com.baeldung.junit5.mockito.User; +import com.baeldung.mockito.junit5.User; public interface UserRepository { User insert(User user); + boolean isUsernameAlreadyExists(String userName); - + } diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/service/DefaultUserService.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/service/DefaultUserService.java similarity index 65% rename from testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/service/DefaultUserService.java rename to testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/service/DefaultUserService.java index 888edbd710..bad4e46682 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/service/DefaultUserService.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/service/DefaultUserService.java @@ -1,16 +1,16 @@ -package com.baeldung.junit5.mockito.service; +package com.baeldung.mockito.junit5.service; -import com.baeldung.junit5.mockito.User; -import com.baeldung.junit5.mockito.repository.MailClient; -import com.baeldung.junit5.mockito.repository.SettingRepository; -import com.baeldung.junit5.mockito.repository.UserRepository; +import com.baeldung.mockito.junit5.User; +import com.baeldung.mockito.junit5.repository.MailClient; +import com.baeldung.mockito.junit5.repository.SettingRepository; +import com.baeldung.mockito.junit5.repository.UserRepository; public class DefaultUserService implements UserService { - + private UserRepository userRepository; private SettingRepository settingRepository; private MailClient mailClient; - + public DefaultUserService(UserRepository userRepository, SettingRepository settingRepository, MailClient mailClient) { this.userRepository = userRepository; this.settingRepository = settingRepository; @@ -26,19 +26,20 @@ public class DefaultUserService implements UserService { } private void validate(User user) { - if(user.getName() == null) { + if (user.getName() == null) { throw new RuntimeException(Errors.USER_NAME_REQUIRED); } - if(user.getName().length() < settingRepository.getUserNameMinLength()) { + if (user.getName() + .length() < settingRepository.getUserNameMinLength()) { throw new RuntimeException(Errors.USER_NAME_SHORT); } - - if(user.getAge() < settingRepository.getUserMinAge()) { + + if (user.getAge() < settingRepository.getUserMinAge()) { throw new RuntimeException(Errors.USER_AGE_YOUNG); } - - if(userRepository.isUsernameAlreadyExists(user.getName())) { + + if (userRepository.isUsernameAlreadyExists(user.getName())) { throw new RuntimeException(Errors.USER_NAME_DUPLICATE); } } diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/service/Errors.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/service/Errors.java similarity index 86% rename from testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/service/Errors.java rename to testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/service/Errors.java index 28283754a3..8a6882124a 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/junit5/mockito/service/Errors.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/service/Errors.java @@ -1,4 +1,4 @@ -package com.baeldung.junit5.mockito.service; +package com.baeldung.mockito.junit5.service; public class Errors { @@ -6,5 +6,5 @@ public class Errors { public static final String USER_NAME_SHORT = "user.name.short"; public static final String USER_AGE_YOUNG = "user.age.young"; public static final String USER_NAME_DUPLICATE = "user.name.duplicate"; - + } diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/service/UserService.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/service/UserService.java new file mode 100644 index 0000000000..fe1fbe4f13 --- /dev/null +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/junit5/service/UserService.java @@ -0,0 +1,9 @@ +package com.baeldung.mockito.junit5.service; + +import com.baeldung.mockito.junit5.User; + +public interface UserService { + + User register(User user); + +} diff --git a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/mockedstatic/StaticUtils.java b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/mockedstatic/StaticUtils.java index 2e2f5ead33..5b2e57ae26 100644 --- a/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/mockedstatic/StaticUtils.java +++ b/testing-modules/mockito-simple/src/main/java/com/baeldung/mockito/mockedstatic/StaticUtils.java @@ -18,5 +18,4 @@ public class StaticUtils { public static String name() { return "Baeldung"; } - } diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/app/rest/FlowerControllerUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/app/rest/FlowerControllerUnitTest.java deleted file mode 100644 index d611cd9e45..0000000000 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/app/rest/FlowerControllerUnitTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.baeldung.app.rest; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.AdditionalMatchers.or; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.endsWith; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.exceptions.misusing.InvalidUseOfMatchersException; -import org.mockito.junit.jupiter.MockitoExtension; - -import com.baeldung.app.api.Flower; -import com.baeldung.domain.service.FlowerService; - -@ExtendWith(MockitoExtension.class) -class FlowerControllerUnitTest { - - @InjectMocks - private FlowerController flowerController; - - @Mock - private FlowerService flowerService; - - @Test - void givenPoppyFlower_whenUsingDoReturn_thenCorrect() { - doReturn("Flower").when(flowerService).analyze("poppy"); - - String response = flowerController.isAFlower("poppy"); - assertThat(response).isEqualTo("Flower"); - } - - @Test - void givenAnyString_whenUsingArgumentMatcher_thenCorrect() { - when(flowerService.analyze(anyString())).thenReturn("Flower"); - - String response = flowerController.isAFlower("violetta"); - assertThat(response).isEqualTo("Flower"); - } - - @Test - void whenIncorrectMatchers_thenThrowsError() { - assertThrows(InvalidUseOfMatchersException.class, () -> { - when(flowerService.isABigFlower("poppy", anyInt())).thenReturn(true); - }); - - Flower flower = new Flower("poppy", 15); - - Boolean response = flowerController.isABigFlower(flower); - assertThat(response).isFalse(); - } - - @Test - void whenCorrectMatchers_thenCorrect() { - when(flowerService.isABigFlower(eq("poppy"), anyInt())).thenReturn(true); - - Flower flower = new Flower("poppy", 15); - - Boolean response = flowerController.isABigFlower(flower); - assertThat(response).isTrue(); - } - - @Test - void whenUsingMatchersAsReturnValue_thenThrowsError() { - flowerController.isAFlower("poppy"); - - String orMatcher = or(eq("poppy"), endsWith("y")); - assertThrows(InvalidUseOfMatchersException.class, () -> { - verify(flowerService).analyze(orMatcher); - }); - } - - @Test - void whenUsingMatchersAsOngoingStubbing_thenCorrect1() { - flowerController.isAFlower("poppy"); - - verify(flowerService).analyze(or(eq("poppy"), endsWith("y"))); - } - - @Test - void whenUsingMatchersAsOngoingStubbing_thenCorrect2() { - flowerController.isAFlower("lily"); - - verify(flowerService).analyze(or(eq("poppy"), endsWith("y"))); - } -} diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/domain/util/MessageMatcher.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/domain/util/MessageMatcher.java deleted file mode 100644 index 51db07fde7..0000000000 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/domain/util/MessageMatcher.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.baeldung.domain.util; - -import com.baeldung.domain.model.Message; -import org.mockito.ArgumentMatcher; - -public class MessageMatcher implements ArgumentMatcher { - - private Message left; - - public MessageMatcher(Message message) { - this.left = message; - } - - @Override - public boolean matches(Message right) { - return left.getFrom().equals(right.getFrom()) && - left.getTo().equals(right.getTo()) && - left.getText().equals(right.getText()) && - right.getDate() != null && - right.getId() != null; - } -} \ No newline at end of file diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/FinalList.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/FinalList.java index 27b7534978..c81e0bb79b 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/FinalList.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/FinalList.java @@ -2,9 +2,9 @@ package com.baeldung.mockito; public final class FinalList extends MyList { - @Override - public int size() { - return 1; - } + @Override + public int size() { + return 1; + } } diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockFinalsUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockFinalsUnitTest.java deleted file mode 100644 index a4b2bd03b4..0000000000 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockFinalsUnitTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.baeldung.mockito; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.junit.jupiter.api.Test; - -class MockFinalsUnitTest { - - @Test - void whenMockFinalMethodMockWorks() { - - MyList myList = new MyList(); - - MyList mock = mock(MyList.class); - when(mock.finalMethod()).thenReturn(1); - - assertThat(mock.finalMethod()).isNotEqualTo(myList.finalMethod()); - } - - @Test - public void whenMockFinalClassMockWorks() { - - FinalList finalList = new FinalList(); - - FinalList mock = mock(FinalList.class); - when(mock.size()).thenReturn(2); - - assertThat(mock.size()).isNotEqualTo(finalList.size()); - } -} diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MyDictionary.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MyDictionary.java index 92a4498696..bb7b076ea6 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MyDictionary.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MyDictionary.java @@ -3,15 +3,15 @@ package com.baeldung.mockito; import java.util.HashMap; import java.util.Map; -class MyDictionary { +public class MyDictionary { private Map wordMap; - MyDictionary() { + public MyDictionary() { wordMap = new HashMap<>(); } - MyDictionary(Map wordMap) { + public MyDictionary(Map wordMap) { this.wordMap = wordMap; } @@ -19,7 +19,7 @@ class MyDictionary { wordMap.put(word, meaning); } - String getMeaning(final String word) { + public String getMeaning(final String word) { return wordMap.get(word); } } diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoAnnotationUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/annotations/MockitoAnnotationUnitTest.java similarity index 89% rename from testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoAnnotationUnitTest.java rename to testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/annotations/MockitoAnnotationUnitTest.java index acfd87e047..20c70ce27b 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoAnnotationUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/annotations/MockitoAnnotationUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.mockito; +package com.baeldung.mockito.annotations; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.doReturn; @@ -20,6 +20,8 @@ import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; +import com.baeldung.mockito.MyDictionary; + @ExtendWith(MockitoExtension.class) class MockitoAnnotationUnitTest { @@ -29,19 +31,20 @@ class MockitoAnnotationUnitTest { @Spy private List spiedList = new ArrayList<>(); - // Use either @RunWith(MockitoJUnitRunner.class) or manually openMocks in the @Before method + // Use either @ExtendWith(MockitoExtension.class) or manually openMocks in the @BeforeEach method /* - @Before + @BeforeEach public void init() { - MockitoAnnotations.openMocks(this); + MockitoAnnotations.openMocks(this); } */ - + // tests @Test void whenNotUseMockAnnotation_thenCorrect() { - final List mockList = mock(List.class); + final List mockList = mock(ArrayList.class); + mockList.add("one"); verify(mockList).add("one"); assertEquals(0, mockList.size()); @@ -63,6 +66,7 @@ class MockitoAnnotationUnitTest { @Test void whenNotUseSpyAnnotation_thenCorrect() { final List spyList = spy(new ArrayList()); + spyList.add("one"); spyList.add("two"); @@ -88,11 +92,12 @@ class MockitoAnnotationUnitTest { doReturn(100).when(spiedList).size(); assertEquals(100, spiedList.size()); } - + @Test void whenNotUseCaptorAnnotation_thenCorrect() { final List mockList = mock(List.class); final ArgumentCaptor arg = ArgumentCaptor.forClass(String.class); + mockList.add("one"); verify(mockList).add(arg.capture()); @@ -100,8 +105,7 @@ class MockitoAnnotationUnitTest { } @Captor - private - ArgumentCaptor argCaptor; + private ArgumentCaptor argCaptor; @Test void whenUseCaptorAnnotation_thenTheSame() { @@ -123,5 +127,4 @@ class MockitoAnnotationUnitTest { assertEquals("aMeaning", dic.getMeaning("aWord")); } - } diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoAnnotationsInitWithMockitoJUnitRuleUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/annotations/MockitoAnnotationsInitWithMockitoJUnitRuleUnitTest.java similarity index 93% rename from testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoAnnotationsInitWithMockitoJUnitRuleUnitTest.java rename to testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/annotations/MockitoAnnotationsInitWithMockitoJUnitRuleUnitTest.java index 512f538a58..b8dadc6deb 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoAnnotationsInitWithMockitoJUnitRuleUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/annotations/MockitoAnnotationsInitWithMockitoJUnitRuleUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.mockito; +package com.baeldung.mockito.annotations; import org.junit.Rule; import org.junit.Test; @@ -6,13 +6,11 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; - import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; - public class MockitoAnnotationsInitWithMockitoJUnitRuleUnitTest { @Rule diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoAnnotationsInjectIntoSpyUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/annotations/MockitoAnnotationsInjectIntoSpyUnitTest.java similarity index 92% rename from testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoAnnotationsInjectIntoSpyUnitTest.java rename to testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/annotations/MockitoAnnotationsInjectIntoSpyUnitTest.java index 89a253c855..91dd30a20b 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoAnnotationsInjectIntoSpyUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/annotations/MockitoAnnotationsInjectIntoSpyUnitTest.java @@ -1,11 +1,12 @@ -package com.baeldung.mockito; - +package com.baeldung.mockito.annotations; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.openMocks; +import java.util.Map; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -13,8 +14,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.util.Map; - +import com.baeldung.mockito.MyDictionary; @ExtendWith(MockitoExtension.class) class MockitoAnnotationsInjectIntoSpyUnitTest { diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoAnnotationsUninitializedUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/annotations/MockitoAnnotationsUninitializedUnitTest.java similarity index 91% rename from testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoAnnotationsUninitializedUnitTest.java rename to testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/annotations/MockitoAnnotationsUninitializedUnitTest.java index 10b0aa6626..7c317c6aca 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoAnnotationsUninitializedUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/annotations/MockitoAnnotationsUninitializedUnitTest.java @@ -1,14 +1,13 @@ -package com.baeldung.mockito; - +package com.baeldung.mockito.annotations; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.when; +import java.util.List; + import org.junit.jupiter.api.Test; import org.mockito.Mock; -import java.util.List; - class MockitoAnnotationsUninitializedUnitTest { @Mock diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentmatchers/FlowerControllerUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentmatchers/FlowerControllerUnitTest.java new file mode 100644 index 0000000000..e9dcc4a774 --- /dev/null +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentmatchers/FlowerControllerUnitTest.java @@ -0,0 +1,80 @@ +package com.baeldung.mockito.argumentmatchers; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.AdditionalMatchers.or; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.endsWith; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.exceptions.misusing.InvalidUseOfMatchersException; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.baeldung.mockito.argumentmatchers.controller.FlowerController; +import com.baeldung.mockito.argumentmatchers.service.FlowerService; + +@ExtendWith(MockitoExtension.class) +class FlowerControllerUnitTest { + + @InjectMocks + private FlowerController flowerController; + + @Mock + private FlowerService flowerService; + + @Test + void givenPoppyFlower_whenUsingDoReturn_thenCorrect() { + doReturn("Flower").when(flowerService).analyze("poppy"); + + String response = flowerController.isAFlower("poppy"); + assertThat(response).isEqualTo("Flower"); + } + + @Test + void givenAnyFlower_whenUsingArgumentMatcher_thenCorrect() { + when(flowerService.analyze(anyString())).thenReturn("Flower"); + + String response = flowerController.isAFlower("violetta"); + assertThat(response).isEqualTo("Flower"); + } + + @Test + void givenIncorrectMatchers_whenUsingArgumentMatchers_thenThrowsError() { + assertThrows(InvalidUseOfMatchersException.class, + () -> when(flowerService.isABigFlower("poppy", anyInt())).thenReturn(true)); + } + + @Test + void givenCorrectMatchers_whenUsingArgumentMatchers_thenCorrect() { + when(flowerService.isABigFlower(eq("poppy"), anyInt())).thenReturn(true); + + Flower flower = new Flower("poppy", 15); + + Boolean response = flowerController.isABigFlower(flower); + assertThat(response).isTrue(); + } + + @Test + void givenMatchersOutsideofStubbing_whenUsingMatchersAsReturnValue_thenThrowsError() { + flowerController.isAFlower("poppy"); + + String orMatcher = or(eq("poppy"), endsWith("y")); + assertThrows(InvalidUseOfMatchersException.class, + () -> verify(flowerService).analyze(orMatcher)); + } + + @Test + void givenMatchersAsOngoingStubbing_whenUsingMatchers_thenCorrect() { + flowerController.isAFlower("poppy"); + + verify(flowerService).analyze(or(eq("poppy"), endsWith("y"))); + } +} diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/app/rest/MessageControllerUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentmatchers/MessageControllerUnitTest.java similarity index 87% rename from testing-modules/mockito-simple/src/test/java/com/baeldung/app/rest/MessageControllerUnitTest.java rename to testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentmatchers/MessageControllerUnitTest.java index 84b5bf241e..89548c9a99 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/app/rest/MessageControllerUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentmatchers/MessageControllerUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.app.rest; +package com.baeldung.mockito.argumentmatchers; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; @@ -11,10 +11,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import com.baeldung.app.api.MessageDTO; -import com.baeldung.domain.model.Message; -import com.baeldung.domain.service.MessageService; -import com.baeldung.domain.util.MessageMatcher; +import com.baeldung.mockito.argumentmatchers.controller.MessageController; +import com.baeldung.mockito.argumentmatchers.service.MessageService; @ExtendWith(MockitoExtension.class) class MessageControllerUnitTest { diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentmatchers/MessageMatcher.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentmatchers/MessageMatcher.java new file mode 100644 index 0000000000..8834df6c38 --- /dev/null +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/argumentmatchers/MessageMatcher.java @@ -0,0 +1,20 @@ +package com.baeldung.mockito.argumentmatchers; + +import org.mockito.ArgumentMatcher; + +public class MessageMatcher implements ArgumentMatcher { + + private Message left; + + public MessageMatcher(Message message) { + this.left = message; + } + + @Override + public boolean matches(Message right) { + return left.getFrom().equals(right.getFrom()) && + left.getTo().equals(right.getTo()) && + left.getText().equals(right.getText()) && + right.getDate() != null && right.getId() != null; + } +} \ No newline at end of file diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoWhenThenExamplesUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/behaviour/MockitoWhenThenExamplesUnitTest.java similarity index 72% rename from testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoWhenThenExamplesUnitTest.java rename to testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/behaviour/MockitoWhenThenExamplesUnitTest.java index c570629ccd..c4551f43ec 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoWhenThenExamplesUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/behaviour/MockitoWhenThenExamplesUnitTest.java @@ -1,7 +1,8 @@ -package com.baeldung.mockito; +package com.baeldung.mockito.behaviour; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; @@ -14,11 +15,12 @@ import static org.mockito.Mockito.when; import org.junit.jupiter.api.Test; +import com.baeldung.mockito.MyList; class MockitoWhenThenExamplesUnitTest { @Test - final void whenMockReturnBehaviorIsConfigured_thenBehaviorIsVerified() { + final void whenSimpleReturnBehaviourConfigured_thenCorrect() { final MyList listMock = mock(MyList.class); when(listMock.add(anyString())).thenReturn(false); @@ -27,7 +29,7 @@ class MockitoWhenThenExamplesUnitTest { } @Test - final void whenMockReturnBehaviorIsConfigured2_thenBehaviorIsVerified() { + final void whenSimpleReturnBehaviourConfiguredAlternatively_thenCorrect() { final MyList listMock = mock(MyList.class); doReturn(false).when(listMock).add(anyString()); @@ -40,55 +42,50 @@ class MockitoWhenThenExamplesUnitTest { final MyList listMock = mock(MyList.class); when(listMock.add(anyString())).thenThrow(IllegalStateException.class); - assertThrows(IllegalStateException.class, () -> { - listMock.add(randomAlphabetic(6)); - }); - + assertThrows(IllegalStateException.class, () -> listMock.add(randomAlphabetic(6))); } @Test - final void givenBehaviorIsConfiguredToThrowExceptionOnSecondCall_whenCallingOnlyOnce_thenNoExceptionIsThrown() { - final MyList listMock = mock(MyList.class); - when(listMock.add(anyString())).thenReturn(false).thenThrow(IllegalStateException.class); - - listMock.add(randomAlphabetic(6)); - } - - @Test - final void whenMethodHasNoReturnType_whenConfiguringBehaviorOfMethod_thenPossible() { + final void givenMethodHasNoReturnType_whenCallingMethod_thenExceptionIsThrown() { final MyList listMock = mock(MyList.class); doThrow(NullPointerException.class).when(listMock).clear(); - assertThrows(NullPointerException.class, () -> { - listMock.clear(); - }); - + assertThrows(NullPointerException.class, () -> listMock.clear()); } @Test final void givenBehaviorIsConfiguredToThrowExceptionOnSecondCall_whenCallingTwice_thenExceptionIsThrown() { final MyList listMock = mock(MyList.class); - when(listMock.add(anyString())).thenReturn(false).thenThrow(IllegalStateException.class); + when(listMock.add(anyString())) + .thenReturn(false) + .thenThrow(IllegalStateException.class); assertThrows(IllegalStateException.class, () -> { listMock.add(randomAlphabetic(6)); listMock.add(randomAlphabetic(6)); }); - } @Test - final void givenSpy_whenConfiguringBehaviorOfSpy_thenCorrectlyConfigured() { + final void givenBehaviorIsConfiguredToThrowExceptionOnSecondCall_whenCallingOnlyOnce_thenNoExceptionIsThrown() { + final MyList listMock = mock(MyList.class); + when(listMock.add(anyString())) + .thenReturn(false) + .thenThrow(IllegalStateException.class); + + assertThatNoException().isThrownBy(() -> listMock.add(randomAlphabetic(6))); + } + + @Test + final void whenSpyBehaviourConfigured_thenCorrect() { final MyList instance = new MyList(); final MyList spy = spy(instance); doThrow(NullPointerException.class).when(spy).size(); - assertThrows(NullPointerException.class, () -> { - spy.size(); - }); + assertThrows(NullPointerException.class, () -> spy.size()); } - + @Test final void whenMockMethodCallIsConfiguredToCallTheRealMethod_thenRealMethodIsCalled() { final MyList listMock = mock(MyList.class); @@ -96,9 +93,9 @@ class MockitoWhenThenExamplesUnitTest { assertThat(listMock).hasSize(1); } - + @Test - final void whenMockMethodCallIsConfiguredWithCustomAnswer_thenRealMethodIsCalled() { + final void whenMockMethodCallIsConfiguredWithCustomAnswer_thenCustomerAnswerIsCalled() { final MyList listMock = mock(MyList.class); doAnswer(invocation -> "Always the same").when(listMock).get(anyInt()); diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoExceptionUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/exceptions/MockitoExceptionUnitTest.java similarity index 50% rename from testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoExceptionUnitTest.java rename to testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/exceptions/MockitoExceptionUnitTest.java index 843edd8d0a..112a6fd7b6 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoExceptionUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/exceptions/MockitoExceptionUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.mockito; +package com.baeldung.mockito.exceptions; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.anyString; @@ -6,66 +6,53 @@ import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; - import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; -@ExtendWith(MockitoExtension.class) +import com.baeldung.mockito.MyDictionary; + class MockitoExceptionUnitTest { @Test - void whenConfigNonVoidRetunMethodToThrowEx_thenExIsThrown() { + void givenNonVoidReturnType_whenUsingWhenThen_thenExceptionIsThrown() { MyDictionary dictMock = mock(MyDictionary.class); when(dictMock.getMeaning(anyString())).thenThrow(NullPointerException.class); - assertThrows(NullPointerException.class, () -> { - dictMock.getMeaning("word"); - }); + assertThrows(NullPointerException.class, () -> dictMock.getMeaning("word")); } @Test - void whenConfigVoidRetunMethodToThrowEx_thenExIsThrown() { + void givenVoidReturnType_whenUsingDoThrow_thenExceptionIsThrown() { MyDictionary dictMock = mock(MyDictionary.class); doThrow(IllegalStateException.class).when(dictMock) .add(anyString(), anyString()); - assertThrows(IllegalStateException.class, () -> { - dictMock.add("word", "meaning"); - }); + assertThrows(IllegalStateException.class, () -> dictMock.add("word", "meaning")); } @Test - void whenConfigNonVoidRetunMethodToThrowExWithNewExObj_thenExIsThrown() { + void givenNonVoidReturnType_whenUsingWhenThenAndExeceptionAsNewObject_thenExceptionIsThrown() { MyDictionary dictMock = mock(MyDictionary.class); when(dictMock.getMeaning(anyString())).thenThrow(new NullPointerException("Error occurred")); - assertThrows(NullPointerException.class, () -> { - dictMock.getMeaning("word"); - }); + assertThrows(NullPointerException.class, () -> dictMock.getMeaning("word")); } @Test - void whenConfigVoidRetunMethodToThrowExWithNewExObj_thenExIsThrown() { + void givenNonVoidReturnType_whenUsingDoThrowAndExeceptionAsNewObject_thenExceptionIsThrown() { MyDictionary dictMock = mock(MyDictionary.class); - doThrow(new IllegalStateException("Error occurred")).when(dictMock) - .add(anyString(), anyString()); - assertThrows(IllegalStateException.class, () -> { - dictMock.add("word", "meaning"); - }); + doThrow(new IllegalStateException("Error occurred")).when(dictMock).add(anyString(), anyString()); + + assertThrows(IllegalStateException.class, () -> dictMock.add("word", "meaning")); } - // ===== - @Test - void givenSpy_whenConfigNonVoidRetunMethodToThrowEx_thenExIsThrown() { + void givenSpyAndNonVoidReturnType_whenUsingWhenThen_thenExceptionIsThrown() { MyDictionary dict = new MyDictionary(); MyDictionary spy = Mockito.spy(dict); when(spy.getMeaning(anyString())).thenThrow(NullPointerException.class); - assertThrows(NullPointerException.class, () -> { - spy.getMeaning("word"); - }); + + assertThrows(NullPointerException.class, () -> spy.getMeaning("word")); } } diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/junit5/UserServiceUnitTest.java similarity index 88% rename from testing-modules/mockito-simple/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java rename to testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/junit5/UserServiceUnitTest.java index cc38d617b7..45eb42a00f 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/junit5/UserServiceUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.junit5.mockito; +package com.baeldung.mockito.junit5; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -18,12 +18,12 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.stubbing.Answer; -import com.baeldung.junit5.mockito.repository.MailClient; -import com.baeldung.junit5.mockito.repository.SettingRepository; -import com.baeldung.junit5.mockito.repository.UserRepository; -import com.baeldung.junit5.mockito.service.DefaultUserService; -import com.baeldung.junit5.mockito.service.Errors; -import com.baeldung.junit5.mockito.service.UserService; +import com.baeldung.mockito.junit5.repository.MailClient; +import com.baeldung.mockito.junit5.repository.SettingRepository; +import com.baeldung.mockito.junit5.repository.UserRepository; +import com.baeldung.mockito.junit5.service.DefaultUserService; +import com.baeldung.mockito.junit5.service.Errors; +import com.baeldung.mockito.junit5.service.UserService; @ExtendWith(MockitoExtension.class) class UserServiceUnitTest { @@ -43,11 +43,14 @@ class UserServiceUnitTest { @BeforeEach void init(@Mock SettingRepository settingRepository) { userService = new DefaultUserService(userRepository, settingRepository, mailClient); - lenient().when(settingRepository.getUserMinAge()) - .thenReturn(10); + + lenient().when(settingRepository.getUserMinAge()).thenReturn(10); + when(settingRepository.getUserNameMinLength()).thenReturn(4); + lenient().when(userRepository.isUsernameAlreadyExists(any(String.class))) .thenReturn(false); + this.settingRepository = settingRepository; } @@ -77,6 +80,8 @@ class UserServiceUnitTest { verify(mailClient).sendUserRegistrationMail(insertedUser); } + // additional tests + @Test void givenShortName_whenSaveUser_thenGiveShortUsernameError() { // Given diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockfinal/MockFinalsUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockfinal/MockFinalsUnitTest.java new file mode 100644 index 0000000000..6041ee1a9b --- /dev/null +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockfinal/MockFinalsUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.mockito.mockfinal; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.withSettings; + +import org.junit.jupiter.api.Test; +import org.mockito.MockMakers; + +import com.baeldung.mockito.FinalList; +import com.baeldung.mockito.MyList; + +class MockFinalsUnitTest { + + @Test + void whenMockFinalMethod_thenMockWorks() { + + MyList mock = mock(MyList.class); + when(mock.finalMethod()).thenReturn(1); + + assertThat(mock.finalMethod()).isNotZero(); + } + + @Test + void whenMockFinalClass_thenMockWorks() { + + FinalList mock = mock(FinalList.class); + when(mock.size()).thenReturn(2); + + assertThat(mock.size()).isNotEqualTo(1); + } + + @Test + public void whenMockFinalMethodMockWorks_withInlineMockMaker() { + MyList myList = new MyList(); + + MyList mock = mock(MyList.class, withSettings().mockMaker(MockMakers.INLINE)); + when(mock.finalMethod()).thenReturn(1); + + assertThat(mock.finalMethod()).isNotEqualTo(myList.finalMethod()); + } +} diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoMockUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockmethods/MockitoMockMethodsUnitTest.java similarity index 86% rename from testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoMockUnitTest.java rename to testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockmethods/MockitoMockMethodsUnitTest.java index 6e9167f0d0..696208c9ec 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoMockUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockmethods/MockitoMockMethodsUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.mockito; +package com.baeldung.mockito.mockmethods; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.assertj.core.api.Assertions.assertThat; @@ -16,36 +16,41 @@ import org.mockito.exceptions.verification.TooFewActualInvocations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -class MockitoMockUnitTest { +import com.baeldung.mockito.MyList; + +class MockitoMockMethodsUnitTest { @Test void whenUsingSimpleMock_thenCorrect() { MyList listMock = mock(MyList.class); when(listMock.add(anyString())).thenReturn(false); + boolean added = listMock.add(randomAlphabetic(6)); - verify(listMock).add(anyString()); assertThat(added).isFalse(); + verify(listMock).add(anyString()); } @Test - void whenUsingMockWithName_thenCorrect() { + void givenFewActualInvocationThanConfigured_whenUsingMockWithName_thenExceptionIsThrown() { MyList listMock = mock(MyList.class, "myMock"); + when(listMock.add(anyString())).thenReturn(false); listMock.add(randomAlphabetic(6)); assertThatThrownBy(() -> verify(listMock, times(2)).add(anyString())) - .isInstanceOf(TooFewActualInvocations.class) - .hasMessageContaining("myMock.add"); + .isInstanceOf(TooFewActualInvocations.class) + .hasMessageContaining("myMock.add"); } private static class CustomAnswer implements Answer { + @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { return false; } } - + @Test void whenUsingMockWithAnswer_thenCorrect() { MyList listMock = mock(MyList.class, new CustomAnswer()); @@ -59,6 +64,7 @@ class MockitoMockUnitTest { void whenUsingMockWithSettings_thenCorrect() { MockSettings customSettings = withSettings().defaultAnswer(new CustomAnswer()); MyList listMock = mock(MyList.class, customSettings); + boolean added = listMock.add(randomAlphabetic(6)); verify(listMock).add(anyString()); diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockedstatic/MockedStaticUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockstatic/MockStaticUnitTest.java similarity index 90% rename from testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockedstatic/MockedStaticUnitTest.java rename to testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockstatic/MockStaticUnitTest.java index 309f066a87..b9268f3c6a 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockedstatic/MockedStaticUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockstatic/MockStaticUnitTest.java @@ -1,14 +1,16 @@ -package com.baeldung.mockito.mockedstatic; +package com.baeldung.mockito.mockstatic; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; +import com.baeldung.mockito.mockedstatic.StaticUtils; + import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.mockStatic; import java.util.Arrays; -class MockedStaticUnitTest { +class MockStaticUnitTest { @Test void givenStaticMethodWithNoArgs_whenMocked_thenReturnsMockSuccessfully() { diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoMisusingMockOrSpyUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoMisusingMockOrSpyUnitTest.java index e1023c5e57..0a510ba6cb 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoMisusingMockOrSpyUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoMisusingMockOrSpyUnitTest.java @@ -18,14 +18,14 @@ class MockitoMisusingMockOrSpyUnitTest { List list = new ArrayList(); assertThatThrownBy(() -> doReturn(100).when(list).size()) - .isInstanceOf(NotAMockException.class) - .hasMessageContaining("Argument passed to when() is not a mock!"); + .isInstanceOf(NotAMockException.class) + .hasMessageContaining("Argument passed to when() is not a mock!"); } - + @Test void givenASpy_whenDoReturn_thenNoError() { final List spyList = spy(new ArrayList<>()); - + assertThatNoException().isThrownBy(() -> doReturn(100).when(spyList).size()); } } diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoSpyUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoSpyUnitTest.java index caef0c3b4b..400de07886 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoSpyUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/spy/MockitoSpyUnitTest.java @@ -16,10 +16,10 @@ import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -public class MockitoSpyUnitTest { +class MockitoSpyUnitTest { @Test - void whenSpyingOnList_thenCorrect() { + void givenUsingSpyMethod_whenSpyingOnList_thenCorrect() { final List list = new ArrayList(); final List spyList = spy(list); @@ -36,7 +36,7 @@ public class MockitoSpyUnitTest { private List aSpyList = new ArrayList(); @Test - void whenUsingTheSpyAnnotation_thenObjectIsSpied() { + void givenUsingSpyAnnotation_whenSpyingOnList_thenCorrect() { aSpyList.add("one"); aSpyList.add("two"); @@ -47,13 +47,14 @@ public class MockitoSpyUnitTest { } @Test - void whenStubASpy_thenStubbed() { + void givenASpy_whenStubbingTheBehaviour_thenCorrect() { final List list = new ArrayList(); final List spyList = spy(list); assertEquals(0, spyList.size()); doReturn(100).when(spyList).size(); + assertThat(spyList).hasSize(100); } diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoVerifyExamplesUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/verify/MockitoVerifyExamplesUnitTest.java similarity index 73% rename from testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoVerifyExamplesUnitTest.java rename to testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/verify/MockitoVerifyExamplesUnitTest.java index a236fc7cfc..902bad33f5 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/MockitoVerifyExamplesUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/verify/MockitoVerifyExamplesUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.mockito; +package com.baeldung.mockito.verify; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -20,34 +20,33 @@ import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.exceptions.verification.NoInteractionsWanted; +import com.baeldung.mockito.MyList; import com.google.common.collect.Lists; class MockitoVerifyExamplesUnitTest { - // tests - @Test - final void givenInteractionWithMockOccurred_whenVerifyingInteraction_thenCorrect() { + final void givenInteractionWithMock_whenVerifyingInteraction_thenCorrect() { final List mockedList = mock(MyList.class); mockedList.size(); verify(mockedList).size(); } @Test - final void givenOneInteractionWithMockOccurred_whenVerifyingNumberOfInteractions_thenCorrect() { + final void givenOneInteractionWithMock_whenVerifyingNumberOfInteractions_thenCorrect() { final List mockedList = mock(MyList.class); mockedList.size(); verify(mockedList, times(1)).size(); } @Test - final void givenNoInteractionWithMockOccurred_whenVerifyingInteractions_thenCorrect() { + final void givenNoInteractionWithWholeMock_whenVerifyingInteractions_thenCorrect() { final List mockedList = mock(MyList.class); verifyNoInteractions(mockedList); } @Test - final void givenNoInteractionWithMethodOfMockOccurred_whenVerifyingInteractions_thenCorrect() { + final void givenNoInteractionWithSpecificMethod_whenVerifyingInteractions_thenCorrect() { final List mockedList = mock(MyList.class); verify(mockedList, times(0)).size(); } @@ -59,14 +58,12 @@ class MockitoVerifyExamplesUnitTest { mockedList.clear(); verify(mockedList).size(); - assertThrows(NoInteractionsWanted.class, () -> { - verifyNoMoreInteractions(mockedList); - }); + assertThrows(NoInteractionsWanted.class, () -> verifyNoMoreInteractions(mockedList)); } @Test - final void whenVerifyingOrderOfInteractions_thenCorrect() { + final void givenInteractionsInOrder_whenVerifyingOrderOfInteractions_thenCorrect() { final List mockedList = mock(MyList.class); mockedList.size(); mockedList.add("a parameter"); @@ -79,7 +76,7 @@ class MockitoVerifyExamplesUnitTest { } @Test - final void whenVerifyingAnInteractionHasNotOccurred_thenCorrect() { + final void givenNoInteraction_whenVerifyingAnInteraction_thenCorrect() { final List mockedList = mock(MyList.class); mockedList.size(); @@ -87,7 +84,7 @@ class MockitoVerifyExamplesUnitTest { } @Test - final void whenVerifyingAnInteractionHasOccurredAtLeastOnce_thenCorrect() { + final void givenInteractionAtLeastOnce_whenVerifyingAnInteraction_thenCorrect() { final List mockedList = mock(MyList.class); mockedList.clear(); mockedList.clear(); @@ -100,7 +97,7 @@ class MockitoVerifyExamplesUnitTest { // with arguments @Test - final void whenVerifyingAnInteractionWithExactArgument_thenCorrect() { + final void givenInteractionWithExactArgument_whenVerifyingAnInteraction_thenCorrect() { final List mockedList = mock(MyList.class); mockedList.add("test"); @@ -108,7 +105,7 @@ class MockitoVerifyExamplesUnitTest { } @Test - final void whenVerifyingAnInteractionWithAnyArgument_thenCorrect() { + final void givenInteractionWithAnyArgument_whenVerifyingAnInteraction_thenCorrect() { final List mockedList = mock(MyList.class); mockedList.add("test"); @@ -116,15 +113,14 @@ class MockitoVerifyExamplesUnitTest { } @Test - final void whenVerifyingAnInteractionWithArgumentCapture_thenCorrect() { + final void givenInteraction_whenVerifyingAnInteractionWithArgumentCapture_thenCorrect() { final List mockedList = mock(MyList.class); - mockedList.addAll(Lists.newArrayList("someElement")); - + mockedList.addAll(Lists. newArrayList("someElement")); + final ArgumentCaptor> argumentCaptor = ArgumentCaptor.forClass(List.class); verify(mockedList).addAll(argumentCaptor.capture()); - + final List capturedArgument = argumentCaptor.getValue(); assertThat(capturedArgument).contains("someElement"); } - } diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/voidmethods/MockitoVoidMethodsUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/voidmethods/MockitoVoidMethodsUnitTest.java index 9b8a713a15..ee8c36435a 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/voidmethods/MockitoVoidMethodsUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/voidmethods/MockitoVoidMethodsUnitTest.java @@ -1,6 +1,5 @@ package com.baeldung.mockito.voidmethods; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -15,17 +14,23 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; -import org.mockito.junit.jupiter.MockitoExtension; import com.baeldung.mockito.MyList; -@ExtendWith(MockitoExtension.class) class MockitoVoidMethodsUnitTest { @Test - void whenAddCalledVerified() { + void whenAddCalled_thenVerified() { + MyList myList = mock(MyList.class); + doNothing().when(myList).add(isA(Integer.class), isA(String.class)); + myList.add(0, ""); + + verify(myList, times(1)).add(0, ""); + } + + @Test + void whenAddCalled_thenVerified2() { MyList myList = mock(MyList.class); myList.add(0, ""); @@ -33,8 +38,9 @@ class MockitoVoidMethodsUnitTest { } @Test - void givenNull_addThrows() { + void givenNull_whenAddCalled_thenThrowsException() { MyList myList = mock(MyList.class); + assertThrows(Exception.class, () -> { doThrow().when(myList).add(isA(Integer.class), isNull()); }); @@ -43,36 +49,42 @@ class MockitoVoidMethodsUnitTest { } @Test - void whenAddCalledValueCaptured() { + void givenArgumentCaptor_whenAddCalled_thenValueCaptured() { MyList myList = mock(MyList.class); + ArgumentCaptor valueCapture = ArgumentCaptor.forClass(String.class); doNothing().when(myList).add(any(Integer.class), valueCapture.capture()); + myList.add(0, "captured"); assertEquals("captured", valueCapture.getValue()); } @Test - void whenAddCalledAnswered() { + void givenDoAnswer_whenAddCalled_thenAnswered() { MyList myList = mock(MyList.class); + doAnswer(invocation -> { Object arg0 = invocation.getArgument(0); Object arg1 = invocation.getArgument(1); - //do something with the arguments here assertEquals(3, arg0); assertEquals("answer me", arg1); return null; - }).when(myList).add(any(Integer.class), any(String.class)); + }).when(myList) + .add(any(Integer.class), any(String.class)); + myList.add(3, "answer me"); } @Test - void whenAddCalledRealMethodCalled() { + void givenDoCallRealMethod_whenAddCalled_thenRealMethodCalled() { MyList myList = mock(MyList.class); - doCallRealMethod().when(myList).add(any(Integer.class), any(String.class)); + + doCallRealMethod().when(myList) + .add(any(Integer.class), any(String.class)); myList.add(1, "real"); - + verify(myList, times(1)).add(1, "real"); } } diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml index 80e0c3bc29..a6b5fba570 100644 --- a/testing-modules/pom.xml +++ b/testing-modules/pom.xml @@ -31,7 +31,7 @@ junit5-migration load-testing-comparison mockito - mockito-simple + mocks mocks-2 mockserver @@ -40,6 +40,7 @@ rest-assured rest-testing selenium-junit-testng + selenium-webdriver spring-mockito spring-testing-2 spring-testing diff --git a/testing-modules/rest-assured/pom.xml b/testing-modules/rest-assured/pom.xml index b19ad1270a..a4860b641d 100644 --- a/testing-modules/rest-assured/pom.xml +++ b/testing-modules/rest-assured/pom.xml @@ -139,16 +139,31 @@ io.rest-assured rest-assured + ${rest-assured.version} test io.rest-assured spring-mock-mvc + ${rest-assured.version} test io.rest-assured json-schema-validator + ${rest-assured.version} + test + + + io.rest-assured + xml-path + ${rest-assured.version} + test + + + io.rest-assured + rest-assured-all + ${rest-assured.version} test @@ -172,8 +187,9 @@ 2.9.6 1.1 1.2 - 2.4.1 + 2.27.2 2.5.3 + 5.3.0 \ No newline at end of file diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2IntegrationTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2IntegrationTest.java index c579f1c260..8de7e6dad6 100644 --- a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2IntegrationTest.java +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2IntegrationTest.java @@ -1,14 +1,8 @@ package com.baeldung.restassured; -import com.github.tomakehurst.wiremock.WireMockServer; -import io.restassured.RestAssured; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; import static com.github.tomakehurst.wiremock.client.WireMock.containing; -import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; @@ -16,6 +10,14 @@ import static io.restassured.RestAssured.get; import static io.restassured.RestAssured.with; import static org.hamcrest.Matchers.hasItems; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.github.tomakehurst.wiremock.WireMockServer; + +import io.restassured.RestAssured; + public class RestAssured2IntegrationTest { private static WireMockServer wireMockServer; @@ -24,44 +26,42 @@ public class RestAssured2IntegrationTest { private static final String ODDS = getJson(); @BeforeClass - public static void before() throws Exception { + public static void before() { System.out.println("Setting up!"); final int port = Util.getAvailablePort(); wireMockServer = new WireMockServer(port); wireMockServer.start(); configureFor("localhost", port); RestAssured.port = port; - stubFor(get(urlEqualTo(EVENTS_PATH)).willReturn( - aResponse().withStatus(200) + stubFor(com.github.tomakehurst.wiremock.client.WireMock.get(urlEqualTo(EVENTS_PATH)) + .willReturn(aResponse().withStatus(200) .withHeader("Content-Type", APPLICATION_JSON) .withBody(ODDS))); - stubFor(post(urlEqualTo("/odds/new")) - .withRequestBody(containing("{\"price\":5.25,\"status\":1,\"ck\":13.1,\"name\":\"X\"}")) - .willReturn(aResponse().withStatus(201))); + stubFor(post(urlEqualTo("/odds/new")).withRequestBody(containing("{\"price\":5.25,\"status\":1,\"ck\":13.1,\"name\":\"X\"}")) + .willReturn(aResponse().withStatus(201))); } @Test public void givenUrl_whenVerifiesOddPricesAccuratelyByStatus_thenCorrect() { - get("/odds").then().body("odds.findAll { it.status > 0 }.price", - hasItems(5.25f, 1.2f)); + get("/odds").then() + .body("odds.findAll { it.status > 0 }.price", hasItems(5.25f, 1.2f)); } @Test public void whenRequestedPost_thenCreated() { with().body(new Odd(5.25f, 1, 13.1f, "X")) - .when() - .request("POST", "/odds/new") - .then() - .statusCode(201); + .when() + .request("POST", "/odds/new") + .then() + .statusCode(201); } private static String getJson() { - return Util.inputStreamToString(RestAssured2IntegrationTest.class - .getResourceAsStream("/odds.json")); + return Util.inputStreamToString(RestAssured2IntegrationTest.class.getResourceAsStream("/odds.json")); } @AfterClass - public static void after() throws Exception { + public static void after() { System.out.println("Running: tearDown"); wireMockServer.stop(); } diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredIntegrationTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredIntegrationTest.java index e4279897e2..3c3e1cc39f 100644 --- a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredIntegrationTest.java +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredIntegrationTest.java @@ -1,17 +1,7 @@ package com.baeldung.restassured; -import com.github.fge.jsonschema.SchemaVersion; -import com.github.fge.jsonschema.cfg.ValidationConfiguration; -import com.github.fge.jsonschema.main.JsonSchemaFactory; -import com.github.tomakehurst.wiremock.WireMockServer; -import io.restassured.RestAssured; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; -import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static io.restassured.RestAssured.get; @@ -20,6 +10,17 @@ import static io.restassured.module.jsv.JsonSchemaValidatorSettings.settings; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItems; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.github.fge.jsonschema.SchemaVersion; +import com.github.fge.jsonschema.cfg.ValidationConfiguration; +import com.github.fge.jsonschema.main.JsonSchemaFactory; +import com.github.tomakehurst.wiremock.WireMockServer; + +import io.restassured.RestAssured; + public class RestAssuredIntegrationTest { private static WireMockServer wireMockServer; @@ -28,79 +29,79 @@ public class RestAssuredIntegrationTest { private static final String GAME_ODDS = getEventJson(); @BeforeClass - public static void before() throws Exception { + public static void before() { System.out.println("Setting up!"); final int port = Util.getAvailablePort(); wireMockServer = new WireMockServer(port); wireMockServer.start(); RestAssured.port = port; configureFor("localhost", port); - stubFor(get(urlEqualTo(EVENTS_PATH)).willReturn( - aResponse().withStatus(200) + stubFor(com.github.tomakehurst.wiremock.client.WireMock.get(urlEqualTo(EVENTS_PATH)) + .willReturn(aResponse().withStatus(200) .withHeader("Content-Type", APPLICATION_JSON) .withBody(GAME_ODDS))); } @Test public void givenUrl_whenCheckingFloatValuePasses_thenCorrect() { - get("/events?id=390").then().assertThat() + get("/events?id=390").then() + .assertThat() .body("odd.ck", equalTo(12.2f)); } @Test public void givenUrl_whenSuccessOnGetsResponseAndJsonHasRequiredKV_thenCorrect() { - get("/events?id=390").then().statusCode(200).assertThat() + get("/events?id=390").then() + .statusCode(200) + .assertThat() .body("id", equalTo("390")); } @Test public void givenUrl_whenJsonResponseHasArrayWithGivenValuesUnderKey_thenCorrect() { - get("/events?id=390").then().assertThat() + get("/events?id=390").then() + .assertThat() .body("odds.price", hasItems("1.30", "5.25", "2.70", "1.20")); } @Test public void givenUrl_whenJsonResponseConformsToSchema_thenCorrect() { - get("/events?id=390").then().assertThat() + get("/events?id=390").then() + .assertThat() .body(matchesJsonSchemaInClasspath("event_0.json")); } @Test public void givenUrl_whenValidatesResponseWithInstanceSettings_thenCorrect() { - JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory - .newBuilder() - .setValidationConfiguration( - ValidationConfiguration.newBuilder() - .setDefaultVersion(SchemaVersion.DRAFTV4) - .freeze()).freeze(); + JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory.newBuilder() + .setValidationConfiguration(ValidationConfiguration.newBuilder() + .setDefaultVersion(SchemaVersion.DRAFTV4) + .freeze()) + .freeze(); - get("/events?id=390") - .then() + get("/events?id=390").then() .assertThat() - .body(matchesJsonSchemaInClasspath("event_0.json").using( - jsonSchemaFactory)); + .body(matchesJsonSchemaInClasspath("event_0.json").using(jsonSchemaFactory)); } @Test public void givenUrl_whenValidatesResponseWithStaticSettings_thenCorrect() { - get("/events?id=390") - .then() + get("/events?id=390").then() .assertThat() - .body(matchesJsonSchemaInClasspath("event_0.json").using( - settings().with().checkedValidation(false))); + .body(matchesJsonSchemaInClasspath("event_0.json").using(settings().with() + .checkedValidation(false))); } @AfterClass - public static void after() throws Exception { + public static void after() { System.out.println("Running: tearDown"); wireMockServer.stop(); } private static String getEventJson() { - return Util.inputStreamToString(RestAssuredIntegrationTest.class - .getResourceAsStream("/event_0.json")); + return Util.inputStreamToString(RestAssuredIntegrationTest.class.getResourceAsStream("/event_0.json")); } } diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredMultipartIntegrationTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredMultipartIntegrationTest.java new file mode 100644 index 0000000000..677a205986 --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredMultipartIntegrationTest.java @@ -0,0 +1,107 @@ +package com.baeldung.restassured; + +import static com.github.tomakehurst.wiremock.client.WireMock.aMultipart; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; +import static com.github.tomakehurst.wiremock.client.WireMock.containing; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static io.restassured.RestAssured.given; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.core.io.ClassPathResource; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.matching.MultipartValuePatternBuilder; + +import io.restassured.RestAssured; +import io.restassured.builder.MultiPartSpecBuilder; +import io.restassured.specification.MultiPartSpecification; + +class RestAssuredMultipartIntegrationTest { + + private WireMockServer wireMockServer; + + @BeforeEach + void startServer() { + int port = Util.getAvailablePort(); + wireMockServer = new WireMockServer(port); + wireMockServer.start(); + configureFor("localhost", port); + RestAssured.port = port; + } + + @AfterEach + void stopServer() { + wireMockServer.stop(); + } + + @Test + void whenUploadOneFile_ThenSuccess() throws IOException { + stubFor(post(urlEqualTo("/upload")).withHeader("Content-Type", containing("multipart/form-data")) + .withRequestBody(containing("file")) + .withRequestBody(containing(getFileContent("baeldung.txt"))) + .willReturn(aResponse().withStatus(200))); + + given().multiPart("file", getFile("baeldung.txt")) + .when() + .post("/upload") + .then() + .statusCode(200); + } + + @Test + void whenUploadTwoFiles_ThenSuccess() throws IOException { + stubFor(post(urlEqualTo("/upload")).withHeader("Content-Type", containing("multipart/form-data")) + .withRequestBody(containing(getFileContent("baeldung.txt"))) + .withRequestBody(containing(getFileContent("helloworld.txt"))) + .willReturn(aResponse().withStatus(200))); + + given().multiPart("file", getFile("baeldung.txt")) + .multiPart("helloworld", getFile("helloworld.txt")) + .when() + .post("/upload") + .then() + .statusCode(200); + } + + @Test + void whenBuildingMultipartSpecification_ThenSuccess() { + MultipartValuePatternBuilder multipartValuePatternBuilder = aMultipart().withName("file") + .withHeader("Content-Disposition", containing("file.txt")) + .withBody(equalTo("File content")) + .withHeader("Content-Type", containing("text/plain")); + + stubFor(post(urlEqualTo("/upload")).withMultipartRequestBody(multipartValuePatternBuilder) + .willReturn(aResponse().withStatus(200))); + + MultiPartSpecification multiPartSpecification = new MultiPartSpecBuilder("File content".getBytes()).fileName("file.txt") + .controlName("file") + .mimeType("text/plain") + .build(); + + given().multiPart(multiPartSpecification) + .when() + .post("/upload") + .then() + .statusCode(200); + } + + private String getFileContent(String fileName) throws IOException { + return new String(Files.readAllBytes(Paths.get(getFile(fileName).getPath()))); + } + + private File getFile(String fileName) throws IOException { + return new ClassPathResource(fileName).getFile(); + } + +} diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2IntegrationTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2IntegrationTest.java index f71cce603c..e99be9c716 100644 --- a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2IntegrationTest.java +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2IntegrationTest.java @@ -1,19 +1,19 @@ package com.baeldung.restassured; -import com.github.tomakehurst.wiremock.WireMockServer; -import io.restassured.RestAssured; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static io.restassured.RestAssured.get; +import static org.hamcrest.Matchers.hasItems; + import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static io.restassured.RestAssured.get; -import static io.restassured.RestAssured.port; -import static org.hamcrest.Matchers.hasItems; +import com.github.tomakehurst.wiremock.WireMockServer; + +import io.restassured.RestAssured; public class RestAssuredXML2IntegrationTest { private static WireMockServer wireMockServer; @@ -23,34 +23,31 @@ public class RestAssuredXML2IntegrationTest { private static final String TEACHERS = getXml(); @BeforeClass - public static void before() throws Exception { + public static void before() { System.out.println("Setting up!"); final int port = Util.getAvailablePort(); wireMockServer = new WireMockServer(port); wireMockServer.start(); RestAssured.port = port; configureFor("localhost", port); - stubFor(get(urlEqualTo(EVENTS_PATH)).willReturn( - aResponse().withStatus(200) + stubFor(com.github.tomakehurst.wiremock.client.WireMock.get(urlEqualTo(EVENTS_PATH)) + .willReturn(aResponse().withStatus(200) .withHeader("Content-Type", APPLICATION_XML) .withBody(TEACHERS))); } @Test public void givenUrl_whenVerifiesScienceTeacherFromXml_thenCorrect() { - get("/teachers") - .then() - .body("teachers.teacher.find { it.@department == 'science' }.subject", - hasItems("math", "physics")); + get("/teachers").then() + .body("teachers.teacher.find { it.@department == 'science' }.subject", hasItems("math", "physics")); } private static String getXml() { - return Util.inputStreamToString(RestAssuredXML2IntegrationTest.class - .getResourceAsStream("/teachers.xml")); + return Util.inputStreamToString(RestAssuredXML2IntegrationTest.class.getResourceAsStream("/teachers.xml")); } @AfterClass - public static void after() throws Exception { + public static void after() { System.out.println("Running: tearDown"); wireMockServer.stop(); } diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLIntegrationTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLIntegrationTest.java index 082dace526..95dd479f43 100644 --- a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLIntegrationTest.java +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLIntegrationTest.java @@ -1,14 +1,7 @@ package com.baeldung.restassured; -import com.github.tomakehurst.wiremock.WireMockServer; -import io.restassured.RestAssured; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; -import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static io.restassured.RestAssured.post; @@ -16,6 +9,14 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.xml.HasXPath.hasXPath; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.github.tomakehurst.wiremock.WireMockServer; + +import io.restassured.RestAssured; + public class RestAssuredXMLIntegrationTest { private static WireMockServer wireMockServer; @@ -24,28 +25,30 @@ public class RestAssuredXMLIntegrationTest { private static final String EMPLOYEES = getXml(); @BeforeClass - public static void before() throws Exception { + public static void before() { System.out.println("Setting up!"); final int port = Util.getAvailablePort(); wireMockServer = new WireMockServer(port); wireMockServer.start(); configureFor("localhost", port); RestAssured.port = port; - stubFor(post(urlEqualTo(EVENTS_PATH)).willReturn( - aResponse().withStatus(200) + stubFor(com.github.tomakehurst.wiremock.client.WireMock.post(urlEqualTo(EVENTS_PATH)) + .willReturn(aResponse().withStatus(200) .withHeader("Content-Type", APPLICATION_XML) .withBody(EMPLOYEES))); } @Test public void givenUrl_whenXmlResponseValueTestsEqual_thenCorrect() { - post("/employees").then().assertThat() + post("/employees").then() + .assertThat() .body("employees.employee.first-name", equalTo("Jane")); } @Test public void givenUrl_whenMultipleXmlValuesTestEqual_thenCorrect() { - post("/employees").then().assertThat() + post("/employees").then() + .assertThat() .body("employees.employee.first-name", equalTo("Jane")) .body("employees.employee.last-name", equalTo("Daisy")) .body("employees.employee.sex", equalTo("f")); @@ -53,38 +56,31 @@ public class RestAssuredXMLIntegrationTest { @Test public void givenUrl_whenMultipleXmlValuesTestEqualInShortHand_thenCorrect() { - post("/employees") - .then() + post("/employees").then() .assertThat() - .body("employees.employee.first-name", equalTo("Jane"), - "employees.employee.last-name", equalTo("Daisy"), - "employees.employee.sex", equalTo("f")); + .body("employees.employee.first-name", equalTo("Jane"), "employees.employee.last-name", equalTo("Daisy"), "employees.employee.sex", equalTo("f")); } @Test public void givenUrl_whenValidatesXmlUsingXpath_thenCorrect() { - post("/employees") - .then() + post("/employees").then() .assertThat() - .body(hasXPath("/employees/employee/first-name", - containsString("Ja"))); + .body(hasXPath("/employees/employee/first-name", containsString("Ja"))); } @Test public void givenUrl_whenValidatesXmlUsingXpath2_thenCorrect() { - post("/employees") - .then() + post("/employees").then() .assertThat() .body(hasXPath("/employees/employee/first-name[text()='Jane']")); } private static String getXml() { - return Util - .inputStreamToString(RestAssuredXMLIntegrationTest.class.getResourceAsStream("/employees.xml")); + return Util.inputStreamToString(RestAssuredXMLIntegrationTest.class.getResourceAsStream("/employees.xml")); } @AfterClass - public static void after() throws Exception { + public static void after() { System.out.println("Running: tearDown"); wireMockServer.stop(); } diff --git a/testing-modules/rest-assured/src/test/resources/baeldung.txt b/testing-modules/rest-assured/src/test/resources/baeldung.txt new file mode 100644 index 0000000000..e0d72ef800 --- /dev/null +++ b/testing-modules/rest-assured/src/test/resources/baeldung.txt @@ -0,0 +1 @@ +baeldung \ No newline at end of file diff --git a/testing-modules/rest-assured/src/test/resources/helloworld.txt b/testing-modules/rest-assured/src/test/resources/helloworld.txt new file mode 100644 index 0000000000..95d09f2b10 --- /dev/null +++ b/testing-modules/rest-assured/src/test/resources/helloworld.txt @@ -0,0 +1 @@ +hello world \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/README.md b/testing-modules/selenium-junit-testng/README.md index 65eb269056..922f5d6a52 100644 --- a/testing-modules/selenium-junit-testng/README.md +++ b/testing-modules/selenium-junit-testng/README.md @@ -8,7 +8,10 @@ - [Running Selenium Scripts with JMeter](https://www.baeldung.com/selenium-jmeter) - [Fixing Selenium WebDriver Executable Path Error](https://www.baeldung.com/java-selenium-webdriver-path-error) - [Handle Browser Tabs With Selenium](https://www.baeldung.com/java-handle-browser-tabs-selenium) - +- [Implicit Wait vs Explicit Wait in Selenium Webdriver](https://www.baeldung.com/selenium-implicit-explicit-wait) +- [StaleElementReferenceException in Selenium](https://www.baeldung.com/selenium-staleelementreferenceexception) +- [Retrieve the Value of an HTML Input in Selenium WebDriver](https://www.baeldung.com/java-selenium-html-input-value) +- [Opening a New Tab Using Selenium WebDriver in Java](https://www.baeldung.com/java-selenium-open-new-tab) #### Notes: - to run the live tests for the article *Fixing Selenium WebDriver Executable Path Error*, follow the manual setup described [Fixing Selenium WebDriver Executable Path Error](https://www.baeldung.com/java-selenium-webdriver-path-error#manual-setup); download the 3 diff --git a/testing-modules/selenium-junit-testng/pom.xml b/testing-modules/selenium-junit-testng/pom.xml index f0a2e43eeb..517dc48dde 100644 --- a/testing-modules/selenium-junit-testng/pom.xml +++ b/testing-modules/selenium-junit-testng/pom.xml @@ -57,9 +57,9 @@ 6.10 - 4.6.0 + 4.8.3 1.5.4 - 5.3.0 + 5.3.2 \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/stale/RobustWebDriver.java b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/stale/RobustWebDriver.java new file mode 100644 index 0000000000..211480dce3 --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/stale/RobustWebDriver.java @@ -0,0 +1,86 @@ +package com.baeldung.selenium.stale; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class RobustWebDriver implements WebDriver { + + private final WebDriver originalWebDriver; + + public RobustWebDriver(WebDriver webDriver) { + this.originalWebDriver = webDriver; + } + + @Override + public void get(String url) { + this.originalWebDriver.get(url); + } + + @Override + public String getCurrentUrl() { + return this.originalWebDriver.getCurrentUrl(); + } + + @Override + public String getTitle() { + return this.originalWebDriver.getTitle(); + } + + @Override + public List findElements(By by) { + return this.originalWebDriver.findElements(by) + .stream().map(e -> new RobustWebElement(e, by, this)) + .collect(Collectors.toList()); + } + + @Override + public WebElement findElement(By by) { + return new RobustWebElement(this.originalWebDriver.findElement(by), by, this); + } + + @Override + public String getPageSource() { + return this.originalWebDriver.getPageSource(); + } + + @Override + public void close() { + this.originalWebDriver.close(); + + } + + @Override + public void quit() { + this.originalWebDriver.quit(); + } + + @Override + public Set getWindowHandles() { + return this.originalWebDriver.getWindowHandles(); + } + + @Override + public String getWindowHandle() { + return this.originalWebDriver.getWindowHandle(); + } + + @Override + public TargetLocator switchTo() { + return this.originalWebDriver.switchTo(); + } + + @Override + public Navigation navigate() { + return this.originalWebDriver.navigate(); + } + + @Override + public Options manage() { + return this.originalWebDriver.manage(); + } +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/stale/RobustWebElement.java b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/stale/RobustWebElement.java new file mode 100644 index 0000000000..fa65e60349 --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/stale/RobustWebElement.java @@ -0,0 +1,176 @@ +package com.baeldung.selenium.stale; + +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.OutputType; +import org.openqa.selenium.Point; +import org.openqa.selenium.Rectangle; +import org.openqa.selenium.StaleElementReferenceException; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.WebElement; + +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; + +public class RobustWebElement implements WebElement { + + private WebElement originalElement; + private final RobustWebDriver driver; + private final By by; + + private static final int MAX_RETRIES = 10; + private static final String SERE = "Element is no longer attached to the DOM"; + + public RobustWebElement(WebElement element, By by, RobustWebDriver driver) { + this.originalElement = element; + this.by = by; + this.driver = driver; + } + + @Override + public void click() { + executeMethodWithRetries(WebElement::click); + } + + @Override + public void submit() { + executeMethodWithRetries(WebElement::submit); + } + + @Override + public void sendKeys(CharSequence... keysToSend) { + executeMethodWithRetriesVoid(WebElement::sendKeys, keysToSend); + } + + @Override + public void clear() { + executeMethodWithRetries(WebElement::clear); + } + + @Override + public String getTagName() { + return executeMethodWithRetries(WebElement::getTagName); + } + + @Override + public String getAttribute(String name) { + return executeMethodWithRetries(WebElement::getAttribute, name); + } + + @Override + public boolean isSelected() { + return executeMethodWithRetries(WebElement::isSelected); + } + + @Override + public boolean isEnabled() { + return executeMethodWithRetries(WebElement::isEnabled); + } + + @Override + public String getText() { + return executeMethodWithRetries(WebElement::getText); + } + + @Override + public List findElements(By by) { + return executeMethodWithRetries(WebElement::findElements, by); + } + + @Override + public WebElement findElement(By by) { + return executeMethodWithRetries(WebElement::findElement, by); + } + + @Override + public boolean isDisplayed() { + return executeMethodWithRetries(WebElement::isDisplayed); + } + + @Override + public Point getLocation() { + return executeMethodWithRetries(WebElement::getLocation); + } + + @Override + public Dimension getSize() { + return executeMethodWithRetries(WebElement::getSize); + } + + @Override + public Rectangle getRect() { + return executeMethodWithRetries(WebElement::getRect); + } + + @Override + public String getCssValue(String propertyName) { + return executeMethodWithRetries(WebElement::getCssValue, propertyName); + } + + + @Override + public X getScreenshotAs(OutputType target) throws WebDriverException { + return executeMethodWithRetries(WebElement::getScreenshotAs, target); + } + + private void executeMethodWithRetries(Consumer method) { + int retries = 0; + while (retries < MAX_RETRIES) { + try { + WebElementUtils.callMethod(originalElement, method); + return; + } catch (StaleElementReferenceException ex) { + refreshElement(); + } + retries++; + } + throw new StaleElementReferenceException(SERE); + } + + private T executeMethodWithRetries(Function method) { + int retries = 0; + while (retries < MAX_RETRIES) { + try { + return WebElementUtils.callMethodWithReturn(originalElement, method); + } catch (StaleElementReferenceException ex) { + refreshElement(); + } + retries++; + } + throw new StaleElementReferenceException(SERE); + } + + private void executeMethodWithRetriesVoid(BiConsumer method, U parameter) { + int retries = 0; + while (retries < MAX_RETRIES) { + try { + WebElementUtils.callMethod(originalElement, method, parameter); + return; + } catch (StaleElementReferenceException ex) { + refreshElement(); + } + retries++; + } + throw new StaleElementReferenceException(SERE); + } + + private T executeMethodWithRetries(BiFunction method, U parameter) { + int retries = 0; + while (retries < MAX_RETRIES) { + try { + return WebElementUtils.callMethodWithReturn(originalElement, method, parameter); + } catch (StaleElementReferenceException ex) { + refreshElement(); + } + retries++; + } + throw new StaleElementReferenceException(SERE); + } + + private void refreshElement() { + this.originalElement = driver.findElement(by); + } +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/stale/WebElementUtils.java b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/stale/WebElementUtils.java new file mode 100644 index 0000000000..460cc02bf5 --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/stale/WebElementUtils.java @@ -0,0 +1,30 @@ +package com.baeldung.selenium.stale; + +import org.openqa.selenium.WebElement; + +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; + +public class WebElementUtils { + + private WebElementUtils(){ + } + + public static void callMethod(WebElement element, Consumer method) { + method.accept(element); + } + + public static void callMethod(WebElement element, BiConsumer method, U parameter) { + method.accept(element, parameter); + } + + public static T callMethodWithReturn(WebElement element, Function method) { + return method.apply(element); + } + + public static T callMethodWithReturn(WebElement element, BiFunction method, U parameter) { + return method.apply(element, parameter); + } +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/stale/RobustWebElementLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/stale/RobustWebElementLiveTest.java new file mode 100644 index 0000000000..3dea95ca82 --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/stale/RobustWebElementLiveTest.java @@ -0,0 +1,58 @@ +package com.baeldung.selenium.stale; + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; + +import java.time.Duration; + +final class RobustWebElementLiveTest { + + private static RobustWebDriver driver; + private static final int TIMEOUT = 10; + + private static final By LOCATOR_REFRESH = By.xpath("//a[.='click here']"); + private static final By LOCATOR_DYNAMIC_CONTENT = By.xpath( + "(//div[@id='content']//div[@class='large-10 columns'])[1]"); + + private static void setupChromeDriver() { + WebDriverManager.chromedriver().setup(); + final ChromeOptions options = new ChromeOptions(); + options.addArguments("--remote-allow-origins=*"); + driver = new RobustWebDriver(new ChromeDriver(options)); + options(); + } + + private static void options() { + driver.manage().window().maximize(); + driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(TIMEOUT)); + } + + @BeforeEach + public void init() { + setupChromeDriver(); + } + + @Test + void givenDynamicPage_whenRefreshingAndAccessingSavedElement_thenOK() { + driver.navigate().to("https://the-internet.herokuapp.com/dynamic_content?with_content=static"); + final WebElement element = driver.findElement(LOCATOR_DYNAMIC_CONTENT); + + driver.findElement(LOCATOR_REFRESH).click(); + Assertions.assertDoesNotThrow(element::getText); + } + + @AfterEach + void teardown() { + if (driver != null) { + driver.quit(); + driver = null; + } + } +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/stale/StaleElementReferenceLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/stale/StaleElementReferenceLiveTest.java new file mode 100644 index 0000000000..9b42571891 --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/stale/StaleElementReferenceLiveTest.java @@ -0,0 +1,102 @@ +package com.baeldung.selenium.stale; + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.StaleElementReferenceException; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; + +import java.time.Duration; + +final class StaleElementReferenceLiveTest { + + private static WebDriver driver; + private static final int TIMEOUT = 10; + + private static final By LOCATOR_REFRESH = By.xpath("//a[.='click here']"); + private static final By LOCATOR_DYNAMIC_CONTENT = By.xpath( + "(//div[@id='content']//div[@class='large-10 columns'])[1]"); + + private static void setupChromeDriver() { + WebDriverManager.chromedriver().setup(); + final ChromeOptions options = new ChromeOptions(); + options.addArguments("--remote-allow-origins=*"); + driver = new ChromeDriver(options); + options(); + } + + private static void options() { + driver.manage().window().maximize(); + driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(TIMEOUT)); + } + + @BeforeEach + public void init() { + setupChromeDriver(); + } + + @Test + void givenDynamicPage_whenRefreshingAndAccessingSavedElement_thenSERE() { + driver.navigate().to("https://the-internet.herokuapp.com/dynamic_content?with_content=static"); + final WebElement element = driver.findElement(LOCATOR_DYNAMIC_CONTENT); + + driver.findElement(LOCATOR_REFRESH).click(); + Assertions.assertThrows(StaleElementReferenceException.class, element::getText); + } + + @Test + void givenDynamicPage_whenRefreshingAndAccessingSavedElement_thenHandleSERE() { + driver.navigate().to("https://the-internet.herokuapp.com/dynamic_content?with_content=static"); + final WebElement element = driver.findElement(LOCATOR_DYNAMIC_CONTENT); + + if (!retryingFindClick(LOCATOR_REFRESH)) { + Assertions.fail("Element is still stale after 5 attempts"); + } + Assertions.assertDoesNotThrow(() -> retryingFindGetText(LOCATOR_DYNAMIC_CONTENT)); + } + + private boolean retryingFindClick(By locator) { + boolean result = false; + int attempts = 0; + while (attempts < 5) { + try { + driver.findElement(locator).click(); + result = true; + break; + } catch (StaleElementReferenceException ex) { + System.out.println(ex.getMessage()); + } + attempts++; + } + return result; + } + + private String retryingFindGetText(By locator) { + String result = null; + int attempts = 0; + while (attempts < 5) { + try { + result = driver.findElement(locator).getText(); + break; + } catch (StaleElementReferenceException ex) { + System.out.println(ex.getMessage()); + } + attempts++; + } + return result; + } + + @AfterEach + void teardown() { + if (driver != null) { + driver.quit(); + driver = null; + } + } +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/tabs/SeleniumOpenNewTabLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/tabs/SeleniumOpenNewTabLiveTest.java new file mode 100644 index 0000000000..9e64073cb9 --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/tabs/SeleniumOpenNewTabLiveTest.java @@ -0,0 +1,53 @@ +package com.baeldung.selenium.tabs; + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WindowType; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.time.Duration; + +public class SeleniumOpenNewTabLiveTest { + + private WebDriver driver; + private static final int TIMEOUT = 10; + private static final int EXPECTED_TABS_COUNT = 2; + + @BeforeMethod + public void initDriver() { + WebDriverManager.chromedriver().setup(); + driver = new ChromeDriver(); + } + + @Test + public void whenUseTabsApiOpenWindow_thenNewTabOpened() { + driver.switchTo().newWindow(WindowType.TAB); + waitTabsCount(EXPECTED_TABS_COUNT); + } + + @Test + public void whenExecuteOpenWindowJsScript_thenNewTabOpened() { + ((JavascriptExecutor) driver).executeScript("window.open()"); + waitTabsCount(EXPECTED_TABS_COUNT); + } + + + @AfterMethod + public void closeBrowser() { + driver.quit(); + } + + + private void waitTabsCount(int tabsCount) { + new WebDriverWait(driver, Duration.ofSeconds(TIMEOUT)) + .withMessage("Tabs count should be: " + tabsCount) + .until(ExpectedConditions.numberOfWindowsToBe(tabsCount)); + } + +} diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/wait/ExplicitWaitLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/wait/ExplicitWaitLiveTest.java new file mode 100644 index 0000000000..65943fbf5e --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/wait/ExplicitWaitLiveTest.java @@ -0,0 +1,79 @@ +package com.baeldung.selenium.wait; + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.ElementNotInteractableException; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import java.time.Duration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +final class ExplicitWaitLiveTest { + + private static WebDriver driver; + private static WebDriverWait wait; + private static final int TIMEOUT = 10; + + private static final By LOCATOR_ABOUT = By.xpath("//a[starts-with(., 'About')]"); + private static final By LOCATOR_ABOUT_BAELDUNG = By.xpath("//h3[normalize-space()='About Baeldung']"); + private static final By LOCATOR_ABOUT_HEADER = By.xpath("//h1"); + + private static void setupChromeDriver() { + WebDriverManager.chromedriver().setup(); + final ChromeOptions options = new ChromeOptions(); + options.addArguments("--remote-allow-origins=*"); + driver = new ChromeDriver(options); + options(); + } + + private static void options() { + driver.manage().window().maximize(); + } + + @BeforeEach + public void init() { + setupChromeDriver(); + wait = new WebDriverWait(driver, Duration.ofSeconds(TIMEOUT)); + } + + @Test + void givenPage_whenNavigatingWithoutExplicitWait_thenElementNotInteractable() { + driver.navigate().to("https://www.baeldung.com/"); + + driver.findElement(LOCATOR_ABOUT).click(); + + assertThrows(ElementNotInteractableException.class, () -> driver.findElement(LOCATOR_ABOUT_BAELDUNG).click()); + } + + @Test + void givenPage_whenNavigatingWithExplicitWait_thenOK() { + final String expected = "About Baeldung"; + driver.navigate().to("https://www.baeldung.com/"); + + driver.findElement(LOCATOR_ABOUT).click(); + wait.until(ExpectedConditions.visibilityOfElementLocated(LOCATOR_ABOUT_BAELDUNG)); + + driver.findElement(LOCATOR_ABOUT_BAELDUNG).click(); + wait.until(ExpectedConditions.visibilityOfElementLocated(LOCATOR_ABOUT_HEADER)); + + final String actual = driver.findElement(LOCATOR_ABOUT_HEADER).getText(); + assertEquals(expected, actual); + } + + @AfterEach + void teardown() { + if (driver != null) { + driver.quit(); + driver = null; + } + } +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/wait/FluentWaitLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/wait/FluentWaitLiveTest.java new file mode 100644 index 0000000000..c41e5619ac --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/wait/FluentWaitLiveTest.java @@ -0,0 +1,83 @@ +package com.baeldung.selenium.wait; + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.ElementNotInteractableException; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.FluentWait; +import org.openqa.selenium.support.ui.Wait; + +import java.time.Duration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +final class FluentWaitLiveTest { + + private static WebDriver driver; + private static Wait wait; + private static final int TIMEOUT = 10; + private static final int POLL_FREQUENCY = 250; + + private static final By LOCATOR_ABOUT = By.xpath("//a[starts-with(., 'About')]"); + private static final By LOCATOR_ABOUT_BAELDUNG = By.xpath("//h3[normalize-space()='About Baeldung']"); + private static final By LOCATOR_ABOUT_HEADER = By.xpath("//h1"); + + private static void setupChromeDriver() { + WebDriverManager.chromedriver().setup(); + final ChromeOptions options = new ChromeOptions(); + options.addArguments("--remote-allow-origins=*"); + driver = new ChromeDriver(options); + options(); + } + + private static void options() { + driver.manage().window().maximize(); + } + + @BeforeEach + public void init() { + setupChromeDriver(); + wait = new FluentWait<>(driver) + .withTimeout(Duration.ofSeconds(TIMEOUT)) + .pollingEvery(Duration.ofMillis(POLL_FREQUENCY)); + } + + @Test + void givenPage_whenNavigatingWithoutFluentWait_thenElementNotInteractable() { + driver.navigate().to("https://www.baeldung.com/"); + + driver.findElement(LOCATOR_ABOUT).click(); + + assertThrows(ElementNotInteractableException.class, () -> driver.findElement(LOCATOR_ABOUT_BAELDUNG).click()); + } + + @Test + void givenPage_whenNavigatingWithFluentWait_thenOK() { + final String expected = "About Baeldung"; + driver.navigate().to("https://www.baeldung.com/"); + + driver.findElement(LOCATOR_ABOUT).click(); + wait.until(ExpectedConditions.visibilityOfElementLocated(LOCATOR_ABOUT_BAELDUNG)); + + driver.findElement(LOCATOR_ABOUT_BAELDUNG).click(); + wait.until(ExpectedConditions.visibilityOfElementLocated(LOCATOR_ABOUT_HEADER)); + + final String actual = driver.findElement(LOCATOR_ABOUT_HEADER).getText(); + assertEquals(expected, actual); + } + + @AfterEach + void teardown() { + if (driver != null) { + driver.quit(); + driver = null; + } + } +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/wait/ImplicitWaitLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/wait/ImplicitWaitLiveTest.java new file mode 100644 index 0000000000..86c401e13a --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/wait/ImplicitWaitLiveTest.java @@ -0,0 +1,63 @@ +package com.baeldung.selenium.wait; + + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; + +import java.time.Duration; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +final class ImplicitWaitLiveTest { + + private static WebDriver driver; + private static final int TIMEOUT = 10; + + private static final By LOCATOR_ABOUT = By.xpath("//a[starts-with(., 'About')]"); + private static final By LOCATOR_ABOUT_BAELDUNG = By.xpath("//h3[normalize-space()='About Baeldung']"); + private static final By LOCATOR_ABOUT_HEADER = By.xpath("//h1"); + + private static void setupChromeDriver() { + WebDriverManager.chromedriver().setup(); + final ChromeOptions options = new ChromeOptions(); + options.addArguments("--remote-allow-origins=*"); + driver = new ChromeDriver(options); + options(); + } + + private static void options() { + driver.manage().window().maximize(); + driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(TIMEOUT)); + } + + @BeforeEach + public void init() { + setupChromeDriver(); + } + + @Test + void givenPage_whenNavigatingWithImplicitWait_ThenOK() { + final String expected = "About Baeldung"; + driver.navigate().to("https://www.baeldung.com/"); + + driver.findElement(LOCATOR_ABOUT).click(); + driver.findElement(LOCATOR_ABOUT_BAELDUNG).click(); + + final String actual = driver.findElement(LOCATOR_ABOUT_HEADER).getText(); + assertEquals(expected, actual); + } + + @AfterEach + void teardown() { + if (driver != null) { + driver.quit(); + driver = null; + } + } +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/webdriver/SeleniumWebDriverUnitTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/webdriver/SeleniumWebDriverUnitTest.java new file mode 100644 index 0000000000..e4e89611d1 --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/webdriver/SeleniumWebDriverUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.selenium.webdriver; + +import org.junit.Assert; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import io.github.bonigarcia.wdm.WebDriverManager; + +public class SeleniumWebDriverUnitTest { + + private WebDriver driver; + + private static final String URL = "https://duckduckgo.com/"; + private static final String INPUT_ID = "search_form_input_homepage"; + + @BeforeEach + public void setUp() { + WebDriverManager.chromedriver().setup(); + driver = new ChromeDriver(); + } + + @AfterEach + public void tearDown() { + driver.quit(); + } + + @Test + public void givenDuckDuckGoHomePage_whenInputHelloWorld_thenInputValueIsHelloWorld() { + driver.get(URL); + WebElement inputElement = driver.findElement(By.id(INPUT_ID)); + inputElement.sendKeys(Keys.chord(Keys.CONTROL, "a"), Keys.DELETE); + inputElement.sendKeys("Hello World!"); + + String inputValue = inputElement.getAttribute("value"); + Assert.assertEquals("Hello World!", inputValue); + } + +} diff --git a/testing-modules/selenium-webdriver/1688web.png b/testing-modules/selenium-webdriver/1688web.png new file mode 100644 index 0000000000..92ae7921fb Binary files /dev/null and b/testing-modules/selenium-webdriver/1688web.png differ diff --git a/testing-modules/selenium-webdriver/README.md b/testing-modules/selenium-webdriver/README.md new file mode 100644 index 0000000000..055144998e --- /dev/null +++ b/testing-modules/selenium-webdriver/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Uploading File Using Selenium Webdriver in Java](https://www.baeldung.com/java-selenium-upload-file) diff --git a/testing-modules/selenium-webdriver/pom.xml b/testing-modules/selenium-webdriver/pom.xml new file mode 100644 index 0000000000..4eac847709 --- /dev/null +++ b/testing-modules/selenium-webdriver/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + selenium-webdriver + 0.0.1-SNAPSHOT + selenium-webdriver + + + com.baeldung + testing-modules + 1.0.0-SNAPSHOT + + + + + org.seleniumhq.selenium + selenium-java + ${selenium-java.version} + + + commons-logging + commons-logging + + + + + org.testng + testng + ${testng.version} + + + io.github.bonigarcia + webdrivermanager + ${webdrivermanager.version} + + + + + + + src/main/resources + true + + + src/test/resources + true + + + + + + 6.10 + 4.8.3 + 5.3.2 + + + \ No newline at end of file diff --git a/testing-modules/selenium-webdriver/src/test/java/com/baeldung/selenium/webdriver/fileupload/FileUploadWebDriverUnitTest.java b/testing-modules/selenium-webdriver/src/test/java/com/baeldung/selenium/webdriver/fileupload/FileUploadWebDriverUnitTest.java new file mode 100644 index 0000000000..18853ede56 --- /dev/null +++ b/testing-modules/selenium-webdriver/src/test/java/com/baeldung/selenium/webdriver/fileupload/FileUploadWebDriverUnitTest.java @@ -0,0 +1,53 @@ +package com.baeldung.selenium.webdriver.fileupload; + +import org.junit.Assert; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; + +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +import org.openqa.selenium.firefox.FirefoxDriver; + +import io.github.bonigarcia.wdm.WebDriverManager; + +public class FileUploadWebDriverUnitTest { + + private WebDriver driver; + + private static final String URL = "http://www.csm-testcenter.org/test?do=show&subdo=common&test=file_upload"; + private static final String INPUT_NAME = "file_upload"; + + @BeforeEach + public void setUp() { + WebDriverManager.firefoxdriver() + .setup(); + driver = new FirefoxDriver(); + } + + @AfterEach + public void tearDown() { + driver.quit(); + } + + @Test + public void givenFileUploadPage_whenInputFilePath_thenFileUploadEndsWithFilename() { + driver.get(URL); + + String filePath = System.getProperty("user.dir") + "/1688web.png"; + WebElement inputElement = driver.findElement(By.name(INPUT_NAME)); + WebElement submitButton = driver.findElement(By.name("http_submit")); + + inputElement.sendKeys(filePath); + + String actualFilePath = inputElement.getAttribute("value"); + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1); + + submitButton.click(); + + Assert.assertTrue(actualFilePath.endsWith(fileName)); + } + +} \ No newline at end of file diff --git a/testing-modules/spring-testing-2/README.md b/testing-modules/spring-testing-2/README.md index 5bd1716609..139b25f4b5 100644 --- a/testing-modules/spring-testing-2/README.md +++ b/testing-modules/spring-testing-2/README.md @@ -4,3 +4,4 @@ - [Concurrent Test Execution in Spring 5](https://www.baeldung.com/spring-5-concurrent-tests) - [Spring 5 Testing with @EnabledIf Annotation](https://www.baeldung.com/spring-5-enabledif) - [The Spring TestExecutionListener](https://www.baeldung.com/spring-testexecutionlistener) +- [Execute Tests Based on Active Profile With JUnit 5](https://www.baeldung.com/spring-boot-junit-5-testing-active-profile) diff --git a/testing-modules/spring-testing-2/src/main/java/com/baeldung/activeprofile/ActiveProfileApplication.java b/testing-modules/spring-testing-2/src/main/java/com/baeldung/activeprofile/ActiveProfileApplication.java new file mode 100644 index 0000000000..19fdff2a0c --- /dev/null +++ b/testing-modules/spring-testing-2/src/main/java/com/baeldung/activeprofile/ActiveProfileApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.activeprofile; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ActiveProfileApplication { + + public static void main(String[] args) { + SpringApplication.run(ActiveProfileApplication.class); + } +} diff --git a/testing-modules/spring-testing-2/src/test/java/com/baeldung/activeprofile/DevActiveProfileUnitTest.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/activeprofile/DevActiveProfileUnitTest.java new file mode 100644 index 0000000000..dcefddbc3c --- /dev/null +++ b/testing-modules/spring-testing-2/src/test/java/com/baeldung/activeprofile/DevActiveProfileUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.activeprofile; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = ActiveProfileApplication.class) +public class DevActiveProfileUnitTest { + + @Value("${profile.property.value}") + private String propertyString; + + @Test + void whenDevIsActive_thenValueShouldBeKeptFromApplicationYaml() { + Assertions.assertEquals("This the the application.yaml file", propertyString); + } +} diff --git a/testing-modules/spring-testing-2/src/test/java/com/baeldung/activeprofile/MultipleActiveProfileUnitTest.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/activeprofile/MultipleActiveProfileUnitTest.java new file mode 100644 index 0000000000..f84d0e36b4 --- /dev/null +++ b/testing-modules/spring-testing-2/src/test/java/com/baeldung/activeprofile/MultipleActiveProfileUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.activeprofile; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.env.Environment; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.EnabledIf; + +@SpringBootTest(classes = ActiveProfileApplication.class) +@EnabledIf(value = "#{{'test', 'prod'}.contains(environment.getActiveProfiles()[0])}", loadContext = true) +@ActiveProfiles(value = "test") +public class MultipleActiveProfileUnitTest { + @Value("${profile.property.value}") + private String propertyString; + + @Autowired + private Environment env; + + @Test + void whenDevIsActive_thenValueShouldBeKeptFromDedicatedApplicationYaml() { + String currentProfile = env.getActiveProfiles()[0]; + Assertions.assertEquals(String.format("This the the application-%s.yaml file", currentProfile), propertyString); + } +} diff --git a/testing-modules/spring-testing-2/src/test/java/com/baeldung/activeprofile/ProdActiveProfileUnitTest.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/activeprofile/ProdActiveProfileUnitTest.java new file mode 100644 index 0000000000..8427f23960 --- /dev/null +++ b/testing-modules/spring-testing-2/src/test/java/com/baeldung/activeprofile/ProdActiveProfileUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.activeprofile; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.EnabledIf; + +@SpringBootTest(classes = ActiveProfileApplication.class) +@EnabledIf(value = "#{environment.getActiveProfiles()[0] == 'prod'}", loadContext = true) +@ActiveProfiles(value = "prod") +public class ProdActiveProfileUnitTest { + + @Value("${profile.property.value}") + private String propertyString; + + @Test + void whenProdIsActive_thenValueShouldBeKeptFromApplicationProdYaml() { + Assertions.assertEquals("This the the application-prod.yaml file", propertyString); + } + +} diff --git a/testing-modules/spring-testing-2/src/test/java/com/baeldung/activeprofile/TestActiveProfileUnitTest.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/activeprofile/TestActiveProfileUnitTest.java new file mode 100644 index 0000000000..f17df37050 --- /dev/null +++ b/testing-modules/spring-testing-2/src/test/java/com/baeldung/activeprofile/TestActiveProfileUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.activeprofile; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +@SpringBootTest(classes = ActiveProfileApplication.class) +@ActiveProfiles(value = "test") +public class TestActiveProfileUnitTest { + + @Value("${profile.property.value}") + private String propertyString; + + @Test + void whenTestIsActive_thenValueShouldBeKeptFromApplicationTestYaml() { + Assertions.assertEquals("This the the application-test.yaml file", propertyString); + } +} diff --git a/testing-modules/spring-testing-2/src/test/resources/application-prod.yaml b/testing-modules/spring-testing-2/src/test/resources/application-prod.yaml new file mode 100644 index 0000000000..98afa0421e --- /dev/null +++ b/testing-modules/spring-testing-2/src/test/resources/application-prod.yaml @@ -0,0 +1,3 @@ +profile: + property: + value: This the the application-prod.yaml file \ No newline at end of file diff --git a/testing-modules/spring-testing-2/src/test/resources/application-test.yaml b/testing-modules/spring-testing-2/src/test/resources/application-test.yaml new file mode 100644 index 0000000000..5f183a8d7e --- /dev/null +++ b/testing-modules/spring-testing-2/src/test/resources/application-test.yaml @@ -0,0 +1,3 @@ +profile: + property: + value: This the the application-test.yaml file \ No newline at end of file diff --git a/testing-modules/spring-testing-2/src/test/resources/application.yaml b/testing-modules/spring-testing-2/src/test/resources/application.yaml new file mode 100644 index 0000000000..cf63649116 --- /dev/null +++ b/testing-modules/spring-testing-2/src/test/resources/application.yaml @@ -0,0 +1,6 @@ +spring: + profiles: + active: dev +profile: + property: + value: This the the application.yaml file \ No newline at end of file diff --git a/vaadin/pom.xml b/vaadin/pom.xml index aa37a2392a..777ab2551c 100644 --- a/vaadin/pom.xml +++ b/vaadin/pom.xml @@ -187,6 +187,7 @@ local mytheme 3.0.0 + 3.3.2 \ No newline at end of file diff --git a/vertx-modules/spring-vertx/pom.xml b/vertx-modules/spring-vertx/pom.xml index 447d31ee55..d19420d571 100644 --- a/vertx-modules/spring-vertx/pom.xml +++ b/vertx-modules/spring-vertx/pom.xml @@ -48,7 +48,7 @@ - 3.4.1 + 3.9.15 \ No newline at end of file diff --git a/vertx-modules/vertx-and-rxjava/pom.xml b/vertx-modules/vertx-and-rxjava/pom.xml index 95bf95020a..16eaf8ebaa 100644 --- a/vertx-modules/vertx-and-rxjava/pom.xml +++ b/vertx-modules/vertx-and-rxjava/pom.xml @@ -36,17 +36,12 @@ org.apache.maven.plugins maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${java.version} - ${java.version} - - 3.5.0.Beta1 + 3.9.15 \ No newline at end of file diff --git a/vertx-modules/vertx-and-rxjava/src/test/java/com/baeldung/weather/VertxWithRxJavaIntegrationTest.java b/vertx-modules/vertx-and-rxjava/src/test/java/com/baeldung/weather/VertxWithRxJavaIntegrationTest.java index a2ddbe5007..d5d58438e2 100644 --- a/vertx-modules/vertx-and-rxjava/src/test/java/com/baeldung/weather/VertxWithRxJavaIntegrationTest.java +++ b/vertx-modules/vertx-and-rxjava/src/test/java/com/baeldung/weather/VertxWithRxJavaIntegrationTest.java @@ -45,18 +45,18 @@ public class VertxWithRxJavaIntegrationTest { // read the file that contains one city name per line fileSystem .rxReadFile("cities.txt").toFlowable() - .doOnNext(buffer -> log.info("File buffer ---\n{}\n---", buffer)) + .doOnNext(buffer -> log.debug("File buffer ---\n{}\n---", buffer)) .flatMap(buffer -> Flowable.fromArray(buffer.toString().split("\\r?\\n"))) - .doOnNext(city -> log.info("City from file: '{}'", city)) + .doOnNext(city -> log.debug("City from file: '{}'", city)) .filter(city -> !city.startsWith("#")) - .doOnNext(city -> log.info("City that survived filtering: '{}'", city)) + .doOnNext(city -> log.debug("City that survived filtering: '{}'", city)) .flatMap(city -> searchByCityName(httpClient, city)) .flatMap(HttpClientResponse::toFlowable) - .doOnNext(buffer -> log.info("JSON of city detail: '{}'", buffer)) + .doOnNext(buffer -> log.debug("JSON of city detail: '{}'", buffer)) .map(extractingWoeid()) .flatMap(cityId -> getDataByPlaceId(httpClient, cityId)) .flatMap(toBufferFlowable()) - .doOnNext(buffer -> log.info("JSON of place detail: '{}'", buffer)) + .doOnNext(buffer -> log.debug("JSON of place detail: '{}'", buffer)) .map(Buffer::toJsonObject) .map(toCityAndDayLength()) .subscribe(System.out::println, Throwable::printStackTrace); diff --git a/vertx-modules/vertx/pom.xml b/vertx-modules/vertx/pom.xml index f8d72f8ae8..786ce44e79 100644 --- a/vertx-modules/vertx/pom.xml +++ b/vertx-modules/vertx/pom.xml @@ -65,7 +65,7 @@ - 3.8.1 + 3.9.15 3.2.1 diff --git a/web-modules/apache-tapestry/pom.xml b/web-modules/apache-tapestry/pom.xml index 7746520a56..9632dd70dc 100644 --- a/web-modules/apache-tapestry/pom.xml +++ b/web-modules/apache-tapestry/pom.xml @@ -115,6 +115,18 @@ + + org.apache.maven.plugins + maven-war-plugin + 3.3.1 + + + + true + + + + @@ -133,11 +145,11 @@ 6.1.16 - 2.7.2 - 2.3.2 - 1.8 - 1.8 - 5.4.5 + 3.0.0-M5 + 3.8.1 + 11 + 11 + 5.8.2 2.5 6.8.21 1.7.19 diff --git a/web-modules/apache-tapestry/src/main/java/com/baeldung/tapestry/services/AppModule.java b/web-modules/apache-tapestry/src/main/java/com/baeldung/tapestry/services/AppModule.java index c4d57d5b86..2798e4a75b 100644 --- a/web-modules/apache-tapestry/src/main/java/com/baeldung/tapestry/services/AppModule.java +++ b/web-modules/apache-tapestry/src/main/java/com/baeldung/tapestry/services/AppModule.java @@ -3,17 +3,17 @@ package com.baeldung.tapestry.services; import java.io.IOException; import org.apache.tapestry5.SymbolConstants; -import org.apache.tapestry5.ioc.MappedConfiguration; -import org.apache.tapestry5.ioc.OrderedConfiguration; +import org.apache.tapestry5.commons.MappedConfiguration; +import org.apache.tapestry5.commons.OrderedConfiguration; +import org.apache.tapestry5.http.services.Request; +import org.apache.tapestry5.http.services.RequestFilter; +import org.apache.tapestry5.http.services.RequestHandler; +import org.apache.tapestry5.http.services.Response; import org.apache.tapestry5.ioc.ServiceBinder; import org.apache.tapestry5.ioc.annotations.Contribute; import org.apache.tapestry5.ioc.annotations.Local; import org.apache.tapestry5.ioc.services.ApplicationDefaults; import org.apache.tapestry5.ioc.services.SymbolProvider; -import org.apache.tapestry5.services.Request; -import org.apache.tapestry5.services.RequestFilter; -import org.apache.tapestry5.services.RequestHandler; -import org.apache.tapestry5.services.Response; import org.slf4j.Logger; /** diff --git a/web-modules/apache-tapestry/src/main/java/com/baeldung/tapestry/services/DevelopmentModule.java b/web-modules/apache-tapestry/src/main/java/com/baeldung/tapestry/services/DevelopmentModule.java index d9c8493e39..1c89587c53 100644 --- a/web-modules/apache-tapestry/src/main/java/com/baeldung/tapestry/services/DevelopmentModule.java +++ b/web-modules/apache-tapestry/src/main/java/com/baeldung/tapestry/services/DevelopmentModule.java @@ -1,7 +1,7 @@ package com.baeldung.tapestry.services; import org.apache.tapestry5.SymbolConstants; -import org.apache.tapestry5.ioc.MappedConfiguration; +import org.apache.tapestry5.commons.MappedConfiguration; /** * This module is automatically included as part of the Tapestry IoC Registry if tapestry.execution-mode diff --git a/web-modules/apache-tapestry/src/main/java/com/baeldung/tapestry/services/QaModule.java b/web-modules/apache-tapestry/src/main/java/com/baeldung/tapestry/services/QaModule.java index fc6fb595e9..d16e498a4b 100644 --- a/web-modules/apache-tapestry/src/main/java/com/baeldung/tapestry/services/QaModule.java +++ b/web-modules/apache-tapestry/src/main/java/com/baeldung/tapestry/services/QaModule.java @@ -1,7 +1,7 @@ package com.baeldung.tapestry.services; import org.apache.tapestry5.SymbolConstants; -import org.apache.tapestry5.ioc.MappedConfiguration; +import org.apache.tapestry5.commons.MappedConfiguration; import org.apache.tapestry5.ioc.ServiceBinder; /** diff --git a/web-modules/bootique/pom.xml b/web-modules/bootique/pom.xml index d06f835889..8da24ebf0a 100644 --- a/web-modules/bootique/pom.xml +++ b/web-modules/bootique/pom.xml @@ -53,6 +53,15 @@ maven-shade-plugin ${maven-shade-plugin.version} + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + + diff --git a/web-modules/jakarta-ee/pom.xml b/web-modules/jakarta-ee/pom.xml index 82993103c8..066bc14766 100644 --- a/web-modules/jakarta-ee/pom.xml +++ b/web-modules/jakarta-ee/pom.xml @@ -78,8 +78,8 @@ maven-compiler-plugin 3.8.0 - 1.8 - 1.8 + 11 + 11 diff --git a/web-modules/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java b/web-modules/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java index 2a370afe85..835275c255 100644 --- a/web-modules/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java +++ b/web-modules/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java @@ -4,6 +4,7 @@ import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -43,4 +44,7 @@ public class UserCheckFilter implements Filter { chain.doFilter(request, response); } + + public void init(FilterConfig arg) throws ServletException { + } } diff --git a/web-modules/jee-7/pom.xml b/web-modules/jee-7/pom.xml index 1b040eb9b8..00314ab35f 100644 --- a/web-modules/jee-7/pom.xml +++ b/web-modules/jee-7/pom.xml @@ -3,6 +3,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 + com.baeldung.jee-7 jee-7 1.0-SNAPSHOT jee-7 diff --git a/web-modules/jooby/conf/application.conf b/web-modules/jooby/conf/application.conf index 2f89e0eb6b..7da56eef6b 100644 --- a/web-modules/jooby/conf/application.conf +++ b/web-modules/jooby/conf/application.conf @@ -1,2 +1,4 @@ #application.secret = 2o128940921eo298e21 -#db = /url/to/the/datastore \ No newline at end of file +#db = /url/to/the/datastore + +#redis = "redis://localhost:6379" \ No newline at end of file diff --git a/web-modules/jooby/pom.xml b/web-modules/jooby/pom.xml index 6c2ce3a5c5..024a41e1d9 100644 --- a/web-modules/jooby/pom.xml +++ b/web-modules/jooby/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/maven-v4_0_0.xsd"> 4.0.0 com.baeldung.jooby jooby @@ -14,26 +14,25 @@ 1.0.0-SNAPSHOT - - - - org.jooby - modules - ${jooby.version} - pom - - - - - org.jooby - jooby-netty + io.jooby + jooby ${jooby.version} - org.jooby - jooby-jedis + io.jooby + jooby-test + ${jooby.version} + + + io.jooby + jooby-jetty + ${jooby.version} + + + io.jooby + jooby-redis ${jooby.version} @@ -42,23 +41,43 @@ test ${rest-assured.version} + + com.squareup.okhttp3 + okhttp + ${squareup.okhttp.version} + - org.apache.maven.plugins maven-shade-plugin ${maven-shade-plugin.version} + + io.jooby + jooby-maven-plugin + ${jooby.version} + + + maven-compiler-plugin + ${maven-compiler.version} + + + -parameters + + + - 1.1.3 + 2.16.1 3.1.1 com.baeldung.jooby.App - 2.4.3 + 3.2.4 + 3.8.1 + 4.9.1 \ No newline at end of file diff --git a/web-modules/jooby/public/form.html b/web-modules/jooby/public/form.html index a23620812a..bb9a705b9a 100644 --- a/web-modules/jooby/public/form.html +++ b/web-modules/jooby/public/form.html @@ -1,17 +1,18 @@ - -Insert title here + + Insert title here -
- - - - - - -
+
+
+
+
+
+
+

+ +
\ No newline at end of file diff --git a/web-modules/jooby/src/main/java/com/baeldung/jooby/App.java b/web-modules/jooby/src/main/java/com/baeldung/jooby/App.java index 94a24048c2..1bfaf6de5d 100644 --- a/web-modules/jooby/src/main/java/com/baeldung/jooby/App.java +++ b/web-modules/jooby/src/main/java/com/baeldung/jooby/App.java @@ -1,95 +1,123 @@ package com.baeldung.jooby; -import org.jooby.Jooby; -import org.jooby.Mutant; -import org.jooby.Session; -import org.jooby.jedis.Redis; -import org.jooby.jedis.RedisSessionStore; - import com.baeldung.jooby.bean.Employee; +import io.jooby.Jooby; +import io.jooby.ServerOptions; +import io.jooby.Session; +import io.jooby.SessionStore; + public class App extends Jooby { + { + setServerOptions(new ServerOptions().setPort(8080) + .setSecurePort(8433)); + } - { - port(8080); - securePort(8443); - } + { + get("/", ctx -> "Hello World!"); + } - { - get("/", () -> "Hello World!"); - } + { + get("/user/{id}", ctx -> "Hello user : " + ctx.path("id") + .value()); + get("/user/:id", ctx -> "Hello user: " + ctx.path("id") + .value()); + get("/uid:{id}", ctx -> "Hello User with id : uid = " + ctx.path("id") + .value()); + } - { - get("/user/{id}", req -> "Hello user : " + req.param("id").value()); - get("/user/:id", req -> "Hello user: " + req.param("id").value()); - get("/uid:{id}", req -> "Hello User with id : uid" + req.param("id").value()); - } + { + onStarting(() -> System.out.println("starting app")); - { - onStart(() -> { - System.out.println("starting app"); - }); + onStop(() -> System.out.println("stopping app")); - onStop(() -> { - System.out.println("stopping app"); - }); + onStarted(() -> System.out.println("app started")); + } - onStarted(() -> { - System.out.println("app started"); - }); - } + { + get("/login", ctx -> "Hello from Baeldung"); + } - { - get("/login", () -> "Hello from Baeldung"); - } + { + post("/save", ctx -> { + String userId = ctx.query("id") + .value(); + return userId; + }); + } - { - post("/save", req -> { - Mutant token = req.param("token"); - return token.intValue(); - }); - } + { + { + assets("/employee", "public/form.html"); + } - { - { - assets("/employee", "form.html"); - } + post("/submitForm", ctx -> { + Employee employee = ctx.path(Employee.class); + // ... + return "employee data saved successfully"; + }); - post("/submitForm", req -> { - Employee employee = req.params(Employee.class); - // TODO - return "empoyee data saved successfullly"; - }); - } + } - { - get("/filter", (req, resp, chain) -> { - // TODO - // resp.send(...); - chain.next(req, resp); - }); - get("/filter", (req, resp) -> { - resp.send("filter response"); - }); - } + { + decorator(next -> ctx -> { + System.out.println("first"); + // Moves execution to next handler: second + return next.apply(ctx); + }); + decorator(next -> ctx -> { + System.out.println("second"); + // Moves execution to next handler: third + return next.apply(ctx); + }); - { -// cookieSession(); - -// use(new Redis()); -// -// session(RedisSessionStore.class); + get("/handler", ctx -> "third"); + } - get("/session", req -> { - Session session = req.session(); - session.set("token", "value"); - return session.get("token").value(); - }); - } + { + get("/sessionInMemory", ctx -> { + Session session = ctx.session(); + session.put("token", "value"); + return session.get("token") + .value(); + }); + } - public static void main(final String[] args) { + { + String secret = "super secret token"; - run(App::new, args); - } + setSessionStore(SessionStore.signed(secret)); + + get("/signedSession", ctx -> { + Session session = ctx.session(); + session.put("token", "value"); + return session.get("token") + .value(); + }); + } + + { + get("/sessionInMemoryRedis", ctx -> { + Session session = ctx.session(); + session.put("token", "value"); + return session.get("token") + .value(); + }); + } + + /* This will work once redis is installed locally + { + install(new RedisModule("redis")); + setSessionStore(new RedisSessionStore(require(RedisClient.class))); + get("/redisSession", ctx -> { + Session session = ctx.session(); + session.put("token", "value"); + return session.get("token"); + }); + }*/ + + public static void main(final String[] args) { + runApp(args, App::new); + } } diff --git a/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/GetController.java b/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/GetController.java index a2c51bae70..bd43fb1717 100644 --- a/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/GetController.java +++ b/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/GetController.java @@ -1,22 +1,23 @@ package com.baeldung.jooby.mvc; -import org.jooby.Result; -import org.jooby.Results; -import org.jooby.mvc.GET; -import org.jooby.mvc.Path; +import java.util.HashMap; + +import io.jooby.ModelAndView; +import io.jooby.annotations.GET; +import io.jooby.annotations.Path; @Path("/hello") public class GetController { - @GET - public String hello() { - return "Hello Baeldung"; - } + @GET + public String hello() { + return "Hello Baeldung"; + } - @GET - @Path("/home") - public Result home() { - return Results.html("welcome").put("model", new Object()); - } + @GET + @Path("/home") + public ModelAndView home() { + return new ModelAndView("welcome.html", new HashMap<>()); + } } diff --git a/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/PostController.java b/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/PostController.java index df00e47da5..0f014580f9 100644 --- a/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/PostController.java +++ b/web-modules/jooby/src/main/java/com/baeldung/jooby/mvc/PostController.java @@ -1,14 +1,13 @@ package com.baeldung.jooby.mvc; -import org.jooby.mvc.POST; -import org.jooby.mvc.Path; +import io.jooby.annotations.POST; +import io.jooby.annotations.Path; @Path("/submit") public class PostController { - @POST - public String hello() { - return "Submit Baeldung"; - } - + @POST + public String hello() { + return "Submit Baeldung"; + } } diff --git a/web-modules/jooby/src/test/java/com/baeldung/jooby/AppLiveTest.java b/web-modules/jooby/src/test/java/com/baeldung/jooby/AppLiveTest.java index 1bd12f8bb3..e55e0e04a4 100644 --- a/web-modules/jooby/src/test/java/com/baeldung/jooby/AppLiveTest.java +++ b/web-modules/jooby/src/test/java/com/baeldung/jooby/AppLiveTest.java @@ -1,21 +1,32 @@ package com.baeldung.jooby; -import static io.restassured.RestAssured.get; -import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertEquals; -import org.jooby.test.JoobyRule; -import org.junit.ClassRule; -import org.junit.Test; +import java.io.IOException; -public class AppLiveTest { +import org.junit.jupiter.api.Test; - @ClassRule - public static JoobyRule app = new JoobyRule(new App()); +import io.jooby.JoobyTest; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; - @Test - public void given_defaultUrl_expect_fixedString() { - get("/").then().assertThat().body(equalTo("Hello World!")).statusCode(200) - .contentType("text/html;charset=UTF-8"); - } +@JoobyTest(value = App.class, port = 8080) +class AppLiveTest { + + static OkHttpClient client = new OkHttpClient(); + + @Test + void given_defaultUrl_expect_fixedString() { + Request request = new Request.Builder().url("http://localhost:8080") + .build(); + try (Response response = client.newCall(request) + .execute()) { + assertEquals("Hello World!", response.body() + .string()); + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/web-modules/jooby/src/test/java/com/baeldung/jooby/AppUnitTest.java b/web-modules/jooby/src/test/java/com/baeldung/jooby/AppUnitTest.java index 9bca30e2c1..98184e11f3 100644 --- a/web-modules/jooby/src/test/java/com/baeldung/jooby/AppUnitTest.java +++ b/web-modules/jooby/src/test/java/com/baeldung/jooby/AppUnitTest.java @@ -2,15 +2,16 @@ package com.baeldung.jooby; import static org.junit.Assert.assertEquals; -import org.jooby.test.MockRouter; import org.junit.Test; +import io.jooby.MockRouter; + public class AppUnitTest { - @Test - public void given_defaultUrl_with_mockrouter_expect_fixedString() throws Throwable { - String result = new MockRouter(new App()).get("/"); - assertEquals("Hello World!", result); - } - + @Test + public void given_defaultUrl_with_mockrouter_expect_fixedString() { + MockRouter router = new MockRouter(new App()); + assertEquals("Hello World!", router.get("/") + .value()); + } } diff --git a/web-modules/pom.xml b/web-modules/pom.xml index 90e8297e09..5d71f105b8 100644 --- a/web-modules/pom.xml +++ b/web-modules/pom.xml @@ -20,18 +20,18 @@ dropwizard google-web-toolkit jakarta-ee - java-lite + javax-servlets javax-servlets-2 jee-7 jooby linkrest - ninja + - ratpack + resteasy - restx + spark-java struts-2 vraptor diff --git a/web-modules/vraptor/src/main/java/com/baeldung/daos/UserDao.java b/web-modules/vraptor/src/main/java/com/baeldung/daos/UserDao.java index 6af1a49d25..f5d5a46de9 100644 --- a/web-modules/vraptor/src/main/java/com/baeldung/daos/UserDao.java +++ b/web-modules/vraptor/src/main/java/com/baeldung/daos/UserDao.java @@ -4,13 +4,10 @@ import com.baeldung.models.User; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; -import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Restrictions; -import org.omg.PortableInterceptor.LOCATION_FORWARD; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; -import java.util.logging.Logger; @RequestScoped public class UserDao { diff --git a/web-modules/wicket/pom.xml b/web-modules/wicket/pom.xml index c9dac11379..9348e15cdb 100644 --- a/web-modules/wicket/pom.xml +++ b/web-modules/wicket/pom.xml @@ -84,7 +84,7 @@ 7.5.0 9.2.13.v20150730 - 2.6 + 3.3.1 \ No newline at end of file