Skip to content

Commit

Permalink
Merge pull request #5 from maoudia/feature/upgrade-records-config
Browse files Browse the repository at this point in the history
Switch to Java Records configuration
  • Loading branch information
aoudiamoncef authored Feb 9, 2024
2 parents f44eb28 + ce28bf6 commit 511ebab
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 115 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Application" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" nameIsGenerated="true">
<option name="ACTIVE_PROFILES" value="dev" />
<envs>
<env name="spring.profiles.active" value="test" />
<env name="reactor.schedulers.defaultBoundedElasticOnVirtualThreads" value="true" />
</envs>
<module name="bulk-update-with-spring-data-mongodb-reactive" />
<option name="SPRING_BOOT_MAIN_CLASS" value="com.maoudia.tutorial.Application" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="CollectionServiceTest" type="JUnit" factoryName="JUnit" nameIsGenerated="true">
<module name="bulk-update-with-spring-data-mongodb-reactive" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="com.maoudia.tutorial.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<option name="PACKAGE_NAME" value="com.maoudia.tutorial" />
<option name="MAIN_CLASS_NAME" value="com.maoudia.tutorial.CollectionServiceTest" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" />
<envs>
<env name="spring.profiles.active" value="test" />
<env name="reactor.schedulers.defaultBoundedElasticOnVirtualThreads" value="true" />
</envs>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
139 changes: 84 additions & 55 deletions bulk-update-with-spring-data-mongodb-reactive/pom.xml
Original file line number Diff line number Diff line change
@@ -1,58 +1,87 @@
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.maoudia</groupId>
<artifactId>bulk-update-with-spring-data-mongodb-reactive</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Bulk Update with Spring data MongoDB Reactive</name>
<description>Bulk Update with Spring data MongoDB Reactive</description>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.maoudia</groupId>
<artifactId>bulk-update-with-spring-data-mongodb-reactive</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Bulk Update with Spring data MongoDB Reactive</name>
<description>Bulk Update with Spring data MongoDB Reactive</description>
<properties>
<java.version>21</java.version>
<netty-resolver-dns-native-macos.version>4.1.76.Final</netty-resolver-dns-native-macos.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-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</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>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mongodb</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<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>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mongodb</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>macos-arm</id>
<activation>
<os>
<family>mac</family>
<arch>aarch64</arch>
</os>
</activation>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-resolver-dns-native-macos</artifactId>
<version>${netty-resolver-dns-native-macos.version}</version>
<classifier>osx-aarch_64</classifier>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -1,52 +1,52 @@
package com.maoudia.tutorial;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.validation.annotation.Validated;

import java.net.URI;

