我有一個 SQS 標準佇列,該佇列由第三方供應商提供,該供應商已授予我們的 IAM 用戶從那里讀取訊息的權限。因此,該佇列的AWS賬戶ID與我的用戶的ID不同。
我試圖使用 spring 的 @SqsListener 注解來消費這些訊息,但我在指定應從哪個帳戶 ID 消費時遇到了困難。
我的客戶端的bean配置看起來像這樣:
@Bean
fun amazonSQSAsyncClient()。AmazonSQSAsync = AmazonSQSAsyncClientBuilder.standard()
.withCredentials(AWSStaticCredentialsProvider(BasicAWSCredentials(awsProperties.accessKey,awsProperties.secretKey))。
.withEndpointConfiguration(AwsClientBuilder.EndpointConfiguration(awsProperties.url,awsProperties.region))。
.build()
我沒有看到在憑證中指定賬戶 Id 的方法,而且我也沒有找到可用于定義賬戶 Id 的任何屬性。
我試著將上面顯示的awsProperties.url設定為類似于https://sqs.us-east-1.amazonaws.com/<accountId>的內容,但這似乎并沒有什么效果。它仍然試圖在我自己的帳戶ID中尋找佇列,并拋出一個佇列未找到的錯誤。
有什么辦法可以解決這個問題,并強制Spring AWS Bean從特定的AwsAccount中進行消費嗎?
uj5u.com熱心網友回復:
你有一個用戶可以訪問另一個賬戶中的佇列。這意味著你可以在你的賬戶中用該用戶運行代碼,而該用戶可以訪問另一個賬戶中的佇列。
初始化一個sqsclient將總是使用它正在運行的賬戶 你不必對此進行調整。
在初始化一個sqsclient時,將總是使用它所運行的賬戶,你不需要調整這個。
@Bean。
fun amazonSQSAsyncClient()。AmazonSQSAsync = AmazonSQSAsyncClientBuilder.standard()
.withCredentials(AWSStaticCredentialsProvider(BasicAWSCredentials(awsProperties.accessKey,awsProperties.secretKey))。
.構建()
您需要確保代碼能夠訪問佇列。
在代碼中,您應該像這樣設定您的佇列 URL。
https://sqs.<region>.amazonaws.com/<account>/<queuename>/code>
,我很快嘗試從另一個賬戶訪問一個佇列。如果佇列的權限設定正確,你有兩種可能。第一個是使用佇列的URL而不是名稱(我檢查過了,它是有效的)。第二種是創建你自己的DestinationResolver并將其提供給SimpleMessageListenerContainer。我用Spring Boot創建了一個小應用,效果很好。我把代碼粘貼在下面。
在下一個功能發布中,我將找出一個更好的方法來支持這一用例。
package demo;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.model.GetQueueUrlRequest;
import com.amazonaws.services.sqs.model.GetQueueUrlResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.aws.core.env.ResourceIdResolver;
匯入 org.springframework.cloud.aws.messaging.config.SimpleMessageListenerContainerFactory;
輸入 org.springframework.cloud.aws.messaging.support.destination.DynamicQueueUrlDestinationResolver。
輸入 org.springframework.context.annotation.Bean。
輸入 org.springframework.messaging.core.DestinationResolutionException。
import org.springframework.messaging.core.DestinationResolver;
import org.springframework.messaging.handler.annotation.MessageMapping;
輸入org.springframework.util.Assert。
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class,args)。
}
@Bean
公共MessageListener messageListener() {
回傳新的MessageListener()。
}
@Bean
public SimpleMessageListenerContainerFactory simpleMessageListenerFactory(AmazonSQS amazonSqs, ResourceIdResolver resourceIdResolver) {
SimpleMessageListenerContainerFactory factory = new SimpleMessageListenerContainerFactory()。
factory.setDestinationResolver(new DynamicAccountAwareQueueUrlDestinationResolver(amazonSqs, resourceIdResolver))。
回傳工廠。
}
public static class DynamicAccountAwareQueueUrlDestinationResolver implements DestinationResolver<String> {
public static final String ACCOUNT_QUEUE_SEPARATOR = ":";
private final AmazonSQS amazonSqs;
private final DynamicQueueUrlDestinationResolver dynamicQueueUrlDestinationResolverDelegate;
public DynamicAccountAwareQueueUrlDestinationResolver(AmazonSQS amazonSqs, ResourceIdResolver resourceIdResolver) {
Assert.notNull(amazonSqs, "amazonSqs must not be null")。
this.amazonSqs = amazonSqs;
this.dynamicQueueUrlDestinationResolverDelegate = new DynamicQueueUrlDestinationResolver(amazonSqs, resourceIdResolver) 。
}
@Override
public String resolveDestination(String queue) throws DestinationResolutionException {
如果(queue.contains(ACCOUNT_QUEUE_SEPARATOR)) {
String account = queue.substring(0, queue.indexOf(ACCOUNT_QUEUE_SEPARATOR))。
String queueName = queue.substring(queue.indexOf(ACCOUNT_QUEUE_SEPARATOR) 1);
GetQueueUrlResult queueUrlResult = this.amazonSqs.getQueueUrl(new GetQueueUrlRequest()
.withQueueName(queueName)
.withQueueOwnerAWSAccountId(account))。
回傳 queueUrlResult.getQueueUrl()。
} else {
return this.dynamicQueueUrlDestinationResolverDelegate.resolveDestination(queue)。
}
}
}
公共靜態類MessageListener {
private static Logger LOG = LoggerFactory.getLogger(MessageListener.class);
@MessageMapping("633332177961:queue-name")
public void listen(String message) {
LOG.info("Received message: {}", message);
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/308790.html
標籤:
