I have two SQS queues from which I want to listen to messages using two different message handlers. I am using Guice to bind and initialise the different consumers and message handlers. However, I am unable to bind the respective consumer to corresponding handler.
Consumer - TransactionQueue, Handler - TransactionMessageHandler
Consumer - RetryQueue, Handler- RetryMessageHandler
com.google.inject.CreationException: Unable to create injector, see the following errors:
1) No implementation for com.amazon.aft.sqsmessageconsumer.messaging.sqs.SqsMessageHandler was bound.
Did you mean?
* com.amazon.aft.sqsmessageconsumer.messaging.sqs.SqsMessageHandler annotated with
@com.google.inject.name.Named(value="TransactionMessageHandler")
* com.amazon.aft.sqsmessageconsumer.messaging.sqs.SqsMessageHandler annotated with
@com.google.inject.name.Named(value="RetryMessageHandler")
while locating com.amazon.aft.sqsmessageconsumer.messaging.sqs.SqsMessageHandler
for the 1st parameter of com.config.providers.ListenerProvider.<init>(TransactionConsumerProvider.java:23)
at com.config.ListenerModule.configure(ListenerModule.java:26) (via modules: com.service.ServiceModule -> com.config.ListenerModule)
I have used @Named
annotation to differentiate the consumers and handlers. Here is how my bindings look like:
@Override
protected void configure() {
bind(SqsConsumer.class).annotatedWith(Names.named("TransactionQueue"))
.toProvider(TransactionConsumerProvider.class)
.asEagerSingleton();
bind(SqsMessageHandler.class).annotatedWith(Names.named("TransactionMessageHandler"))
.toProvider(TransactionMessageHandlerProvider.class)
.asEagerSingleton();
bind(SqsConsumer.class).annotatedWith(Names.named("RetryQueue"))
.toProvider(RetryConsumerProvider.class)
.asEagerSingleton();
bind(SqsMessageHandler.class).annotatedWith(Names.named("RetryMessageHandler"))
.toProvider(RetryMessageHandlerProvider.class)
.asEagerSingleton();
}
Here are the classes for the consumers and the handlers:
TransactionConsumerProvider.class
@AllArgsConstructor(onConstructor = @__(@Inject))
public final class TransactionConsumerProvider implements Provider<SqsConsumer> {
@Named("TransactionMessageHandler")
private final SqsMessageHandler sqsMessageHandler;
@Override
public SqsConsumer get() {
// initializing transaction SQS queue
final SqsConsumer consumer = new SqsConsumer(
"TransactionQueue",
sqsClientBuilder,
sqsMessageHandler,
new SimpleMessageProcessingFailureHandler()
);
}
TransactionMessageHandlerProvider.class
@AllArgsConstructor(onConstructor = @__(@Inject))
public final class TransactionMessageHandlerProvider implements Provider<SqsMessageHandler> {
@Override
public SqsMessageHandler get() {
// Initialising TransactionMessageHandler
}
RetryConsumerProvider.class
@AllArgsConstructor(onConstructor = @__(@Inject))
public final class RetryConsumerProvider implements Provider<SqsConsumer> {
@Named("RetryMessageHandler")
private final SqsMessageHandler sqsMessageHandler;
@Override
public SqsConsumer get() {
// initializing retry SQS queue
}
RetryMessageHandlerProvider.class
@AllArgsConstructor(onConstructor = @__(@Inject))
public final class RetryMessageHandlerProvider implements Provider<SqsMessageHandler> {
@Override
public SqsMessageHandler get() {
// Initialising RetryMessageHandlerProvider
}
I think I have used com.google.inject.name.Names
import correctly, but I am willing to try any new suggestions to make this work.
Thanks