sos.scheduler.job.JobSchedulerHttpPostJob.java Source code

Java tutorial

Introduction

Here is the source code for sos.scheduler.job.JobSchedulerHttpPostJob.java

Source

/**
 * Copyright (C) 2014 BigLoupe http://bigloupe.github.io/SoS-JobScheduler/
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */
/********************************************************* begin of preamble
**
** Copyright (C) 2003-2012 Software- und Organisations-Service GmbH. 
** All rights reserved.
**
** This file may be used under the terms of either the 
**
**   GNU General Public License version 2.0 (GPL)
**
**   as published by the Free Software Foundation
**   http://www.gnu.org/licenses/gpl-2.0.txt and appearing in the file
**   LICENSE.GPL included in the packaging of this file. 
**
** or the
**  
**   Agreement for Purchase and Licensing
**
**   as offered by Software- und Organisations-Service GmbH
**   in the respective terms of supply that ship with this file.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
********************************************************** end of preamble*/
package sos.scheduler.job;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Vector;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;

import sos.spooler.Order;
import sos.spooler.Variable_set;

import sos.util.SOSFile;

/**
 * post files via http, based on Jakarta Commons HTTP Client, see commons-httpclient-3.0.jar
 * 
 * job parameters:
 * input_directory
 * input_filespec
 * output_directory
 * url
 * 
 * @author andreas.pueschel@sos-berlin.com
 * @since 1.0 2006-02-12 
 */
public class JobSchedulerHttpPostJob extends JobSchedulerJob {

    protected Vector inputFileList = null;

    protected Iterator inputFileListIterator = null;

    /** input directory */
    protected String inputDirectory = "";

    /** regular expression for file list */
    protected String inputFileSpec = "^(.*)$";

    /** output directory */
    protected String outputDirectory = "";

    /** post to url */
    protected String url = "";

    /** content type of input file(s) */
    protected String contentType = "";

    /** timeout for http request */
    protected int timeout = 0;

    /** Set of merged variables for replacements **/
    Variable_set mergedVariables;

    /**
     * Initialisation
     */
    public boolean spooler_init() {

        try {
            if (!super.spooler_init())
                return false;

            try { // to process job parameters
                if (spooler_task != null) {

                    if (spooler_task.params().var("input") != null
                            && spooler_task.params().var("input").length() > 0) {
                        this.setInputDirectory(spooler_task.params().var("input"));
                        spooler_log.info(".. job parameter [input]: " + this.getInputDirectory());
                    }

                    if (spooler_task.params().var("input_directory") != null
                            && spooler_task.params().var("input_directory").length() > 0) {
                        this.setInputDirectory(spooler_task.params().var("input_directory"));
                        spooler_log.info(".. job parameter [input_directory]: " + this.getInputDirectory());
                    }

                    if (spooler_task.params().var("input_filespec") != null
                            && spooler_task.params().var("input_filespec").length() > 0) {
                        this.setInputFileSpec(spooler_task.params().var("input_filespec"));
                        spooler_log.info(".. job parameter [input_filespec]: " + this.getInputFileSpec());
                    }

                    if (spooler_task.params().var("output") != null
                            && spooler_task.params().var("output").length() > 0) {
                        this.setOutputDirectory(spooler_task.params().var("output"));
                        spooler_log.info(".. job parameter [output]: " + this.getOutputDirectory());
                    }

                    if (spooler_task.params().var("output_directory") != null
                            && spooler_task.params().var("output_directory").length() > 0) {
                        this.setOutputDirectory(spooler_task.params().var("output_directory"));
                        spooler_log.info(".. job parameter [output_directory]: " + this.getOutputDirectory());
                    }

                    if (spooler_task.params().var("url") != null && spooler_task.params().var("url").length() > 0) {
                        this.setUrl(spooler_task.params().var("url"));
                        spooler_log.info(".. job parameter [url]: " + this.getUrl());
                    }

                    if (spooler_task.params().var("content_type") != null
                            && spooler_task.params().var("content_type").length() > 0) {
                        this.setContentType(spooler_task.params().var("content_type"));
                        spooler_log.info(".. job parameter [content_type]: " + this.getContentType());
                    }
                }

                // use a simple Apache Logger
                // System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
                // do not log
                System.setProperty("org.apache.commons.logging.log", "sos.util.SOSJCLNullLogger");
            } catch (Exception e) {
                throw (new Exception("an error occurred processing job parameters: " + e.getMessage()));
            }

            return true;
        } catch (Exception e) {
            spooler_log.warn("failed to initialize job: " + e.getMessage());
            return false;
        }
    }

