如何将组超时与Aggregator的Java配置一起使用?

时间:2018-08-02 12:59:49

标签: java spring spring-integration

我想使用SI中的Aggregator Endpoint聚合基于消息主题的MQTT消息,并在到目前为止收到所有部件(某些陀螺仪值:X,Y和Z)时释放聚合消息,到目前为止没有问题。 。 有用。 但是我想添加一个组超时,以便在一段时间内没有收到所有3个值时,消息将被丢弃,我可以等待新消息。

我的工作代码:

配置:

@SpringBootApplication
public class MqttListenerApplication {

    public static void main(String[] args) {
        SpringApplication.run(MqttListenerApplication.class, args);
    }

    @Bean
    public MessageChannel mqttInputChannel() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel filterOutputChannel() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel aggregatorOutputChannel() {
        return new DirectChannel();
    }

    @Bean
    public MqttPahoClientFactory clientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName("demo:application");
        options.setPassword("PwdApps".toCharArray());
        factory.setConnectionOptions(options);
        return factory;
    }

    @Bean
    public MessageProducer inbound() {
        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter("tcp://mqtt2.thingsplay.com:1883", "test-007", clientFactory(),"#");
        adapter.setCompletionTimeout(5000);
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(1);
        adapter.setOutputChannel(mqttInputChannel());
        return adapter;
    }
}

过滤器端点:

@MessageEndpoint
public class MqttFilter {

    @Filter(
            inputChannel = "mqttInputChannel",
            outputChannel = "filterOutputChannel"
    )
    public boolean isValid(@Header("mqtt_receivedTopic") String topic, Message<?> message) {
        if (topic.contains("testbw")) {
            System.out.println("------ Valid Message ! ------");
            return true;
        } else {
            return false;
        }
    }

}

聚合器端点:

@MessageEndpoint
public class GyroAggregator {

    private static final Logger logger = LogManager.getLogger();

    @Aggregator(
            inputChannel = "filterOutputChannel",
            outputChannel = "aggregatorOutputChannel"
    )
    public GyroCompleted aggregate(List<Message<?>> messages) {
        GyroCompleted gyroCompleted = new GyroCompleted();
        for (Message<?> message : messages) {
            String topic = (String) message.getHeaders().get("mqtt_receivedTopic");
            if (topic.contains("ACCX")) {
                gyroCompleted.setAcc_x(Integer.valueOf((String) message.getPayload()));
            } else if (topic.contains("ACCY")) {
                gyroCompleted.setAcc_y(Integer.valueOf((String) message.getPayload()));
            } else if (topic.contains("ACCZ")) {
                gyroCompleted.setAcc_z(Integer.valueOf((String) message.getPayload()));
            }
        }
        return gyroCompleted;
    }

    @ReleaseStrategy
    public boolean hasAllAxes(List<Message<?>> messages) {
        logger.debug("In Release Strategy method.");
        logger.debug(messages);
        boolean x = false, y = false, z = false;
        for (Message<?> message : messages) {
            String topic = (String) message.getHeaders().get("mqtt_receivedTopic");
            if (topic.contains("ACCX")) {
                x = true;
            } else if (topic.contains("ACCY")) {
                y = true;
            } else if (topic.contains("ACCZ")) {
                z = true;
            }
        }
        logger.debug("Release Strategy method returning {}", x && y && z);
        return x && y && z;
    }

    @CorrelationStrategy
    public String correlateBy(@Header("mqtt_receivedTopic") String topic, Message<?> message) {
        logger.debug("In Correlation Strategy method.");
        String deviceId = topic.substring(0, topic.indexOf("/"));
        logger.debug("Correlation Strategy returning Key : {}", deviceId);
        return deviceId;
    }

}

回声端点:

@MessageEndpoint
public class EchoServiceActivator {

    private static final Logger logger = LogManager.getLogger();

    @ServiceActivator(
            inputChannel = "aggregatorOutputChannel"
    )
    public void echo(Message<?> message) {
        logger.debug("Echo : " + message);
    }

}

但是对于组超时点,我无法使其工作...尽管文档中说了这样,但注释中没有配置:

  

xml元素提供的所有配置选项也都是   可用于@Aggregator注释。

但是下面几行是这样说的:

  

聚合器的注释配置(@Aggregator等)   组件仅涵盖简单的用例,其中大多数默认选项是   足够。如果您需要使用以下选项来更好地控制这些选项   注释配置,请考虑将@Bean定义用于   AggregatingMessageHandler并将其@Bean方法标记为   @ServiceActivator

问题是我无法使@Bean工作...

AggregatingMessageHandler

我试图将其放在带有@MessageEndpoint注释的类中,但它也不起作用。我以为它将为聚集器自动装配所有组件。

我如何使其工作?

1 个答案:

答案 0 :(得分:1)

使用Java DSL更容易。像这样:

@Bean
public IntegrationFlow aggregatorFlow(GyroAggregator agg) {
    return IntegrationFlows.from("filterOutputChannel")
            .aggregate(a -> a
                            .processor(agg)
                            .groupTimeout(500L))
            .channel("aggregatorOutputChannel")
            .get();
}

当然,您可以将MQTT适配器和过滤器连接到同一流程中。

如果要将处理程序定义为@Bean,请在ctor中使用new SimpleMessageStore()