ヘッダーパーシングプログラム
プログラムの用途 | 実装するJavaインターフェース | 適用する設定画面 | 注意事項 |
---|---|---|---|
ルータープログラム | UnmarshalProcessor | Router Information > Processing Program ID | 電文をBXIが理解できるように変換する場合 |
ルータープログラム | MarshalProcessor | Router Information > Processing Program ID | BXIの内部電文を機関、またはチャネルに伝送する場合 |
共通部電文がJSON、FLD、XMLでない場合、または電文フォーマットが特殊な形式である場合、ヘッダーパーシングプログラムを開発して適用することができる。
開発方法
下記は、Nexacro端末で使用する電文のヘッダーをUnmarshalするプログラムの例である。 Nexacro端末の電文形式は、一般的なXMLとは異なるため、端末で提供するxapiを使用して電文をUnmarshalする必要がある。
<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns="http://www.nexacroplatform.com/platform/dataset">
<Parameters />
<Dataset id="_ds_cmmHeader">
<ColumnInfo>
<Column id="stdMsgLen" type="STRING" size="8" />
<Column id="stdMsgVer" type="STRING" size="3" />
<Column id="guid" type="STRING" size="32" />
<Column id="guidSeq" type="STRING" size="3" />
…
<Column id="sq1RpesDeptCd" type="STRING" size="4" />
</ColumnInfo>
<Rows>
<Row>
<Col id="stdMsgLen">123</Col>
<Col id="stdMsgVer">123</Col>
<Col id="guid">abcdefg123456789123113</Col>
<Col id="guidSeq">1</Col>
<Col id="fstGuid">hijklmn1234567321312312</Col>
<Col id="recpSysCd">CORE1</Col>
<Col id="recpTrnsCd">SVC0011</Col>
<Col id="rsltRecpTrnsCd"></Col>
<Col id="msgClssCd">S</Col>
<Col id="syncClssCd">1234567</Col>
…
</Row>
</Rows>
</Dataset>
<Dataset id="ds_root">
<ColumnInfo>
<Column id="nodeNm" type="STRING" size="64" />
<Column id="instanceNm" type="STRING" size="64" />
<Column id="instCd" type="STRING" size="16" />
…
</ColumnInfo>
<Rows>
<Row>
<Col id="nodeNm">test</Col>
<Col id="instanceNm">testnode04</Col>
<Col id="instCd">A200</Col>
…
</Row>
</Rows>
</Dataset>
</Root>
1. Unmarshalメソッド
@Override
public void unmarshal(ProcessorExchange exchange) throws Exception {
// Check input parameter
ExchangeMessage bxiMessage = exchange.getBxiMessage();
if (ObjectUtil.isEmpty(bxiMessage)) {
return;
}
}
ヘッダー電文をUnmarshalするメソッドである。 ProcessorExchangeオブジェクトには、電文をUnmarshalするために必要な情報が保存されている。
2. チャネル受信データ検証
// The message received from the Nexacro terminal is received via getMessage()
String message = bxiMessage.getMessage(String.class);
if (StringUtil.isEmpty(message)) {
ErrorLogger.errorLogging(bxiMessage, "BXIE02144");
throw new BxiException("BXIE02144");
}
BXIは、対外機関や端末で受信した電文を、ExchangeMessageのmessage
フィールドに保存する。
電文のヘッダー部Unmarshalは、電文全体が保存されたmessageでデータを参照してヘッダー部をUnmarshalすればよい。 受信された電文がない場合、ヘッダー部をUnmarshalできないため、電文データがあるかを検証する部分である。
3. チャネル電文ヘッダーレイアウト照会
/** Query header layout information of system where Nexacro terminal is defined.
* The header layout uses the information registered in the common header layout
* of the system-specific business information
*/
BxiIntrnlSysBizIO intrnlSysBizInfo = getHeader(CamelHeader.INTERNAL_SYS_BIZ_INFO,
BxiIntrnlSysBizIO.class);
// Query message layout
String headerLayout = intrnlSysBizInfo.getStdMsgHdrLayout();
BxiMsgLayoutMngIO msgTrnsfrmInfo = LayoutUtil.selectMessageManagement(headerLayout);
if (ObjectUtil.isEmpty(msgTrnsfrmInfo)) {
ErrorLogger.errorLogging(bxiMessage, "BXIE02113", headerLayout);
throw new BxiException("BXIE02113", headerLayout);
}
Map<String, BxiMsgLayoutIO> layoutMap = LayoutUtil.selectBxiMsgLayout(headerLayout);
電文のヘッダー部をUnmarshalするには、ヘッダーレイアウトを知っておく必要がある。
チャネルに対するヘッダーレイアウトは、FEPでは、Institutional Business Information
で管理し、MCIやEAIでは、System Business Information
で管理する。
上記のプログラムは、MCIが端末で受信されたヘッダー部をUnmarshalする部分で、システム別業務情報を照会し、システム別業務情報の共通ヘッダーレイアウトで電文情報レイアウトを照会したものである。
4. Nexacro端末で受信したデータ抽出
// Extract data received from Nexacro terminal
InputStream inStream = new ByteArrayInputStream(message.getBytes());
HttpPlatformRequest xrequest = new HttpPlatformRequest(inStream);
xrequest.receiveData();
// Extract XML data from Request for Nexacro
PlatformData xdata = xrequest.getData();
logger.debug("request input xml data = [{}]", xdata.saveXml());
チャネルから受信したデータは、Nexacro電文形式を使用する。 Nexacro電文形式のデータ抽出は、入力ストリームを作って使用するため、入力ストリームを作成する。
次に、Nexacro電文形式でPlatformデータを抽出する。
5. ヘッダー部電文Unmarshal
// Extract the header data from the extracted layout data
// and store it in Unmarshal and comHeader
Map<String, Object> header = new LinkedHashMap<String, Object>();
DataSet ds = xdata.getDataSet(FieldName.HEADER_DATASET_NAME); // "_ds_cmmHeader"
if (ds != null) {
// Nexacro header unmarshal
unmarshalHeader(ds, layoutMap, headerLayout, header);
} else {
ErrorLogger.errorLogging(bxiMessage, "BXIE02113", "nexacro");
throw new BxiException("BXIE02113", "nexacro");
}
if (ObjectUtil.isEmpty(header)) {
ErrorLogger.errorLogging(bxiMessage, "BXIE02113", headerLayout);
throw new BxiException("BXIE02113", headerLayout);
}
// Unmarshal data should be stored in comHeader.
bxiMessage.setComHeader(header);
前出のNexacro電文形式を見ると、Platformデータのヘッダー部は、_ds_cmmHeader
と定義されており、個別部はds_root
と定義されている。
このうち、ヘッダー部のデータを照会し、電文レイアウトに定義されたフィールド単位でデータを抽出してMap形式に変換する。
実質的な変換は、unmarshalHeader
メソッドを参考にする。
このように、変換したMap形式のヘッダー部は、次の処理のためにcomHeader
に保存する。
6. 電文情報保存
// Save layout information
XmlTypeInfo xmlInfo = LayoutUtil.makeXmlTypeInfo(msgTrnsfrmInfo, 0);
bxiMessage.setComHeaderMsgInfo(xmlInfo);
電文情報はBXIエンジンでインターフェースを識別するために、電文から必要データを抽出する必要がある。
通常はチャネル電文ヘッダーレイアウト照会で使用したように、システム別業務情報に登録されたレイアウトを照会して使用できるが、Customizingプログラムで他のレイアウトを使用することもできるため、使用した電文レイアウト情報を保存する必要がある。
Mapデータを「comHeader」に保存したので、電文レイアウト情報もヘッダー部領域である「comHeaderMsgInfo」に保存する。
7. 個別部の電文分離
// Originally, we had to separate the header message from the whole message.
// but Nexacro can not be detached, so you can save the entire message as Body Message
bxiMessage.setBodyMessage(message);
ヘッダー部をUnmarshalした後、電文からヘッダー部を分離し、残りの個別部だけをbodyMessageに保存して、次の処理である個別部Unmarshalを行う必要がある。
上記のように、処理する理由は、個別部をUnmarshalしない状態でヘッダー部と個別部を分離しないと、個別部を対内システムに伝送できないためである。
したがって、個別部をUnmarshalしない場合は、必ず電文からヘッダー部を分離し、個別部だけをbodyMessage
に保存する必要がある。
8. Nexacroヘッダー部の電文変換処理
/**
* The layout field data is a field name defined in the layout
* and is retrieved from the dataset and stored in the map.
* If you are in a Sub layout, create a Map for the Sub layout and unmarshal it in the same way.
*/
private void unmarshalHeader(DataSet ds, Map<String, BxiMsgLayoutIO> layoutMap,
String headerLayout, Map<String, Object> colData) {
if (ObjectUtil.isEmpty(layoutMap)) {
// Inquiry message layout details
layoutMap = LayoutUtil.selectBxiMsgLayout(headerLayout);
if (ObjectUtil.isEmpty(layoutMap)) {
ErrorLogger.errorLogging("BXIE02158", headerLayout);
throw new BxiException("BXIE02158", headerLayout);
}
}
for (Entry<String, BxiMsgLayoutIO> entry : layoutMap.entrySet()) {
BxiMsgLayoutIO layout = entry.getValue();
JavaTypeEnum type = JavaTypeEnum.getByCode(layout.getFldTypeCd());
if (type == JavaTypeEnum.OMM) {
Map<String, Object> sub = new LinkedHashMap<String, Object>();
unmarshalHeader(ds, null, layout.getFldFormat(), sub);
colData.put(layout.getFldNm(), sub);
} else {
colData.put(layout.getFldNm(), ds.getObject(0, layout.getFldNm()));
}
}
}
Nexacro電文を、レイアウトに定義されたフィールドごとにMapに変換する部分である。
レイアウトに定義されたフィールド名でDataSetでデータを照会し、フィールド名でMapに保存する。 レイアウト内にサブレイアウトがある場合は、サブレイアウトも同じ方同じ方式で変換する。
全体例
ヘッダー部の電文Unmarshalプログラム
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.nexacro17.xapi.data.DataSet;
import com.nexacro17.xapi.data.PlatformData;
import com.nexacro17.xapi.tx.HttpPlatformRequest;
import bxi.api.impl.UnmarshalProcessor;
import bxi.common.constant.CamelHeader;
import bxi.common.context.ErrorLogger;
import bxi.common.dao.dto.BxiIntrnlSysBizIO;
import bxi.common.dao.dto.BxiMsgLayoutIO;
import bxi.common.dao.dto.BxiMsgLayoutMngIO;
import bxi.common.enums.JavaTypeEnum;
import bxi.common.exception.BxiException;
import bxi.common.model.ExchangeMessage;
import bxi.common.model.XmlTypeInfo;
import bxi.common.utility.ObjectUtil;
import bxi.common.utility.StringUtil;
import bxi.extension.customizing.constant.FieldName;
import bxi.parser.base.LayoutUtil;
@Component
public class NexacroHeaderUnmarshalProcessor extends UnmarshalProcessor {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void unmarshal(ExchangeMessage bxiMessage) throws Exception {
// Check input parameter
if (ObjectUtil.isEmpty(bxiMessage)) {
return;
}
logger.debug("Input getBody : {}", bxiMessage);
// The message received from the Nexacro terminal is received via getMessage()
String message = bxiMessage.getMessage(String.class);
if (StringUtil.isEmpty(message)) {
ErrorLogger.errorLogging(bxiMessage, "BXIE02144");
throw new BxiException("BXIE02144");
}
logger.debug("message : {}", message);
/** Query header layout information of system where Nexacro terminal is defined.
* The header layout uses the information registered in the common header layout
* of the system-specific business information
*/
BxiIntrnlSysBizIO intrnlSysBizInfo = getHeader(CamelHeader.INTERNAL_SYS_BIZ_INFO,
BxiIntrnlSysBizIO.class);
// Query message layout
String headerLayout = intrnlSysBizInfo.getStdMsgHdrLayout();
BxiMsgLayoutMngIO msgTrnsfrmInfo = LayoutUtil.selectMessageManagement(headerLayout);
if (ObjectUtil.isEmpty(msgTrnsfrmInfo)) {
ErrorLogger.errorLogging(bxiMessage, "BXIE02113", headerLayout);
throw new BxiException("BXIE02113", headerLayout);
}
Map<String, BxiMsgLayoutIO> layoutMap = LayoutUtil.selectBxiMsgLayout(headerLayout);
// Extract data received from Nexacro terminal
InputStream inStream = new ByteArrayInputStream(message.getBytes());
HttpPlatformRequest xrequest = new HttpPlatformRequest(inStream);
xrequest.receiveData();
// Extract XML data from Request for Nexacro
PlatformData xdata = xrequest.getData();
logger.debug("request input xml data = [{}]", xdata.saveXml());
// Extract the header data from the extracted layout data
// and store it in Unmarshal and comHeader
Map<String, Object> header = new LinkedHashMap<String, Object>();
DataSet ds = xdata.getDataSet(FieldName.HEADER_DATASET_NAME);
if (ds != null) {
// Nexacro header unmarshal
unmarshalHeader(ds, layoutMap, headerLayout, header);
} else {
ErrorLogger.errorLogging(bxiMessage, "BXIE02113", "nexacro");
throw new BxiException("BXIE02113", "nexacro");
}
if (ObjectUtil.isEmpty(header)) {
ErrorLogger.errorLogging(bxiMessage, "BXIE02113", headerLayout);
throw new BxiException("BXIE02113", headerLayout);
}
bxiMessage.setComHeader(header);
logger.debug("header : {}", header);
// Save layout information
XmlTypeInfo xmlInfo = LayoutUtil.makeXmlTypeInfo(msgTrnsfrmInfo, 0);
bxiMessage.setComHeaderMsgInfo(xmlInfo);
// Originally, we had to separate the header message from the whole message.
// but Nexacro can not be detached, so you can save the entire message as Body Message
bxiMessage.setBodyMessage(message);
}
/**
* Nexacro header unmarshal
*
* The layout field data is a field name defined in the layout
* and is retrieved from the dataset and stored in the map.
* If you are in a Sub layout, create a Map for the Sub layout and unmarshal it in the same way.
*
* @param ds
* @param layoutMap
* @param headerLayout
* @param colData
*/
private void unmarshalHeader(DataSet ds, Map<String, BxiMsgLayoutIO> layoutMap,
String headerLayout, Map<String, Object> colData) {
if (ObjectUtil.isEmpty(layoutMap)) {
// Inquiry message layout details
layoutMap = LayoutUtil.selectBxiMsgLayout(headerLayout);
if (ObjectUtil.isEmpty(layoutMap)) {
ErrorLogger.errorLogging("BXIE02158", headerLayout);
throw new BxiException("BXIE02158", headerLayout);
}
}
for (Entry<String, BxiMsgLayoutIO> entry : layoutMap.entrySet()) {
BxiMsgLayoutIO layout = entry.getValue();
JavaTypeEnum type = JavaTypeEnum.getByCode(layout.getFldTypeCd());
if (type == JavaTypeEnum.OMM) {
Map<String, Object> sub = new LinkedHashMap<String, Object>();
unmarshalHeader(ds, null, layout.getFldFormat(), sub);
colData.put(layout.getFldNm(), sub);
} else {
colData.put(layout.getFldNm(), ds.getObject(0, layout.getFldNm()));
}
}
}
}
電文形式が異なる場合の個別部の電文Unmarshalプログラム
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.nexacro17.xapi.data.DataSet;
import com.nexacro17.xapi.data.PlatformData;
import com.nexacro17.xapi.tx.HttpPlatformRequest;
import com.nexacro17.xapi.tx.PlatformException;
import bxi.api.impl.UnmarshalProcessor;
import bxi.common.constant.CamelHeader;
import bxi.common.context.ErrorLogger;
import bxi.common.dao.dto.BxiMsgLayoutIO;
import bxi.common.dao.dto.BxiMsgLayoutMngIO;
import bxi.common.dao.dto.BxiOnlineIntrfcIO;
import bxi.common.enums.JavaTypeEnum;
import bxi.common.enums.RequestResponseKindEnum;
import bxi.common.exception.BxiException;
import bxi.common.model.ExchangeMessage;
import bxi.common.model.XmlTypeInfo;
import bxi.common.utility.ObjectUtil;
import bxi.common.utility.StringUtil;
import bxi.extension.customizing.constant.FieldName;
import bxi.parser.base.LayoutUtil;
@Component
public class NexacroBodyUnmarshalProcessor extends UnmarshalProcessor {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void unmarshal(ExchangeMessage bxiMessage) throws Exception {
// Check input parameter
if (ObjectUtil.isEmpty(bxiMessage)) {
return;
}
logger.debug("Input getBody : {}", bxiMessage);
// The message received from the Nexacro terminal is received via getMessage()
String message = bxiMessage.getMessage(String.class);
if (StringUtil.isEmpty(message)) {
ErrorLogger.errorLogging(bxiMessage, "BXIE02144");
throw new BxiException("BXIE02144");
}
logger.debug("message : {}", message);
// Do not marshall the body unless transaction specific information is registered.
BxiOnlineIntrfcIO onlIntrfcInfo = getHeader(CamelHeader.ONLINE_INTERFACE_INFO,
BxiOnlineIntrfcIO.class);
String msgBodyLayout = bodyMsgLayout(onlIntrfcInfo, bxiMessage.getRqstRspsDscd());
if (StringUtil.isEmpty(msgBodyLayout)) {
return;
}
// Body message unmarshal
if (unmarshalBody(bxiMessage, msgBodyLayout)) {
throw new BxiException("BXIE02109");
}
}
/**
* Body message unmarshal
*
* @param bxiMessage
* @param msgBodyLayout
* @return
* @throws Exception
*/
private boolean unmarshalBody(ExchangeMessage bxiMessage, String msgBodyLayout)
throws Exception {
logger.debug("msgBodyLayout : {}", msgBodyLayout);
// Inquiry message layout
BxiMsgLayoutMngIO msgTrnsfrmInfo = LayoutUtil.selectMessageManagement(msgBodyLayout);
if (ObjectUtil.isEmpty(msgTrnsfrmInfo)) {
ErrorLogger.errorLogging(bxiMessage, "BXIE02109", msgBodyLayout);
return true;
}
Map<String, BxiMsgLayoutIO> layoutMap = LayoutUtil.selectBxiMsgLayout(msgBodyLayout);
// Extract data received from Nexacro terminal
PlatformData xdata = getNexacroXmlData(bxiMessage);
// Extract individual data from the extracted layout data
// and store it in body by Unmarshal
Map<String, Object> body = new LinkedHashMap<String, Object>();
setNexacroXmlToMap(body, layoutMap, xdata);
bxiMessage.setBody(body);
logger.debug("InternalBody : {}", body);
// Save layout information
XmlTypeInfo xmlInfo = LayoutUtil.makeXmlTypeInfo(msgTrnsfrmInfo, 0);
bxiMessage.setBodyMsgInfo(xmlInfo);
return false;
}
/**
* Extract data received from Nexacro terminal
*
* @param bxiMessage
* @return PltformData
* @throws PlatformException
* @throws UnsupportedEncodingException
*/
private PlatformData getNexacroXmlData(ExchangeMessage bxiMessage)
throws PlatformException, UnsupportedEncodingException {
// Request Extraction for Nexacro
byte[] byteMessage = ((String) bxiMessage.getMessage()).getBytes();
InputStream inStream = new ByteArrayInputStream(byteMessage);
HttpPlatformRequest xrequest = new HttpPlatformRequest(inStream);
xrequest.receiveData();
// Extract XML data from Request for Nexacro
logger.debug("request body input xml data = [{}]", xrequest.getData().saveXml());
return xrequest.getData();
}
/**
* Change Nexacro Xml data to Map
*
* @param body
* @param layoutMap
* @param xdata
*/
private void setNexacroXmlToMap(Map<String, Object> body, Map<String, BxiMsgLayoutIO> layoutMap,
PlatformData xdata) {
// All fields in the top-level layout are passed to the Root DataSet
DataSet dsRoot = xdata.getDataSet(FieldName.ROOT_DATASET_NAME);
// Parses Nexacro Xml data to Map to a defined layout
for (Entry<String, BxiMsgLayoutIO> entry : layoutMap.entrySet()) {
BxiMsgLayoutIO layout = entry.getValue();
JavaTypeEnum type = JavaTypeEnum.getByCode(layout.getFldTypeCd());
// List
if (!StringUtil.isEmpty(layout.getArrayRefNm())) {
List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
DataSet dsTemp = xdata.getDataSet(layout.getFldNm());
if (!ObjectUtil.isEmpty(dsTemp)) {
for (int i = 0; i < dsTemp.getRowCount(); i++) {
Map<String, Object> row = new LinkedHashMap<String, Object>();
unmarshalNexacro(i, dsTemp, null, layout.getFldFormat(), row);
listMap.add(row);
}
body.put(layout.getFldNm(), listMap);
}
}
// OMM
else if (type == JavaTypeEnum.OMM) {
DataSet dsTemp = xdata.getDataSet(layout.getFldNm());
if (!ObjectUtil.isEmpty(dsTemp)) {
Map<String, Object> sub = new LinkedHashMap<String, Object>();
unmarshalNexacro(0, dsTemp, null, layout.getFldFormat(), sub);
body.put(layout.getFldNm(), sub);
}
}
// Field
else {
body.put(layout.getFldNm(), dsRoot.getObject(0, layout.getFldNm()));
}
}
}
/**
* Nexacro bidy unmarshal
*
* @param ds
* @param layoutMap
* @param colData
*/
private void unmarshalNexacro(int crow, DataSet ds, Map<String, BxiMsgLayoutIO> layoutMap,
String msgBodyLayout, Map<String, Object> colData) {
if (ObjectUtil.isEmpty(layoutMap)) {
// Inquiry message layout details
layoutMap = LayoutUtil.selectBxiMsgLayout(msgBodyLayout);
if (ObjectUtil.isEmpty(layoutMap)) {
ErrorLogger.errorLogging("BXIE02158", msgBodyLayout);
throw new BxiException("BXIE02158", msgBodyLayout);
}
}
for (Entry<String, BxiMsgLayoutIO> entry : layoutMap.entrySet()) {
BxiMsgLayoutIO layout = entry.getValue();
JavaTypeEnum type = JavaTypeEnum.getByCode(layout.getFldTypeCd());
if (type == JavaTypeEnum.OMM) {
Map<String, Object> sub = new LinkedHashMap<String, Object>();
unmarshalNexacro(crow, ds, null, layout.getFldFormat(), sub);
colData.put(layout.getFldNm(), sub);
} else {
colData.put(layout.getFldNm(), ds.getObject(crow, layout.getFldNm()));
}
}
}
/**
* Body DtoName Lookup
*
* @param onlIntrfcInfo
* @param rqstRspsDscd
*/
private String bodyMsgLayout(BxiOnlineIntrfcIO onlIntrfcInfo, String rqstRspsDscd) {
if (StringUtil.isEmpty(rqstRspsDscd)) {
return null;
}
RequestResponseKindEnum rqstRsps = RequestResponseKindEnum.getByCode(rqstRspsDscd);
if (rqstRsps == RequestResponseKindEnum.REQUEST) {
return onlIntrfcInfo.getRqstMsgLayout();
} else {
return onlIntrfcInfo.getRspsMsgLayout();
}
}
}
電文構造が異なる場合の個別部の電文Unmarshalプログラム
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import bxi.api.impl.UnmarshalProcessor;
import bxi.common.constant.CamelHeader;
import bxi.common.constant.Constant;
import bxi.common.context.ErrorLogger;
import bxi.common.dao.dto.BxiIntrnlSysBizIO;
import bxi.common.dao.dto.BxiMsgLayoutMngIO;
import bxi.common.dao.dto.BxiOnlineIntrfcIO;
import bxi.common.enums.RequestResponseKindEnum;
import bxi.common.exception.BxiException;
import bxi.common.model.ExchangeMessage;
import bxi.common.model.XmlTypeInfo;
import bxi.common.utility.ObjectUtil;
import bxi.common.utility.StringUtil;
import bxi.extension.customizing.constant.FieldName;
import bxi.parser.Unmarshaller;
import bxi.parser.base.LayoutUtil;
@Component
public class BcMciBodyUnmarshalProcessor extends UnmarshalProcessor {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* Body Message Parsing Processing
*/
@Override
public void unmarshal(ExchangeMessage bxiMessage) throws Exception {
// Check input parameter
if (ObjectUtil.isEmpty(bxiMessage)) {
return;
}
logger.debug("Input getBody : {}", bxiMessage);
// Verification of individual part except header part
if (ObjectUtil.isEmpty(bxiMessage.getBodyMessage())) {
logger.debug("BodyMessage is Null Or Space");
return;
}
// Online interface information inquiry
BxiOnlineIntrfcIO onlIntrfcInfo = getHeader(CamelHeader.ONLINE_INTERFACE_INFO,
BxiOnlineIntrfcIO.class);
// Unmarshal the message part only for the response
RequestResponseKindEnum rqstRsps = RequestResponseKindEnum.getByCode(
bxiMessage.getRqstRspsDscd());
if (rqstRsps == RequestResponseKindEnum.RESPONSE) {
// Message part unmarshal
BxiIntrnlSysBizIO intrnlSysBizInfo = getHeader(CamelHeader.INTERNAL_SYS_BIZ_INFO,
BxiIntrnlSysBizIO.class);
unmarshalResponseMessage(intrnlSysBizInfo, bxiMessage);
}
// Individual layout inquiry
String msgBodyLayout = bodyMsgLayout(onlIntrfcInfo, bxiMessage.getRqstRspsDscd());
if (StringUtil.isEmpty(msgBodyLayout)) {
return;
}
// Body message unmarshal
if (unmarshalBody(bxiMessage, msgBodyLayout)) {
throw new BxiException("BXIE02109");
}
}
/**
* Message part unmarshal
*
* @param intrnlSysBizInfo
* @param bxiMessage
* @return
* @throws Exception
*/
private Map<String, Object> unmarshalResponseMessage(BxiIntrnlSysBizIO intrnlSysBizInfo,
ExchangeMessage bxiMessage) throws Exception {
// Unmarshal message part
Map<String, Object> messageMap = Unmarshaller.unmarshal(intrnlSysBizInfo.getChlMsgTypeCd(),
FieldName.MESSAGE_LAYOUT_NAME, bxiMessage.getBodyMessage(),
intrnlSysBizInfo.getMsgCharSetCd(), false, null);
logger.debug("messageMap: {}", messageMap);
// Returns if there is no message part data
if (ObjectUtil.isEmpty(messageMap)) {
return null;
}
int length = (int) messageMap.get(Constant.MESSAGE_LENGTH_NAME);
messageMap.remove(Constant.MESSAGE_LENGTH_NAME);
bxiMessage.setErrMessage(messageMap);
// Save layout information
BxiMsgLayoutMngIO msgTrnsfrmInfo = LayoutUtil.selectMessageManagement(
FieldName.ADD_MESSAGE_LAYOUT_NAME);
XmlTypeInfo xmlInfo = LayoutUtil.makeXmlTypeInfo(msgTrnsfrmInfo, length);
bxiMessage.setErrMsgInfo(xmlInfo);
return messageMap;
}
/**
* Body message unmarshal
*
* @param bxiMessage
* @param msgBodyLayout
* @return
*/
private boolean unmarshalBody(ExchangeMessage bxiMessage, String msgBodyLayout) {
// System business information
BxiIntrnlSysBizIO intrnlSysBizInfo = getHeader(CamelHeader.INTERNAL_SYS_BIZ_INFO,
BxiIntrnlSysBizIO.class);
if (logger.isDebugEnabled()) {
logger.debug("messageType : {}", intrnlSysBizInfo.getChlMsgTypeCd());
logger.debug("msgBodyLayout : {}", msgBodyLayout);
logger.debug("bodyMessage : {}", bxiMessage.getBodyMessage());
}
// Query layout information
BxiMsgLayoutMngIO msgTrnsfrmInfo = LayoutUtil.selectMessageManagement(msgBodyLayout);
if (ObjectUtil.isEmpty(msgTrnsfrmInfo)) {
ErrorLogger.errorLogging(bxiMessage, "BXIE02109", msgBodyLayout);
return true;
}
// Unmarshal
Map<String, Object> body = Unmarshaller.unmarshal(intrnlSysBizInfo.getChlMsgTypeCd(),
msgBodyLayout, bxiMessage.getBodyMessage(), intrnlSysBizInfo.getMsgCharSetCd(),
false, null);
if (ObjectUtil.isEmpty(body)) {
ErrorLogger.errorLogging(bxiMessage, "BXIE02109", msgBodyLayout);
return true;
}
int length = (int) body.get(Constant.MESSAGE_LENGTH_NAME);
body.remove(Constant.MESSAGE_LENGTH_NAME);
// Save layout information
XmlTypeInfo xmlInfo = LayoutUtil.makeXmlTypeInfo(msgTrnsfrmInfo, length);
bxiMessage.setBodyMsgInfo(xmlInfo);
logger.debug("InternalBody : {}", body);
bxiMessage.setBodyMessage(null);
bxiMessage.setBody(body);
return false;
}
/**
* Body DtoName Lookup
*
* @param onlIntrfcInfo
* @param rqstRspsDscd
*/
private String bodyMsgLayout(BxiOnlineIntrfcIO onlIntrfcInfo, String rqstRspsDscd) {
if (StringUtil.isEmpty(rqstRspsDscd)) {
return null;
}
RequestResponseKindEnum rqstRsps = RequestResponseKindEnum.getByCode(rqstRspsDscd);
if (rqstRsps == RequestResponseKindEnum.REQUEST) {
return onlIntrfcInfo.getRqstMsgLayout();
} else {
return onlIntrfcInfo.getRspsMsgLayout();
}
}
}
電文Marshalプログラム
import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.nexacro17.xapi.data.DataSet;
import com.nexacro17.xapi.data.DataTypes;
import com.nexacro17.xapi.data.PlatformData;
import com.nexacro17.xapi.data.VariableList;
import com.nexacro17.xapi.tx.PlatformResponse;
import bxi.api.impl.MarshalProcessor;
import bxi.common.constant.CamelHeader;
import bxi.common.context.ErrorLogger;
import bxi.common.dao.dto.BxiIntrnlSysBizIO;
import bxi.common.dao.dto.BxiMsgLayoutIO;
import bxi.common.dao.dto.BxiOnlineIntrfcIO;
import bxi.common.enums.JavaTypeEnum;
import bxi.common.exception.BxiException;
import bxi.common.model.ExchangeMessage;
import bxi.common.utility.CharsetUtil;
import bxi.common.utility.ObjectUtil;
import bxi.common.utility.StringUtil;
import bxi.extension.customizing.constant.FieldName;
import bxi.online.common.DaoProcess;
import bxi.parser.base.LayoutUtil;
@Component
public class NexacroMarshalProcessor extends MarshalProcessor {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/** DaoProcess */
@Autowired
private DaoProcess daoProcess;
@Override
public void marshal(ExchangeMessage bxiMessage) throws Exception {
// Check input parameter
if (ObjectUtil.isEmpty(bxiMessage)) {
return;
}
logger.debug("Input getBody : {}", bxiMessage);
// System business information inquiry
BxiIntrnlSysBizIO intrnlSysBizInfo = internalSystemBizInfo(bxiMessage);
// Preparing to generate Nexacro Xml data
DataSet headerDS = new DataSet(FieldName.HEADER_DATASET_NAME);
PlatformData xdata = new PlatformData();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
PlatformResponse xresponse = new PlatformResponse(outStream);
// Convert header part to Nexacro layout format
marshalNexacroHeader(bxiMessage, intrnlSysBizInfo.getStdMsgHdrLayout(), headerDS, xdata);
xdata.addDataSet(headerDS);
// Convert message part to Nexacro layout format if message part exists
if (!ObjectUtil.isEmpty(bxiMessage.getErrMessage())) {
marshalNexacroMessage(bxiMessage.getComHeader(), bxiMessage.getErrMessage(), xdata);
}
// Convert individual parts to Nexacro layout format if separate parts exist
if (!ObjectUtil.isEmpty(bxiMessage.getBody())) {
BxiOnlineIntrfcIO onlIntrfcInfo = getHeader(CamelHeader.ONLINE_INTERFACE_INFO,
BxiOnlineIntrfcIO.class);
marshalNexacroBody(bxiMessage.getBody(), onlIntrfcInfo.getRspsMsgLayout(), xdata);
}
logger.debug("NexacroMarshal result : {}", xdata.saveXml());
// Save Nexacro Response Data
xresponse.setData(xdata);
xresponse.sendData();
logger.debug("Send Message : {}", outStream.toString());
// Setting Nexacro Response Data in BXI
bxiMessage.setMessage(outStream.toString().getBytes(CharsetUtil.DEFAULT_CHARSET));
}
/**
* Convert header part to Nexacro layout format
*
* @param bxiMessage
* @param headerLayout
* @param headerDS
* @param xdata
*/
private void marshalNexacroHeader(ExchangeMessage bxiMessage, String headerLayout,
DataSet headerDS, PlatformData xdata) {
// Query header layout information
Map<String, BxiMsgLayoutIO> layoutMap = LayoutUtil.selectBxiMsgLayout(headerLayout);
// Header data
Map<String, Object> mapHeader = bxiMessage.getComHeader();
// Generate Nexacro DataSet Column data for a defined layout layout
for (Entry<String, BxiMsgLayoutIO> entry : layoutMap.entrySet()) {
BxiMsgLayoutIO layout = entry.getValue();
int xformType = convertTypeDescriptor(layout.getFldTypeCd());
headerDS.addColumn(layout.getFldNm(), xformType, layout.getFldLen());
}
// Generate Nexacro DataSet Row data for a defined layout layout
int rowNumHeader = headerDS.newRow();
for (Entry<String, BxiMsgLayoutIO> entry : layoutMap.entrySet()) {
BxiMsgLayoutIO layout = entry.getValue();
int xformType = convertTypeDescriptor(layout.getFldTypeCd());
if (xformType == DataTypes.UNDEFINED) {
continue;
}
headerDS.set(rowNumHeader, layout.getFldNm(), mapHeader.get(layout.getFldNm()));
}
}
/**
* Convert message part to Nexacro layout format
*
* @param headerMap
* @param messageMap
* @param xdata
*/
private void marshalNexacroMessage(Map<String, Object> headerMap, Map<String, Object> messageMap,
PlatformData xdata) {
// Query message layout information
Map<String, BxiMsgLayoutIO> msgLayoutMap = LayoutUtil.selectBxiMsgLayout(
FieldName.MESSAGE_LAYOUT_NAME);
// Query message detail layout information
Map<String, BxiMsgLayoutIO> msgDetailLayoutMap = LayoutUtil.selectBxiMsgLayout(
FieldName.ADD_MESSAGE_LAYOUT_NAME);
DataSet dsMsg = new DataSet(FieldName.MESSAGE_DATASET_NAME);
addColumnMessageDataSet(dsMsg, msgLayoutMap, msgDetailLayoutMap, messageMap);
@SuppressWarnings("unchecked")
List<Map<String, Object>> list = (List<Map<String, Object>>) messageMap.get(
FieldName.ADD_MESSAGE_FIELD_NAME);
for (Map<String, Object> map : list) {
int rowNum = dsMsg.newRow();
for (Entry<String, BxiMsgLayoutIO> entryDetail : msgDetailLayoutMap.entrySet()) {
BxiMsgLayoutIO layoutDetail = entryDetail.getValue();
dsMsg.set(rowNum, layoutDetail.getFldNm(), map.get(layoutDetail.getFldNm()));
}
}
xdata.addDataSet(dsMsg);
// Insert ErrorCode value -1 in Nexacro Parameter if error response
// 1: System error, 2: Business error, 3: DB error
if ("1".equals(headerMap.get(FieldName.RESPONSE_DIVISION_CODE))
|| "2".equals(headerMap.get(FieldName.RESPONSE_DIVISION_CODE))
|| "3".equals(headerMap.get(FieldName.RESPONSE_DIVISION_CODE))) {
VariableList varList = xdata.getVariableList();
varList.add(FieldName.NEXACRO_ERR_CD, -1);
varList.add(FieldName.NEXACRO_ERR_MSG, dsMsg.saveXml());
}
}
/**
* Convert individual part to Nexacro layout format
*
* @param bodyMap
* @param msgBodyLayout
* @param xdata
*/
@SuppressWarnings("unchecked")
private void marshalNexacroBody(Map<String, Object> bodyMap, String msgBodyLayout,
PlatformData xdata) {
// Query individual layout information
Map<String, BxiMsgLayoutIO> bodyLayoutMap = LayoutUtil.selectBxiMsgLayout(msgBodyLayout);
DataSet dsRoot = new DataSet(FieldName.ROOT_DATASET_NAME);
addColumnDataSet(dsRoot, bodyLayoutMap, null);
int rootRowNum = dsRoot.newRow();
List<Map<String, Object>> list = null;
for (Entry<String, BxiMsgLayoutIO> entry : bodyLayoutMap.entrySet()) {
BxiMsgLayoutIO layout = entry.getValue();
JavaTypeEnum type = JavaTypeEnum.getByCode(layout.getFldTypeCd());
// List
if (!StringUtil.isEmpty(layout.getArrayRefNm())) {
DataSet dsTemp = new DataSet(layout.getFldNm());
addColumnDataSet(dsTemp, null, layout.getFldFormat());
list = (List<Map<String, Object>>) bodyMap.get(layout.getFldNm());
if (list != null) {
for (Map<String, Object> map : list) {
int rowNum = dsTemp.newRow();
addRowDataSet(rowNum, dsTemp, layout.getFldFormat(), map);
}
}
xdata.addDataSet(dsTemp);
}
// OMM
else if (type == JavaTypeEnum.OMM) {
Map<String, Object> sub = (Map<String, Object>) bodyMap.get(layout.getFldNm());
DataSet dsTemp = new DataSet(layout.getFldNm());
addColumnDataSet(dsTemp, null, layout.getFldFormat());
int rowNum = dsTemp.newRow();
addRowDataSet(rowNum, dsTemp, layout.getFldFormat(), sub);
xdata.addDataSet(dsTemp);
}
// Field
else {
dsRoot.set(rootRowNum, layout.getFldNm(), bodyMap.get(layout.getFldNm()));
}
}
logger.debug("NexacroMarshal result : {}", xdata.saveXml());
xdata.addDataSet(dsRoot);
}
/**
* Generate column information of message part DataSet
*
* @param dsTemp
* @param layoutMap
* @param layoutDetailMap
* @param messageMap
*/
private void addColumnMessageDataSet(DataSet dsTemp, Map<String, BxiMsgLayoutIO> layoutMap,
Map<String, BxiMsgLayoutIO> layoutDetailMap, Map<String, Object> messageMap) {
for (Entry<String, BxiMsgLayoutIO> entry : layoutMap.entrySet()) {
BxiMsgLayoutIO layout = entry.getValue();
if (!StringUtil.isEmpty(layout.getArrayRefNm())) {
for (Entry<String, BxiMsgLayoutIO> detailEntry : layoutDetailMap.entrySet()) {
BxiMsgLayoutIO layoutDetail = detailEntry.getValue();
int xformType = convertTypeDescriptor(layoutDetail.getFldTypeCd());
if (xformType == DataTypes.UNDEFINED) {
continue;
}
dsTemp.addColumn(layoutDetail.getFldNm(), xformType, layoutDetail.getFldLen());
}
} else {
dsTemp.addConstantColumn(layout.getFldNm(), messageMap.get(layout.getFldNm()));
}
}
}
/**
* Generate column information of individual part DataSet
*
* @param dsTemp
* @param layoutMap
* @param msgBodyLayout
*/
private void addColumnDataSet(DataSet dsTemp, Map<String, BxiMsgLayoutIO> layoutMap,
String msgBodyLayout) {
if (layoutMap == null) {
// Query message detail layout information
layoutMap = LayoutUtil.selectBxiMsgLayout(msgBodyLayout);
}
for (Entry<String, BxiMsgLayoutIO> entry : layoutMap.entrySet()) {
BxiMsgLayoutIO layout = entry.getValue();
int xformType = convertTypeDescriptor(layout.getFldTypeCd());
if (xformType == DataTypes.UNDEFINED) {
continue;
}
dsTemp.addColumn(layout.getFldNm(), xformType, layout.getFldLen());
}
}
/**
* Generate Row information of individual part DataSet
*
* @param rowNum
* @param dsTemp
* @param msgBodyLayout
* @param sub
*/
private void addRowDataSet(int rowNum, DataSet dsTemp, String msgBodyLayout,
Map<String, Object> sub) {
// Query message detail layout information
Map<String, BxiMsgLayoutIO> layoutMap = LayoutUtil.selectBxiMsgLayout(msgBodyLayout);
for (Entry<String, BxiMsgLayoutIO> entry : layoutMap.entrySet()) {
BxiMsgLayoutIO layout = entry.getValue();
dsTemp.set(rowNum, layout.getFldNm(), sub.get(layout.getFldNm()));
}
}
/**
* Extracting the field type for the DataSet
*
* @param type
* @return
*/
private int convertTypeDescriptor(String type) {
if (type.toUpperCase().equals("STRING")) {
return DataTypes.STRING;
} else if (type.toUpperCase().equals("BOOLEAN")) {
return DataTypes.BOOLEAN;
} else if (type.toUpperCase().equals("DOUBLE")) {
return DataTypes.DOUBLE;
} else if (type.toUpperCase().equals("FLOAT")) {
return DataTypes.FLOAT;
} else if (type.toUpperCase().equals("INTEGER")) {
return DataTypes.INT;
} else if (type.toUpperCase().equals("LONG")) {
return DataTypes.LONG;
} else if (type.toUpperCase().equals("DATE")) {
return DataTypes.DATE_TIME;
} else if (type.toUpperCase().equals("BIGDECIMAL")) {
return DataTypes.BIG_DECIMAL;
} else {
return DataTypes.UNDEFINED;
}
}
/**
* System business information inquiry
*
* @param bxiMessage
* @return
*/
private BxiIntrnlSysBizIO internalSystemBizInfo(ExchangeMessage bxiMessage) {
BxiIntrnlSysBizIO intrnlSysBizInfo = null;
String sysId = null;
if (bxiMessage.isErrorResponseFlag()) {
intrnlSysBizInfo = getHeader(CamelHeader.INTERNAL_SYS_BIZ_INFO,
BxiIntrnlSysBizIO.class);
sysId = bxiMessage.getSysId();
} else {
intrnlSysBizInfo = getHeader(CamelHeader.SEND_SYS_BIZ_INFO,
BxiIntrnlSysBizIO.class);
sysId = bxiMessage.getSendSysId();
}
if (!ObjectUtil.isEmpty(intrnlSysBizInfo)) {
return intrnlSysBizInfo;
}
intrnlSysBizInfo = daoProcess.selectInternalSystemBizInfo(bxiMessage, sysId,
bxiMessage.getBizCd());
if (ObjectUtil.isEmpty(intrnlSysBizInfo)) {
ErrorLogger.errorLogging(bxiMessage, "BXIE02025",
bxiMessage.getSendSysId(), bxiMessage.getBizCd());
throw new BxiException("BXIE02025",
bxiMessage.getSendSysId(), bxiMessage.getBizCd());
}
if (bxiMessage.isErrorResponseFlag()) {
setHeader(CamelHeader.INTERNAL_SYS_BIZ_INFO, intrnlSysBizInfo);
} else {
setHeader(CamelHeader.SEND_SYS_BIZ_INFO, intrnlSysBizInfo);
}
return intrnlSysBizInfo;
}
}