/* * Copyright (c) 2006-2007 Massachusetts General Hospital * All rights reserved. This program and the accompanying materials * are made available under the terms of the i2b2 Software License v1.0 * which accompanies this distribution. * * Contributors: * Rajesh Kuttan */ package edu.harvard.i2b2.crc.ejb; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import javax.xml.bind.JAXBElement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.harvard.i2b2.common.exception.I2B2DAOException; import edu.harvard.i2b2.common.exception.I2B2Exception; import edu.harvard.i2b2.common.util.ServiceLocator; import edu.harvard.i2b2.common.util.jaxb.JAXBUtil; import edu.harvard.i2b2.crc.dao.DAOFactoryHelper; import edu.harvard.i2b2.crc.dao.IDAOFactory; import edu.harvard.i2b2.crc.dao.SetFinderDAOFactory; import edu.harvard.i2b2.crc.dao.setfinder.CheckSkipTempTable; import edu.harvard.i2b2.crc.dao.setfinder.IQueryInstanceDao; import edu.harvard.i2b2.crc.dao.setfinder.QueryExecutorDao; import edu.harvard.i2b2.crc.datavo.CRCJAXBUtil; import edu.harvard.i2b2.crc.datavo.db.DataSourceLookup; import edu.harvard.i2b2.crc.datavo.db.QtQueryInstance; import edu.harvard.i2b2.crc.datavo.i2b2message.InfoType; import edu.harvard.i2b2.crc.datavo.i2b2message.PollingUrlType; import edu.harvard.i2b2.crc.datavo.i2b2message.RequestHeaderType; import edu.harvard.i2b2.crc.datavo.i2b2message.RequestMessageType; import edu.harvard.i2b2.crc.datavo.i2b2message.ResponseHeaderType; import edu.harvard.i2b2.crc.datavo.i2b2message.ResponseMessageType; import edu.harvard.i2b2.crc.datavo.i2b2message.ResultStatusType; import edu.harvard.i2b2.crc.datavo.i2b2message.StatusType; import edu.harvard.i2b2.crc.datavo.setfinder.query.PsmQryHeaderType; import edu.harvard.i2b2.crc.datavo.setfinder.query.QueryDefinitionRequestType; import edu.harvard.i2b2.crc.datavo.setfinder.query.QueryModeType; import edu.harvard.i2b2.crc.datavo.setfinder.query.ResultOutputOptionListType; import edu.harvard.i2b2.crc.util.QueryProcessorUtil; public class QueryManagerBeanUtil { /** log **/ protected final Log log = LogFactory.getLog(getClass()); public final static String RESPONSE_QUEUE_NAME = "queue/jms.querytool.QueryResponse"; // public final static String UPLOADPROCESSOR_QUEUE_NAME = // "queue/jms.querytool.QueryExecutor"; public final static String SMALL_QUEUE_NAME = "queue/jms.querytool.QueryExecutorSmall"; public final static String MEDIUM_QUEUE_NAME = "queue/jms.querytool.QueryExecutorMedium"; public final static String LARGE_QUEUE_NAME = "queue/jms.querytool.QueryExecutorLarge"; public final static String QUEUE_CONN_FACTORY_NAME = "ConnectionFactory"; public final static String QUERY_MASTER_GENERATED_SQL_PARAM = "QUERY_MASTER_GENERATED_SQL_PARAM"; public final static String QUERY_INSTANCE_ID_PARAM = "QUERY_INSTANCE_ID_PARAM"; public final static String QUERY_PATIENT_SET_ID_PARAM = "QUERY_PATIENT_SET_ID_PARAM"; public final static String XML_REQUEST_PARAM = "XML_REQUEST_PARAM"; public final static String DS_LOOKUP_DOMAIN_ID = "DS_LOOKUP_DOMAIN_ID"; public final static String DS_LOOKUP_PROJECT_ID = "DS_LOOKUP_PROJECT_ID"; public final static String DS_LOOKUP_OWNER_ID = "DS_LOOKUP_OWNER_ID"; public static final String QUEUED = "QUEUED"; public static final String SMALL_QUEUE = "SMALL_QUEUE"; public static final String MEDIUM_QUEUE = "MEDIUM_QUEUE"; public static final String LARGE_QUEUE = "LARGE_QUEUE"; public final static String QUERY_STATUS_PARAM = "QUERY_STATUS_PARAM"; public final static String QT_QUERY_RESULT_INSTANCE_ID_PARAM = "QT_QUERY_RESULT_INSTANCE_ID_PARAM"; public QueryManagerBeanUtil() { } public Map testSend(String domainId, String projectId, String ownerId, String generatedSql, String sessionId, String queryInstanceId, String patientSetId, String xmlRequest, long timeout) throws Exception { String status = null; int queryResultInstanceId = 0; log.debug("in testSend"); QueryProcessorUtil qpUtil = QueryProcessorUtil.getInstance(); ServiceLocator serviceLocator = ServiceLocator.getInstance(); /* QueueConnection conn = serviceLocator.getQueueConnectionFactory( QUEUE_CONN_FACTORY_NAME).createQueueConnection(); Queue sendQueue = serviceLocator.getQueue(SMALL_QUEUE_NAME); Queue responseQueue = serviceLocator.getQueue(RESPONSE_QUEUE_NAME); QueueSession session = conn.createQueueSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE); String id = sessionId; String selector = "JMSCorrelationID='" + id + "'"; QueueSender sender = session.createSender(sendQueue); MapMessage mapMsg = session.createMapMessage(); mapMsg.setJMSCorrelationID(id); mapMsg.setJMSReplyTo(responseQueue); mapMsg.setString(XML_REQUEST_PARAM, xmlRequest); mapMsg.setString(QUERY_MASTER_GENERATED_SQL_PARAM, generatedSql); mapMsg.setString(QUERY_INSTANCE_ID_PARAM, queryInstanceId); mapMsg.setString(QUERY_PATIENT_SET_ID_PARAM, patientSetId); mapMsg.setString(DS_LOOKUP_DOMAIN_ID, domainId); mapMsg.setString(DS_LOOKUP_PROJECT_ID, projectId); mapMsg.setString(DS_LOOKUP_OWNER_ID, ownerId); sender.send(mapMsg); QueueConnection conn1 = serviceLocator.getQueueConnectionFactory( QUEUE_CONN_FACTORY_NAME).createQueueConnection(); conn1.start(); QueueSession recvSession = conn1.createQueueSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE); QueueReceiver rcvr = recvSession .createReceiver(responseQueue, selector); MapMessage receivedMsg = (MapMessage) rcvr.receive(timeout); if (receivedMsg == null) { status = "RUNNING"; log.info("STATUS IS RUNNING " + status); } else { String responseObj = (String) receivedMsg.getString("para1"); status = (String) receivedMsg .getString(QueryManagerBeanUtil.QUERY_STATUS_PARAM); log.debug("Got back response from executor " + responseObj); if (status != null && status.indexOf("LOCKEDOUT") > -1) { ; } else { status = "DONE"; } queryResultInstanceId = receivedMsg .getInt(QT_QUERY_RESULT_INSTANCE_ID_PARAM); log.info("RESULT INSTANCE ID " + queryResultInstanceId); } */ //TODO mm bypass JMS and call directly long waitTime = getTimeout(xmlRequest); ExecRunnable exec = new ExecRunnable(); exec.execute(generatedSql, queryInstanceId, patientSetId, xmlRequest, domainId, projectId, ownerId); Thread t = new Thread(exec); synchronized (t) { t.start(); try { //if (waitTime > 0) { // t.wait(waitTime); //} else { // t.wait(); //} long startTime = System.currentTimeMillis(); long deltaTime = -1; while((exec.isJobCompleteFlag() == false)&& (deltaTime < waitTime)){ if (waitTime > 0) { t.wait(waitTime - deltaTime); deltaTime = System.currentTimeMillis() - startTime; } else { t.wait(); } } if (exec.isJobCompleteFlag() == false) { String timeOuterror = "Result waittime millisecond <result_waittime_ms> :" + waitTime + " elapsed, setting to next queue"; log.debug(timeOuterror); DAOFactoryHelper daoFactoryHelper = new DAOFactoryHelper( domainId, projectId, ownerId); IDAOFactory daoFactory = daoFactoryHelper.getDAOFactory(); SetFinderDAOFactory sfDAOFactory = daoFactory .getSetFinderDAOFactory(); //DataSourceLookup dsLookup = sfDAOFactory.getDataSourceLookup(); // check if the status is cancelled IQueryInstanceDao queryInstanceDao = sfDAOFactory .getQueryInstanceDAO(); QtQueryInstance queryInstance = queryInstanceDao .getQueryInstanceByInstanceId(queryInstanceId); queryInstance.setBatchMode(MEDIUM_QUEUE); //queryInstance.setEndDate(new Date(System // .currentTimeMillis())); queryInstanceDao.update(queryInstance, false); log.debug("Set to MEDIUM Queue"); Map returnMap = new HashMap(); returnMap.put(QUERY_STATUS_PARAM, "RUNNING"); int id = Integer.parseInt(queryInstanceId); returnMap.put(QT_QUERY_RESULT_INSTANCE_ID_PARAM, id); return returnMap; //throw new Exception("Timed Out, setting to MEDIUM Queue"); } } catch (InterruptedException e) { log.error("Error in thread: " + e.getMessage()); e.printStackTrace(); throw new I2B2Exception("Thread error while running CRC job " , e); } finally { t.interrupt(); //exec = null; t = null; } } // closeAll(sender, null, conn, session); // closeAll(null, rcvr, conn1, recvSession); // closeAllTopic(rcvr,conn1,recvSession); //MM // Map returnMap = new HashMap(); // returnMap.put(QUERY_STATUS_PARAM, status); // returnMap.put(QT_QUERY_RESULT_INSTANCE_ID_PARAM, queryResultInstanceId); // return returnMap; return exec.getResult(); } /* * public String buildQueryRequestResponse(String requestXml, String * status,String sessionId,String masterId, String * queryInstanceId,ResultResponseType resultResponseType) throws Exception { * return buildObject(requestXml, status, sessionId, * masterId,queryInstanceId,resultResponseType ); } */ public void writerRepsonseFile(String sessionId, long recordCount) { try { BufferedWriter bw = new BufferedWriter(new FileWriter(sessionId)); bw.write(String.valueOf(recordCount)); bw.close(); } catch (IOException ioE) { ioE.printStackTrace(); } } public long getTimeout(String xmlRequest) throws Exception { JAXBUtil jaxbUtil = CRCJAXBUtil.getJAXBUtil(); JAXBElement jaxbElement = jaxbUtil.unMashallFromString(xmlRequest); RequestMessageType requestMessageType = (RequestMessageType) jaxbElement .getValue(); RequestHeaderType requestHeader = requestMessageType.getRequestHeader(); long timeOut = 1; if (requestHeader != null && requestHeader.getResultWaittimeMs() > -1) { timeOut = requestHeader.getResultWaittimeMs(); } return timeOut; } public DataSourceLookup getDataSourceLookupInput(String xmlRequest) throws Exception { DataSourceLookup dsLookupInput = null; JAXBUtil jaxbUtil = CRCJAXBUtil.getJAXBUtil(); JAXBElement jaxbElement = jaxbUtil.unMashallFromString(xmlRequest); RequestMessageType requestMessageType = (RequestMessageType) jaxbElement .getValue(); String projectId = requestMessageType.getMessageHeader().getProjectId(); String domainId = requestMessageType.getMessageHeader().getSecurity() .getDomain(); String ownerId = requestMessageType.getMessageHeader().getSecurity() .getUsername(); dsLookupInput = new DataSourceLookup(); dsLookupInput.setProjectPath(projectId); dsLookupInput.setDomainId(domainId); dsLookupInput.setOwnerId(ownerId); return dsLookupInput; } public String getStatus(String sessionId) { String status = "UNKNOWN"; // check directory File file = new File(sessionId); if (file.exists()) { status = "DONE"; } else { //TODO removed JMS // QueueConnection conn1 = null; // Queue responseQueue = null; // QueueSession recvSession = null; // QueueReceiver rcvr = null; try { // check jms QueryProcessorUtil qpUtil = QueryProcessorUtil.getInstance(); ServiceLocator serviceLocator = ServiceLocator.getInstance(); /* conn1 = serviceLocator.getQueueConnectionFactory( "ConnectionFactory").createQueueConnection(); conn1.start(); responseQueue = serviceLocator.getQueue(RESPONSE_QUEUE_NAME); recvSession = conn1.createQueueSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE); // TopicSubscriber rcvr = // recvSession.createSubscriber(responseTopic,selector,false); rcvr = recvSession.createReceiver(responseQueue); String selector = "JMSCorrelationID='" + sessionId + "'"; log.debug("SessionId getResult" + sessionId); recvSession.createReceiver(responseQueue, selector); MapMessage receivedMsg = (MapMessage) rcvr.receiveNoWait(); if (receivedMsg == null) { log.debug("No Reply Message Received"); status = "PROCESSING"; } else { String responseObj = (String) receivedMsg .getString("para1"); log.debug("got back response from executor " + responseObj); status = "DONE"; } */ } catch (Exception e) { status = "ERROR"; e.printStackTrace(); } finally { // closeAll(null, rcvr, conn1, recvSession); } } return status; } public String buildGetQueryResultResponse(String sessionId, String status) { StringWriter strWriter = new StringWriter(); // build infotype InfoType infoType = new InfoType(); infoType.setUrl(""); infoType.setValue(""); ResultStatusType rsType = new ResultStatusType(); StatusType st = new StatusType(); st.setType(sessionId); st.setValue(status); rsType.setStatus(st); PollingUrlType pollUrlType = new PollingUrlType(); pollUrlType .setValue("http://localhost:9093/queryProcessor/checkStatus"); rsType.setPollingUrl(pollUrlType); // MessageType messageType = dtoFactory.buildMessageType(infoType, // rsType); ResponseHeaderType responseHeader = new ResponseHeaderType(); responseHeader.setInfo(infoType); responseHeader.setResultStatus(rsType); ResponseMessageType responseMessageType = new ResponseMessageType(); responseMessageType.setResponseHeader(responseHeader); try { JAXBUtil jaxbUtil = CRCJAXBUtil.getJAXBUtil(); edu.harvard.i2b2.crc.datavo.i2b2message.ObjectFactory of = new edu.harvard.i2b2.crc.datavo.i2b2message.ObjectFactory(); jaxbUtil.marshaller(of.createResponse(responseMessageType), strWriter); log.debug("i2b2 Response XML " + strWriter.toString()); } catch (Exception e) { e.printStackTrace(); } return strWriter.toString(); } /* public void closeAll(QueueSender send, QueueReceiver recv, QueueConnection conn, QueueSession session) { try { if (send != null) { send.close(); } if (recv != null) { recv.close(); } if (conn != null) { conn.stop(); if (conn != null) { conn.close(); } } if (session != null) { session.close(); } } catch (JMSException jmse) { jmse.printStackTrace(); } } */ }