init
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user