lafual
lafual

Reputation: 775

Spring Integration Transform Failure rolling back JMS and not forwarding to error channel

using Boot 2.2.2 and Integration 5.2.2 - when an XML message is sourced from a File and fails unmarshalling (i.e. it is not XML) the message proceeds as expect to errorChannel. However, when the message comes from JMS, through the same route of channels and fails unmarshalling, it is not routed to errorChannel and the message is rolled-back to JMS. After which I am stuck in an endless loop of SAXParseException for the same message.

I had following this example from Proper ultimate way to migrate JMS event listening to Spring Integration with Spring Boot . Is there some implied transaction control that I am not considering? How do I have Spring Integration forward the message to errorChannel and commit the 'get' from the incoming queue?

Synopsis of code is as follows;

    @Bean
    public IntegrationFlow fileReader() {
        return IntegrationFlows
            .from(
                Files
                    .inboundAdapter( ... )
                    ...
                    .get(), e -> e.poller(Pollers.fixedDelay(1000))
            )
            .transform(new FileToStringTransformer())
            .channel("backUpChannel")
            .get();
    }

    @Bean
    public IntegrationFlow getMessageFromJms(ConnectionFactory connectionFactory, @Value("${queues.myQueue}") String myQueue) {
        return IntegrationFlows.from(
            Jms
                .messageDrivenChannelAdapter(connectionFactory)
                .destination(myQueue)
        )
        .channel("backUpChannel")
        .get();
    }

    @Bean
    public IntegrationFlow doBackUp() {
        return IntegrationFlows
            .from("backUpChannel")
            .<String>handle((payload, headers) -> {
                String uuid = headers.get(MessageHeaders.ID).toString();
                File backUpFile = new File("c:/backup/" + uuid + ".txt");
                byte[] payloadContent = payload.getBytes();
                try {
                    java.nio.file.Files.write(backUpFile.toPath(), payloadContent);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return payload;
            })
            .channel("XXX")
            .get();
    }

    @Bean
    public Jaxb2Marshaller unmarshaller() {
        Jaxb2Marshaller unmarshaller = new Jaxb2Marshaller();
        unmarshaller.setClassesToBeBound(MyClass.class);
        return unmarshaller;
    }

    @Bean
    public IntegrationFlow handleParseXml() {

        return IntegrationFlows
            .from("XXX")
            .transform(new UnmarshallingTransformer(unmarshaller()))
            .channel("YYY")
            .get();
    }

Upvotes: 0

Views: 455

Answers (1)

Gary Russell
Gary Russell

Reputation: 174534

You need to add .errorChannel(...) to the message-driven channel adapter.

Upvotes: 1

Related Questions