Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error while sending message to turn on Spring Integration inbound adapter using ControlBus

This is my first attempt using ControlBus to turn inbound channel adapters on/off.

To make it simple, I'm sending my control message by writing an empty file into a directory watched by a inbound file adapter (this one is perpetually turned on), which I then route to a service activator that will turn on/off my other inbound adapters.

<int:channel id="controlBusChannel" />
<int:control-bus input-channel="controlBusChannel" auto-startup="true"/>
<file:inbound-channel-adapter id="controlFilesIn" directory="file:/tmp/control/input" prevent-duplicates="true" auto-startup="true">
    <int:poller id="poller" fixed-delay="500"/>
</file:inbound-channel-adapter>
<int:service-activator input-channel="controlFilesIn" output-channel="controlFilesOut" ref="controlFileHandler" method="handleUpdate"/>
<bean id="controlFileHandler" class="com.myproj.integration.ControlBusController"/>
<file:outbound-channel-adapter id="controlFilesOut" directory="file:/tmp/control/output" delete-source-files="true" />

<file:inbound-channel-adapter id="filesIn" directory="file:/tmp/filesIn/input" prevent-duplicates="true" filter="FileFilterOnLastModifiedTime" auto-startup="false">
    <int:poller id="poller" fixed-delay="500"/>
</file:inbound-channel-adapter>

In my ControlBusController bean:

@Component
public class ControlBusController implements ApplicationContextAware {
    final static Logger logger = LoggerFactory.getLogger(ControlBusController.class);

    private ApplicationContext ctx;

    public File handleUpdate(File input) throws ParseException, IOException, FileNotFoundException {
        String fileName = input.getName();
        logger.info("===================================");
        logger.info("Triggering control bus update by " + fileName);
        String[] fnArray = fileName.split("_");
        String inputChannel = fnArray[1];
        String inputCommand = fnArray[2];
        if ("FILESIN".equals(inputChannel) && "START".equals(inputCommand)) {
            MessageChannel channel = ctx.getBean("controlBusChannel", MessageChannel.class);
            if (channel != null) {
                String controlMessage = "@filesIn.start()";
                logger.info("Sending control message: " + controlMessage);
                channel.send(new GenericMessage<>(controlMessage));
            } else logger.error("Could not get Message Channel from context or context was null");
        }
        return input;
    }

    @Override
    public void setApplicationContext(ApplicationContext ac) throws BeansException {
        this.ctx = ac;
    }
}

The message gets sent through into the controlBusChannel, but I get an error saying:

Caused by: org.springframework.expression.EvaluationException: The method 'start' is not supported by this command processor. If using the Control Bus, consider adding @ManagedOperation or @ManagedAttribute.
        at org.springframework.integration.handler.ExpressionCommandMessageProcessor$ExpressionCommandMethodResolver.validateMethod(ExpressionCommandMessageProcessor.java:111)

filesIn is already declared as the ID for my adapter, as seen above in the XML snippet.

Any ideas? Thanks!

P.S. I've tried just putting in the @ManagedOperation / @ManagedAttribute annotations and they don't seem to have any positive effect.

like image 664
feicipet Avatar asked Oct 19 '22 11:10

feicipet


1 Answers

Since you don't have a channel attribute on the <int-file:inbound-channel-adapter>, but just an id, so the channel is auto-created and it is exactly with that id. The adapter itself gets a bean name like filesIn.adapter.

So, you must change your ControlBus command expression to this:

String controlMessage = "@'filesIn.adapter'.start()";
like image 150
Artem Bilan Avatar answered Oct 22 '22 00:10

Artem Bilan