package edu.harvard.i2b2.crc.dao.setfinder;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import javax.xml.bind.JAXBElement;
import org.apache.axis2.AxisFault;
import org.springframework.beans.factory.BeanFactory;
import com.microsoft.sqlserver.jdbc.SQLServerException;
import edu.harvard.i2b2.common.exception.I2B2DAOException;
import edu.harvard.i2b2.common.exception.I2B2Exception;
import edu.harvard.i2b2.common.exception.StackTraceUtil;
import edu.harvard.i2b2.common.util.ServiceLocator;
import edu.harvard.i2b2.common.util.jaxb.JAXBUtilException;
import edu.harvard.i2b2.crc.dao.CRCDAO;
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.querybuilder.ProcessTimingReportUtil;
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.db.QtQueryResultInstance;
import edu.harvard.i2b2.crc.datavo.db.QtQueryStatusType;
import edu.harvard.i2b2.crc.datavo.i2b2message.RequestMessageType;
import edu.harvard.i2b2.crc.datavo.i2b2message.SecurityType;
import edu.harvard.i2b2.crc.datavo.pm.ProjectType;
import edu.harvard.i2b2.crc.datavo.pm.RoleType;
import edu.harvard.i2b2.crc.datavo.pm.RolesType;
import edu.harvard.i2b2.crc.datavo.setfinder.query.ResultOutputOptionListType;
import edu.harvard.i2b2.crc.datavo.setfinder.query.ResultOutputOptionType;
import edu.harvard.i2b2.crc.delegate.ejbpm.EJBPMUtil;
import edu.harvard.i2b2.crc.delegate.ontology.CallOntologyUtil;
import edu.harvard.i2b2.crc.delegate.pm.CallPMUtil;
import edu.harvard.i2b2.crc.ejb.role.MissingRoleException;
import edu.harvard.i2b2.crc.role.AuthrizationHelper;
import edu.harvard.i2b2.crc.util.I2B2RequestMessageHelper;
import edu.harvard.i2b2.crc.util.LogTimingUtil;
import edu.harvard.i2b2.crc.util.PMServiceAccountUtil;
import edu.harvard.i2b2.crc.util.QueryProcessorUtil;
/**
* This class executes the setfinder query's panel sql. The temp table stores
* the patient/visits for the query and the temp table will be passed to rest of
* the result type generator class.
*
*/
public class QueryExecutorHelperDao extends CRCDAO {
private DataSourceLookup dataSourceLookup = null,
originalDataSourceLookup = null;
private static Map generatorMap = null;
private static String defaultResultType = null;
private String processTimingFlag = ProcessTimingReportUtil.NONE;
private ProcessTimingReportUtil ptrUtil = null;
private boolean queryWithoutTempTableFlag = false;
static {
QueryProcessorUtil qpUtil = QueryProcessorUtil.getInstance();
BeanFactory bf = qpUtil.getSpringBeanFactory();
generatorMap = (Map) bf.getBean("setFinderResultGeneratorMap");
defaultResultType = (String) bf.getBean("defaultSetfinderResultType");
}
public QueryExecutorHelperDao(DataSource dataSource,
DataSourceLookup dataSourceLookup,
DataSourceLookup originalDataSourceLookup) {
setDataSource(dataSource);
setDbSchemaName(dataSourceLookup.getFullSchema());
this.dataSourceLookup = dataSourceLookup;
this.originalDataSourceLookup = originalDataSourceLookup;
}
public void setProcessTimingFlag(String processTimingFlag) {
this.processTimingFlag = processTimingFlag;
try {
ptrUtil = new ProcessTimingReportUtil(dataSourceLookup);
} catch (I2B2DAOException e) {
log.error("Error trying to construct ProcessTimingReportUtil" + e.getMessage());
}
}
public void setQueryWithoutTempTableFlag(boolean queryWithoutTempTableFlag) {
this.queryWithoutTempTableFlag = queryWithoutTempTableFlag;
}
/**
* Execute the Panel's sql to write the patient/visit list into the temp
* table.
*
* And then pass this temp table data to rest of the result type generator.
*
* @param transaction
* @param transactionTimeout
* @param dsLookup
* @param sfDAOFactory
* @param requestXml
* @param sqlString
* @param queryInstanceId
* @param patientSetId
* @param resultOutputList
* @param generatedSql
* @param tm
* @param ut
* @throws CRCTimeOutException
* @throws I2B2DAOException
*/
public void executeQuery(
int transactionTimeout, DataSourceLookup dsLookup,
SetFinderDAOFactory sfDAOFactory, String requestXml,
String sqlString, String queryInstanceId, String patientSetId,
ResultOutputOptionListType resultOutputList, String generatedSql, String pmXml
)
throws CRCTimeOutException, I2B2DAOException {
boolean errorFlag = false, timeOutErrorFlag = false;
Statement stmt = null;
ResultSet resultSet = null;
Connection manualConnection = null;
String singleSql = null;
int recordCount = 0, obfuscatedRecordCount = 0;
transactionTimeout = 7200;
/** Global temp table to store intermediate setfinder results* */
String TEMP_TABLE = "#GLOBAL_TEMP_TABLE";
/** Global temp table to store intermediate patient list * */
String TEMP_DX_TABLE = "#DX";
String TEMP_MASTER_TABLE = "#MASTER_GLOBAL_TEMP_TABLE";
if (dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.SQLSERVER)) {
TEMP_TABLE = getDbSchemaName() + "#GLOBAL_TEMP_TABLE";
TEMP_DX_TABLE = getDbSchemaName() + "#DX";
TEMP_MASTER_TABLE = getDbSchemaName() + "#MASTER_GLOBAL_TEMP_TABLE";
} else if (dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.ORACLE) ) {
TEMP_TABLE = getDbSchemaName() + "QUERY_GLOBAL_TEMP";
TEMP_DX_TABLE = getDbSchemaName() + "DX";
TEMP_MASTER_TABLE = getDbSchemaName() + "MASTER_QUERY_GLOBAL_TEMP";
} else if (dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.POSTGRESQL) ) {
TEMP_TABLE = "QUERY_GLOBAL_TEMP";
TEMP_DX_TABLE = "DX";
TEMP_MASTER_TABLE = "MASTER_QUERY_GLOBAL_TEMP";
}
Exception exception = null;
try {
// manualConnection =
// QueryProcessorUtil.getInstance().getManualConnection();
manualConnection = ServiceLocator.getInstance()
.getAppServerDataSource(dsLookup.getDataSource())
.getConnection();
// manualConnection =
// QueryProcessorUtil.getInstance().getSpringDataSource(dsLookup.
// getDataSource()).getConnection();
// manualConnection =
// QueryProcessorUtil.getInstance().getConnection();
stmt = manualConnection.createStatement();
int count = 0;
if (dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.SQLSERVER) || dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.POSTGRESQL)) {
String checkDeleteGlobalTempTable = "drop table " + TEMP_TABLE;
String checkDeleteCountTable = "drop table " + TEMP_DX_TABLE;
String checkDeleteMasterTable = "drop table " + TEMP_MASTER_TABLE;
Statement clearTempStmt = manualConnection.createStatement();
try {
clearTempStmt.executeUpdate(checkDeleteGlobalTempTable);
} catch (SQLException dEx) {
;
}
try {
clearTempStmt.executeUpdate(checkDeleteCountTable);
} catch (SQLException dEx) {
;
}
try {
clearTempStmt.executeUpdate(checkDeleteMasterTable);
} catch (SQLException dEx) {
;
}
clearTempStmt.close();
String createSql = "CREATE TABLE " + TEMP_TABLE + " ( "
+ " ENCOUNTER_NUM int, " + " PATIENT_NUM int, INSTANCE_NUM int, CONCEPT_CD varchar(50), START_DATE DATETIME, PROVIDER_ID varchar(50), "
+ " PANEL_COUNT int, " + " fact_count int, "
+ " fact_panels int " + ")";
if (dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.POSTGRESQL))
createSql = "CREATE TEMP TABLE " + TEMP_TABLE + " ( "
+ " ENCOUNTER_NUM int, " + " PATIENT_NUM int, INSTANCE_NUM int, CONCEPT_CD varchar(50), START_DATE TIMESTAMP, PROVIDER_ID varchar(50), "
+ " PANEL_COUNT int, " + " fact_count int, "
+ " fact_panels int " + ")";
stmt.executeUpdate(createSql);
createSql = " CREATE TABLE " + TEMP_DX_TABLE + " ( "
+ " ENCOUNTER_NUM int, " + " PATIENT_NUM int, INSTANCE_NUM int, CONCEPT_CD varchar(50), START_DATE DATETIME, PROVIDER_ID varchar(50), temporal_start_date datetime, temporal_end_date DATETIME ) ";
if (dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.POSTGRESQL))
createSql = " CREATE TEMP TABLE " + TEMP_DX_TABLE + " ( "
+ " ENCOUNTER_NUM int, " + " PATIENT_NUM int, INSTANCE_NUM int, CONCEPT_CD varchar(50), START_DATE TIMESTAMP, PROVIDER_ID varchar(50), temporal_start_date TIMESTAMP, temporal_end_date TIMESTAMP ) ";
stmt.executeUpdate(createSql);
createSql = " CREATE TABLE " + TEMP_MASTER_TABLE + " ( "
+ " ENCOUNTER_NUM int, PATIENT_NUM int , INSTANCE_NUM int, CONCEPT_CD varchar(50), START_DATE DATETIME, PROVIDER_ID varchar(50), MASTER_ID varchar(50), LEVEL_NO int, temporal_start_date DATETIME, temporal_end_date DATETIME ) ";
if (dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.POSTGRESQL))
createSql = " CREATE TEMP TABLE " + TEMP_MASTER_TABLE + " ( "
+ " ENCOUNTER_NUM int, PATIENT_NUM int , INSTANCE_NUM int, CONCEPT_CD varchar(50), START_DATE TIMESTAMP, PROVIDER_ID varchar(50), MASTER_ID varchar(50), LEVEL_NO int, temporal_start_date TIMESTAMP, temporal_end_date TIMESTAMP ) ";
stmt.executeUpdate(createSql);
if (dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.SQLSERVER)) {
String indexSql = "create index tempIndex on "
+ getDbSchemaName()
+ "#global_temp_table (patient_num,encounter_num,panel_count)";
log.debug("Executing sql [ " + indexSql + " ]");
stmt.executeUpdate(indexSql);
indexSql = "CREATE NONCLUSTERED INDEX master_index_v1 "
+ " ON " + TEMP_MASTER_TABLE + " (master_id, level_no, temporal_start_date, temporal_end_date) "
+ " INCLUDE (patient_num) ";
log.debug("Executing sql [ " + indexSql + " ]");
stmt.executeUpdate(indexSql);
indexSql = "CREATE NONCLUSTERED INDEX master_index_v2 "
+ " ON " + TEMP_MASTER_TABLE + " (patient_num, master_id) "
+ " INCLUDE (temporal_start_date, temporal_end_date) ";
log.debug("Executing sql [ " + indexSql + " ]");
stmt.executeUpdate(indexSql);
}
} else if (dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.ORACLE)) {
String clearGlobalTempTable = "delete from " + TEMP_TABLE;
String clearCountTable = "delete from " + TEMP_DX_TABLE;
String clearMasterTable = "delete from " + TEMP_MASTER_TABLE;
Statement clearTempStmt = manualConnection.createStatement();
try {
clearTempStmt.executeUpdate(clearGlobalTempTable);
clearTempStmt.executeUpdate(clearCountTable);
clearTempStmt.executeUpdate(clearMasterTable);
} catch (SQLException dEx) {
;
} finally {
clearTempStmt.close();
}
}
// set transaction timeout
stmt.setQueryTimeout(transactionTimeout);
// start seperate thread to cancel the running sql if the
// stmt.setQueryTimeout did not work
CancelStatementRunner csr = new CancelStatementRunner(stmt,
transactionTimeout);
Thread csrThread = new Thread(csr);
csrThread.start();
// ut.commit();
String[] sqls = null;
if (this.queryWithoutTempTableFlag == false) {
sqls = generatedSql.split("<\\*>");
} else {
sqls = new String[] {generatedSql};
}
// UserTransaction could not be used here because it needs a
// XA datasource.
try {
log.debug("Transaction timeout in sec " + transactionTimeout);
// ut.setTransactionTimeout(transactionTimeout);
} catch (Exception e2) {
e2.printStackTrace();
}
long startTime = System.currentTimeMillis();
LogTimingUtil logTimingUtil = new LogTimingUtil();
LogTimingUtil outerLogTimingUtil = new LogTimingUtil();
outerLogTimingUtil.setStartTime();
// execute generated sql
while (count < sqls.length) {
singleSql = sqls[count++];
if (singleSql != null && singleSql.trim().length() > 10) {
log.debug("Executing setfinder query sql [" + singleSql + "]"
+ " for query instance= " + queryInstanceId);
logTimingUtil.setStartTime();
if (this.queryWithoutTempTableFlag == false) {
int rows = stmt.executeUpdate(singleSql);
log.debug("Rows affected [" + rows + "] for query instance");
// if the database is sqlserver, then updating the temp
// table statistics speed up the query
if (this.dataSourceLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.SQLSERVER)) {
log.debug("UPDATE STATISTICS "
+ getDbSchemaName()
+ "#global_temp_table ");
stmt.executeUpdate("UPDATE STATISTICS "
+ getDbSchemaName()
+ "#global_temp_table ");
}
} else {
resultSet = stmt.executeQuery(singleSql);
}
logTimingUtil.setEndTime();
//log the time to the query instance
if (this.processTimingFlag.equalsIgnoreCase(ProcessTimingReportUtil.DEBUG)) {
ptrUtil.logProcessTimingMessage(queryInstanceId, ptrUtil.buildProcessTiming(logTimingUtil,"EXECUTE SQL - ITEM ","sql="+singleSql));
}
}
}
outerLogTimingUtil.setEndTime();
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
log.debug("Time to run the SETFINDER query query instance id ["
+ queryInstanceId + "] is [" + totalTime + " ]");
//log the process timing to the query instance
if (this.processTimingFlag.equalsIgnoreCase(ProcessTimingReportUtil.INFO)) {
ptrUtil.logProcessTimingMessage(queryInstanceId, ptrUtil.buildProcessTiming(outerLogTimingUtil,"EXECUTE SQL",null));
}
// set the cancel thread the
csr.setSqlFinishedFlag();
csrThread.interrupt();
String fetchSql = " select count(distinct patient_num) as patient_num_count from "
+ TEMP_DX_TABLE;
Statement countStmt = manualConnection.createStatement();
if (this.queryWithoutTempTableFlag == false) {
resultSet = countStmt.executeQuery(fetchSql);
}
int i = 0;
//read count sigma from property file
double countSigma = GaussianBoxMuller.getCountSigma();
double obfuscatedMinimumValue = GaussianBoxMuller.getObfuscatedMinimumVal();
while (resultSet.next() && (i++ < 10)) {
recordCount = resultSet.getInt("patient_num_count");
GaussianBoxMuller gaussianBoxMuller = new GaussianBoxMuller();
obfuscatedRecordCount = (int) gaussianBoxMuller
.getNormalizedValueForCount(recordCount,countSigma,obfuscatedMinimumValue);
log.debug("Calculated Patient set size :[" + recordCount
+ "] for query instance= " + queryInstanceId);
}
countStmt.close();
resultSet.close();
// tm.begin();
// call the result generator with the db connection/temp table
callResultGenerator(resultOutputList, manualConnection,
sfDAOFactory, requestXml, patientSetId, queryInstanceId,
TEMP_DX_TABLE, recordCount, obfuscatedRecordCount, transactionTimeout, pmXml);
if (dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.SQLSERVER) || dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.POSTGRESQL)) {
//Delete temp table for Sqlsever
String checkDeleteGlobalTempTable = "drop table " + TEMP_TABLE;
String checkDeleteCountTable = "drop table " + TEMP_DX_TABLE;
String checkDeleteMasterTable = "drop table " + TEMP_MASTER_TABLE;
Statement clearTempStmt = manualConnection.createStatement();
try {
clearTempStmt.executeUpdate(checkDeleteGlobalTempTable);
} catch (SQLException dEx) {
;
}
try {
clearTempStmt.executeUpdate(checkDeleteCountTable);
} catch (SQLException dEx) {
;
}
try {
clearTempStmt.executeUpdate(checkDeleteMasterTable);
} catch (SQLException dEx) {
;
}
clearTempStmt.close();
} else if (dsLookup.getServerType().equalsIgnoreCase(
DAOFactoryHelper.ORACLE) ) {
String deleteGlobalTempTable = "";
String deleteCountTable = "", deleteMasterTable = "";
deleteGlobalTempTable = "delete from " + TEMP_TABLE;
deleteCountTable = "delete from " + TEMP_DX_TABLE;
deleteMasterTable = "delete from " + TEMP_MASTER_TABLE;
Statement deleteStmt = manualConnection.createStatement();
Statement deleteStmt1 = manualConnection.createStatement();
log.debug("Executing Sql [" + deleteGlobalTempTable + "]");
deleteStmt.executeUpdate(deleteGlobalTempTable);
log.debug("Executing Sql [" + deleteCountTable + "]");
deleteStmt1.executeUpdate(deleteCountTable);
log.debug("Executing Sql [" + deleteMasterTable + "]");
deleteStmt1.executeUpdate(deleteMasterTable);
deleteStmt.close();
deleteStmt1.close();
}
// update query instance restult status
setQueryInstanceStatus(sfDAOFactory, queryInstanceId, 6, null);
log.debug("Query executor completed processing query instance[ "
+ queryInstanceId + " ]");
} catch (CRCTimeOutException timeoutEx) {
timeOutErrorFlag = true;
throw timeoutEx;
} catch (SQLServerException sqlServerEx) {
if (sqlServerEx.getMessage().indexOf("The query was canceled.") > -1) {
timeOutErrorFlag = true;
throw new CRCTimeOutException(sqlServerEx.getMessage(),
sqlServerEx);
}
if (sqlServerEx.getMessage().indexOf("timed out") > -1) {
timeOutErrorFlag = true;
throw new CRCTimeOutException(sqlServerEx.getMessage(),
sqlServerEx);
} else {
errorFlag = true;
exception = sqlServerEx;
log.error("Sqlserver error while executing sql", sqlServerEx);
throw new I2B2DAOException(
"Sqlserver error while executing sql", sqlServerEx);
}
} catch (SQLException sqlEx) {
if (sqlEx.toString().indexOf("ORA-01013") > -1) {
timeOutErrorFlag = true;
throw new CRCTimeOutException(sqlEx.getMessage(), sqlEx);
} else if (sqlEx.getMessage().indexOf("The query was canceled.") > -1) {
timeOutErrorFlag = true;
throw new CRCTimeOutException(sqlEx.getMessage(),
sqlEx);
}
else if (sqlEx.getMessage().indexOf("timed out") > -1) {
timeOutErrorFlag = true;
throw new CRCTimeOutException(sqlEx.getMessage(),
sqlEx);
}
errorFlag = true;
exception = sqlEx;
log.error("Error while executing sql", sqlEx);
throw new I2B2DAOException("Error while executing sql", sqlEx);
} catch (LockedoutException crcDaoEx) {
// I2B2DAOException
errorFlag = true;
exception = crcDaoEx;
throw crcDaoEx;
} catch (I2B2Exception i2b2Ex) {
errorFlag = true;
exception = i2b2Ex;
log.error("Error executing " + i2b2Ex.getMessage(), i2b2Ex);
throw new I2B2DAOException("Error executing "
+ i2b2Ex.getMessage(), i2b2Ex);
} catch (IllegalStateException e) {
errorFlag = true;
exception = e;
e.printStackTrace();
throw new I2B2DAOException("IllegalState exception", e);
} catch (SecurityException e) {
errorFlag = true;
exception = e;
e.printStackTrace();
throw new I2B2DAOException("SecurityException", e);
} finally {
// close resultset and statement
try {
if (resultSet != null) {
resultSet.close();
}
if (stmt != null) {
stmt.close();
}
if (manualConnection != null) {
manualConnection.close();
}
} catch (SQLException sqle) {
log.error("Error closing statement/resultset ", sqle);
}
}
}
private void setQueryInstanceStatus(SetFinderDAOFactory sfDAOFactory,
String queryInstanceId, int statusTypeId, String message) throws I2B2DAOException {
IQueryInstanceDao queryInstanceDao = sfDAOFactory.getQueryInstanceDAO();
QtQueryInstance queryInstance = queryInstanceDao
.getQueryInstanceByInstanceId(queryInstanceId);
QtQueryStatusType queryStatusType = new QtQueryStatusType();
queryStatusType.setStatusTypeId(statusTypeId);
queryInstance.setQtQueryStatusType(queryStatusType);
queryInstance.setEndDate(new Date(System.currentTimeMillis()));
queryInstance.setMessage(message);
queryInstanceDao.update(queryInstance, true);
}
private void setQueryResultInstanceStatus(SetFinderDAOFactory sfDAOFactory,
String queryInstanceId, int statusTypeId, String message) {
IQueryResultInstanceDao queryResultInstanceDao = sfDAOFactory
.getPatientSetResultDAO();
List<QtQueryResultInstance> resultInstanceList = queryResultInstanceDao
.getResultInstanceList(queryInstanceId);
for (QtQueryResultInstance queryResultInstance : resultInstanceList) {
queryResultInstanceDao.updatePatientSet(queryResultInstance
.getResultInstanceId(), statusTypeId, message, -1, -1, "");
}
}
@SuppressWarnings("unchecked")
private void callResultGenerator(
ResultOutputOptionListType resultOutputList,
Connection manualConnection, SetFinderDAOFactory sfDAOFactory,
String requestXml, String patientSetId, String queryInstanceId,
String TEMP_DX_TABLE, int recordCount, int obfuscatedRecordCount, int transactionTimeout, String pmXml)
throws CRCTimeOutException, LockedoutException, I2B2DAOException {
log.debug("getting queryProcess instance");
QueryProcessorUtil qpUtil = QueryProcessorUtil.getInstance();
//BeanFactory bf = qpUtil.getSpringBeanFactory();
// Map ontologyKeyMap = (Map)
// bf.getBean("setFinderResultOntologyKeyMap");
Map ontologyKeyMap = (Map) new HashMap();
// CallOntologyUtil callOntologyUtil = null;
String ontologyGetChildrenUrl = null;
SecurityType securityType = null;
//String projectId = null;
try {
String ontologyUrl = qpUtil
.getCRCPropertyValue("edu.harvard.i2b2.crc.delegate.ontology.url");
String getChildrenOperationName = qpUtil
.getCRCPropertyValue("edu.harvard.i2b2.crc.delegate.ontology.operation.getchildren");
ontologyGetChildrenUrl = ontologyUrl
+ getChildrenOperationName;
log.debug("In callResultGenerator: Ontology getChildren url from property file ["
+ ontologyGetChildrenUrl + "]");
JAXBElement responseJaxb = CRCJAXBUtil.getJAXBUtil()
.unMashallFromString(requestXml);
RequestMessageType request = (RequestMessageType) responseJaxb
.getValue();
//projectId = request.getMessageHeader().getProjectId();
SecurityType tempSecurityType = request.getMessageHeader()
.getSecurity();
securityType = PMServiceAccountUtil
.getServiceSecurityType(tempSecurityType.getDomain());
// callOntologyUtil = new CallOntologyUtil(ontologyGetChildrenUrl,
// requestXml);
} catch (JAXBUtilException e) {
e.printStackTrace();
throw new I2B2DAOException(e.getMessage());
} catch (I2B2Exception e) {
e.printStackTrace();
throw new I2B2DAOException(e.getMessage());
}
// get roles either from cache or by calling PM
List<String> roles = new ArrayList<String>();
try {
roles = getRoleFromPM(requestXml, pmXml);
} catch (I2B2Exception e) {
throw new I2B2DAOException(e.getMessage());
}
int lockoutQueryCount = -1, lockoutQueryDay = -1, lockoutQueryZeroCount = -1;
boolean dataObfuscFlag = false;
String projectId = null;
try {
DataSourceLookup dataSourceLookup = sfDAOFactory
.getDataSourceLookup();
String domainId = dataSourceLookup.getDomainId();
projectId = dataSourceLookup.getProjectPath();
String userId = dataSourceLookup.getOwnerId();
DAOFactoryHelper helper = new DAOFactoryHelper(domainId, projectId,
userId);
IDAOFactory daoFactory = helper.getDAOFactory();
AuthrizationHelper authHelper = new AuthrizationHelper(domainId,
projectId, userId, daoFactory);
boolean noDataAggFlag = false, noDataObfuscFlag = false;
try {
authHelper.checkRoleForProtectionLabel(
"SETFINDER_QRY_WITHOUT_DATAOBFSC", roles);
} catch (MissingRoleException noRoleEx) {
noDataAggFlag = true;
} catch (I2B2Exception e) {
throw e;
}
try {
authHelper.checkRoleForProtectionLabel(
"SETFINDER_QRY_WITH_DATAOBFSC", roles);
} catch (MissingRoleException noRoleEx) {
noDataObfuscFlag = true;
} catch (I2B2Exception e) {
throw e;
}
if (noDataAggFlag && !noDataObfuscFlag) {
dataObfuscFlag = true;
}
String lockoutQueryCountStr = qpUtil
.getCRCPropertyValue("edu.harvard.i2b2.crc.lockout.setfinderquery.count");
if (lockoutQueryCountStr != null) {
lockoutQueryCount = Integer.parseInt(lockoutQueryCountStr);
}
String lockoutQueryDayStr = qpUtil
.getCRCPropertyValue("edu.harvard.i2b2.crc.lockout.setfinderquery.day");
if (lockoutQueryDayStr != null) {
lockoutQueryDay = Integer.parseInt(lockoutQueryDayStr);
}
String lockoutQueryZeroCountStr = null;
lockoutQueryZeroCountStr = qpUtil
.getCRCPropertyValue("edu.harvard.i2b2.crc.lockout.setfinderquery.zero.count");
if (lockoutQueryZeroCountStr != null) {
lockoutQueryZeroCount = Integer.parseInt(lockoutQueryZeroCountStr);
}
} catch (I2B2Exception e) {
throw new I2B2DAOException(e.getMessage());
}
Map param = new HashMap();
log.debug("Creatiung hash map");
SetFinderConnection sfConn = new SetFinderConnection(manualConnection);
param.put("SetFinderConnection", sfConn);
param.put("SetFinderDAOFactory", sfDAOFactory);
param.put("PatientSetId", patientSetId);
param.put("QueryInstanceId", queryInstanceId);
param.put("TEMP_DX_TABLE", TEMP_DX_TABLE);
param.put("setFinderResultOntologyKeyMap", ontologyKeyMap);
param.put("ServerType", this.dataSourceLookup.getServerType());
// param.put("CallOntologyUtil", callOntologyUtil);
param.put("projectId", projectId);
param.put("ontologyGetChildrenUrl", ontologyGetChildrenUrl);
param.put("securityType", securityType);
param.put("OriginalDataSourceLookup", this.originalDataSourceLookup);
param.put("Roles", roles);
param.put("TransactionTimeout", transactionTimeout);
param.put("ProcessTimingFlag", processTimingFlag);
param.put("ObfuscatedRecordCount", obfuscatedRecordCount);
param.put("RecordCount", recordCount);
param.put("ObfuscatedRoleFlag", dataObfuscFlag);
if (resultOutputList != null) {
if (resultOutputList.getResultOutput() != null
&& resultOutputList.getResultOutput().size() > 0) {
List<ResultOutputOptionType> resultOptionList = resultOutputList
.getResultOutput();
for (ResultOutputOptionType resultOutputOption : resultOptionList) {
String resultName = resultOutputOption.getName()
.toUpperCase();
String resultInstanceId = getQueryResultInstanceId(
sfDAOFactory, queryInstanceId, resultName);
param.put("ResultInstanceId", resultInstanceId);
param.put("ResultOptionName", resultName);
// ::TODO check if the result state is completed, before
// running the result
runGenerator(resultName, param);
// check if the user need to be locked
// if the lockoutQueryCount = -1 skip lockout check
log.debug("check if the user need to be locked");
if (lockoutQueryCount>-1) {
// resultInstanceId, userId
if (dataObfuscFlag) {
String userLockedDate = null;
try {
userLockedDate = processUserLock(sfDAOFactory,
requestXml, resultInstanceId,
lockoutQueryCount, lockoutQueryDay,lockoutQueryZeroCount);
} catch (I2B2Exception e) {
throw new I2B2DAOException(e.getMessage());
}
if (userLockedDate != null) {
throw new LockedoutException(EJBPMUtil.LOCKEDOUT
+ " error : User account locked on ["
+ userLockedDate + "]");
}
}
} else {
log.debug("Setfinder not doing the lockout check for instance ["+ queryInstanceId + "] " +
"the property value of query count is -1");
}
}
} else {
log
.warn("No result output process to run, the <result_output_option> is empty");
}
} else {
String resultType = defaultResultType;
// perform patient set
String resultInstanceId = getQueryResultInstanceId(sfDAOFactory,
queryInstanceId, defaultResultType);
param.put("ResultInstanceId", resultInstanceId);
runGenerator(resultType, param);
// check if the user need to be locked
// if the lockoutQueryCount = -1 skip lockout check
if (lockoutQueryCount>-1) {
// resultInstanceId, userId
if (dataObfuscFlag) {
// do the check if the user need to be locked
String userLockedDate = null;
try {
userLockedDate = processUserLock(sfDAOFactory, requestXml,
resultInstanceId, lockoutQueryCount, lockoutQueryDay,lockoutQueryZeroCount);
} catch (I2B2Exception e) {
throw new I2B2DAOException(e.getMessage());
}
if (userLockedDate != null) {
throw new LockedoutException(EJBPMUtil.LOCKEDOUT
+ " error : User account locked on [" + userLockedDate
+ "]");
}
}
} else {
log.debug("Setfinder not doing the lockout check for instance ["+ queryInstanceId + "] " +
"the property value of query count is -1");
}
}
}
private void runGenerator(String resultName, Map param)
throws I2B2DAOException, CRCTimeOutException {
String generatorClassName = (String) generatorMap.get(resultName);
if (generatorClassName == null) {
throw new I2B2DAOException("Could not find result name ["
+ resultName + "] in the config file");
}
Class generatorClass;
IResultGenerator resultGenerator;
try {
generatorClass = Class.forName(generatorClassName, true, Thread
.currentThread().getContextClassLoader());
if (generatorClass == null) {
throw new I2B2DAOException(
"Generator class not configured for result name["
+ resultName + "] ");
}
resultGenerator = (IResultGenerator) generatorClass.newInstance();
log.debug("Running " + resultName + "'s class "
+ generatorClassName);
resultGenerator.generateResult(param);
} catch (ClassNotFoundException e) {
throw new I2B2DAOException(
"Class not found for the generator class["
+ generatorClassName + "] ", e);
} catch (InstantiationException e) {
throw new I2B2DAOException("Could not initialize generator class["
+ generatorClassName + "] ", e);
} catch (IllegalAccessException e) {
throw new I2B2DAOException(
"Illegal Access Exception for generator class["
+ generatorClassName + "] ", e);
}
}
private String getQueryResultInstanceId(SetFinderDAOFactory sfDAOFactory,
String queryInstanceId, String resultName) {
IQueryResultInstanceDao resultInstanceDao = sfDAOFactory
.getPatientSetResultDAO();
QtQueryResultInstance resultInstance = resultInstanceDao
.getResultInstanceByQueryInstanceIdAndName(queryInstanceId,
resultName);
return resultInstance.getResultInstanceId();
}
private String processUserLock(SetFinderDAOFactory sfDAOFactory,
String requestXml, String resultInstanceId, int lockoutQueryCount,
int lockoutQueryDay, int lockoutQueryZeroCount) throws I2B2Exception {
String userLockedDate = null;
I2B2RequestMessageHelper reqMsgHelper = new I2B2RequestMessageHelper(
requestXml);
SecurityType origSecurityType = reqMsgHelper.getSecurityType();
String projectId = reqMsgHelper.getProjectId();
String userId = origSecurityType.getUsername();
IQueryResultInstanceDao queryResultInstanceDao = sfDAOFactory
.getPatientSetResultDAO();
QtQueryResultInstance resultInstance = queryResultInstanceDao
.getResultInstanceById(resultInstanceId);
int resultTypeId = resultInstance.getQtQueryResultType()
.getResultTypeId();
int setSize = resultInstance.getRealSetSize();
//if the lockout query zero count is -1, dont count zero
if (setSize == 0 ) {
if (lockoutQueryZeroCount == -1) {
log.debug("Setfinder not doing the lockout check for result instance ["+ resultInstanceId + "] " +
"the zero count property value is -1");
return userLockedDate;
} else {
//assign the lockout query zero count to lockout query count
log.debug("Setfinder lockout query count value for result instance ["+ resultInstanceId + "] " +
"taken from zero count property value is ["+lockoutQueryZeroCount +"]");
lockoutQueryCount = lockoutQueryZeroCount;
}
}
int queryCount = queryResultInstanceDao
.getResultInstanceCountBySetSize(userId, lockoutQueryDay,
resultTypeId, setSize, lockoutQueryCount);
if (queryCount > 0) {
userLockedDate = new Date(System.currentTimeMillis()).toString();
SecurityType serviceSecurityType = PMServiceAccountUtil
.getServiceSecurityType(origSecurityType.getDomain());
// send pm message
//EJBPMUtil ejbPMUtil = new EJBPMUtil(serviceSecurityType, projectId);
//ejbPMUtil.setUserLockedParam(userId, projectId,
// EJBPMUtil.LOCKEDOUT, userLockedDate);
EJBPMUtil.setUserLockedParam(userId,
EJBPMUtil.LOCKEDOUT, userLockedDate, serviceSecurityType, projectId,
QueryProcessorUtil.getInstance()
.getProjectManagementCellUrl());
}
return userLockedDate;
}
/**
* Call PM to get user roles. The security info is taken from the request
* xml
*
* @param requestXml
* @return
* @throws I2B2Exception
*/
public List<String> getRoleFromPM(String requestXml, String pmXml) throws I2B2Exception {
log.debug("In getRoleFromPM, pmXml is " + pmXml);
I2B2RequestMessageHelper reqMsgHelper = new I2B2RequestMessageHelper(
requestXml);
SecurityType origSecurityType = reqMsgHelper.getSecurityType();
String projectId = reqMsgHelper.getProjectId();
SecurityType serviceSecurityType = PMServiceAccountUtil
.getServiceSecurityType(origSecurityType.getDomain());
//EJBPMUtil callPMUtil = new EJBPMUtil(serviceSecurityType, projectId);
List<String> roleList = new ArrayList<String>();
try {
if (pmXml == null) {
//RolesType rolesType = callPMUtil.callGetRole(origSecurityType
// .getUsername(), projectId);
RolesType rolesType = EJBPMUtil.callGetRole(origSecurityType
.getUsername(), origSecurityType, projectId,
QueryProcessorUtil.getInstance()
.getProjectManagementCellUrl());
RoleType roleType = null;
for (java.util.Iterator<RoleType> iterator = rolesType.getRole()
.iterator(); iterator.hasNext();) {
roleType = iterator.next();
roleList.add(roleType.getRole());
}
} else {
ProjectType projectType = CallPMUtil.getUserProjectFromResponse(pmXml, origSecurityType,
projectId);
roleList = projectType.getRole();
}
} catch (AxisFault e) {
throw new I2B2Exception(" Failed to get user role from PM "
+ StackTraceUtil.getStackTrace(e));
} catch (JAXBUtilException e) {
// TODO Auto-generated catch block
throw new I2B2Exception(" Failed to Process PM Xml message "
+ StackTraceUtil.getStackTrace(e));
}
return roleList;
/*
* I2B2RequestMessageHelper reqMsgHelper = new I2B2RequestMessageHelper(
* requestXml); SecurityType securityType =
* reqMsgHelper.getSecurityType(); String projectId =
* reqMsgHelper.getProjectId(); // get roles from pm driver
* PMServiceDriver serviceDriver = new PMServiceDriver(); ProjectType
* projectType = null;
*
* try { projectType = serviceDriver.checkValidUser(securityType,
* projectId); } catch (AxisFault e) { e.printStackTrace(); throw new
* I2B2Exception(" Failed to get user role from PM " +
* StackTraceUtil.getStackTrace(e)); } catch (JAXBUtilException e) {
* e.printStackTrace(); throw new
* I2B2Exception(" Failed to get user role from PM " +
* StackTraceUtil.getStackTrace(e)); } return projectType.getRole();
*/
}
}