    /**
     * check for files to post
     */

    public boolean spooler_open() {

        try {
            if (this.getInputDirectory() == null || this.getInputDirectory().length() == 0)
                return true;

            File inputFile = new File(this.getInputDirectory());
            if (inputFile.isDirectory()) {
                if (!inputFile.canRead())
                    throw new Exception("input directory is not accessible: " + inputFile.getCanonicalPath());
                spooler_log.debug6("retrieving files from directory: " + this.getInputDirectory()
                        + " for file specification: " + this.getInputFileSpec());
                this.inputFileList = SOSFile.getFilelist(this.getInputDirectory(), this.getInputFileSpec(), 0);
            } else {
                if (!inputFile.canRead())
                    throw new Exception("input file is not accessible: " + inputFile.getCanonicalPath());
                this.inputFileList = new Vector();
                this.inputFileList.add(inputFile);
            }

            if (this.inputFileList.size() > 0)
                spooler_log.info(this.inputFileList.size() + " input files found");

            this.inputFileListIterator = this.inputFileList.iterator();
            return this.inputFileListIterator.hasNext();

        } catch (Exception e) {
            spooler_log.warn("failed to retrieve input files from directory [" + this.getInputDirectory() + ", "
                    + this.getInputFileSpec() + "]: " + e.getMessage());
            return false;
        }
    }

