Package ke.go.moh.oec.adt

Source Code of ke.go.moh.oec.adt.Daemon

/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* 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 OpenEMRConnect.
*
* The Initial Developer of the Original Code is International Training &
* Education Center for Health (I-TECH) <http://www.go2itech.org/>
*
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
package ke.go.moh.oec.adt;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.xml.parsers.ParserConfigurationException;
import ke.go.moh.oec.adt.controller.*;
import ke.go.moh.oec.adt.data.LinkedRecord;
import ke.go.moh.oec.adt.data.Record;
import ke.go.moh.oec.adt.data.RecordSource;
import ke.go.moh.oec.adt.data.Transaction;
import ke.go.moh.oec.adt.exceptions.BadRecordSourceException;
import ke.go.moh.oec.adt.format.OneLineRecordFormat;
import ke.go.moh.oec.adt.format.RecordFormat;
import ke.go.moh.oec.lib.Mediator;
import org.apache.commons.codec.binary.Base64InputStream;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.xml.sax.SAXException;

/**
* @date Apr 29, 2012
*
* @author Gitahi Ng'ang'a
*/
public class Daemon implements Runnable {

    private final String method;
    private final long interval;
    private final String timeOfDay;
    private final long lookback;

    public Daemon(String method, long interval, String timeOfDay, long lookback) {
        this.method = method;
        this.interval = interval;
        this.timeOfDay = timeOfDay;
        this.lookback = lookback;
    }

