Reputation: 3527
I have a SqsQueueSender to send messages to AWS. I want to test this class. My thought is that it should be a @Component
that is injected in to the classes that need it. Importantly, I want to configure the endpoint of the SqsQueueSender
to be different in testing vs. production environments.
I've been moving @Autowired and @Component around the classes various different ways but must have some basic misunderstanding. Here's my latest configuration:
package com.foo.fulfillmentApi.dao;
import com.amazonaws.services.sqs.AmazonSQSAsyncClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate;
import org.springframework.messaging.support.MessageBuilder;
@Component
public class SqsQueueSender {
private static final Logger LOGGER = LoggerFactory.getLogger(SqsQueueSender.class);
private final QueueMessagingTemplate queueMessagingTemplate;
@Autowired
AmazonSQSAsyncClient amazonSQSAsyncClient;
//This value is from /resources/application.properties
private @Value("${sqs.endpoint}") String endpoint;
public SqsQueueSender(AmazonSQSAsyncClient amazonSqsAsyncClient) {
amazonSqsAsyncClient.setEndpoint(endpoint);
this.queueMessagingTemplate = new QueueMessagingTemplate(amazonSqsAsyncClient);
}
public void send(String queueName, String message) {
this.queueMessagingTemplate.convertAndSend(queueName, MessageBuilder.withPayload(message).build());
}
}
The error message on startup states
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.amazonaws.services.sqs.AmazonSQSAsyncClient' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
To implement SqsQueueSender
you must pass an AmazonSQSAsyncClient
. How do I make sure this component can access an existing bean of that type?
Upvotes: 3
Views: 6677
Reputation: 4681
If you use springboot - define into your startup application file as below
@Bean
public AmazonSNSAsync amazonSNSClient() {
ClientConfiguration config = new ClientConfiguration();
return AmazonSNSAsyncClient.asyncBuilder().withClientConfiguration(config)
.withRegion(Regions.fromName(region))
.withCredentials(new DefaultAWSCredentialsProviderChain())
.build();
}
Upvotes: 1
Reputation: 26522
You need to create a configuration class. In your case it would be something like this:
@Configuration
public class AWSConfig {
@Bean(name ="awsClient")
public AmazonSQSAsync amazonSQSClient() {
AmazonSQSAsyncClient awsSQSAsyncClient
= new AmazonSQSAsyncClient();
// set up the client
return awsSQSAsyncClient;
}
If it has problems with injecting then add qualifier in qsQueueSender:
@Autowired
@Qualifier("awsClient")
AmazonSQSAsyncClient amazonSQSAsyncClient;
You can also do this using the xml configuration but as you are using annotations then this is more advisable approach.
Upvotes: 3
Reputation: 8396
Add @Component/@Service in com.amazonaws.services.sqs.AmazonSQSAsyncClient or return an object of that using @Bean annotation from configuration class.
Upvotes: 0