5

Spring Boot アプリケーションがあり、複数の AWS SQS キューからメッセージを受信したいと考えています。これらのキューはすべて独自の認証情報を持っています (悲しいことに、それについて私にできることは何もありません)。これらのクレデンシャルはいずれも、他のキューの 1 つにアクセスできません。それらはすべて、1 つのキューだけに制限されています。

キューと資格情報が 1 つだけなので、簡単です。AWSCredentialsProvider資格情報をBeanとして提供し、メソッドに@SqsListener\で注釈を付けるだけ@EnableSqsです。
しかし、複数の資格情報でそれを行う方法がわかりません。

@SqsListener注釈には、資格情報、事前構成されたオブジェクト、またはその他の役立つものを提供する方法がありませんAmazonSqs

CredentialsProviderまたはAmazonSqsクライアントを拡張して、キューを資格情報にマップする方法を探しましたが、役に立ちませんでした。
AmazonHttpClient のヘッダーに認証情報を挿入しようとしましたが、それもできませんでした。

SQS キューを手動でリッスンするために必要なものをすべて作成しようとしました。しかし、私は の MessageHandler を作成することに行き詰まっていSimpleMessageListenerContainerます。
requiredQueueMessageHandlerは、アプリケーション コンテキストを使用して Bean として作成された場合にのみ機能します。そうしないと、 で注釈が付けられたメソッドが検索されません@SqsListener
悲しいことに、私が見つけることができた唯一のチュートリアルまたは例は、避けたい JMS を使用しているか、@SqsListener1 つのキューのみでアノテーションを使用していました。

複数のキューに異なる資格情報を提供する他の方法はありますか?

私のテストコード:

@Component
@Slf4j
public class TestOneQueueA {

  public static final String QUEUE_A = "TestOneQueueA";

  public TestOneQueueA(Cloud cloud, ResourceIdResolver resourceIdResolver) {
    SqsServiceInfo serviceInfo = (SqsServiceInfo) cloud.getServiceInfo(QUEUE_A);
    AWSStaticCredentialsProvider credentialsProvider =
        new AWSStaticCredentialsProvider(new BasicAWSCredentials(serviceInfo.getAccessKey(),
            serviceInfo.getSecretAccessKey()));

    AmazonSQSAsync client = AmazonSQSAsyncClientBuilder.standard()
        .withCredentials(credentialsProvider)
        .withRegion(serviceInfo.getRegion()).build();

    QueueMessageHandlerFactory queueMessageHandlerFactory = new QueueMessageHandlerFactory();
    queueMessageHandlerFactory.setAmazonSqs(client);
    queueMessageHandlerFactory.setMessageConverters(Collections.singletonList(new MappingJackson2MessageConverter()));

    QueueMessageHandler queueMessageHandler = queueMessageHandlerFactory.createQueueMessageHandler();
    queueMessageHandler.afterPropertiesSet(); // won't do anything because of no ApplicationContext

    SimpleMessageListenerContainerFactory factory = new SimpleMessageListenerContainerFactory();
    factory.setAmazonSqs(client);
    factory.setResourceIdResolver(resourceIdResolver);
    factory.setQueueMessageHandler(queueMessageHandler);

    SimpleMessageListenerContainer simpleMessageListenerContainer = factory.createSimpleMessageListenerContainer();
    simpleMessageListenerContainer.setMessageHandler(queueMessageHandler);
    try {
      simpleMessageListenerContainer.afterPropertiesSet();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    simpleMessageListenerContainer.start();
    simpleMessageListenerContainer.start(QUEUE_A); // fails with "Queue with name 'TestOneQueueA' does not exist"
  }

  @SqsListener(value = QUEUE_A, deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
  public void receiveMessage(@NotificationMessage TestDto dto, @NotificationSubject String subject) {
    log.info("Received SQS Message: \nSubject: %s \n%s", subject, dto);
  }
}

編集:

もう少し試した後、AmazonSQS クライアントを 2 つの別々の に注入することができましたSimpleMessageListenerContainer。その後、問題はQueueMessageHandler.

@SqsListenerBean コンテキストなしで手動で作成すると、アノテーションを使用してメソッドが検索されません。また、ハンドラーを手動で設定する方法はありません。
Bean として作成すると、注釈のすべての Bean が表示されます。そのため、探すべきではないキューのメソッドも見つけます。そして、資格情報が機能しないため、クラッシュします。単一の SqsListener メソッドのみ
を作成する方法がわかりません。 そして、 a 以外は何も取りません。QueueMessageHandler
SimpleMessageListenerContainerQueueMessageHandler

4

2 に答える 2