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

通信網電文処理プログラム

プログラムの用途実装するJavaインターフェース適用する設定画面
ユーザー呼び出しプログラムNetMessageProcessBase Setting Management > Institutional Business Information

機関の開始、終了状態をFEPで管理する場合、通信網管理プログラムを利用して、機関の通信網電文の代行応答や、状態管理を実行することができる。

caution

機関の通信網状態を管理しない機関の場合、内部業務システムで管理する場合には使用しない。

通信網電文の種類

  • 開始当日取引を開始する前に相手と業務開始を知らせる電文
  • 終了当日の取引をすべて終えた後に相手との業務を終了する電文
  • 終了予告当日の業務がまもなく終了するため、溜まっている取引がある場合に早く終了することを依頼する電文
  • 一時停止のための、一時的に取引を停止する電文
  • 一時取引解除のための、一時的に停止した取引を再開する電文
  • 回線試験ポーリング電文で、チャネルが切断したかを確認する電文

開発方法

通信網電文は、通信網処理が同じであれば1つのプログラムで処理できるが、電文レイアウトと電文コードが異なる場合、対外機関別に別のプログラムで処理する必要がある。

要求通信網電文処理API

対外機関に要求通信網電文を作成するAPIである。

@Override
public byte[] requestMessage(String instCd, String bizCd, String netTypeCd, String netLayout) {
Map<String, Object> comHead = new LinkedHashMap<String, Object>();

// 1. Generate transaction code
BusinessOpenStatusEnum typeCd = BusinessOpenStatusEnum.getByCode(netTypeCd);
if (typeCd == BusinessOpenStatusEnum.POLLING) {
comHead.put("txCode", "POLLING");
} else if (typeCd == BusinessOpenStatusEnum.INITIATED) {
comHead.put("txCode", "STARTED");
}

// 2. Create management message
comHead.put("msgLen", "0081");
comHead.put("sysId", "90");
comHead.put("repInstCd", instCd);
comHead.put("msgCbtpCd", "0800");

if (typeCd == BusinessOpenStatusEnum.POLLING) {
comHead.put("msgBizDscd", "300");
} else if (typeCd == BusinessOpenStatusEnum.INITIATED) {
comHead.put("msgBizDscd", "101");
}

comHead.put("srFlag", "C");
comHead.put("rspsCd", "000");
comHead.put("brnchCd", "0020001");

Random random = new Random();
int fdrtnMsgNo = random.nextInt(9999999);
comHead.put("fnceInstMsgNo", String.format("%07d", fdrtnMsgNo));
comHead.put("fnceInstMsgTm",
DateUtil.getCurrentDate(DateUtil.EMPTY_MILL_DATE_TIME_TYPE).substring(0, 14));
comHead.put("fdrtnMsgNo", "0000000");
comHead.put("fdrtnMsgTm",
DateUtil.getCurrentDate(DateUtil.EMPTY_MILL_DATE_TIME_TYPE).substring(0, 14));

// 3. Create transfer message
byte[] array = (byte[]) Marshaller.marshal(MessageTypeEnum.FIXED_MESSAGE, netLayout,
comHead, null, false, null);

return array;
}
  1. 通信網電文の種類別に取引コードを作成する。
  2. 機関の通信網電文のレイアウトに適する通信網電文を作成する。
  3. 作成した通信網電文を対外機関に伝送できる電文に変換する。
  4. BXIは、作成された電文を当該機関に接続されたコネクションに伝送する。

☑ 入力

  • instCd : 通信網電文を伝送する機関コード
  • bizCd : 機関に属する業務コード
  • netTypeCd : 通信網の種類コード
  • netLayout : 通信網電文のレイアウト名
通信網の種類コード

1 : 開始、2 : 種類、3 : 終了予告、5 : 一時取引停止、6 : 一時取引停止解除、7 : 回線試験(ポーリング)

☑ 出力

  • 入力で伝達された通信網の種類別に作成された電文

応答通信網電文処理API

対外機関から受信した要求通信網電文に対する応答電文を作成するAPIである。

@Override
public byte[] responseMessage(String instCd, String bizCd, String msgCbtpCd,
String msgBizDscd, byte[] message, String netLayout) {

// Change category code
byte[] response = new byte[message.length];
System.arraycopy(message, 0, response, 0, 20);
response[20] = '1';
System.arraycopy(message, 21, response, 21, (message.length - 21));

return response;
}
  1. 要求通信網電文による応答電文を作成する。
  2. 上記の例は、通信網の種別コードを応答の種別コードに変更する例である。
  3. BXIは、APIで作成された電文を当該機関に接続されたコネクションに応答する。

