package edu.harvard.i2b2.crc.loader.ejb;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import javax.xml.bind.JAXBElement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.harvard.i2b2.common.exception.I2B2Exception;
import edu.harvard.i2b2.common.util.jaxb.JAXBUtil;
import edu.harvard.i2b2.common.util.jaxb.JAXBUtilException;
import edu.harvard.i2b2.crc.loader.dao.IUploaderDAOFactory;
import edu.harvard.i2b2.crc.loader.dao.UploadStatusDAO;
import edu.harvard.i2b2.crc.loader.dao.UploadStatusDAOI;
import edu.harvard.i2b2.crc.loader.datavo.loader.UploadSetStatus;
import edu.harvard.i2b2.crc.loader.datavo.loader.query.PublishDataRequestType;
/**
* Main class for datamart load operation. The Load function delegates load
* operation to appropriate loader class.
*
* @author rk903
*
*/
public class DataMartLoader implements IDataMartLoaderHelper {
// if the format is xml, then input file is in PatientData schema.
public final static String INPUT_LOAD_FORMAT_XML = "XML";
public final static String INPUT_LOAD_FORMAT_CSV = "CSV";
// this is temp holder, later its read thru property file
public static String loaderWorkingDirectory = "/";
// @EJB(mappedName = "service/local")
// private Service service;
// log
private static Log log = LogFactory.getLog(DataMartLoader.class);
/*
* public void load(int uploadId, String inputLoadFile, String
* inputLoadFileFormat, String sourceSystemCd, boolean visitLoadFlag,
* boolean observationFactLoadFlag,boolean pidLoadFlag, boolean
* patientLoadFlag, String encounterSource, String conceptCodePrefix,
* boolean appendFlag, String userId, boolean tempCleanUpFlag) throws
* I2B2Exception {
*/
/**
* Main function to start upload process.
*
* @param inputLoadFile
* @param inputLoadFileFormat
* @param visitLoadFlag
* @param observationFactLoadFlag
* @param userId
* @param tempCleanUpFlag
* @throws I2B2Exception
*/
public void load(IUploaderDAOFactory uploaderDaoFactory, String userId,
int uploadId, String localUploadFile, String publishMessage)
throws I2B2Exception {
try {
JAXBUtil jaxbUtil = edu.harvard.i2b2.crc.loader.datavo.CRCLoaderJAXBUtil
.getJAXBUtil();
PublishDataRequestType publishType = null;
try {
JAXBElement<?> jaxbElement = jaxbUtil
.unMashallFromString(publishMessage);
publishType = (PublishDataRequestType) jaxbElement.getValue();
} catch (JAXBUtilException jaxbEx) {
throw new I2B2Exception("Error proacessing request message "
+ jaxbEx.getMessage(), jaxbEx);
}
String uploadFileName = localUploadFile;
String inputLoadFileFormat = publishType.getInputList()
.getDataFile().getDataFormatType().toString();
String sourceSystemCd = publishType.getInputList().getDataFile()
.getSourceSystemCd();
boolean visitLoadFlag = (publishType.getLoadList()
.getLoadEventSet() != null) ? true : false;
boolean observationFactLoadFlag = (publishType.getLoadList()
.getLoadObservationSet() != null) ? true : false;
boolean appendFlag = false;
if (observationFactLoadFlag) {
appendFlag = publishType.getLoadList().getLoadObservationSet()
.isAppendFlag();
}
boolean pidLoadFlag = (publishType.getLoadList().getLoadPidSet() != null) ? true
: false;
boolean eidLoadFlag = (publishType.getLoadList().getLoadEidSet() != null) ? true
: false;
boolean patientLoadFlag = (publishType.getLoadList()
.getLoadPatientSet() != null) ? true : false;
boolean conceptLoadFlag = (publishType.getLoadList()
.getLoadConceptSet() != null) ? true : false;
boolean conceptDeleteExistingDataFlag = (publishType.getLoadList()
.getLoadConceptSet() != null) ? publishType.getLoadList()
.getLoadConceptSet().isDeleteExistingData() : false;
boolean modifierLoadFlag = (publishType.getLoadList()
.getLoadModifierSet() != null) ? true : false;
boolean modifierDeleteExistingDataFlag = (publishType.getLoadList()
.getLoadModifierSet() != null) ? publishType.getLoadList()
.getLoadModifierSet().isDeleteExistingData() : false;
boolean observerLoadFlag = (publishType.getLoadList()
.getLoadObserverSet() != null) ? true : false;
boolean observerDeleteExistingDataFlag = (publishType.getLoadList()
.getLoadObserverSet() != null) ? publishType.getLoadList()
.getLoadObserverSet().isDeleteExistingData() : false;
boolean stagingCleanUpFlag = publishType.getLoadList()
.isClearTempLoadTables();
String encounterSource = "";
String conceptCodePrefix = "";
doNullCheck(uploadFileName, inputLoadFileFormat, sourceSystemCd,
userId);
log.info("Starting to process loadfile :" + uploadFileName
+ "format " + inputLoadFileFormat + " userid " + userId);
// create Upload Status
// uploadId = createUploadStatus(inputLoadFile, "STARTED",
// sourceSystemCd, userId);
// log.info("Created Upload Status: uploadId=" + uploadId);
// check if pid set need to be loaded
UploadStatusDAOI uploadStatusDAO = uploaderDaoFactory
.getUploadStatusDAO();
if (pidLoadFlag) {
PidLoader pidLoader = new PidLoader(uploaderDaoFactory,
uploadFileName, inputLoadFileFormat, encounterSource,
sourceSystemCd, uploadId);
performLoad(pidLoader, UploadStatusDAO.PID_SET);
log.info("Pid load complete " + uploadFileName + " uploadId"
+ uploadId);
if (stagingCleanUpFlag) {
log.info("Droping temp table ["
+ pidLoader.getStagingTableName() + "]");
uploadStatusDAO.dropTempTable(pidLoader
.getStagingTableName());
}
}
// check if eid set need to be loaded
if (eidLoadFlag) {
EidLoader eidLoader = new EidLoader(uploaderDaoFactory,
uploadFileName, inputLoadFileFormat, encounterSource,
sourceSystemCd, uploadId);
performLoad(eidLoader, UploadStatusDAO.EID_SET);
log.info("Eid load complete " + uploadFileName + " uploadId"
+ uploadId);
if (stagingCleanUpFlag) {
log.info("Droping temp table ["
+ eidLoader.getStagingTableName() + "]");
uploadStatusDAO.dropTempTable(eidLoader
.getStagingTableName());
}
}
// check if patient set need to be loaded
if (patientLoadFlag) {
PatientLoader patientLoader = new PatientLoader(
uploaderDaoFactory, uploadFileName,
inputLoadFileFormat, encounterSource, sourceSystemCd,
uploadId);
performLoad(patientLoader, UploadStatusDAO.PATIENT_SET);
log.info("Patient load complete " + uploadFileName
+ " uploadId" + uploadId);
if (stagingCleanUpFlag) {
log.info("Droping temp table ["
+ patientLoader.getStagingTableName() + "]");
uploadStatusDAO.dropTempTable(patientLoader
.getStagingTableName());
}
}
// check if visit need to be added
if (visitLoadFlag) {
VisitLoader visitLoader = new VisitLoader(uploaderDaoFactory,
uploadFileName, inputLoadFileFormat, encounterSource,
sourceSystemCd, uploadId);
performLoad(visitLoader, UploadStatusDAO.EVENT_SET);
log.info("Visit load complete " + uploadFileName + " uploadId"
+ uploadId);
if (stagingCleanUpFlag) {
log.info("Droping temp table ["
+ visitLoader.getStagingTableName() + "]");
uploadStatusDAO.dropTempTable(visitLoader
.getStagingTableName());
}
}
// check if concept set need to be loaded
if (conceptLoadFlag) {
log.info("Concept load started " + uploadFileName + " uploadId"
+ uploadId);
ConceptLoader conceptLoader = new ConceptLoader(
uploaderDaoFactory, uploadFileName,
inputLoadFileFormat, encounterSource, sourceSystemCd,
conceptDeleteExistingDataFlag, uploadId);
performLoad(conceptLoader, UploadStatusDAO.CONCEPT_SET);
log.info("Concept load complete " + uploadFileName
+ " uploadId" + uploadId);
if (stagingCleanUpFlag) {
log.info("Droping temp table ["
+ conceptLoader.getStagingTableName() + "]");
uploadStatusDAO.dropTempTable(conceptLoader
.getStagingTableName());
}
}
// check if modifier set need to be loaded
if (modifierLoadFlag) {
log.info("Modifier load started " + uploadFileName + " uploadId"
+ uploadId);
ModifierLoader modifierLoader = new ModifierLoader(
uploaderDaoFactory, uploadFileName,
inputLoadFileFormat, encounterSource, sourceSystemCd,
modifierDeleteExistingDataFlag, uploadId);
performLoad(modifierLoader, UploadStatusDAO.MODIFIER_SET);
log.info("Modifier load complete " + uploadFileName
+ " uploadId" + uploadId);
if (stagingCleanUpFlag) {
log.info("Droping temp table ["
+ modifierLoader.getStagingTableName() + "]");
uploadStatusDAO.dropTempTable(modifierLoader
.getStagingTableName());
}
}
// check if observer set need to be loaded
if (observerLoadFlag) {
log.info("Provider load started " + uploadFileName
+ " uploadId" + uploadId);
ProviderLoader providerLoader = new ProviderLoader(
uploaderDaoFactory, uploadFileName,
inputLoadFileFormat, encounterSource, sourceSystemCd,
observerDeleteExistingDataFlag, uploadId);
performLoad(providerLoader, UploadStatusDAO.OBSERVER_SET);
log.info("Provider load complete " + uploadFileName
+ " uploadId" + uploadId);
if (stagingCleanUpFlag) {
log.info("Droping temp table ["
+ providerLoader.getStagingTableName() + "]");
uploadStatusDAO.dropTempTable(providerLoader
.getStagingTableName());
}
}
// check if observation fact need to be added
if (observationFactLoadFlag) {
ObservationFactLoader obsFactLoader = new ObservationFactLoader(
uploaderDaoFactory, uploadFileName,
inputLoadFileFormat, encounterSource,
conceptCodePrefix, sourceSystemCd, appendFlag, uploadId);
performLoad(obsFactLoader, UploadStatusDAO.OBSERVATION_SET);
log.info("ObservationFact load complete " + uploadFileName
+ " uploadId" + uploadId);
if (stagingCleanUpFlag) {
log.info("Droping temp table ["
+ obsFactLoader.getStagingTableName() + "]");
uploadStatusDAO.dropTempTable(obsFactLoader
.getStagingTableName());
}
}
if (stagingCleanUpFlag) {
try { // remove local input file File
File deleteLocalFile = new File(localUploadFile);
deleteLocalFile.delete();
} catch (Throwable t) {
log.error("Unable to delete the temp file ["
+ localUploadFile + " ]");
}
}
} catch (Throwable ex) {
ex.printStackTrace();
log.error("Error in Upload Process ", ex);
/*
try {
if (utx.getStatus() == Status.STATUS_ACTIVE) {
utx.rollback();
}
} catch (Exception e) {
log.error("unable to rollback transaction [" + e.getMessage()
+ "]");
}
*/
// rethrow exception
throw new I2B2Exception("Error in Upload Process ["
+ ex.getMessage() + "]");
}
}
public String getLoaderWorkingDirectory() {
return loaderWorkingDirectory;
}
public void setLoaderWorkingDirectory(String loaderWorkingDirectory) {
DataMartLoader.loaderWorkingDirectory = loaderWorkingDirectory;
}
private void performLoad(AbstractDimensionLoader dimensionLoader,
int setTypeId) throws I2B2Exception {
Throwable t = null;
// setstatus started
IUploaderDAOFactory uploadDaoFactory = dimensionLoader
.getUploaderDaoFactory();
try {
// utx.begin();
UploadStatusDAOI uploadStatusDao = uploadDaoFactory
.getUploadStatusDAO();
UploadSetStatus setStatus = new UploadSetStatus();
setStatus.setUploadId(dimensionLoader.getUploadId());
setStatus.setLoadStatus("PROCESSING");
setStatus.setSetTypeId(setTypeId);
setStatus.setInputFileName(dimensionLoader.getInputLoadFile());
setStatus.setSourceCd(dimensionLoader.getSourceSystemCd());
setStatus.setLoadDate(new Date(System.currentTimeMillis()));
uploadStatusDao.insertUploadSetStatus(setStatus);
// utx.commit();
// utx.begin();
dimensionLoader.createTempTable();
// utx.commit();
// utx.begin();
int totalRecords = dimensionLoader.loadTempTable();
// utx.commit();
// if (deleteExistingDataFlag) {
// utx.begin();
// dimensionLoader.backupAndClearTable();
// utx.commit();
// }
// utx.begin();
int loadedRecords = dimensionLoader.mergeTempTable();
// utx.commit();
// utx.begin();
setStatus = uploadStatusDao.getUploadSetStatus(dimensionLoader
.getUploadId(), setTypeId);
if (loadedRecords == totalRecords) {
setStatus.setLoadStatus("FINISHED");
} else {
setStatus.setLoadStatus("WARNING");
}
setStatus.setLoadedRecord(loadedRecords);
setStatus.setEndDate(new Date(System.currentTimeMillis()));
setStatus.setNoOfRecord(totalRecords);
uploadStatusDao.updateUploadSetStatus(setStatus);
// utx.commit();
} catch (Throwable e) {
e.printStackTrace();
t = e;
} finally {
if (t != null) {
try { // check if exception thrown after the begin, if so
// rollback
// if (utx.getStatus() == Status.STATUS_ACTIVE) {
// utx.rollback();
// } // update set status with error status
// utx.begin();
UploadStatusDAOI uploadStatusDao = uploadDaoFactory
.getUploadStatusDAO();
UploadSetStatus setStatus = uploadStatusDao
.getUploadSetStatus(dimensionLoader.getUploadId(),
setTypeId);
setStatus.setLoadStatus("ERROR");
StringWriter stringWriter = new StringWriter();
t.printStackTrace(new PrintWriter(stringWriter));
String message = stringWriter.toString();
if (message != null) {
setStatus.setMessage(message.substring(0, (message
.length() > 3995) ? 3995 : message.length()));
}
setStatus.setEndDate(new Date(System.currentTimeMillis()));
uploadStatusDao.updateUploadSetStatus(setStatus);
// utx.commit();
// } catch (NotSupportedException e) {
// e.printStackTrace();
// } catch (SystemException e) {
// e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
// } catch (RollbackException e) {
// e.printStackTrace();
// } catch (HeuristicMixedException e) {
// e.printStackTrace();
// } catch (HeuristicRollbackException e) {
// e.printStackTrace();
}
throw new I2B2Exception("Error while loading data "
+ t.getMessage());
}
}
// setstatus fininshed
}
public void deleteUploadData(IUploaderDAOFactory uploaderDaoFactory,
int uploadId) throws I2B2Exception {
UploadStatusDAOI uploadStatusDAO = uploaderDaoFactory
.getUploadStatusDAO();
// :TODO throw i2b2exception to client.
try {
uploadStatusDAO.deleteUploadData(uploadId);
} catch (I2B2Exception i2b2Ex) {
i2b2Ex.printStackTrace();
}
}
private void doNullCheck(String inputLoadFile, String inputLoadFileFormat,
String sourceSystemCd, String userId) throws I2B2Exception {
if (inputLoadFile == null) {
throw new I2B2Exception("Input load file is null");
}
if (inputLoadFileFormat == null) {
throw new I2B2Exception("Input load file format is null");
}
if (sourceSystemCd == null) {
throw new I2B2Exception("Input source system code is null");
}
if (userId == null) {
throw new I2B2Exception("User id is null");
}
}
}