CatalogInfrastructureConfig.java
package com.ecommerce.catalog.infrastructure.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.ecommerce.catalog.infrastructure.storage.MediaStorageProperties;
import com.ecommerce.catalog.infrastructure.search.CatalogSearchProperties;
import com.ecommerce.catalog.infrastructure.persistence.ProductReviewRepository;
import com.ecommerce.platform.common.observability.ConsumerFailureObservability;
import com.ecommerce.platform.common.observability.ConsumerFailureRetryCoordinator;
import com.ecommerce.platform.common.observability.ConsumerFailureRetryHandler;
import io.minio.MinioClient;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Clock;
import java.time.Duration;
import java.util.List;
@Configuration
@EnableConfigurationProperties({
MediaStorageProperties.class,
ReviewEventConsumerProperties.class,
CatalogSearchProperties.class
})
public class CatalogInfrastructureConfig {
@Bean
public Clock clock() {
return Clock.systemUTC();
}
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
@Bean
public MinioClient minioClient(MediaStorageProperties properties) {
return MinioClient.builder()
.endpoint(properties.endpoint())
.credentials(properties.username(), properties.password())
.build();
}
@Bean
public ConsumerFailureObservability catalogConsumerFailureObservability(
MeterRegistry registry,
ProductReviewRepository repository,
Clock clock) {
return new ConsumerFailureObservability(
registry,
"catalog-service",
repository,
clock);
}
@Bean
@ConditionalOnProperty(
prefix = "ecommerce.messaging.consumer-failure-retry",
name = "enabled",
havingValue = "true",
matchIfMissing = true)
public ConsumerFailureRetryCoordinator catalogConsumerFailureRetryCoordinator(
ProductReviewRepository repository,
ConsumerFailureObservability observability,
List<ConsumerFailureRetryHandler> handlers,
@Value("${ecommerce.messaging.consumer-failure.max-delivery-attempts:16}")
int maximumAttempts,
@Value("${ecommerce.messaging.consumer-failure-retry.batch-size:20}")
int batchSize,
@Value("${ecommerce.messaging.consumer-failure-retry.retry-delay:PT15S}")
Duration retryDelay,
@Value("${ecommerce.messaging.consumer-failure-retry.lease-duration:PT30S}")
Duration leaseDuration,
@Value("${ecommerce.messaging.consumer-failure-retry.worker-id:}")
String workerId) {
return new ConsumerFailureRetryCoordinator(
"catalog-service",
repository,
observability,
maximumAttempts,
batchSize,
retryDelay,
leaseDuration,
workerId,
handlers);
}
}