Java tutorial
/** * 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; } }