Issue
I'm in a situation in which I have two AWS accounts in the same project. In one account I have a DynamoDB database that I need to access. In another one, I have Amazon Kinesis. In order to run kinesis producers and consumers properly, I need to define three beans: one for Kinesis, another for Cloudwatch and a last one for Dynamo.
@Bean
public AmazonKinesisAsync amazonKinesisAsync() {
}
@Bean
public AmazonDynamoDBAsync amazonDynamoDBAsync() {
}
@Bean
public AmazonCloudWatchAsync amazonCloudwatchAsync() {
}
Which is fine. The problem is that AmazonDynamoDBAsync
extends AmazonDynamoDB
, and I have another AmazonDynamoDB
bean set up in my project (in order to access the other account). This obviously causes the following error:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.amazonaws.services.dynamodbv2.AmazonDynamoDB' available: expected single matching bean but found 2: amazonDynamoDBAsync,amazonDynamoDB
32
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.20.jar!/:5.3.20]
I have no idea how to specify to spring-cloud-stream
or to spring-cloud-stream-binder-kinesis
which bean it should use. I would love to be able to just use @Qualifier
for this. I have read documentation extensively, searching for ways to specify a bean through configuration or code and found nothing. I also tried deleting the AmazonDynamoDBAsync
bean to force Kinesis to use the already existing Bean of the DynamoDB on the other account, but it seems that If I do not specify a AmazonDynamoDBAsync
bean, spring-cloud-stream
tries to create its own, and I still get NoUniqueBeanDefinitionException
.
Any leads on how to specify to spring-cloud-stream
which Bean it should use? I cannot run away from using two AWS accounts, unfortunately. My POM:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-kinesis</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<version>3.2.5</version>
</dependency>
Solution
In the end, simply using @Primary
on the AmazonDynamoDBAsync
made the trick. However, I got some other errors down the road. For anyone out there with the same or similar issue, I do not recommend having two Dynamo beans using the same SDK in the same project, it will only give you headaches. If you can, is preferable not to have more than one Bean. If you cannot run from it, having two SDKs helped me kind of organize who is who. In the end I stopped using spring-cloud-stream
and went with KCL 2.X
. Thus, with different AWS SDK implementations (the other Dynamo is using SDK 1.X) I had no more conflicts.
Answered By - Pelicer
Answer Checked By - Terry (JavaFixing Volunteer)