Merge branch 'eugenp:master' into master

This commit is contained in:
sIvanovKonstantyn 2024-04-14 18:18:06 +02:00 committed by GitHub
commit b1ae6680d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
86 changed files with 1494 additions and 262 deletions

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}

View File

@ -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)

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -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());
}
}

View File

@ -0,0 +1,2 @@
## Relevant Articles:
- [[<-- Prev]](/core-java-modules/core-java-networking-4)

View File

@ -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>

View File

@ -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);
}
}
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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);
}
}
}

View File

@ -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());
}
}

View File

@ -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>

View File

@ -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)

View File

@ -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>

View File

@ -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 {

View File

@ -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 {

View File

@ -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> {

View File

@ -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 {

View File

@ -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> { }

View File

@ -0,0 +1 @@
spring.application.name=spring-boot-persistence-mongodb-4

View File

@ -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

View File

@ -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;

View File

@ -0,0 +1 @@
spring.mongodb.embedded.version=4.4.9

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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());
}
}

View File

@ -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>

View File

@ -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) {

View File

@ -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 -->

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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");
}
}

View File

@ -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");
}
}

View File

@ -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);
}
}

View File

@ -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));
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
};
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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>

View File

@ -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());
}
}

View File

@ -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";
}
}

View File

@ -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);
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}
}

View File

@ -11,6 +11,6 @@ public class WebClientConfig {
public WebClient configureWebClient() {
return WebClient.builder()
.build();
};
}
}

View File

@ -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();
}
}

View File

@ -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

View File

@ -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>