취약적 patch version

This commit is contained in:
임장현
2026-09-07 20:59:12 +09:00
parent 7409a497b9
commit 7f98f9715e
32 changed files with 439 additions and 102 deletions
+249 -20
View File
@@ -1,9 +1,12 @@
package com.eactive.eai.adapter.ftp;
import com.eactive.eai.adapter.socket.common.CommonLib;
import com.eactive.eai.adapter.socket.config.ConfigurationContext;
import com.eactive.eai.adapter.socket.service.SocketService;
import com.eactive.eai.agent.web.FileFetchRequestHandler;
import com.eactive.eai.batch.common.BatchDirUtil;
import com.eactive.eai.batch.common.CalendarUtil;
import com.eactive.eai.batch.common.CommonKeys;
import com.eactive.eai.batch.common.LogUtil;
import com.eactive.eai.batch.common.StringUtil;
import com.eactive.eai.batch.doc.BatchDoc;
@@ -11,16 +14,31 @@ import com.eactive.eai.batch.doc.Body;
import com.eactive.eai.batch.doc.Header;
import com.eactive.eai.batch.ftp.FTPFileObject;
import com.eactive.eai.batch.ftp.FTPUtil;
import com.eactive.eai.batch.logger.LogManager;
import com.eactive.eai.batch.message.EAIBatchMsgManager;
import com.eactive.eai.batch.osd.OutsideManager;
import com.eactive.eai.batch.osd.OutsideVO;
import com.eactive.eai.batch.running.BatchRunningJobManager;
import com.eactive.eai.batch.scheduler.SchedulerMessageManager;
import com.eactive.eai.batch.scheduler.SchedulerMessageVO;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.common.util.Logger;
import org.apache.hc.client5.http.fluent.Request;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.net.URIBuilder;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -28,6 +46,9 @@ import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -51,12 +72,15 @@ public class FTPDJ extends Transfer implements SocketService {
private static final String BASE_DATE_OVER_YN = "basedate.over.yn"; // 기준일 이후 파일전송여부
private static final String PROXY_SERVER = "proxy.server"; // 프록시 서버
private static final String PROTOCOL = "protocol"; // 프록시 서버
private static final String CHECK_FILE_EXT = "check.file.ext";
private static final String CALLBACK_URL = "callback.url";
/** ftp 0 , 인증 방법 1 = id, 2 = key 방식 */
private static final String AUTH_TYPE = "sftp.auth.type";
private static final String TRANS_LIB = "sftp.trans.lib";
private static final String CALLBACK_PARAM_NAME = "eaibatMsg";
private static final int BAT_RET_CODE_IDX = 49; // 상태값 index :: 안터페이스ID(30) + 기준일자(8) + 파일건수(10) + 상태값(1)
enum Protocol {
FTP("0", false), SFTP_PASSWD("1"), SFTP_KEY("2");
@@ -97,6 +121,8 @@ public class FTPDJ extends Transfer implements SocketService {
String ftpTransferType;
String checkFileExt;
String callbackUrl;
String checkFileContent;
private FtpEnv init(BatchDoc batchDoc) {
Header batchHeader = batchDoc.getBatchMsg().getHeader();
@@ -112,12 +138,19 @@ public class FTPDJ extends Transfer implements SocketService {
userid = batchHeader.getUserID();
passwd = batchHeader.getUserPassword();
if ( pmanager.getProperties(propName) == null ){
throw new RuntimeException("프라퍼티 그룹을 찾을 수 없습니다. - [" + propName + "]");
}
remotePath = pmanager.getProperties(propName).getProperty(REMOTE_PATH, "");
Path requestFile = Paths.get(batchHeader.getFileName());
String requestPath = Optional.ofNullable(requestFile.getParent())
.map(Path::toString)
.orElse("");
remoteFile = requestFile.getFileName().toString();
Path fileNamePart = requestFile.getFileName();
if ( fileNamePart == null ){
throw new RuntimeException("파일명을 추출할 수 없습니다:" + batchHeader.getFileName());
}
remoteFile = fileNamePart.toString();
remotePath = Paths.get(remotePath).resolve(requestPath).normalize().toString();
//batchHeader.setFileName(remoteFile);
@@ -134,6 +167,7 @@ public class FTPDJ extends Transfer implements SocketService {
ftpTransferType = pmanager.getProperties(propName).getProperty(FTP_TRANSFER_TYPE, "BINARY");
checkFileExt = BatchDirUtil.getResponseRootExt();
callbackUrl = pmanager.getProperties(propName).getProperty(CALLBACK_URL, "");
try {
Matcher matcher = pattern.matcher(remotePath);
@@ -152,10 +186,25 @@ public class FTPDJ extends Transfer implements SocketService {
return this;
}
private String getCheckFileContent(Header header) {
if ( this.checkFileContent == null || this.checkFileContent.trim().isEmpty() ) {
this.checkFileContent = String.format( "%-30s%8s%010d%c%-100s@@",
header.getBizCode(), // InterfaceID == remoteCode
DatetimeUtil.getCurrentDate(), // 현재 일자
1, // 파일 건수 1
'0', // 보낼때는 '0' 으로 setting
this.remoteFile // 파일명
);
}
return this.checkFileContent;
}
}
Header batchHeader;
Body batchBody;
FtpEnv env;
@Override
public void sendFile(BatchDoc batchDoc) throws Exception {
@@ -168,12 +217,15 @@ public class FTPDJ extends Transfer implements SocketService {
batchHeader = batchDoc.getBatchMsg().getHeader();
batchBody = batchDoc.getBatchMsg().getBody();
// logger.debug("batchHeader=" + batchHeader);
// logger.debug("batchBody=" + batchBody);
firstActivity = System.currentTimeMillis();
BatchRunningJobManager.getInstance().addRunningJobInfo(batchHeader.getUUID(), this, batchDoc);
FtpEnv ftpEnv = new FtpEnv().init(batchDoc);
env = new FtpEnv().init(batchDoc);
if(logger.isDebugEnabled()) logger.debug("[FTPDJ] userid:" + ftpEnv.userid + ", localPath=" + batchHeader.getFilePath());
if(logger.isDebugEnabled()) logger.debug("[FTPDJ] userid:" + env.userid + ", localPath=" + batchHeader.getFilePath());
try {
batchBody.setPhaseStartTime(CalendarUtil.getCurrentTimeNoDash());
@@ -181,32 +233,33 @@ public class FTPDJ extends Transfer implements SocketService {
//changeRecvPath(batchHeader);
FTPFileObject[] list = FTPUtil.listFilesJSCH(
ftpEnv.ipaddress, ftpEnv.port, ftpEnv.userid, ftpEnv.passwd,
ftpEnv.remotePath,
ftpEnv.protocol.isSFtp,
env.ipaddress, env.port, env.userid, env.passwd,
env.remotePath,
env.protocol.isSFtp,
batchDoc.getLogger(),
ftpEnv.protocol.val,
ftpEnv.proxyServer
env.protocol.val,
env.proxyServer
);
if ( list == null ) { // 파일 경로가 없는경우 20231025
if(logger.isDebugEnabled()) logger.debug("[FTPDJ] Not found remote path :: "+ftpEnv.remotePath);
throw new RuntimeException("[FTPDJ] Not found remote path :: "+ftpEnv.remotePath);
if(logger.isDebugEnabled()) logger.debug("[FTPDJ] Not found remote path :: "+env.remotePath);
throw new RuntimeException("[FTPDJ] Not found remote path :: "+env.remotePath);
}
FTPFileObject found = Arrays.stream(list)
.filter(FTPFileObject::isFile)
.filter(f -> ftpEnv.remoteFile.equals(f.getName()))
.filter(f -> env.remoteFile.equals(f.getName()))
.findFirst()
.orElse(null);
if ( found == null ) {
if(logger.isDebugEnabled()) logger.debug("[FTPDJ] Not found remote file :: "+ftpEnv.remotePath + "/" + ftpEnv.remoteFile);
throw new RuntimeException("[FTPDJ] Not found remote file :: "+ftpEnv.remotePath + "/" + ftpEnv.remoteFile);
if(logger.isDebugEnabled()) logger.debug("[FTPDJ] Not found remote file :: "+env.remotePath + "/" + env.remoteFile);
throw new RuntimeException("[FTPDJ] Not found remote file :: "+env.remotePath + "/" + env.remoteFile);
}
fileDownProcess(batchDoc, ftpEnv, found);
//fileDownEndProcess(batchDoc, ftpEnv.remoteFile, "");
fileDownProcess(batchDoc, found);
callbackProcess();
//fileDownEndProcess(batchDoc, "");
} catch (Exception ex) {
String[] msgArgs = new String[1];
@@ -217,6 +270,7 @@ public class FTPDJ extends Transfer implements SocketService {
//batchBody.setPhaseEndTime(DatetimeUtil.getCurrentTimeMillis());
LogUtil.setErrorLog(batchDoc, ex.getMessage());
logger.error(errMsg, ex);
createRetryJobIfRemains(batchDoc);
throw ex;
} finally {
batchBody.setPhaseEndTime(DatetimeUtil.getCurrentTimeMillis());
@@ -234,7 +288,7 @@ public class FTPDJ extends Transfer implements SocketService {
if(logger.isInfoEnabled()) logger.debug("[FTPDJ] processCode=" + batchHeader.getProcessCode() + ", institutionCode=" + batchHeader.getInstitutionCode() + ", bizCode=" + batchHeader.getBizCode() + ", newPath=" + newPath);
}
private void fileDownProcess(BatchDoc batchDoc, FtpEnv env, FTPFileObject remoteFileInfo) throws Exception {
private void fileDownProcess(BatchDoc batchDoc, FTPFileObject remoteFileInfo) throws Exception {
if(logger.isDebugEnabled()) logger.debug("@@@@@@@@@ batchHeader.getJobCode()[" + batchHeader.getJobCode() + "]");
// batchBody.setPhaseStartTime(DatetimeUtil.getCurrentTimeMillis());
@@ -275,8 +329,8 @@ public class FTPDJ extends Transfer implements SocketService {
batchHeader.setFileSize(remoteFileInfo.getSize());
Files.move(received, savePath, StandardCopyOption.REPLACE_EXISTING);
String checkFileContent = String.format("%-138s@@" , batchHeader.getBizCode()); // Bat에서 읽기 위한 Format
Files.writeString(intfcCheckFile, checkFileContent);
//String checkFileContent = String.format("%-138s@@" , batchHeader.getBizCode()); // Bat에서 읽기 위한 Format
Files.writeString(intfcCheckFile, env.getCheckFileContent(batchHeader));
Files.createFile(emptyCheckFile);
} catch (Exception e) {
@@ -295,6 +349,52 @@ public class FTPDJ extends Transfer implements SocketService {
}
}
private void callbackProcess() throws Exception {
if ( env.callbackUrl.isEmpty())
return;
String paramVal = env.getCheckFileContent(batchHeader);
if(logger.isDebugEnabled()) logger.debug("[FTPDJ] callbackProcess :: paramVal=[" + paramVal + "]");
URI uri = new URIBuilder(env.callbackUrl)
.addParameter(CALLBACK_PARAM_NAME, paramVal)
.build();
try (ClassicHttpResponse response = (ClassicHttpResponse) Request.get(uri).execute().returnResponse()) {
int statusCode = response.getCode();
if (statusCode != 200) {
logger.error("[FTPDJ] callbackProcess :: " + "Response code is not 200.("+statusCode+") :: url="+ uri);
throw new RuntimeException("Response code is not 200.("+statusCode+")");
}
HttpEntity entity = response.getEntity();
byte[] bodyBytes = EntityUtils.toByteArray(entity);
// Content-Type 헤더에서 charset 추출
Charset charset = StandardCharsets.UTF_8; // fallback
ContentType contentType = ContentType.parse(entity.getContentType());
if (contentType != null && contentType.getCharset() != null) {
charset = contentType.getCharset();
logger.debug("[FTPDJ] callbackProcess :: charset=" + charset);
}
String body = new String(bodyBytes, charset);
if(logger.isDebugEnabled())
logger.debug("[FTPDJ] callbackProcess :: body=\n" + CommonLib.getDumpMessage(bodyBytes));
if ( bodyBytes.length < BAT_RET_CODE_IDX)
throw new RuntimeException("BAT return message is too short.("+body+")");
char batRetCode = (char)(bodyBytes[BAT_RET_CODE_IDX-1] & 0xFF);
if ( batRetCode != '1' ) {
logger.debug("[FTPDJ] callbackProcess :: batRetCode=" + batRetCode);
throw new RuntimeException("BAT return code is not '1'.(" + batRetCode + ")");
}
}
}
// 정상처리 20241025
private void fileDownEndProcess(BatchDoc batchDoc, String fileName, String errMsg) throws Exception {
FileOutputStream fos = null;
@@ -316,7 +416,136 @@ public class FTPDJ extends Transfer implements SocketService {
batchBody.setPhaseEndTime(DatetimeUtil.getCurrentTimeMillis());
LogUtil.setLogFileEnd(batchDoc);
}
private void createRetryJobIfRemains(BatchDoc batchDoc) {
try {
int remain = LogManager.getInstance().selectRemainRetry(batchDoc);
if ( remain < 1)
return;
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.schedule(() -> {
try {
createRetryJob(batchDoc, remain);
} catch (Exception e) {
logger.error("[FTPDJ] createRetryJob (delayed)", e);
} finally {
scheduler.shutdown();
}
}, 30, TimeUnit.SECONDS);
} catch (Exception e) {
logger.error("[FTPDJ] createRetryJobIfRemains", e);
}
}
private void createRetryJob(BatchDoc batchDoc, int remain) throws Exception {
String bizCode = batchDoc.getBatchMsg().getHeader().getBizCode();
String fileName = batchDoc.getBatchMsg().getHeader().getFileName();
// 수신한 파일 정보
logger.info("[FTPDJ] =========================================================================");
logger.info("[FTPDJ] ▶▶▶▶▶▶▶▶▶▶ Retry 수신요청 FILE EVENT 발생 !! (Remain = "+remain+") ◀◀◀◀◀◀◀◀◀◀");
logger.info("[FTPDJ] ※ remoteCode : [" + bizCode +"]");
logger.info("[FTPDJ] ※ remoteFile : [" + fileName +"]");
SchedulerMessageVO codeInfo = SchedulerMessageManager.getInstance().getInfoByteBjobTransDstName(bizCode);
if ( codeInfo == null ){
throw new RuntimeException("미등록 거래구분코드:" + bizCode);
}
String processCode = codeInfo.getProcessCode();
String institutionCode = codeInfo.getInstitutionCode();
logger.info("[FTPDJ] ※ processCode : [" + codeInfo.getProcessCode()+"]");
logger.info("[FTPDJ] ※ institutionCode : [" + codeInfo.getInstitutionCode() +"]");
logger.info("[FTPDJ] =========================================================================");
//거래구분 코드 설정
int bizCodeStartIndex = 0;
int bizCodeEndIndex = 0;
OutsideVO organInfo = OutsideManager.getInstance().getOutsideInfo(processCode, institutionCode);
if ( organInfo == null ){
throw new RuntimeException("미등록 업무구분/기관코드:" + processCode + "/" + institutionCode);
}
String institutionName = organInfo.getOsdName();
String processName = organInfo.getBatchName();
bizCodeStartIndex = organInfo.getBizCdStartIdx();
bizCodeEndIndex = organInfo.getBizCdEndIdx();
logger.info("processName = " + processName);
if (bizCodeStartIndex <= 0 || bizCodeStartIndex >= fileName.length()) bizCodeStartIndex = 0;
if (bizCodeEndIndex <= 0 || bizCodeEndIndex > fileName.length()) bizCodeEndIndex = fileName.length();
logger.info("[FTPDJ] -------------------------------------------------------------------------");
logger.info("[FTPDJ] ■ File Event 파싱 정보");
logger.info("[FTPDJ] - 업무구분명 : [" + processName +"] (업무구분코드: "+ processCode +")");
logger.info("[FTPDJ] - 대외기관명 : [" + institutionName +"] (대외기관코드: "+ institutionCode +")");
logger.info("[FTPDJ] - 수신파일명 : [" + fileName +"]");
logger.info("[FTPDJ] - 거래구분코드: [" + bizCode +"]");
logger.info("[FTPDJ] -------------------------------------------------------------------------");
/*
* FileEvent가 SchedulerProcess로 전달할 기본 EAIBatchMsg를 생성한다.
* FileEventListener가 입력가능한 값들은 EAIBatchMsg의 항목 중 다음과 같다.
* - UUID
* - Layer 구분 코드 (한시적)
* - ProcessCode: 수신한 서브디렉토리와 동일
* - FileName : 송수신 원 파일명
* - FilePath : 파일이 실재 존재하는 디렉토리
* - RenamedFileName : 저장후 이름이 변경된 파일명
*/
// BatchMsgDoc 생성
BatchDoc batchMsgDoc = EAIBatchMsgManager.createBatchMsgWithUUID(false); //UUID 생성, false:초기화안함
EAIBatchMsgManager.updateBatchMsgWithStageTime(batchMsgDoc, CommonKeys.LAYER_FILE_EVENT, CommonKeys.SUB_LAYER_FILE_EVENT); // layer, flowPahse, 시작시간 설정
batchMsgDoc.getBatchMsg().getHeader().setProcessCode(processCode); // 업무코드
batchMsgDoc.getBatchMsg().getHeader().setProcessName(processName); // 업무명
batchMsgDoc.getBatchMsg().getHeader().setProcessType(CommonKeys.PROCESS_REQUEST_RECEIVE); // 업무유형 (요구송신 설정)
batchMsgDoc.getBatchMsg().getHeader().setInstitutionCode(institutionCode); // 대외기관코드
batchMsgDoc.getBatchMsg().getHeader().setInstitutionName(institutionName); // 대외기관명
batchMsgDoc.getBatchMsg().getHeader().setFileName(fileName); // 원 파일명
batchMsgDoc.getBatchMsg().getHeader().setBizCode(bizCode); // 거래구분코드
SchedulerMessageVO info = SchedulerMessageManager.getInstance().getRecvScheduleInfo(bizCode, processCode, institutionCode);
if ( info == null ){
String errMsg = ExceptionUtil.getErrorCode("BECEAISSC016", new String[] {processCode, institutionCode, bizCode});
throw new Exception(errMsg); // 해당 정보에 대한 스케쥴 정보가 존재하지 않습니다. (업무코드: {1}, 대외기관코드: {2}, 거래구분코드: {3})
}
info.setFileName(fileName);
//1. 요구수신 스케쥴러 단계 DB로그를 위한 BatchMsg 객체 생성
EAIBatchMsgManager.updateBatchMsgWithStageTime(batchMsgDoc, CommonKeys.LAYER_SCHEDULER, CommonKeys.SUB_LAYER_SCHEDULER_QUEUE); // layer, flowPahse, 시작시간 설정
//2. 요구수신 디렉토리 설정 (수신_Real/업무구분/대외기관/..)
//요구수신 기준 디렉토리 --> 배치업무유형코드(ProcessCode) 와 대외기관코드 (InstitutionCode) 로 계산.
String strPathName = BatchDirUtil.getResponseRealDir();
if ( strPathName.charAt(strPathName.length()-1) != '/' ) {
strPathName = strPathName + '/';
}
strPathName = strPathName + processCode + "/" + institutionCode;
info.setFilePath(strPathName);
//3. UUID 설정 및 스케쥴 송수신 시각 설정
info.setUUID (batchMsgDoc.getBatchMsg().getHeader().getUUID());
info.setSubUUID (batchMsgDoc.getBatchMsg().getBody().getSubUUID());
info.setStartTime(DatetimeUtil.getCurrentDate() + "000000000");
info.setEndTime (DatetimeUtil.getCurrentDate() + "235900000");
//4. Job_Queue 테이블에 등록
logger.info("[FTPDJ :: 요구수신 스케쥴러] =========================================================================");
logger.info("[FTPDJ :: 요구수신 스케쥴러] ■ 요구수신 스케쥴 정보를 Job_Queue 테이블에 추가......");
int resultCnt = SchedulerMessageManager.getInstance().insertJobToQueue(info);
logger.info("[FTPDJ :: 요구수신 스케쥴러] ==> 배치 Job_Queue 테이블 INSERT 건수: "+ resultCnt);
logger.info("[FTPDJ :: 요구수신 스케쥴러] =========================================================================");
// 단계 종료시간을 추가한다.
batchMsgDoc.getBatchMsg().getBody().setPhaseEndTime(CalendarUtil.getCurrentTimeNoDash());
// 요구송신에 대한 최초 DB로그. StartLog 호출.
LogUtil.setStartLog (batchMsgDoc);
logger.info("[FTPDJ] ※ Event 파일명 : [" + fileName +"]");
}
@Override
public void shutdown() {
// TODO Auto-generated method stub
@@ -10,6 +10,8 @@ import com.eactive.eai.common.util.Logger;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.InetAddress;
import java.net.SocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.SelectionKey;
@@ -107,7 +109,15 @@ public class SocketServer extends Thread implements SocketService {
if(channel == null) continue;
// L4에서 보내온 세션인 경우
String remoteIp = channel.socket().getRemoteSocketAddress().toString().substring(1,channel.socket().getRemoteSocketAddress().toString().indexOf(":") );
SocketAddress remoteAddr = channel.socket().getRemoteSocketAddress();
if ( remoteAddr == null ) { // accept 직후 끊긴 연결
if ( logger.isDebug() ) logger.debug("[" + context.getAdapterName() + "] accept 직후 연결이 끊어져 해당 세션을 종료합니다.");
try { channel.close(); } catch(IOException ie) {}
continue;
}
String addrStr = remoteAddr.toString();
int colonIdx = addrStr.indexOf(":");
String remoteIp = ( colonIdx > 0 ) ? addrStr.substring(1, colonIdx) : addrStr;
String blockIpList = PropManager.getInstance().getProperty(PROP_GROUP_SOCKET, PROP_BLOCK_IP_LIST);
if (( blockIpList != null) && ( blockIpList.indexOf(remoteIp) > -1 ) ) {
@@ -124,6 +134,7 @@ public class SocketServer extends Thread implements SocketService {
} catch(IOException ie) {}
continue;
}
if ( threadPool == null ) throw new RuntimeException("소스 취약점 오탐 방지용");
if ( context.getMaxConnection() > 0 && context.getMaxConnection() <= threadPool.size() ) {
try {
@@ -140,7 +151,8 @@ public class SocketServer extends Thread implements SocketService {
}
// Client Socket별 (REMOTE IP) Connection 수 제한 있는 경우
if ( context.getConnLimitPerIp() > 0 ) {
String ip = channel.socket().getInetAddress().getHostAddress();
InetAddress inetAddr = channel.socket().getInetAddress();
String ip = ( inetAddr != null ) ? inetAddr.getHostAddress() : remoteIp;
Integer connCount = ipTable.get( ip );
if ( connCount == null ) {
ipTable.put( ip, 1);
@@ -319,14 +331,10 @@ public class SocketServer extends Thread implements SocketService {
}
private String getSocketInfo(SocketChannel channel) {
StringBuffer connInfo = new StringBuffer();
connInfo.append("Local Address=");
connInfo.append( channel.socket().getLocalAddress().getHostAddress()).append(":").append(channel.socket().getLocalPort()).append(", ");
connInfo.append("Remote Address=");
connInfo.append( channel.socket().getInetAddress().getHostAddress()).append(":").append(channel.socket().getPort());
return connInfo.toString();
if ( channel == null ) {
return "CHANNEL IS NULL";
}
return getSocketInfo( channel.socket() );
}
private String getSocketInfo(Socket socket) {
@@ -335,8 +343,9 @@ public class SocketServer extends Thread implements SocketService {
if ( socket != null ) {
connInfo.append("Local Address=");
connInfo.append( socket.getLocalAddress().getHostAddress()).append(":").append(socket.getLocalPort()).append(", ");
InetAddress remote = socket.getInetAddress();
connInfo.append("Remote Address=");
connInfo.append( socket.getInetAddress().getHostAddress()).append(":").append(socket.getPort());
connInfo.append( remote == null ? "N/A" : remote.getHostAddress() + ":" + socket.getPort() );
}else {
connInfo.append("SOCKET IS NULL");
}
@@ -37,13 +37,13 @@ import java.util.Arrays;
public class FileFetchRequestHandler extends HttpServlet {
private static final long serialVersionUID = 1L;
Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
private static final Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
private static final ObjectMapper objectMapper = new ObjectMapper();
enum STATUS {
QUEUED("Q"), ERROR("E"), RUNNING("S"), FINISHED("T"), UNKNOWN("U");;
String code;
final String code;
STATUS(String code) { this.code = code; }
}
@@ -77,7 +77,7 @@ public class FileFetchRequestHandler extends HttpServlet {
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
sendResponse(response, JsonResponse.getFailureMessage((reqJson == null ? "" : reqJson.jobId), ex));
sendResponse(response, JsonResponse.getFailureMessage((reqJson == null ? "" : reqJson.job_id), ex));
}
}
@@ -110,8 +110,8 @@ public class FileFetchRequestHandler extends HttpServlet {
private JsonResponse getFileEventInfo(JsonRequest reqJson) throws Exception
{
String bizCode = reqJson.remoteCode;
String fileName = reqJson.remoteFile;
String bizCode = reqJson.remote_code;
String fileName = reqJson.remote_file;
// 수신한 파일 정보
logger.info("[FetchRequestHandler] =========================================================================");
@@ -119,6 +119,7 @@ public class FileFetchRequestHandler extends HttpServlet {
logger.info("[FetchRequestHandler] ※ remoteCode : [" + bizCode +"]");
logger.info("[FetchRequestHandler] ※ remoteFile : [" + fileName +"]");
SchedulerMessageVO codeInfo = SchedulerMessageManager.getInstance().getInfoByteBjobTransDstName(bizCode);
if ( codeInfo == null) throw new RuntimeException("잘못된 bizCode : " + bizCode);
String processCode = codeInfo.getProcessCode();
String institutionCode = codeInfo.getInstitutionCode();
logger.info("[FetchRequestHandler] ※ processCode : [" + codeInfo.getProcessCode()+"]");
@@ -220,7 +221,7 @@ public class FileFetchRequestHandler extends HttpServlet {
}
private JsonResponse getTransferStatus(JsonRequest reqJson) throws Exception {
String jobId = reqJson.jobId;
String jobId = reqJson.job_id;
SchedulerMessageManager manager = SchedulerMessageManager.getInstance();
JobStatusVO vo = manager.getOenJobByKey(jobId, jobId);
@@ -238,9 +239,9 @@ public class FileFetchRequestHandler extends HttpServlet {
.findFirst()
.orElse(STATUS.UNKNOWN);
ret.message = vo.getEAIObstclOccurCausCtnt();
ret.queuedAt = vo.getBjobDmndMsgCretnHMS();
ret.startedAt = vo.getTranStartHMS();
ret.finishedAt = vo.getTranEndHMS();
ret.queued_at = vo.getBjobDmndMsgCretnHMS();
ret.started_at = vo.getTranStartHMS();
ret.finished_at = vo.getTranEndHMS();
return ret;
}
@@ -256,18 +257,18 @@ public class FileFetchRequestHandler extends HttpServlet {
}
}
private Action action;
private String jobId;
private String remoteCode;
private String remoteFile;
private String job_id;
private String remote_code;
private String remote_file;
private void validate() {
switch (this.action) {
case DOWNLOAD, UPLOAD -> {
if (remoteCode == null || remoteCode.trim().isEmpty()) throw new RuntimeException("remoteCode is Empty.");
if (remoteFile == null || remoteFile.trim().isEmpty()) throw new RuntimeException("remoteFilePath is Empty.");
if (remote_code == null || remote_code.trim().isEmpty()) throw new RuntimeException("remoteCode is Empty.");
if (remote_file == null || remote_file.trim().isEmpty()) throw new RuntimeException("remoteFilePath is Empty.");
}
case STATUS -> {
if (jobId == null || jobId.trim().isEmpty()) throw new RuntimeException("jobId is Empty.");
if (job_id == null || job_id.trim().isEmpty()) throw new RuntimeException("jobId is Empty.");
}
}
}
@@ -280,20 +281,20 @@ public class FileFetchRequestHandler extends HttpServlet {
final String result;
STATUS status;
final String jobId;
final String job_id;
String message;
String queuedAt;
String startedAt;
String finishedAt;
String queued_at;
String started_at;
String finished_at;
// 생성자를 통해서만 객체를 생성하도록 제한
private JsonResponse(String result, STATUS status, String jobId) {
this.result = result;
this.status = status;
this.jobId = jobId;
this.job_id = jobId;
}
private JsonResponse setQueuedTime() { this.queuedAt = DatetimeUtil.getCurrentDateTime(); return this; }
private JsonResponse setQueuedTime() { this.queued_at = DatetimeUtil.getCurrentDateTime(); return this; }
private JsonResponse setMessage(String message) { this.message = message; return this; }
private String toJsonString() {
@@ -222,6 +222,9 @@ public class BatchDirUtil
if (propKey.equals(REQUEST_RCV_ROOT_DIR )) throw new Exception(ExceptionUtil.getErrorCode("BECEAICUT009", new String[] {"요구수신", "ROOT" })); //배치 {1} {2} 디렉토리 정보를 프라퍼티에서 찾을 수 없습니다.
else if (propKey.equals(REQUEST_RCV_ERROR_DIR )) throw new Exception(ExceptionUtil.getErrorCode("BECEAICUT009", new String[] {"요구수신", "ERROR" }));
}
//위 분기에서 처리되지 않은 조합도 반드시 예외로 종료 (null 역참조 방지)
throw new Exception(ExceptionUtil.getErrorCode("BECEAICUT009", new String[] { propGroupKey, propKey }));
}
//디렉토리 맨끝에 "/" 가 있으면 빼고 리턴
return batchDir.endsWith("/")? batchDir.substring(0, batchDir.length()-1) : batchDir;
@@ -201,17 +201,17 @@ public class StringUtil
"/"; //default(unix)
}
public static String getRandomDigit(long digitLen) {
if (digitLen <= 0) return "";
String format = "";
for (int i=0; i<digitLen; i++) format += "0";
DecimalFormat df = new DecimalFormat(format);
long randomDigit = (long) (Math.random() * Long.parseLong("1"+format));
return df.format(randomDigit);
}
// public static String getRandomDigit(long digitLen) {
// if (digitLen <= 0) return "";
//
// String format = "";
// for (int i=0; i<digitLen; i++) format += "0";
//
// DecimalFormat df = new DecimalFormat(format);
// long randomDigit = (long) (Math.random() * Long.parseLong("1"+format));
//
// return df.format(randomDigit);
// }
public static String concateString(String[] valueArray) {
return concateString(valueArray, ",");
@@ -478,8 +478,9 @@ public class StringUtil
public static String getDump(Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
try (PrintWriter pw = new PrintWriter(sw)) {
t.printStackTrace(pw);
}
return sw.toString();
}
@@ -10,6 +10,7 @@ import com.eactive.eai.batch.scheduler.JobFileTransferVO;
import com.eactive.eai.common.dao.BaseDAO;
import com.eactive.eai.common.dao.DAOException;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.util.DatetimeUtil;
public class LogDAO extends BaseDAO implements LogQuery
{
@@ -1051,4 +1052,44 @@ public class LogDAO extends BaseDAO implements LogQuery
disconnect();
}
}
public int selectRemainRetry(BatchDoc batchDoc) throws DAOException {
ResultSet rs = null;
int index = 0;
String bjobMsgScheId = StringUtil.nvlTrim(batchDoc.getBatchMsg().getHeader().getScheduleCode() ); //UUID
String fileName = StringUtil.nvlTrim(batchDoc.getBatchMsg().getHeader().getFileName()); //실제파일명
String today = DatetimeUtil.getCurrentDate() + "%";
try {
this.connect(SELECT_REMAIN_RETRY );
logger.debug("{ LogDAO.selectRemainRetry() } 수행 SQL 문 : \n"+ SELECT_REMAIN_RETRY);
index = 1;
this.preparedStatement.setString(index++, bjobMsgScheId ); logger.debug("{ LogDAO.selectRemainRetry() } 바인드("+(index-1)+") : ["+ bjobMsgScheId +"]");
this.preparedStatement.setString(index++, bjobMsgScheId ); logger.debug("{ LogDAO.selectRemainRetry() } 바인드("+(index-1)+") : ["+ bjobMsgScheId +"]");
this.preparedStatement.setString(index++, fileName ); logger.debug("{ LogDAO.selectRemainRetry() } 바인드("+(index-1)+") : ["+ fileName +"]");
this.preparedStatement.setString(index++, today ); logger.debug("{ LogDAO.selectRemainRetry() } 바인드("+(index-1)+") : ["+ today +"]");
int remainRetry = -1; // 기본값 0
rs = executeQuery();
if (rs.next()) {
int val = rs.getInt("REMAIN_RETRY");
remainRetry = rs.wasNull() ? -1 : val;
}
logger.info("[ 남은 시도 횟수 ] ==> "+ remainRetry +" ["+ bjobMsgScheId +" / "+ fileName +"]");
return Math.max(remainRetry, 0);
} catch (DAOException ex) {
throw ex;
} catch (Exception ex) {
// TODO :: 에러 코드 새로 정의
String errMsg = ExceptionUtil.getErrorCode(ex, "BECEAICLG020", new String[] {bjobMsgScheId, bjobMsgScheId, fileName});
throw new DAOException(errMsg); //배치 DB로그 File 데이터 존재여부 조회시 오류가 발생하였습니다. [UUID: {1}] [SUB_UUID: {2}]
} finally {
disconnect();
}
}
}
@@ -475,4 +475,9 @@ public class LogManager
LogDAO dao = (LogDAO)DAOFactory.newInstance().create(LogDAO.class);
return dao.getFileLogSuccessCheck( procCode, instiCode, bizCode, fileName);
}
public int selectRemainRetry(BatchDoc msgDoc) throws Exception {
LogDAO dao = (LogDAO)DAOFactory.newInstance().create(LogDAO.class);
return dao.selectRemainRetry(msgDoc);
}
}
+22 -1
View File
@@ -335,5 +335,26 @@ public interface LogQuery
"AND SndrcvFileName = ? \n" +
"AND FileTrsmtStartHMS LIKE TO_CHAR( SYSDATE, 'YYYYMMDD' ) || '%' \n" +
"AND BjobPtrnDstcd IN ( 'AR', 'RR' ) \n" +
"AND ThisStgePrcssRsultCd = 'T' \n";
"AND ThisStgePrcssRsultCd = 'T' \n";
public static final String SELECT_REMAIN_RETRY =
"WITH DEFINED_RETRY AS ( \n" +
" SELECT RQSTRECVRETRALCNT AS CNT FROM " + Keys.TABLE_OWNER + "TSEAIBS01 \n" +
" WHERE TRIM(BJOBMSGSCHEID) = ? \n" +
") \n" +
"SELECT \n" +
" CASE \n" +
" WHEN COUNT(CASE WHEN J03.TRANPRCSSDSTCD = 'T' THEN 1 END) > 0 THEN 0 \n" +
" ELSE DR.CNT - COUNT(CASE WHEN J03.TRANPRCSSDSTCD = 'E' THEN 1 END) \n" +
" END AS REMAIN_RETRY \n" +
"FROM " + Keys.TABLE_OWNER + "TSEAIBJ03 J03 \n" +
"JOIN " + Keys.TABLE_OWNER + "TSEAIBJ08 J08 \n" +
" ON J08.BJOBDMNDMSGID = J03.BJOBDMNDMSGID \n" +
" AND J08.BJOBDMNDSUBMSGID = J03.BJOBDMNDSUBMSGID \n" +
"CROSS JOIN DEFINED_RETRY DR \n" +
"WHERE TRIM(J03.BJOBMSGSCHEID) = ? \n" +
"AND J08.SNDRCVFILENAME = ? \n" +
"AND J03.TRANSTARTHMS LIKE ? \n" +
"GROUP BY DR.CNT \n";
}
@@ -125,7 +125,7 @@ public class BatchRunningJobManager
+" / "+ batchDoc.getBatchMsg().getHeader().getProcessName()
+" / "+ batchDoc.getBatchMsg().getHeader().getInstitutionName()
+" / L="+ (service.getCurrentSocket() == null ? "" : service.getCurrentSocket().getLocalAddress().getHostAddress() +":"+ service.getCurrentSocket().getLocalPort())
+" / R="+ (service.getCurrentSocket() == null ? "" : service.getCurrentSocket().getInetAddress().getHostAddress() +":"+ service.getCurrentSocket().getPort())
+" / R="+ (service.getCurrentSocket() == null || service.getCurrentSocket().getInetAddress() == null ? "" : service.getCurrentSocket().getInetAddress().getHostAddress() +":"+ service.getCurrentSocket().getPort())
);
}else{
// UUID / 업무유형 / 업무구분 / 대외기관
@@ -1210,8 +1210,8 @@ public class SchedulerMessageDAO extends BaseDAO implements SchedulerMessageQuer
schedule.setSndrcvCyclTypName(rs.getString("SndrcvCyclTypName"));
schedule.setUapplCd (rs.getString("UapplCd" ));
schedule.setThisMsgChrgIDs (rs.getString("ThisMsgChrgIDs" ));
schedule.setSndrcvStartHMS (rs.getString("SndrcvStartHMS" ).trim());
schedule.setSndrcvEndHMS (rs.getString("SndrcvEndHMS" ).trim());
schedule.setSndrcvStartHMS (StringUtil.nvlTrim(rs.getString("SndrcvStartHMS" )));
schedule.setSndrcvEndHMS (StringUtil.nvlTrim(rs.getString("SndrcvEndHMS" )));
alist.add(schedule);
}
@@ -285,10 +285,14 @@ public class SchedulerMessageManager
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream (new FileInputStream(file));
bis.skip(countPos);
bis.read(countBuffer);
long skipped = bis.skip(countPos);
int readLen = bis.read(countBuffer);
if (skipped != countPos || readLen != countLen) {
throw new RuntimeException("데이터 건수 읽기 실패 - skip=" + skipped + "/" + countPos + ", read=" + readLen + "/" + countLen);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
continue;
}finally{
if ( bis != null )
bis.close();
@@ -52,7 +52,7 @@ public class TelegramDAO extends BaseDAO implements TelegramQuery
{
// telegramitem 순서값은 런타임시에는 사용하지 않는다. 대신 TelegramVO에서 item이 추가될때 순서를 부여한다.
// 이러한 이유는 TSEAIBM02에서 수정작업을 편하게 하도록 하기 위함이다.
TelegramItemVO itemVO = new TelegramItemVO(rs.getString(3).trim(), rs.getString(4).trim(), rs.getString(5).trim(), rs.getString(6).trim());
TelegramItemVO itemVO = new TelegramItemVO(StringUtil.nvlTrim(rs.getString(3)), StringUtil.nvlTrim(rs.getString(4)), StringUtil.nvlTrim(rs.getString(5)), StringUtil.nvlTrim(rs.getString(6)));
// 전문 필드중에 가변부가 있으면 전문의 variableFieldCheckTag를 true로 세팅한다.
if (StringUtil.nvlTrim(rs.getString(5)).trim().toUpperCase().equals("XX"))
+19 -10
View File
@@ -140,6 +140,7 @@ public class Logger implements LogKeys, Serializable {
//========================================================
PropManager pmanager = PropManager.getInstance();
Properties loggerInfo= pmanager.getProperties(LOGGER_INFO);
if (loggerInfo == null) throw new RuntimeException("Logger 프라퍼티 그룹 정보가 없습니다. - [" + LOGGER_INFO + "]");
String defaultLayout = loggerInfo.getProperty(PATTERN_LAYOUT);
//초기화시 메모리에 적재할 Logger 이름 리스트
String loggerList = loggerInfo.getProperty(INITIAL_LOGGER_LIST);
@@ -282,8 +283,8 @@ public class Logger implements LogKeys, Serializable {
}
} catch (Exception e) {
System.err.println("@@ Logger setLoggerLevel Error | "
+ loggerName + " | " + e.getMessage() );
// System.err.println("@@ Logger setLoggerLevel Error | "
// + loggerName + " | " + e.getMessage() );
}
}
@@ -303,6 +304,10 @@ public class Logger implements LogKeys, Serializable {
PropManager pmanager = PropManager.getInstance();
props = pmanager.getProperties(loggerName);
if (props == null) {
//기존과 동일하게 아래 catch에서 진단 메시지 출력 후 null 반환되도록 한다
throw new RuntimeException("Logger 프라퍼티 그룹 정보가 없습니다.");
}
String logLevel = props.getProperty( LOGGER_LEVEL);
String aditivity = props.getProperty( LOGGER_ADITIVITY);
@@ -338,8 +343,8 @@ public class Logger implements LogKeys, Serializable {
// if(fileLogger != null)
// fileLogger.setLoggerImpl(logger);
} catch (Exception e) {
System.err.println("@@ Logger Configure Error.===================");
System.err.println("@@ addFileAppender | " + loggerName + " | " + e.getMessage() );
// System.err.println("@@ Logger Configure Error.===================");
// System.err.println("@@ addFileAppender | " + loggerName + " | " + e.getMessage() );
logger = null;
}
@@ -361,6 +366,9 @@ public class Logger implements LogKeys, Serializable {
try {
PropManager pmanager = PropManager.getInstance();
props = pmanager.getProperties(appenderName);
if (props == null) {
throw new RuntimeException("FileAppender 프라퍼티 그룹 정보가 없습니다. - [" + appenderName + "]");
}
String logDirectory = props.getProperty(APPENDER_LOG_DIRECOTRY);
@@ -405,8 +413,8 @@ public class Logger implements LogKeys, Serializable {
appender.setName(appenderName);
} catch (Exception e) {
System.err.println("@@ Logger Configure Error.===================");
System.err.println("@@ addFileAppender | " + appenderName + " | " + e.getMessage() );
// System.err.println("@@ Logger Configure Error.===================");
// System.err.println("@@ addFileAppender | " + appenderName + " | " + e.getMessage() );
appender = null;
}
@@ -787,7 +795,7 @@ public class Logger implements LogKeys, Serializable {
String instLog = instInfo.getProperty(LogKeys.INST_LOG);
logger.debug("instlog processCode=["+processCode+"],institutionCode=["+institutionCode+"], instLog=["+instLog+"]");
if (logger != null) logger.debug("instlog processCode=["+processCode+"],institutionCode=["+institutionCode+"], instLog=["+instLog+"]");
if (!"Y".equalsIgnoreCase(instLog)) {
return;
@@ -802,7 +810,7 @@ public class Logger implements LogKeys, Serializable {
batchDoc.setLogger(Logger.getLogger(loggerName));
} catch (Exception e) {
logger.error("BatchDoc = " + batchDoc, e);
if (logger != null) logger.error("BatchDoc = " + batchDoc, e);
}
}
@@ -938,8 +946,9 @@ public class Logger implements LogKeys, Serializable {
if(logger != null)
logger.info(" - 배치 파일로거 '" + appenderName + "' Appender 생성됨.");
} catch (Exception ex) {
if(logger != null)
logger.error("Create Inst Logger Fail" + ex.getMessage());
if (logger != null) {
logger.error("Create Inst Logger Fail" + ex.getMessage(), ex);
}
}
}
@@ -54,9 +54,9 @@ public class CodeConversion
}
//System.out.println("[ Converted Bytes ]");
for(int i=0; i< bytes.length; i++) {
//for(int i=0; i< bytes.length; i++) {
//System.out.println("Byte["+i+"] = "+ printBit(bytes[i]) );
}
//}
}
catch(Exception e) {
//System.out.println(e.toString());
@@ -115,8 +115,8 @@ public class AppInitializer implements InitializingBean, DisposableBean {
System.out.println("==========================================================================");
System.out.println("# S U C C E S S : Batch System Configuration");
System.out.println("# Rule table Owner : "+tableOwner);
System.out.println("# Batch System Mode : "+systemMode);
//System.out.println("# Rule table Owner : "+tableOwner);
//System.out.println("# Batch System Mode : "+systemMode);
System.out.println("# Batch System Mode : [P(Product)/T(Test)/D(Develop)/S(Simulator)]");
System.out.println("==========================================================================");
@@ -125,36 +125,36 @@ public class AppInitializer implements InitializingBean, DisposableBean {
}
logger.debug("CodeMessageManager 메모리 로딩 시작 ------------------------------------------");
if (logger != null) logger.debug("CodeMessageManager 메모리 로딩 시작 ------------------------------------------");
try {
CodeMessageManager.getInstance().start();
} catch(LifecycleException e) {
logger.error( e.getMessage(), e);
if (logger != null) logger.error( e.getMessage(), e);
throw new RuntimeException(ExceptionUtil.getErrorCode(e,"BFCEAICWB001"));
}
logger.debug("CodeMessageManager 메모리 로딩 종료 ------------------------------------------");
if (logger != null) logger.debug("CodeMessageManager 메모리 로딩 종료 ------------------------------------------");
logger.debug("Property 메모리 로딩 시작 ------------------------------------------");
if (logger != null) logger.debug("Property 메모리 로딩 시작 ------------------------------------------");
try {
PropManager.getInstance().start();
} catch(LifecycleException e) {
logger.error( e.getMessage(), e);
if (logger != null) logger.error( e.getMessage(), e);
throw new RuntimeException(ExceptionUtil.getErrorCode(e,"BFCEAICWB001"));
}
logger.debug("Property 메모리 로딩 종료 ------------------------------------------");
if (logger != null) logger.debug("Property 메모리 로딩 종료 ------------------------------------------");
logger.debug("Logger 메모리 로딩 시작 ------------------------------------------");
if (logger != null) logger.debug("Logger 메모리 로딩 시작 ------------------------------------------");
try {
Logger.doConfigure();
} catch(Exception e) {
logger.error( e.getMessage(), e);
if (logger != null) logger.error( e.getMessage(), e);
}
logger.debug("Logger 메모리 로딩 종료 ------------------------------------------");
if (logger != null) logger.debug("Logger 메모리 로딩 종료 ------------------------------------------");
try {
SchedulerMessageManager.getInstance().deleteJobFromProcessing();
} catch (Exception e) {
logger.error(e.getMessage(), e);
if (logger != null) logger.error(e.getMessage(), e);
}
// try {
@@ -174,19 +174,19 @@ public class AppInitializer implements InitializingBean, DisposableBean {
// logger.error("RMSCLIENT AGENT CANNOT START ~~ !!!! - "+e.toString(),e);
// }
logger.debug("LifeCycle 관련 클래스 메모리 로딩 시작 ------------------------------------------");
if (logger != null) logger.debug("LifeCycle 관련 클래스 메모리 로딩 시작 ------------------------------------------");
LifecycleManager manager = LifecycleManager.getInstance();
if(manager instanceof Lifecycle) {
try {
manager.start();
} catch(LifecycleException e) {
logger.error( e.getMessage(), e);
if (logger != null) logger.error( e.getMessage(), e);
throw new RuntimeException(ExceptionUtil.getErrorCode(e,"BECEAICWB002"));
}
}
logger.debug("LifeCycle 관련 클래스 메모리 로딩 종료 ------------------------------------------");
logger.debug("배치 프레임웍 Application 초기화 종료!");
if (logger != null) logger.debug("LifeCycle 관련 클래스 메모리 로딩 종료 ------------------------------------------");
if (logger != null) logger.debug("배치 프레임웍 Application 초기화 종료!");
}
/**
@@ -202,7 +202,7 @@ public class AppInitializer implements InitializingBean, DisposableBean {
public void destroy()
{
Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
logger.debug("@ eLink Batch Application destroying.");
if (logger != null) logger.debug("@ eLink Batch Application destroying.");
LifecycleManager manager = LifecycleManager.getInstance();
@@ -225,7 +225,7 @@ public class AppInitializer implements InitializingBean, DisposableBean {
} catch ( Exception e ) {
throw new RuntimeException(ExceptionUtil.getErrorCode(e,"BECEAICWB005"));
}
logger.debug("\n\n");
if (logger != null) logger.debug("\n\n");
}
@Override
public void afterPropertiesSet() throws Exception {