Java tutorial
/******************************************************************************* * Copyright SemanticBits, Northwestern University and Akaza Research * * Distributed under the OSI-approved BSD 3-Clause License. * See http://ncip.github.com/caaers/LICENSE.txt for details. ******************************************************************************/ package gov.nih.nci.cabig.caaers.service; import gov.nih.nci.cabig.caaers.CaaersConfigurationException; import gov.nih.nci.cabig.caaers.CaaersSystemException; import gov.nih.nci.cabig.caaers.dao.StudyDao; import gov.nih.nci.cabig.caaers.domain.LocalStudy; import gov.nih.nci.cabig.caaers.domain.OrganizationAssignedIdentifier; import gov.nih.nci.cabig.caaers.domain.Study; import gov.nih.nci.cabig.caaers.domain.SystemAssignedIdentifier; import gov.nih.nci.cabig.caaers.event.EventFactory; import gov.nih.nci.cabig.caaers.integration.schema.study.Studies; import gov.nih.nci.cabig.caaers.service.migrator.StudyConverter; import gov.nih.nci.cabig.caaers.tools.configuration.Configuration; import gov.nih.nci.cabig.caaers.utils.DateUtils; import gov.nih.nci.cabig.caaers.utils.XsltTransformer; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSession; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.ws.client.core.WebServiceTemplate; public class ProxyWebServiceFacade implements AdeersIntegrationFacade { protected final Log log = LogFactory.getLog(getClass()); public static final String SYNC_ORG_ENTITY_NAME = "organization"; public static final String SYNC_ORG_OPERATION_NAME = "getOrganizationsLOV"; public static final String SYNC_AGENT_ENTITY_NAME = "agent"; public static final String SYNC_AGENT_OPERATION_NAME = "getAgentsLOV"; public static final String SYNC_DEVICE_ENTITY_NAME = "device"; public static final String SYNC_DEVICE_OPERATION_NAME = "getDevicesLOV"; public static final String SYNC_LAB_ENTITY_NAME = "lab"; public static final String SYNC_LAB_OPERATION_NAME = "getLabsLOV"; public static final String SYNC_PRIOR_THERAPY_ENTITY_NAME = "priortherapy"; public static final String SYNC_PRIOR_THERAPY_OPERATION_NAME = "getTherapiesLOV"; public static final String SYNC_ASAEL_ENTITY_NAME = "asael"; public static final String SYNC_ASAEL_OPERATION_NAME = "getASAEL"; public static final String SYNC_DOSE_UOM_ENTITY_NAME = "agentDoseUOM"; public static final String SYNC_DOSE_UOM_OPERATION_NAME = "getAgentDoseUOMLOV"; public static final String SYNC_PRE_EXISTING_COND_ENTITY_NAME = "preexistingcondition"; public static final String SYNC_PRE_EXISTING_COND_OPERATION_NAME = "getPreExistingConditionsLOV"; public static final String CREATE_STUDY_ENTITY_NAME = "study"; public static final String CREATE_STUDY_OPERATION_NAME = "createStudy"; public static final String UPDATE_STUDY_ENTITY_NAME = "study"; public static final String UPDATE_STUDY_OPERATION_NAME = "updateStudy"; public static final String SEARCH_STUDY_ENTITY_NAME = "study"; public static final String SEARCH_STUDY_OPERATION_NAME = "searchStudy"; public static final String SYNC_CTCAE_ENTITY_NAME = "ctcae"; public static final String SYNC_CTCAE_OPERATION_NAME = "getCTCAELOV"; public static final String MERGED_ORG_ENTITY_NAME = "mergedorganization"; public static final String MERGED_ORG_OPERATION_NAME = "getMergedOrganization"; private EventFactory eventFactory; private WebServiceTemplate webServiceTemplate; private StudyConverter studyConverter; private Configuration configuration; private StudyDao studyDao; private JAXBContext jaxbContext = null; private Unmarshaller unmarshaller = null; private XsltTransformer xsltTransformer; public ProxyWebServiceFacade() { try { jaxbContext = JAXBContext.newInstance("gov.nih.nci.cabig.caaers.integration.schema.study"); unmarshaller = jaxbContext.createUnmarshaller(); xsltTransformer = new XsltTransformer(); } catch (JAXBException jb) { throw new CaaersConfigurationException("Unable to create proxy webservice : " + jb.getMessage(), jb); } } public void setDefaultUri(String defaultUri) { webServiceTemplate.setDefaultUri(defaultUri); } // send to the configured default URI public String simpleSendAndReceive(String message) { String wsURI = configuration.get(Configuration.ESB_WS_URL); StringBuilder sb = new StringBuilder(8192); try { URL url = new URL(wsURI); HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection(); if (httpConnection instanceof HttpsURLConnection) { ((HttpsURLConnection) httpConnection).setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { // TODO Auto-generated method stub log.warn("Going to trust hostname: '" + hostname + "'."); return true; } }); } httpConnection.setRequestMethod("POST"); httpConnection.setDoOutput(true); httpConnection.connect(); StringBuffer xmlMessage = new StringBuffer(); xmlMessage.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") .append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">") .append("<soapenv:Header>"); //Generate header; xmlMessage.append("<wsse:Security xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" ").append( "xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">") .append("<wsse:UsernameToken wsu:Id=\"UsernameToken-2765109\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">") .append("<wsse:Username>").append(configuration.get(Configuration.WS_USERNAME)) .append("</wsse:Username>") .append("<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">") .append(configuration.get(Configuration.WS_PASSWORD)).append("</wsse:Password>") .append("</wsse:UsernameToken>").append("</wsse:Security> "); xmlMessage.append("</soapenv:Header>").append("<soapenv:Body>").append(message) .append("</soapenv:Body>").append("</soapenv:Envelope>"); try (OutputStream out = httpConnection.getOutputStream(); OutputStreamWriter write = new OutputStreamWriter(out, StandardCharsets.UTF_8)) { write.write(xmlMessage.toString()); } try (InputStream in = httpConnection.getInputStream(); BufferedReader r = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { String str = null; while ((str = r.readLine()) != null) { sb.append(str); } } } catch (Exception e) { log.error("Error while processing the proxywebservoce facade.\nFailed message: '" + message + "'. \nStacktrace;\n", e); } return sb.toString(); } // send to the configured default URI public String send(String entity, String operationName, boolean sync, Map<String, String> criteria) { String corelationId = RandomStringUtils.randomAlphanumeric(15); String message = buildMessage(corelationId, "adeers", entity, operationName, sync ? "sync" : "async", criteria); simpleSendAndReceive(message); return corelationId; } public void setWebServiceTemplate(WebServiceTemplate webServiceTemplate) { this.webServiceTemplate = webServiceTemplate; } public void setStudyConverter(StudyConverter studyConverter) { this.studyConverter = studyConverter; } public void setConfiguration(Configuration configuration) { this.configuration = configuration; } public void setStudyDao(StudyDao studyDao) { this.studyDao = studyDao; } public void setEventFactory(EventFactory eventFactory) { this.eventFactory = eventFactory; } private static String buildMessage(String corelationId, String system, String entity, String operationName, String operationMode, Map<String, String> criteria) { StringBuffer sb = new StringBuffer(); sb.append( "<gen:GenericRequest xmlns:gen=\"http://webservice.caaers.cabig.nci.nih.gov/GenericProcessor/\">"); sb.append("<payload correlationId=\"" + corelationId + "\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"); sb.append("<system>" + system + "</system>"); sb.append("<request>"); sb.append("<!--Optional:-->"); sb.append("<entity>" + entity + "</entity>"); sb.append("<operation name=\"" + operationName + "\" mode=\"" + operationMode + "\">"); sb.append("<criteria>"); for (String key : criteria.keySet()) { sb.append("<criterion name=\"" + key + "\">" + criteria.get(key) + "</criterion>"); } sb.append("</criteria>"); sb.append("</operation>"); sb.append("</request>"); sb.append("</payload>"); sb.append("</gen:GenericRequest>"); return sb.toString(); } private static Map<String, String> buildCriteriaMap(String criteria) { Map<String, String> criteriaMap = new HashMap<String, String>(); String since = ""; try { since = DateUtils.formatDateForWS(DateUtils.parseDate("01/01/1990")); } catch (ParseException e) { e.printStackTrace(); } criteriaMap.put("createdDate", since); criteriaMap.put("lastUpdatedDate", since); return criteriaMap; } public String syncOrganizations() { return send(SYNC_ORG_ENTITY_NAME, SYNC_ORG_OPERATION_NAME, false, buildCriteriaMap(null)); } public String mergeOrganizations() { return send(MERGED_ORG_ENTITY_NAME, MERGED_ORG_OPERATION_NAME, false, buildCriteriaMap(null)); } public String syncAgents() { return send(SYNC_AGENT_ENTITY_NAME, SYNC_AGENT_OPERATION_NAME, false, buildCriteriaMap(null)); } public String syncDevices() { return send(SYNC_DEVICE_ENTITY_NAME, SYNC_DEVICE_OPERATION_NAME, false, buildCriteriaMap(null)); } public String syncLabs() { return send(SYNC_LAB_ENTITY_NAME, SYNC_LAB_OPERATION_NAME, false, buildCriteriaMap(null)); } public String syncPriorTherapyLOV() { return send(SYNC_PRIOR_THERAPY_ENTITY_NAME, SYNC_PRIOR_THERAPY_OPERATION_NAME, false, buildCriteriaMap(null)); } public String syncPreExistingConditionLOV() { return send(SYNC_PRE_EXISTING_COND_ENTITY_NAME, SYNC_PRE_EXISTING_COND_OPERATION_NAME, false, buildCriteriaMap(null)); } public String syncASAEL() { return send(SYNC_ASAEL_ENTITY_NAME, SYNC_ASAEL_OPERATION_NAME, false, buildCriteriaMap(null)); } public String syncAgentUOM() { return send(SYNC_DOSE_UOM_ENTITY_NAME, SYNC_DOSE_UOM_OPERATION_NAME, false, buildCriteriaMap(null)); } public String syncCTCAE() { return send(SYNC_CTCAE_ENTITY_NAME, SYNC_CTCAE_OPERATION_NAME, false, buildCriteriaMap(null)); } public List<Study> searchStudies(String searchText) { List<Study> studyList = new ArrayList<Study>(); if (StringUtils.isNotEmpty(searchText)) { try { //invoke the webservice Map<String, String> criteriaMap = new HashMap<String, String>(); criteriaMap.put("documentTitle", searchText); criteriaMap.put("nciDocumentNumber", searchText); criteriaMap.put("localDocumentNumber", searchText); String correlationId = RandomStringUtils.randomAlphanumeric(15); String message = buildMessage(correlationId, "adeers", SEARCH_STUDY_ENTITY_NAME, SEARCH_STUDY_OPERATION_NAME, "sync", criteriaMap); String xmlSearchResult = simpleSendAndReceive(message); // Added the line to fix CAAERS-5799 issue xmlSearchResult = xmlSearchResult.replaceAll("encoding=\"UTF-8\"", "encoding=\"ISO-8859-1\""); if (log.isDebugEnabled()) log.debug("xmlSearchResult : for (" + searchText + ") :" + xmlSearchResult); String xmlStudies = xsltTransformer.toText(xmlSearchResult, "xslt/c2a_generic_response.xslt"); if (StringUtils.isEmpty(xmlStudies)) return studyList; Studies studies = (Studies) unmarshaller.unmarshal(new StringReader(xmlStudies)); for (gov.nih.nci.cabig.caaers.integration.schema.study.Study dtoStudy : studies.getStudy()) { Study domainStudy = new LocalStudy(); studyConverter.convertStudyDtoToStudyDomain(dtoStudy, domainStudy); //the following extra steps are need for the UI to get a valid Study structure. domainStudy.addStudyFundingSponsor(domainStudy.getFundingSponsor().getStudyFundingSponsor()); OrganizationAssignedIdentifier identifier = domainStudy.getFundingSponsor() .getOrganizationAssignedIdentifier(); identifier.setOrganization( domainStudy.getFundingSponsor().getStudyFundingSponsor().getOrganization()); domainStudy.addIdentifier(identifier); SystemAssignedIdentifier systemAssignedIdentifier = new SystemAssignedIdentifier(); systemAssignedIdentifier.setSystemName("CTEP-ESYS"); systemAssignedIdentifier.setType("Other"); systemAssignedIdentifier.setValue(domainStudy.getFundingSponsorIdentifierValue()); domainStudy.addIdentifier(systemAssignedIdentifier); studyList.add(domainStudy); } } catch (Exception e) { log.error("Error occured while invoking ServiceMix Study Search : " + e.getMessage(), e); log.info("Returning empty study list : unable to search in adeers for (" + searchText + ") :"); throw new CaaersSystemException(e.getMessage(), e); } } return studyList; } public String syncStudies() { throw new CaaersSystemException( "gov.nih.nci.cabig.caaers.service.ProxyWebServiceFacade.syncStudies : Not implemented"); } private String syncStudy(String operationName, String sponsorIdentifierValue) { try { //invoke the webservice Map<String, String> criteriaMap = new HashMap<String, String>(); criteriaMap.put("nciDocumentNumber", sponsorIdentifierValue); String correlationId = RandomStringUtils.randomAlphanumeric(15); String message = buildMessage(correlationId, "adeers", "study", operationName, "async", criteriaMap); String xmlStudyDetails = simpleSendAndReceive(message); if (log.isDebugEnabled()) log.debug("result for getStudyDetails : for (" + sponsorIdentifierValue + ") :" + xmlStudyDetails); String studyDbId = xsltTransformer.toText(xmlStudyDetails, "xslt/c2a_generic_response.xslt"); studyDbId = StringUtils.trim(studyDbId); if (log.isInfoEnabled()) log.info("Got study details : Study DB ID :" + studyDbId); return studyDbId; } catch (Exception e) { log.error("Error occurred while invoking ServiceMix Study Details : " + e.getMessage(), e); return "Import study failed:" + e.getMessage(); } } public String importStudy(String sponsorIdentifierValue) { boolean syncEnabled = ThreadScopeDataHolderService.getInstance().isStudySyncEnabled(); if (!syncEnabled) { log.info("Ignoring study sync/import call - as it is turned off for this thread"); return null; } String studyDbId = syncStudy(CREATE_STUDY_OPERATION_NAME, sponsorIdentifierValue); Study study = new LocalStudy(); if (NumberUtils.isNumber(studyDbId)) { study.setId(NumberUtils.toInt(studyDbId)); if (eventFactory != null) eventFactory.publishEntityModifiedEvent(study, false); } return studyDbId; } public String updateStudy(Integer id, boolean force) { boolean syncEnabled = ThreadScopeDataHolderService.getInstance().isStudySyncEnabled(); if (!syncEnabled) { log.info("Ignoring study sync/update call - as it is turned off for this thread"); return String.valueOf(id); } Study study = studyDao.getById(id); if (study == null) return "Unable to find the study (" + id + ")"; if (!force) { Date lastSyncedOn = study.getLastSynchedDate(); long diff = DateUtils.differenceInMinutes(DateUtils.today(), lastSyncedOn); Integer allowedDuration = configuration.get(Configuration.STUDY_SYNC_DELAY); allowedDuration = allowedDuration == null ? 0 : allowedDuration; if (diff < allowedDuration) { log.info("Ignoring the Sync Study request, as it was last updated on " + String.valueOf(lastSyncedOn)); return String.valueOf(study.getId()); } } String idText = study.getCtepEsysIdentifierValue(); if (idText == null) { idText = study.getFundingSponsorIdentifierValue(); } return syncStudy(UPDATE_STUDY_OPERATION_NAME, idText); } }