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,19 @@
package com.eactive.eai.common.worker;
// SA 인터페이스 유형에서 요청에 대한 응답을 맞추기 위해 Outbound 인터페이스에서 사용하는 Worker Action
public interface Action {
// Action의 고유 ID를 반환
public String getId();
// Action의 고유 ID를 Setting하고, Action의 초기화
public void doInit(String id) throws ActionException;
// 요청에 대한 응답 메시지를 수신하기위한 전처리
public void doStart(Slot slot) throws ActionException;
// 초기화 로직에 대한 Undo 로직을 처리
public void doEnd() throws ActionException;
// 요청에 대한 응답 메시지를 받기 위한 초기화가 되었는지 Flag를 반환
public boolean isReady();
}
@@ -0,0 +1,11 @@
package com.eactive.eai.common.worker;
public class ActionException extends Exception {
public ActionException() {
super("ActionException is occured.");
}
public ActionException(String msg) {
super(msg);
}
}
@@ -0,0 +1,27 @@
package com.eactive.eai.common.worker;
import com.eactive.eai.common.util.Logger;
public abstract class ActionSupport implements Action {
protected boolean ready;
protected String id;
protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
public String getId() {
return this.id;
}
public boolean isReady() {
return this.ready;
}
public void doInit(String id) throws ActionException {
this.id = id;
logger.info("execute doInit... ");
}
public void doEnd() throws ActionException {
logger.info("execute doEnd... ");
}
}
@@ -0,0 +1,30 @@
package com.eactive.eai.common.worker;
public class Future {
private Object value;
private Slot slot; // shared with some worker
public Future() {
this.slot = new Slot();
}
public Slot getSlot() {
return this.slot;
}
public Object value() {
synchronized (slot) { // avoid race conditions!
if (value == null)
value = slot.get();
}
return value;
}
public Object value(long timeout) {
synchronized (slot) { // avoid race conditions!
if (value == null)
value = slot.get(timeout);
}
return value;
}
}
@@ -0,0 +1,192 @@
package com.eactive.eai.common.worker;
import java.lang.Thread.State;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import com.eactive.eai.common.jms.JmsServiceLocator;
import com.eactive.eai.common.util.ContainerUtil;
public class JMSListenerAction extends ActionSupport implements MessageListener {
private String topicConFactory;
private String topicName;
private int timeout;
private TopicConnectionFactory tconFactory;
private TopicConnection tcon;
private TopicSession tsession;
private TopicSubscriber tsubscriber;
private Topic topic;
private Slot slot;
public JMSListenerAction(String topicConFactory, String topicName, int timeout) {
this.topicConFactory = topicConFactory;
this.topicName = topicName;
this.timeout = timeout;
}
public void doStart(Slot slot) throws ActionException {
if (ContainerUtil.get() == ContainerUtil.WEBSPHERE) {
doStartForWebSphere(slot);
} else if (ContainerUtil.get() == ContainerUtil.WEBLOGIC) {
doStartForWeblogic(slot);
} else {
doStartForWeblogic(slot);
}
}
public void doStartForWeblogic(Slot slot) throws ActionException {
this.slot = slot;
try {
JmsServiceLocator slocator = JmsServiceLocator.getInstance();
tconFactory = (TopicConnectionFactory) slocator.getTopicConnectionFactory(this.topicConFactory);
tcon = tconFactory.createTopicConnection();
tsession = tcon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
topic = (Topic) slocator.getTopic(this.topicName);
tsubscriber = tsession.createSubscriber(topic, "JMSCorrelationID = '" + id + "'", true);
tsubscriber.setMessageListener(this);
tcon.start();
this.ready = true;
} catch (Exception e) {
this.ready = false;
this.doEnd();
throw new ActionException("ResponseTopic에 응답메시지를 수신하기 위한 JMSListener를 초기화 하지 못했습니다.");
}
}
public void doStartForWebSphere(Slot slot) throws ActionException {
this.slot = slot;
int retryCount = 0;
try {
if (logger.isWarn())
logger.warn("start correlationID[" + id + "]");
JmsServiceLocator slocator = JmsServiceLocator.getInstance();
tconFactory = (TopicConnectionFactory) slocator.getTopicConnectionFactory(this.topicConFactory);
if (tconFactory == null)
throw new Exception("tconFactory not found - " + this.topicConFactory);
while (retryCount < 3) {
try {
tcon = tconFactory.createTopicConnection();
} catch (Exception ex) {
retryCount++;
if (retryCount < 3) {
// if(logger.isWarn())
logger.error("correlationID[" + id + "] retry count=" + retryCount);
continue;
}
throw ex;
}
if (tcon != null)
break;
}
tsession = tcon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
topic = (Topic) slocator.getTopic(this.topicName);
tsubscriber = tsession.createSubscriber(topic, "JMSCorrelationID = '" + id + "'", true);
tcon.start();
Thread receiverThread = new Thread(new Runnable() {
@Override
public void run() {
if (logger.isWarn())
logger.warn("run correlationID[" + id + "]");
long startTime = System.currentTimeMillis();
Message msg = null;
if (logger.isInfo())
logger.info("executing. - " + id);
try {
msg = tsubscriber.receive(timeout + (10 * 1000L));
if (logger.isInfoEnabled())
logger.info("receive JMSCorrelationID=" + id + ", message=" + msg);
if (logger.isWarn())
logger.warn("receive correlationID[" + id + "]");
if (msg instanceof ObjectMessage) {
ObjectMessage omsg = (ObjectMessage) msg;
Object value = omsg.getObject();
slot.put(value);
}
if (logger.isWarn())
logger.warn("slot.put correlationID[" + id + "]");
} catch (Exception e) {
logger.error("JMSListenerAction Error", e);
}
long endTime = System.currentTimeMillis();
if (logger.isInfo())
logger.info(id + " >> ELAPSE TIME : " + (endTime - startTime) / 1000.);
}
});
receiverThread.setName("JMSTopicReceiver");
receiverThread.setPriority(Thread.MAX_PRIORITY);
receiverThread.start();
int i = 0;
while (true) {
State s = receiverThread.getState();
if (s == Thread.State.TIMED_WAITING || i > 100) {
if (i > 100) {
logger.error("JMSListenerAction] receiverThread state = " + s.toString() + ",count=" + i);
} else if (100 >= i && i > 0) {
logger.info("JMSListenerAction] receiverThread state = " + s.toString() + ",count=" + i);
}
break;
}
Thread.sleep(10L);
i++;
}
this.ready = true;
} catch (Exception e) {
this.ready = false;
this.doEnd();
logger.error("ResponseTopic에 응답메시지를 수신하기 위한 JMSListener를 초기화 하지 못했습니다.topicConFactory="
+ this.topicConFactory + ", topic=" + topicName + ", " + e.getMessage(), e);
throw new ActionException("ResponseTopic에 응답메시지를 수신하기 위한 JMSListener를 초기화 하지 못했습니다.");
}
}
public void doEnd() {
try {
if (tsubscriber != null)
tsubscriber.close();
} catch (Exception e) {
}
try {
if (tsession != null)
tsession.close();
} catch (Exception e) {
}
try {
if (tcon != null)
tcon.close();
} catch (Exception e) {
}
}
public void onMessage(Message msg) {
long startTime = System.currentTimeMillis();
if (logger.isInfo())
logger.info("executing. - " + id);
try {
if (msg instanceof ObjectMessage) {
ObjectMessage omsg = (ObjectMessage) msg;
Object value = omsg.getObject();
this.slot.put(value);
}
} catch (Exception e) {
logger.error("JMSListenerAction Error - " + e.getMessage());
}
long endTime = System.currentTimeMillis();
if (logger.isInfo())
logger.info(id + " >> ELAPSE TIME : " + (endTime - startTime) / 1000.);
}
}
@@ -0,0 +1,38 @@
package com.eactive.eai.common.worker;
import java.util.concurrent.ConcurrentHashMap;
public class ResponseMap {
private volatile static ResponseMap singleton;
private static ConcurrentHashMap<String, Future> responseMap = new ConcurrentHashMap<String, Future>();
private ResponseMap() {
// System.out.println("Create ResponseMap...");
}
public static ResponseMap getInstance() {
if (singleton == null) {
synchronized (ResponseMap.class) {
if (singleton == null) {
singleton = new ResponseMap();
}
}
}
return singleton;
}
public void put(String key, Future future) {
responseMap.put(key, future);
}
public Future get(String key) {
return responseMap.remove(key);
}
public boolean containsKey(String key) {
return responseMap.containsKey(key);
}
}
@@ -0,0 +1,49 @@
package com.eactive.eai.common.worker;
public class Slot {
private Object slotVal;
public synchronized void put(Object val) {
while (slotVal != null) {
try {
wait();
} catch (InterruptedException e) {
;
}
}
slotVal = val;
notifyAll();
}
public synchronized Object get() {
Object rval;
while (slotVal == null) {
try {
if (slotVal == null)
wait();
} catch (InterruptedException e) {
break;
}
}
rval = slotVal;
slotVal = null;
notifyAll();
return rval;
}
public synchronized Object get(long timeout) {
Object rval;
try {
if (slotVal == null)
wait(timeout);
} catch (InterruptedException e) {
rval = slotVal;
}
rval = slotVal;
slotVal = null;
notifyAll();
return rval;
}
}