라우터 프로그램

프로그램용도 구현할 인터페이스

라우터 처리 프로그램

Processor

라우터 프로그램

AbstractRouter

기본 라우터 외에 신규 라우터를 추가하거나, 기존 라우터의 처리 프로그램을 변경하고자 할 때 사용한다.

  • 기존 라우터의 처리 프로그램만 변경: 라우터 처리 프로그램만 개발 필요

  • 신규 라우터 추가: 라우터 처리 프로그램라우터 프로그램을 함께 개발 필요

1. 라우터 처리 프로그램

1.1. 개발

org.apache.camel.Processor를 구현한다.

package bxi.extension.sample;

import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import bxi.common.model.BxiMessage;

@Component
public class SampleProcessor implements Processor {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void process(Exchange exchange) {
        Message in = exchange.getIn();
        BxiMessage bxiMessage = in.getBody(BxiMessage.class);

        logger.debug("========================================================");
        logger.debug("message: {}", bxiMessage.getMessage());
        logger.debug("standard header: {}", bxiMessage.getStdHeader());
        logger.debug("body: {}", bxiMessage.getBody());
        logger.debug("========================================================");
    }
}

1.2. 배포

1.2.1. 프로그램 배포

서버의 경로에 class 파일을 업로드하고, 기본설정관리 > 프로그램정보 화면에서 작성한 프로그램을 등록 및 배포한다.

router processor program1

기존 라우터의 처리 프로그램만 변경하는 경우 아래와 같이 프로그램을 변경한다. 신규 라우터를 추가하는 경우 라우터 프로그램을 참조한다.

1.2.2. 라우터 처리 프로그램 변경

router processor program2

2. 라우터 프로그램

bxi.online.router.direct.AbstractRouter를 구현한다.

2.1. 개발

package bxi.extension.sample;

import bxi.online.router.direct.AbstractRouter;

public class SampleRouter extends AbstractRouter {

    public SampleRouter(String beanName) {
        super(beanName);
    }
}

2.2. 배포

2.2.1. 라우터 등록

router program1

플로우관리 > 라우터정보 화면에서 개발한 라우터를 등록한다.

라우터 프로그램은 기본설정관리 > 프로그램정보 화면에는 등록하지 않으며, 동적반영도 불가하다. 따라서 배포 시 class를 플로우관리 > 라우터정보 화면에서 정의한 라우터클래스명 위치에 맞게 직접 업로드해야 한다.

2.2.2. 플로우 추가

router program2

등록한 라우터를 실제로 사용하고자 하는 플로우에 추가한다.

3. 전체 예제

3.1. 헤더부 전문 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.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.BxiMessage;
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 implements Processor {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void process(Exchange exchange) {
        Message in = exchange.getIn();
        BxiMessage bxiMessage = in.getBody(BxiMessage.class);

        // 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<>();
                unmarshalHeader(ds, null, layout.getFldFormat(), sub);
                colData.put(layout.getFldNm(), sub);
            } else {
                colData.put(layout.getFldNm(), ds.getObject(0, layout.getFldNm()));
            }
        }
    }
}

3.2. 전문 형식이 다른 경우 개별부 전문 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.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.BxiMessage;
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 implements Processor {
   private final Logger logger = LoggerFactory.getLogger(this.getClass());

   @Override
   public void process(Exchange exchange) {
       Message in = exchange.getIn();
       BxiMessage bxiMessage = in.getBody(BxiMessage.class);

        // 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(BxiMessage 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(BxiMessage 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();
        }
    }
}

3.3. 전문 구조가 다른 경우 개별부 전문 Unmarshal 프로그램

import java.util.Map;

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

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.BxiMessage;
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 implements Processor {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void process(Exchange exchange) {
        Message in = exchange.getIn();
        BxiMessage bxiMessage = in.getBody(BxiMessage.class);

        // 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,
            BxiMessage 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(BxiMessage 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();
        }
    }
}

3.4. 전문 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.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.BxiMessage;
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 implements Processor {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private DaoProcess daoProcess;

    @Override
    public void process(Exchange exchange) {
        Message in = exchange.getIn();
        BxiMessage bxiMessage = in.getBody(BxiMessage.class);

        // 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(BxiMessage 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(BxiMessage 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;
    }
}
SWLab Bankware Global
  • 전체
  • BXM
  • BXCM
  • BXCP
  • BXI
제품 선택 시 더 정확한 매뉴얼 가이드를 제공해드립니다.

Copyright© Bankwareglobal All Rights Reserved.