LoginSignup
2
1

More than 5 years have passed since last update.

インターセプタを設定したTcpConnectionが発行するTcpConnectionOpenEventのコネクションファクトリ名がunknownになる件が修正されます

Last updated at Posted at 2018-01-16

確認環境

  • Java 8
  • STS 3.9.1.RELEASE
  • Spring Framework 4.3.13
  • Spring Integration 4.3.12

どういう問題?

おおまかなTCP/IP通信の仕組み

Spring IntegrationではTCP/IP通信をサポートしていて、TcpIn/OutboundGatewayや、In/OutboundChannelAdapterが通信の窓口として用意され、それぞれにConnectionFactoryに紐づけられています。通信が必要になった場合、窓口となるGatewayまたはAdapterConnectionFactoryからTcpConnectionインスタンスを生成し通信します。

インターセプタとは?

通信する際に、ログ出力など、なんらかの処理を挟み込みたい場合は、ConnectionFactoryInterceptorFactoryChainプロパティにTcpConnectionInterceptorSupportを継承したクラスのインスタンスを返すTcpConnectionInterceptorFactoryクラスを指定します。以下は実装例です。

TcpConnectionInterceptorSupportを継承したクラス
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorSupport;
import org.springframework.messaging.Message;

public class SimpleInterceptor extends TcpConnectionInterceptorSupport {

    private static final Logger logger = LoggerFactory.getLogger(SimpleInterceptor.class);

    public SimpleInterceptor(ApplicationEventPublisher publisher) {
        super(publisher);
    }

    @Override
    public void send(Message<?> message) throws Exception {
        // メッセージ送信前にログ出力処理を挟み込む
        logger.debug("send message via interceptor");
        super.send(message);
    }
}
TcpConnectionInterceptorSupportを継承したクラスのインスタンスを返すTcpConnectionInterceptorFactory
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactory;
import org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorSupport;

public class SimpleInterceptorFactory extends ApplicationObjectSupport implements TcpConnectionInterceptorFactory {

    public SimpleInterceptorFactory() {
    }

    @Override
    public TcpConnectionInterceptorSupport getInterceptor() {
        return new SimpleInterceptor(getApplicationContext());
    }
}
bean定義ファイル
<int-ip:tcp-connection-factory id="client1"
    type="client" host="localhost" port="${availableServerSocket1}"
    single-use="true" interceptor-factory-chain="interceptorFactoryChain" />
<bean id="interceptorFactoryChain"
    class="org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactoryChain">
    <property name="interceptors">
        <array>
            <bean
                class="com.neriudon.example.tcp.interceptor.SimpleInterceptorFactory" />
        </array>
    </property>
</bean>

何が問題なの?

ConnectionFactoryTcpConnectionを生成しSocketレベルでの接続が確立されるタイミングでTcpConnectionOpenEventを発行しますが、ConnectionFactoryにインターセプタを設定していると、connectionfactorynameプロパティが初期値であるunknownのままになります。
以下はインターセプタを設定した場合と設定していない場合のログ出力結果の比較です。

インターセプタを設定した場合
11:58:32.397 [main] DEBUG com.neriudon.example.tcp.listener.TcpConnectionEventsListener - ★OPEN★ TcpConnectionOpenEvent [source=SimpleInterceptor:null], [factory=unknown, connectionId=localhost:50001:58459:aa1f25b0-570e-4631-8477-33a19f1bb6ba] **OPENED**
インターセプタを設定していない場合
11:58:32.434 [main] DEBUG com.neriudon.example.tcp.listener.TcpConnectionEventsListener - ★OPEN★ TcpConnectionOpenEvent [source=TcpNetConnection:localhost:50002:58460:a92051dd-9003-4563-be59-3675dee3112d], [factory=client2, connectionId=localhost:50002:58460:a92051dd-9003-4563-be59-3675dee3112d] **OPENED**

この問題が発生する理由と改善策

TcpConnectionInterceptorSupportクラスにConnectionFactoryNameを設定する処理がないのが原因です。が、ConnectionFactoryの情報は実際に通信をするTcpConnectionが持っているので、ConnectionFactoryNameを返す時にTcpConnectionInterceptorSupportTcpConnectionConnectionFactoryNameを返すようにすれば:ok_hand:。詳しくは下記のPRのリンクを参照してください。
ちなみに他のTcpConnectionEventは元々TcpConnectionInterceptorSupportTcpConnectionの処理を呼び出すよう設計されているので問題ありません。

この問題による影響は?

ほとんど無いです:stuck_out_tongue_winking_eye:
TcpConnectionInterceptorSupportがmasterに取り込まれたのが2016年3月で、それからバグ報告がされなかったのと、TcpConnectionOpenEvent自体がSpring Integrationドキュメントでも浅く書かれているので、この問題がプロジェクトに深刻な影響を与えてはいないでしょう。

いつ修正されるの?

リリースされる日付は分かりませんが、JIRAを見る限り、次の5.0.1, 4.3.14で修正されます。2018年1月15日時点でPRが出されているので、近々マージされるでしょう。

この記事を投稿するに至った経緯

この件についてstackoverflowで質問したのが私だからです:stuck_out_tongue_closed_eyes:
Spring Integrationプロジェクトでは、使い方や仕様に関する質問はspring-integrationタグを付けてstackoverflowで質問するルールになっています。私はバグか仕様なのか判断がつかなかったので、サンプルアプリを作成したうえで、発生する条件やログを提示したところ、中の人からバグですと回答がありました。
しかし、もたもたしてるうちに中の人がJIRAに起票してしまったので、初のOSSへのバグ報告できなくて残念:confounded:

1/30 追記:
今回の修正を取り込んだ4.3.14.RELEASEおよび5.0.1.RELEASEがリリースされました:v:

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1