dk.cloudcreate.essentials.components.boot.autoconfigure.mongodb.EssentialsComponentsConfiguration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spring-boot-starter-mongodb Show documentation
Show all versions of spring-boot-starter-mongodb Show documentation
This library provides Spring Boot auto-configuration for all MongoDB focused Essentials components
The newest version!
/*
* Copyright 2021-2024 the original author or authors.
*
* 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
*
* https://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 dk.cloudcreate.essentials.components.boot.autoconfigure.mongodb;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.mongodb.*;
import dk.cloudcreate.essentials.components.distributed.fencedlock.springdata.mongo.MongoFencedLockManager;
import dk.cloudcreate.essentials.components.foundation.fencedlock.*;
import dk.cloudcreate.essentials.components.foundation.json.*;
import dk.cloudcreate.essentials.components.foundation.lifecycle.*;
import dk.cloudcreate.essentials.components.foundation.messaging.RedeliveryPolicy;
import dk.cloudcreate.essentials.components.foundation.messaging.eip.store_and_forward.*;
import dk.cloudcreate.essentials.components.foundation.messaging.queue.*;
import dk.cloudcreate.essentials.components.foundation.messaging.queue.micrometer.*;
import dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue;
import dk.cloudcreate.essentials.components.foundation.reactive.command.*;
import dk.cloudcreate.essentials.components.foundation.transaction.*;
import dk.cloudcreate.essentials.components.foundation.transaction.spring.mongo.SpringMongoTransactionAwareUnitOfWorkFactory;
import dk.cloudcreate.essentials.components.queue.springdata.mongodb.MongoDurableQueues;
import dk.cloudcreate.essentials.jackson.immutable.EssentialsImmutableJacksonModule;
import dk.cloudcreate.essentials.jackson.types.EssentialTypesJacksonModule;
import dk.cloudcreate.essentials.reactive.*;
import dk.cloudcreate.essentials.reactive.command.*;
import dk.cloudcreate.essentials.reactive.command.interceptor.CommandBusInterceptor;
import dk.cloudcreate.essentials.reactive.spring.ReactiveHandlersBeanPostProcessor;
import dk.cloudcreate.essentials.types.CharSequenceType;
import dk.cloudcreate.essentials.types.springdata.mongo.*;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.observation.ObservationRegistry;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.propagation.Propagator;
import org.slf4j.*;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.*;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.EventListener;
import org.springframework.context.event.*;
import org.springframework.core.convert.converter.*;
import org.springframework.data.mongodb.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import java.util.*;
import java.util.function.Function;
import static dk.cloudcreate.essentials.shared.FailFast.requireNonNull;
/**
* MongoDB focused Essentials Components auto configuration
*
* Security:
* If you in your own Spring Boot application choose to override the Beans defined by this starter,
* then you need to check the component document to learn about the Security implications of each configuration.
*
* {@link MongoFencedLockManager}
* To support customization of storage collection name, the {@code fencedLocksCollectionName} will be directly used as Collection name,
* which exposes the component to the risk of malicious input.
*
* Security Note:
* It is the responsibility of the user of this component to sanitize the {@code fencedLocksCollectionName}
* to ensure the security of the resulting MongoDB configuration and associated Queries/Updates/etc. The {@link dk.cloudcreate.essentials.components.distributed.fencedlock.springdata.mongo.MongoFencedLockStorage} component, used by {@link MongoFencedLockManager} will
* call the {@link dk.cloudcreate.essentials.components.foundation.mongo.MongoUtil#checkIsValidCollectionName(String)} method to validate the collection name as a first line of defense.
* The method provided is designed as an initial layer of defense against users providing unsafe collection names, by applying naming conventions intended to reduce the risk of malicious input.
* However, Essentials components as well as {@link dk.cloudcreate.essentials.components.foundation.mongo.MongoUtil#checkIsValidCollectionName(String)} does not offer exhaustive protection, nor does it assure the complete security of the resulting MongoDB configuration and associated Queries/Updates/etc..
* The responsibility for implementing protective measures against malicious input lies exclusively with the users/developers using the Essentials components and its supporting classes.
* Users must ensure thorough sanitization and validation of API input parameters, collection names.
* Insufficient attention to these practices may leave the application vulnerable to attacks, potentially endangering the security and integrity of the database.
*
* It is highly recommended that the {@code fencedLocksCollectionName} value is only derived from a controlled and trusted source.
* To mitigate the risk of malicious input attacks, external or untrusted inputs should never directly provide the {@code fencedLocksCollectionName} value.
* Failure to adequately sanitize and validate this value could expose the application to malicious input attacks, compromising the security and integrity of the database.
*
* {@link MongoDurableQueues}
* To support customization of storage collection name, the {@link MongoDurableQueues#getSharedQueueCollectionName()} will be directly used as Collection name,
* which exposes the component to the risk of malicious input.
*
* Security Note:
* It is the responsibility of the user of this component to sanitize the {@code sharedQueueCollectionName}
* to ensure the security of the resulting MongoDB configuration and associated Queries/Updates/etc. The {@link MongoDurableQueues}, will
* call the {@link dk.cloudcreate.essentials.components.foundation.mongo.MongoUtil#checkIsValidCollectionName(String)} method to validate the collection name as a first line of defense.
* The method provided is designed as an initial layer of defense against users providing unsafe collection names, by applying naming conventions intended to reduce the risk of malicious input.
* However, Essentials components as well as {@link dk.cloudcreate.essentials.components.foundation.mongo.MongoUtil#checkIsValidCollectionName(String)} does not offer exhaustive protection, nor does it assure the complete security of the resulting MongoDB configuration and associated Queries/Updates/etc..
* The responsibility for implementing protective measures against malicious input lies exclusively with the users/developers using the Essentials components and its supporting classes.
* Users must ensure thorough sanitization and validation of API input parameters, collection names.
* Insufficient attention to these practices may leave the application vulnerable to attacks, potentially endangering the security and integrity of the database.
*
* It is highly recommended that the {@code sharedQueueCollectionName} value is only derived from a controlled and trusted source.
* To mitigate the risk of malicious input attacks, external or untrusted inputs should never directly provide the {@code sharedQueueCollectionName} value.
* Failure to adequately sanitize and validate this value could expose the application to malicious input attacks, compromising the security and integrity of the database.
*
* @see dk.cloudcreate.essentials.components.queue.springdata.mongodb.MongoDurableQueues
* @see dk.cloudcreate.essentials.components.distributed.fencedlock.springdata.mongo.MongoFencedLockManager
* @see dk.cloudcreate.essentials.components.distributed.fencedlock.springdata.mongo.MongoFencedLockStorage
*/
@AutoConfiguration
@EnableConfigurationProperties(EssentialsComponentsProperties.class)
public class EssentialsComponentsConfiguration {
@Bean
@ConditionalOnProperty(prefix = "management.tracing", name = "enabled", havingValue = "true")
public DurableQueuesMicrometerTracingInterceptor durableQueuesMicrometerTracingInterceptor(Optional tracer,
Optional propagator,
Optional observationRegistry,
EssentialsComponentsProperties properties) {
return new DurableQueuesMicrometerTracingInterceptor(tracer.get(),
propagator.get(),
observationRegistry.get(),
properties.getDurableQueues().isVerboseTracing());
}
@Bean
@ConditionalOnProperty(prefix = "management.tracing", name = "enabled", havingValue = "true")
public DurableQueuesMicrometerInterceptor durableQueuesMicrometerInterceptor(Optional meterRegistry,
EssentialsComponentsProperties properties) {
return new DurableQueuesMicrometerInterceptor(meterRegistry.get(), properties.getTracingProperties().getModuleTag());
}
/**
* Auto-registers any {@link CommandHandler} with the single {@link CommandBus} bean found
* AND auto-registers any {@link EventHandler} with all {@link EventBus} beans foound
*
* @return the {@link ReactiveHandlersBeanPostProcessor} bean
*/
@Bean
@ConditionalOnMissingBean
public static ReactiveHandlersBeanPostProcessor reactiveHandlersBeanPostProcessor() {
return new ReactiveHandlersBeanPostProcessor();
}
/**
* Essential Jackson module which adds support for serializing and deserializing any Essentials types (note: Map keys still needs to be explicitly defined - see doc)
*
* @return the Essential Jackson module which adds support for serializing and deserializing any Essentials types
*/
@Bean
@ConditionalOnMissingBean
public EssentialTypesJacksonModule essentialJacksonModule() {
return new EssentialTypesJacksonModule();
}
/**
* Essential Immutable Jackson module which adds support for serializing and deserializing objects with no {@link JsonCreator} or a default constructor
*
* @return the Essential Immutable Jackson module which adds support for serializing and deserializing objects with no {@link JsonCreator} or a default constructor
*/
@Bean
@ConditionalOnClass(name = "org.objenesis.ObjenesisStd")
@ConditionalOnProperty(prefix = "essentials", name = "immutable-jackson-module-enabled", havingValue = "true")
@ConditionalOnMissingBean
public EssentialsImmutableJacksonModule essentialsImmutableJacksonModule() {
return new EssentialsImmutableJacksonModule();
}
/**
* Essential Jackson module which adds support for serializing and deserializing objects with semantic types
*
* @return the Essential Jackson module which adds support for serializing and deserializing objects with semantic types
*/
@Bean
@ConditionalOnMissingBean
public EssentialTypesJacksonModule essentialsJacksonModule() {
return new EssentialTypesJacksonModule();
}
@Bean
@ConditionalOnMissingBean
public SingleValueTypeRandomIdGenerator registerIdGenerator() {
return new SingleValueTypeRandomIdGenerator();
}
/**
* Creates a {@link MongoCustomConversions} bean (using SpringDataJavaTimeCodecs
)
* with optional additional char sequence types supported and generic converters.
* Registers new SingleValueTypeConverter(LockName.class, QueueEntryId.class, QueueName.class)))
with the {@link MongoCustomConversions}
* as {@link LockName}, {@link QueueEntryId} and {@link QueueName} are required by {@link FencedLockManager} and {@link DurableQueues}
* and any additional {@link CharSequenceType}'s provided in the optional {@link AdditionalCharSequenceTypesSupported} parameter.
* Through the optional {@link AdditionalConverters} parameter it supports easily registration of additional {@link Converter}/{@link GenericConverter}'s/etc
*
* Example Spring Config:
* {@code
* @Bean
* AdditionalCharSequenceTypesSupported additionalCharSequenceTypesSupported() {
* return new AdditionalCharSequenceTypesSupported(OrderId.class);
* }
*
* @Bean
* AdditionalConverters additionalGenericConverters() {
* return new AdditionalConverters(Jsr310Converters.StringToDurationConverter.INSTANCE,
* Jsr310Converters.DurationToStringConverter.INSTANCE);
* }
* }
*
* @param optionalAdditionalCharSequenceTypesSupported An optional additional concrete {@link CharSequenceType}'s that will be registered with the {@link SingleValueTypeConverter}
* being added to the returned {@link MongoCustomConversions}
* @param optionalAdditionalGenericConverters An optional additional {@link Converter}/{@link GenericConverter}'s/etc. that will be
* added to the returned {@link MongoCustomConversions}
* @return the {@link MongoCustomConversions}
*/
@Bean
@ConditionalOnMissingBean
public MongoCustomConversions mongoCustomConversions(Optional optionalAdditionalCharSequenceTypesSupported,
Optional optionalAdditionalGenericConverters) {
return MongoCustomConversions.create(mongoConverterConfigurationAdapter -> {
mongoConverterConfigurationAdapter.useSpringDataJavaTimeCodecs();
List>> allCharSequenceTypesSupported = new ArrayList<>(List.of(LockName.class, QueueEntryId.class, QueueName.class));
optionalAdditionalCharSequenceTypesSupported.ifPresent(additionalCharSequenceTypesSupported -> allCharSequenceTypesSupported.addAll(additionalCharSequenceTypesSupported.charSequenceTypes));
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy