Spring integration 如何使RedisQueueMessageDrivenEndpoint与IntegrationFlow一起工作?

Spring integration 如何使RedisQueueMessageDrivenEndpoint与IntegrationFlow一起工作?,spring-integration,dsl,Spring Integration,Dsl,我想知道如何使RedisQueueMessageDrivenEndpoint与IntegrationFlow一起工作,以便从以下代码中指定的列表中接收出队列的消息?“redisrppchannel()”似乎根本不接收任何消息。请帮忙 @Bean public RedisOutboundGateway redisOutboundGateway(RedisConnectionFactory connectionFactory) { RedisOutboundGateway gateway =

我想知道如何使RedisQueueMessageDrivenEndpoint与IntegrationFlow一起工作,以便从以下代码中指定的列表中接收出队列的消息?“redisrppchannel()”似乎根本不接收任何消息。请帮忙

@Bean
public RedisOutboundGateway redisOutboundGateway(RedisConnectionFactory connectionFactory) {
    RedisOutboundGateway gateway = new RedisOutboundGateway(connectionFactory);
    Jackson2JsonRedisSerializer<? extends JsonNode> serializer = new Jackson2JsonRedisSerializer<>(JsonNode.class);
    gateway.setArgumentsSerializer(serializer);
    return gateway;
}

@Bean
public IntegrationFlow redisLpushRequestFlow(RedisOutboundGateway gateway, BeanFactory beanFactory) {
    ExpressionArgumentsStrategy strategy = new ExpressionArgumentsStrategy(new String[]{"headers.queue", "#cmd == 'LPUSH' ? payload : null"}, true);
    strategy.setBeanFactory(beanFactory);
    gateway.setArgumentsStrategy(strategy);
    return flow -> flow.publishSubscribeChannel(s->s.subscribe(f -> f
            .enrich(e -> e.<ObjectNode>requestPayload(m -> {
                String partition = m.getHeaders().get("correlationId").toString();
                ObjectNode objectNode = m.getPayload();
                objectNode.put(PayLoadKeys.PARTITION, partition);
                objectNode.put(PayLoadKeys.SEQ, m.getHeaders().get("sequenceNumber").toString());
                return objectNode;
            }).shouldClonePayload(false)
                    .header(RedisHeaders.COMMAND, "LPUSH").header("queue", files))
            .handle(gateway).channel("redisLpushResponseFlow.input")));
}

@Bean
public IntegrationFlow redisLpushResponseFlow() {
    return flow -> flow.resequence().aggregate().<List<Long>>handle((p,h)-> {
                ObjectNode objectNode = mapper.createObjectNode();
                objectNode.put(PayLoadKeys.PARTITION, h.get("correlationId").toString());
                if(h.get("mode").equals("debug")) {
                    objectNode.set(PayLoadKeys.DEBUG,
                            mapper.valueToTree(p.stream().collect(Collectors.toList())));
                }
                return objectNode;
            }).channel(httpInboundReplyChannel());
@Bean
public MessageChannel redisRpopChannel() {
    return MessageChannels.queue().get();
}

@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata poller() {
    return Pollers.fixedRate(500).get();
}

@Bean
public RedisQueueMessageDrivenEndpoint redisQueueMessageDrivenEndpoint(RedisConnectionFactory connectionFactory, BeanFactory beanFactory) {
    RedisQueueMessageDrivenEndpoint endpoint = new RedisQueueMessageDrivenEndpoint(files, connectionFactory);
    Jackson2JsonRedisSerializer<? extends JsonNode> serializer = new Jackson2JsonRedisSerializer<>(JsonNode.class);
    endpoint.setSerializer(serializer);
    endpoint.setBeanFactory(beanFactory);
    endpoint.setAutoStartup(true);
    endpoint.setOutputChannel(redisRpopChannel());
    endpoint.afterPropertiesSet();
    endpoint.start();
    return endpoint;
}

@Bean
public IntegrationFlow redisQueuePollingFlow() {

    class ThrottledTaskExecutor implements TaskExecutor {
        final Semaphore semaphore;
        final TaskExecutor taskExecutor;

        ThrottledTaskExecutor(ThreadPoolTaskExecutor taskExecutor) {
            this.taskExecutor = taskExecutor;
            this.semaphore = new Semaphore(taskExecutor.getCorePoolSize());
        }

        @Override
        public void execute(Runnable task) {
            if (task == null) {
                throw new NullPointerException("Task is null in ThrottledTaskExecutor.");
            }
            doSubmit(task);
        }

        void doSubmit(final Runnable task) {
            try {
                semaphore.acquire();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new TaskRejectedException("Task could not be submitted because of a thread interruption.");
            }
            try {
                taskExecutor.execute(new FutureTask<Void>(task, null) {

                    @Override
                    protected void done() {
                        semaphore.release();
                    }
                });
            } catch (TaskRejectedException e) {
                semaphore.release();
                throw e;
            }
        }
    }

    return IntegrationFlows
            .from(redisRpopChannel())
            .transform(Transformers.fromJson(ObjectNode.class))
            .handle(message -> {
                ObjectNode p = (ObjectNode) message.getPayload();
                ThreadPoolTaskExecutor taskExecutor = taskExecutor();
                ThrottledTaskExecutor throttledTaskExecutor = new ThrottledTaskExecutor(taskExecutor);
                if(p.hasNonNull(PayLoadKeys.ID_ARRAY)) {
                    String array = p.remove(PayLoadKeys.ID_ARRAY).asText();
                    if (p.hasNonNull(array)) {
                        p.remove(array).forEach(id -> {
                            ObjectNode param = p.deepCopy();
                            final Long finalId = id.asLong();
                            param.put("id", finalId);
                            throttledTaskExecutor.execute(new JobLaunchTask(param));
                        });
                    }
                } else {
                    throttledTaskExecutor.execute(new JobLaunchTask(p));
                }
                taskExecutor.shutdown();
            }).get();
}
@Bean
公共RedisOutboundGateway RedisOutboundGateway(RedisConnectionFactory connectionFactory){
RedisOutboundGateway=新的RedisOutboundGateway(connectionFactory);
Jackson2JsonRedisSerializer在DSL中使用消息驱动的端点(定义为
@Bean
s)时,当前存在以下问题

问题是初始化期间需要输出通道。但是,当端点稍后连接到流中时,该通道将被替换

您不应该在
@Bean
定义中调用像
afterPropertieSet()
start()
这样的方法

这对我有用

@Bean
public RedisConnectionFactory connectionFactory() {
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
    jedisConnectionFactory.setPort(6379);
    return jedisConnectionFactory;
}

@Bean
public RedisQueueMessageDrivenEndpoint redisQueueMessageDrivenEndpoint(RedisConnectionFactory connectionFactory) {
    RedisQueueMessageDrivenEndpoint endpoint = new RedisQueueMessageDrivenEndpoint("foo", connectionFactory);
    Jackson2JsonRedisSerializer<? extends JsonNode> serializer = new Jackson2JsonRedisSerializer<>(JsonNode.class);
    endpoint.setSerializer(serializer);
    endpoint.setAutoStartup(true);
    endpoint.setOutputChannel(new DirectChannel()); // will be replaced
    return endpoint;
}

@Bean
public IntegrationFlow flow(RedisConnectionFactory connectionFactory) {
    return IntegrationFlows.from(redisQueueMessageDrivenEndpoint(connectionFactory))
            .handle(System.out::println)
            .get();
}

再一次,我从端点删除了所有容器管理的属性;Spring设置了所有这些属性。

感谢您的审阅。我真的非常感谢您的审阅。我也非常钦佩您的工作。我想知道为什么没有支持redis迭代并添加到组中的协议适配器,所以我们都可以像IntegrationFlows一样编写(Redis.inboundGateway(connectionFactory,queue))?我们的资源有限。我们要求社区帮助我们优先考虑通过向DSL中添加对Redis等的一流支持。请随时在那里提出改进问题,我们将看看我们能做些什么。我们也欢迎。
@Bean
public RedisQueueMessageDrivenEndpoint redisQueueMessageDrivenEndpoint(RedisConnectionFactory connectionFactory) {
    RedisQueueMessageDrivenEndpoint endpoint = new RedisQueueMessageDrivenEndpoint("foo", connectionFactory);
    Jackson2JsonRedisSerializer<? extends JsonNode> serializer = new Jackson2JsonRedisSerializer<>(JsonNode.class);
    endpoint.setSerializer(serializer);
    endpoint.setAutoStartup(true);
    endpoint.setOutputChannel(rpopChannel());
    return endpoint;
}

@Bean
public IntegrationFlow flow(RedisConnectionFactory connectionFactory) {
    return IntegrationFlows.from(rpopChannel())
            .handle(System.out::println)
            .get();
}

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