Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions inventory-orders-service/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ dependencies {
// Spring Boot
implementation("org.springframework.boot:spring-boot-starter-web")

// Springdata for MongoDB dependency
implementation("org.springframework.boot:spring-boot-starter-data-mongodb")

// Others dependencies needed for this example
// implementation("org.slf4j:slf4j-simple:2.0.6") // Commented out - Spring Boot provides logging

Expand Down Expand Up @@ -91,6 +94,10 @@ tasks.named<Jar>("jar") {
})
}

tasks.jar {
isZip64 = true
}

tasks.withType<JavaCompile> {
options.compilerArgs.add("-parameters")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
package io.flamingock.examples.inventory;

import com.mongodb.client.MongoClient;
import io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient;
import io.confluent.kafka.schemaregistry.client.SchemaRegistryClient;
import io.flamingock.internal.core.external.store.CommunityAuditStore;
import io.flamingock.store.mongodb.sync.MongoDBSyncAuditStore;
import io.flamingock.examples.inventory.util.KafkaSchemaManager;
import io.flamingock.examples.inventory.util.LaunchDarklyClient;
import io.flamingock.examples.inventory.util.MongoDBUtil;
import io.flamingock.targetsystem.mongodb.springdata.MongoDBSpringDataTargetSystem;
import io.flamingock.targetsystem.nontransactional.NonTransactionalTargetSystem;
import io.flamingock.targetsystem.mongodb.sync.MongoDBSyncTargetSystem;
import org.apache.kafka.clients.admin.AdminClient;
import org.apache.kafka.clients.admin.AdminClientConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import jakarta.annotation.PreDestroy;
import org.springframework.data.mongodb.core.MongoTemplate;

import java.time.Duration;
import java.util.Collections;
import java.util.Properties;

@Configuration
public class FlamingockConfig {

@Value("${mongodb.uri:mongodb://localhost:27017/}")
private String mongodbUri;

@Value("${kafka.bootstrap-servers:localhost:9092}")
private String kafkaBootstrapServers;

Expand All @@ -38,14 +35,9 @@ public class FlamingockConfig {

private AdminClient kafkaAdminClient;

@Bean(destroyMethod = "close")
public MongoClient mongoClient() {
return MongoDBUtil.getMongoClient(mongodbUri);
}

@Bean
public MongoDBSyncTargetSystem mongoDBSyncTargetSystem(MongoClient mongoClient) {
return new MongoDBSyncTargetSystem(TargetSystems.MONGODB_TARGET_SYSTEM, mongoClient, TargetSystems.DATABASE_NAME);
public MongoDBSpringDataTargetSystem mongoDBSpringDataTargetSystem(MongoTemplate mongoTemplate) {
return new MongoDBSpringDataTargetSystem(TargetSystems.MONGODB_TARGET_SYSTEM, mongoTemplate);
}

@Bean
Expand Down Expand Up @@ -78,8 +70,8 @@ public NonTransactionalTargetSystem toggleTargetSystem() {

//This could return any of the available community audit stores
@Bean
public CommunityAuditStore auditStore(MongoDBSyncTargetSystem mongoDBSyncTargetSystem) {
return MongoDBSyncAuditStore.from(mongoDBSyncTargetSystem);
public CommunityAuditStore auditStore(MongoDBSpringDataTargetSystem mongoDBSpringDataTargetSystem) {
return MongoDBSyncAuditStore.from(mongoDBSpringDataTargetSystem);
}

@PreDestroy
Expand Down
Original file line number Diff line number Diff line change
@@ -1,63 +1,9 @@
package io.flamingock.examples.inventory;

import com.mongodb.client.MongoClient;
import io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient;
import io.confluent.kafka.schemaregistry.client.SchemaRegistryClient;
import io.flamingock.examples.inventory.util.KafkaSchemaManager;
import io.flamingock.examples.inventory.util.LaunchDarklyClient;
import io.flamingock.examples.inventory.util.MongoDBUtil;
import io.flamingock.targetsystem.nontransactional.NonTransactionalTargetSystem;
import io.flamingock.targetsystem.mongodb.sync.MongoDBSyncTargetSystem;
import org.apache.kafka.clients.admin.AdminClient;
import org.apache.kafka.clients.admin.AdminClientConfig;

import java.util.Collections;
import java.util.Properties;

public final class TargetSystems {
public static final String MONGODB_TARGET_SYSTEM = "mongodb-inventory";
public static final String KAFKA_TARGET_SYSTEM = "kafka-inventory";
public static final String FEATURE_FLAG_TARGET_SYSTEM = "toggle-inventory";


public static final String DATABASE_NAME = "inventory";
public static final String CONFIG_FILE_PATH = "config/application.yml";

private TargetSystems() {}

public static NonTransactionalTargetSystem toggleTargetSystem() {
// Create LaunchDarkly Management API client for demonstration
// In demo mode, this uses a dummy token and will log intended operations
LaunchDarklyClient launchDarklyClient = new LaunchDarklyClient(
"demo-token", // In real usage, this would be your LaunchDarkly API token
"inventory-service",
"production"
);

return new NonTransactionalTargetSystem(FEATURE_FLAG_TARGET_SYSTEM).addDependency(launchDarklyClient);
}

public static MongoDBSyncTargetSystem mongoDBSyncTargetSystem() {
MongoClient mongoClient = MongoDBUtil.getMongoClient("mongodb://localhost:27017/");
return new MongoDBSyncTargetSystem(MONGODB_TARGET_SYSTEM, mongoClient, DATABASE_NAME);
}

public static NonTransactionalTargetSystem kafkaTargetSystem() throws Exception {
SchemaRegistryClient schemaRegistryClient = new CachedSchemaRegistryClient(
Collections.singletonList("http://localhost:8081"),
100
);

// Kafka Admin client for topic management
Properties kafkaProps = new Properties();
kafkaProps.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
AdminClient kafkaAdminClient = AdminClient.create(kafkaProps);

// Kafka schema manager
KafkaSchemaManager schemaManager = new KafkaSchemaManager(schemaRegistryClient, kafkaAdminClient);
//We simulate the topic is already created
schemaManager.createTopicIfNotExists("order-created", 3, (short) 1);
return new NonTransactionalTargetSystem(KAFKA_TARGET_SYSTEM).addDependency(schemaManager);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@

package io.flamingock.examples.inventory.changes;

import com.mongodb.client.MongoDatabase;
import io.flamingock.api.annotations.Apply;
import io.flamingock.api.annotations.Change;
import io.flamingock.api.annotations.Rollback;
import io.flamingock.api.annotations.TargetSystem;
import org.bson.Document;
import org.springframework.data.mongodb.core.MongoTemplate;

import java.time.LocalDateTime;
import java.util.Arrays;
Expand All @@ -36,27 +36,23 @@ public class _0001__mongodb_addDiscountCodeFieldToOrders {
private static final String ORDERS_COLLECTION_NAME = "orders";

@Apply
public void apply(MongoDatabase mongoDatabase) {
public void apply(MongoTemplate mongoTemplate) {
Document order1 = buildOrder1();
Document order2 = buildOrder2();
mongoDatabase
mongoTemplate
.getCollection(ORDERS_COLLECTION_NAME)
.insertMany(Arrays.asList(order1, order2));

}

@Rollback
public void rollback(MongoDatabase mongoDatabase) {
if(doesExistOrdersCollection(mongoDatabase)) {
mongoDatabase.getCollection(ORDERS_COLLECTION_NAME).drop();
public void rollback(MongoTemplate mongoTemplate) {
if(mongoTemplate.collectionExists(ORDERS_COLLECTION_NAME)) {
mongoTemplate.dropCollection(ORDERS_COLLECTION_NAME);
}
}


private boolean doesExistOrdersCollection(MongoDatabase mongoDatabase) {
return mongoDatabase.listCollectionNames().into(new java.util.ArrayList<>()).contains("orders");
}

private static Document buildOrder2() {
return new Document()
.append("orderId", "ORD-002")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package io.flamingock.examples.inventory.changes;

import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
import io.flamingock.api.annotations.Apply;
Expand All @@ -27,6 +26,7 @@
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.MongoTemplate;

import static io.flamingock.examples.inventory.TargetSystems.MONGODB_TARGET_SYSTEM;

Expand All @@ -37,10 +37,10 @@ public class _0004__mongodb_backfillDiscountsForExistingOrders {
private static final Logger logger = LoggerFactory.getLogger(_0004__mongodb_backfillDiscountsForExistingOrders.class);

@Apply
public void apply(MongoDatabase mongoDatabase) {
public void apply(MongoTemplate mongoTemplate) {
logger.info("Backfilling discountCode field for existing orders");

MongoCollection<Document> orders = mongoDatabase.getCollection("orders");
MongoCollection<Document> orders = mongoTemplate.getCollection("orders");

// Update all orders that don't have a discountCode field
var filter = Filters.exists("discountCode", false);
Expand All @@ -60,10 +60,10 @@ public void apply(MongoDatabase mongoDatabase) {
}

@Rollback
public void rollback(MongoDatabase mongoDatabase) {
public void rollback(MongoTemplate mongoTemplate) {
logger.info("Rolling back: Removing discountCode and discountApplied fields");

MongoCollection<Document> orders = mongoDatabase.getCollection("orders");
MongoCollection<Document> orders = mongoTemplate.getCollection("orders");

// Remove the discountCode field from all documents
orders.updateMany(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package io.flamingock.examples.inventory.changes;

import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.IndexOptions;
import com.mongodb.client.model.Indexes;
import io.flamingock.api.annotations.Apply;
Expand All @@ -27,11 +26,12 @@
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.MongoTemplate;

import static io.flamingock.examples.inventory.TargetSystems.MONGODB_TARGET_SYSTEM;

@TargetSystem(id = MONGODB_TARGET_SYSTEM)
@Change(id = "add-index-on-discount-code", author = "flamingock-team", transactional = true)
@Change(id = "add-index-on-discount-code", author = "flamingock-team", transactional = false)

public class _0005__mongodb_addIndexOnDiscountCode {

Expand All @@ -41,10 +41,10 @@ public class _0005__mongodb_addIndexOnDiscountCode {
private static final String ORDERS_COLLECTION = "orders";

@Apply
public void apply(MongoDatabase mongoDatabase) {
public void apply(MongoTemplate mongoTemplate) {
logger.info("Creating index on discountCode field for efficient reporting queries");

MongoCollection<Document> orders = mongoDatabase.getCollection(ORDERS_COLLECTION);
MongoCollection<Document> orders = mongoTemplate.getCollection(ORDERS_COLLECTION);

// Check if index already exists (idempotent operation)
boolean indexExists = orders.listIndexes()
Expand All @@ -66,10 +66,10 @@ public void apply(MongoDatabase mongoDatabase) {
}

@Rollback
public void rollback(MongoDatabase mongoDatabase) {
public void rollback(MongoTemplate mongoTemplate) {
logger.info("Rolling back: Dropping index on discountCode field");

MongoCollection<Document> orders = mongoDatabase.getCollection(ORDERS_COLLECTION);
MongoCollection<Document> orders = mongoTemplate.getCollection(ORDERS_COLLECTION);

try {
// Check if index exists before attempting to drop it
Expand Down
3 changes: 3 additions & 0 deletions inventory-orders-service/src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
spring:
application:
name: inventory-orders-service
data:
mongodb:
database: inventory

server:
port: 8080
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class InventoryOrdersAppTest {

@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("mongodb.uri", mongoDBContainer::getConnectionString);
registry.add("spring.mongodb.uri", mongoDBContainer::getReplicaSetUrl);
registry.add("kafka.bootstrap-servers", kafkaContainer::getBootstrapServers);
registry.add("kafka.schema-registry-url", () -> String.format("http://%s:%d",
schemaRegistryContainer.getHost(),
Expand Down