diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9b0fe6145..2133e6d64 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -266,6 +266,19 @@ jobs: FLAMINGOCK_JRELEASER_GPG_SECRET_KEY: ${{ secrets.FLAMINGOCK_JRELEASER_GPG_SECRET_KEY }} FLAMINGOCK_JRELEASER_GPG_PASSPHRASE: ${{ secrets.FLAMINGOCK_JRELEASER_GPG_PASSPHRASE }} + mongodb-target-system-api: + needs: [ build ] + uses: ./.github/workflows/module-release-graalvm.yml + with: + module: mongodb-target-system-api + secrets: + FLAMINGOCK_JRELEASER_GITHUB_TOKEN: ${{ secrets.FLAMINGOCK_JRELEASER_GITHUB_TOKEN }} + FLAMINGOCK_JRELEASER_MAVENCENTRAL_USERNAME: ${{ secrets.FLAMINGOCK_JRELEASER_MAVENCENTRAL_USERNAME }} + FLAMINGOCK_JRELEASER_MAVENCENTRAL_PASSWORD: ${{ secrets.FLAMINGOCK_JRELEASER_MAVENCENTRAL_PASSWORD }} + FLAMINGOCK_JRELEASER_GPG_PUBLIC_KEY: ${{ secrets.FLAMINGOCK_JRELEASER_GPG_PUBLIC_KEY }} + FLAMINGOCK_JRELEASER_GPG_SECRET_KEY: ${{ secrets.FLAMINGOCK_JRELEASER_GPG_SECRET_KEY }} + FLAMINGOCK_JRELEASER_GPG_PASSPHRASE: ${{ secrets.FLAMINGOCK_JRELEASER_GPG_PASSPHRASE }} + mongodb-sync-target-system: needs: [ build ] uses: ./.github/workflows/module-release-graalvm.yml @@ -491,6 +504,7 @@ jobs: flamingock-importer, flamingock-springboot-integration, nontransactional-target-system, + mongodb-target-system-api, mongodb-sync-target-system, mongodb-springdata-target-system, sql-target-system, diff --git a/buildSrc/src/main/kotlin/flamingock.project-structure.gradle.kts b/buildSrc/src/main/kotlin/flamingock.project-structure.gradle.kts index 88ce79772..00120ad74 100644 --- a/buildSrc/src/main/kotlin/flamingock.project-structure.gradle.kts +++ b/buildSrc/src/main/kotlin/flamingock.project-structure.gradle.kts @@ -35,6 +35,7 @@ val pluginProjects = setOf( val targetSystemProjects = setOf( "nontransactional-target-system", + "mongodb-target-system-api", "mongodb-sync-target-system", "mongodb-springdata-target-system", "sql-target-system", diff --git a/cli/flamingock-cli/build.gradle.kts b/cli/flamingock-cli/build.gradle.kts index 24d4f23bd..99f6a46b1 100644 --- a/cli/flamingock-cli/build.gradle.kts +++ b/cli/flamingock-cli/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { implementation(project(":core:flamingock-core")) implementation(project(":community:flamingock-community")) implementation(project(":utils:sql-util")) + implementation(project(":core:target-systems:mongodb-target-system-api")) // CLI framework implementation("info.picocli:picocli:4.7.5") diff --git a/community/flamingock-auditstore-mongodb-sync/src/main/java/io/flamingock/community/mongodb/sync/driver/MongoDBSyncAuditStore.java b/community/flamingock-auditstore-mongodb-sync/src/main/java/io/flamingock/community/mongodb/sync/driver/MongoDBSyncAuditStore.java index 7267dc066..03baa3054 100644 --- a/community/flamingock-auditstore-mongodb-sync/src/main/java/io/flamingock/community/mongodb/sync/driver/MongoDBSyncAuditStore.java +++ b/community/flamingock-auditstore-mongodb-sync/src/main/java/io/flamingock/community/mongodb/sync/driver/MongoDBSyncAuditStore.java @@ -18,7 +18,6 @@ import com.mongodb.ReadConcern; import com.mongodb.ReadPreference; import com.mongodb.WriteConcern; -import com.mongodb.client.MongoClient; import com.mongodb.client.MongoDatabase; import io.flamingock.community.mongodb.sync.internal.MongoDBSyncAuditPersistence; import io.flamingock.community.mongodb.sync.internal.MongoDBSyncLockService; @@ -30,6 +29,7 @@ import io.flamingock.internal.core.store.CommunityAuditStore; import io.flamingock.internal.util.TimeService; import io.flamingock.internal.util.id.RunnerId; +import io.flamingock.targetystem.mongodb.api.MongoDBTargetSystem; import io.flamingock.targetystem.mongodb.sync.MongoDBSyncTargetSystem; import static io.flamingock.internal.util.constants.CommunityPersistenceConstants.DEFAULT_AUDIT_STORE_NAME; @@ -37,13 +37,12 @@ public class MongoDBSyncAuditStore implements CommunityAuditStore { + private final MongoDBTargetSystem mongoDBTargetSystem; protected RunnerId runnerId; private CommunityConfigurable communityConfiguration; private MongoDBSyncAuditPersistence persistence; private MongoDBSyncLockService lockService; - private final MongoClient client; - private final String databaseName; private MongoDatabase database; private String auditRepositoryName = DEFAULT_AUDIT_STORE_NAME; private String lockRepositoryName = DEFAULT_LOCK_STORE_NAME; @@ -53,9 +52,8 @@ public class MongoDBSyncAuditStore implements CommunityAuditStore { private boolean autoCreate = true; - private MongoDBSyncAuditStore(MongoClient client, String databaseName) { - this.client = client; - this.databaseName = databaseName; + private MongoDBSyncAuditStore(MongoDBTargetSystem mongoDBTargetSystem) { + this.mongoDBTargetSystem = mongoDBTargetSystem; } /** @@ -68,8 +66,8 @@ private MongoDBSyncAuditStore(MongoClient client, String databaseName) { * @param targetSystem the target system from which to derive the client and database * @return a new audit store bound to the same MongoDB instance as the target system */ - public static MongoDBSyncAuditStore from(MongoDBSyncTargetSystem targetSystem) { - return new MongoDBSyncAuditStore(targetSystem.getClient(), targetSystem.getDatabaseName()); + public static MongoDBSyncAuditStore from(MongoDBTargetSystem targetSystem) { + return new MongoDBSyncAuditStore(targetSystem); } public MongoDBSyncAuditStore withAuditRepositoryName(String auditRepositoryName) { @@ -106,6 +104,7 @@ public MongoDBSyncAuditStore withAutoCreate(boolean autoCreate) { public void initialize(ContextResolver baseContext) { runnerId = baseContext.getRequiredDependencyValue(RunnerId.class); communityConfiguration = baseContext.getRequiredDependencyValue(CommunityConfigurable.class); + database = mongoDBTargetSystem.getMongoDatabase(); this.validate(); } @@ -145,15 +144,10 @@ public synchronized CommunityLockService getLockService() { private void validate() { - if (client == null) { - throw new FlamingockException("The 'client' instance is required."); + if (database == null ) { + throw new FlamingockException("The 'database' instance is required."); } - if (databaseName == null || databaseName.trim().isEmpty()) { - throw new FlamingockException("The 'databaseName' property is required."); - } - database = client.getDatabase(databaseName); - if (auditRepositoryName == null || auditRepositoryName.trim().isEmpty()) { throw new FlamingockException("The 'auditRepositoryName' property is required."); } diff --git a/community/flamingock-community/build.gradle.kts b/community/flamingock-community/build.gradle.kts index 71afd3fee..009abc7c9 100644 --- a/community/flamingock-community/build.gradle.kts +++ b/community/flamingock-community/build.gradle.kts @@ -6,6 +6,7 @@ dependencies { api(project(":core:target-systems:nontransactional-target-system")) api(project(":core:target-systems:couchbase-target-system")) api(project(":core:target-systems:dynamodb-target-system")) + api(project(":core:target-systems:mongodb-target-system-api")) api(project(":core:target-systems:mongodb-springdata-target-system")) api(project(":core:target-systems:mongodb-sync-target-system")) api(project(":core:target-systems:sql-target-system")) diff --git a/core/flamingock-core/src/main/java/io/flamingock/internal/core/builder/AbstractBuilder.java b/core/flamingock-core/src/main/java/io/flamingock/internal/core/builder/AbstractBuilder.java index 39a237d9f..70ce0da1d 100644 --- a/core/flamingock-core/src/main/java/io/flamingock/internal/core/builder/AbstractBuilder.java +++ b/core/flamingock-core/src/main/java/io/flamingock/internal/core/builder/AbstractBuilder.java @@ -82,9 +82,9 @@ protected AbstractBuilder( protected abstract HOLDER getSelf(); protected void configureStoreAndTargetSystem(PriorityContext dependencyContext) { - auditStore.initialize(dependencyContext); //remove this, targetSystem should be mandatory targetSystemManager.initialize(dependencyContext); + auditStore.initialize(dependencyContext); } protected AuditPersistence getAuditPersistence(PriorityContext hierarchicalContext) { diff --git a/core/target-systems/mongodb-springdata-target-system/build.gradle.kts b/core/target-systems/mongodb-springdata-target-system/build.gradle.kts index 699f11ae0..478e6cde4 100644 --- a/core/target-systems/mongodb-springdata-target-system/build.gradle.kts +++ b/core/target-systems/mongodb-springdata-target-system/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { api(project(":core:flamingock-core")) implementation(project(":utils:mongodb-util")) implementation(project(":legacy:mongock-importer-mongodb")) + api(project(":core:target-systems:mongodb-target-system-api")) //General compileOnly("org.mongodb:mongodb-driver-sync:${versions["mongodb"]}") diff --git a/core/target-systems/mongodb-springdata-target-system/src/main/java/io/flamingock/targetsystem/mongodb/springdata/MongoDBSpringDataTargetSystem.java b/core/target-systems/mongodb-springdata-target-system/src/main/java/io/flamingock/targetsystem/mongodb/springdata/MongoDBSpringDataTargetSystem.java index cb4650fbb..550ea8d69 100644 --- a/core/target-systems/mongodb-springdata-target-system/src/main/java/io/flamingock/targetsystem/mongodb/springdata/MongoDBSpringDataTargetSystem.java +++ b/core/target-systems/mongodb-springdata-target-system/src/main/java/io/flamingock/targetsystem/mongodb/springdata/MongoDBSpringDataTargetSystem.java @@ -18,6 +18,7 @@ import com.mongodb.ReadConcern; import com.mongodb.ReadPreference; import com.mongodb.WriteConcern; +import com.mongodb.client.MongoDatabase; import io.flamingock.importer.mongock.mongodb.MongockImporterMongoDB; import io.flamingock.internal.common.core.audit.AuditHistoryReader; import io.flamingock.internal.common.core.audit.AuditReaderType; @@ -26,6 +27,7 @@ import io.flamingock.internal.core.targets.mark.NoOpTargetSystemAuditMarker; import io.flamingock.internal.core.targets.TransactionalTargetSystem; import io.flamingock.internal.core.transaction.TransactionWrapper; +import io.flamingock.targetystem.mongodb.api.MongoDBTargetSystem; import org.springframework.data.mongodb.core.MongoTemplate; import java.util.Objects; @@ -35,9 +37,10 @@ import static io.flamingock.internal.common.core.metadata.Constants.DEFAULT_MONGOCK_ORIGIN; -public class MongoDBSpringDataTargetSystem extends TransactionalTargetSystem { +public class MongoDBSpringDataTargetSystem extends TransactionalTargetSystem + implements MongoDBTargetSystem { - private MongoTemplate mongoTemplate; + private final MongoTemplate mongoTemplate; private WriteConcern writeConcern = WriteConcern.MAJORITY.withJournal(true); private ReadConcern readConcern = ReadConcern.MAJORITY; private ReadPreference readPreference = ReadPreference.primary(); @@ -80,6 +83,14 @@ public ReadPreference getReadPreference() { return readPreference; } + @Override + public MongoDatabase getMongoDatabase() { + if (mongoTemplate == null) { + throw new FlamingockException("TargetSystem is not initialized. The 'mongoTemplate' instance is required."); + } + return mongoTemplate.getDb(); + } + @Override public void initialize(ContextResolver baseContext) { this.validate(); diff --git a/core/target-systems/mongodb-sync-target-system/build.gradle.kts b/core/target-systems/mongodb-sync-target-system/build.gradle.kts index d029ec45b..a760adf4e 100644 --- a/core/target-systems/mongodb-sync-target-system/build.gradle.kts +++ b/core/target-systems/mongodb-sync-target-system/build.gradle.kts @@ -4,6 +4,7 @@ dependencies { api(project(":core:flamingock-core")) implementation(project(":utils:mongodb-util")) implementation(project(":legacy:mongock-importer-mongodb")) + api(project(":core:target-systems:mongodb-target-system-api")) //General compileOnly("org.mongodb:mongodb-driver-sync:4.0.0") diff --git a/core/target-systems/mongodb-sync-target-system/src/main/java/io/flamingock/targetystem/mongodb/sync/MongoDBSyncTargetSystem.java b/core/target-systems/mongodb-sync-target-system/src/main/java/io/flamingock/targetystem/mongodb/sync/MongoDBSyncTargetSystem.java index 35bcf98ae..452877be0 100644 --- a/core/target-systems/mongodb-sync-target-system/src/main/java/io/flamingock/targetystem/mongodb/sync/MongoDBSyncTargetSystem.java +++ b/core/target-systems/mongodb-sync-target-system/src/main/java/io/flamingock/targetystem/mongodb/sync/MongoDBSyncTargetSystem.java @@ -30,6 +30,7 @@ import io.flamingock.internal.core.targets.TransactionalTargetSystem; import io.flamingock.internal.core.transaction.TransactionWrapper; import io.flamingock.importer.mongock.mongodb.MongockImporterMongoDB; +import io.flamingock.targetystem.mongodb.api.MongoDBTargetSystem; import java.util.Objects; import java.util.Optional; @@ -37,7 +38,7 @@ import static io.flamingock.internal.common.core.audit.AuditReaderType.MONGOCK; import static io.flamingock.internal.common.core.metadata.Constants.DEFAULT_MONGOCK_ORIGIN; -public class MongoDBSyncTargetSystem extends TransactionalTargetSystem { +public class MongoDBSyncTargetSystem extends TransactionalTargetSystem implements MongoDBTargetSystem { private final MongoClient mongoClient; private final String databaseName; @@ -73,8 +74,12 @@ public MongoClient getClient() { return mongoClient; } - public MongoDatabase getDatabase() { - return database; + @Override + public MongoDatabase getMongoDatabase() { + if (mongoClient == null || databaseName == null || databaseName.isEmpty()) { + throw new FlamingockException("TargetSystem is not initialized. The 'mongoClient' instance and 'databaseName' property are required."); + } + return mongoClient.getDatabase(databaseName); } public String getDatabaseName() { diff --git a/core/target-systems/mongodb-target-system-api/build.gradle.kts b/core/target-systems/mongodb-target-system-api/build.gradle.kts new file mode 100644 index 000000000..ac1456959 --- /dev/null +++ b/core/target-systems/mongodb-target-system-api/build.gradle.kts @@ -0,0 +1,14 @@ +dependencies { + implementation(project(":core:flamingock-core-api")) + + // MongoDB driver for storage implementations + compileOnly("org.mongodb:mongodb-driver-sync:4.0.0") +} + +description = "MongoDB target system api" + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) + } +} \ No newline at end of file diff --git a/core/target-systems/mongodb-target-system-api/src/main/java/io/flamingock/targetystem/mongodb/api/MongoDBTargetSystem.java b/core/target-systems/mongodb-target-system-api/src/main/java/io/flamingock/targetystem/mongodb/api/MongoDBTargetSystem.java new file mode 100644 index 000000000..89c258256 --- /dev/null +++ b/core/target-systems/mongodb-target-system-api/src/main/java/io/flamingock/targetystem/mongodb/api/MongoDBTargetSystem.java @@ -0,0 +1,24 @@ +/* + * Copyright 2025 Flamingock (https://www.flamingock.io) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.flamingock.targetystem.mongodb.api; + +import com.mongodb.client.MongoDatabase; +import io.flamingock.api.targets.TargetSystem; + +public interface MongoDBTargetSystem extends TargetSystem { + + MongoDatabase getMongoDatabase(); +} diff --git a/settings.gradle.kts b/settings.gradle.kts index a6a3dbc48..6a7514c34 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -93,6 +93,11 @@ project(":core:target-systems:nontransactional-target-system").projectDir = file("core/target-systems/nontransactional-target-system") project(":core:target-systems:nontransactional-target-system").name = "nontransactional-target-system" +include("core:target-systems:mongodb-target-system-api") +project(":core:target-systems:mongodb-target-system-api").projectDir = + file("core/target-systems/mongodb-target-system-api") +project(":core:target-systems:mongodb-target-system-api").name = "mongodb-target-system-api" + include("core:target-systems:mongodb-sync-target-system") project(":core:target-systems:mongodb-sync-target-system").projectDir = file("core/target-systems/mongodb-sync-target-system")