我正在尝试开发一个需要从两个不同的AWS账户收听SQS队列的Spring Boot(1.5)应用。 是否可以使用JmsListener注释创建一个侦听器?我已检查权限是否正确,我可以使用getQueueUrl()获取队列网址,并使用setQueueOwnerAWSAccountId()设置正确的帐户ID。
以下是我在主帐户下用于听众的代码。尝试将其用于其他帐户的队列,会出错
HTTPStatusCode: 400 AmazonErrorCode: AWS.SimpleQueueService.NonExistentQueue
com.amazonaws.services.sqs.model.QueueDoesNotExistException: The specified queue does not exist for this wsdl version.
队列读者类
@Service
public class QueueReader {
@JmsListener(destination = "queue-name")
public void messageReceived(@Payload String message) {
// message received
}
}
队列配置类
@Configuration
@EnableJms
public class QueueReaderConfig {
SQSConnectionFactory connectionFactory = SQSConnectionFactory.builder().withRegion(Region.getRegion(Regions.EU_WEST_1))
.withAWSCredentialsProvider(new DefaultAWSCredentialsProviderChain())
.build();
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory =
new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(this.connectionFactory);
factory.setDestinationResolver(new DynamicDestinationResolver());
factory.setConcurrency("3-10");
factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
return factory;
}
@Bean
public JmsTemplate defaultJmsTemplate() {
return new JmsTemplate(this.connectionFactory);
}
}
答案 0 :(得分:0)
我也遇到了同样的问题。我通过创建自定义DestinationResolver并将其设置在“ DefaultJmsListenerContainerFactory”和“ JmsTemplate”中找到了解决方法。
此外,在“ CustomDynamicDestinationResolver”中,按ownerAccountId查找队列。
queue = ((SQSSession) session).createQueue(queueName, ownerAccountId);
使用连接工厂监听队列。
@JmsListener(destination = "MyQueue", containerFactory = "customJmsListenerContainerFactory")
public void process(String message) throws IOException {
有点晚了,但是我希望这可以帮助像我这样的人寻求解决方案。
谢谢
Akshay
import com.amazon.sqs.javamessaging.ProviderConfiguration;
import com.amazon.sqs.javamessaging.SQSConnectionFactory;
import com.amazon.sqs.javamessaging.SQSSession;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.util.Assert;
import javax.jms.*;
@Configuration
public class CustomJmsConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomJmsConfig.class);
@Value("${copies.processor.concurrency:5}")
private String concurrency;
@Value("${owner.account.id:1234}")
private String ownerAccountId;
SQSConnectionFactory customConnectionFactory =
new SQSConnectionFactory(
new ProviderConfiguration(),
AmazonSQSClientBuilder.standard().withRegion(Regions.EU_CENTRAL_1).withCredentials(new DefaultAWSCredentialsProviderChain())
);
@Bean
public DefaultJmsListenerContainerFactory customJmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(this.customConnectionFactory);
factory.setDestinationResolver(new CustomDynamicDestinationResolver(ownerAccountId));
factory.setConcurrency(concurrency);
factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
return factory;
}
@Bean
public JmsTemplate customJmsTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate(this.customConnectionFactory);
jmsTemplate.setDestinationResolver(new CustomDynamicDestinationResolver(ownerAccountId));
return jmsTemplate;
}
public static class CustomDynamicDestinationResolver implements DestinationResolver {
private String ownerAccountId;
public CustomDynamicDestinationResolver(String ownerAccountId) {
this.ownerAccountId = ownerAccountId;
}
@Override
public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain) throws JMSException {
Assert.notNull(session, "Session must not be null");
Assert.notNull(destinationName, "Destination name must not be null");
if (pubSubDomain) {
return resolveTopic(session, destinationName);
} else {
return resolveQueue(session, destinationName);
}
}
protected Topic resolveTopic(Session session, String topicName) throws JMSException {
return session.createTopic(topicName);
}
protected Queue resolveQueue(Session session, String queueName) throws JMSException {
Queue queue;
LOGGER.info("Getting destination for libraryOwnerAccountId: {}, queueName: {}", libraryOwnerAccountId, queueName);
if (libraryOwnerAccountId != null && session instanceof SQSSession) {
queue = ((SQSSession) session).createQueue(queueName, ownerAccountId);
} else {
queue = session.createQueue(queueName);
}
return queue;
}
}
}