☑ 入力

  • instCd : 通信網電文を受信した機関コード
  • bizCd : 機関に属する業務コード
  • msgCbtpCd : 通信網の種別コード
  • msgBizDscd : 通信網の業務区分コード(開始、終了、終了予告、障害)
  • message : 受信した通信網電文
  • netLayout : 通信網電文のレイアウト名

☑ 出力

  • 通信網要求電文に対する応答電文

通信網電文検証API

対外機関から受信した通信網電文が、登録された通信網電文なのかを判断するAPIである。

@Override
public boolean isMessage(String netTypeCd, byte[] message) {
// Communication category code
byte[] array = new byte[4];
System.arraycopy(message, 18, array, 0, 4);
String msgCbTpCd = new String(array);

// Communication business type code
array = new byte[3];
System.arraycopy(message, 22, array, 0, 3);
String msgBizCd = new String(array);

logger.debug("msgCbTpCd : [{}], msgBizCd : [{}]", msgCbTpCd, msgBizCd);

if ((msgCbTpCd.equals("0800") || msgCbTpCd.equals("0810"))) {
BusinessOpenStatusEnum typeCd = BusinessOpenStatusEnum.getByCode(netTypeCd);
if (typeCd == BusinessOpenStatusEnum.POLLING) {
return (msgBizCd.equals("300"));
}
}

return false;
}
  1. 受信した電文で電文種別コードを求める。
  2. 受信した電文で業務区分コードを求める。
  3. 種別コードが通信網電文でありながら、入力で与えられた通信網電文の種類と同じの場合、trueを返す。
  4. 上記の例は、Polling電文なのかを判断する例である。

☑ 入力

  • netTypeCd : 通信網の種類コード
  • message : 受信した通信網電文

☑ 出力

  • true : 入力で伝達された通信網電文の種類と同じ電文である。
  • false : 入力で伝達された通信網電文の種類と違う電文である。

通信網電文であるかどうかの検証API

対外機関から受信した電文が、通信網電文なのかを判断するAPIである。

@Override
public boolean isMessage(String instCd, String bizCd, byte[] message) {
// Communication category code
byte[] array = new byte[4];
System.arraycopy(message, 18, array, 0, 4);
String msgCbTpCd = new String(array);

logger.debug("msgCbTpCd : [{}]", msgCbTpCd);

if ((msgCbTpCd.equals("0800") || msgCbTpCd.equals("0810"))) {
return true;
} else {
return false;
}
}
  1. 受信した電文で電文種別コードを求める。
  2. 種別コードが通信網電文の場合、trueを返す。

☑ 入力

  • instCd : 電文を受信した機関コード
  • bizCd : 機関に属する業務コード
  • message : 受信した電文

☑ 出力

  • true : 受信した電文が通信網電文である
  • false : 受信した電文が通信網電文ではない

通信網電文状態コード変換API

BXIは、機関別に通信網状態を管理する。 つまり、通信網状態が開始前の場合、電文を対外機関に伝送できないように制御する。

通信網電文状態コード変換APIは、対外機関から受信した通信網電文を、業務区分コード別に状態コードに変換するAPIである。

@Override
public String netStatus(String msgCbtpCd, String msgBizDscd, Map<String, Object> message) {
if (!msgCbtpCd.equals("0800") && !msgCbtpCd.equals("0810")) {
return BusinessOpenStatusEnum.UNKNOWN.getCode();
}

switch (Integer.parseInt(msgBizDscd)) {
case 101:
return BusinessOpenStatusEnum.INITIATED.getCode();

case 210:
return BusinessOpenStatusEnum.CLOSED.getCode();

case 300:
return BusinessOpenStatusEnum.POLLING.getCode();

case 400:
return BusinessOpenStatusEnum.ACCIDENT.getCode();

case 500:
return BusinessOpenStatusEnum.ACCIDENT_RECOVERY.getCode();

default:
return BusinessOpenStatusEnum.UNKNOWN.getCode();
}
}
  1. 通信網電文ではない場合、返す。
  2. 業務区分コード別に状態コードを返す。
  3. BXIは、状態コードを機関別にデータベースに反映する。

☑ 入力

  • msgCbtpCd : 通信網の種別コード
  • msgBizDscd : 通信網の業務区分コード(開始、終了、終了予告、障害)
  • message : 受信した電文をUnmarshalしたデータ

☑ 出力

  • 状態コード

全体例

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import bxi.api.NetMessageProcess;
import bxi.common.enums.BusinessOpenStatusEnum;
import bxi.common.enums.MessageTypeEnum;
import bxi.common.utility.DateUtil;
import bxi.parser.Marshaller;

