후행 처리 커스터마이징

이번 장은 후행 처리 커스터마이징에 대하여 설명하는 장이다.

1. 후행 처리 커스터마이징 Interface

후행 처리 커스터 마이징은 아래의 3가지의 Interface를 이용하여 커스터 마이징을 할 수 있다.

Interface 설명

IDeferredApTableReader

타겟 테이블에서 처리일련번호를 조회 처리

IDeferredPrePostProcessor

후행 처리 선/후처리

IDeferredUtils

영업일/업무마감여부를 처리

INumberingPrePostProcessor

넘버링 선/후처리

2. IDeferredApTableReader Interface

타겟 테이블에서 후행 처리의 일련번호를 조회 하는 Interface 이다.

2.1. 구현 Method

IDeferredApTableReader 의 구현 Method는 다음과 같다.

public IDeferredExecInfo getApTableProcInfo(final IDeferredMainInfo deferredMainInfo, final long lastSeq);

2.1.1. getApTableProcInfo() Method

타겟 테이블에서 후행 처리가 일련번호를 조회 한다.

속성

설명

파라 미터

IDeferredMainInfo

deferredMainInfo

후행 처리 메인/상태 정보를 조회한 정보

long lastSeq

후행처리작업(BXM_DEFERRED_WORK)테이블에서 마지막으로 조회한 종료일련번호

리턴

IDeferredExcelInfo

후행 처리 실행(BXM_DEFERRED_EXEC)에 등록할 실행 정보

getApTableProcInfo() Sample

아래의 예는 타겟 테이블에서 일련번호를 조회하는 예로서, 만일 실행할 일련번호가 존재하지 않으면 null을 return 한다.

private static final String SELECT_APTABLE_SQL =
    " SELECT MAX(%s) " +
    " FROM %s " +
    " WHERE %s > ? AND %s <= COALESCE(CAST(? as int), 0) + ? " +
    " %s "
    ;

@Override
public IDeferredExecInfo getApTableProcInfo(final IDeferredMainInfo deferredMainInfo, long maxSeq)
{
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;

    IDeferredExecInfo deferredExecInfo = null;

    try
    {
        conn = BxmDeferredUtils.getConnection();

        // Table명 설정
        String tableName = null;
        if(deferredMainInfo.isDayTableYn())
        {
            tableName = new StringBuilder().append(deferredMainInfo.getTargetTableNm())
                                           .append(DeferredConstants.TABLE_WORD_SEPARATE_VAL)
                                           .append(BxmDeferredUtils.getDay(deferredMainInfo.getBizDt()))
                                           .toString();
        }
        else
        {
            tableName = deferredMainInfo.getTargetTableNm();
        }

        String sql = null;

        // 노드병 실행 여부에 따른 조회 쿼리 정의
        if(deferredMainInfo.isNodeExecYn())
        {
            sql = String.format(SELECT_APTABLE_SQL
                    , deferredMainInfo.getTargetColumnNm()
                    , tableName
                    , deferredMainInfo.getTargetColumnNm()
                    , deferredMainInfo.getTargetColumnNm()
                    , DeferredConstants.WHERE_NODE_NO_SQL
                    );
        }
        else
        {
            sql = String.format(SELECT_APTABLE_SQL
                    , deferredMainInfo.getTargetColumnNm()
                    , tableName
                    , deferredMainInfo.getTargetColumnNm()
                    , deferredMainInfo.getTargetColumnNm()
                    , ""
                    );
        }

        pstmt = conn.prepareStatement(sql);

        int ix = 0;

        pstmt.setLong(++ix, maxSeq);
        pstmt.setLong(++ix, maxSeq);
        pstmt.setInt(++ix, deferredMainInfo.getFetchCnt());
        if(deferredMainInfo.isNodeExecYn())
        {
            pstmt.setInt(++ix, BxmDeferredUtils.getNodeNo());
        }

        rs = pstmt.executeQuery();
        if(rs.next())
        {
            // 실행정보 설정
            long startSeq = maxSeq + 1;
            long endSeq =  rs.getLong(1);

            if(startSeq != 0 && startSeq <= endSeq)
            {
                deferredExecInfo = new DeferredExecInfo();

                deferredExecInfo.setStartSeq(startSeq);
                deferredExecInfo.setEndSeq(endSeq);
                deferredExecInfo.setDeferredId(deferredMainInfo.getDeferredId());
                deferredExecInfo.setNodeNo(BxmDeferredUtils.getNodeNo());
                deferredExecInfo.setBizDt(deferredMainInfo.getBizDt());
                deferredExecInfo.setDeferredStatusCd(DeferredConstants.EXEC_STATUS_PROCEEDING);
                deferredExecInfo.setStartDttm(BxmDeferredUtils.getCurrentSystemTime());
                deferredExecInfo.setErrCd("");
                deferredExecInfo.setErrMsgCtt("");
            }
        }
    }
    catch (Exception e)
    {
        logger.error(e.getMessage(), e);
        throw new IllegalStateException(e);
    }
    finally
    {
        BxmDeferredUtils.closeDbConn(conn, pstmt, rs);
    }
    return deferredExecInfo;
}

