softwareplay
softwareplay

Reputation: 1409

Spring integration mail inbound channel

i'm new to Spring and Spring integration, and i have a simple task to accomplish. Filtering some emails by it's subject though a regex and register some info in the db.

I've set the JavaMailProperties and the test gives me the output of the read emails but the method i'm setting with service-activator is never called and this is actually making me have a strong headache.

The following is the xml configuration file:

<?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:mail="http://www.springframework.org/schema/integration/mail"
       xmlns:int="http://www.springframework.org/schema/integration"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
              http://www.springframework.org/schema/integration/mail  
              http://www.springframework.org/schema/integration/mail/spring-integration-mail-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">  
<util:properties id="javaMailProperties">
        <prop key="mail.store.protocol">pop3</prop>
        <prop key="mail.debug">true</prop>
    </util:properties>
    <mail:inbound-channel-adapter id="pop3Adapter" 
                                      store-uri="pop3://username:[email protected]:110/INBOX"                                     
                                      channel="recieveEmailChannel"                                          
                                      should-delete-messages="false"                                   
                                      auto-startup="true"
                                      java-mail-properties="javaMailProperties"
                                      mail-filter-expression="subject matches '(^Presente+\\s([1-9]{1})+(\\s[-]\\s)+([A-Z]{4,})+(\\s[A-Z]{6,})$)'">
        <int:poller max-messages-per-poll="10" fixed-delay="10000"/>
    </mail:inbound-channel-adapter>
    <int:channel id="recieveEmailChannel">        
        <int:interceptors>
            <int:wire-tap channel="logger"/>
        </int:interceptors>
    </int:channel>
    <int:logging-channel-adapter id="logger" level="DEBUG"/>
    <int:service-activator input-channel="recieveEmailChannel" ref="leggiMail" method="processa_mail"/>
    <bean id="leggiMail" class="it.jenia.ac.mail.rapportini.LeggiMail">
    </bean>
</beans>

The LeggiMail class with the processa_mail method is very simple:

import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.stereotype.Service;

@Service
public class LeggiMail {
    private static Logger logger = Logger.getLogger(LeggiMail.class);
    public static int count_get = 0;
    @ServiceActivator
    public void processa_mail(MimeMessage mimeMessage) {
        count_get++;
        logger.debug("porcessa_mail working");
    }

The test class i'm using this application in:

@ContextConfiguration(locations = { "classpath*:/test-spring-configuration.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
public class LeggiMailTest {
    private static Logger logger = Logger.getLogger(LeggiMailTest.class);
    @Autowired
    LeggiMail lm;
    @Test
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
    public void test_processa_mail(){
        logger.debug("Test started");
    }
}

The log Test started appears correctly in the console, but the log porcessa_mail working never shows up..

The first tutorial i found on this subject just spoke about a method that would have been called by default by the context. http://blog.solidcraft.eu/2011/04/read-emails-from-imap-with-spring.html (And it says that the method "processa_mail" should be called by default when the context is loaded, cause it's a service-activator.

Reading this tutorial about service activator didn't help enough: http://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html

Upvotes: 0

Views: 1799

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121177

When you try to test some async stuff you some barrier to prevent the main thread to be stopped early, than it is neccessary for entire test-case.

The simples way is add Thread.sleep() before the end of test method.

But better solution is based on some synchonizer, like CountDonwLatch.

From other side there is QueueChannel in the Spring Integration. You can use it as an output-channel for <service-activator>. Inject it to the test class and wait on the output.receive(10000). And assert... the result message to make your test realy unit-test.

Upvotes: 1

Related Questions