0

I want to push out 1 response and wait X milliseconds for N responses based on a correlation ID in the headers.

Current code is pretty simple: Send a call then start polling indiscriminately. That works ... for one call.

I know there is talk of a JMS solution ("JMSReader?") that spawns N number of listeners looking for correlation ID allowing these futures to time out, but I am not finding anything remotely related.

Joe
  • 1
  • 1
  • 3

1 Answers1

0

Here is a demo app that shows one way to do it...

@SpringBootApplication
public class So57377491Application {

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

    private final ConcurrentMap<String, List<String>> pending = new ConcurrentHashMap<>();

    private final ConcurrentMap<String, SettableListenableFuture<List<String>>> futures = new ConcurrentHashMap<>();

    @Bean
    public ApplicationRunner runner(RabbitTemplate template) {
        return args -> {
            this.pending.put("bar", new ArrayList<>());
            this.futures.put("bar", new SettableListenableFuture<>());
            template.convertAndSend("so57377491", "", "Foo", msg -> {
                msg.getMessageProperties().setCorrelationId("bar");
                msg.getMessageProperties().setReplyTo("replyExchange/so57377491-replies");
                return msg;
            });
            try {
                List<String> list = this.futures.get("bar").get(5, TimeUnit.SECONDS);
                System.out.println(list);
            }
            catch (TimeoutException toe) {
                System.out.println("Partial result after timeout " + this.pending.remove("bar"));
            }
            finally {
                this.futures.remove("bar");
            }

        };
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "so57377491-1"),
            exchange = @Exchange(value = "so57377491", type = "fanout")))
    public String listen1(String in) {
        System.out.println(in);
        return in.toUpperCase();
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "so57377491-2"),
            exchange = @Exchange(value = "so57377491", type = "fanout")))
    public String listen2(String in) {
        System.out.println(in);
        return in.toLowerCase();
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "so57377491-3"),
            exchange = @Exchange(value = "so57377491", type = "fanout")))
    public String listen3(String in) {
        System.out.println(in);
        return in + in;
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "so57377491-replies"),
            exchange = @Exchange(value = "replyExchange", type = "fanout")))
    public void replies(String in, @Header(AmqpHeaders.CORRELATION_ID) String correlationId) {
        System.out.println(in);
        List<String> list = this.pending.get(correlationId);
        if (list == null) {
            System.out.println("Late reply for " + correlationId);
        }
        else {
            list.add(in);
            if (list.size() == 3) {
                this.futures.get(correlationId).set(list);
                this.pending.remove(correlationId);
            }
        }
    }

}

Result

Foo
Foo
Foo
foo
FOO
FooFoo
[foo, FOO, FooFoo]
Gary Russell
  • 166,535
  • 14
  • 146
  • 179