/**
* Configuration properties for the application.
* These properties are bound from the application.yml (or application.properties) file using the specified prefix.
*/
@ConfigurationProperties(prefix = "app")
public class AppProperties{
private int bulkSize;
private int bufferMaxSize;
private String collectionName;
private String enrichingKey;
private String enrichingUri;

public int getBulkSize() {
return bulkSize;
}

public void setBulkSize(final int bulkSize) {
this.bulkSize = bulkSize;
}

public int getBufferMaxSize() {
return bufferMaxSize;
}

public void setBufferMaxSize(final int bufferMaxSize) {
this.bufferMaxSize = bufferMaxSize;
}

public String getCollectionName() {
return collectionName;
}

public void setCollectionName(final String collectionName) {
this.collectionName = collectionName;
}

public String getEnrichingKey() {
return enrichingKey;
}

public void setEnrichingKey(final String enrichingKey) {
this.enrichingKey = enrichingKey;
}

public String getEnrichingUri() {
return enrichingUri;
}

public void setEnrichingUri(final String enrichingUri) {
this.enrichingUri = enrichingUri;
}
@Validated
public record AppProperties(

/*
* The bulk size configuration.
*/
@DefaultValue("128")
@Positive
int bulkSize,

/*
* The maximum buffer size configuration.
*/
@DefaultValue("1024")
@Positive
int bufferMaxSize,

/*
* The name of the collection.
*/
@NotBlank
String collectionName,

/*
* The key used for enriching.
*/
@NotBlank
String enrichingKey,

/*
* The URI used for enriching.
*/
@NotNull
URI enrichingUri
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import reactor.core.scheduler.Schedulers;

@SpringBootApplication(exclude = MongoReactiveRepositoriesAutoConfiguration.class)
@ConfigurationPropertiesScan("com.maoudia.tutorial")
Expand All @@ -28,7 +29,7 @@ public Application(AppProperties properties, CollectionService service) {

@Override
public void run(final String... args) {
service.enrichAll(properties.getCollectionName(), properties.getEnrichingKey(), properties.getEnrichingUri())
service.enrichAll(properties.collectionName(), properties.enrichingKey(), properties.enrichingUri())
.doOnSubscribe(unused -> LOGGER.info("------------------< Staring Collection Enriching Command >-------------------"))
.doOnNext(bulkWriteResult -> LOGGER.info("Bulk write result with {} modified document(s)", bulkWriteResult.getModifiedCount()))
.doOnError(throwable -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,20 @@ public CollectionService(AppProperties properties,
this.client = client;
}

public Flux<BulkWriteResult> enrichAll(String collectionName, String enrichingKey, String enrichingUri) {
public Flux<BulkWriteResult> enrichAll(String collectionName,
String enrichingKey,
URI enrichingUri) {
return template.findAll(Document.class, collectionName)
.onBackpressureBuffer(properties.getBufferMaxSize())
.onBackpressureBuffer(properties.bufferMaxSize())
.flatMap(document -> enrich(document, enrichingKey, enrichingUri))
.map(CollectionService::toReplaceOneModel)
.window(properties.getBulkSize())
.window(properties.bulkSize())
.flatMap(replaceOneModelFlux -> bulkWrite(replaceOneModelFlux, collectionName));
}
private Publisher<Document> enrich(Document document, String enrichingKey, String enrichingUri) {

private Publisher<Document> enrich(Document document,
String enrichingKey,
URI enrichingUri) {
return getEnrichingDocument(enrichingUri)
.map(enrichingDocument -> {
document.put(enrichingKey, enrichingDocument);
Expand All @@ -59,13 +64,15 @@ private Publisher<Document> enrich(Document document, String enrichingKey, Strin
});
}

private Mono<Document> getEnrichingDocument(String enrichingUri) {
private Mono<Document> getEnrichingDocument(URI enrichingUri) {
return client.get()
.uri(URI.create(enrichingUri))
.uri(enrichingUri)
.retrieve()
.bodyToMono(Document.class);
}
private Flux<BulkWriteResult> bulkWrite(Flux<ReplaceOneModel<Document>> updateOneModelFlux, String collectionName) {

private Flux<BulkWriteResult> bulkWrite(Flux<ReplaceOneModel<Document>> updateOneModelFlux,
String collectionName) {
return updateOneModelFlux
.collectList()
.flatMapMany(updateOneModels -> template.getCollection(collectionName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
import com.mongodb.bulk.BulkWriteResult;
import com.mongodb.internal.bulk.WriteRequest;
import org.bson.Document;
import org.junit.ClassRule;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.BindMode;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.MongoDBContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import reactor.test.StepVerifier;

import java.util.Arrays;
Expand All @@ -24,11 +24,12 @@
@Testcontainers
class CollectionServiceTest {


@Container
public static GenericContainer<?> jsonServerContainer = new GenericContainer<>("clue/json-server:latest")
.withExposedPorts(80)
.withFileSystemBind("./data/product/db.json", "/data/db.json");
.withFileSystemBind("./data/product/db.json", "/data/db.json", BindMode.READ_ONLY)
.waitingFor(Wait.forHttp("/").forStatusCode(200).forPort(80))
.withReuse(true);

@Container
private static final MongoDBContainer mongoDBContainer = new MongoDBContainer("mongo:7.0.2");
Expand Down Expand Up @@ -57,14 +58,14 @@ void multipleBulkWriteResultsAreReturned() {
Document givenDocument3 = new Document();
givenDocument3.put("_id", "628ea3edb5110304e5e814f8");
givenDocument3.put("type", "housenumber");
template.insert(Arrays.asList(givenDocument1, givenDocument2, givenDocument3), properties.getCollectionName()).blockLast();
template.insert(Arrays.asList(givenDocument1, givenDocument2, givenDocument3), properties.collectionName()).blockLast();

BulkWriteResult expectedBulkWriteResult1 = BulkWriteResult.acknowledged(WriteRequest.Type.REPLACE, 2, 2, Collections.emptyList(),
Collections.emptyList());
BulkWriteResult expectedBulkWriteResult2 = BulkWriteResult.acknowledged(WriteRequest.Type.REPLACE, 1, 1, Collections.emptyList(),
Collections.emptyList());

command.enrichAll(properties.getCollectionName(), properties.getEnrichingKey() , properties.getEnrichingUri())
command.enrichAll(properties.collectionName(), properties.enrichingKey() , properties.enrichingUri())
.as(StepVerifier::create)
.expectNext(expectedBulkWriteResult1)
.expectNext(expectedBulkWriteResult2)
Expand Down

0 comments on commit 511ebab

Please sign in to comment.