@Component
public class NetMessageProcessImpl implements NetMessageProcess {
private final static Logger logger = LoggerFactory.getLogger(NetMessageProcessImpl.class);

@Override
public byte[] requestMessage(String instCd, String bizCd, String netTypeCd, String netLayout) {
Map<String, Object> comHead = new LinkedHashMap<String, Object>();

BusinessOpenStatusEnum typeCd = BusinessOpenStatusEnum.getByCode(netTypeCd);
if (typeCd == BusinessOpenStatusEnum.POLLING) {
comHead.put("txCode", "POLLING");
} else if (typeCd == BusinessOpenStatusEnum.INITIATED) {
comHead.put("txCode", "STARTED");
}

comHead.put("msgLen", "0081");
comHead.put("sysId", "90");
comHead.put("repInstCd", instCd);
comHead.put("msgCbtpCd", "0800");

if (typeCd == BusinessOpenStatusEnum.POLLING) {
comHead.put("msgBizDscd", "300");
} else if (typeCd == BusinessOpenStatusEnum.INITIATED) {
comHead.put("msgBizDscd", "101");
}

comHead.put("srFlag", "C");
comHead.put("rspsCd", "000");
comHead.put("brnchCd", "0020001");

int fdrtnMsgNo = ThreadLocalRandom.current().nextInt(9999999);
comHead.put("fnceInstMsgNo", String.format("%07d", fdrtnMsgNo));
comHead.put("fnceInstMsgTm",
DateUtil.getCurrentDate(DateUtil.EMPTY_MILL_DATE_TIME_TYPE).substring(0, 14));
comHead.put("fdrtnMsgNo", "0000000");
comHead.put("fdrtnMsgTm",
DateUtil.getCurrentDate(DateUtil.EMPTY_MILL_DATE_TIME_TYPE).substring(0, 14));

byte[] array = (byte[]) Marshaller.marshal(MessageTypeEnum.FIXED_MESSAGE, netLayout,
comHead, null, false, null);

return array;
}

@Override
public byte[] responseMessage(String instCd, String bizCd, String msgCbtpCd,
String msgBizDscd, byte[] message, String netLayout) {

// Change category code
byte[] response = new byte[message.length];
System.arraycopy(message, 0, response, 0, 20);
response[20] = '1';
System.arraycopy(message, 21, response, 21, (message.length - 21));

return response;
}

@Override
public boolean isMessage(String netTypeCd, byte[] message) {
// Communication category code
byte[] array = new byte[4];
System.arraycopy(message, 18, array, 0, 4);
String msgCbTpCd = new String(array);

// Communication business type code
array = new byte[3];
System.arraycopy(message, 22, array, 0, 3);
String msgBizCd = new String(array);

logger.debug("msgCbTpCd : [{}], msgBizCd : [{}]", msgCbTpCd, msgBizCd);

if ((msgCbTpCd.equals("0800") || msgCbTpCd.equals("0810"))) {
BusinessOpenStatusEnum typeCd = BusinessOpenStatusEnum.getByCode(netTypeCd);
if (typeCd == BusinessOpenStatusEnum.POLLING) {
return (msgBizCd.equals("300"));
}
}

return false;
}

@Override
public boolean isMessage(String instCd, String bizCd, byte[] message) {
// Communication category code
byte[] array = new byte[4];
System.arraycopy(message, 18, array, 0, 4);
String msgCbTpCd = new String(array);

logger.debug("msgCbTpCd : [{}]", msgCbTpCd);

if ((msgCbTpCd.equals("0800") || msgCbTpCd.equals("0810"))) {
return true;
} else {
return false;
}
}

@Override
public String netStatus(String msgCbtpCd, String msgBizDscd, Map<String, Object> message) {
if (!msgCbtpCd.equals("0800") && !msgCbtpCd.equals("0810")) {
return BusinessOpenStatusEnum.UNKNOWN.getCode();
}

switch (Integer.parseInt(msgBizDscd)) {
case 101:
return BusinessOpenStatusEnum.INITIATED.getCode();

case 210:
return BusinessOpenStatusEnum.CLOSED.getCode();

case 300:
return BusinessOpenStatusEnum.POLLING.getCode();

case 400:
return BusinessOpenStatusEnum.ACCIDENT.getCode();

case 500:
return BusinessOpenStatusEnum.ACCIDENT_RECOVERY.getCode();

default:
return BusinessOpenStatusEnum.UNKNOWN.getCode();
}
}
}