This commit is contained in:
Rinjae
2025-09-05 18:57:45 +09:00
commit aacc1a389e
1229 changed files with 167963 additions and 0 deletions
@@ -0,0 +1,15 @@
package com.eactive.eai.common.testcall;
import com.eactive.eai.adapter.AdapterVO;
/*
* TestCallRunner가 일정 주기로 TestCall의 isAlive() 메서드를 실행하여 결과가 true일 경우 해당 어댑터의 상태를 true로 변경한다.
* Recovery 통신 테스트 로직을 isAlive() 메서드에 구현한다.
*/
public interface TestCall {
public AdapterVO getAdapterInfo();
public void setAdapterInfo(AdapterVO adapterInfo);
public boolean isAlive() throws TestCallException;
}
@@ -0,0 +1,17 @@
package com.eactive.eai.common.testcall;
public class TestCallException extends Exception {
private static final long serialVersionUID = 1L;
public TestCallException() {
super("TestCallException is occured.");
}
public TestCallException(String msg) {
super(msg);
}
public TestCallException(String msg, Throwable t) {
super(msg, t);
}
}
@@ -0,0 +1,167 @@
package com.eactive.eai.common.testcall;
import java.util.Iterator;
import java.util.Timer;
import java.util.concurrent.ConcurrentHashMap;
import com.eactive.eai.adapter.AdapterVO;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.lifecycle.Lifecycle;
import com.eactive.eai.common.lifecycle.LifecycleException;
import com.eactive.eai.common.lifecycle.LifecycleListener;
import com.eactive.eai.common.lifecycle.LifecycleSupport;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger;
public class TestCallManager implements Lifecycle {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
public static final String PROP_GROUP = "TestCallManager";
// TestCallManager에서 사용하는 Property Key : TestCallRunner의 동작 주기
public static final String PROP_PERIOD = "testcall.runner.period";
// TestCallManager에서 사용하는 Property Key : TestCallRunner의 응답 타입
public static final String RESPONSE_TYPE = "RESPONSE_TYPE";
// TestCallManager에서 사용하는 Property Key : TestCallRunner의 HTTP 응답 타임 아웃
public static final String HTTP_TIME_OUT = "HTTP_TIME_OUT";
// TestCallManager에서 사용하는 Property Key : TestCallRunner의 HTTP 접속 타임 아웃
public static final String CONNECTION_TIMEOUT = "CONNECTION_TIMEOUT";
/**
* TestCallManager에서 사용하는 Property Key : TestCallRunner의 TESTCALL 여부 "Y" 이면 테스트콜
* 거래 로그 안찍힘 "N" 면 테스트콜 거래 로그 찍힘
*/
public static final String TESTCALL_YN = "TESTCALL_YN";
// TestCallManager에서 사용하는 Property Key : TestCallRunner의 요청 메시지
public static final String REQUEST_MESSAGE = "REQUEST_MESSAGE";
// TestCallManager에서 사용하는 Property Key : TestCallRunner의 응답 메시지
public static final String RESPONSE_MESSAGE = "RESPONSE_MESSAGE";
private static TestCallManager manager = new TestCallManager();
private LifecycleSupport lifecycle = new LifecycleSupport(this);
private boolean started;
private ConcurrentHashMap<String, TestCall> testers = new ConcurrentHashMap<>();
private TestCallRunner runner;
private Timer timer;
public static TestCallManager getInstance() {
return manager;
}
public void start() throws LifecycleException {
if (started)
throw new LifecycleException("RECEAICTM001");
lifecycle.fireLifecycleEvent(STARTING_EVENT, this);
PropManager pmanager = PropManager.getInstance();
// default 10 mins
long period = 1000 * 600;
try {
period = Long.parseLong(pmanager.getProperty(PROP_GROUP, PROP_PERIOD));
} catch (Exception e) {
logger.info("PROP_PERIOD not number");
}
this.runner = new TestCallRunner();
this.runner.setTestCallManager(this);
this.timer = new Timer("TestCallTimer");
this.timer.schedule(this.runner, period, period);
started = true;
lifecycle.fireLifecycleEvent(STARTED_EVENT, this);
}
public void stop() throws LifecycleException {
if (!started)
throw new LifecycleException("RECEAICTM002");
lifecycle.fireLifecycleEvent(STOPING_EVENT, this);
this.timer.cancel();
this.timer = null;
this.runner = null;
if (this.testers != null) {
this.testers.clear();
this.testers = null;
}
started = false;
lifecycle.fireLifecycleEvent(STOPPED_EVENT, null);
}
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
public LifecycleListener[] findLifecycleListeners() {
return lifecycle.findLifecycleListeners();
}
public void removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
}
public boolean isStarted() {
return this.started;
}
public void addTester(AdapterVO vo) throws TestCallException {
if (vo.getTestCallClass() == null)
throw new TestCallException("RECEAICTM005");
Class<?> tclass = null;
if (!started) {
logger.error("TesterManager] TesterManager is stopped");
}
try {
tclass = Class.forName(vo.getTestCallClass());
} catch (Exception e) {
logger.error("TesterManager] addTester Error. [" + vo.getAdapterGroupName() + "][" + vo.getName() + "]["
+ vo.getTestCallClass() + "]", e);
throw new TestCallException(ExceptionUtil.getErrorCode(e, "RECEAICTM003"), e);
}
try {
TestCall tester = (TestCall) tclass.newInstance();
tester.setAdapterInfo(vo);
if (this.testers != null && vo != null) {
this.testers.put(vo.getAdapterGroupName() + "-" + vo.getName(), tester);
}
} catch (Exception e) {
logger.error("TesterManager] addTester Error. [" + vo.getAdapterGroupName() + "][" + vo.getName() + "]["
+ vo.getTestCallClass() + "]", e);
throw new TestCallException(ExceptionUtil.getErrorCode(e, "RECEAICTM004"));
}
}
public Iterator<String> getAllAdapterNames() {
ConcurrentHashMap<String, TestCall> map = new ConcurrentHashMap<>(testers);
return map.keySet().iterator();
}
public TestCall getTestCall(String adapterName) {
return this.testers.get(adapterName);
}
public void removeTestCall(String adapterName) {
this.testers.remove(adapterName);
}
public int getTestCallCount() {
return this.testers.size();
}
}
@@ -0,0 +1,68 @@
package com.eactive.eai.common.testcall;
import java.util.Iterator;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.eactive.eai.adapter.AdapterVO;
import com.eactive.eai.common.errorcode.ErrorCodeHandler;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.util.Logger;
public class TestCallRunner extends TimerTask {
static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
private TestCallManager manager;
// TestCallRunner 동작 시 INFO 메시지에 대한 코드
private static final String START_MSGCODE = "RICEAICTR001";
// TestCallRunner 동작 시 발생되는 오류에 대한 코드
private static final String ERROR_MSGCODE = "RECEAICTR002";
public void setTestCallManager(TestCallManager manager) {
this.manager = manager;
}
public void run() {
String msg = ErrorCodeHandler.getMessage(START_MSGCODE, new String[] { Thread.currentThread().getName() });
logger.warn("TestCallRunner] " + msg);
if (this.manager == null || !this.manager.isStarted()) {
logger.warn("TestCallManager is stopped. stop TestCallRunner.");
return;
}
Iterator<String> adapterNames = manager.getAllAdapterNames();
ExecutorService executor = Executors.newFixedThreadPool(10);
try {
while (adapterNames.hasNext()) {
String name = adapterNames.next();
TestCall testObj = manager.getTestCall(name);
AdapterVO vo = testObj.getAdapterInfo();
if (testObj == null || vo.isStatus()) {
manager.removeTestCall(name);
continue;
}
executor.submit(() -> {
try {
if (testObj.isAlive()) {
manager.removeTestCall(name);
vo.setStatus(true);
}
} catch (Exception e) {
String[] args = { testObj.getAdapterInfo().toString(), e.getMessage() };
if (logger.isError()) {
logger.error(ExceptionUtil.make(ERROR_MSGCODE, args), e);
}
}
});
}
}
finally {
executor.shutdown();
}
}
}
@@ -0,0 +1,19 @@
package com.eactive.eai.common.testcall;
import com.eactive.eai.adapter.AdapterVO;
public class TestCallSupport implements TestCall {
protected AdapterVO adapterInfo;
public boolean isAlive() throws TestCallException {
return false;
}
public void setAdapterInfo(AdapterVO adapterInfo) {
this.adapterInfo = adapterInfo;
}
public AdapterVO getAdapterInfo() {
return this.adapterInfo;
}
}