    /**
     * Process single file
     */
    public boolean spooler_process() {

        Order order = null;
        File inputFile = null;
        File outputFile = null;
        String inputFileSpec = "";
        String url = "";
        String contentType = "";

        boolean rc = true;

        try {
            if (this.getOutputDirectory() != null && this.getOutputDirectory().length() > 0) {
                outputFile = new File(this.getOutputDirectory());
            }
            getLogger().debug8("merging parameters...");
            mergedVariables = spooler.create_variable_set();

            Variable_set env = spooler_task.create_subprocess().env();
            //this merge doesn't work:
            //mergedVariables.merge(env);
            String[] envVars = env.names().split(";");
            for (int i = 0; i < envVars.length; i++) {
                String currentName = envVars[i];
                mergedVariables.set_var(currentName, env.value(currentName));
            }
            mergedVariables.merge(spooler_task.params());
            // classic or order driven
            if (spooler_task.job().order_queue() == null) {
                if (!this.inputFileListIterator.hasNext())
                    return true;
                inputFile = (File) this.inputFileListIterator.next();
                rc = this.inputFileListIterator.hasNext();

                if (inputFile == null)
                    throw new Exception("empty input file item was found.");

            } else {
                // input file migth be specified on startup for order driven jobs 
                if (this.inputFileListIterator != null && this.inputFileListIterator.hasNext()) {
                    inputFile = (File) this.inputFileListIterator.next();
                }

                order = spooler_task.order();
                mergedVariables.merge(order.params());
                if (order.params() != null) {
                    if (order.params().value("input") != null
                            && order.params().value("input").toString().length() > 0) {
                        inputFile = new File(order.params().value("input").toString());
                        spooler_log.info(".. order parameter [input]: " + order.params().value("input").toString());
                    } else if (order.params().value("input_directory") != null
                            && order.params().value("input_directory").toString().length() > 0) {
                        inputFile = new File(order.params().value("input_directory").toString());
                        spooler_log.info(".. order parameter [input_directory]: "
                                + order.params().value("input_directory").toString());
                    }

                    if (order.params().value("input_filespec") != null
                            && order.params().value("input_filespec").toString().length() > 0) {
                        inputFileSpec = order.params().value("input_filespec").toString();
                        spooler_log.info(".. order parameter [input_filespec]: " + inputFileSpec);
                    }

                    if (order.params().value("output") != null
                            && order.params().value("output").toString().length() > 0) {
                        outputFile = new File((order.params().value("output").toString()));
                        spooler_log
                                .info(".. order parameter [output]: " + order.params().value("output").toString());
                    } else if (order.params().value("output_directory") != null
                            && order.params().value("output_directory").toString().length() > 0) {
                        outputFile = new File((order.params().value("output_directory").toString()));
                        spooler_log.info(".. order parameter [output_directory]: "
                                + order.params().value("output_directory").toString());
                    }

                    if (order.params().value("url") != null
                            && order.params().value("url").toString().length() > 0) {
                        url = order.params().value("url").toString();
                        spooler_log.info(".. order parameter [url]: " + url);
                    }

                    if (order.params().value("content_type") != null
                            && order.params().value("content_type").toString().length() > 0) {
                        contentType = order.params().value("content_type").toString();
                        spooler_log.info(".. order parameter [content_type]: " + contentType);
                    }
                }
            }

            if (url == null || url.length() == 0)
                url = this.getUrl();
            if (inputFileSpec == null || inputFileSpec.length() == 0)
                inputFileSpec = this.getInputFileSpec();

            if (!inputFile.exists())
                throw new Exception("input file [" + inputFile.getCanonicalPath() + "] does not exist.");
            if (url == null || url.length() == 0)
                throw new Exception("no URL was given to post files.");

            if (contentType == null || contentType.length() == 0)
                contentType = this.getContentType();
            if (contentType == null || contentType.length() == 0) {
                if (inputFile.getName().endsWith(".xml")) {
                    contentType = "text/xml";
                } else if (inputFile.getName().endsWith(".htm") || inputFile.getName().endsWith(".html")) {
                    contentType = "text/html";
                }

                // encoding ermitteln
                if (contentType.equals("text/html") || contentType.equals("text/xml")) {
                    BufferedReader br = new BufferedReader(new FileReader(inputFile));
                    String buffer = "";
                    String line = null;
                    int c = 0;
                    // die ersten 5 Zeilen nach einem encoding durchsuchen
                    while ((line = br.readLine()) != null || ++c > 5)
                        buffer += line;
                    Pattern p = Pattern.compile("encoding[\\s]*=[\\s]*['\"](.*?)['\"]", Pattern.CASE_INSENSITIVE);
                    Matcher m = p.matcher(buffer);
                    if (m.find())
                        contentType += "; charset=" + m.group(1);
                    br.close();
                }
            }

            int responseCode = postFile(inputFile, this.getInputFileSpec(), outputFile, contentType, url);
            spooler_log.info("input file [" + inputFile.getCanonicalPath() + "] processed for URL [" + url
                    + "] with response code " + responseCode);

            if (spooler_task.job().order_queue() != null) {
                return rc;
            } else {
                return this.inputFileListIterator.hasNext();
            }

        } catch (Exception e) {
            String message = "error occurred processing";
            if (inputFile != null)
                message += " file [" + inputFile.getAbsolutePath() + "]";
            if (url != null && url.length() > 0)
                message += " for url [" + url + "]";
            spooler_log.warn(message + ": " + e);

            // restart this order driven task in case of errors to make the task log available by mail
            if (spooler_task.job().order_queue() != null) {
                spooler_task.end();
                return false;
            } else {
                return this.inputFileListIterator.hasNext();
            }
        }
    }