참고로, 후행 처리 메인 에서 테이블리더빈 명(TABLE_READER_BEAN_NM)이 정의되어 있다면 해당 Interface는 수행하지 않는다.

3. IDeferredPrePostProcessor Interface

후행 처리 선/후처리 및 후행 처리 서비스 호출에 대하여 커스터마이징 할 수 있도록 제공하고 있는 Interface 이다.

3.1. 구현 Method

IDeferredPrePostProcessor 의 구현 Method는 다음과 같다.

public IOmmObject deferredPreProcessor(final ContextHeader cHeader, final Application application
        , final ServiceTraceContextImpl serviceTraceContextImpl, final IDeferredMainInfo deferredMainInfo
        , final IDeferredExecInfo deferredExecInfo, final Long procSeq);

public void executeDeferredService(final ContextHeader cHeader,
        final ServiceTraceContextImpl serviceTraceContextImpl,
        final IDeferredMainInfo deferredMainInfo, final IOmmObject iOmmObject) throws NestedRuntimeException, NestedCheckedException;

public void deferredErrorPostProcessor(final ContextHeader cHeader
        , final IDeferredMainInfo deferredMainInfo, final IDeferredExecInfo deferredExecInfo, Exception exception, long procNum);

public void deferredPostProcessor(final ContextHeader cHeader, final IDeferredMainInfo deferredMainInfo
        , final IDeferredExecInfo deferredExecInfo);

3.1.1. deferredPreProcessor() Method

후행 처리 서비스를 호출하기 위한 선처리 작업을 수행하는 Method 이다. 해당 Method 에서는 헤더, 후행 처리 전달 OMM 등을 정의 할 수 있다.

속성

설명

파라 미터

ContextHeader cHeader

시스템 헤더

Application application

Deploy한 Application

ServiceTraceContextImpl serviceTraceContextImpl

서비스 Trace Context

IDeferredMainInfo deferredMainInfo

후행 처리 메인/상태 정보를 조회한 정보

Long procSeq

현재 처리 일련번호

리턴

IOmmObject

후행 처리 서비스에 전달할 OMM(Default OMM은 DeferredExcelO)

deferredPreProcessor() Sample

아래의 예는 후행 처리 선 처리에서 구현하는 예시이다. 필요 시 해당 선 처리에서 로그레벨, 후행 처리 서비스 입력 OMM 등 다양하게 프로젝트 환경에 맞춰 커스터마이징을 할 수 있다.

@Override
public DeferredExecIO deferredPreProcessor(final ContextHeader cHeader, final Application application,
        final ServiceTraceContextImpl serviceTraceContextImpl, final IDeferredMainInfo deferredMainInfo
        , final IDeferredExecInfo deferredExecInfo, final Long procSeq)
{
    // Header 설정
    cHeader.setRemoteAddr("localhost");
    cHeader.setUuid(SystemUtils.generateGUID());
    ((IOmmObject)cHeader).set("userId", "deferredExecutor");

    // 후행 처리 Service 입력 데이터 생성
    DeferredExecIO deferredExecIO = new DeferredExecIO();
    deferredExecIO.setDeferredId(deferredExecInfo.getDeferredId());
    deferredExecIO.setBizDt(deferredExecInfo.getBizDt());

    // 일련번호 하나씩.. 서비스 호출
    if(DeferredConstants.SVC_PROC_ONE.equals(deferredMainInfo.getSvcProcCd()))
    {
        // Error 가 발생한 일련번호 설정
        deferredExecIO.setProcSeq(procSeq);
    }
    // 대상전체.. 서비스 호출
    else if(DeferredConstants.SVC_PROC_ALL.equals(deferredMainInfo.getSvcProcCd()))
    {
        deferredExecIO.setStartSeq(deferredExecInfo.getStartSeq());
        deferredExecIO.setEndSeq(deferredExecInfo.getEndSeq());
    }
    deferredExecIO.setTargetTableNm(deferredMainInfo.getTargetTableNm());
    deferredExecIO.setTargetColumnNm(deferredMainInfo.getTargetColumnNm());
    deferredExecIO.setNodeNo(deferredExecInfo.getNodeNo());

    return deferredExecIO;
}

