diff --git a/docs/audit-stores/community/couchbase-audit-store.md b/docs/audit-stores/community/couchbase-audit-store.md index 69d212de..b7d1a6fa 100644 --- a/docs/audit-stores/community/couchbase-audit-store.md +++ b/docs/audit-stores/community/couchbase-audit-store.md @@ -1,6 +1,6 @@ --- title: Couchbase -sidebar_position: 5 +sidebar_position: 6 --- import Tabs from '@theme/Tabs'; diff --git a/docs/audit-stores/community/dynamodb-audit-store.md b/docs/audit-stores/community/dynamodb-audit-store.md index 7d8f00ef..0e24fb5b 100644 --- a/docs/audit-stores/community/dynamodb-audit-store.md +++ b/docs/audit-stores/community/dynamodb-audit-store.md @@ -1,6 +1,6 @@ --- title: DynamoDB -sidebar_position: 4 +sidebar_position: 5 --- import Tabs from '@theme/Tabs'; diff --git a/docs/audit-stores/community/mongodb-reactive-audit-store.md b/docs/audit-stores/community/mongodb-reactive-audit-store.md new file mode 100644 index 00000000..fa7b2580 --- /dev/null +++ b/docs/audit-stores/community/mongodb-reactive-audit-store.md @@ -0,0 +1,114 @@ +--- +title: MongoDB Reactive +sidebar_position: 3 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# MongoDB Reactive Audit Store + +The MongoDB reactive audit store (`MongoDBReactiveAuditStore`) enables Flamingock to record execution history and ensure safe coordination across distributed deployments using MongoDB as the storage backend, through the official MongoDB reactive streams driver. + +> For a conceptual explanation of the audit store vs target systems, see [Audit store vs target system](../../get-started/audit-store-vs-target-system.md). + +## Version compatibility + +| Component | Version Requirement | +|----------------------------------|---------------------| +| MongoDB Reactive Streams Driver | 4.0.0+ | + +MongoDB 4.0+ is recommended for optimal performance and feature support. + +## Installation + +Add the MongoDB reactive streams driver dependency to your project: + + + +```kotlin +implementation("org.mongodb:mongodb-driver-reactivestreams:4.0.0") +``` + + +```xml + + org.mongodb + mongodb-driver-reactivestreams + 4.0.0 + +``` + + + +## Basic setup + +Configure the audit store from a MongoDB reactive target system to get the connection configuration: + +```java +var auditStore = MongoDBReactiveAuditStore.from(mongoDbReactiveTargetSystem); +``` + +A `MongoDBReactiveAuditStore` must be created from an existing target system that implements `MongoDBReactiveExternalSystem` - such as `MongoDBReactiveTargetSystem` or `MongoDBSpringDataReactiveTargetSystem`. + +This ensures that both components point to the **same external MongoDB database**: + +- The **Target System** applies your business changes. +- The **Audit Store** stores the execution history associated with those changes. + +Internally, the Audit Store takes the Target System's underlying MongoDB database and creates its **own dedicated access handle**, keeping audit operations isolated while still referring to the same physical system. + +> For a full conceptual explanation of this relationship, see +> **[Target Systems vs Audit Store](../../get-started/audit-store-vs-target-system.md)**. + +Optional configurations can be added via `.withXXX()` methods. + +:::info Register Audit Store +Once created, you need to register this audit store with Flamingock. See [Registering the community audit store](../introduction.md#registering-the-community-audit-store) for details. +::: + +## Optional configuration (.withXXX() methods) + +These configurations can be customized via `.withXXX()` methods with **no global context fallback**: + +| Configuration | Method | Default | Description | +|--------------------------|-----------------------------------|--------------------------|-----------------------------------------| +| `Auto Create` | `.withAutoCreate(enabled)` | `true` | Auto-create collections and indexes | +| `WriteConcern` | `.withWriteConcern(concern)` | `MAJORITY` with journal | Write acknowledgment level | +| `ReadConcern` | `.withReadConcern(concern)` | `MAJORITY` | Read isolation level | +| `ReadPreference` | `.withReadPreference(pref)` | `PRIMARY` | Server selection for reads | +| `Audit Repository Name` | `.withAuditRepositoryName(name)` | `flamingockAuditLog` | Collection name for audit entries | +| `Lock Repository Name` | `.withLockRepositoryName(name)` | `flamingockLock` | Collection name for distributed locks | + +**Important**: These default values are optimized for maximum consistency and should ideally be left unchanged. Override them only for testing purposes or exceptional cases. + +## Configuration example + +Here's a comprehensive example showing the configuration: + +```java +// Create a MongoDB Reactive Target System +MongoDBReactiveTargetSystem mongoDbReactiveTargetSystem = new MongoDBReactiveTargetSystem("mongodb", mongoReactiveClient, auditDatabase); +// Audit store configuration (mandatory via constructor) +var auditStore = MongoDBReactiveAuditStore.from(mongoDbReactiveTargetSystem) + .withWriteConcern(WriteConcern.W1) // Optional configuration + .withReadPreference(ReadPreference.secondary()); // Optional configuration + +// Register with Flamingock +Flamingock.builder() + .setAuditStore(auditStore) + .addTargetSystems(targetSystems...) + .build(); +``` + +**Audit store configuration resolution:** +- **MongoDB reactive target system**: Must be provided via `from()` method. Gets the reactive `MongoDatabase` from the target system. +- **WriteConcern**: Uses explicit configuration instead of default +- **ReadPreference**: Uses explicit configuration instead of default + +This architecture ensures explicit audit store configuration with no fallback dependencies. + +## Next steps + +- Learn about [Target systems](../../target-systems/introduction.md) +- 👉 See a [full example project](https://github.com/flamingock/flamingock-java-examples) diff --git a/docs/audit-stores/community/sql-audit-store.md b/docs/audit-stores/community/sql-audit-store.md index 1b0027cf..1db56e16 100644 --- a/docs/audit-stores/community/sql-audit-store.md +++ b/docs/audit-stores/community/sql-audit-store.md @@ -1,6 +1,6 @@ --- title: SQL -sidebar_position: 3 +sidebar_position: 4 --- import Tabs from '@theme/Tabs'; diff --git a/docs/audit-stores/introduction.md b/docs/audit-stores/introduction.md index 7acc8a01..f1d4b76a 100644 --- a/docs/audit-stores/introduction.md +++ b/docs/audit-stores/introduction.md @@ -34,6 +34,7 @@ The audit store is **automatically provided and managed** by Flamingock Cloud. N Alternatively, you can configure your own audit store using one of the supported databases: - [MongoDB audit store](./community/mongodb-audit-store.md) +- [MongoDB Reactive audit store](./community/mongodb-reactive-audit-store.md) - [DynamoDB audit store](./community/dynamodb-audit-store.md) - [Couchbase audit store](./community/couchbase-audit-store.md) - [SQL audit store](./community/sql-audit-store.md) diff --git a/docs/target-systems/couchbase-target-system.md b/docs/target-systems/couchbase-target-system.md index 5d63235e..00037b46 100644 --- a/docs/target-systems/couchbase-target-system.md +++ b/docs/target-systems/couchbase-target-system.md @@ -1,6 +1,6 @@ --- title: Couchbase -sidebar_position: 6 +sidebar_position: 8 --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; diff --git a/docs/target-systems/dynamodb-target-system.md b/docs/target-systems/dynamodb-target-system.md index 5eae6a3f..8cdf08ec 100644 --- a/docs/target-systems/dynamodb-target-system.md +++ b/docs/target-systems/dynamodb-target-system.md @@ -1,6 +1,6 @@ --- title: DynamoDB -sidebar_position: 5 +sidebar_position: 7 --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; diff --git a/docs/target-systems/introduction.md b/docs/target-systems/introduction.md index d91e512e..250911a9 100644 --- a/docs/target-systems/introduction.md +++ b/docs/target-systems/introduction.md @@ -54,7 +54,9 @@ The standard choice for systems without native transaction support: These implementations leverage native transaction capabilities for automatic rollback: - [MongoDB target system](../target-systems/mongodb-target-system.md) - For MongoDB with the sync driver +- [MongoDB Reactive target system](../target-systems/mongodb-reactive-target-system.md) - For MongoDB with the reactive streams driver - [MongoDB Spring Data target system](../target-systems/mongodb-springdata-target-system.md) - For MongoDB with Spring Data +- [MongoDB Spring Data Reactive target system](../target-systems/mongodb-springdata-reactive-target-system.md) - For MongoDB with reactive Spring Data - [SQL target system](../target-systems/sql-target-system.md) - For relational databases (PostgreSQL, MySQL, etc.) - [DynamoDB target system](../target-systems/dynamodb-target-system.md) - For Amazon DynamoDB - [Couchbase target system](../target-systems/couchbase-target-system.md) - For Couchbase diff --git a/docs/target-systems/mongodb-reactive-target-system.md b/docs/target-systems/mongodb-reactive-target-system.md new file mode 100644 index 00000000..53355bb2 --- /dev/null +++ b/docs/target-systems/mongodb-reactive-target-system.md @@ -0,0 +1,156 @@ +--- +title: MongoDB Reactive +sidebar_position: 4 +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# MongoDB Reactive Target System + +The MongoDB Reactive target system (`MongoDBReactiveTargetSystem`) enables Flamingock to apply changes to MongoDB databases using the official MongoDB reactive streams driver. As a transactional target system, it supports automatic rollback through MongoDB's native transaction capabilities. + +## Version compatibility + +| Component | Version Requirement | +|-----------|-------------------| +| MongoDB Reactive Streams Driver | 4.0.0+ | + +MongoDB 4.0+ is required for transaction support. + +## Installation + +Add the MongoDB reactive streams driver dependency to your project (version 4.0.0+ required): + + + +```kotlin +implementation("org.mongodb:mongodb-driver-reactivestreams:4.0.0") +``` + + +```xml + + org.mongodb + mongodb-driver-reactivestreams + 4.0.0 + +``` + + + +## Basic setup + +Configure the target system: + +```java +var mongoTarget = new MongoDBReactiveTargetSystem("user-database-id", mongoClient, "userDb"); +``` + +The constructor requires the target system name, a reactive `MongoClient`, and the database name. Optional configurations can be added via `.withXXX()` methods. + +:::info Register Target System +Once created, you need to register this target system with Flamingock. See [Registering target systems](introduction.md#registering-target-systems) for details. +::: + +## Target System configuration + +The MongoDB Reactive target system uses Flamingock's [split dependency resolution architecture](introduction.md#dependency-injection) with separate flows for target system configuration and change execution dependencies. + +### Constructor dependencies (mandatory) + +These dependencies must be provided at target system creation time with **no global context fallback**: + +| Dependency | Constructor Parameter | Description | +|------------|----------------------|-------------| +| `MongoClient` (reactive) | `mongoClient` | Reactive MongoDB connection client - **required** for both target system configuration and change execution | +| `String` | `databaseName` | Target database name - **required** to identify which database changes will affect | + +## Dependencies available to Changes + +Changes can access dependencies through [dependency injection with fallback](../changes/anatomy-and-structure.md#method-parameters-and-dependency-injection): + +1. **Target system context** (highest priority) - `MongoClient`, `MongoDatabase`, `ClientSession` (all from the reactive streams driver) +2. **Target system additional dependencies** - added via `.addDependency()` or `.setProperty()` +3. **Global context** (fallback) - shared dependencies available to all target systems + +## Configuration example + +Here's a comprehensive example showing the new architecture: + +```java +// Target system configuration (mandatory via constructor) +var mongoTarget = new MongoDBReactiveTargetSystem("user-database", productionMongoClient, "userDb") + .addDependency(auditService); // Additional dependency for changes + +// Global context with shared dependencies +Flamingock.builder() + .addDependency(emailService) // Available to all target systems + .addDependency(logService) // Available to all target systems + .addTargetSystems(mongoTarget) + .build(); +``` + +**Target system configuration resolution:** +- **MongoClient**: Must be provided via constructor (`productionMongoClient`) +- **Database name**: Must be provided via constructor (`"userDb"`) + +**Change dependency resolution for Changes in "user-database":** +- **MongoClient**: From target system context (`productionMongoClient`) +- **MongoDatabase**: From target system context (derived from `productionMongoClient` + `"userDb"`) +- **ClientSession**: From target system context (created by Flamingock) +- **AuditService**: From target system additional dependencies +- **EmailService**: From global context (fallback) +- **LogService**: From global context (fallback) + +This architecture ensures explicit target system configuration while providing flexible dependency access for changes. + +## Transactional support + +For a Change to leverage MongoDB's transactional capabilities, it must use the reactive `ClientSession` parameter. Flamingock uses the injected `MongoClient` and `MongoDatabase` dependencies to create and manage this session's lifecycle - starting the transaction before execution, committing on success, and rolling back on failure. + +> For detailed information on transaction handling, see [Transactions](../changes/transactions.md). + +```java +@TargetSystem("user-database-id") +@Change(id = "create-users", author = "team") // order extracted from filename +public class _0001__CreateUsers { + + @Apply + public void apply(MongoDatabase db, ClientSession session) { + // The reactive ClientSession is required for transactional execution + // Flamingock uses the target system's MongoClient to create this session + // and handles transaction start, commit, and rollback automatically + MongoCollection users = db.getCollection("users"); + Publisher insert = users.insertOne(session, new Document("name", "John")); + + // The Change method runs synchronously from Flamingock's point of view, so the + // publisher must be awaited before returning - it won't execute on its own. + Mono.from(insert).block(); + } +} +``` + +**How transactions work:** +1. **Session creation**: Flamingock uses the target system's reactive `MongoClient` to create a `ClientSession` +2. **Transaction management**: The same `MongoClient` and `MongoDatabase` handle transaction operations +3. **Lifecycle**: Flamingock automatically starts the transaction, commits on success, or rolls back on failure + +Without the `ClientSession` parameter, operations will execute but won't participate in transactions. + +:::info Reactive publishers must be consumed +The reactive streams driver returns `Publisher` objects that only execute once subscribed to - Flamingock does not subscribe to them for you. Every publisher produced inside a Change must be awaited before the method returns, so the operation actually completes within the Change's lifecycle and any failure surfaces synchronously (required for Flamingock to catch it and trigger rollback). + +The example above uses Project Reactor's `Mono.from(publisher).block()`, since Reactor is already a common dependency in reactive stacks (and a hard requirement for the [Spring Data Reactive target system](mongodb-springdata-reactive-target-system.md)). If you'd rather not add Reactor as a dependency, subscribe with your own `Subscriber` (or RxJava's `Flowable.fromPublisher(...)`) and block until `onComplete`/`onError`. +::: + +## Available dependencies in Changes + +Your Changes can inject MongoDB reactive-specific dependencies like `MongoClient`, `MongoDatabase`, and `ClientSession` (for transactions), but are not limited to these. The target system provides these dependencies through its context, and you can add additional dependencies via `.addDependency()` that take precedence over global dependencies. + +For comprehensive details on change dependency resolution, see [Change Anatomy & Structure](../changes/anatomy-and-structure.md). + +## Next steps + +- Learn about [Target systems](introduction.md) +- Explore [Changes](../changes/introduction.md) +- See [Flamingock examples](https://github.com/flamingock/flamingock-java-examples) diff --git a/docs/target-systems/mongodb-springdata-reactive-target-system.md b/docs/target-systems/mongodb-springdata-reactive-target-system.md new file mode 100644 index 00000000..19317c1e --- /dev/null +++ b/docs/target-systems/mongodb-springdata-reactive-target-system.md @@ -0,0 +1,163 @@ +--- +title: MongoDB Spring Data Reactive +sidebar_position: 5 +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# MongoDB Spring Data Reactive Target System + +The MongoDB Spring Data Reactive target system (`MongoDBSpringDataReactiveTargetSystem`) enables Flamingock to apply changes to MongoDB databases using Spring Data's `ReactiveMongoTemplate`. As a transactional target system, it integrates with Spring's reactive transaction management and supports automatic rollback through MongoDB's native transaction capabilities. + +## Version compatibility + +| Component | Version Requirement | +|-----------|-------------------| +| Spring Data MongoDB (reactive) | 3.1.x - 4.x | +| MongoDB Reactive Streams Driver | 4.0.0+ | +| Project Reactor | 3.4.x+ | + +Spring Data MongoDB versions from 3.1.x through 4.x are supported. Version 3.1.x+ is included in Spring Boot 2.4.3+. + +## Installation + +Add the Spring Data MongoDB reactive dependency to your project (versions 3.1.x - 4.x supported): + + + +```kotlin +implementation("org.springframework.data:spring-data-mongodb:3.1.4") +implementation("org.mongodb:mongodb-driver-reactivestreams:4.0.0") +implementation("io.projectreactor:reactor-core:3.4.34") +``` + + +```xml + + org.springframework.data + spring-data-mongodb + 3.1.4 + + + org.mongodb + mongodb-driver-reactivestreams + 4.0.0 + + + io.projectreactor + reactor-core + 3.4.34 + +``` + + + + +## Basic setup + +Configure the target system: + +```java +var mongoTarget = new MongoDBSpringDataReactiveTargetSystem("user-database-id", reactiveMongoTemplate); +``` + +The constructor requires the target system name and a `ReactiveMongoTemplate`. Optional configurations can be added via `.withXXX()` methods. + +:::info Register Target System +Once created, you need to register this target system with Flamingock. See [Registering target systems](introduction.md#registering-target-systems) for details. +::: + +## Target System configuration + +The MongoDB Spring Data Reactive target system uses Flamingock's [split dependency resolution architecture](introduction.md#dependency-injection) with separate flows for target system configuration and change execution dependencies. + +### Constructor dependencies (mandatory) + +These dependencies must be provided at target system creation time with **no global context fallback**: + +| Dependency | Constructor Parameter | Description | +|------------|----------------------|-------------| +| `ReactiveMongoTemplate` | `mongoTemplate` | Spring Data reactive MongoDB template - **required** for both target system configuration and change execution | + +## Dependencies available to Changes + +Changes can access dependencies through [dependency injection with fallback](../changes/anatomy-and-structure.md#method-parameters-and-dependency-injection): + +1. **Target system context** (highest priority) - `ReactiveMongoTemplate` +2. **Target system additional dependencies** - added via `.addDependency()` or `.setProperty()` +3. **Global context** (fallback) - shared dependencies available to all target systems + +## Configuration example + +Here's a comprehensive example showing the new architecture: + +```java +// Target system configuration (mandatory via constructor) +var mongoTarget = new MongoDBSpringDataReactiveTargetSystem("user-database", userReactiveMongoTemplate) + .addDependency(userAuditService); // Additional dependency for changes + +// Global context with shared dependencies +Flamingock.builder() + .addDependency(emailService) // Available to all target systems + .addDependency(logService) // Available to all target systems + .addTargetSystems(mongoTarget) + .build(); +``` + +**Target system configuration resolution:** +- **ReactiveMongoTemplate**: Must be provided via constructor (`userReactiveMongoTemplate`) + +**Change dependency resolution for Changes in "user-database":** +- **ReactiveMongoTemplate**: From target system context (`userReactiveMongoTemplate`) +- **UserAuditService**: From target system additional dependencies +- **EmailService**: From global context (fallback) +- **LogService**: From global context (fallback) + +This architecture ensures explicit target system configuration while providing flexible dependency access for changes. + +## Transactional support + +The Spring Data Reactive target system integrates with Spring's reactive transaction management. When a Change is marked as transactional (the default), Flamingock uses the injected `ReactiveMongoTemplate` dependency to handle transaction operations through Spring's reactive infrastructure. + +> For detailed information on transaction handling, see [Transactions](../changes/transactions.md). + +```java +@TargetSystem("user-database-id") +@Change(id = "create-users", author = "team") // order extracted from filename +public class _0001__CreateUsers { + + @Apply + public void apply(ReactiveMongoTemplate mongoTemplate) { + // ReactiveMongoTemplate automatically participates in Flamingock-managed transactions + // The publisher must be subscribed to (e.g. via block()) for the operation to execute + mongoTemplate.save(new User("john@example.com", "John Doe")).block(); + } +} +``` + +**How transactions work:** +1. **Reactive integration**: Flamingock leverages the target system's `ReactiveMongoTemplate` within its transaction context +2. **Transaction management**: The same `ReactiveMongoTemplate` handles both Change operations and transaction coordination +3. **Lifecycle**: Flamingock automatically starts the transaction, commits on success, or rolls back on failure + +:::info Reactive publishers must be consumed +`ReactiveMongoTemplate` operations return `Mono`/`Flux` publishers that only execute once subscribed to. Make sure your Change method blocks on (or otherwise awaits) every publisher it produces before returning, so the operation actually completes within the Change's lifecycle. +::: + +## Available dependencies in Changes + +Your Changes can inject `ReactiveMongoTemplate`, but are not limited to it. The target system provides this dependency through its context, and you can add additional dependencies via `.addDependency()` that take precedence over global dependencies. + +For comprehensive details on change dependency resolution, see [Change Anatomy & Structure](../changes/anatomy-and-structure.md). + +## Spring integration + +This target system is designed to work seamlessly with Spring Boot applications using Spring WebFlux. When using Spring Boot auto-configuration, your existing `ReactiveMongoTemplate` beans are automatically available for injection into target systems. + +For more information on Spring Boot integration, see [Spring Boot integration](../frameworks/springboot-integration/introduction.md). + +## Next steps + +- Learn about [Target systems](introduction.md) +- Explore [Changes](../changes/introduction.md) +- See [Flamingock examples](https://github.com/flamingock/flamingock-java-examples)