/** * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations under * the License. * * The Original Code is OpenELIS code. * * Copyright (C) ITECH, University of Washington, Seattle WA. All Rights Reserved. * */ package us.mn.state.health.lims.dataexchange.aggregatereporting; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.hibernate.Transaction; import us.mn.state.health.lims.common.util.DateUtil; import us.mn.state.health.lims.dataexchange.aggregatereporting.dao.ReportExternalImportDAO; import us.mn.state.health.lims.dataexchange.aggregatereporting.daoimpl.ReportExternalImportDAOImpl; import us.mn.state.health.lims.dataexchange.aggregatereporting.valueholder.ReportExternalImport; import us.mn.state.health.lims.hibernate.HibernateUtil; import us.mn.state.health.lims.login.dao.LoginDAO; import us.mn.state.health.lims.login.daoimpl.LoginDAOImpl; import us.mn.state.health.lims.login.valueholder.Login; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; public class IndicatorAggregationReportingServlet extends HttpServlet { private static ReportExternalImportDAO reportImportDAO = new ReportExternalImportDAOImpl(); private static LoginDAO loginDAO = new LoginDAOImpl(); private final String DATE_PATTERN = "yyyy-MM-dd"; @Override protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException { response.setStatus(HttpServletResponse.SC_OK); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // LogEvent.logFatal("IndicatorAggregationReportingServlet", "size", String.valueOf(request.getContentLength())); ServletInputStream inputStream = request.getInputStream(); List<ReportExternalImport> insertableImportReports = new ArrayList<ReportExternalImport>(); List<ReportExternalImport> updatableImportReports = new ArrayList<ReportExternalImport>(); Document sentIndicators = getDocument( inputStream, request.getContentLength()); if (sentIndicators == null) { response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } if (!authenticated(sentIndicators)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return; } /* This is too handle the problem where either 1. The same lab sends a report quickly enough to cause a race condition 2. Two different labs send a report at the same time but one is miss-configured and uses the same site id In both cases createReportItems considers the report a new one rather than a modification of an existing report */ synchronized( this ){ createReportItems( sentIndicators, insertableImportReports, updatableImportReports ); updateReports( insertableImportReports, updatableImportReports ); } response.setStatus(HttpServletResponse.SC_OK); } private Document getDocument(ServletInputStream inputStream, int contentLength) { int charCount = 0; byte[] byteBuffer = new byte[contentLength]; while( true){ try { int readLength = inputStream.readLine(byteBuffer, charCount, 1024); //LogEvent.logFatal("IndicatorAggregationReportingServlet", String.valueOf(readLength), new String(byteBuffer).trim()); if( readLength == -1){ return DocumentHelper.parseText(new String(byteBuffer).trim()); }else{ charCount += readLength; } } catch (IOException e) { e.printStackTrace(); return null; } catch (DocumentException de) { de.printStackTrace(); return null; } } } private void updateReports(List<ReportExternalImport> insertableImportReports, List<ReportExternalImport> updatableImportReports) { Transaction tx = HibernateUtil.getSession().beginTransaction(); try { for (ReportExternalImport importReport : insertableImportReports) { reportImportDAO.insertReportExternalImport(importReport); } for (ReportExternalImport importReport : updatableImportReports) { reportImportDAO.updateReportExternalImport(importReport); } tx.commit(); } catch (Exception e) { tx.rollback(); } } private void createReportItems(Document aggregateDoc, List<ReportExternalImport> insertableImportReports, List<ReportExternalImport> updatableImportReports) { String sendingSiteId = (String) aggregateDoc.getRootElement().element("site-id").getData(); Set<String> eventDateSet = new HashSet<String>(); // to make sure no // duplicates for (Object reportObj : aggregateDoc.getRootElement().elements("reports")) { Element report = (Element) reportObj; String eventDate = (String) report.element("event-date").getData(); eventDate = eventDate.split(" ")[0]; if (!eventDateSet.contains(eventDate)) { eventDateSet.add(eventDate); String data = (String) report.element("data").getData(); ReportExternalImport importReport = createReportExternalImport(sendingSiteId, eventDate, data); if (importReport.getId() == null) { insertableImportReports.add(importReport); } else { updatableImportReports.add(importReport); } } } } private boolean authenticated(Document sentIndicators) { Element userElement = sentIndicators.getRootElement().element("user"); Element passwordElement = sentIndicators.getRootElement().element("drowssap"); if (userElement == null || passwordElement == null) { return false; } String user = (String) userElement.getData(); String password = (String) passwordElement.getData(); Login login = new Login(); login.setLoginName(user); login.setPassword(password); Login loginInfo = loginDAO.getValidateLogin(login); return loginInfo != null; } private ReportExternalImport createReportExternalImport(String sendingSiteId, String eventDate, String data) { ReportExternalImport importReport = new ReportExternalImport(); importReport.setEventDate(DateUtil.convertStringDateToTimestampWithPatternNoLocale(eventDate, DATE_PATTERN)); importReport.setSendingSite(sendingSiteId); importReport.setReportType("testIndicators"); ReportExternalImport rei = reportImportDAO.getReportByEventDateSiteType(importReport); if (rei != null) { importReport = rei; } importReport.setData(data); importReport.setSysUserId("1"); importReport.setRecievedDate(DateUtil.getTimestampAtMidnightForDaysAgo(0)); return importReport; } private static final long serialVersionUID = 1L; }