メインコンテンツまでスキップ
Version: 3.4.4

ルータープログラム

プログラムの用途実装するJavaインターフェース注意事項
ルータープログラムRouteBuilderFlow Management > Router Information
ルータープログラムRouterProcessorRouter Information > Processing Program ID

基本ルーター以外に、新規ルーターを追加する場合に使用する。 ルータープログラム、およびルータープログラムを一緒に開発する必要がある。

開発方法

ルーター処理プログラムは、RouterProcessorを継承してprocessメソッドを実装する必要がある。下記の例は、対内システムで受信された電文が、Dummy電文かどうかを判断するルーターを開発し、当該ルーターを呼び出すルーター処理プログラムの例である。

caution

ルータープログラムは、開発後Flow Management > Router Informationに登録して使用する必要がある。 ルータープログラムは、動的に追加することはできるが、変更はできないため、ルータープログラムを変更した場合には、BXIを再実行する必要がある。

ルータープログラム

Apache camelのRouteBuilderを実装する。

public class InternalResponseDistinctRouter extends RouteBuilder {

/** Router process bean name */
private final String beanName;

/**
* Constructor
*
* @param beanName
*/
public InternalResponseDistinctRouter(String beanName) {
this.beanName = beanName;
}

/**
* Let's configure the Camel routing rules using Java code...
*/
@Override
public void configure() {
Processor nameProcess = RouterUtil.routerTemporaryProcess(beanName);

interceptFrom().setHeader(CamelHeader.ROUTER_ID, constant("internalResponseDistinctRouter"))
.routeId("internalResponseDistinctRouter").process("loggingPreProcessor");
from("direct:internalResponseDistinct").routeId("internalResponseDistinctRouter")
.process(nameProcess)
.process("routerBeanCallProcessor")
.end().process("loggingPostProcessor");
}
}

1. ルーターで処理するプログラムを入力

public class InternalResponseDistinctRouter extends RouteBuilder {

/** Router process bean name */
private final String beanName;

/**
* Constructor
*
* @param beanName
*/
public InternalResponseDistinctRouter(String beanName) {
this.beanName = beanName;
}

Router ProgramのConstructorを通じて処理プログラムの入力を受ける。入力される処理プログラムは、必ずSpring Beanプログラムでなければならない。

2. ルーター処理Configure

@Override
public void configure() {

RouteBuilderのconfigureメソッドを実装する。

configureメソッドは、ルーターがメッセージを受け取って処理する部分について順序どおりに記述する部分である。 configureメソッドに記述するルーターIDは、ルーターを識別するIDでUniqueでなければならない。 また、from句のURLは、外部から当該ルーターを呼び出す際に使用するURLとしてUniqueでなければならない。

3. ルーター処理プログラム伝達準備

Processor nameProcess = RouterUtil.routerTemporaryProcess(beanName);

入力で受け取ったプログラムを、直接.process()の因子として渡すことはできない。 そのため、Processor interfaceのinnerオブジェクトを1つ作成し、入力されたプログラムを、Exchangeのin領域のヘッダーを通じて伝達する。

このようにする理由は、.process()で呼び出されるすべての処理プログラムの因子は、常にExchangeであるからである。 1つのルーターから他のルーターを呼び出す際に入力で伝達されるメッセージは、Exchange in領域に伝達し、Exchange inやout領域で結果を受け取る。

4. ルーター入力ロギング

interceptFrom().setHeader(CamelHeader.ROUTER_ID, constant("internalResponseDistinctRouter"))
.routeId("internalResponseDistinctRouter").process("loggingPreProcessor");

ルータープログラムの処理は、常にfromから始まる。

BXIのルーターは、ルーター入力と出力に対してロギングできるが、これを処理するために、fromをインターセプターして、先に入力に対するロギングを行う。loggingPreProcessorに入力で伝達される因子は、fromから受けるExchangeである。

5. ルーター処理プログラムの呼び出し

from("direct:internalResponseDistinct").routeId("internalResponseDistinctRouter")
.process(nameProcess)
.process("routerBeanCallProcessor")

外部からルーターを呼び出すURLは、from句に記述したdirect:internalResponseDistinctである。

つまり、ルーターを代表するURLでも、重複するとエラーが発生するため、ルーターごとにUniqueなURLを付与する必要がある。 BXIは、ルーター情報を登録する際に、ルーターのURLも一緒に登録してフローを作成する際に使用する。

外部からdirect:requestHeaderMappingでルーターを呼び出すと、まずルーター処理プログラム伝達準備のプロセスを先に実行し、入力で受け取ったプログラムをExchangeのin領域のヘッダーに保存する。

次にrouterBeanCallProcessorプログラムは、Exchangeを入力で受け取り、in領域のヘッダーからルーター処理プログラムを照会してプログラムを呼び出す。 routerBeanCallProcessorは、BXIからルーター処理プログラムを呼び出すUtilityである。

ルーター処理プログラムを呼び出す際の入力としてはfromから受け取ったExchangeである。

6. ルーター出力ロギング

.end().process("loggingPostProcessor");

ルーターのすべての処理が終わったら、最後にルーターの出力に対するロギングを処理する。 出力をロギングするloggingPostProcessorは、Exchangeを入力で受け取ってロギングする。

ルーター処理プログラム

bxi.api-{version}.jarRouterProcessorを実装する。

@Component
public class InternalResponseDistinctProcessor extends RouterProcessor {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

/**
* Processes the message exchange
*
* @param exchange
* @throws Exception
*/
@Override
public void process(ProcessorExchange exchange) throws Exception {
ExchangeMessage bxiMessage = exchange.getBxiMessage();
logger.debug("Input getBody : {}", bxiMessage);

// TODO : Writing the program for the router function

RequestResponseKindEnum rqstRspsDscd = RequestResponseKindEnum.getByCode(
bxiMessage.getRqstRspsDscd());
if (RequestResponseKindEnum.REQUEST == rqstRspsDscd) {
return;
}

Map<String, Object> header = ObjectUtil.isEmpty(bxiMessage.getStdHeader())
? bxiMessage.getComHeader() : bxiMessage.getStdHeader();
logger.debug("header : {}", header);

if ("DMY".equals(header.get("rspsCd"))) {
logger.info("Skip message. Dummy response. guid : {}", bxiMessage.getGuid());
// 次のRouter Stop処理のためにHeader Set
exchange.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);
}
}
}

1. ルーター処理プログラム開始

@Override
public void process(ProcessorExchange exchange) throws Exception {
ExchangeMessage bxiMessage = exchange.getBxiMessage();
logger.debug("Input getBody : {}", bxiMessage);

processメソッドはパラメータでProcessorExchangeを受け取る。

2. ルーター処理プログラム開発

RequestResponseKindEnum rqstRspsDscd = RequestResponseKindEnum.getByCode(
bxiMessage.getRqstRspsDscd());
if (RequestResponseKindEnum.REQUEST == rqstRspsDscd) {
return;
}

Map<String, Object> header = ObjectUtil.isEmpty(bxiMessage.getStdHeader())
? bxiMessage.getComHeader() : bxiMessage.getStdHeader();
logger.debug("header : {}", header);

if ("DMY".equals(header.get("rspsCd"))) {
logger.info("Skip message. Dummy response. guid : {}", bxiMessage.getGuid());
// 次のRouter Stop処理のためにHeader Set
exchange.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);
}

この部分にルーターの機能に適するプログラムを開発する。 上記の例は、当該電文が要求電文でありながらDummy電文である場合に処理を中断する例である。