    public int postFile(File inputFile, String inputFileSpec, File outputFile, String contentType, String url)
            throws Exception {

        int rc = 0;

        try {
            if (inputFile.isDirectory()) {
                Vector filelist = SOSFile.getFilelist(inputFile.getCanonicalPath(), inputFileSpec, 0);
                Iterator iterator = filelist.iterator();
                while (iterator.hasNext()) {
                    rc = this.postFile((File) iterator.next(), inputFileSpec, outputFile, contentType, url);
                }
                return rc;
            } else {
                PostMethod post = new PostMethod(url);
                String content = SOSFile.readFile(inputFile);
                getLogger().debug9("post before replacements: " + content);
                content = mergedVariables.substitute(content);
                getLogger().debug5("Posting: " + content);
                StringRequestEntity req = new StringRequestEntity(content);
                // post.setRequestEntity(new InputStreamRequestEntity(new FileInputStream(inputFile), inputFile.length()));
                post.setRequestEntity(req);
                post.setRequestHeader("Content-type", contentType);

                HttpClient httpClient = new HttpClient();
                if (this.getTimeout() > 0) {
                    HttpConnectionManager httpManager = httpClient.getHttpConnectionManager();
                    HttpConnectionManagerParams httpParams = new HttpConnectionManagerParams();
                    httpParams.setConnectionTimeout(this.getTimeout() * 1000);
                    httpManager.setParams(httpParams);
                }
                rc = httpClient.executeMethod(post);

                if (outputFile != null)
                    logResponse(inputFile, outputFile, post.getResponseBodyAsStream());
                return rc;
            }
        } catch (Exception e) {
            throw new Exception("error occurred in HTTP POST: " + e.getMessage());
        }
    }

    private void logResponse(File inputFile, File outputFile, InputStream responseStream) throws Exception {

        if (outputFile == null)
            throw new Exception("cannot write response: output file is null");
        if (responseStream == null)
            throw new Exception("cannot write response: response is null");

        if (!outputFile.canRead()) {
            File path = new File(outputFile.getParent());
            if (!path.canRead())
                path.mkdirs();
            outputFile.createNewFile();
        }

        if (!outputFile.canWrite())
            throw new Exception("cannot write to file: " + outputFile.getCanonicalPath());

        if (outputFile.isDirectory())
            outputFile = new File(outputFile.getCanonicalPath() + "/" + inputFile.getName());

        FileOutputStream outputStream = new FileOutputStream(outputFile);

        try {
            byte buffer[] = new byte[1000];
            int numOfBytes = 0;

            while ((numOfBytes = responseStream.read(buffer)) != -1)
                outputStream.write(buffer, 0, numOfBytes);
        } catch (Exception e) {
            throw new Exception("error occurred while logging to file [" + outputFile.getCanonicalPath() + "]: "
                    + e.getMessage());
        } finally {
            try {
                if (responseStream != null) {
                    responseStream.close();
                }
            } catch (Exception ex) {
            } // gracefully ignore this error
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (Exception ex) {
            } // gracefully ignore this error
        }
    }

    /**
     * @return Returns the inputDirectory.
     */
    public String getInputDirectory() {
        return inputDirectory;
    }

    /**
     * @param inputDirectory The inputDirectory to set.
     */
    public void setInputDirectory(String inputDirectory) {
        this.inputDirectory = inputDirectory;
    }

    /**
     * @return Returns the inputFileSpec.
     */
    public String getInputFileSpec() {
        return inputFileSpec;
    }

    /**
     * @param inputFileSpec The inputFileSpec to set.
     */
    public void setInputFileSpec(String inputFileSpec) {
        this.inputFileSpec = inputFileSpec;
    }

    /**
     * @return Returns the outputDirectory.
     */
    public String getOutputDirectory() {
        return outputDirectory;
    }

    /**
     * @param outputDirectory The outputDirectory to set.
     */
    public void setOutputDirectory(String outputDirectory) {
        this.outputDirectory = outputDirectory;
    }

    /**
     * @return Returns the url.
     */
    public String getUrl() {
        return url;
    }

    /**
     * @param url The url to set.
     */
    public void setUrl(String url) {
        this.url = url;
    }

    /**
     * @return Returns the contentType.
     */
    public String getContentType() {
        return contentType;
    }

    /**
     * @param contentType The contentType to set.
     */
    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    /**
     * @return Returns the timeout.
     */
    public int getTimeout() {
        return timeout;
    }

    /**
     * @param timeout The timeout to set.
     */
    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

}