question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to setup error channel for PubSub consumer binding with explicit subscription name?

See original GitHub issue

I have consumer binding defined like:

spring.cloud.stream.gcp:
  pubsub:
    bindings:
      ongoing-messages-input:
         consumer:
         subscriptionName: my-pull-transactions

I define error handler like this:

    @ServiceActivator(inputChannel = "ongoing-messages-input.errors")
    public void handleError(Message<MessagingException> failedMessage) {

The framework creates an error channel out-of-box my-pull-transactions.errors, i.e. based on subscription name.

I want it to be ongoing-messages-input.errors how to achieve this? It should work as well, all error message from this channel goes to my custom channel.

I can’t rely on the subscription name as this is a dynamic value for me and depends on the environment.

I tried:

  • Define
spring.cloud.stream:
  bindings:
    ongoing-messages-input: #channel name
      destination: my-topic-name #topic name
      binder: pubsub
  • Customize error channel name like this:
    @Bean
    public ConsumerEndpointCustomizer<PubSubInboundChannelAdapter> messageChannelAdapter() {
        return (endpoint, destinationName, group) -> endpoint.setErrorChannelName("ongoing-messages-input.errors");
    }

I get the error:

java.lang.IllegalArgumentException: 'beanFactory' must not be null
	at org.springframework.util.Assert.notNull(Assert.java:201)
	at org.springframework.integration.support.channel.ChannelResolverUtils.getChannelResolver(ChannelResolverUtils.java:49)
	at org.springframework.integration.context.IntegrationObjectSupport.getChannelResolver(IntegrationObjectSupport.java:257)
	at org.springframework.integration.endpoint.MessageProducerSupport.getErrorChannel(MessageProducerSupport.java:126)
	at com.google.cloud.spring.pubsub.integration.inbound.PubSubInboundChannelAdapter.getErrorChannel(PubSubInboundChannelAdapter.java:161)
	at org.springframework.integration.endpoint.MessageProducerSupport.sendErrorMessageIfNecessary(MessageProducerSupport.java:252)
	at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:211)

To fix this I tried to define channel bean with a correspondent name - no result:

    @Bean(name = "ongoing-messages-input.errors")
    public MessageChannel errorChannel() {
        return new QueueChannel();
    }

Suggestion, it would be really helpful if PubSubInboundChannelAdapter has a method to return input channel name, as it has reference to this bean. Even fixing this bug, inside ConsumerEndpointCustomizer there is no way to properly resolve the new name in case of multiple binders. In my example, I have to hardcode, which is not good.

Workaround: Propagate bean factory:

@Bean
    public ConsumerEndpointCustomizer<PubSubInboundChannelAdapter> messageChannelAdapter(ConfigurableApplicationContext applicationContext) {
        return (endpoint, destinationName, group) -> {
            endpoint.setErrorChannelName("ongoing-messages-input.errors");
            endpoint.setBeanFactory(applicationContext.getBeanFactory());
        };
    }

I think this workaround should be fixed somewhere in com.google.cloud.spring.stream.binder.pubsub.PubSubMessageChannelBinder #createConsumerEndpoint as this class has a reference to app context and a method to get bean factory already.

The suggestion still is open, as it will be a problem for multiple consumer bindings. I’m open to contribute ✌️

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:11 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
dzoucommented, Jun 22, 2021

Ok, I see what you’re saying.

  • pubSubInboundChannelAdapter.getChannelName() seems fine to add, I would be okay with the contribution.
  • This endpoint.setBeanFactory(applicationContext.getBeanFactory()); seems to make sense but will have to double check to make sure it doesn’t cause a regression.

Let us check-in with Spring team on how to override error channel.

@artembilan – Do you have any advice regarding how a user might easily override the default error channel destination for a Spring stream channel binder? We configure a Pub/Sub stream error handler like this. I’m wondering if there is a standard way in Spring to let users to override this destination or easily forward messages from the default error channel to a custom one.

0reactions
dzoucommented, Jun 25, 2021

Fixed by #515

Read more comments on GitHub >

github_iconTop Results From Across the Web

Handle message failures | Cloud Pub/Sub
In the Google Cloud console, go to the Pub/Sub subscriptions page. · Click Create subscription. · In the Subscription ID field, enter a...
Read more >
Cloud Pub/Sub - Spring Boot on GCP
In Spring Integration, you can configure bind an input channel to a Pub/Sub Subscription using the PubSubInboundChannelAdapter .
Read more >
Spring Cloud GCP
Publish and subscribe to Google Cloud Pub/Sub topics. Configure Spring JDBC with a few properties to use Google Cloud SQL.
Read more >
Publish and subscribe overview - Dapr Docs
The consumer, or subscriber, subscribes to the topic and receives messages from an output channel, unaware which service produced these messages ...
Read more >
Spring Cloud Stream Reference Guide
Spring Cloud Stream uses Spring Boot for configuration, and the ... In this example, the created bound channel will be named inboundOrders ....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found