Merge branch 'eugenp:master' into master
This commit is contained in:
commit
b1ae6680d8
|
@ -1,23 +1,22 @@
|
|||
package com.baeldung.algorithms.mergeintervals;
|
||||
|
||||
import static java.lang.Integer.max;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class MergeOverlappingIntervals {
|
||||
|
||||
public List<Interval> doMerge(List<Interval> intervals) {
|
||||
// Sort the intervals based on start time
|
||||
intervals.sort((one, two) -> one.start - two.start);
|
||||
|
||||
// Create somewhere to put the merged list, start it off with the earliest starting interval
|
||||
intervals.sort(Comparator.comparingInt(interval -> interval.start));
|
||||
ArrayList<Interval> merged = new ArrayList<>();
|
||||
merged.add(intervals.get(0));
|
||||
|
||||
// Loop over each interval and merge if start time is before the end time of the
|
||||
// previous interval
|
||||
intervals.forEach(interval -> {
|
||||
if (merged.get(merged.size() - 1).end > interval.start) {
|
||||
merged.get(merged.size() - 1).setEnd(interval.end);
|
||||
Interval lastMerged = merged.get(merged.size() - 1);
|
||||
if (interval.start <= lastMerged.end){
|
||||
lastMerged.setEnd(max(interval.end, lastMerged.end));
|
||||
} else {
|
||||
merged.add(interval);
|
||||
}
|
||||
|
@ -25,5 +24,4 @@ public class MergeOverlappingIntervals {
|
|||
|
||||
return merged;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,30 +1,38 @@
|
|||
package com.baeldung.algorithms.mergeintervals;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class MergeIntervalsUnitTest {
|
||||
|
||||
private ArrayList<Interval> intervals = new ArrayList<>(Arrays.asList(
|
||||
new Interval(2, 5),
|
||||
new Interval(13, 20),
|
||||
new Interval(11, 15),
|
||||
new Interval(1, 3)
|
||||
private List<Interval> intervals = new ArrayList<>(Arrays.asList(
|
||||
// @formatter:off
|
||||
new Interval(3, 5),
|
||||
new Interval(13, 20),
|
||||
new Interval(11, 15),
|
||||
new Interval(15, 16),
|
||||
new Interval(1, 3),
|
||||
new Interval(4, 5),
|
||||
new Interval(16, 17)
|
||||
// @formatter:on
|
||||
));
|
||||
private ArrayList<Interval> intervalsMerged = new ArrayList<>(Arrays.asList(
|
||||
new Interval(1, 5),
|
||||
new Interval(11, 20)
|
||||
private List<Interval> intervalsMerged = new ArrayList<>(Arrays.asList(
|
||||
// @formatter:off
|
||||
new Interval(1, 5),
|
||||
new Interval(11, 20)
|
||||
// @formatter:on
|
||||
));
|
||||
|
||||
@Test
|
||||
void givenIntervals_whenMerging_thenReturnMergedIntervals() {
|
||||
MergeOverlappingIntervals merger = new MergeOverlappingIntervals();
|
||||
ArrayList<Interval> result = (ArrayList<Interval>) merger.doMerge(intervals);
|
||||
assertArrayEquals(intervalsMerged.toArray(), result.toArray());
|
||||
List<Interval> result = merger.doMerge(intervals);
|
||||
assertEquals(intervalsMerged, result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -3,3 +3,4 @@
|
|||
- [Find the Equilibrium Indexes of an Array in Java](https://www.baeldung.com/java-equilibrium-index-array)
|
||||
- [Moves Zeros to the End of an Array in Java](https://www.baeldung.com/java-array-sort-move-zeros-end)
|
||||
- [Finding the Majority Element of an Array in Java](https://www.baeldung.com/java-array-find-majority-element)
|
||||
- [Set Matrix Elements to Zero in Java](https://www.baeldung.com/java-set-matrix-elements-to-zero)
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
package com.baeldung.matrixtozero;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SetMatrixToZero{
|
||||
static void setZeroesByNaiveApproach(int[][] matrix) {
|
||||
int row = matrix.length;
|
||||
int col = matrix[0].length;
|
||||
int [][] result = new int[row][col];
|
||||
|
||||
for(int i = 0; i<row; i++){
|
||||
for(int j = 0; j < col; j++){
|
||||
result[i][j] = matrix[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < row; i++){
|
||||
for(int j = 0; j < col; j++){
|
||||
if(matrix[i][j] == 0){
|
||||
for(int k = 0; k < col; k++){
|
||||
result[i][k] = 0;
|
||||
}
|
||||
for(int k = 0; k < row; k++){
|
||||
result[k][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < row; i++){
|
||||
for(int j = 0; j < col; j++){
|
||||
matrix[i][j] = result[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setZeroesByTimeOptimizedApproach(int[][] matrix) {
|
||||
int rows = matrix.length;
|
||||
int cols = matrix[0].length;
|
||||
|
||||
Set<Integer> rowSet = new HashSet<>();
|
||||
Set<Integer> colSet = new HashSet<>();
|
||||
|
||||
for(int i = 0; i < rows; i++){
|
||||
for(int j = 0; j < cols; j++){
|
||||
if (matrix[i][j] == 0){
|
||||
rowSet.add(i);
|
||||
colSet.add(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int row: rowSet){
|
||||
for(int j = 0; j < cols; j++){
|
||||
matrix[row][j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(int col: colSet) {
|
||||
for(int i = 0; i < rows; i++){
|
||||
matrix[i][col] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static boolean hasZeroInFirstRow(int[][] matrix, int cols) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
if (matrix[0][j] == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean hasZeroInFirstCol(int[][] matrix, int rows) {
|
||||
for (int i = 0; i < rows; i++) {
|
||||
if (matrix[i][0] == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void markZeroesInMatrix(int[][] matrix, int rows, int cols) {
|
||||
for (int i = 1; i < rows; i++) {
|
||||
for (int j = 1; j < cols; j++) {
|
||||
if (matrix[i][j] == 0) {
|
||||
matrix[i][0] = 0;
|
||||
matrix[0][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setZeroesInRows(int[][] matrix, int rows, int cols) {
|
||||
for (int i = 1; i < rows; i++) {
|
||||
if (matrix[i][0] == 0) {
|
||||
for (int j = 1; j < cols; j++) {
|
||||
matrix[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setZeroesInCols(int[][] matrix, int rows, int cols) {
|
||||
for (int j = 1; j < cols; j++) {
|
||||
if (matrix[0][j] == 0) {
|
||||
for (int i = 1; i < rows; i++) {
|
||||
matrix[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setZeroesInFirstRow(int[][] matrix, int cols) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
matrix[0][j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void setZeroesInFirstCol(int[][] matrix, int rows) {
|
||||
for (int i = 0; i < rows; i++) {
|
||||
matrix[i][0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void setZeroesByOptimalApproach(int[][] matrix) {
|
||||
int rows = matrix.length;
|
||||
int cols = matrix[0].length;
|
||||
|
||||
boolean firstRowZero = hasZeroInFirstRow(matrix, cols);
|
||||
boolean firstColZero = hasZeroInFirstCol(matrix, rows);
|
||||
|
||||
markZeroesInMatrix(matrix, rows, cols);
|
||||
|
||||
setZeroesInRows(matrix, rows, cols);
|
||||
setZeroesInCols(matrix, rows, cols);
|
||||
|
||||
if (firstRowZero) {
|
||||
setZeroesInFirstRow(matrix, cols);
|
||||
}
|
||||
if (firstColZero) {
|
||||
setZeroesInFirstCol(matrix, rows);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.baeldung.matrixtozero;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SetMatrixToZeroUnitTest{
|
||||
@Test
|
||||
void givenMatrix_whenUsingSetZeroesByNaiveApproach_thenSetZeroes() {
|
||||
int[][] matrix = {
|
||||
{1, 2, 3},
|
||||
{4, 0, 6},
|
||||
{7, 8, 9}
|
||||
};
|
||||
int[][] expected = {
|
||||
{1, 0, 3},
|
||||
{0, 0, 0},
|
||||
{7, 0, 9}
|
||||
};
|
||||
SetMatrixToZero.setZeroesByNaiveApproach(matrix);
|
||||
assertArrayEquals(expected, matrix);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMatrix_whenUsingSetZeroesByTimeOptimizedApproach_thenSetZeroes() {
|
||||
int[][] matrix = {
|
||||
{1, 2, 3},
|
||||
{4, 0, 6},
|
||||
{7, 8, 9}
|
||||
};
|
||||
int[][] expected = {
|
||||
{1, 0, 3},
|
||||
{0, 0, 0},
|
||||
{7, 0, 9}
|
||||
};
|
||||
SetMatrixToZero.setZeroesByTimeOptimizedApproach(matrix);
|
||||
assertArrayEquals(expected, matrix);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMatrix_whenUsingSetZeroesByOptimalApproach_thenSetZeroes() {
|
||||
int[][] matrix = {
|
||||
{1, 2, 3},
|
||||
{4, 0, 6},
|
||||
{7, 8, 9}
|
||||
};
|
||||
int[][] expected = {
|
||||
{1, 0, 3},
|
||||
{0, 0, 0},
|
||||
{7, 0, 9}
|
||||
};
|
||||
SetMatrixToZero.setZeroesByOptimalApproach(matrix);
|
||||
assertArrayEquals(expected, matrix);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.baeldung.printnullvalues;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class Employee {
|
||||
private String name;
|
||||
private int age;
|
||||
private String department;
|
||||
|
||||
public Employee(String name, int age, String department) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
this.department = department;
|
||||
}
|
||||
|
||||
public String toStringUsingNullCheck() {
|
||||
return "Name: " + (name != null ? name : "Unknown") +
|
||||
", Age: " + age +
|
||||
", Department: " + (department != null ? department : "Unknown");
|
||||
}
|
||||
|
||||
public String toStringUsingOptional() {
|
||||
return "Name: " + Optional.ofNullable(name).orElse("Unknown") +
|
||||
", Age: " + age +
|
||||
", Department: " + Optional.ofNullable(department).orElse("Unknown");
|
||||
}
|
||||
|
||||
private String getDefaultIfNull(String value, String defaultValue) {
|
||||
return value != null ? value : defaultValue;
|
||||
}
|
||||
|
||||
public String toStringUsingCustomHelper() {
|
||||
return "Name: " + getDefaultIfNull(name, "Unknown") +
|
||||
", Age: " + age +
|
||||
", Department: " + getDefaultIfNull(department, "Unknown");
|
||||
}
|
||||
|
||||
public String toStringUsingObjects() {
|
||||
return "Name: " + Objects.toString(name, "Unknown") +
|
||||
", Age: " + age +
|
||||
", Department: " + Objects.toString(department, "Unknown");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.printnullvalues;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class PrintingNullValuesUnitTest {
|
||||
Employee employee = new Employee(null, 30, null);
|
||||
String expected = "Name: Unknown, Age: 30, Department: Unknown";
|
||||
|
||||
@Test
|
||||
public void givenNullValues_whenToStringUsingNullCheck_thenCorrectStringReturned() {
|
||||
assertEquals(expected, employee.toStringUsingNullCheck());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNullValues_whenToStringUsingOptional_thenCorrectStringReturned() {
|
||||
assertEquals(expected, employee.toStringUsingOptional());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNullValues_whenToStringUsingCustomHelper_thenCorrectStringReturned() {
|
||||
assertEquals(expected, employee.toStringUsingCustomHelper());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNullValues_whenToStringUsingObjects_thenCorrectStringReturned() {
|
||||
assertEquals(expected, employee.toStringUsingObjects());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
## Relevant Articles:
|
||||
- [[<-- Prev]](/core-java-modules/core-java-networking-4)
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-networking-5</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-networking-5</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-validator</groupId>
|
||||
<artifactId>commons-validator</artifactId>
|
||||
<version>${commons-validator.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>${jsoup.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${httpclient.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
<version>${javax.ws.rs-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.core</groupId>
|
||||
<artifactId>jersey-common</artifactId>
|
||||
<version>${jersey-common.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${spring-web.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<commons-validator.version>1.7</commons-validator.version>
|
||||
<jsoup.version>1.17.2</jsoup.version>
|
||||
<httpclient.version>4.5.2</httpclient.version>
|
||||
<javax.ws.rs-api.version>2.1.1</javax.ws.rs-api.version>
|
||||
<jersey-common.version>2.22.2</jersey-common.version>
|
||||
<spring-web.version>6.0.6</spring-web.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,57 @@
|
|||
package com.baeldung.redirectedurl;
|
||||
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
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.HttpClients;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class RedirectedUrlUnitTest {
|
||||
String canonicalUrl = "http://www.baeldung.com/";
|
||||
String expectedRedirectedUrl = "https://www.baeldung.com/";
|
||||
|
||||
@Test
|
||||
public void givenOriginalUrl_whenFindRedirectUrlUsingHttpURLConnection_thenCorrectRedirectedUrlReturned() throws IOException {
|
||||
URL url = new URL(canonicalUrl);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setInstanceFollowRedirects(true);
|
||||
int status = connection.getResponseCode();
|
||||
String redirectedUrl = null;
|
||||
if (status == HttpURLConnection.HTTP_MOVED_PERM || status == HttpURLConnection.HTTP_MOVED_TEMP) {
|
||||
redirectedUrl = connection.getHeaderField("Location");
|
||||
}
|
||||
connection.disconnect();
|
||||
assertEquals(expectedRedirectedUrl, redirectedUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenOriginalUrl_whenFindRedirectUrlUsingHttpClient_thenCorrectRedirectedUrlReturned() throws IOException {
|
||||
RequestConfig config = RequestConfig.custom()
|
||||
.setRedirectsEnabled(false)
|
||||
.build();
|
||||
try (CloseableHttpClient httpClient = HttpClients.custom()
|
||||
.setDefaultRequestConfig(config)
|
||||
.build()) {
|
||||
HttpGet httpGet = new HttpGet(canonicalUrl);
|
||||
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
String redirectedUrl = null;
|
||||
if (statusCode == HttpURLConnection.HTTP_MOVED_PERM || statusCode == HttpURLConnection.HTTP_MOVED_TEMP) {
|
||||
org.apache.http.Header[] headers = response.getHeaders("Location");
|
||||
if (headers.length > 0) {
|
||||
redirectedUrl = headers[0].getValue();
|
||||
}
|
||||
}
|
||||
assertEquals(expectedRedirectedUrl, redirectedUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -165,6 +165,7 @@
|
|||
<module>core-java-networking</module>
|
||||
<module>core-java-networking-2</module>
|
||||
<module>core-java-networking-4</module>
|
||||
<module>core-java-networking-5</module>
|
||||
<module>core-java-nio</module>
|
||||
<module>core-java-nio-2</module>
|
||||
<module>core-java-numbers</module>
|
||||
|
|
|
@ -49,11 +49,23 @@
|
|||
|
||||
<properties>
|
||||
<jool.version>0.9.12</jool.version>
|
||||
<parallel-collectors.version>2.6.0</parallel-collectors.version>
|
||||
<parallel-collectors.version>3.0.0</parallel-collectors.version>
|
||||
<vavr.version>0.9.0</vavr.version>
|
||||
<eclipse-collections.version>8.2.0</eclipse-collections.version>
|
||||
<streamex.version>0.8.1</streamex.version>
|
||||
<protonpack.version>1.15</protonpack.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>21</source>
|
||||
<target>21</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
package com.baeldung.parallel_collectors;
|
||||
|
||||
import com.pivovarit.collectors.ParallelCollectors;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
public class ParallelCollectorsVirtualThreadsManualTest {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ParallelCollectorsVirtualThreadsManualTest.class);
|
||||
|
||||
// increase the number of parallel processes to find the max number of threads on your machine
|
||||
@Test
|
||||
public void givenParallelism_whenUsingOSThreads_thenShouldRunOutOfThreads() {
|
||||
int parallelProcesses = 50_000;
|
||||
|
||||
var e = Executors.newFixedThreadPool(parallelProcesses);
|
||||
|
||||
var result = timed(() -> Stream.iterate(0, i -> i + 1).limit(parallelProcesses)
|
||||
.collect(ParallelCollectors.parallel(i -> fetchById(i), toList(), e, parallelProcesses))
|
||||
.join());
|
||||
|
||||
log.info("{}", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenParallelism_whenUsingVThreads_thenShouldProcessInParallel() {
|
||||
int parallelProcesses = 1000_000;
|
||||
|
||||
var result = timed(() -> Stream.iterate(0, i -> i + 1).limit(parallelProcesses)
|
||||
.collect(ParallelCollectors.parallel(i -> fetchById(i), toList()))
|
||||
.join());
|
||||
|
||||
log.info("{}", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenParallelismAndPCollectors2_whenUsingVThreads_thenShouldProcessInParallel() {
|
||||
int parallelProcesses = 1000_000;
|
||||
|
||||
var result = timed(() -> Stream.iterate(0, i -> i + 1).limit(parallelProcesses)
|
||||
.collect(ParallelCollectors.parallel(i -> fetchById(i), toList(), Executors.newVirtualThreadPerTaskExecutor(), Integer.MAX_VALUE))
|
||||
.join());
|
||||
|
||||
log.info("{}", result);
|
||||
}
|
||||
|
||||
private static String fetchById(int id) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore shamelessly
|
||||
}
|
||||
|
||||
return "user-" + id;
|
||||
}
|
||||
|
||||
private static <T> T timed(Supplier<T> supplier) {
|
||||
var before = Instant.now();
|
||||
T result = supplier.get();
|
||||
var after = Instant.now();
|
||||
log.info("Execution time: {} ms", Duration.between(before, after).toMillis());
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -34,7 +34,7 @@
|
|||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${spring.webmvc.version}</version>
|
||||
<version>${springdoc-openapi-webmvc-ui.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -71,6 +71,7 @@
|
|||
<java.version>17</java.version>
|
||||
<conductor.client.version>2.0.8</conductor.client.version>
|
||||
<spring.webmvc.version>2.1.0</spring.webmvc.version>
|
||||
<springdoc-openapi-webmvc-ui.version>2.5.0</springdoc-openapi-webmvc-ui.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -19,10 +19,15 @@
|
|||
<version>${mockito-inline.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.32</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<mockito-inline.version>5.2.0</mockito-inline.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.builder.implementation;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class GenericBuilder<T> {
|
||||
|
||||
private final Supplier<T> supplier;
|
||||
|
||||
private GenericBuilder(Supplier<T> supplier) {
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
public static <T> GenericBuilder<T> of(Supplier<T> supplier) {
|
||||
return new GenericBuilder<>(supplier);
|
||||
}
|
||||
|
||||
public <P> GenericBuilder<T> with(BiConsumer<T, P> consumer, P value) {
|
||||
return new GenericBuilder<>(() -> {
|
||||
T object = supplier.get();
|
||||
consumer.accept(object, value);
|
||||
return object;
|
||||
});
|
||||
}
|
||||
|
||||
public T build() {
|
||||
return supplier.get();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.builder.implementation;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
@Setter
|
||||
public class LombokPost {
|
||||
|
||||
private String title;
|
||||
|
||||
private String text;
|
||||
|
||||
private String category;
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.baeldung.builder.implementation;
|
||||
|
||||
public class Post {
|
||||
|
||||
private String title;
|
||||
|
||||
private String text;
|
||||
|
||||
private String category;
|
||||
|
||||
Post(Builder builder) {
|
||||
this.title = builder.title;
|
||||
this.text = builder.text;
|
||||
this.category = builder.category;
|
||||
}
|
||||
|
||||
Post() {}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public void setCategory(String category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Post{" + "title='" + title + '\'' + ", text='" + text + '\'' + ", category='" + category + '\'' + '}';
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String title;
|
||||
private String text;
|
||||
private String category;
|
||||
|
||||
public Builder() {}
|
||||
|
||||
public Builder title(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder text(String text) {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder category(String category) {
|
||||
this.category = category;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Post build() {
|
||||
return new Post(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.builder.implementation;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class BuilderImplementationUnitTest {
|
||||
|
||||
@Test
|
||||
void givenClassicBuilder_whenBuild_thenReturnObject() {
|
||||
|
||||
Post post = new Post.Builder()
|
||||
.title("Java Builder Pattern")
|
||||
.text("Explaining how to implement the Builder Pattern in Java")
|
||||
.category("Programming")
|
||||
.build();
|
||||
|
||||
assertEquals("Java Builder Pattern", post.getTitle());
|
||||
assertEquals("Explaining how to implement the Builder Pattern in Java", post.getText());
|
||||
assertEquals("Programming", post.getCategory());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenGenericBuilder_whenBuild_thenReturnObject() {
|
||||
|
||||
Post post = GenericBuilder.of(Post::new)
|
||||
.with(Post::setTitle, "Java Builder Pattern")
|
||||
.with(Post::setText, "Explaining how to implement the Builder Pattern in Java")
|
||||
.with(Post::setCategory, "Programming")
|
||||
.build();
|
||||
|
||||
assertEquals("Java Builder Pattern", post.getTitle());
|
||||
assertEquals("Explaining how to implement the Builder Pattern in Java", post.getText());
|
||||
assertEquals("Programming", post.getCategory());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenLombokBuilder_whenBuild_thenReturnObject() {
|
||||
|
||||
LombokPost post = LombokPost.builder()
|
||||
.title("Java Builder Pattern")
|
||||
.text("Explaining how to implement the Builder Pattern in Java")
|
||||
.category("Programming")
|
||||
.build();
|
||||
|
||||
assertEquals("Java Builder Pattern", post.getTitle());
|
||||
assertEquals("Explaining how to implement the Builder Pattern in Java", post.getText());
|
||||
assertEquals("Programming", post.getCategory());
|
||||
}
|
||||
}
|
|
@ -69,6 +69,7 @@
|
|||
<module>spring-boot-persistence-mongodb</module>
|
||||
<module>spring-boot-persistence-mongodb-2</module>
|
||||
<module>spring-boot-persistence-mongodb-3</module>
|
||||
<module>spring-boot-persistence-mongodb-4</module>
|
||||
<module>spring-data-arangodb</module>
|
||||
<!--<module>spring-data-cassandra</module>--> <!-- failing after upgrading to jdk17. JDK 17 compatibility in progress CASSANDRA-16895 -->
|
||||
<module>spring-data-cassandra-test</module>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# Relevant Articles
|
||||
|
||||
- [ZonedDateTime with Spring Data MongoDB](https://www.baeldung.com/spring-data-mongodb-zoneddatetime)
|
||||
- [A Guide to @DBRef in MongoDB](https://www.baeldung.com/spring-mongodb-dbref-annotation)
|
||||
- More articles: [[<--prev]](../spring-boot-persistence-mongodb-3)
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-boot-persistence-mongodb-4</artifactId>
|
||||
<name>spring-boot-persistence-mongodb-4</name>
|
||||
<description>This is simple boot application for Spring boot persistence mongodb test</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!-- MongoDB -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -1,5 +1,6 @@
|
|||
package com.baeldung.mongodb.dbref;
|
||||
|
||||
import com.baeldung.mongodb.dbref.repository.PersonRepository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -7,8 +8,6 @@ import org.springframework.boot.ApplicationArguments;
|
|||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.baeldung.mongodb.dbref.repository.PersonRepository;
|
||||
|
||||
@Component
|
||||
public class DbRefTester implements ApplicationRunner {
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
package com.baeldung.mongodb.dbref.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Document(collection = "Person")
|
||||
public class Person {
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
package com.baeldung.mongodb.dbref.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
import com.baeldung.mongodb.dbref.model.Person;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
public interface PersonRepository extends MongoRepository<Person, String> {
|
||||
|
|
@ -1,15 +1,14 @@
|
|||
package com.baeldung.zoneddatetime.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.zoneddatetime.converter.ZonedDateTimeReadConverter;
|
||||
import com.baeldung.zoneddatetime.converter.ZonedDateTimeWriteConverter;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
|
||||
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
|
||||
import com.baeldung.zoneddatetime.converter.ZonedDateTimeReadConverter;
|
||||
import com.baeldung.zoneddatetime.converter.ZonedDateTimeWriteConverter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@EnableMongoRepositories(basePackages = { "com.baeldung" })
|
||||
public class MongoConfig extends AbstractMongoClientConfiguration {
|
|
@ -1,7 +1,6 @@
|
|||
package com.baeldung.zoneddatetime.repository;
|
||||
|
||||
import com.baeldung.zoneddatetime.model.Action;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
import com.baeldung.zoneddatetime.model.Action;
|
||||
|
||||
public interface ActionRepository extends MongoRepository<Action, String> { }
|
|
@ -0,0 +1 @@
|
|||
spring.application.name=spring-boot-persistence-mongodb-4
|
|
@ -1,11 +1,11 @@
|
|||
package com.baeldung.mongodb.dbref;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.mongodb.dbref.model.Person;
|
||||
import com.baeldung.mongodb.dbref.model.Pet;
|
||||
import com.baeldung.mongodb.dbref.repository.PersonRepository;
|
||||
import com.mongodb.BasicDBObjectBuilder;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.DBRef;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -14,12 +14,11 @@ import org.springframework.data.mongodb.core.MongoTemplate;
|
|||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.mongodb.dbref.model.Person;
|
||||
import com.baeldung.mongodb.dbref.model.Pet;
|
||||
import com.baeldung.mongodb.dbref.repository.PersonRepository;
|
||||
import com.mongodb.BasicDBObjectBuilder;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.DBRef;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
|
@ -1,5 +1,8 @@
|
|||
package com.baeldung.zoneddatetime;
|
||||
|
||||
import com.baeldung.zoneddatetime.config.MongoConfig;
|
||||
import com.baeldung.zoneddatetime.model.Action;
|
||||
import com.baeldung.zoneddatetime.repository.ActionRepository;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
@ -10,10 +13,6 @@ import org.springframework.data.mongodb.core.MongoOperations;
|
|||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.baeldung.zoneddatetime.config.MongoConfig;
|
||||
import com.baeldung.zoneddatetime.model.Action;
|
||||
import com.baeldung.zoneddatetime.repository.ActionRepository;
|
||||
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
|
|
@ -0,0 +1 @@
|
|||
spring.mongodb.embedded.version=4.4.9
|
|
@ -4,8 +4,6 @@
|
|||
- [Spring Boot Integration Testing with Embedded MongoDB](http://www.baeldung.com/spring-boot-embedded-mongodb)
|
||||
- [Upload and Retrieve Files Using MongoDB and Spring Boot](https://www.baeldung.com/spring-boot-mongodb-upload-file)
|
||||
- [GridFS in Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-gridfs)
|
||||
- [ZonedDateTime with Spring Data MongoDB](https://www.baeldung.com/spring-data-mongodb-zoneddatetime)
|
||||
- [A Guide to @DBRef in MongoDB](https://www.baeldung.com/spring-mongodb-dbref-annotation)
|
||||
- [Import Data to MongoDB From JSON File Using Java](https://www.baeldung.com/java-import-json-mongodb)
|
||||
- [Spring Data MongoDB – Configure Connection](https://www.baeldung.com/spring-data-mongodb-connection)
|
||||
- More articles: [[next-->]](../spring-boot-persistence-mongodb-2)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.projection.model;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
@Document(collection = "student")
|
||||
public class Student {
|
||||
@Id
|
||||
private String id;
|
||||
private String name;
|
||||
private Long age;
|
||||
|
||||
public Student(String id, String name, Long age) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public Long getAge() {
|
||||
return age;
|
||||
}
|
||||
public void setAge(Long age) {
|
||||
this.age = age;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.projection.repository;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.repository.Aggregation;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
import com.baeldung.projection.model.Student;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface StudentRepository extends MongoRepository<Student, String> {
|
||||
@Aggregation(pipeline = {
|
||||
"{ '$skip': ?0 }",
|
||||
"{ '$limit': ?1 }"
|
||||
})
|
||||
List<Student> findAll(Long skip, Long limit);
|
||||
@Aggregation(pipeline = {
|
||||
"{ '$match': { 'age': ?0 } }",
|
||||
"{ $skip: ?1 }",
|
||||
"{ $limit: ?2 }"
|
||||
})
|
||||
List<Student> findAllByAgeCriteria(Long age, Long skip, Long limit);
|
||||
@Aggregation(pipeline = {
|
||||
"{ '$match': { 'id' : ?0 } }",
|
||||
"{ '$sort' : { 'id' : 1 } }",
|
||||
"{ '$skip' : ?1 }",
|
||||
"{ '$limit' : ?2 }"
|
||||
})
|
||||
List<Student> findByStudentId(final String studentId, Long skip, Long limit);
|
||||
Page<Student> findAll(Pageable pageable);
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package com.baeldung.projection;
|
||||
|
||||
import com.baeldung.projection.config.ProjectionConfig;
|
||||
import com.baeldung.projection.model.Student;
|
||||
import com.baeldung.projection.repository.StudentRepository;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = ProjectionConfig.class)
|
||||
public class StudentIntegrationTest {
|
||||
@Autowired
|
||||
private StudentRepository studentRepository;
|
||||
private List<Student> studentList;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Student student1 = new Student("A", "Abraham", 15L);
|
||||
Student student2 = new Student("B", "Usman", 30L);
|
||||
Student student3 = new Student("C", "David", 20L);
|
||||
Student student4 = new Student("D", "Tina", 45L);
|
||||
Student student5 = new Student("E", "Maria", 33L);
|
||||
|
||||
studentList = Arrays.asList(student1, student2, student3, student4, student5);
|
||||
studentRepository.saveAll(studentList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenRetrievingAllStudents_thenReturnsCorrectNumberOfRecords() {
|
||||
// WHEN
|
||||
List<Student> result = studentRepository.findAll(0L, 5L);
|
||||
// THEN
|
||||
assertEquals(5, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenLimitingAndSkipping_thenReturnsLimitedStudents() {
|
||||
// WHEN
|
||||
List<Student> result = studentRepository.findAll(3L, 2L);
|
||||
// THEN
|
||||
assertEquals(2, result.size());
|
||||
assertEquals("Tina", result.get(0).getName());
|
||||
assertEquals("Maria", result.get(1).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFilteringByAge_thenReturnsStudentsMatchingCriteria() {
|
||||
// WHEN
|
||||
List<Student> result = studentRepository.findAllByAgeCriteria(30L, 0L, 10L);
|
||||
// THEN
|
||||
assertEquals(1, result.size());
|
||||
assertEquals("Usman", result.get(0).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFindingById_thenReturnsMatchingStudent() {
|
||||
// WHEN
|
||||
List<Student> result = studentRepository.findByStudentId("A", 0L, 5L);
|
||||
// THEN
|
||||
assertEquals(1, result.size());
|
||||
assertEquals("Abraham", result.get(0).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFindByStudentIdUsingPageable_thenReturnsPageOfStudents() {
|
||||
// GIVEN
|
||||
Sort sort = Sort.by(Sort.Direction.DESC, "id");
|
||||
Pageable pageable = PageRequest.of(0, 5, sort);
|
||||
|
||||
// WHEN
|
||||
Page<Student> resultPage = studentRepository.findAll(pageable);
|
||||
|
||||
// THEN
|
||||
assertEquals(5, resultPage.getTotalElements());
|
||||
assertEquals("Maria", resultPage.getContent().get(0).getName());
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -30,7 +31,7 @@
|
|||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
||||
<version>${spring-boot.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -46,47 +47,11 @@
|
|||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<properties>
|
||||
<spring-boot.version>3.2.0-SNAPSHOT</spring-boot.version>
|
||||
<junit-jupiter.version>5.10.0</junit-jupiter.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spring-boot.version>3.2.4</spring-boot.version> <!-- Requires at least spring framework version 6.1.X to work -->
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -4,8 +4,7 @@ import org.springframework.boot.SpringApplication;
|
|||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@SpringBootApplication
|
||||
@ComponentScan(basePackages = "com.baledung.jdbcclient")
|
||||
@SpringBootApplication(scanBasePackages = "com.baeldung")
|
||||
public class JdbcClientDemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -737,7 +737,7 @@
|
|||
<module>libraries-security</module>
|
||||
<module>libraries-server-2</module>
|
||||
<module>libraries-server</module>
|
||||
<module>libraries-stream</module>
|
||||
<!-- <module>libraries-stream</module> JDK21-->
|
||||
<module>libraries-testing-2</module>
|
||||
<module>libraries-transform</module>
|
||||
<module>libraries</module> <!-- very long running -->
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<url>https://repo.spring.io/snapshot</url> <!-- We need this for experimental dependencies not available on Maven Central -->
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
|
|
|
@ -14,14 +14,6 @@
|
|||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>repository.spring.release</id>
|
||||
<name>Spring GA Repository</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -73,7 +65,7 @@
|
|||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
<version>${springdoc-openapi-webmvc-ui.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
|
@ -102,7 +94,6 @@
|
|||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<version>3.2.0-M2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
|
@ -202,18 +193,6 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>3.2.0-M2</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<profiles>
|
||||
|
||||
<profile>
|
||||
|
@ -300,6 +279,8 @@
|
|||
<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
|
||||
<jedis.version>5.0.2</jedis.version>
|
||||
<spring-kafka.version>3.1.2</spring-kafka.version>
|
||||
<spring-boot.version>3.2.4</spring-boot.version>
|
||||
<springdoc-openapi-webmvc-ui.version>2.5.0</springdoc-openapi-webmvc-ui.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
<version>${springdoc-openapi-webmvc-ui.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -100,6 +100,7 @@
|
|||
<maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version>
|
||||
<native.maven.plugin.version>0.9.17</native.maven.plugin.version>
|
||||
<java.version>17</java.version>
|
||||
<springdoc-openapi-webmvc-ui.version>2.5.0</springdoc-openapi-webmvc-ui.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -89,7 +89,7 @@
|
|||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
<version>${springdoc-openapi-webmvc-ui.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
|
@ -211,46 +211,10 @@
|
|||
<maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version>
|
||||
<start-class>com.baeldung.sample.TodoApplication</start-class>
|
||||
<mockserver.version>5.14.0</mockserver.version>
|
||||
<spring-boot.version>3.2.0-SNAPSHOT</spring-boot.version>
|
||||
<spring-boot.version>3.2.4</spring-boot.version>
|
||||
<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
|
||||
<jupiter.version>5.10.0</jupiter.version>
|
||||
<springdoc-openapi-webmvc-ui.version>2.5.0</springdoc-openapi-webmvc-ui.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
</project>
|
|
@ -40,7 +40,7 @@
|
|||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
<version>${springdoc-openapi-webmvc-ui.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
|
@ -119,6 +119,7 @@
|
|||
|
||||
<properties>
|
||||
<springdoc.version>2.2.0</springdoc.version>
|
||||
<springdoc-openapi-webmvc-ui.version>2.5.0</springdoc-openapi-webmvc-ui.version>
|
||||
<springdoc-openapi-maven-plugin.version>1.4</springdoc-openapi-maven-plugin.version>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
<version>${springdoc-openapi-webmvc-ui.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
|
@ -53,6 +53,7 @@
|
|||
<properties>
|
||||
<springdoc.version>2.1.0</springdoc.version>
|
||||
<javax.version>1.3.2</javax.version>
|
||||
<springdoc-openapi-webmvc-ui.version>2.5.0</springdoc-openapi-webmvc-ui.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -14,14 +14,16 @@ import org.springframework.stereotype.Component;
|
|||
matchIfMissing = true)
|
||||
@Component
|
||||
public class ApplicationRunnerTaskExecutor implements ApplicationRunner {
|
||||
private TaskService taskService;
|
||||
|
||||
private final TaskService taskService;
|
||||
|
||||
public ApplicationRunnerTaskExecutor(TaskService taskService) {
|
||||
this.taskService = taskService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
public void run(ApplicationArguments args) {
|
||||
taskService.execute("application runner task");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,14 +13,14 @@ import org.springframework.stereotype.Component;
|
|||
matchIfMissing = true)
|
||||
@Component
|
||||
public class CommandLineTaskExecutor implements CommandLineRunner {
|
||||
private TaskService taskService;
|
||||
private final TaskService taskService;
|
||||
|
||||
public CommandLineTaskExecutor(TaskService taskService) {
|
||||
this.taskService = taskService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
public void run(String... args) {
|
||||
taskService.execute("command line runner task");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ import org.springframework.stereotype.Service;
|
|||
|
||||
@Service
|
||||
public class TaskService {
|
||||
private static Logger logger = LoggerFactory.getLogger(TaskService.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(TaskService.class);
|
||||
|
||||
public void execute(String task) {
|
||||
logger.info("do " + task);
|
||||
logger.info("do {}", task);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
package com.baeldung.prevent.commandline.application.runner.execution;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
|
||||
import com.baeldung.prevent.commandline.application.runner.execution.ApplicationRunnerTaskExecutor;
|
||||
import com.baeldung.prevent.commandline.application.runner.execution.CommandLineTaskExecutor;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
|
||||
@SpringBootTest
|
||||
class RunApplicationIntegrationTest {
|
||||
@SpyBean
|
||||
|
@ -21,6 +18,6 @@ class RunApplicationIntegrationTest {
|
|||
@Test
|
||||
void whenContextLoads_thenRunnersRun() throws Exception {
|
||||
verify(applicationRunnerTaskExecutor, times(1)).run(any());
|
||||
verify(commandLineTaskExecutor, times(1)).run(any());
|
||||
verify(commandLineTaskExecutor, times(1)).run(any(String[].class));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,14 +90,6 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>repository.spring.milestone</id>
|
||||
<name>Spring Milestone Repository</name>
|
||||
<url>https://repo.spring.io/release</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
|
|
@ -44,8 +44,18 @@
|
|||
<version>${spring-boot.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<version>${byte-buddy.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<byte-buddy.version>1.14.13</byte-buddy.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
|
|
@ -44,8 +44,18 @@
|
|||
<version>${spring-boot.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<version>${byte-buddy.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<byte-buddy.version>1.14.13</byte-buddy.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
|
|
@ -52,8 +52,19 @@
|
|||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<version>${byte-buddy.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<byte-buddy.version>1.14.13</byte-buddy.version>
|
||||
</properties>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
|
|
@ -60,6 +60,12 @@
|
|||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<version>${byte-buddy.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -82,6 +88,7 @@
|
|||
<properties>
|
||||
<spring-cloud-dependencies.version>2021.0.3</spring-cloud-dependencies.version>
|
||||
<spring-cloud-netflix-zuul.version>2.2.7.RELEASE</spring-cloud-netflix-zuul.version>
|
||||
<byte-buddy.version>1.14.13</byte-buddy.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -15,27 +15,6 @@
|
|||
<relativePath>../parent-boot-3</relativePath>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<name>Spring Milestone</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-snapshot</id>
|
||||
<name>Spring Snapshot</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-plugins-snapshot</id>
|
||||
<name>Spring Plugins Snapshot</name>
|
||||
<url>https://repo.spring.io/plugins-snapshot</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
|
|
@ -15,32 +15,6 @@
|
|||
<relativePath>../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<name>Spring Milestone</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-snapshot</id>
|
||||
<name>Spring Snapshot</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-plugins-snapshot</id>
|
||||
<name>Spring Plugins Snapshot</name>
|
||||
<url>https://repo.spring.io/plugins-snapshot</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-plugins-milestone</id>
|
||||
<name>Spring Plugins Milestone</name>
|
||||
<url>https://repo.spring.io/plugins-milestone</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -84,5 +58,31 @@
|
|||
<spring-native.version>0.12.1</spring-native.version>
|
||||
<log4j2.version>2.17.1</log4j2.version>
|
||||
</properties>
|
||||
<!-- Experimental dependency in this repository cannot rely on Maven Central alone -->
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<name>Spring Milestone</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-snapshot</id>
|
||||
<name>Spring Snapshot</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-plugins-snapshot</id>
|
||||
<name>Spring Plugins Snapshot</name>
|
||||
<url>https://repo.spring.io/plugins-snapshot</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-plugins-milestone</id>
|
||||
<name>Spring Plugins Milestone</name>
|
||||
<url>https://repo.spring.io/plugins-milestone</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
</project>
|
|
@ -20,6 +20,7 @@
|
|||
<module>spring-reactive-data</module>
|
||||
<module>spring-reactive-2</module>
|
||||
<module>spring-reactive-3</module>
|
||||
<module>spring-reactive-4</module>
|
||||
<module>spring-reactive-client</module>
|
||||
<module>spring-reactive-client-2</module>
|
||||
<module>spring-reactive-filters</module>
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-reactive-4</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>spring-reactive-4</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>spring sample project about new features</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-3</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<wiremock-standalone.version>3.4.2</wiremock-standalone.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.wiremock</groupId>
|
||||
<artifactId>wiremock-standalone</artifactId>
|
||||
<version>${wiremock-standalone.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringReactiveApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringReactiveApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@RestController
|
||||
public class TraceController {
|
||||
|
||||
@GetMapping(value = "/trace-annotated")
|
||||
public Mono<String> trace(@RequestHeader(name = "traceId") final String traceId) {
|
||||
return Mono.just("TraceId: ".concat(traceId));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/trace-exceptional")
|
||||
public Mono<String> traceExceptional() {
|
||||
return Mono.just("Traced");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.filters;
|
||||
|
||||
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 ExceptionalTraceFilter implements WebFilter {
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||
if (exchange.getRequest()
|
||||
.getPath()
|
||||
.toString()
|
||||
.equals("/trace-exceptional")) {
|
||||
exchange.getRequest()
|
||||
.getHeaders()
|
||||
.add("traceId", "TRACE-ID");
|
||||
}
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.filters;
|
||||
|
||||
import org.springframework.web.reactive.function.server.HandlerFilterFunction;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class TraceHandlerFilterFunction implements HandlerFilterFunction<ServerResponse, ServerResponse> {
|
||||
|
||||
@Override
|
||||
public Mono<ServerResponse> filter(ServerRequest request, HandlerFunction<ServerResponse> handlerFunction) {
|
||||
|
||||
ServerRequest serverRequest = ServerRequest.from(request)
|
||||
.header("traceId", "FUNCTIONAL-TRACE-ID")
|
||||
.build();
|
||||
return handlerFunction.handle(serverRequest);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.filters;
|
||||
|
||||
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 TraceWebFilter implements WebFilter {
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||
exchange.getRequest()
|
||||
.mutate()
|
||||
.header("traceId", "ANNOTATED-TRACE-ID");
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.filters;
|
||||
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.reactive.function.client.ClientRequest;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
|
||||
|
||||
public final class WebClientFilters {
|
||||
|
||||
public static ExchangeFilterFunction modifyRequestHeaders(final MultiValueMap<String, String> changedMap) {
|
||||
return (request, next) -> {
|
||||
final ClientRequest clientRequest = ClientRequest.from(request)
|
||||
.header("traceId", "TRACE-ID")
|
||||
.build();
|
||||
changedMap.addAll(clientRequest.headers());
|
||||
return next.exchange(clientRequest);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.handler;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
|
||||
|
||||
@Component
|
||||
public class TraceRouterHandler {
|
||||
|
||||
public Mono<ServerResponse> handle(final ServerRequest serverRequest) {
|
||||
|
||||
final String traceId = serverRequest.headers()
|
||||
.firstHeader("traceId");
|
||||
assert traceId != null;
|
||||
final Mono<String> body = Mono.just("TraceId: ".concat(traceId));
|
||||
return ok().body(body, String.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.router;
|
||||
|
||||
import com.baeldung.filters.TraceHandlerFilterFunction;
|
||||
import com.baeldung.handler.TraceRouterHandler;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
||||
|
||||
@Configuration
|
||||
public class TraceRouter {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> routes(TraceRouterHandler routerHandler) {
|
||||
return route(GET("/trace-functional-filter"), routerHandler::handle).filter(new TraceHandlerFilterFunction())
|
||||
.and(route().GET("/trace-functional-before", routerHandler::handle)
|
||||
.before(request -> ServerRequest.from(request)
|
||||
.header("traceId", "FUNCTIONAL-TRACE-ID")
|
||||
.build())
|
||||
.build());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.controller;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
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.autoconfigure.web.reactive.WebFluxTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.reactive.server.EntityExchangeResult;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebFluxTest(controllers = TraceController.class)
|
||||
public class TraceControllerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webTestClient;
|
||||
|
||||
@Test
|
||||
void whenCallTraceAnnotatedEndpoint_thenResponseContainsTraceId() {
|
||||
EntityExchangeResult<String> result = webTestClient.get()
|
||||
.uri("/trace-annotated")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody(String.class)
|
||||
.returnResult();
|
||||
|
||||
final String body = "TraceId: ANNOTATED-TRACE-ID";
|
||||
assertEquals(result.getResponseBody(), body);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCallTraceExceptionalEndpoint_thenThrowsException() {
|
||||
EntityExchangeResult<Map> result = webTestClient.get()
|
||||
.uri("/trace-exceptional")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is5xxServerError()
|
||||
.expectBody(Map.class)
|
||||
.returnResult();
|
||||
|
||||
assertNotNull(result.getResponseBody());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.baeldung.filters;
|
||||
|
||||
import static com.baeldung.filters.WebClientFilters.modifyRequestHeaders;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.get;
|
||||
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
|
||||
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
|
||||
|
||||
@WireMockTest
|
||||
public class WebClientFilterUnitTest {
|
||||
|
||||
@RegisterExtension
|
||||
static WireMockExtension extension = WireMockExtension.newInstance()
|
||||
.options(wireMockConfig().dynamicPort()
|
||||
.dynamicHttpsPort())
|
||||
.build();
|
||||
|
||||
@Test
|
||||
void whenCallEndpoint_thenRequestHeadersModified() {
|
||||
extension.stubFor(get("/test").willReturn(aResponse().withStatus(200)
|
||||
.withBody("SUCCESS")));
|
||||
|
||||
final MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||
|
||||
WebClient webClient = WebClient.builder()
|
||||
.filter(modifyRequestHeaders(map))
|
||||
.build();
|
||||
String actual = sendGetRequest(webClient);
|
||||
|
||||
final String body = "SUCCESS";
|
||||
Assertions.assertEquals(actual, body);
|
||||
Assertions.assertEquals("TRACE-ID", map.getFirst("traceId"));
|
||||
}
|
||||
|
||||
private String sendGetRequest(final WebClient webClient) {
|
||||
return webClient.get()
|
||||
.uri(getUrl())
|
||||
.retrieve()
|
||||
.bodyToMono(String.class)
|
||||
.block();
|
||||
}
|
||||
|
||||
private String getUrl() {
|
||||
return "http://localhost:" + extension.getPort() + "/test";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.baeldung.handler;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
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.boot.test.autoconfigure.web.reactive.WebFluxTest;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.reactive.server.EntityExchangeResult;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
import com.baeldung.router.TraceRouter;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = { TraceRouter.class, TraceRouterHandler.class })
|
||||
@WebFluxTest
|
||||
public class TraceRouteHandlerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
private WebTestClient webTestClient;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
webTestClient = WebTestClient.bindToApplicationContext(context)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCallTraceFunctionalFilterEndpoint_thenResponseContainsTraceId() {
|
||||
EntityExchangeResult<String> result = webTestClient.get()
|
||||
.uri("/trace-functional-filter")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody(String.class)
|
||||
.returnResult();
|
||||
|
||||
final String body = "TraceId: FUNCTIONAL-TRACE-ID";
|
||||
assertEquals(result.getResponseBody(), body);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCallTraceFunctionalBeforeEndpoint_thenResponseContainsTraceId() {
|
||||
EntityExchangeResult<String> result = webTestClient.get()
|
||||
.uri("/trace-functional-before")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody(String.class)
|
||||
.returnResult();
|
||||
|
||||
final String body = "TraceId: FUNCTIONAL-TRACE-ID";
|
||||
assertEquals(result.getResponseBody(), body);
|
||||
}
|
||||
}
|
|
@ -65,6 +65,12 @@
|
|||
<version>${couchbaseMock.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<version>${byte-buddy.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -129,6 +135,7 @@
|
|||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<java.version>11</java.version>
|
||||
<byte-buddy.version>1.14.13</byte-buddy.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -11,9 +11,10 @@
|
|||
<description>WebFlux and Spring Security OAuth</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.spring.reactive</groupId>
|
||||
<artifactId>spring-reactive-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-3</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -62,4 +63,8 @@
|
|||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<start-class>com.baeldung.reactive.oauth.Spring5ReactiveOauthApplication</start-class>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,6 +1,7 @@
|
|||
package com.baeldung.reactive.oauth;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
|
||||
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
||||
import org.springframework.security.web.server.SecurityWebFilterChain;
|
||||
|
@ -10,10 +11,11 @@ public class SecurityConfig {
|
|||
|
||||
@Bean
|
||||
public SecurityWebFilterChain configure(ServerHttpSecurity http) throws Exception {
|
||||
return http.authorizeExchange()
|
||||
return http.authorizeExchange(auth -> auth
|
||||
.pathMatchers("/about").permitAll()
|
||||
.anyExchange().authenticated()
|
||||
.and().oauth2Login()
|
||||
.and().build();
|
||||
.anyExchange().authenticated())
|
||||
.oauth2Login(Customizer.withDefaults())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,9 +4,12 @@ import org.springframework.boot.SpringApplication;
|
|||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository;
|
||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||
import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction;
|
||||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
@PropertySource("classpath:default-application.yml")
|
||||
|
@ -24,4 +27,13 @@ public class Spring5ReactiveOauthApplication {
|
|||
.filter(filter)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ReactiveClientRegistrationRepository clientRegistrations() {
|
||||
ClientRegistration registration = ClientRegistration.withRegistrationId("bael").authorizationGrantType(
|
||||
AuthorizationGrantType.CLIENT_CREDENTIALS).clientId("bael").tokenUri("default").build();
|
||||
|
||||
return new InMemoryReactiveClientRegistrationRepository(registration);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.baeldung.webclient.authorizationcodeclient.configuration;
|
|||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
||||
import org.springframework.security.web.server.SecurityWebFilterChain;
|
||||
|
||||
|
@ -9,13 +10,9 @@ import org.springframework.security.web.server.SecurityWebFilterChain;
|
|||
public class WebSecurityConfig {
|
||||
@Bean
|
||||
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
http.authorizeExchange()
|
||||
.anyExchange()
|
||||
.authenticated()
|
||||
.and()
|
||||
.oauth2Client()
|
||||
.and()
|
||||
.formLogin();
|
||||
http.authorizeExchange(s-> s.anyExchange().authenticated())
|
||||
.oauth2Client(Customizer.withDefaults())
|
||||
.formLogin(Customizer.withDefaults());
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.baeldung.webclient.authorizationcodelogin.configuration;
|
|||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
||||
import org.springframework.security.web.server.SecurityWebFilterChain;
|
||||
|
||||
|
@ -9,11 +10,8 @@ import org.springframework.security.web.server.SecurityWebFilterChain;
|
|||
public class WebSecurityConfig {
|
||||
@Bean
|
||||
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
http.authorizeExchange()
|
||||
.anyExchange()
|
||||
.authenticated()
|
||||
.and()
|
||||
.oauth2Login();
|
||||
http.authorizeExchange(s-> s.anyExchange().authenticated())
|
||||
.oauth2Login(Customizer.withDefaults());
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,60 @@
|
|||
package com.baeldung.webclient.clientcredentials.configuration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.oauth2.client.AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager;
|
||||
import org.springframework.security.oauth2.client.InMemoryReactiveOAuth2AuthorizedClientService;
|
||||
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
|
||||
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository;
|
||||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
|
||||
import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction;
|
||||
import org.springframework.security.oauth2.client.web.server.UnAuthenticatedServerOAuth2AuthorizedClientRepository;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
@Configuration
|
||||
public class WebClientConfig {
|
||||
|
||||
@Bean
|
||||
WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations) {
|
||||
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, new UnAuthenticatedServerOAuth2AuthorizedClientRepository());
|
||||
oauth.setDefaultClientRegistrationId("bael");
|
||||
return WebClient.builder()
|
||||
.filter(oauth)
|
||||
ReactiveClientRegistrationRepository clientRegistrations(
|
||||
@Value("${spring.security.oauth2.client.provider.bael.token-uri}") String token_uri,
|
||||
@Value("${spring.security.oauth2.client.registration.bael.client-id}") String client_id,
|
||||
@Value("${spring.security.oauth2.client.registration.bael.client-secret}") String client_secret,
|
||||
@Value("${spring.security.oauth2.client.registration.bael.authorization-grant-type}") String authorizationGrantType
|
||||
|
||||
) {
|
||||
ClientRegistration registration = ClientRegistration
|
||||
.withRegistrationId("keycloak")
|
||||
.tokenUri(token_uri)
|
||||
.clientId(client_id)
|
||||
.clientSecret(client_secret)
|
||||
.authorizationGrantType(new AuthorizationGrantType(authorizationGrantType))
|
||||
.build();
|
||||
return new InMemoryReactiveClientRegistrationRepository(registration);
|
||||
}
|
||||
@Bean
|
||||
public AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager(
|
||||
ReactiveClientRegistrationRepository clientRegistrationRepository) {
|
||||
InMemoryReactiveOAuth2AuthorizedClientService clientService =
|
||||
new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrationRepository);
|
||||
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
|
||||
ReactiveOAuth2AuthorizedClientProviderBuilder.builder().clientCredentials().build();
|
||||
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
|
||||
new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
|
||||
clientRegistrationRepository, clientService);
|
||||
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
|
||||
return authorizedClientManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebClient webClient(AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager auth2AuthorizedClientManager) {
|
||||
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =
|
||||
new ServerOAuth2AuthorizedClientExchangeFilterFunction(auth2AuthorizedClientManager);
|
||||
oauth2Client.setDefaultClientRegistrationId("bael");
|
||||
return WebClient.builder()
|
||||
.filter(oauth2Client)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@ public class WebClientConfig {
|
|||
public WebClient configureWebClient() {
|
||||
return WebClient.builder()
|
||||
.build();
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,9 +9,7 @@ import org.springframework.security.web.server.SecurityWebFilterChain;
|
|||
public class WebSecurityConfig {
|
||||
@Bean
|
||||
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
http.authorizeExchange()
|
||||
.anyExchange()
|
||||
.permitAll();
|
||||
http.authorizeExchange(s -> s.anyExchange().permitAll());
|
||||
return http.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package com.baeldung.reactive.oauth;
|
||||
|
||||
import com.baeldung.webclient.clientcredentials.configuration.WebClientConfig;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@SpringBootTest(classes = WebClientConfig.class)
|
||||
public class Spring5ReactiveOauthIntegrationTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
<version>${springdoc-openapi-webmvc-ui.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
|
@ -45,6 +45,7 @@
|
|||
<properties>
|
||||
<springdoc.version>2.4.0</springdoc.version>
|
||||
<start-class>com.baeldung.basicauth.SpringBootSpringdocBasicAuth</start-class>
|
||||
<springdoc-openapi-webmvc-ui.version>2.5.0</springdoc-openapi-webmvc-ui.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
Loading…
Reference in New Issue