LoginSignup
6
6

More than 5 years have passed since last update.

簡単にコンポーネントのデフォルト値を書き換える・バグを避ける(Apache Camel)

Last updated at Posted at 2016-04-22

オープンソースを使う事

オープンソースを使うからバグを治せると言っても実際に治した後の対処が大変。
しかし、この記事のように横から置き換える事ができると気軽に治せる。

治した後はコミュニティにスタックトレースでも送ってくださいね。
今回の例の場合では翌日には修正されていました。

デフォルト値とバグ

全く違うような話だがそうでもない。
どちらもデフォルトの動作を書き換えようという話だから。
そして、どちらも業務的な実装を書き換える事はしなくて済む話をする。

不具合の例

サンプルコード

from("direct:in")
        .to("netty4-http:http://camel.apache.org")
        .to("log:test");

発生する例外
java.lang.IllegalArgumentException: port out of range:-1

Camel2.17.0で発生し、2.17.1で修正される

回避方法

不具合を起こす設定を書き換えてあげる

MyNettyHttpComponent.java
package hello.camel;

import org.apache.camel.Endpoint;
import org.apache.camel.component.netty4.NettyConfiguration;
import org.apache.camel.component.netty4.http.NettyHttpComponent;
import org.apache.camel.component.netty4.http.NettyHttpEndpoint;

import java.util.Map;

public class MyNettyHttpComponent extends NettyHttpComponent {

    // .to("netty4-http:xxxxx")が呼び出される度に、ここで初期化される
    @Override
    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
        Endpoint endpoint = super.createEndpoint(uri, remaining, parameters);
        NettyHttpEndpoint nettyHttpEndpoint = (NettyHttpEndpoint) endpoint;
        // configurationのポート番号が-1に設定されるバグなので、書き換え
        NettyConfiguration configuration = nettyHttpEndpoint.getConfiguration();
        if (configuration.getPort() == -1) {
            if (remaining.startsWith("http:")) {
                configuration.setPort(80);
            } else if (remaining.startsWith("https:")) {
                configuration.setPort(443);
            }
        }
        return nettyHttpEndpoint;
    }
}

netty4-httpのコンポーネントを自作したコンポーネントに切り替える

@Componentを付けたクラスならどこに書いても良い

MyConfig.java
package hello.camel;

import org.apache.camel.component.netty4.http.NettyHttpComponent;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class MyConfig {
    // to("netty4-http:xxxxx")は自作のコンポーネントに書き換える
    @Bean(name = "netty4-http")
    public NettyHttpComponent netty4http() {
        NettyHttpComponent component = new MyNettyHttpComponent();
        return component;
    }
}

これだけでバグ修復完成!
動かないけどどうしても使いたいコンポーネントがあれば、これで修復できる場合がある。
ランタイム部分の実装を修正するには別の機会にでも・・・

Timerコンポーネントのデフォルト値の書き換え

デフォルト値を設定してあげる

やり方は同じ
今回はTimerコンポーネントのperiodデフォルト値を5sに書き換える

MyTimerComponent.java
package hello.camel;

import org.apache.camel.Endpoint;
import org.apache.camel.component.timer.TimerComponent;

import java.util.Map;

public class MyTimerComponent extends TimerComponent {
    @Override
    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
        // periodが設定されていない場合、ここで設定してあげる
        if (!parameters.containsKey("period"))
            parameters.put("period", "5s");
        return super.createEndpoint(uri, remaining, parameters);
    }
}

Timerのコンポーネントを切り替える

MyConfig2.java
package hello.camel;

import org.apache.camel.component.timer.TimerComponent;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class MyConfig2 {
    @Bean(name = "timer")
    public TimerComponent timerComponent() {
        TimerComponent component = new MyTimerComponent();
        return component;
    }
}

ソースコード

6
6
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
6
6