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,10 @@
package com.eactive.eai.flowcontrol.action;
public interface RouteAction {
/**
* EAI 서비스코드별 Routing 정보를 위한 값을 추출하는 기능을 수행한다.
*/
public String[] getRouteKeys(byte[] message) throws Exception;
public String getDescription();
}
@@ -0,0 +1,11 @@
package com.eactive.eai.flowcontrol.action;
public class RouteActionException extends Exception {
public RouteActionException() {
super("RouteActionException is occured.");
}
public RouteActionException(String msg) {
super(msg);
}
}
@@ -0,0 +1,20 @@
package com.eactive.eai.flowcontrol.action;
import com.eactive.eai.common.util.Logger;
public class RouteActionFactory {
static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
public static RouteAction createAction(String actionName) throws RouteActionException {
RouteAction action = null;
try {
Class cl = Class.forName(actionName);
action = (RouteAction)cl.newInstance();
} catch(Exception e) {
logger.error("Cannot create a RouteAction.", e);
throw new RouteActionException("Cannot create a RouteAction. - "+actionName);
}
return action;
}
}
@@ -0,0 +1,84 @@
package com.eactive.eai.flowcontrol.action;
import com.eactive.eai.common.util.Logger;
public class RouteActionSupport implements RouteAction {
static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
public String[] getRouteKeys(byte[] message) throws Exception {
String[] keys = null;
return keys;
}
public int strncmp(String src, String value, int length) {
int result = -1;
if(src == null || value == null) {
return -1;
}
if(src.length() < length) {
return -1;
}
if(src.startsWith(value)) {
result = 0;
}
return result;
}
public String strncpy(String src, String value, int startPos) {
if(value == null || value.length() < 1) {
return src;
}
StringBuffer sb = new StringBuffer();
sb.append(src.substring(0,startPos));
sb.append(value);
sb.append( src.substring(startPos+value.length()) );
return sb.toString();
}
public String strncpy(byte[] src, int startPos, int length) {
if(src == null || src.length <(startPos + length)) {
return "";
}
byte[] resBytes = new byte[length];
System.arraycopy(src, startPos, resBytes, 0, resBytes.length );
return new String(resBytes);
}
public boolean bytesncmp(byte[] src, int startPos, String value) {
if(value == null || value.length() < 1) {
return false;
}
byte[] valueBytes = value.getBytes();
int valueBytesLength = valueBytes.length;
if(src == null || src.length <(startPos + valueBytesLength)) {
return false;
}
byte[] cmpareBytes = new byte[valueBytesLength];
System.arraycopy(src, startPos, cmpareBytes, 0, cmpareBytes.length );
if(value.equals(new String(cmpareBytes))) {
return true;
}
return false;
}
public String getDescription() {
return "";
}
}
@@ -0,0 +1,132 @@
package com.eactive.eai.flowcontrol.activemq;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.routing.ElinkESBProcessProxy;
import com.eactive.eai.common.routing.RoutingManager;
import com.eactive.eai.common.routing.RoutingVO;
import com.eactive.eai.common.util.Logger;
import javax.jms.*;
import java.util.Enumeration;
import java.util.Properties;
import java.lang.IllegalStateException;
public class DefaultQueueConsumer implements Runnable, ExceptionListener {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
Connection connection = null;
Session session = null;
MessageConsumer consumer = null;
String name = null;
String queue = null;
boolean run = true;
public DefaultQueueConsumer(String name, Connection con, String queue) {
this.connection = con;
try {
this.name = name;
this.queue = queue;
connection.start();
connection.setExceptionListener(this);
// Create a Session
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create the destination (Topic or Queue)
Destination destination = session.createQueue(queue);
consumer = session.createConsumer(destination);
} catch (JMSException e) {
logger.error(e);
}
}
@Override
public void run() {
EAIMessage eaiMessage = null;
while(run) {
try {
Message message = consumer.receive(2000);
ObjectMessage omsg = null;
if(message == null) {
// logger.warn(name + " -> EMPTY MESSAGE...");
continue;
}
if(message instanceof ObjectMessage) {
omsg = (ObjectMessage)message;
} else {
throw new RuntimeException(name+" Invlid JMS Message Type. - "+message);
}
try {
eaiMessage = (EAIMessage)omsg.getObject();
} catch(Exception e) {
throw new RuntimeException(name+" Invlid value object in ObjectMessage. - "+e.getMessage() );
}
RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm());
String serviceURI = routingVO.getSyncRoutingPath();
boolean isLocal = true;
Properties prop = new Properties();
try {
Enumeration en = omsg.getPropertyNames();
for (; en.hasMoreElements(); ) {
String propName = (String)en.nextElement();
try {
String propValue = omsg.getStringProperty(propName);
prop.setProperty(propName, propValue);
} catch (MessageFormatException e) {
prop.put(propName, omsg.getObjectProperty(propName));
}
}
} catch(JMSException e) {
throw new RuntimeException(name+" onMessage Error. - "+e.getMessage());
}
try {
logger.debug("ActiveMQ Receiver : " + eaiMessage);
eaiMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal, prop);
} catch(Exception e) {
throw new RuntimeException(name+" onMessage Error. - "+e.getMessage());
}
}
catch(IllegalStateException ise) {
logger.error(name+" IllegalStateException = " + ise.getMessage(), ise);
}
catch(JMSException e) {
logger.error(name+" JMSException = " + e.getMessage(), e);
run = false;
}
catch(RuntimeException e) {
logger.error(name+" RuntimeException = " + e.getMessage(), e);
}
}
}
public void stop() {
run = false;
if(consumer != null)
try {
consumer.close();
} catch (JMSException e) { }
if(session != null)
try {
session.close();
} catch (JMSException e) { }
if(connection != null)
try {
connection.close();
} catch (JMSException e) { }
}
@Override
public void onException(JMSException arg0) {
logger.error("JMS Exception occured. Shutting down client.");
stop();
}
}
@@ -0,0 +1,120 @@
package com.eactive.eai.flowcontrol.activemq;
import com.eactive.eai.common.util.Logger;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import javax.jms.Connection;
import javax.jms.Session;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class QueueConsumerService implements InitializingBean, DisposableBean {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
// uri = "vm://localhost?broker.persistent=false&broker.useJmx=false"
// uri = "tcp://localhost:61617""
private String uri;
private String queue;
private int maxThread;
Connection connection = null;
Session[] sessions = null;
DefaultQueueConsumer[] consumers = null;
ExecutorService es = null;
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getQueue() {
return queue;
}
public void setQueue(String queue) {
this.queue = queue;
}
public int getMaxThread() {
return maxThread;
}
public void setMaxThread(int maxThread) {
this.maxThread = maxThread;
}
@Override
public void afterPropertiesSet() throws Exception {
startConsumer();
}
@Override
public void destroy() throws Exception {
stopConsumer();
}
public void startConsumer() {
try {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(uri);
connectionFactory.setTrustAllPackages(true);
es = Executors.newFixedThreadPool(maxThread);
connection = connectionFactory.createConnection();
connection.start();
consumers = new DefaultQueueConsumer[maxThread];
for(int i=0; i<maxThread; i++) {
DefaultQueueConsumer consumer = new DefaultQueueConsumer("AMQ-" +i, connection, queue);
es.submit(consumer);
consumers[i] = consumer;
}
logger.info("Start ActiveMQ QueueListener [ uri=" + uri +
", queue="+queue + ", maxthread=" + maxThread+"] and wait for listening");
}
catch(Exception ex) {
logger.error("startConsumer error", ex);
}
}
public void stopConsumer() {
for(int i=0; i<maxThread; i++) {
try {
consumers[i].stop();
} catch (Exception e) {
logger.warn(e.getMessage());
}
}
if(es != null) {
es.shutdown();
}
es = null;
}
// public static void main(String args[]) throws Exception {
// test();
//}
// private static void test() throws Exception {
// QueueConsumerService service = new QueueConsumerService();
// service.setUri("vm://localhost?broker.persistent=false&broker.useJmx=false");
// service.setQueue("TESTQ1");
// service.setMaxThread(10);
// service.startConsumer();
//
// Thread.sleep(2 * 1000);
//
// service.stopConsumer();
//
// Thread.sleep(2 * 1000);
// }
}
@@ -0,0 +1,129 @@
package com.eactive.eai.flowcontrol.jeus;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.routing.ElinkESBProcessProxy;
import com.eactive.eai.common.routing.RoutingManager;
import com.eactive.eai.common.routing.RoutingVO;
import com.eactive.eai.common.util.Logger;
import javax.jms.*;
import java.util.Enumeration;
import java.util.Properties;
import java.lang.IllegalStateException;
public class DefaultQueueConsumer implements Runnable, ExceptionListener {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
Connection connection = null;
Session session = null;
MessageConsumer consumer = null;
String name = null;
String queue = null;
boolean run = true;
public DefaultQueueConsumer(String name, Connection con, String queue) {
this.connection = con;
try {
this.name = name;
this.queue = queue;
connection.start();
connection.setExceptionListener(this);
// Create a Session
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create the destination (Topic or Queue)
Destination destination = session.createQueue(queue);
consumer = session.createConsumer(destination);
} catch (JMSException e) {
e.printStackTrace();
}
}
@Override
public void run() {
EAIMessage eaiMessage = null;
while(run) {
try {
Message message = consumer.receive(2000);
ObjectMessage omsg = null;
if(message == null) {
// logger.warn(name + " -> EMPTY MESSAGE...");
continue;
}
if(message instanceof ObjectMessage) {
omsg = (ObjectMessage)message;
} else {
throw new RuntimeException(name+" Invlid JMS Message Type. - "+message);
}
try {
eaiMessage = (EAIMessage)omsg.getObject();
} catch(Exception e) {
throw new RuntimeException(name+" Invlid value object in ObjectMessage. - "+e.getMessage() );
}
RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm());
String serviceURI = routingVO.getSyncRoutingPath();
boolean isLocal = true;
Properties prop = new Properties();
try {
Enumeration en = omsg.getPropertyNames();
for (; en.hasMoreElements(); ) {
String propName = (String)en.nextElement();
String propValue = omsg.getStringProperty(propName);
prop.setProperty(propName, propValue);
}
} catch(JMSException e) {
throw new RuntimeException(name+" onMessage Error. - "+e.getMessage());
}
try {
logger.debug("JEUS JMS Receiver : " + eaiMessage);
eaiMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal, prop);
} catch(Exception e) {
throw new RuntimeException(name+" onMessage Error. - "+e.getMessage());
}
}
catch(IllegalStateException ise) {
logger.error(name+" IllegalStateException = " + ise.getMessage(), ise);
}
catch(JMSException e) {
logger.error(name+" JMSException = " + e.getMessage(), e);
run = false;
}
catch(RuntimeException e) {
logger.error(name+" RuntimeException = " + e.getMessage(), e);
}
}
}
public void stop() {
run = false;
if(consumer != null)
try {
consumer.close();
} catch (JMSException e) { }
if(session != null)
try {
session.close();
} catch (JMSException e) { }
if(connection != null)
try {
connection.close();
} catch (JMSException e) { }
}
@Override
public void onException(JMSException arg0) {
logger.error("JMS Exception occured. Shutting down client.");
stop();
}
}
@@ -0,0 +1,103 @@
package com.eactive.eai.flowcontrol.jeus;
import com.eactive.eai.common.util.Logger;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import javax.jms.Connection;
import javax.jms.QueueConnectionFactory;
import javax.jms.Session;
import javax.naming.InitialContext;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class QueueConsumerService implements InitializingBean, DisposableBean {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
private String uri;
private String queue;
private int maxThread;
Connection connection = null;
Session[] sessions = null;
DefaultQueueConsumer[] consumers = null;
public final static String JNDI_FACTORY = "";
ExecutorService es = null;
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getQueue() {
return queue;
}
public void setQueue(String queue) {
this.queue = queue;
}
public int getMaxThread() {
return maxThread;
}
public void setMaxThread(int maxThread) {
this.maxThread = maxThread;
}
@Override
public void afterPropertiesSet() throws Exception {
startConsumer();
}
@Override
public void destroy() throws Exception {
stopConsumer();
}
public void startConsumer() {
try {
InitialContext ctx = new InitialContext();
QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx.lookup(uri);
es = Executors.newFixedThreadPool(maxThread);
connection = connectionFactory.createConnection();
connection.start();
consumers = new DefaultQueueConsumer[maxThread];
for(int i=0; i<maxThread; i++) {
DefaultQueueConsumer consumer = new DefaultQueueConsumer("JEUSJMS-" +i, connection, queue);
es.submit(consumer);
consumers[i] = consumer;
}
logger.info("Start JEUS JMS QueueListener [ uri=" + uri +
", queue="+queue + ", maxthread=" + maxThread+"] and wait for listening");
}
catch(Exception ex) {
ex.printStackTrace();
}
}
public void stopConsumer() {
for(int i=0; i<maxThread; i++) {
try {
consumers[i].stop();
} catch (Exception e) {
logger.warn(e.getMessage());
}
}
if(es != null) {
es.shutdown();
}
es = null;
}
}
@@ -0,0 +1,635 @@
package com.eactive.eai.flowcontrol.jms;
import java.util.Enumeration;
import java.util.Properties;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnectionFactory;
import com.eactive.eai.common.activemq.AmqPooledConnectionFactory;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.logger.EAILogSender;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.routing.ElinkESBProcessProxy;
import com.eactive.eai.common.routing.RoutingManager;
import com.eactive.eai.common.routing.RoutingVO;
import com.eactive.eai.common.util.JMSSender;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.MessageUtil;
import com.ext.eai.common.stdmessage.STDMessageKeys;
public class FCActiveMqReceiver {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
// ------------------------------------
// Rule Var
// ------------------------------------
private String receiverName;
private String queueName;
private String errorQueueName;
private int receiverCount;
private int errorDelayTimeMs;
private int retryCount;
private String messageSelector = "";
private String description;
// ------------------------------------
// Used for Test
// ------------------------------------
public static boolean isSingleApplication = false;
// ------------------------------------
// Objects needed for RabbitMQ clients
// ------------------------------------
private ActiveMQConnectionFactory factory;
private Connection[] connection;
private ReceiverObject[] receiverObj = null;
// ------------------------------------
// Thread Runtime Info
// ------------------------------------
private Thread[] receiverThread = null;
private boolean[] threadDowned = null;
public boolean allThreadDowned = true;
// ------------------------------------
// private static String instid = "11";
// static {
// String serverName = System.getProperty(Keys.WLI_SERVER_KEY);
// if(serverName != null && serverName.length() > 2) {
// instid = serverName.substring(serverName.length()-2, serverName.length());
// }
// }
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[ FCActiveMqReceiver INFO ]");
sb.append("\nReveciver Name = " + this.receiverName);
sb.append(", Queue Name = " + this.queueName);
sb.append(", Error Queue Name = " + this.errorQueueName);
sb.append(", Recever Count = " + this.receiverCount);
sb.append(", Delay Time(ms) = " + this.errorDelayTimeMs);
sb.append(", Retry Count = " + this.retryCount);
sb.append(", Selector = " + this.messageSelector);
sb.append(", Description = " + this.description);
return sb.toString();
}
public FCActiveMqReceiver(String rcvName, String qname, String errorqname, int rcvCount, int delayMs, int retryCnt,
boolean isTx, int ackMode, String msgSelector, String descr) throws Exception {
queueName = qname;
errorQueueName = errorqname;
receiverName = rcvName;
receiverCount = rcvCount;
errorDelayTimeMs = delayMs;
retryCount = retryCnt;
messageSelector = msgSelector;
description = descr;
// trim space
if (queueName != null)
queueName = queueName.trim();
if (errorQueueName != null)
errorQueueName = errorQueueName.trim();
if (receiverName != null)
receiverName = receiverName.trim();
if (messageSelector != null)
messageSelector = messageSelector.trim();
// this.isTx = isTx;
threadDowned = new boolean[receiverCount];
connection = new Connection[receiverCount];
receiverObj = new ReceiverObject[receiverCount];
receiverThread = new Thread[receiverCount];
String clientId = receiverName;
String connectionUrl = AmqPooledConnectionFactory.CONNECTION_URI;
if (logger.isInfo())
logger.info("FCActiveMqReceiver Connection : " + connectionUrl);
try {
factory = new ActiveMQConnectionFactory(connectionUrl);
factory.setTrustAllPackages(true);
// Create the connections
for (int i = 0; i < receiverCount; i++) {
// create each connection
connection[i] = factory.createConnection();
// clientId = receiverName + instid + "-" + i;
// clientId = receiverName + "-" + i;
receiverObj[i] = new ReceiverObject(rcvName, i, connection[i], queueName, this.messageSelector,
this.errorQueueName, this.errorDelayTimeMs, this.retryCount, connectionUrl);
receiverObj[i].setName(clientId);
if (logger.isDebug())
logger.debug("[" + new java.util.Date() + "] Receiver Thread : [" + clientId + "] " + queueName);
receiverThread[i] = new Thread(receiverObj[i]);
receiverThread[i].setDaemon(true);// avoids thread leaks if
receiverThread[i].start();
}
} catch (Exception e) {
if (logger.isError())
logger.error(" Exception while in constructor : ", e);
close();
throw e;
}
}
/**
* Start receiving for all receivers
*/
public synchronized void startReceiving() throws Exception {
if (!allThreadDowned) {
throw new Exception("Thread Started Already !");
}
try {
allThreadDowned = false;
} catch (Exception jmse) {
if (logger.isError()) {
logger.error("FCQueueReceiver: JMSException while in startReceiving() method : ", jmse);
}
close();
throw jmse;
}
}
/**
* Clear any messages received after the connection was started but before the
* user starts the test.
*/
public synchronized void clearReceived() {
// Clear Counter
for (int i = 0; i < receiverObj.length; i++) {
receiverObj[i].clearCount();
}
}
/**
* Stop sending for all Receiver threads
*/
public synchronized void stopReceiving() {
// Cleanup each ReceiverObj (stops sending and causes thread to exit)
for (int i = 0; i < receiverObj.length; i++) {
// stops each ReceiverObject
if (receiverObj[i] != null)
receiverObj[i].stopReceiver();
receiverObj[i].stopThread();
}
}
public String[][] getStatus() {
String[][] receiveStatus = new String[receiverObj.length][4];
for (int i = 0; i < receiverObj.length; i++) {
if (receiverObj[i] != null) {
receiveStatus[i][0] = receiverObj[i].getName();
receiveStatus[i][1] = "" + receiverObj[i].msgCounter;
receiveStatus[i][2] = "" + receiverObj[i].msgSuccessCounter;
receiveStatus[i][3] = "" + receiverObj[i].receiverStatus;
}
}
return receiveStatus;
}
public String[] getMessageCount() {
String[] receiveStatus = new String[2];
int receivedTotal = 0;
int successTotal = 0;
for (int i = 0; i < receiverObj.length; i++) {
if (receiverObj[i] != null) {
receivedTotal += receiverObj[i].msgCounter;
successTotal += receiverObj[i].msgSuccessCounter;
}
}
receiveStatus[0] = "" + receivedTotal;
receiveStatus[1] = "" + successTotal;
return receiveStatus;
}
/**
* Closes all connections which in turn stops the receivers and close
*/
public void close() {
// Close all the connections
for (int i = 0; i < connection.length; i++) {
try {
if (connection[i] != null)
connection[i].close();
} catch (Exception ex) {
if (logger.isError()) {
logger.error("In close(): Caught Exception trying to close connection(s)", ex);
}
}
}
}
// ////////////////////////////////////////////////////////////////////////
/**
* Inner class: ReceiverObject is an ASYNCHRONOUS receiver.
*/
// ////////////////////////////////////////////////////////////////////////
private class ReceiverObject extends Thread implements ExceptionListener {
private String recvName = null;
private String queueName = null;
// Channel
private Connection connection = null;
Session session = null;
MessageConsumer consumer = null;
private int id; // identifies the ReceiverObject
private int msgCounter = 0; // keeps track of messages
private int msgSuccessCounter = 0;
private int receiverStatus = 0; // 0 - wait, 1 - running, 2 - retry
private Object lockCounter = new Object();// used to synchronize
// updates of the message
// counter
private boolean keepRunning = false; // used to exit the sending loop
// in the run method
private String messageSelector = "";
private String errorQueueName = "";
private int errorDelayTimeMs = 0;
private int retryCount = 0;
private String queueConFactory = "";
/**
* Construct a ReceiverObject param id - the id number should be unique for each
* ReceiverObject param sess - the session object under which the receiver is
* created param q - the Queue object to receiver from
*/
public ReceiverObject(String recvName, int id, Connection connection, String queueName, String messageSelector,
String errorQueueName, int errorDelayMs, int retryCnt, String connectionUri) throws Exception {
init(recvName, id, connection, queueName, messageSelector, errorQueueName, errorDelayMs, retryCnt,
connectionUri);
}
public void init(String recvName, int sid, Connection connection, String queueName, String selector,
String errQueueName, int deplayMs, int retryCnt, String qConFactory) throws Exception {
this.recvName = recvName;
this.id = sid;
this.connection = connection;
this.queueName = queueName;
this.messageSelector = selector;
this.errorQueueName = errQueueName;
this.errorDelayTimeMs = deplayMs;
this.retryCount = retryCnt;
this.queueConFactory = qConFactory;
logger.info("recvName=" + this.recvName + ",messageSelector=" + this.messageSelector);
try {
this.connection.start();
this.connection.setExceptionListener(this);
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(queueName);
consumer = session.createConsumer(destination);
} catch (Exception jmse) {
if (logger.isError())
logger.error(this.getName()
+ "] In ReceiverObject constructor: JMSException while setting up receiverObj[" + id + "]"
+ recvName, jmse);
close();
throw jmse;
}
}
/**
* Get number of message received since last get
*
* return totaSinceLastGet total number of messages received since the last get
*/
public int getMsgCount() {
synchronized (lockCounter) {
return msgCounter;
}
}
public void setMsgCount(int msgCounter) {
synchronized (lockCounter) {
this.msgCounter = msgCounter;
}
}
/**
* Clear any messages received
*/
public void clearCount() {
synchronized (lockCounter) {
if (logger.isError()) {
logger.error(this.getName() + "] Clearing id: [" + id + "] clearing: " + msgCounter);
}
// reset counter
msgCounter = 0;
msgSuccessCounter = 0;
}
}
/**
* Stop the receiver
*/
public void stopReceiver() {
keepRunning = false;
// stop Receiver from sending which causes thread to exit run() method
// and thus finish.
if (consumer != null)
try {
consumer.close();
} catch (JMSException e) {
}
if (session != null)
try {
session.close();
} catch (JMSException e) {
}
if (connection != null)
try {
connection.close();
} catch (JMSException e) {
}
}
public void stopThread() {
// super.stop();
}
public void run() {
if (Thread.currentThread().getName().startsWith("Thread-")) {
Thread.currentThread().setName(queueName + "-" + Thread.currentThread().getName());
}
keepRunning = true;
threadDowned[id] = false;
EAIMessage eaiMessage = null;
while (keepRunning) {
try {
receiverStatus = 0;
Message message = consumer.receive(2000);
if (message == null) {
// Thread.sleep(500);
continue;
}
synchronized (lockCounter) {
receiverStatus = 1;
msgCounter++;
}
ObjectMessage omsg = null;
if (message == null) {
// logger.warn(name + " -> EMPTY MESSAGE...");
continue;
}
if (message instanceof ObjectMessage) {
omsg = (ObjectMessage) message;
} else {
throw new RuntimeException("Invlid JMS Message Type. - " + message);
}
try {
eaiMessage = (EAIMessage) omsg.getObject();
} catch (Exception e) {
throw new RuntimeException(this.getName() + "] EAI메시지가 아닙니다. - " + e.getMessage());
}
// String guidLogPrefix = "ActiveMQ Receiver] GUID["+eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+eaiMessage.getSvcOgNo()+"] ";
String guidLogPrefix = "ActiveMQ Receiver] GUID["
+ eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage()) + "] UUID["
+ eaiMessage.getSvcOgNo() + "] ";
if (logger.isDebug()) {
logger.debug(guidLogPrefix + this.getName() + "] receiverObj[" + id + "] Executed - "
+ eaiMessage.getEAISvcCd() + ":" + eaiMessage.getSvcOgNo());
}
RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm());
String serviceURI = routingVO.getSyncRoutingPath();
boolean isLocal = true;
Properties prop = new Properties();
try {
Enumeration en = omsg.getPropertyNames();
while (en.hasMoreElements()) {
String propName = (String) en.nextElement();
Object objProp = omsg.getObjectProperty(propName);
prop.put(propName, objProp);// HttpAdapterServiceRest 의 INBOUND_HEADER 항목 고려해서 변경
}
} catch (Exception e) {
throw new RuntimeException(guidLogPrefix + this.getName() + "] 프라퍼티 설정에러 - " + e.getMessage());
}
EAIMessage resEAIMessage = null;
try {
// EAI 거래처리 Error 이고 retry count가 있으면 회수만큼 재시도
// errorDelayTimeMs > 0 면 sleep
int retry = 1;
// retry count 만큼 반복한다.
// -1 : 무한대 retry
// 0 : 처리되지 않는다.
if (this.retryCount == 0) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] SKIP Execute EAISvcCd ("
+ eaiMessage.getEAISvcCd() + ") Retry Count - " + this.retryCount);
}
continue; // 처리를 중단한다.
} else if (this.retryCount > 1) {
receiverStatus = 2;
}
while (((retry <= this.retryCount) || (this.retryCount == -1)) && keepRunning) {
resEAIMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal,
prop);
if (resEAIMessage == null) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName()
+ "] response EAIMessage is NULL. SKIP Retry Count - " + this.retryCount);
}
break;
}
if (MessageUtil.checkRspErrCd(resEAIMessage.getRspErrCd())) {
break;
} else {
if ((this.retryCount > 0) && (retry <= this.retryCount)) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] Call Error("
+ resEAIMessage.getRspErrCd() + ") Retry - " + retry + "/"
+ this.retryCount);
}
// 다음 처리전에 delay를 준다.
if (this.errorDelayTimeMs > 0) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] Delay Before Retry - "
+ this.errorDelayTimeMs);
}
try {
Thread.sleep(this.errorDelayTimeMs);
} catch (Exception e) {
}
}
} else {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] FlowControl Call Error("
+ resEAIMessage.getRspErrCd() + ") No Retry");
}
}
}
retry++;
}
} catch (Exception e) {
if (logger.isError()) {
if (resEAIMessage == null) {
logger.error(
guidLogPrefix + this.getName() + "] FlowControl Call Error " + e.getMessage(),
e);
} else {
logger.error(guidLogPrefix + this.getName() + "] FlowControl Call Error("
+ resEAIMessage.getRspErrCd() + ") " + e.getMessage(), e);
}
}
}
// increment message counter
synchronized (lockCounter) {
msgSuccessCounter++;
}
// EAI 거래처리 Error 면
// errorQueueName 이 있으면 redirect
// errorDelayTimeMs > 0 면 sleep
if (resEAIMessage != null && (!MessageUtil.checkRspErrCd(resEAIMessage.getRspErrCd()))) {
if (this.errorQueueName != null && this.errorQueueName.length() > 0) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] Redirect Messsage to - "
+ this.errorQueueName);
}
JMSSender.sendToQueue(eaiMessage, queueConFactory, this.errorQueueName, prop);
}
}
// 다음 처리 전에 delay를 준다.
if (this.errorDelayTimeMs > 0) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] Delay Before Receive Next Message - "
+ this.errorDelayTimeMs);
}
try {
Thread.sleep(this.errorDelayTimeMs);
} catch (Exception e) {
}
}
} catch (Exception ex) {
if (logger.isError()) {
logger.error(this.getName() + "] JMSException for receiverObj[" + id + "] - " + ex.getMessage(),
ex);
}
try {
// --------------------------------------------
// Set Error
if (eaiMessage != null) {
String[] msgArgs = new String[1];
msgArgs[0] = eaiMessage.getEAISvcCd();
String rspErrorCode = "RECEAIFQR001"; // [EAI 서비스코드:{1}] 큐수신자가 플로우컨트롤 호출 중 오류 발생
String rspErrorMsg = ExceptionUtil.make(ex, rspErrorCode, msgArgs);
// eaiMessage.setRspErrCd(rspErrorCode);
// eaiMessage.setRspErrMsg(rspErrorMsg);
eaiMessage.setRspErr(rspErrorCode,rspErrorMsg);
// --------------------------------------------
// String mesgDmanDvcd = eaiMessage.getKbMsg().getKBHeader().getTelgmDmndDstcd();
// String mesgDmanDvcd = eaiMessage.getExtMsg().getSendRecv();
String mesgDmanDvcd = eaiMessage.getMapper()
.getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R
if (STDMessageKeys.SEND_RECV_CD_RECV.equals(mesgDmanDvcd)) {
// 응답인 경우
eaiMessage.setLogPssSno(400);
} else {
// 요청 인경우
eaiMessage.setLogPssSno(200);
}
EAILogSender.send(eaiMessage, null);
} else {
throw new Exception("EAIMessage is NULL");
}
} catch (Exception e) {
if (logger.isError())
logger.error(this.getName() + "] ErrorLogging :" + e.getMessage());
}
// auto reconnect so wait 10 seconds
try {
Thread.sleep(10000);
} catch (Exception e) {
// Do nothing
}
}
} // end of while
// if Stop Event Occurred
if (!keepRunning) {
threadDowned[id] = true;
synchronized (this) {
boolean tmpDowned = false;
for (int j = 0; j < threadDowned.length; j++) {
if (threadDowned[j] == true) {
tmpDowned = true;
} else {
tmpDowned = false;
break;
}
}
if (tmpDowned) {
allThreadDowned = true;
}
}
}
} // end of run
@Override
public void onException(JMSException arg0) {
logger.error("JMS Exception occured. Shutting down client.");
stopReceiver();
}
}// end of inner class ReceiverObject
}
@@ -0,0 +1,706 @@
package com.eactive.eai.flowcontrol.jms;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import javax.jms.JMSException;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSession;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.logger.EAILogSender;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.routing.ElinkESBProcessProxy;
import com.eactive.eai.common.routing.RouteKeys;
import com.eactive.eai.common.routing.RoutingManager;
import com.eactive.eai.common.routing.RoutingVO;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.util.JMSSender;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.MessageUtil;
import com.ext.eai.common.stdmessage.STDMessageKeys;
public class FCQueueReceiver {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
private static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW);
// ------------------------------------
// Rule Var
// ------------------------------------
private String receiverName;
private String queueName;
private String errorQueueName;
private int receiverCount;
private int errorDelayTimeMs;
private int retryCount;
private String messageSelector = "";
private String description;
// ------------------------------------
// Used for Test
// ------------------------------------
public static final boolean isSingleApplication = false;
public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
// ------------------------------------
// Objects needed for JMS clients
// ------------------------------------
private QueueConnectionFactory factory;
private QueueConnection[] connection;
private QueueSession[] session;
private ReceiverObject[] receiverObj = null;
private boolean isTx = false;
// ------------------------------------
// Thread Runtime Info
// ------------------------------------
private Thread[] receiverThread = null;
private boolean[] threadDowned = null;
public boolean allThreadDowned = true;
private static String instid = "11";
static {
instid = EAIServerManager.getInstance().getInstId();
}
// For Local Test with Single Application
private static InitialContext getInitialContext(String url) throws NamingException {
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[ FCQueueReceiver INFO ]");
sb.append("\nReveciver Name = " + this.receiverName);
sb.append(", Queue Name = " + this.queueName);
sb.append(", Error Queue Name = " + this.errorQueueName);
sb.append(", Recever Count = " + this.receiverCount);
sb.append(", Delay Time(ms) = " + this.errorDelayTimeMs);
sb.append(", Retry Count = " + this.retryCount);
sb.append(", Selector = " + this.messageSelector);
sb.append(", Description = " + this.description);
return sb.toString();
}
public FCQueueReceiver(String rcvName, String qname, String errorqname, int rcvCount, int delayMs, int retryCnt,
boolean isTx, int ackMode, String msgSelector, String descr) throws Exception {
queueName = qname;
errorQueueName = errorqname;
receiverName = rcvName;
receiverCount = rcvCount;
errorDelayTimeMs = delayMs;
retryCount = retryCnt;
messageSelector = msgSelector;
description = descr;
// trim space
if (queueName != null)
queueName = queueName.trim();
if (errorQueueName != null)
errorQueueName = errorQueueName.trim();
if (receiverName != null)
receiverName = receiverName.trim();
if (messageSelector != null)
messageSelector = messageSelector.trim();
this.isTx = isTx;
threadDowned = new boolean[receiverCount];
connection = new QueueConnection[receiverCount];
session = new QueueSession[receiverCount];
receiverObj = new ReceiverObject[receiverCount];
receiverThread = new Thread[receiverCount];
Queue[] queue = new Queue[receiverCount];
InitialContext ctx = null;
String clientId = receiverName;
String queueConFactory = "";
try {
if (isSingleApplication) {
if (logger.isDebug())
logger.debug("Local Application Test");
ctx = getInitialContext("t3://localhost:7001");
queueConFactory = "TestConnectionFactory";
} else {
ctx = new InitialContext();
PropManager propManager = PropManager.getInstance();
queueConFactory = propManager.getProperty(RouteKeys.GROUP_NAME,
RouteKeys.ROUTING_QUEUE_CONNECTION_FACTORY);
}
} catch (Exception e) {
if (logger.isError())
logger.error("FCQueueReceiver: get InitialContext Error", e);
throw e;
}
if (logger.isDebug())
logger.debug(queueConFactory);
try {
// Create the connections
for (int i = 0; i < receiverCount; i++) {
factory = (QueueConnectionFactory) ctx.lookup(queueConFactory);
// create each connection
connection[i] = factory.createQueueConnection();
// Auto Reconnection with WebLogic Function
// ((weblogic.jms.extensions.WLConnection)
// connection[i]).setReconnectPolicy("all");
clientId = receiverName + instid + "-" + i;
// connection[i].setClientID(clientId);
session[i] = connection[i].createQueueSession(isTx, ackMode);
queue[i] = (Queue) ctx.lookup(queueName);
receiverObj[i] = new ReceiverObject(i, session[i], queue[i], this.messageSelector, this.errorQueueName,
this.errorDelayTimeMs, this.retryCount, queueConFactory);
receiverObj[i].setName(clientId);
if (logger.isDebug())
logger.debug("[" + new java.util.Date() + "] Receiver Thread : [" + clientId + "] " + queue[i]);
receiverThread[i] = new Thread(receiverObj[i]);
receiverThread[i].setDaemon(true);// avoids thread leaks ifz
}
// } catch(weblogic.jms.common.InvalidClientIDException icid) {
// if(logger.isError()) logger.error("Duplicate ClientID Exception while in constructor : ");
// icid.printStackTrace();
// close();
// throw icid;
} catch (Exception e) {
if (logger.isError())
logger.error(" Exception while in constructor", e);
close();
throw e;
}
}
/**
* Start receiving for all receivers
*/
public synchronized void startReceiving() throws Exception {
if (!allThreadDowned) {
throw new Exception("Thread Started Already !");
}
try {
for (int i = 0; i < connection.length; i++) {
connection[i].start();
}
for (int i = 0; i < receiverThread.length; i++) {
receiverThread[i].start();
}
allThreadDowned = false;
} catch (JMSException jmse) {
logger.error("FCQueueReceiver: JMSException while in startReceiving() method", jmse);
close();
throw jmse;
}
}
/**
* Clear any messages received after the connection was started but before the
* user starts the test.
*/
public synchronized void clearReceived() {
// Clear Counter
for (int i = 0; i < receiverObj.length; i++) {
receiverObj[i].clearCount();
}
}
/**
* Stop sending for all Receiver threads
*/
public synchronized void stopReceiving() {
// Cleanup each ReceiverObj (stops sending and causes thread to exit)
for (int i = 0; i < receiverObj.length; i++) {
// stops each ReceiverObject
if (receiverObj[i] != null)
receiverObj[i].stopReceiver();
receiverObj[i].stopThread();
}
}
public String[][] getStatus() {
String[][] receiveStatus = new String[receiverObj.length][4];
for (int i = 0; i < receiverObj.length; i++) {
if (receiverObj[i] != null) {
receiveStatus[i][0] = receiverObj[i].getName();
receiveStatus[i][1] = "" + receiverObj[i].msgCounter;
receiveStatus[i][2] = "" + receiverObj[i].msgSuccessCounter;
receiveStatus[i][3] = "" + receiverObj[i].receiverStatus;
}
}
return receiveStatus;
}
public String[] getMessageCount() {
String[] receiveStatus = new String[2];
int receivedTotal = 0;
int successTotal = 0;
for (int i = 0; i < receiverObj.length; i++) {
if (receiverObj[i] != null) {
receivedTotal += receiverObj[i].msgCounter;
successTotal += receiverObj[i].msgSuccessCounter;
}
}
receiveStatus[0] = "" + receivedTotal;
receiveStatus[1] = "" + successTotal;
return receiveStatus;
}
/**
* Closes all connections which in turn stops the receivers and exits JVM
*/
public void close() {
if (isTx) {
for (int k = 0; k < session.length; k++) {
try {
if (session[k] != null) {
session[k].rollback();
}
} catch (JMSException jmse) {
logger.warn("Exception rolling back session " + k, jmse);
}
}
}
// Close all the connections before exiting the application
for (int i = 0; i < connection.length; i++) {
try {
if (connection[i] != null)
connection[i].close();
} catch (JMSException jmse) {
logger.error("In close(): Caught JMSException trying to close connection(s)", jmse);
}
}
}
// ////////////////////////////////////////////////////////////////////////
/**
* Inner class: ReceiverObject is an ASYNCHRONOUS receiver.
*/
// ////////////////////////////////////////////////////////////////////////
private class ReceiverObject extends Thread {
// Session
private QueueSession qsession = null; // session to use for receiving
private QueueReceiver qreceiver = null; // reciever object to use
// for receiving
private Queue queue = null; // queue object to receive from
private int id; // identifies the ReceiverObject
private int msgCounter = 0; // keeps track of messages
private int msgSuccessCounter = 0;
private int receiverStatus = 0; // 0 - wait, 1 - running, 2 - retry
private Object lockCounter = new Object();// used to synchronize
// updates of the message
// counter
private boolean keepRunning = false; // used to exit the sending loop
// in the run method
private String messageSelector = "";
private String errorQueueName = "";
private int errorDelayTimeMs = 0;
private int retryCount = 0;
private String queueConFactory = "";
/**
* Construct a ReceiverObject param id - the id number should be unique for each
* ReceiverObject param sess - the session object under which the receiver is
* created param q - the Queue object to receiver from
*/
public ReceiverObject(int id, QueueSession sess, Queue q, String messageSelector, String errorQueueName,
int errorDelayMs, int retryCnt, String qConFactory) throws Exception {
init(id, sess, q, messageSelector, errorQueueName, errorDelayMs, retryCnt, qConFactory);
}
public void init(int sid, QueueSession sess, Queue q, String selector, String errQueueName, int deplayMs,
int retryCnt, String qConFactory) throws Exception {
id = sid;
qsession = sess;
queue = q;
messageSelector = selector;
errorQueueName = errQueueName;
errorDelayTimeMs = deplayMs;
retryCount = retryCnt;
queueConFactory = qConFactory;
try {
if (messageSelector == null || messageSelector.trim().length() == 0) {
qreceiver = qsession.createReceiver(queue);
} else {
qreceiver = qsession.createReceiver(queue, messageSelector);
}
} catch (JMSException jmse) {
if (logger.isWarn())
logger.warn(this.getName()
+ "] In ReceiverObject constructor: JMSException while setting up receiverObj[" + id + "]",
jmse);
close();
throw jmse;
}
}
/**
* Get number of message received since last get
*
* return totaSinceLastGet total number of messages received since the last get
*/
public int getMsgCount() {
synchronized (lockCounter) {
return msgCounter;
}
}
public void setMsgCount(int msgCounter) {
synchronized (lockCounter) {
this.msgCounter = msgCounter;
}
}
/**
* Clear any messages received
*/
public void clearCount() {
synchronized (lockCounter) {
if (logger.isWarn())
logger.warn(this.getName() + "] Clearing id: [" + id + "] clearing: " + msgCounter);
// reset counter
msgCounter = 0;
msgSuccessCounter = 0;
}
}
/**
* Stop the receiver
*/
public void stopReceiver() {
// stop Receiver from sending which causes thread to exit run() method
// and thus finish.
keepRunning = false;
}
public void stopThread() {
// super.stop();
}
@Override
public void run() {
if (Thread.currentThread().getName().startsWith("Thread-")) {
Thread.currentThread().setName(queueName + "-" + Thread.currentThread().getName());
}
keepRunning = true;
threadDowned[id] = false;
javax.jms.Message msg = null;
ObjectMessage omsg = null;
EAIMessage eaiMessage = null;
while (keepRunning) {
try {
receiverStatus = 0;
eaiMessage = null;
msg = qreceiver.receive(1000);
if (msg == null) {
continue;
}
synchronized (lockCounter) {
receiverStatus = 1;
msgCounter++;
}
if (msg instanceof ObjectMessage) {
omsg = (ObjectMessage) msg;
} else {
throw new RuntimeException(this.getName() + "] 지원하지않는 메시지 - " + msg);
}
try {
eaiMessage = (EAIMessage) omsg.getObject();
} catch (Exception e) {
throw new RuntimeException(this.getName() + "] EAI메시지가 아닙니다. - " + e.getMessage());
}
// String guidLogPrefix = "Queue Receiver] GUID["+eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+eaiMessage.getSvcOgNo()+"] ";
String guidLogPrefix = "Queue Receiver] GUID["
+ eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage()) + "] UUID["
+ eaiMessage.getSvcOgNo() + "] ";
if (esbLogger.isInfo()) {
esbLogger.info(guidLogPrefix + this.getName() + "] receiverObj[" + id + "] Executed - "
+ eaiMessage.getEAISvcCd());
}
RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm());
String serviceURI = routingVO.getSyncRoutingPath();
boolean isLocal = true;
Properties prop = new Properties();
try {
Enumeration en = omsg.getPropertyNames();
while (en.hasMoreElements()) {
String propName = (String) en.nextElement();
Object objProp = omsg.getObjectProperty(propName);
prop.put(propName, objProp);// HttpAdapterServiceRest 의 INBOUND_HEADER 항목 고려해서 변경
}
} catch (JMSException e) {
throw new RuntimeException(guidLogPrefix + this.getName() + "] 프라퍼티 설정에러 - " + e.getMessage());
}
EAIMessage resEAIMessage = null;
try {
// EAI 거래처리 Error 이고 retry count가 있으면 회수만큼 재시도
// errorDelayTimeMs > 0 면 sleep
int retry = 1;
// retry count 만큼 반복한다.
// -1 : 무한대 retry
// 0 : 처리되지 않는다.
if (this.retryCount == 0) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] SKIP Execute EAISvcCd ("
+ eaiMessage.getEAISvcCd() + ") Retry Count - " + this.retryCount);
}
continue; // 처리를 중단한다.
} else if (this.retryCount > 1) {
receiverStatus = 2;
}
while (((retry <= this.retryCount) || (this.retryCount == -1)) && keepRunning) {
resEAIMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal,
prop);
if (resEAIMessage == null) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName()
+ "] response EAIMessage is NULL. SKIP Retry Count - " + this.retryCount);
}
break;
}
if (MessageUtil.checkRspErrCd(resEAIMessage.getRspErrCd())) {
break;
} else {
if ((this.retryCount > 0) && (retry <= this.retryCount)) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] Call Error("
+ resEAIMessage.getRspErrCd() + ") Retry - " + retry + "/"
+ this.retryCount);
}
// 다음 처리전에 delay를 준다.
if (this.errorDelayTimeMs > 0) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] Delay Before Retry - "
+ this.errorDelayTimeMs);
}
try {
Thread.sleep(this.errorDelayTimeMs);
} catch (Exception e) {
logger.warn("sleep error", e);
}
}
} else {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] FlowControl Call Error("
+ resEAIMessage.getRspErrCd() + ") No Retry");
}
}
}
retry++;
} // while(retry <= this.retryCount)
} catch (Exception e) {
if (logger.isError()) {
logger.error(guidLogPrefix + this.getName() + "] FlowControl Call Error", e);
}
}
if (msg != null) {
if (isTx) {
try {
qsession.commit();
} catch (JMSException jmse) {
throw jmse;
}
}
// increment message counter
synchronized (lockCounter) {
msgSuccessCounter++;
}
msg = null;
}
if (resEAIMessage != null) {
// EAI 거래처리 Error 면
// errorQueueName 이 있으면 redirect
// errorDelayTimeMs > 0 면 sleep
if (!MessageUtil.checkRspErrCd(resEAIMessage.getRspErrCd())) {
if (this.errorQueueName != null && this.errorQueueName.length() > 0) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] Redirect Messsage to - "
+ this.errorQueueName);
}
JMSSender.sendToQueue(eaiMessage, queueConFactory, this.errorQueueName, prop);
}
}
}
// 다음 처리 전에 delay를 준다.
if (this.errorDelayTimeMs > 0) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] Delay Before Receive Next Message - "
+ this.errorDelayTimeMs);
}
try {
Thread.sleep(this.errorDelayTimeMs);
} catch (Exception e) {
logger.warn("sleep error", e);
}
}
} catch (Exception jmse) {
if (msg != null) {
msg = null;
}
if (logger.isError()) {
logger.error(
this.getName() + "] JMSException for receiverObj[" + id + "] - " + jmse.getMessage(),
jmse);
}
if (eaiMessage != null) {
// --------------------------------------------
// Set Error
String[] msgArgs = new String[1];
msgArgs[0] = eaiMessage.getEAISvcCd();
String rspErrorCode = "RECEAIFQR001"; // [EAI 서비스코드:{1}] 큐수신자가 플로우컨트롤 호출 중 오류 발생
String rspErrorMsg = ExceptionUtil.make(jmse, rspErrorCode, msgArgs);
// eaiMessage.setRspErrCd(rspErrorCode);
// eaiMessage.setRspErrMsg(rspErrorMsg);
eaiMessage.setRspErr(rspErrorCode,rspErrorMsg);
// --------------------------------------------
// String telgmDmndDstcd = eaiMessage.getKbMsg().getKBHeader().getTelgmDmndDstcd();
// String telgmDmndDstcd = eaiMessage.getExtMsg().getSendRecv();
String telgmDmndDstcd = eaiMessage.getMapper()
.getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R
if (STDMessageKeys.SEND_RECV_CD_RECV.equals(telgmDmndDstcd)) {
// 응답인 경우
eaiMessage.setLogPssSno(400);
} else {
// 요청 인경우
eaiMessage.setLogPssSno(200);
}
try {
EAILogSender.send(eaiMessage, null);
} catch (Exception e) {
if (logger.isError())
logger.error(this.getName() + "] ErrorLogging :" + e.getMessage());
}
}
// auto reconnect so wait 10 seconds
try {
Thread.sleep(10000);
} catch (Exception e) {
logger.warn("sleep error", e);
}
} catch (Throwable rte) {
if (logger.isError()) {
logger.error(this.getName() + "] runtime exception for receiverObj[" + id + "] - "
+ rte.getMessage(), rte);
}
if (eaiMessage != null) {
// --------------------------------------------
// Set Error
String[] msgArgs = new String[1];
msgArgs[0] = eaiMessage.getEAISvcCd();
String rspErrorCode = "RECEAIFQR001"; // [EAI 서비스코드:{1}] 플로우컨트롤 호출 중 오류가 발생
String rspErrorMsg = ExceptionUtil.make(rte, rspErrorCode, msgArgs);
// eaiMessage.setRspErrCd(rspErrorCode);
// eaiMessage.setRspErrMsg(rspErrorMsg);
eaiMessage.setRspErr(rspErrorCode,rspErrorMsg);
// --------------------------------------------
// String telgmDmndDstcd = eaiMessage.getKbMsg().getKBHeader().getTelgmDmndDstcd();
// String telgmDmndDstcd = eaiMessage.getExtMsg().getSendRecv();
String telgmDmndDstcd = eaiMessage.getMapper()
.getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R
if (STDMessageKeys.SEND_RECV_CD_RECV.equals(telgmDmndDstcd)) {
// 응답인 경우
eaiMessage.setLogPssSno(400);
} else {
// 요청 인경우
eaiMessage.setLogPssSno(200);
}
try {
EAILogSender.send(eaiMessage, null);
} catch (Exception e) {
if (logger.isError())
logger.error(this.getName() + "] ErrorLogging :" + e.getMessage());
}
}
}
} // end of while
// if Stop Event Occurred
if (!keepRunning) {
threadDowned[id] = true;
synchronized (this) {
boolean tmpDowned = false;
for (int j = 0; j < threadDowned.length; j++) {
if (threadDowned[j] == true) {
tmpDowned = true;
} else {
tmpDowned = false;
break;
}
}
if (tmpDowned) {
allThreadDowned = true;
}
}
}
} // end of run
}// end of inner class ReceiverObject
}
@@ -0,0 +1,69 @@
package com.eactive.eai.flowcontrol.jms;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
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.server.EAIServerManager;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.data.entity.onl.flowcontrol.jms.FCQueueReceiver;
import com.eactive.eai.flowcontrol.jms.loader.FCQueueReceiverLoader;
import com.eactive.eai.flowcontrol.jms.mapper.FCQueueReceiverMapper;
@Service
@Transactional
public class FCQueueReceiverDAO extends BaseDAO {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
@Autowired
private FCQueueReceiverLoader fcQueueReceiverEntityService;
@Autowired
private FCQueueReceiverMapper fcQueueReceiverMapper;
public Map<String, FCQueueReceiverVO> getAllReceivers() throws DAOException {
boolean isScalable = BooleanUtils.toBoolean(System.getProperty("scalable"));
String serverName ="";
if(isScalable) {
serverName ="ALL";
}else {
serverName = EAIServerManager.getInstance().getLocalServerName();
}
try {
Map<String, FCQueueReceiverVO> fCQueueMap = new HashMap<>();
Stream<FCQueueReceiver> fcQueuesReceivers = fcQueueReceiverEntityService.loadAll(serverName);
logger.info("[ @@ Load FCQueueReceiver Configuration - starting >>>>>>>>>>>>>>>>> ]");
fcQueuesReceivers.forEach(e -> {
FCQueueReceiverVO fcQueueReceiverVO = fcQueueReceiverMapper.toVo(e);
fCQueueMap.put(fcQueueReceiverVO.getReceiverName(), fcQueueReceiverVO);
logger.info("@ " + fcQueueReceiverVO.toString());
});
logger.info("[>>Load FCQueueReceiver Configuration - ended ]");
return fCQueueMap;
} catch (Exception e) {
throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICCM101"));
}
}
public FCQueueReceiverVO getReceiver(String queRcverName) throws DAOException {
try {
FCQueueReceiver fcQueueReceiver = fcQueueReceiverEntityService.getById(queRcverName);
FCQueueReceiverVO fcQueueReceiverVO = fcQueueReceiverMapper.toVo(fcQueueReceiver);
logger.info("@ " + fcQueueReceiverVO.toString());
return fcQueueReceiverVO;
} catch (Exception e) {
throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICCM101"));
}
}
}
@@ -0,0 +1,406 @@
package com.eactive.eai.flowcontrol.jms;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.jms.Session;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.eactive.eai.common.activemq.AmqPooledConnectionFactory;
import com.eactive.eai.common.dao.DAOException;
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.routing.RouteKeys;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.util.ApplicationContextProvider;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.env.ElinkConfig;
@Component
public class FCQueueReceiverManager implements Lifecycle {
public static final int MQ_ACTIVEMQ = 0;
public static final int MQ_JMS = 1;
public static final int MQ_RABBITMQ = 2;
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
private Map<String, FCQueueReceiverVO> receiverVos = new HashMap<>();
private HashMap<String, Object> receivers = new HashMap<>();
private LifecycleSupport lifecycle = new LifecycleSupport(this);
private boolean started;
@Autowired
FCQueueReceiverDAO fcQueueReceiverDAO;
public static FCQueueReceiverManager getInstance() {
return ApplicationContextProvider.getContext().getBean(FCQueueReceiverManager.class);
}
private String getConnectionURL() {
String connectionUrl = PropManager.getInstance().getProperty(RouteKeys.GROUP_NAME,
RouteKeys.ROUTING_QUEUE_CONNECTION_FACTORY);
if (connectionUrl == null || ElinkConfig.isUseInternalQueue()) {
connectionUrl = AmqPooledConnectionFactory.CONNECTION_URI;
}
return connectionUrl;
}
private int getMqType() {
String connectionUri = getConnectionURL();
int type = MQ_ACTIVEMQ;
if (connectionUri == null) {
return MQ_ACTIVEMQ;
}
if (connectionUri.startsWith("tcp:")) {
type = MQ_ACTIVEMQ;
} else if (connectionUri.startsWith("vm:")) {
type = MQ_ACTIVEMQ;
} else if (connectionUri.startsWith("amqp:")) {
type = MQ_RABBITMQ;
} else {
type = MQ_JMS;
}
return type;
}
public void start() throws LifecycleException {
if (started)
throw new LifecycleException("RECEAICFM201");
lifecycle.fireLifecycleEvent(STARTING_EVENT, this);
try {
receiverVos = fcQueueReceiverDAO.getAllReceivers();
} catch (DAOException e) {
throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICFM202"));
}
Iterator<String> it = receiverVos.keySet().iterator();
String key = "";
while (it.hasNext()) {
key = it.next();
FCQueueReceiverVO vo = receiverVos.get(key);
try {
if ("1".equals(vo.getBascQueRcverYn())) {
startReceiver(vo.getReceiverName(), vo.getQueueName(), vo.getErrorQueueName(),
vo.getReceiverCount(), vo.getErrorDelayTimeMs(), vo.getRetryCount(),
vo.getMessageSelector(), vo.getDescription());
} else {
if (logger.isWarn()) {
logger.warn("FCQueueReceiverManager] Error Occurred while start FCReceiver["
+ vo.getReceiverName() + "] 사용안함 ");
}
}
} catch (Exception e) {
logger.error("FCQueueReceiverManager] Error Occured while start FCReceiver[" + key
+ "] continue start : Error - " + e.getMessage());
}
}
started = true;
lifecycle.fireLifecycleEvent(STARTED_EVENT, this);
}
public void stop() throws LifecycleException {
if (!started)
throw new LifecycleException("RECEAICFM203");
lifecycle.fireLifecycleEvent(STOPING_EVENT, this);
Iterator<String> it = receiverVos.keySet().iterator();
String key = "";
while (it.hasNext()) {
key = it.next();
try {
stopReceiver(key);
} catch (Exception e) {
if (logger.isWarn()) {
logger.warn("FCQueueReceiverManager] Error Occurred while stop FCReceiver[" + key
+ "] continue start : Error - " + e.getMessage());
}
}
}
receiverVos.clear();
started = false;
lifecycle.fireLifecycleEvent(STOPPED_EVENT, this);
}
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 FCQueueReceiverVO getFCQueueReceiver(String receiverName) {
if (receiverName == null)
return null;
return receiverVos.get(receiverName);
}
public void loadFCQueueReceiver(String queRcverName) throws Exception {
FCQueueReceiverVO vo = null;
try {
boolean isScalable = BooleanUtils.toBoolean(System.getProperty("scalable"));
String localServerName ="";
if(isScalable) {
localServerName ="ALL";
}else {
localServerName = EAIServerManager.getInstance().getLocalServerName();
}
vo = fcQueueReceiverDAO.getReceiver(queRcverName);
if (this.receivers.get(vo.getReceiverName()) != null) {
stopReceiver(vo.getReceiverName());
}
if (localServerName.equals(vo.getEaiSevrInstncName())) {
receiverVos.put(vo.getReceiverName(), vo);
if ("1".equals(vo.getBascQueRcverYn())) {
startReceiver(vo.getReceiverName(), vo.getQueueName(), vo.getErrorQueueName(),
vo.getReceiverCount(), vo.getErrorDelayTimeMs(), vo.getRetryCount(),
vo.getMessageSelector(), vo.getDescription());
} else {
if (logger.isWarn()) {
logger.warn("FCQueueReceiverManager] Error Occurred while start FCReceiver["
+ vo.getReceiverName() + "] 사용안함 ");
}
}
}
} catch (Exception e) {
String message = "";
if (vo != null) {
message = "FCQueueReceiverManager] Error Occurred while start FCReceiver[" + vo.getReceiverName()
+ "] - " + e.getMessage();
} else {
message = "FCQueueReceiverManager] Error Occurred while start FCReceiver[" + queRcverName + "] - "
+ e.getMessage();
}
logger.error(message, e);
throw new Exception(message);
}
}
public void setFCQueueReceiver(FCQueueReceiverVO vo) throws Exception {
try {
receiverVos.put(vo.getReceiverName(), vo);
if (this.receivers.get(vo.getReceiverName()) != null) {
stopReceiver(vo.getReceiverName());
}
startReceiver(vo.getReceiverName(), vo.getQueueName(), vo.getErrorQueueName(), vo.getReceiverCount(),
vo.getErrorDelayTimeMs(), vo.getRetryCount(), vo.getMessageSelector(), vo.getDescription());
} catch (Exception e) {
String message = "FCQueueReceiverManager] Error Occurred while start FCReceiver[" + vo.getReceiverName()
+ "] - " + e.getMessage();
logger.error(message, e);
throw new Exception(message);
}
}
public void removeFCQueueReceiver(String receiverName) throws Exception {
try {
stopReceiver(receiverName);
receiverVos.remove(receiverName);
} catch (Exception e) {
String message = "FCQueueReceiverManager] Error Occurred while stop FCReceiver[" + receiverName + "] - "
+ e.getMessage() + "] - " + e.getMessage();
logger.error(message, e);
throw new Exception(message);
}
}
public Map<String, FCQueueReceiverVO> getAllFCQueueReceiverVos() {
return this.receiverVos;
}
// -------------------------------------------------------------------
// receiver control Method
// -------------------------------------------------------------------
public void startReceiver(String receiverName, String QueueName, String errorQueueName, int receiverCount,
int deplayMs, int retryCnt, String selector, String descr) throws Exception {
try {
int type = getMqType();
switch (type) {
case MQ_RABBITMQ:
FCRabbitMqReceiver rabbitMqReceiverApp = new FCRabbitMqReceiver(receiverName, QueueName, errorQueueName,
receiverCount, deplayMs, retryCnt, false, // TxMode
1, // (Session.AUTO_ACKNOWLEDGE)
selector, descr);
rabbitMqReceiverApp.startReceiving();
receivers.put(receiverName, rabbitMqReceiverApp);
logger.warn("FCRabbitMqReceiver Start - " + rabbitMqReceiverApp);
break;
case MQ_JMS:
FCQueueReceiver receiverApp = new FCQueueReceiver(receiverName, QueueName, errorQueueName,
receiverCount, deplayMs, retryCnt, false, // TxMode
Session.AUTO_ACKNOWLEDGE, selector, descr);
receiverApp.startReceiving();
receivers.put(receiverName, receiverApp);
logger.warn("FCQueueReceiverManager] Start - " + receiverName);
break;
default:
FCActiveMqReceiver activeMqReceiverApp = new FCActiveMqReceiver(receiverName, QueueName, errorQueueName,
receiverCount, deplayMs, retryCnt, false, // TxMode
1, // (Session.AUTO_ACKNOWLEDGE)
selector, descr);
activeMqReceiverApp.startReceiving();
receivers.put(receiverName, activeMqReceiverApp);
logger.warn("FCActiveMqReceiver Start - " + activeMqReceiverApp);
break;
}
} catch (Exception e) {
logger.error("FCQueueReceiverManager] Start Error", e);
throw e;
}
}
public void startReceiver(String receiverName) throws Exception {
try {
FCQueueReceiverVO vo = fcQueueReceiverDAO.getReceiver(receiverName);
startReceiver(vo.getReceiverName(), vo.getQueueName(), vo.getErrorQueueName(), vo.getReceiverCount(),
vo.getErrorDelayTimeMs(), vo.getRetryCount(), vo.getMessageSelector(), vo.getDescription());
logger.warn("FCQueueReceiverManager] Start - " + receiverName);
} catch (Exception e) {
logger.error("FCQueueReceiverManager] Error ", e);
throw e;
}
}
public void stopReceiver(String receiverName) throws Exception {
try {
Object receiverObj = receivers.get(receiverName);
if (receiverObj instanceof FCQueueReceiver) {
FCQueueReceiver receiverApp = (FCQueueReceiver) receiverObj;
receiverApp.stopReceiving();
receiverApp.close();
receivers.remove(receiverName);
logger.warn("FCQueueReceiverManager] FCQueueReceiver Stopped - " + receiverName);
} else if (receiverObj instanceof FCActiveMqReceiver) {
FCActiveMqReceiver receiverApp = (FCActiveMqReceiver) receiverObj;
receiverApp.stopReceiving();
receiverApp.close();
receivers.remove(receiverName);
logger.warn("FCQueueReceiverManager] Receiver Stopped - " + receiverName);
} else if (receiverObj instanceof FCRabbitMqReceiver) {
FCRabbitMqReceiver receiverApp = (FCRabbitMqReceiver) receiverObj;
receiverApp.stopReceiving();
receiverApp.close();
receivers.remove(receiverName);
logger.warn("FCQueueReceiverManager] FCRabbitMqReceiver Stopped - " + receiverName);
}
} catch (Exception e) {
logger.error("FCQueueReceiverManager] Receiver Stop error", e);
throw e;
}
}
// 개별 Queue Receiver의 Thread별 건수 조회
public String[][] getMonitorData(String receiverName) throws Exception {
String[][] status = null;
// 0 : receiver Thread Name
// 1 : 메시지 처리건수
// 2 : 메시지 성공건수
// 3 : 현재상태 (0 - wait, 1 - running, 2 - retry)
try {
FCQueueReceiver receiverApp = (FCQueueReceiver) receivers.get(receiverName);
if (receiverApp != null) {
status = receiverApp.getStatus();
} else {
throw new Exception("Receiver Already Stopped - " + receiverName);
}
} catch (Exception e) {
logger.error("FCQueueReceiverManager] getMonitorData error", e);
throw e;
}
return status;
}
// Queue Receiver의 전체 건수 조회
public String[][] getMonitorData() throws Exception {
String[][] status = new String[receivers.size()][3];
try {
int i = 0;
for (Map.Entry<String, Object> entry : receivers.entrySet()) {
String receiverName = entry.getKey();
FCQueueReceiver receiverApp = (FCQueueReceiver) entry.getValue();
if (receiverApp != null) {
String[] counter = receiverApp.getMessageCount();
status[i][0] = receiverName;
status[i][1] = counter[0]; // 메시지 건수
status[i][2] = counter[1]; // 성공건수
} else {
status[i][0] = receiverName;
status[i][1] = "0";
status[i][2] = "0";
}
i++;
}
} catch (Exception e) {
logger.error("FCQueueReceiverManager] getMonitorData error", e);
throw e;
}
return status;
}
public void resetCount(String receiverName) throws Exception {
try {
FCQueueReceiver receiverApp = (FCQueueReceiver) receivers.get(receiverName);
if (receiverApp != null) {
receiverApp.clearReceived();
} else {
throw new Exception("Receiver Already Stopped - " + receiverName);
}
} catch (Exception e) {
logger.error("FCQueueReceiverManager] resetCount error", e);
throw e;
}
}
public String[] getAllReceiverNames() {
String[] receiverName = new String[receivers.size()];
Iterator<String> it = receivers.keySet().iterator();
for (int i = 0; it.hasNext(); i++) {
receiverName[i] = it.next();
}
return receiverName;
}
}
@@ -0,0 +1,108 @@
package com.eactive.eai.flowcontrol.jms;
import java.io.Serializable;
public class FCQueueReceiverVO implements Serializable {
private static final long serialVersionUID = 1L;
private String receiverName ; // Receiver Name
private String queueName ; // Queue Name
private String errorQueueName ; // Error Queue Name
private int receiverCount ; // Receiver 수
private int errorDelayTimeMs; // 에러 발생시 delay 타임(ms)
private int retryCount ; // 에러큐에 대한 retry 회수
private String messageSelector ; // Selector
private String bascQueRcverYn ; // 기본큐수신자여부 ( 1-Default, 0 - Not)
private String description ; // 설명
private String eaiSevrInstncName; // 서버인스탄스명
public String getEaiSevrInstncName() {
return eaiSevrInstncName;
}
public void setEaiSevrInstncName(String eaiSevrInstncName) {
this.eaiSevrInstncName = eaiSevrInstncName;
}
public FCQueueReceiverVO() {
receiverCount = 1;
errorDelayTimeMs = 0;
retryCount = 0;
messageSelector = "";
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getMessageSelector() {
return messageSelector;
}
public void setMessageSelector(String messageSelector) {
this.messageSelector = messageSelector;
}
public String getQueueName() {
return queueName;
}
public void setQueueName(String queueName) {
this.queueName = queueName;
}
public int getReceiverCount() {
return receiverCount;
}
public void setReceiverCount(int receiverCount) {
this.receiverCount = receiverCount;
}
public String getReceiverName() {
return receiverName;
}
public void setReceiverName(String receiverName) {
this.receiverName = receiverName;
}
public int getErrorDelayTimeMs() {
return errorDelayTimeMs;
}
public void setErrorDelayTimeMs(int errorDelayTimeMs) {
this.errorDelayTimeMs = errorDelayTimeMs;
}
public String getErrorQueueName() {
return errorQueueName;
}
public void setErrorQueueName(String errorQueueName) {
this.errorQueueName = errorQueueName;
}
public int getRetryCount() {
return retryCount;
}
public void setRetryCount(int retryCount) {
this.retryCount = retryCount;
}
public String getBascQueRcverYn() {
return bascQueRcverYn;
}
public void setBascQueRcverYn(String bascQueRcverYn) {
this.bascQueRcverYn = bascQueRcverYn;
}
}
@@ -0,0 +1,605 @@
package com.eactive.eai.flowcontrol.jms;
import java.util.HashMap;
import java.util.Properties;
import org.apache.commons.lang.SerializationUtils;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.logger.EAILogSender;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.routing.ElinkESBProcessProxy;
import com.eactive.eai.common.routing.RouteKeys;
import com.eactive.eai.common.routing.RoutingManager;
import com.eactive.eai.common.routing.RoutingVO;
import com.eactive.eai.common.util.JMSSender;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.MessageUtil;
import com.ext.eai.common.stdmessage.STDMessageKeys;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.GetResponse;
public class FCRabbitMqReceiver {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
private String receiverName;
private String queueName;
private String errorQueueName;
private int receiverCount;
private int errorDelayTimeMs;
private int retryCount;
private String messageSelector = "";
private String description;
// ------------------------------------
// Used for Test
// ------------------------------------
public static final boolean isSingleApplication = false;
// ------------------------------------
// Objects needed for RabbitMQ clients
// ------------------------------------
private ConnectionFactory factory;
private Connection[] connection;
private Channel[] channel;
private ReceiverObject[] receiverObj = null;
// private boolean isTx = false;
// private static final DecimalFormat dFormat = new DecimalFormat("#0.0");
// ------------------------------------
// Thread Runtime Info
// ------------------------------------
private Thread[] receiverThread = null;
private boolean[] threadDowned = null;
public boolean allThreadDowned = true;
// private static String instid = "11";
static {
// String serverName = System.getProperty(Keys.WLI_SERVER_KEY);
// if(serverName != null && serverName.length() > 2) {
// instid = serverName.substring(serverName.length()-2, serverName.length());
// }
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[ FCRabbitMqReceiver INFO ]");
sb.append("\nReveciver Name = " + this.receiverName);
sb.append(", Queue Name = " + this.queueName);
sb.append(", Error Queue Name = " + this.errorQueueName);
sb.append(", Recever Count = " + this.receiverCount);
sb.append(", Delay Time(ms) = " + this.errorDelayTimeMs);
sb.append(", Retry Count = " + this.retryCount);
sb.append(", Selector = " + this.messageSelector);
sb.append(", Description = " + this.description);
return sb.toString();
}
public FCRabbitMqReceiver(String rcvName, String qname, String errorqname, int rcvCount, int delayMs, int retryCnt,
boolean isTx, int ackMode, String msgSelector, String descr) throws Exception {
queueName = qname;
errorQueueName = errorqname;
receiverName = rcvName;
receiverCount = rcvCount;
errorDelayTimeMs = delayMs;
retryCount = retryCnt;
messageSelector = msgSelector;
description = descr;
// trim space
if (queueName != null)
queueName = queueName.trim();
if (errorQueueName != null)
errorQueueName = errorQueueName.trim();
if (receiverName != null)
receiverName = receiverName.trim();
if (messageSelector != null)
messageSelector = messageSelector.trim();
threadDowned = new boolean[receiverCount];
connection = new Connection[receiverCount];
channel = new Channel[receiverCount];
receiverObj = new ReceiverObject[receiverCount];
receiverThread = new Thread[receiverCount];
String clientId = receiverName;
String connectionUrl = "";
try {
if (isSingleApplication) {
if (logger.isDebug())
logger.debug("Local Application Test");
connectionUrl = "amqp://guest:guest@localhost:5672";
} else {
PropManager propManager = PropManager.getInstance();
connectionUrl = propManager.getProperty(RouteKeys.GROUP_NAME,
RouteKeys.ROUTING_QUEUE_CONNECTION_FACTORY);
}
} catch (Exception e) {
if (logger.isError())
logger.error("FCQueueReceiver: get InitialContext Error : ", e);
throw e;
}
if (logger.isInfo())
logger.info("RabbitMQ Connection : " + connectionUrl);
try {
// Create the connections
for (int i = 0; i < receiverCount; i++) {
factory = new ConnectionFactory();
factory.setUri(connectionUrl);
// create each connection
connection[i] = factory.newConnection();
// clientId = receiverName + instid + "-" + i;
// clientId = receiverName + "-" + i;
channel[i] = connection[i].createChannel();
channel[i].queueDeclare(queueName, false, false, false, null);
receiverObj[i] = new ReceiverObject(rcvName, i, channel[i], queueName, this.messageSelector,
this.errorQueueName, this.errorDelayTimeMs, this.retryCount, connectionUrl);
receiverObj[i].setName(clientId);
if (logger.isDebug())
logger.debug("[" + new java.util.Date() + "] Receiver Thread : [" + clientId + "] " + queueName);
receiverThread[i] = new Thread(receiverObj[i]);
receiverThread[i].setDaemon(true);// avoids thread leaks if
}
} catch (Exception e) {
if (logger.isError())
logger.error(" Exception while in constructor : ", e);
close();
throw e;
}
}
public synchronized void startReceiving() throws Exception {
if (!allThreadDowned) {
throw new Exception("Thread Started Already !");
}
try {
allThreadDowned = false;
} catch (Exception jmse) {
if (logger.isError()) {
logger.error("FCQueueReceiver: JMSException while in startReceiving() method : ", jmse);
}
close();
throw jmse;
}
}
public synchronized void clearReceived() {
// Clear Counter
for (int i = 0; i < receiverObj.length; i++) {
receiverObj[i].clearCount();
}
}
public synchronized void stopReceiving() {
// Cleanup each ReceiverObj (stops sending
for (int i = 0; i < receiverObj.length; i++) {
// stops each ReceiverObject
if (receiverObj[i] != null)
receiverObj[i].stopReceiver();
receiverObj[i].stopThread();
}
}
public String[][] getStatus() {
String[][] receiveStatus = new String[receiverObj.length][4];
for (int i = 0; i < receiverObj.length; i++) {
if (receiverObj[i] != null) {
receiveStatus[i][0] = receiverObj[i].getName();
receiveStatus[i][1] = "" + receiverObj[i].msgCounter;
receiveStatus[i][2] = "" + receiverObj[i].msgSuccessCounter;
receiveStatus[i][3] = "" + receiverObj[i].receiverStatus;
}
}
return receiveStatus;
}
public String[] getMessageCount() {
String[] receiveStatus = new String[2];
int receivedTotal = 0;
int successTotal = 0;
for (int i = 0; i < receiverObj.length; i++) {
if (receiverObj[i] != null) {
receivedTotal += receiverObj[i].msgCounter;
successTotal += receiverObj[i].msgSuccessCounter;
}
}
receiveStatus[0] = "" + receivedTotal;
receiveStatus[1] = "" + successTotal;
return receiveStatus;
}
/**
* Closes all connections which in turn stops the receivers and exits JVM
*/
public void close() {
for (int k = 0; k < channel.length; k++) {
try {
if (channel[k] != null) {
channel[k].close();
}
} catch (Exception ex) {
if (logger.isError()) {
logger.error("Exceptionchannel " + k + " message is " + ex.getMessage());
}
}
}
// Close all the connections before exiting the application
for (int i = 0; i < connection.length; i++) {
try {
if (connection[i] != null)
connection[i].close();
} catch (Exception ex) {
if (logger.isError()) {
logger.error("In exit(): Caught Exception trying to close connection(s)", ex);
}
}
}
}
// ////////////////////////////////////////////////////////////////////////
/**
* Inner class: ReceiverObject is an ASYNCHRONOUS receiver.
*/
// ////////////////////////////////////////////////////////////////////////
private class ReceiverObject extends Thread {
private String recvName = null;
private String queueName = null;
// Channel
private Channel channel = null;
private int id; // identifies the ReceiverObject
private int msgCounter = 0; // keeps track of messages
private int msgSuccessCounter = 0;
private int receiverStatus = 0; // 0 - wait, 1 - running, 2 - retry
private Object lockCounter = new Object();// used to synchronize
// updates of the message
// counter
private boolean keepRunning = false; // used to exit the sending loop
// in the run method
private String messageSelector = "";
private String errorQueueName = "";
private int errorDelayTimeMs = 0;
private int retryCount = 0;
private String queueConFactory = "";
/**
* Construct a ReceiverObject param id - the id number should be unique for each
* ReceiverObject param sess - the session object under which the receiver is
* created param q - the Queue object to receiver from
*/
public ReceiverObject(String recvName, int id, Channel channel, String queueName, String messageSelector,
String errorQueueName, int errorDelayMs, int retryCnt, String connectionUri) throws Exception {
init(recvName, id, channel, queueName, messageSelector, errorQueueName, errorDelayMs, retryCnt,
connectionUri);
}
public void init(String recvName, int sid, Channel channel, String queueName, String selector,
String errQueueName, int deplayMs, int retryCnt, String qConFactory) throws Exception {
this.recvName = recvName;
this.id = sid;
this.channel = channel;
this.queueName = queueName;
this.messageSelector = selector;
this.errorQueueName = errQueueName;
this.errorDelayTimeMs = deplayMs;
this.retryCount = retryCnt;
this.queueConFactory = qConFactory;
try {
logger.info("recvName=" + this.recvName + ",messageSelector=" + this.messageSelector);
} catch (Exception jmse) {
if (logger.isError())
logger.error(this.getName()
+ "] In ReceiverObject constructor: JMSException while setting up receiverObj[" + id + "]",
jmse);
close();
throw jmse;
}
}
/**
* Get number of message received since last get
*
* return totaSinceLastGet total number of messages received since the last get
*/
public int getMsgCount() {
synchronized (lockCounter) {
return msgCounter;
}
}
public void setMsgCount(int msgCounter) {
synchronized (lockCounter) {
this.msgCounter = msgCounter;
}
}
public void clearCount() {
synchronized (lockCounter) {
if (logger.isError()) {
logger.error(this.getName() + "] Clearing id: [" + id + "] clearing: " + msgCounter);
}
// reset counter
msgCounter = 0;
msgSuccessCounter = 0;
}
}
public void stopReceiver() {
// stop Receiver from sending which causes thread to exit run() method
// and thus finish.
keepRunning = false;
}
public void stopThread() {
// super.stop();
}
@Override
public void run() {
if (Thread.currentThread().getName().startsWith("Thread-")) {
Thread.currentThread().setName(queueName + "-" + Thread.currentThread().getName());
}
keepRunning = true;
threadDowned[id] = false;
EAIMessage eaiMessage = null;
while (keepRunning) {
try {
receiverStatus = 0;
GetResponse response = channel.basicGet(queueName, false);
if (response == null) {
Thread.sleep(500);
continue;
}
synchronized (lockCounter) {
receiverStatus = 1;
msgCounter++;
}
byte[] body = response.getBody();
try {
eaiMessage = (EAIMessage) SerializationUtils.deserialize(body);
} catch (Exception e) {
throw new RuntimeException(this.getName() + "] EAI메시지가 아닙니다. - " + e.getMessage());
}
// String guidLogPrefix = "RabbitMQ Receiver] GUID["+eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+eaiMessage.getSvcOgNo()+"] ";
String guidLogPrefix = "RabbitMQ Receiver] GUID["
+ eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage()) + "] UUID["
+ eaiMessage.getSvcOgNo() + "] ";
if (logger.isDebug()) {
logger.debug(this.getName() + "] receiverObj[" + id + "] Executed - " + eaiMessage.getEAISvcCd()
+ ":" + eaiMessage.getSvcOgNo());
}
RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm());
String serviceURI = routingVO.getSyncRoutingPath();
boolean isLocal = true;
HashMap<String, Object> headers = (HashMap<String, Object>) response.getProps().getHeaders();
Properties prop = new Properties();
try {
if (headers != null) {
for (String key : headers.keySet()) {
String propName = key;
String propValue = (String) headers.get(propName);
prop.setProperty(propName, propValue);
}
}
} catch (Exception e) {
throw new RuntimeException(this.getName() + "] 프라퍼티 설정에러 - " + e.getMessage());
}
EAIMessage resEAIMessage = null;
channel.basicAck(response.getEnvelope().getDeliveryTag(), false);
try {
// EAI 거래처리 Error 이고 retry count가 있으면 회수만큼 재시도
// errorDelayTimeMs > 0 면 sleep
int retry = 1;
// retry count 만큼 반복한다.
// -1 : 무한대 retry
// 0 : 처리되지 않는다.
if (this.retryCount == 0) {
if (logger.isWarn()) {
logger.warn(this.getName() + "] SKIP Execute EAISvcCd (" + eaiMessage.getEAISvcCd()
+ ") Retry Count - " + this.retryCount);
}
continue; // 처리를 중단한다.
} else if (this.retryCount > 1) {
receiverStatus = 2;
}
while (((retry <= this.retryCount) || (this.retryCount == -1)) && keepRunning) {
resEAIMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal,
prop);
if (resEAIMessage == null) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName()
+ "] response EAIMessage is NULL. SKIP Retry Count - " + this.retryCount);
}
break;
}
if (MessageUtil.checkRspErrCd(resEAIMessage.getRspErrCd())) {
break;
} else {
if ((this.retryCount > 0) && (retry <= this.retryCount)) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] Call Error("
+ resEAIMessage.getRspErrCd() + ") Retry - " + retry + "/"
+ this.retryCount);
}
// 다음 처리전에 delay를 준다.
if (this.errorDelayTimeMs > 0) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] Delay Before Retry - "
+ this.errorDelayTimeMs);
}
try {
Thread.sleep(this.errorDelayTimeMs);
} catch (Exception e) {
}
}
} else {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] FlowControl Call Error("
+ resEAIMessage.getRspErrCd() + ") No Retry");
}
}
}
retry++;
} // while(retry <= this.retryCount)
} catch (Exception e) {
if (resEAIMessage != null && logger.isError()) {
logger.error(guidLogPrefix + this.getName() + "] FlowControl Call Error("
+ resEAIMessage.getRspErrCd() + ") " + e.getMessage(), e);
}
}
if (response != null) {
// increment message counter
synchronized (lockCounter) {
msgSuccessCounter++;
}
response = null;
}
if (resEAIMessage != null) {
// EAI 거래처리 Error 면
// errorQueueName 이 있으면 redirect
// errorDelayTimeMs > 0 면 sleep
if (!MessageUtil.checkRspErrCd(resEAIMessage.getRspErrCd())) {
if (this.errorQueueName != null && this.errorQueueName.length() > 0) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] Redirect Messsage to - "
+ this.errorQueueName);
}
JMSSender.sendToQueue(eaiMessage, queueConFactory, this.errorQueueName, prop);
}
}
}
// 다음 처리 전에 delay를 준다.
if (this.errorDelayTimeMs > 0) {
if (logger.isWarn()) {
logger.warn(guidLogPrefix + this.getName() + "] Delay Before Receive Next Message - "
+ this.errorDelayTimeMs);
}
try {
Thread.sleep(this.errorDelayTimeMs);
} catch (Exception e) {
}
}
} catch (Exception ex) {
if (logger.isError()) {
logger.error(this.getName() + "] JMSException for receiverObj[" + id + "] - " + ex.getMessage(),
ex);
}
if (eaiMessage != null) {
// --------------------------------------------
// Set Error
String[] msgArgs = new String[1];
msgArgs[0] = eaiMessage.getEAISvcCd();
String rspErrorCode = "RECEAIFQR001"; // [EAI 서비스코드:{1}] 큐수신자가 플로우컨트롤 호출 중 오류 발생
String rspErrorMsg = ExceptionUtil.make(ex, rspErrorCode, msgArgs);
// eaiMessage.setRspErrCd(rspErrorCode);
// eaiMessage.setRspErrMsg(rspErrorMsg);
eaiMessage.setRspErr(rspErrorCode,rspErrorMsg);
// --------------------------------------------
// String mesgDmanDvcd = eaiMessage.getKbMsg().getKBHeader().getTelgmDmndDstcd();
// String mesgDmanDvcd = eaiMessage.getExtMsg().getSendRecv();
String mesgDmanDvcd = eaiMessage.getMapper()
.getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R
if (STDMessageKeys.SEND_RECV_CD_RECV.equals(mesgDmanDvcd)) {
// 응답인 경우
eaiMessage.setLogPssSno(400);
} else {
// 요청 인경우
eaiMessage.setLogPssSno(200);
}
try {
EAILogSender.send(eaiMessage, null);
} catch (Exception e) {
if (logger.isError())
logger.error(this.getName() + "] ErrorLogging :" + e.getMessage());
}
}
// auto reconnect so wait 10 seconds
try {
Thread.sleep(10000);
} catch (Exception e) {
// Do nothing
}
}
} // end of while
// if Stop Event Occurred
if (!keepRunning) {
threadDowned[id] = true;
synchronized (this) {
boolean tmpDowned = false;
for (int j = 0; j < threadDowned.length; j++) {
if (threadDowned[j]) {
tmpDowned = true;
} else {
tmpDowned = false;
break;
}
}
if (tmpDowned) {
allThreadDowned = true;
}
}
}
} // end of run
}// end of inner class ReceiverObject
}
@@ -0,0 +1,59 @@
package com.eactive.eai.flowcontrol.jms;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
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.server.EAIServerManager;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.data.entity.onl.flowcontrol.jms.QueueMonitor;
import com.eactive.eai.flowcontrol.jms.loader.QueueMonitorLoader;
import com.eactive.eai.flowcontrol.jms.mapper.QueueMonitorMapper;
@Service
@Transactional
public class QueueMonitorDAO extends BaseDAO {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
@Autowired
QueueMonitorLoader queueMonitorLoader;
@Autowired
QueueMonitorMapper queueMonitorMapper;
public Map<String, QueueMonitorVO> getAllQueue() throws DAOException {
boolean isScalable = BooleanUtils.toBoolean(System.getProperty("scalable"));
String serverName ="";
if(isScalable) {
serverName ="ALL";
}else {
serverName = EAIServerManager.getInstance().getLocalServerName();
}
try {
Map<String, QueueMonitorVO> queueMonitorMap = new HashMap<>();
logger.info("[ @@ Load QueueMonitor Configuration - starting >>>>>>>>>>>>>>>>> ]");
List<QueueMonitor> queueMonitors = queueMonitorLoader
.findByIdEaisevrinstncname(serverName);
for (QueueMonitor queueMonitor : queueMonitors) {
QueueMonitorVO queueMonitorVO = queueMonitorMapper.toVo(queueMonitor);
queueMonitorMap.put(queueMonitorVO.getQueueName() + queueMonitorVO.getSevrInstncName(), queueMonitorVO);
logger.info("@ " + queueMonitorVO.toString());
}
logger.info("[>>Load QueueMonitor getInflowMap Configuration - ended ]");
return queueMonitorMap;
} catch (Exception e) {
throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICCM101"));
}
}
}
@@ -0,0 +1,127 @@
package com.eactive.eai.flowcontrol.jms;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.eactive.eai.common.dao.DAOException;
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.util.ApplicationContextProvider;
import com.eactive.eai.common.util.Logger;
@Component
public class QueueMonitorManager implements Lifecycle {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
private Map<String, QueueMonitorVO> queueVos = new HashMap<>();
@Autowired
QueueMonitorDAO queueMonitorDAO;
private LifecycleSupport lifecycle = new LifecycleSupport(this);
private boolean started;
public static QueueMonitorManager getInstance() {
return ApplicationContextProvider.getContext().getBean(QueueMonitorManager.class);
}
public void start() throws LifecycleException {
if (started)
throw new LifecycleException("RECEAICFM201");
lifecycle.fireLifecycleEvent(STARTING_EVENT, this);
try {
queueVos = queueMonitorDAO.getAllQueue();
} catch (DAOException e) {
throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICFM202"));
}
started = true;
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(STARTED_EVENT, this);
}
public void stop() throws LifecycleException {
// Validate and update our current component state
if (!started)
throw new LifecycleException("RECEAICFM203");
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(STOPING_EVENT, this);
queueVos.clear();
started = false;
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(STOPPED_EVENT, this);
}
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 QueueMonitorVO getQueueMonitor(String qName) {
if (qName == null)
return null;
return queueVos.get(qName);
}
public void setQueueMonitor(QueueMonitorVO vo) throws Exception {
try {
QueueMonitorVO queueVo = queueVos.get(vo.getQueueName());
if (queueVo == null) {
queueVos.put(vo.getQueueName(), vo);
} else {
queueVo.setMaxCount(vo.getMaxCount());
queueVo.setQueBzwkCtnt(vo.getQueBzwkCtnt());
queueVo.setQueUseYn(vo.getQueUseYn());
queueVo.setQueUsagDstcd(vo.getQueUsagDstcd());
queueVo.setBzwkDstcd(vo.getBzwkDstcd());
queueVo.setQueBzwkDtalsCtnt(vo.getQueBzwkDtalsCtnt());
queueVo.setSevrInstncName(vo.getSevrInstncName());
queueVos.put(queueVo.getQueueName(), queueVo);
}
} catch (Exception e) {
String message = "QueueMonitorManager] Error Occurred while setQueueMonitor[" + vo.getQueueName() + "] - "
+ e.getMessage();
logger.error(message, e);
throw new Exception(message);
}
}
public void removeQueueMonitor(String qName) throws Exception {
try {
queueVos.remove(qName);
} catch (Exception e) {
String message = "QueueMonitorManager] Error Occurred while remove[" + qName + "] - " + e.getMessage()
+ "] - " + e.getMessage();
logger.error(message, e);
throw new Exception(message);
}
}
public Map<String, QueueMonitorVO> getAllQueueMonitorVos() {
return this.queueVos;
}
}
@@ -0,0 +1,144 @@
package com.eactive.eai.flowcontrol.jms;
import java.io.Serializable;
public class QueueMonitorVO implements Serializable {
private static final long serialVersionUID = 1L;
private String queueName; // Queue Name
private long currentCount; // 모니터링 현재값
private long previousCount; // 모니터링 이전값
private long maxCount; // EAI큐임계치값
private String queBzwkCtnt; // EAI큐업무내용
private String queUseYn; // 큐사용여부
private String queUsagDstcd; // 큐용도구분코드
private String bzwkDstcd; // EAI업무구분코드
private String queBzwkDtalsCtnt; // EAI큐업무세부내용
private String sevrInstncName; // EAI서버인스턴스명
public QueueMonitorVO(String qName, long max) {
queueName = qName;
currentCount = 0;
previousCount = 0;
maxCount = max;
}
public long getCurrentCount() {
return currentCount;
}
public void setCurrentCount(long currentCount) {
this.previousCount = this.currentCount;
this.currentCount = currentCount;
}
public long getMaxCount() {
return maxCount;
}
public void setMaxCount(long maxCount) {
this.maxCount = maxCount;
}
public long getPreviousCount() {
return previousCount;
}
public void setPreviousCount(long previousCount) {
this.previousCount = previousCount;
}
public String getQueueName() {
return queueName;
}
public void setQueueName(String queueName) {
this.queueName = queueName;
}
public int checkCount() {
int status = 0; // 정상상태
// 이상 Alert
if ((previousCount < maxCount) && (currentCount >= maxCount)) {
status = 1;
}
// 이상상태 계속
else if ((previousCount >= maxCount) && (currentCount >= maxCount)) {
status = 2;
}
// 이상상태 복구 Alert
else if ((previousCount >= maxCount) && (currentCount < maxCount)) {
status = 3;
}
return status;
}
public String getBzwkDstcd() {
return bzwkDstcd;
}
public void setBzwkDstcd(String bzwkDstcd) {
this.bzwkDstcd = bzwkDstcd;
}
public String getQueBzwkCtnt() {
return queBzwkCtnt;
}
public void setQueBzwkCtnt(String queBzwkCtnt) {
this.queBzwkCtnt = queBzwkCtnt;
}
public String getQueBzwkDtalsCtnt() {
return queBzwkDtalsCtnt;
}
public void setQueBzwkDtalsCtnt(String queBzwkDtalsCtnt) {
this.queBzwkDtalsCtnt = queBzwkDtalsCtnt;
}
public String getQueUsagDstcd() {
return queUsagDstcd;
}
public void setQueUsagDstcd(String queUsagDstcd) {
this.queUsagDstcd = queUsagDstcd;
}
public String getQueUseYn() {
return queUseYn;
}
public void setQueUseYn(String queUseYn) {
this.queUseYn = queUseYn;
}
public String getSevrInstncName() {
return sevrInstncName;
}
public void setSevrInstncName(String sevrInstncName) {
this.sevrInstncName = sevrInstncName;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("queueName=").append(queueName).append(",");
sb.append("currentCount=").append(currentCount).append(",");
sb.append("previousCount=").append(previousCount).append(",");
sb.append("maxCount=").append(maxCount).append(",");
sb.append("queBzwkCtnt=").append(queBzwkCtnt).append(",");
sb.append("queUseYn=").append(queUseYn).append(",");
sb.append("queUsagDstcd=").append(queUsagDstcd).append(",");
sb.append("bzwkDstcd=").append(bzwkDstcd).append(",");
sb.append("queBzwkDtalsCtnt=").append(queBzwkDtalsCtnt).append(",");
sb.append("sevrInstncName=").append(sevrInstncName);
return sb.toString();
}
}
@@ -0,0 +1,29 @@
package com.eactive.eai.flowcontrol.jms.mapper;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import com.eactive.eai.data.entity.onl.flowcontrol.jms.FCQueueReceiver;
import com.eactive.eai.data.mapper.BaseMapperConfig;
import com.eactive.eai.data.mapper.GenericMapper;
import com.eactive.eai.flowcontrol.jms.FCQueueReceiverVO;
@Mapper(config = BaseMapperConfig.class)
public interface FCQueueReceiverMapper extends GenericMapper<FCQueueReceiverVO, FCQueueReceiver> {
@Mapping(source = "quercvername", target = "receiverName")
@Mapping(source = "bascquercveryn", target = "bascQueRcverYn")
@Mapping(source = "eaisevrinstncname", target = "eaiSevrInstncName")
@Mapping(source = "nonsyncztranobstclquename", target = "errorQueueName")
@Mapping(source = "nonsyncztranquename", target = "queueName")
@Mapping(source = "quemsgselctctnt", target = "messageSelector")
@Mapping(source = "quercvercnt", target = "receiverCount")
@Mapping(source = "quercverdtalsctnt", target = "description")
@Mapping(source = "senddlayttmval", target = "errorDelayTimeMs")
@Mapping(source = "sendretralnotms", target = "retryCount")
@Override
FCQueueReceiverVO toVo(FCQueueReceiver entity);
@InheritInverseConfiguration
FCQueueReceiver toEntity(FCQueueReceiverVO vo);
}
@@ -0,0 +1,27 @@
package com.eactive.eai.flowcontrol.jms.mapper;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import com.eactive.eai.data.entity.onl.flowcontrol.jms.QueueMonitor;
import com.eactive.eai.data.mapper.BaseMapperConfig;
import com.eactive.eai.data.mapper.GenericMapper;
import com.eactive.eai.flowcontrol.jms.QueueMonitorVO;
@Mapper(config = BaseMapperConfig.class)
public interface QueueMonitorMapper extends GenericMapper<QueueMonitorVO, QueueMonitor> {
@Mapping(source = "id.nonsyncztranquename", target = "queueName")
@Mapping(source = "id.eaisevrinstncname", target = "sevrInstncName")
@Mapping(source = "eaibzwkdstcd", target = "bzwkDstcd")
@Mapping(source = "eaiquebzwkctnt", target = "queBzwkCtnt")
@Mapping(source = "eaiquebzwkdtalsctnt", target = "queBzwkDtalsCtnt")
@Mapping(source = "eaiquecrtcnmvlval", target = "maxCount")
@Mapping(source = "queusagdstcd", target = "queUsagDstcd")
@Mapping(source = "queuseyn", target = "queUseYn")
@Override
QueueMonitorVO toVo(QueueMonitor entity);
@InheritInverseConfiguration
QueueMonitor toEntity(QueueMonitorVO vo);
}
@@ -0,0 +1,131 @@
package com.eactive.eai.flowcontrol.websphere;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.routing.ElinkESBProcessProxy;
import com.eactive.eai.common.routing.RoutingManager;
import com.eactive.eai.common.routing.RoutingVO;
import com.eactive.eai.common.util.Logger;
import javax.jms.*;
import java.util.Enumeration;
import java.util.Properties;
import java.lang.IllegalStateException;
public class DefaultQueueConsumer implements Runnable, ExceptionListener {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
Connection connection = null;
Session session = null;
MessageConsumer consumer = null;
String name = null;
String queue = null;
boolean run = true;
public DefaultQueueConsumer(String name, Connection con, String queue) {
this.connection = con;
try {
this.name = name;
this.queue = queue;
connection.start();
connection.setExceptionListener(this);
// Create a Session
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create the destination (Topic or Queue)
Destination destination = session.createQueue(queue);
consumer = session.createConsumer(destination);
} catch (JMSException e) {
logger.error(e);
}
}
@Override
public void run() {
EAIMessage eaiMessage = null;
while(run) {
try {
Message message = consumer.receive(2000);
ObjectMessage omsg = null;
if(message == null) {
// logger.warn(name + " -> EMPTY MESSAGE...");
continue;
}
if(message instanceof ObjectMessage) {
omsg = (ObjectMessage)message;
} else {
throw new RuntimeException(name+" Invlid JMS Message Type. - "+message);
}
try {
eaiMessage = (EAIMessage)omsg.getObject();
} catch(Exception e) {
throw new RuntimeException(name+" Invlid value object in ObjectMessage. - "+e.getMessage() );
}
// String guidLogPrefix = "GUID["+eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+eaiMessage.getSvcOgNo()+"] ";
String guidLogPrefix = "GUID["+ eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage()) +"] UUID["+eaiMessage.getSvcOgNo()+"] ";
RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm());
String serviceURI = routingVO.getSyncRoutingPath();
boolean isLocal = true;
Properties prop = new Properties();
try {
Enumeration en = omsg.getPropertyNames();
for (; en.hasMoreElements(); ) {
String propName = (String)en.nextElement();
String propValue = omsg.getStringProperty(propName);
prop.setProperty(propName, propValue);
}
} catch(JMSException e) {
throw new RuntimeException(name+" onMessage Error. - "+e.getMessage());
}
try {
if(logger.isInfo()) logger.info("Websphere JMS Receiver : " + guidLogPrefix + eaiMessage);
eaiMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal, prop);
} catch(Exception e) {
throw new RuntimeException("Websphere JMS Receiver : " + guidLogPrefix +name+" onMessage Error. - "+e.getMessage());
}
}
catch(IllegalStateException ise) {
logger.error(name+" IllegalStateException = " + ise.getMessage(), ise);
}
catch(JMSException e) {
logger.error(name+" JMSException = " + e.getMessage(), e);
run = false;
}
catch(RuntimeException e) {
logger.error(name+" RuntimeException = " + e.getMessage(), e);
}
}
}
public void stop() {
run = false;
if(consumer != null)
try {
consumer.close();
} catch (JMSException e) { }
if(session != null)
try {
session.close();
} catch (JMSException e) { }
if(connection != null)
try {
connection.close();
} catch (JMSException e) { }
}
@Override
public void onException(JMSException arg0) {
logger.error("JMS Exception occured. Shutting down client.");
stop();
}
}
@@ -0,0 +1,121 @@
package com.eactive.eai.flowcontrol.websphere;
import com.eactive.eai.common.util.Logger;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import javax.jms.Connection;
import javax.jms.QueueConnectionFactory;
import javax.jms.Session;
import javax.naming.InitialContext;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class QueueConsumerService implements InitializingBean, DisposableBean {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
private String uri;
private String queue;
private int maxThread;
Connection connection = null;
Session[] sessions = null;
DefaultQueueConsumer[] consumers = null;
public final static String JNDI_FACTORY = "com.ibm.websphere.naming.WsninittialContextFactory";
ExecutorService es = null;
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getQueue() {
return queue;
}
public void setQueue(String queue) {
this.queue = queue;
}
public int getMaxThread() {
return maxThread;
}
public void setMaxThread(int maxThread) {
this.maxThread = maxThread;
}
@Override
public void afterPropertiesSet() throws Exception {
startConsumer();
}
@Override
public void destroy() throws Exception {
stopConsumer();
}
public void startConsumer() {
try {
InitialContext ctx = new InitialContext();
QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx.lookup(uri);
es = Executors.newFixedThreadPool(maxThread);
connection = connectionFactory.createConnection();
connection.start();
consumers = new DefaultQueueConsumer[maxThread];
for(int i=0; i<maxThread; i++) {
DefaultQueueConsumer consumer = new DefaultQueueConsumer("WebsphereJMS-" +i, connection, queue);
es.submit(consumer);
consumers[i] = consumer;
}
logger.info("Start Websphere JMS QueueListener [ uri=" + uri +
", queue="+queue + ", maxthread=" + maxThread+"] and wait for listening");
}
catch(Exception ex) {
logger.error("startConsumer error", ex);
}
}
public void stopConsumer() {
for(int i=0; i<maxThread; i++) {
try {
consumers[i].stop();
} catch (Exception e) {
logger.warn(e.getMessage());
}
}
if(es != null) {
es.shutdown();
}
es = null;
}
// public static void main(String args[]) throws Exception {
// test();
//}
// private static void test() throws Exception {
// QueueConsumerService service = new QueueConsumerService();
// service.setUri("xxx");
// service.setQueue("TESTQ1");
// service.setMaxThread(10);
// service.startConsumer();
//
// Thread.sleep(2 * 1000);
//
// service.stopConsumer();
//
// Thread.sleep(2 * 1000);
// }
}