/* * 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: * Mike Mendis - initial API and implementation */ package edu.harvard.i2b2.pm.ws; import java.util.regex.Matcher; import java.util.regex.Pattern; import edu.harvard.i2b2.common.exception.I2B2Exception; import edu.harvard.i2b2.common.util.jaxb.JAXBUtilException; import edu.harvard.i2b2.pm.datavo.i2b2message.ResponseMessageType; import edu.harvard.i2b2.pm.delegate.RequestHandler; import edu.harvard.i2b2.pm.delegate.ServicesHandler; import edu.harvard.i2b2.pm.ws.ExecutorRunnable; import edu.harvard.i2b2.pm.ws.MessageFactory; import javax.xml.stream.XMLStreamException; import org.apache.axiom.om.OMElement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * This is webservice skeleton class. It passes incoming report to PFT parser * and collects parsed pft concepts. Then these parsed concepts returned back to * webservice client in Patient Data Object XML format. * */ public class PMService { private static Log log = LogFactory.getLog(PMService.class); private static String msgVersion = "1.1"; public OMElement getVersion(OMElement getPMDataElement) throws I2B2Exception, JAXBUtilException { Pattern p = Pattern.compile("<password>.+</password>"); Matcher m = p.matcher(getPMDataElement.toString()); String outString = m.replaceAll("<password>*********</password>"); p = Pattern.compile(">.+</ns9:set_password>"); m = p.matcher(outString); outString = m.replaceAll(">*********</ns9:set_password>"); log.debug("Received Request PM Element " + outString); OMElement returnElement = null; if (getPMDataElement == null) { log.error("Incoming Version request is null"); throw new I2B2Exception("Incoming Version request is null"); } VersionMessage servicesMsg = new VersionMessage(getPMDataElement.toString()); String version = servicesMsg.getRequestMessageType().getMessageBody().getGetMessageVersion().toString(); if (version.equals("")) { edu.harvard.i2b2.pm.datavo.i2b2versionmessage.ResponseMessageType pmDataResponse = new edu.harvard.i2b2.pm.datavo.i2b2versionmessage.ResponseMessageType(); edu.harvard.i2b2.pm.datavo.i2b2versionmessage.ResponseMessageType.MessageBody mb = new edu.harvard.i2b2.pm.datavo.i2b2versionmessage.ResponseMessageType.MessageBody(); mb.setI2B2MessageVersion(msgVersion); pmDataResponse.setMessageBody(mb); String xmlMsg = MessageFactory.convertToXMLString(pmDataResponse); try { returnElement = MessageFactory.createResponseOMElementFromString(xmlMsg); log.debug("my pm repsonse is: " + pmDataResponse); log.debug("my return is: " + returnElement); } catch (XMLStreamException e) { log.error("Error creating OMElement from response string " + pmDataResponse, e); } } return returnElement; } /** * This function is main webservice interface to get pulmonary data from * pulmonary report. It uses AXIOM elements(OMElement) to conveniently parse * xml messages. * * It excepts incoming request in i2b2 message format, which wraps PFT * report inside patientdata object. The response is also will be in i2b2 * message, which will wrap patientdata object. Patient data object will * have all the extracted pft concepts from the report. * * * @param getServices * @return OMElement in i2b2message format * @throws PortletServiceNotFoundException * @throws PortletServiceUnavailableException * @throws Exception */ public OMElement getServices(OMElement getPMDataElement) throws I2B2Exception { /* OMElement returnElement = null; String pmDataResponse = null; String unknownErrorMessage = "Error message delivered from the remote server \n" + "You may wish to retry your last action"; if (getPMDataElement == null) { log.error("Incoming PM request is null"); ResponseMessageType responseMsgType = MessageFactory.doBuildErrorResponse(null, unknownErrorMessage); pmDataResponse = MessageFactory.convertToXMLString(responseMsgType); return MessageFactory.createResponseOMElementFromString(pmDataResponse); } ServicesMessage servicesMsg = new ServicesMessage(getPMDataElement.toString()); // String requestElementString = getPMDataElement.toString(); // childrenDataMsg.setRequestMessageType(requestElementString); long waitTime = 0; if (servicesMsg.getRequestMessageType() != null) { if (servicesMsg.getRequestMessageType().getRequestHeader() != null) { waitTime = servicesMsg.getRequestMessageType() .getRequestHeader() .getResultWaittimeMs(); } } //do Workplace query processing inside thread, so that // service could send back message with timeout error. ExecutorRunnable er = new ExecutorRunnable(); return er.execute(new ServicesHandler(servicesMsg), waitTime); */ OMElement returnElement = null; if (getPMDataElement == null) { log.error("Incoming PM request is null"); throw new I2B2Exception("Incoming PM request is null"); } Pattern p = Pattern.compile("<password>.+</password>"); Matcher m = p.matcher(getPMDataElement.toString()); String outString = m.replaceAll("<password>*********</password>"); p = Pattern.compile(">.+</ns9:set_password>"); m = p.matcher(outString); outString = m.replaceAll(">*********</ns9:set_password>"); log.debug("Received Request PM Element " + outString); log.debug("Begin getting servicesMsg"); ServicesMessage servicesMsg = new ServicesMessage(getPMDataElement.toString()); long waitTime = 0; if (servicesMsg.getRequestMessageType() != null) { if (servicesMsg.getRequestMessageType().getRequestHeader() != null) { waitTime = servicesMsg.getRequestMessageType() .getRequestHeader() .getResultWaittimeMs(); } } log.debug("Completed getting servicesMsg, waittime is: " + waitTime); //do PM processing inside thread, so that // service could sends back message with timeout error. String pmDataResponse = null; try { ExecutorRunnable er = new ExecutorRunnable(); //er.setInputString(requestElementString); log.debug("begin setRequestHandler, my servicesMsg: " + servicesMsg); er.setRequestHandler(new ServicesHandler(servicesMsg)); log.debug("middle setRequestHandler"); log.debug("end setRequestHandler"); Thread t = new Thread(er); ResponseMessageType responseMsgType = null; synchronized (t) { t.start(); try { //if (waitTime > 0) { // t.wait(waitTime); //} else { // t.wait(); //} long startTime = System.currentTimeMillis(); long deltaTime = -1; while((er.isJobCompleteFlag() == false)&& (deltaTime < waitTime)){ if (waitTime > 0) { t.wait(waitTime - deltaTime); deltaTime = System.currentTimeMillis() - startTime; } else { t.wait(); } } pmDataResponse = er.getOutputString(); if (pmDataResponse == null) { if (er.getJobException() != null) { pmDataResponse = ""; throw new I2B2Exception("Portal is not property configured."); } else if (er.isJobCompleteFlag() == false) { String timeOuterror = "Result waittime millisecond <result_waittime_ms> :" + waitTime + " elapsed, try again with increased value"; log.debug(timeOuterror); responseMsgType = MessageFactory.doBuildErrorResponse(null, timeOuterror); pmDataResponse = MessageFactory.convertToXMLString(responseMsgType); } } } catch (InterruptedException e) { log.error("Error in thread: " + e.getMessage()); e.printStackTrace(); throw new I2B2Exception("Thread error while running PM job " + getPMDataElement, e); } finally { t.interrupt(); er = null; t = null; } } } catch (Exception e) { log.error("Error: " + e.getMessage()); e.printStackTrace(); } try { returnElement = MessageFactory.createResponseOMElementFromString(pmDataResponse); log.debug("my pm repsonse is: " + pmDataResponse); log.debug("my return is: " + returnElement); } catch (XMLStreamException e) { log.error("Error creating OMElement from response string " + pmDataResponse, e); } return returnElement; } }