How to identify that an SQS-Queue does not exist?

Viewed 264

I would expect that if the SQS queue specified in the following annotation does not exist, Spring will throw a NonExistentQueue exception at start time.

@SqsListener(value = "nonExistingQueue", deletionPolicy = SqsMessageDeletionPolicy.ALWAYS)

But somehow no exception is thrown in my case and the application will be started without the queue. Why will be no exception thrown? May it be disabled somehow? Sorry, I am pretty new to AWS. My goal is that my application couldn't even start without a queue present. If an exception were thrown would it suffice, or maybe I need to create an @PostConstruct method that checks for existence and manually throws an exception?

My properties:

cloud.aws.credentials.access-key=accesKey
cloud.aws.credentials.secret-key=secretKey
cloud.aws.region.auto=false
cloud.aws.region.static=eu-central-1
cloud.aws.stack.auto=false

When I create the SQS-Queue that SqlListened needs, the application works fine. Here is my pom to check out my dependencies:

    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-s3</artifactId>
        <version>1.11.792</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-aws-autoconfigure</artifactId>
        <version>2.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-aws-context</artifactId>
        <version>2.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-aws-messaging</artifactId>
        <version>2.2.5.RELEASE</version>
    </dependency>

Thank you very much.

1 Answers

I've requested this feature in spring-cloud-aws project: https://github.com/awspring/spring-cloud-aws/issues/393 just c/p my workaround here:

  1. Custom destination resolver that throws RuntimeException that will not be catched by SimpleMessageListenerContainer:
public class FailingDestinationResolver<T> implements DestinationResolver<T> {
    
    private final DestinationResolver<T> destinationResolver;

    public FailingDestinationResolver(DestinationResolver<T> destinationResolver) {
        this.destinationResolver = destinationResolver;
    }

    @Override
    public T resolveDestination(String name) {
        try {
            return destinationResolver.resolveDestination(name);
        } catch (DestinationResolutionException e) {
            throw new RuntimeException("Fail to resolve '" + name + "' destination", e);
        }
    }
}
  1. Configure SimpleMessageListenerContainerFactory bean with custom queue resolver:
@Bean
public SimpleMessageListenerContainerFactory sqsListenerContainerFactory(DestinationResolver<String> queueDestinationResolver) {
    SimpleMessageListenerContainerFactory factory = new SimpleMessageListenerContainerFactory();
    factory.setDestinationResolver(queueDestinationResolver);
    return factory;
}
    
@Bean
public DestinationResolver<String> queueDestinationResolver(AmazonSQSAsync sqs) {
    return new CachingDestinationResolverProxy<>(new FailingDestinationResolver<>(new DynamicQueueUrlDestinationResolver(sqs, null)));
}

Note that spring cloud.aws.sqs.listener.* properties ignored for this configuration, additional code is required to pick them up from SqsProperties.

Related