3.1.2. executeDeferredService() Method

후행 처리 서비스를 호출하기 위한 Method이다.

속성

설명

파라 미터

ContextHeader cHeader

시스템 헤더

ServiceTraceContextImpl serviceTraceContextImpl

서비스 Trace Context

IDeferredMainInfo deferredMainInfo

후행 처리 메인/상태 정보를 조회한 정보

IOmmObject iOmmObject

후행 처리 서비스의 입력 DTO

리턴

void

executeDeferredService() Sample

아래의 예는 후행 처리 서비스를 호출 하는 예이다.

@Override
public void executeDeferredService(final ContextHeader cHeader,
        final ServiceTraceContextImpl serviceTraceContextImpl, final IDeferredMainInfo deferredMainInfo, final IOmmObject iOmmObject)
                throws NestedRuntimeException, NestedCheckedException
{
    // Deferred Service 호출
    ServiceExecutor.execute(deferredMainInfo.getBxmAppId(), deferredMainInfo.getSvcNm()
            , deferredMainInfo.getOpNm(), iOmmObject);
}

3.1.3. deferredPostProcessor() Method

후행 처리 서비스가 정상적으로 처리가 완료가 된 경우에 호출 되는 Method 이다. 서비스 처리 완료 후에 추가적으로 처리할 부분이 있으면 해당 Method 에서 커스터마이징을 할 수 있다.

속성

설명

파라 미터

ContextHeader cHeader

시스템 헤더

ServiceTraceContextImpl serviceTraceContextImpl

서비스 Trace Context

IDeferredMainInfo deferredMainInfo

후행 처리 메인/상태 정보를 조회한 정보

IDeferredExecInfo deferredExecInfo

후행 처리 서비스 실행 정보

리턴

void

deferredPostProcessor()

아래는 후행 처리 후처리 Sample Method이다.

@Override
public void deferredPostProcessor(final ContextHeader cHeader, final IDeferredMainInfo deferredMainInfo, final IDeferredExecInfo deferredExecInfo)
{

}

3.1.4. deferredErrorPostProcessor() Method

후행 처리 서비스에서 에러가 발생한 경우에 호출 되는 Method 이다. 에러 발생 시 추가적으로 처리할 부분이 있으면 해당 Method 에서 커스터마이징을 할 수 있다.

속성

설명

파라 미터

ContextHeader cHeader

시스템 헤더

IDeferredMainInfo deferredMainInfo

후행 처리 메인/상태 정보를 조회한 정보

IDeferredExecInfo deferredExecInfo

후행 처리 서비스 실행 정보

Exception exception

후행 처리 서비스에서 발생한 Exception 정보

int procNum

현재처리일련번호

리턴

void

deferredErrorPostProcessor()

아래는 후행 처리 에러 후처리 Sample Method 이다.

@Override
public void deferredErrorPostProcessor(final ContextHeader cHeader
        , final IDeferredMainInfo deferredMainInfo, final IDeferredExecInfo deferredExecInfo, Exception exception, int procNum)
{

}

4. IDeferredUtils Interface

후행 처리 수행 시 영업일자와 업무마감여부를 확인하기 위한 Interface 이다.

4.1. 구현 Method

IDeferredUtils 의 구현 Method는 다음과 같다.

public String loadBizDt();
public boolean isApEndYn(IDeferredMainInfo deferredMainInfo);
public void decideApEndYn(IDeferredMainInfo deferredMainInfo, IDeferredWorkInfo deferredWorkInfo);

4.1.1. loadBizDt() Method

현재의 영업일자를 가져오는 Method이다.

속성 설명

리턴

String

현재의 영업일자

loadBizDt() Sample

아래의 예는 현재의 영업일자를 가져오는 Sample 이다. Default 로는 System 일자로 가져온다.

@Override
public String loadBizDt()
{
    return DateUtils.getCurrentDate(DateUtils.EMPTY_DATE_TYPE);
}

4.2. isApEndYn() Method