    @Override
    public void run() {
        try {
            Date since = null;
            if (lookback > 0) {
                Date now = new Date();
                since = new Date(now.getTime() - lookback);
            }
            List<RecordSource> recordSourceList = new ResourceManager().loadRecordSources();
            if ("interval".equalsIgnoreCase(method)) {
                while (true) {
                    work(recordSourceList, since);
                    Thread.sleep(interval);
                }
            } else {
                DateFormat dateFormat = new SimpleDateFormat("HH:mm");
                while (true) {
                    String currentTime = dateFormat.format(new Date());
                    if (currentTime.equalsIgnoreCase(timeOfDay)) {
                        work(recordSourceList, since);
                    }
                }
            }
        } catch (InterruptedException ex) {
            Mediator.getLogger(Daemon.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BadRecordSourceException ex) {
            Mediator.getLogger(Daemon.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(1);
        } catch (ParserConfigurationException ex) {
            Mediator.getLogger(Daemon.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(1);
        } catch (SAXException ex) {
            Mediator.getLogger(Daemon.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(1);
        } catch (IOException ex) {
            Mediator.getLogger(Daemon.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Mediator.getLogger(Daemon.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void work(List<RecordSource> recordSourceList, Date since) throws SQLException, BadRecordSourceException, IOException {
        Mediator.getLogger(Daemon.class.getName()).log(Level.INFO, "Service running...");
        if (!recordSourceList.isEmpty()) {
            Mediator.getLogger(Daemon.class.getName()).log(Level.FINE, "Mining transactions...");
            TransactionMiner transactionMiner = new TransactionMiner();
            Map<RecordSource, Map<Integer, Transaction>> transactionMap =
                    transactionMiner.mine(recordSourceList, since);
            int transactionCount = countTransactions(transactionMap);
            if (transactionCount != 0) {
                Mediator.getLogger(Daemon.class.getName()).log(Level.FINE, "{0} transactions found.", transactionCount);
                Mediator.getLogger(Daemon.class.getName()).log(Level.FINE, "Mining records...");
                RecordMiner recordMiner = new RecordMiner();
                Map<RecordSource, List<Record>> recordMap = recordMiner.mine(transactionMap);
                int recordCount = countRecords(recordMap);
                Mediator.getLogger(Daemon.class.getName()).log(Level.FINE, "Linking {0} records...", recordCount);
                List<LinkedRecord> linkedRecordList = new RecordLinker(recordMiner).link(recordMap);
                if (!linkedRecordList.isEmpty()) {
                    Mediator.getLogger(Daemon.class.getName()).log(Level.FINE, "{0} records linked.", linkedRecordList.size());
                    RecordFormat oneLineFormat = new OneLineRecordFormat();
                    RecordCsvWriter csvWriter = new RecordCsvWriter(oneLineFormat);

                    int recordsPerFile = 100;
                    try {
                        recordsPerFile = Integer.parseInt(Mediator.getProperty("outputrecordlimit"));
                    } catch (Exception ex) {
                        Mediator.getLogger(Daemon.class.getName()).log(Level.INFO, "The outputrecordlimit property is missing, "
                                + "unspecified or not a number. The default value of 100 will be used.", ex);
                    }

                    csvWriter.writeToCsv(linkedRecordList, ResourceManager.getSetting("outputdir"), ResourceManager.getSetting("outputfilename"),
                            ResourceManager.getSetting("outputfileextension"), recordsPerFile);

                    // Send extracted file to remote Mirth instance if so configured
                    if ("remote".equalsIgnoreCase(ResourceManager.getSetting("mirth.location"))) {
                        if (!"".equals(ResourceManager.getSetting("mirth.url"))
                                && ResourceManager.getSetting("mirth.url") != null) {
                            if (sendMessage(ResourceManager.getSetting("mirth.url"), ResourceManager.getSetting("outputfilename") + ".csv")) {
                                Mediator.getLogger(Daemon.class.getName()).log(Level.INFO, "File sent!");
                            } else {
                                Mediator.getLogger(Daemon.class.getName()).log(Level.INFO, "File not sent!");
                            }
                        } else {
                            Mediator.getLogger(Daemon.class.getName()).log(Level.INFO, "No URL provided for remote Mirth instance.  The file was not sent!");
                        }
                    }
                } else {
                    Mediator.getLogger(Daemon.class.getName()).log(Level.FINE, "No records linked.");
                }
                transactionMiner.saveLastTransactionId();
                Mediator.getLogger(Daemon.class.getName()).log(Level.INFO, "Done!");
            } else {
                Mediator.getLogger(Daemon.class.getName()).log(Level.FINE, "No transactions found.");
            }
        } else {
            Mediator.getLogger(Daemon.class.getName()).log(Level.FINE, "No record sources found.");
        }
        Mediator.getLogger(Main.class.getName()).log(Level.INFO, "Suspending service for {0} seconds...", interval / 1000);
    }

    private int countTransactions(Map<RecordSource, Map<Integer, Transaction>> transactionMap) {
        int transactionCount = 0;
        for (RecordSource rs : transactionMap.keySet()) {
            Map<Integer, Transaction> tm = transactionMap.get(rs);
            if (tm != null) {
                transactionCount += tm.size();
            }
        }
        return transactionCount;
    }

    private int countRecords(Map<RecordSource, List<Record>> recordMap) {
        int recordCount = 0;
        for (RecordSource rs : recordMap.keySet()) {
            List<Record> rl = recordMap.get(rs);
            if (rl != null) {
                recordCount += rl.size();
            }
        }
        return recordCount;
    }

    private static boolean sendMessage(String url, String filename) {
        int returnStatus = HttpStatus.SC_CREATED;
        HttpClient httpclient = new HttpClient();
        HttpConnectionManager connectionManager = httpclient.getHttpConnectionManager();
        connectionManager.getParams().setSoTimeout(120000);

        PostMethod httpPost = new PostMethod(url);

        RequestEntity requestEntity;
        try {
            FileInputStream message = new FileInputStream(filename);
            Base64InputStream message64 = new Base64InputStream(message, true, -1, null);
            requestEntity = new InputStreamRequestEntity(message64, "application/octet-stream");
        } catch (FileNotFoundException e) {
            Mediator.getLogger(Daemon.class.getName()).log(Level.SEVERE, "File not found.", e);
            return false;
        }
        httpPost.setRequestEntity(requestEntity);
        try {
            httpclient.executeMethod(httpPost);
            returnStatus = httpPost.getStatusCode();
        } catch (SocketTimeoutException e) {
            returnStatus = HttpStatus.SC_REQUEST_TIMEOUT;
            Mediator.getLogger(Daemon.class.getName()).log(Level.SEVERE, "Request timed out.  Not retrying.", e);
        } catch (HttpException e) {
            returnStatus = HttpStatus.SC_INTERNAL_SERVER_ERROR;
            Mediator.getLogger(Daemon.class.getName()).log(Level.SEVERE, "HTTP exception.  Not retrying.", e);
        } catch (ConnectException e) {
            returnStatus = HttpStatus.SC_SERVICE_UNAVAILABLE;
            Mediator.getLogger(Daemon.class.getName()).log(Level.SEVERE, "Service unavailable.  Not retrying.", e);
        } catch (UnknownHostException e) {
            returnStatus = HttpStatus.SC_NOT_FOUND;
            Mediator.getLogger(Daemon.class.getName()).log(Level.SEVERE, "Not found.  Not retrying.", e);
        } catch (IOException e) {
            returnStatus = HttpStatus.SC_GATEWAY_TIMEOUT;
            Mediator.getLogger(Daemon.class.getName()).log(Level.SEVERE, "IO exception.  Not retrying.", e);
        } finally {
            httpPost.releaseConnection();
        }
        return returnStatus == HttpStatus.SC_OK;
    }
}
TOP

Related Classes of ke.go.moh.oec.adt.Daemon

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.