spring-cloud-aws icon indicating copy to clipboard operation
spring-cloud-aws copied to clipboard

Is there any support to have multiple SimpleMessageListenerContainerFactory

Open tmnuwan12 opened this issue 7 years ago • 2 comments

Question:

Is there any possibility we can run multiple SimpleMessageListenerContainerFactory?

My use-case is I have Fifo queue in one region and standard queue in another region. I need to listen to both of these queues in the same application. How can I do this? Please help.

tmnuwan12 avatar Sep 20 '18 09:09 tmnuwan12

https://github.com/spring-cloud/spring-cloud-aws/issues/78#issuecomment-129043213

With the above inspiration you can write your custom resolver.

Please see the below class:

public class DynamicFifoQueueUrlDestinationResolver extends DynamicQueueUrlDestinationResolver {

	private AmazonSQSAsync fifoSQS;

	private boolean autoCreate;
	private final AmazonSQS amazonSqs;
	private final ResourceIdResolver resourceIdResolver = null;

	/**
	 * @param amazonSqs
	 */
	public DynamicFifoQueueUrlDestinationResolver(AmazonSQS amazonSqs, AmazonSQSAsync fifo) {
		super(amazonSqs);
		this.amazonSqs = amazonSqs;
		this.fifoSQS = fifo;
	}

	// quick hack
	@Override
	public String resolveDestination(String name) throws DestinationResolutionException {
		String queueName = name;

		if (this.resourceIdResolver != null) {
			queueName = this.resourceIdResolver.resolveToPhysicalResourceId(name);
		}

		if (isValidQueueUrl(queueName)) {
			return queueName;
		}

		if (this.autoCreate) {

			if (name.contains(Queues.FIFO.name())) {
				// Auto-create is fine to be called even if the queue exists.
				CreateQueueResult createQueueResult = this.fifoSQS.createQueue(new CreateQueueRequest(name));
				return createQueueResult.getQueueUrl();
			} else {
				// Auto-create is fine to be called even if the queue exists.
				CreateQueueResult createQueueResult = this.amazonSqs.createQueue(new CreateQueueRequest(name));
				return createQueueResult.getQueueUrl();
			}
		} else {

			if (name.contains(Queues.FIFOQUEUE.name())) {

				try {
					GetQueueUrlResult getQueueUrlResult = this.fifoSQS.getQueueUrl(new GetQueueUrlRequest(name));
					return getQueueUrlResult.getQueueUrl();
				} catch (QueueDoesNotExistException e) {
					throw new DestinationResolutionException(e.getMessage(), e);
				}
			} else {
				try {
					GetQueueUrlResult getQueueUrlResult = this.amazonSqs.getQueueUrl(new GetQueueUrlRequest(name));
					return getQueueUrlResult.getQueueUrl();
				} catch (QueueDoesNotExistException e) {
					throw new DestinationResolutionException(e.getMessage(), e);
				}
			}
		}

	}

	private static boolean isValidQueueUrl(String name) {
		try {
			URI candidate = new URI(name);
			return ("http".equals(candidate.getScheme()) || "https".equals(candidate.getScheme()));
		} catch (URISyntaxException e) {
			return false;
		}
	}

	public void setAutoCreate(boolean autoCreate) {
		this.autoCreate = autoCreate;
	}

}

tmnuwan12 avatar Sep 20 '18 10:09 tmnuwan12

It would be great if Spring boot can provide this out of the box.

tmnuwan12 avatar Sep 20 '18 10:09 tmnuwan12