sdiaz1000
sdiaz1000

Reputation: 27

How to make Java ServiceActivator visible in JUnit Test?

How to make Java ServiceActivator visible in JUnit Test?

I have started writing a test which imports some spring integration xmls via some Java Config files (ie, files set in the @ContextConfiguration). One of these xml files references a channel called pollerErrorChannel this is the input-channel to a ServiceActivator declared in a Java Class. When the test cranks up I get the following error:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sftpInboundAdapterBusiness': Cannot create inner bean '(inner bean)#1fe8d51b' of type [org.springframework.integration.scheduling.PollerMetadata] while setting bean property 'pollerMetadata'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1fe8d51b': Cannot create inner bean '(inner bean)#324dcd31' of type [org.springframework.integration.channel.MessagePublishingErrorHandler] while setting bean property 'errorHandler'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#324dcd31': Cannot resolve reference to bean 'pollerErrorChannel' while setting bean property 'defaultErrorChannel'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'pollerErrorChannel' available

Below in my test

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {PropertySourcesPlaceholderConfigurer.class, 
    SFTPSampleReceiver.class,
    SampleIngestBusinessConfig.class, 
    SampleIngestConfig.class, 
    SessionFactoryConfig.class},
    initializers = ConfigFileApplicationContextInitializer.class)
@TestPropertySource(locations={"/application.yml"})
public class BusinessSampleRecieverTests {


    @Test
    public void test() {

    }

}

Segment from sample-ingest-business.xml which specifies pollerErrorChannel as a channel

   <int-sftp:inbound-channel-adapter id="sftpInboundAdapterBusiness"
        channel="sftpInboundBusiness"
        session-factory="sftpSessionFactory"
        local-directory="${sftp.localdirectory}/business-local"
        filter="businessCompositeFilter"
        remote-file-separator="/"
        remote-directory="${sftp.directory}/business-sftp">
    <int:poller cron="${sftp.cron}"  max-messages-per-poll="1" error-channel="pollerErrorChannel"/>
</int-sftp:inbound-channel-adapter>

Here is The Java Class which specifies pollerErrorChannel as the InputChannel to a @ServiceActivator

@Slf4j
@MessageEndpoint
@Component
public class SFTPSampleReceiver {

    @ServiceActivator(inputChannel = "pollerErrorChannel", outputChannel = "errorUploadChannel")

    public Message<String> processInvalidSample(GenericMessage errorMessage) {

        String error = ((Exception) errorMessage.getPayload()).getCause().toString();
        String fileName = ((MessagingException) errorMessage.getPayload()).getFailedMessage().getHeaders()
            .get("file_name").toString();
        String directory = ((MessagingException) errorMessage.getPayload()).getFailedMessage().getHeaders()
            .get("sample_type").toString() + "-sftp";
        String shortFileName = fileName.replace(".xml", "");
        String errorFile = shortFileName + "_error.txt";

        log.debug(fileName + " Was invalid and rejected.");

        final Message<String> message = MessageBuilder.withPayload(error).setHeader("error_file_name",
            errorFile).setHeader("file_name", fileName).setHeader("short_file_name",
            shortFileName).setHeader("directory", directory).build();

        return message;
    }


}

thanks

Upvotes: 1

Views: 1198

Answers (2)

sdiaz1000
sdiaz1000

Reputation: 27

Garys comment about adding < int:annotation-config/> to your XML worked

Upvotes: 0

Artem Bilan
Artem Bilan

Reputation: 121542

You have to declare that pollerErrorChannel bean.

With just a @ServiceActivator(inputChannel = "pollerErrorChannel" it will be already to late to have that channel auto-created. The <poller> is parsed and populated as a bean a bit earlier.

We might review the PollerParser to use MessagePublishingErrorHandler.setDefaultErrorChannelName() isntead of errorHandler.addPropertyReference("defaultErrorChannel", errorChannel); to let to resolve the channel late on demand.

Feel free to raise a JIRA on the matter!

Upvotes: 0

Related Questions