All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ee.bitweb.core.amqp.AmqpAutoConfiguration Maven / Gradle / Ivy

There is a newer version: 4.0.0
Show newest version
package ee.bitweb.core.amqp;

import com.fasterxml.jackson.databind.ObjectMapper;
import ee.bitweb.core.trace.invoker.amqp.AmqpTraceAdvisor;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.amqp.rabbit.annotation.RabbitListenerAnnotationBeanPostProcessor;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ErrorHandler;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Configuration
@ConditionalOnClass(ConnectionFactory.class)
@ConditionalOnProperty(value = AmqpProperties.PREFIX + ".auto-configuration", havingValue = "true")
public class AmqpAutoConfiguration {

    @Bean
    public AmqpService amqpService(RabbitTemplate template) {
        return new AmqpService(template);
    }

    @Bean(RabbitListenerAnnotationBeanPostProcessor.DEFAULT_RABBIT_LISTENER_CONTAINER_FACTORY_BEAN_NAME)
    @ConditionalOnMissingBean
    public SimpleRabbitListenerContainerFactory jsaFactory(
            ConnectionFactory connectionFactory,
            MessageConverter converter,
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            List interceptors
    ) {
        log.info("Creating a default SimpleRabbitListenerContainerFactory");
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        factory.setMessageConverter(converter);

        factory.setErrorHandler(createDefaultErrorHandler());

        var sortedInterceptors = sortTraceIdInterceptorToFirst(interceptors);
        for (AmqpListenerInterceptor interceptor : sortedInterceptors) {
            log.info("Adding {} to SimpleRabbitListenerContainerFactory", interceptor.getClass().getSimpleName());
        }
        factory.setAdviceChain(sortedInterceptors.toArray(new MethodInterceptor[0]));

        return factory;
    }

    private List sortTraceIdInterceptorToFirst(List interceptors) {
        List sorted = new ArrayList<>();

        var traceIdInterceptor = interceptors.stream().filter(AmqpTraceAdvisor.class::isInstance)
                .findFirst()
                .orElse(null);

        if (traceIdInterceptor != null) {
            sorted.add(traceIdInterceptor);
            interceptors.remove(traceIdInterceptor);
        }

        sorted.addAll(interceptors);

        return sorted;
    }

    private ErrorHandler createDefaultErrorHandler() {
        ConditionalRejectingErrorHandler errorHandler = new ConditionalRejectingErrorHandler(
                new CoreExceptionStrategy()
        );
        errorHandler.setDiscardFatalsWithXDeath(false);

        return errorHandler;
    }

    @Bean
    @ConditionalOnMissingBean
    public RabbitTemplate rabbitTemplate(
            ConnectionFactory connectionFactory,
            MessageConverter converter,
            List processors
    ) {
        log.info("Creating a default RabbitTemplate");
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        template.setMessageConverter(converter);

        for (AmqpBeforePublishMessageProcessor processor : processors) {
            log.info("Adding {} to RabbitTemplate", processor.getClass().getSimpleName());
        }
        template.setBeforePublishPostProcessors(processors.toArray(new AmqpBeforePublishMessageProcessor[0]));

        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    public MessageConverter jsonMessageConverter(ObjectMapper mapper) {
        return new Jackson2JsonMessageConverter(mapper);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy