Home > Software design >  How to use error-channel for catching exception in Spring Integration?
How to use error-channel for catching exception in Spring Integration?

Time:08-04

What I am trying to do? : I am new to Spring Integration and already have read many similar questions regarding error handling but I don't understand how to catch exceptions using error-channel?

What I have done so far:

@EnableIntegration
@IntegrationComponentScan
@Configuration
public class TcpClientConfig implements ApplicationEventPublisherAware {

  private ApplicationEventPublisher applicationEventPublisher;
  private final ConnectionProperty connectionProperty;

  @Override
  public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
    this.applicationEventPublisher = applicationEventPublisher;
  }

  TcpClientConfig(ConnectionProperty connectionProperty) {
    this.connectionProperty = connectionProperty;
  }

  @Bean
  public AbstractClientConnectionFactory clientConnectionFactory() {
    TcpNioClientConnectionFactory tcpNioClientConnectionFactory =
        getTcpNioClientConnectionFactoryOf(
            connectionProperty.getPrimaryHSMServerIpAddress(),
            connectionProperty.getPrimaryHSMServerPort());

    final List<AbstractClientConnectionFactory> fallBackConnections = getFallBackConnections();
    fallBackConnections.add(tcpNioClientConnectionFactory);

    final FailoverClientConnectionFactory failoverClientConnectionFactory =
        new FailoverClientConnectionFactory(fallBackConnections);

    return new CachingClientConnectionFactory(
        failoverClientConnectionFactory, connectionProperty.getConnectionPoolSize());
  }

  @Bean
  DefaultTcpNioSSLConnectionSupport connectionSupport() {

    final DefaultTcpSSLContextSupport defaultTcpSSLContextSupport =
        new DefaultTcpSSLContextSupport(
            connectionProperty.getKeystorePath(),
            connectionProperty.getTrustStorePath(),
            connectionProperty.getKeystorePassword(),
            connectionProperty.getTruststorePassword());

    final String protocol = "TLSv1.2";
    defaultTcpSSLContextSupport.setProtocol(protocol);
    return new DefaultTcpNioSSLConnectionSupport(defaultTcpSSLContextSupport, false);
  }

  @Bean
  public MessageChannel outboundChannel() {
    return new DirectChannel();
  }



  @Bean
  @ServiceActivator(inputChannel = "outboundChannel")
  public MessageHandler outboundGateway(AbstractClientConnectionFactory clientConnectionFactory) {
    TcpOutboundGateway tcpOutboundGateway = new TcpOutboundGateway();
    tcpOutboundGateway.setConnectionFactory(clientConnectionFactory);
    return tcpOutboundGateway;
  }
  @Bean
  @ServiceActivator(inputChannel = "error-channel")
  public void handleError(ErrorMessage em) {
    throw new RuntimeException(String.valueOf(em));
  }

  private List<AbstractClientConnectionFactory> getFallBackConnections() {
    final int size = connectionProperty.getAdditionalHSMServersConfig().size();
    List<AbstractClientConnectionFactory> collector = new ArrayList<>(size);
    for (final Map.Entry<String, Integer> server :
        connectionProperty.getAdditionalHSMServersConfig().entrySet()) {
      collector.add(getTcpNioClientConnectionFactoryOf(server.getKey(), server.getValue()));
    }
    return collector;
  }

  private TcpNioClientConnectionFactory getTcpNioClientConnectionFactoryOf(
      final String ipAddress, final int port) {
    TcpNioClientConnectionFactory tcpNioClientConnectionFactory =
        new TcpNioClientConnectionFactory(ipAddress, port);
    tcpNioClientConnectionFactory.setUsingDirectBuffers(true);
    tcpNioClientConnectionFactory.setDeserializer(new CustomDeserializer());
    tcpNioClientConnectionFactory.setApplicationEventPublisher(applicationEventPublisher);
    tcpNioClientConnectionFactory.setSoKeepAlive(true);
    tcpNioClientConnectionFactory.setConnectTimeout(connectionProperty.getConnectionTimeout());
    tcpNioClientConnectionFactory.setSoTcpNoDelay(true);
    tcpNioClientConnectionFactory.setTcpNioConnectionSupport(connectionSupport());
    return tcpNioClientConnectionFactory;
  }
}

Gateway

@Component
@MessagingGateway(defaultRequestChannel = "outboundChannel",errorChannel ="error-channel" )
public interface TcpClientGateway {
    String send(String message);
}

Also currently, I am facing

required a bean of type org.springframework.messaging.support.ErrorMessage that could not be found

I need some assistance!
Thanking you in advance,

CodePudding user response:

See documentation about messaging annotation:

Your problem is here: https://docs.spring.io/spring-integration/docs/current/reference/html/configuration.html#annotations_on_beans

  @Bean
  @ServiceActivator(inputChannel = "error-channel")
  public void handleError(ErrorMessage em) {

This is a plain POJO method, therefore it cannot be marked with a @Bean. You use a @Bean really for beans to expose. Then you decide if that has to be a @ServiceActivator or not. So, just remove @Bean from this method and your error-channel consumer should be OK.

  • Related