Shahbour
Shahbour

Reputation: 1323

loggingchannel transactionManager

I am using spring-boot and spring integration to receive emails and save attachments into files .

I used PseudoTransactionManager because i wanted to raise an exception and role back if the email have no attachment (in role back i am moving the email to failed folder and on commit i move it to success folder).

@Bean(name="emailTransactionManager")
public PseudoTransactionManager emailTransactionManager() {
    return new PseudoTransactionManager();
}

@Bean(name="transactionManager")
@Primary
public PlatformTransactionManager transactionManager() {
    return new JpaTransactionManager();
}

Every thing is working good except when i role back i got the below error .

2015-12-09 21:01:03.388  INFO 874 --- [ask-scheduler-1] o.s.integration.mail.ImapMailReceiver    : attempting to receive mail from folder [INBOX]
2015-12-09 21:01:04.767  INFO 874 --- [pool-3-thread-1] c.t.r.m.support.EmailTransformer         : Email contains 1 fragments.
2015-12-09 21:01:04.772 ERROR 874 --- [pool-3-thread-1] o.s.integration.handler.LoggingHandler   : org.springframework.messaging.MessageHandlingException: nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: emailTransactionManager,transactionManager
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:96)
    at org.springframework.integration.splitter.AbstractMessageProcessingSplitter.splitMessage(AbstractMessageProcessingSplitter.java:61)
    at org.springframework.integration.splitter.AbstractMessageSplitter.handleRequestMessage(AbstractMessageSplitter.java:55)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:99)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at org.springframework.integration.handler.MessageHandlerChain$1.send(MessageHandlerChain.java:123)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:231)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:154)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:102)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:105)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at org.springframework.integration.handler.MessageHandlerChain.handleMessageInternal(MessageHandlerChain.java:104)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:147)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:392)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
    at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:105)
    at org.springframework.integration.mail.ImapIdleChannelAdapter.access$2300(ImapIdleChannelAdapter.java:62)
    at org.springframework.integration.mail.ImapIdleChannelAdapter$1.run(ImapIdleChannelAdapter.java:269)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
    at com.sun.proxy.$Proxy83.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: emailTransactionManager,transactionManager
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:366)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:332)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:367)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:271)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:654)
    at com.teltacworldwide.rateserver.mailattachments.support.EmailSplitter$$EnhancerBySpringCGLIB$$d5a16c5e.splitIntoMessages(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:113)
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:129)
    at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49)
    at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:342)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:330)
    at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:166)
    at org.springframework.integration.util.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:317)
    at org.springframework.integration.util.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:155)
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:93)
    ... 43 more

2015-12-09 21:01:04.774  INFO 874 --- [pool-3-thread-1] c.t.r.mailattachments.support.ImapMove   : Moving message <[email protected]> to success folder

I don't know if it is a spring-boot or integration but logging-adapter is subscribed to errorChannel and it can't autowire transactionManager i tried to annotate transactionManager with @Primary but it did not work

Integration XML

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:int-file="http://www.springframework.org/schema/integration/file"
    xmlns:int-mail="http://www.springframework.org/schema/integration/mail"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
    xsi:schemaLocation="http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream-4.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
        http://www.springframework.org/schema/integration/mail http://www.springframework.org/schema/integration/mail/spring-integration-mail.xsd
        http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">


    <int:transaction-synchronization-factory
        id="syncFactory">
        <int:after-commit expression="@imapMove.success(payload)" />
        <int:after-rollback expression="@imapMove.fail(payload)" />
    </int:transaction-synchronization-factory> 

    <int-mail:imap-idle-channel-adapter
        id="poll-for-email" channel="emailChannel" java-mail-properties="javaMailProperties"
        store-uri="imaps://xxxxxxx\test:[email protected]/INBOX"
        should-delete-messages="false" error-channel="failed-email-fetch" auto-startup="true">
        <int-mail:transactional transaction-manager="emailTransactionManager" synchronization-factory="syncFactory"/>
    </int-mail:imap-idle-channel-adapter>

    <util:properties id="javaMailProperties">
        <prop key="mail.store.protocol">imaps</prop>
        <prop key="mail.pop3.starttls.enable">true</prop>
        <prop key="mail.pop3.ssl.trust">exchange.xxxxxxx.co</prop>
        <prop key="mail.imaps.starttls.enable">true</prop>
        <prop key="mail.imaps.ssl.trust">exchange.xxxxxxx.co</prop>
        <prop key="mail.smtp.starttls.enable">true</prop>
        <prop key="mail.smtp.ssl.trust">exchange.xxxxxxx.co</prop>
        <prop key="mail.debug">false</prop>
    </util:properties>

    <int:channel id="emailChannel" />

    <int:chain id="transform-split-save" input-channel="emailChannel"
        output-channel="jobChannel">

        <int:transformer ref="emailTransformer" />

        <int:splitter ref="emailSplitter" />


        <int:header-enricher ref="carrierEnricher"  method="addCarrier" />

        <int-file:outbound-gateway id="save-as-file"
        auto-create-directory="true"  
         directory-expression="'target/out/' + headers.directory" />

    </int:chain>

    <!-- <int-file:outbound-channel-adapter id="save-as-file" auto-create-directory="true" 
        channel="outputChannel" directory-expression="'target/out/' + headers.directory"/> -->

    <int:channel id="jobChannel" />

    <int-stream:stdout-channel-adapter channel="jobChannel">

    </int-stream:stdout-channel-adapter>

    <int:exception-type-router input-channel="failed-email-fetch" default-output-channel="errorChannel">
        <int:mapping exception-type="com.xxxxxxx.rateserver.exception.RateException"
            channel="customError" />
    </int:exception-type-router>

    <int:channel id="failed-email-fetch" />

    <int:channel id="customError" />

    <int:service-activator input-channel="customError" ref="emailError" method="onEmailFetchFailed" />

</beans>

Upvotes: 1

Views: 300

Answers (1)

Shahbour
Shahbour

Reputation: 1323

I found the problem, on the splitter the method was annotated with @Transactional so it was using default transactionManager.

To confirm I tried it with @Transactional(transactionManager="emailTranasactionmanager") and it worked. In my case I just removed the @Transaction as I need only one transaction.

Upvotes: 1

Related Questions