업무마감 여부를 판단하는 Method 이다.

속성 설명

파라 미터

IDeferredMainInfo deferredMainInfo

후행 처리 메인/상태 정보

리턴

boolean

마감여부

isApEndYn() Sample

아래의 예는 업무마감여부를 판단하는 예이다. Default는 후행 처리의 영업일자와 System 일자가 다를 경우 마감으로 판단하고 true로 return 한다.

사이트에 맞게 커스텀마이징 해야 한다.

@Override
public boolean isApEndYn(IDeferredMainInfo deferredMainInfo) {
    // 업무에대한 마감 여부를 판단한다.
    // 현재는 입력받은 영업일자와 현재의 System 일자를 비교하여 다르면 마감이라고 판단한다.
    // 마감여부 판단은 시스템에 따라서 처리하는 부분이 다르기 때문에.. 필요시 해당 Method에서 구현하여 처리할 수 있도록 한다.
    String sysDt = DateUtils.getCurrentDate(DateUtils.EMPTY_DATE_TYPE);

    return sysDt.equals(deferredMainInfo.getBizDt()) ? false : true;
}

4.2.1. decideApEndYn() Method

업무마감을 결정하는 Method이다.

속성 설명

파라 미터

IDeferredMainInfo deferredMainInfo ,IDeferredWorkInfo
deferredWorkInfo

후행 처리 메인/상태 정보

리턴

void

없음

decideApEndYn() Sample

아래의 예는 업무마감을 결정하는 예이다.

@Override
public void decideApEndYn(IDeferredMainInfo deferredMainInfo, IDeferredWorkInfo deferredWorkInfo)
{
    if ( !isApEndYn(deferredMainInfo))
    {
        return ;
    }

    if (isExistingRunningDeferredService(deferredMainInfo))
    {
        logger.info("Deferred[{}] is running. Can not be closed.", deferredMainInfo.getDeferredId());
    }
    else
    {
        if (isEndDeferredProcessor(deferredMainInfo))
        {
            workEnd(deferredMainInfo, deferredWorkInfo);
        }
    }
}

private boolean isExistingRunningDeferredService(IDeferredMainInfo deferredMainInfo)
{
    return (DeferredContainer.getDeferredDBProcessor().getDeferredExecInfoCount(deferredMainInfo) > 0);
}

private void workEnd(IDeferredMainInfo deferredMainInfo, IDeferredWorkInfo deferredWorkInfo)
{
    deferredWorkInfo.setEndYn(true);
    int result = DeferredContainer.getDeferredDBProcessor().modifyDeferredWorkEnd(deferredWorkInfo);
    if(result != 0)
    {
        logger.info("Deferred[{}] to NodeNo[{}]/BizDate[{}] is now complete."
                , new Object[]{deferredMainInfo.getDeferredId()
                            , deferredWorkInfo.getNodeNo()
                            , deferredMainInfo.getBizDt()});
    }
}

5. INumberingPrePostProcessor Interface

넘버링 선/후 처리를 할 수 있도록 제공하는 Interface이다.

5.1. 구현 Method

INumberingPrePostProcessor 의 구현 Method는 다음과 같다.

public void numberingPreProcessor(final ContextHeader cHeader, final IDeferredMainInfo deferredMainInfo);
public void numberingPostProcessor(final ContextHeader cHeader, final IDeferredMainInfo deferredMainInfo);
public void numberingErrorPostProcessor(final ContextHeader cHeader, final IDeferredMainInfo deferredMainInfo, Exception exception);

5.1.1. numberingPreProcessor() Method

넘버링 선처리 Method이다.

속성

설명

파라 미터

ContextHeader cHeader

시스템 헤더

IDeferredMainInfo deferredMainInfo

후행 처리 메인/상태 정보

리턴

void

5.1.2. numberingPostProcessor() Method

넘버링이 정상 수행 후 호출 되는 Method이다.

속성

설명

파라 미터

ContextHeader cHeader

시스템 헤더

IDeferredMainInfo deferredMainInfo

후행 처리 메인/상태 정보

리턴

void

5.1.3. numberingErrorPostProcessor() Method

넘버링이 에러 발생 후 호출 되는 Method이다.

속성

설명

파라 미터

ContextHeader cHeader

시스템 헤더

IDeferredMainInfo deferredMainInfo

후행 처리 메인/상태 정보

Exception exception

Numbering Exception

리턴

void

Copyright© Bankwareglobal All Rights Reserved.