/** process single mail order */ public boolean spooler_process() { Order order = null; Variable_set parameters = null; File listFile = null; File messageFile = null; File failedFile = null; String messageId = ""; long mailOrderId = 0; long curDeliveryCounter = 1; try { // classic or order driven if (spooler_task.job().order_queue() == null) { parameters = spooler_task.params(); if (!this.mailOrderIterator.hasNext()) return true; listFile = (File) this.mailOrderIterator.next(); } else { order = spooler_task.order(); parameters = (Variable_set) spooler_task.order().payload(); if (parameters.var("file") == null || parameters.var("file").toString().length() == 0) throw (new Exception("no filename was given in payload")); listFile = new File( this.getQueueDirectory() + ((!this.getQueueDirectory().endsWith("/") && !this.getQueueDirectory().endsWith("\\")) ? "/" : "") + parameters.var("file")); } File workFile = new File(listFile.getAbsolutePath()); if (this.getLogger() != null) this.getLogger().info("processing mail file: " + workFile.getAbsolutePath()); if (workFile == null) { throw new Exception("empty file name found."); } else if (!workFile.exists()) { throw new Exception("mail file [" + workFile.getAbsolutePath() + "] does not exist."); } else if (!workFile.canRead()) { throw new Exception("cannot read from mail file [" + workFile.getAbsolutePath() + "]"); } // prepare a file for later rename operations in case of error String failedPath = ""; if (workFile.getAbsolutePath().lastIndexOf("/") > 0) { failedPath = workFile.getAbsolutePath().substring(0, workFile.getAbsolutePath().lastIndexOf("/")); } else if (workFile.getAbsolutePath().lastIndexOf("\\") > 0) { failedPath = workFile.getAbsolutePath().substring(0, workFile.getAbsolutePath().lastIndexOf("\\")); } if (!failedPath.endsWith("/") && !failedPath.endsWith("\\")) failedPath += "/"; String failedName = workFile.getName(); if (failedName.endsWith("~")) { failedName = failedName.substring(0, failedName.length() - 1); } failedFile = new File(failedPath + this.getFailedPrefix() + failedName); messageFile = new File(workFile.getAbsolutePath() + "~"); if (messageFile.exists()) messageFile.delete(); workFile.renameTo(messageFile); // populate mailer with settings if (this.sosMailSettings != null) { sosMail = new SOSMail(this.sosMailSettings); } else { sosMail = new SOSMail(spooler_log.mail().smtp()); } if (this.getLogger() != null) sosMail.setSOSLogger(this.getLogger()); // job scheduler sets mail host if no default was specified by settings if (sosMail.getHost() == null || sosMail.getHost().length() == 0 || sosMail.getHost().equalsIgnoreCase("-queue")) { if (!spooler_log.mail().smtp().equalsIgnoreCase("-queue")) { sosMail.setHost(spooler_log.mail().smtp()); } else { throw new Exception("no SMTP host was configured, global settings contain smtp=-queue"); } } // job scheduler sets mail queue directory if no default was specified by parameters or // settings if (sosMail.getQueueDir() == null || sosMail.getQueueDir().length() == 0) sosMail.setQueueDir(this.getQueueDirectory()); // set queue prefix "sos" to enable dequeueing by JobSchedulerMailDequeueJob sosMail.setQueuePraefix(this.getQueuePrefix()); SOSSettings smtpSettings = new SOSProfileSettings(spooler.ini_path()); Properties smtpProperties = smtpSettings.getSection("smtp"); if (!smtpProperties.isEmpty()) { if (smtpProperties.getProperty("mail.smtp.user") != null && smtpProperties.getProperty("mail.smtp.user").length() > 0) { sosMail.setUser(smtpProperties.getProperty("mail.smtp.user")); } if (smtpProperties.getProperty("mail.smtp.password") != null && smtpProperties.getProperty("mail.smtp.password").length() > 0) { sosMail.setPassword(smtpProperties.getProperty("mail.smtp.password")); } } try { // to load mail and check delivery counter sosMail.loadFile(messageFile); messageId = sosMail.getLoadedMessageId(); } catch (Exception e) { throw new Exception("mail file [" + workFile.getAbsolutePath() + "]: " + e.getMessage()); } try { // to retrieve mail order from database if (this.getConnection() != null && this.hasDatabase()) { String id = this.getConnection() .getSingleValue( "SELECT \"ID\" FROM " + this.getTableMails() + " WHERE \"MESSAGE_ID\"='" + messageId + "'"); if (id == null || id.length() == 0) { this.getLogger() .debug1( "no entry found in database for message id [" + messageId + "] of mail file: " + workFile.getAbsolutePath()); } else { mailOrderId = Integer.parseInt(id); } } } catch (Exception e) { throw new Exception( "error occurred retrieving entry in database for message id [" + messageId + "] of mail file [" + workFile.getAbsolutePath() + "]: " + e.getMessage()); } try { // to check the delivery counter if (sosMail.getMessage().getHeader("X-SOSMail-delivery-counter") != null && sosMail.getMessage().getHeader("X-SOSMail-delivery-counter").length > 0) { try { curDeliveryCounter = Integer.parseInt( sosMail .getMessage() .getHeader("X-SOSMail-delivery-counter")[0] .toString() .trim()); } catch (Exception ex) { throw new Exception( "illegal header value for X-SOSMail-delivery-counter: " + sosMail.getMessage().getHeader("X-SOSMail-delivery-counter")[0].toString()); } if (++curDeliveryCounter > this.getMaxDeliveryCounter() && this.getMaxDeliveryCounter() > 0) { if (this.getLogger() != null) this.getLogger() .debug3( "mail file [" + workFile.getAbsolutePath() + "] exceeds number of trials [" + this.getMaxDeliveryCounter() + "] to send mail and will not be dequeued"); sosMail.setQueueDir(""); } } sosMail .getMessage() .setHeader("X-SOSMail-delivery-counter", String.valueOf(curDeliveryCounter)); sosMail.getMessage().saveChanges(); } catch (Exception e) { throw new Exception("mail file [" + workFile.getAbsolutePath() + "]: " + e.getMessage()); } try { // to send boolean shouldSend = true; File mailFile = null; String message = ""; if (this.getLogDirectory() != null && this.getLogDirectory().length() > 0) { // dump message with attachments mailFile = this.getMailFile(this.getLogDirectory()); sosMail.dumpMessageToFile(mailFile, true); } if (this.isLogOnly()) { message = "mail was NOT sent" + ((this.getMaxDeliveryCounter() > 0) ? " (trial " + curDeliveryCounter + " of " + this.getMaxDeliveryCounter() + ")" : "") + " but stored to file: " + mailFile.getAbsolutePath(); if (this.getLogger() != null) this.getLogger().info(message); message = (message.length() > 250 ? message.substring(message.length() - 250) : message); message = message.replaceAll("'", "''"); shouldSend = false; } else if (!sosMail.send()) { message = "mail was NOT sent but stored for later dequeueing" + ((this.getMaxDeliveryCounter() > 0) ? " (trial " + curDeliveryCounter + " of " + this.getMaxDeliveryCounter() + ")" : "") + ", reason was: " + sosMail.getLastError(); if (this.getLogger() != null) this.getLogger().info(message); message = (message.length() > 250 ? message.substring(message.length() - 250) : message); message = message.replaceAll("'", "''"); shouldSend = false; } try { // to check the delivery counter if mail could not be sent if (!shouldSend && curDeliveryCounter > this.getMaxDeliveryCounter() && this.getMaxDeliveryCounter() > 0) { throw new Exception( "number of trials [" + this.getMaxDeliveryCounter() + "] exceeded to send mail from file: " + workFile.getAbsolutePath()); } } catch (Exception e) { throw new Exception(e.getMessage()); } if (this.getLogger() != null) { if (this.isLogOnly()) { this.getLogger() .info( "mail was processed from file [" + workFile.getAbsolutePath() + "] to: " + sosMail.getRecipientsAsString() + " into: " + mailFile.getAbsolutePath()); } else { this.getLogger() .info( "mail was sent from file [" + workFile.getAbsolutePath() + "] to: " + sosMail.getRecipientsAsString()); } } if (this.getConnection() != null && this.hasDatabase() && mailOrderId > 0) { this.getConnection() .executeUpdate( "UPDATE " + this.getTableMails() + " SET \"JOB_ID\"=" + spooler_task.id() + ", \"STATUS\"=" + STATE_SUCCESS + ", \"STATUS_TEXT\"='" + message + "'" + ", \"MESSAGE_ID\"='" + sosMail.getMessage().getMessageID() + "'" + ", \"MODIFIED\"=%now, \"MODIFIED_BY\"='" + spooler_task.job().name() + "', \"DELIVERED\"=%now" + " WHERE \"ID\"=" + mailOrderId); this.getConnection().commit(); } if (this.getLogger() != null) this.getLogger().debug3("mail was sent with headers: " + sosMail.dumpHeaders()); } catch (Exception ex) { throw new Exception( "mail was NOT sent from file [" + workFile.getAbsolutePath() + "]" + ((mailOrderId > 0) ? " for order [" + mailOrderId + "]" : "") + ": " + ex.getMessage()); } messageFile.delete(); // return value for classic and order driven processing if (spooler_task.job().order_queue() == null) { return this.mailOrderIterator.hasNext(); } else { return true; } } catch (Exception e) { String message = ""; if (spooler_task.job().order_queue() != null) { message = "error occurred processing mail [" + mailOrderId + "] : " + e.getMessage(); } else { message = "error occurred processing mail: " + e.getMessage(); } // do not create warnings (that are sent by mail) if the number of dequeue trials has exceeded // no: always create warnings if ((curDeliveryCounter > this.getMaxDeliveryCounter() && this.getMaxDeliveryCounter() > 0) && (sosMail.getQueueDir() == null || sosMail.getQueueDir().length() == 0)) { spooler_log.warn(message); } else { spooler_log.warn(message); } try { // to update database if mail order has been identified if (this.getConnection() != null && this.hasDatabase() && mailOrderId > 0) { message = (e.getMessage().length() > 250 ? e.getMessage().substring(e.getMessage().length() - 250) : e.getMessage()); message = message.replaceAll("'", "''"); this.getConnection() .executeUpdate( "UPDATE " + this.getTableMails() + " SET \"JOB_ID\"=" + spooler_task.id() + ", \"STATUS\"=" + STATE_ERROR + ", \"STATUS_TEXT\"='" + message + "'," + "\"MODIFIED\"=%now, \"MODIFIED_BY\"='" + spooler_task.job().name() + "', \"DELIVERED\"=NULL" + " WHERE \"ID\"=" + mailOrderId); this.getConnection().commit(); } } catch (Exception ex) { spooler_log.warn("error occurred updating mail order: " + ex.getMessage()); } // return value for classic and order driven processing if (spooler_task.job().order_queue() == null) { return this.mailOrderIterator.hasNext(); } else { return false; } } finally { try { // this file should only exist in case of errors, we rename it with a prefix to prevent // further processing if (messageFile.exists()) { spooler_log.info( "mail file is renamed to exclude it from further processing: " + failedFile.getAbsolutePath()); messageFile.renameTo(failedFile); } } catch (Exception ex) { } // gracefully ignore this error to preserve the original exception try { if (this.getConnection() != null) this.getConnection().rollback(); } catch (Exception ex) { } // gracefully ignore this error to preserve the original exception } }
public boolean spooler_process() { try { super.spooler_process(); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } boolean checkParallel = false; boolean parallelTransfer = false; String parallelTransferCheckSetback = "00:00:60"; int parallelTransferCheckRetry = 60; Variable_set params = null; boolean rc = false; boolean isFilePath = false; boolean orderSelfDestruct = false; // Properties schedulerParams = null; HashMap<String, String> schedulerParams = null; try { this.setLogger(new SOSSchedulerLogger(spooler_log)); getLogger().info(JSVersionInfo.getVersionString()); getLogger().info(conSVNVersion); try { // to get the job and order parameters params = getParameters(); schedulerParams = objOptions.DeletePrefix(super.getSchedulerParameterAsProperties(params), "ftp_"); schedulerParams.putAll(getParameterDefaults(params)); checkParallel = sosString.parseToBoolean( sosString.parseToString(schedulerParams.get(conParameterCHECK_PARALLEL))); parallelTransfer = sosString.parseToBoolean( sosString.parseToString(schedulerParams.get(conParameterPARALLEL))); } catch (Exception e) { throw new JobSchedulerException("could not process job parameters: " + e.getMessage(), e); } try { if (checkParallel && spooler_job.order_queue() != null) { boolean bSuccess = true; String[] paramNames = sosString.parseToString(spooler.variables().names()).split(";"); for (int i = 0; i < paramNames.length; i++) { if (paramNames[i].startsWith( "ftp_check_send_" + normalize(spooler_task.order().id()) + ".")) { if (sosString.parseToString(spooler.var(paramNames[i])).equals("0")) { // Anzahl der Wiederholungen merken String sRetry = sosString.parseToString( spooler .variables() .var("cur_transfer_retry" + normalize(spooler_task.order().id()))); int retry = sRetry.length() == 0 ? 0 : Integer.parseInt(sRetry); --retry; spooler .variables() .set_var( "cur_transfer_retry" + normalize(spooler_task.order().id()), String.valueOf(retry)); if (retry == 0) { getLogger().debug("terminated cause max order setback reached: " + paramNames[i]); spooler .variables() .set_var( "terminated_cause_max_order_setback_" + normalize(spooler_task.order().id()), "1"); return false; } getLogger() .debug( "launching setback: " + parallelTransferCheckRetry + " * " + parallelTransferCheckSetback); spooler_task.order().setback(); return false; } else if (sosString.parseToString(spooler.var(paramNames[i])).equals("1")) { getLogger().debug("successfully terminated: " + paramNames[i]); } else if (sosString.parseToString(spooler.var(paramNames[i])).equals("2")) { bSuccess = false; getLogger().debug("terminated with error : " + paramNames[i]); } } } return bSuccess; } else if (sosString.parseToString(params.var("ftp_parent_order_id")).length() > 0) { // Hauptauftrag wurde wegen Erreichens von ftp_parallel_check_retry beendet -> die // restlichen Unterauftr�ge sollen // nicht durchlaufen String state = spooler .variables() .var( "terminated_cause_max_order_setback_" + normalize(params.var("ftp_parent_order_id"))); if (state.equals("1")) return false; } if (sosString.parseToString(schedulerParams.get("file_path")).length() > 0) { isFilePath = true; } else { isFilePath = false; } } catch (Exception e) { throw (new Exception("invalid or insufficient parameters: " + e.getMessage())); } try { // to process ftp if (parallelTransfer && !isFilePath) { // nur die filelist holen um Parallelen transfer zu erm�glichen Properties p = new Properties(); p.putAll((Properties) schedulerParams.clone()); p.put("skip_transfer", "yes"); // kb 2011-04--27 no longer needed due to too much trouble with this file / concept // createIncludeConfigurationFile("sos/net/sosftp/Configuration.xml", // "sos.net.sosftp.Configuration.xml");//Alle // Parametern sind hier auch g�ltig SOSConfiguration con = new SOSConfiguration( null, p, sosString.parseToString(schedulerParams.get(conParameterSETTINGS)), sosString.parseToString(schedulerParams.get(conParameterPROFILE)), // "sos/scheduler/ftp/SOSFTPConfiguration.xml", new // SOSSchedulerLogger(spooler_log)); null, new SOSSchedulerLogger(spooler_log)); con.checkConfigurationItems(); sos.net.sosftp.SOSFTPCommandSend ftpCommand = new sos.net.sosftp.SOSFTPCommandSend(con, new SOSSchedulerLogger(spooler_log)); ftpCommand.setSchedulerJob(this); rc = ftpCommand.transfer(); Vector<File> filelist = ftpCommand.getTransferredFilelist(); Iterator iterator = filelist.iterator(); if (isJobchain() == false) { // parallel transfer for standalone job while (iterator.hasNext()) { File fileName = (File) iterator.next(); Variable_set newParams = params; newParams.set_var("ftp_file_path", fileName.getCanonicalPath()); newParams.set_var("ftp_local_dir", ""); getLogger() .info( "launching job for parallel transfer with parameter ftp_file_path: " + fileName.getCanonicalPath()); spooler.job(spooler_task.job().name()).start(params); } return signalSuccess(); } else { // parallel transfer for order job while (iterator.hasNext()) { File fileName = (File) iterator.next(); Variable_set newParams = spooler.create_variable_set(); if (spooler_task.params() != null) newParams.merge(params); newParams.set_var("ftp_file_path", fileName.getCanonicalPath()); newParams.set_var("ftp_parent_order_id", spooler_task.order().id()); newParams.set_var("ftp_order_self_destruct", "1"); Order newOrder = spooler.create_order(); newOrder.set_state(spooler_task.order().state()); newOrder.set_params(newParams); spooler.job_chain(spooler_task.order().job_chain().name()).add_order(newOrder); getLogger() .info( "launching order for parallel transfer with parameter ftp_file_path: " + fileName.getCanonicalPath()); spooler .variables() .set_var( "ftp_order", normalize(spooler_task.order().id()) + "." + normalize(newOrder.id()) + "." + "0"); spooler .variables() .set_var( "ftp_check_send_" + normalize(spooler_task.order().id()) + "." + normalize(newOrder.id()), "0"); } // am aktuellen Auftrag speichern, dass im Wiederholungsfall per setback() nicht erneut // Auftr�ge erzeugt werden // sollen, sondern dass deren Erledigungszustand gepr�ft wird: spooler_task.order().params().set_var("ftp_check_parallel", "yes"); spooler_job.set_delay_order_after_setback(1, parallelTransferCheckSetback); spooler_job.set_max_order_setbacks(parallelTransferCheckRetry); spooler_task.order().setback(); spooler .variables() .set_var( "cur_transfer_retry" + normalize(spooler_task.order().id()), String.valueOf(parallelTransferCheckRetry)); return false; } } // end Parallel Transfer // createIncludeConfigurationFile("sos/net/sosftp/Configuration.xml", // "sos.net.sosftp.Configuration.xml");// Alle Parametern // // sind hier auch // // g�ltig SOSConfiguration con = new SOSConfiguration( null, mapToProperties(schedulerParams), sosString.parseToString(schedulerParams.get(conParameterSETTINGS)), sosString.parseToString(schedulerParams.get(conParameterPROFILE)), // "sos/scheduler/ftp/SOSFTPConfiguration.xml", new // SOSSchedulerLogger(spooler_log)); null, new SOSSchedulerLogger(spooler_log)); con.checkConfigurationItems(); sos.net.sosftp.SOSFTPCommandSend ftpCommand = new sos.net.sosftp.SOSFTPCommandSend(con, new SOSSchedulerLogger(spooler_log)); ftpCommand.setSchedulerJob(this); rc = ftpCommand.transfer(); // return the number of transferred files createReturnParameter(ftpCommand); if (parallelTransfer && isFilePath && spooler_job.order_queue() != null) { spooler .variables() .set_var( "ftp_check_send_" + normalize(params.var("ftp_parent_order_id")) + "." + normalize(spooler_task.order().id()), "1"); } processResult(rc, ""); spooler_job.set_state_text(ftpCommand.getState() != null ? ftpCommand.getState() : ""); return (spooler_task.job().order_queue() == null) ? false : rc; } catch (Exception e) { rc = false; if (parallelTransfer && isFilePath && spooler_job.order_queue() != null) { spooler .variables() .set_var( "ftp_check_send_" + normalize(params.var("ftp_parent_order_id")) + "." + normalize(spooler_task.order().id()), "2"); } throw (new Exception("could not process file transfer: " + e, e)); } finally { if (parallelTransfer) { if (orderSelfDestruct) { // find positive end state for parallel orders String state = ""; sos.spooler.Job_chain_node node = spooler_task.order().job_chain_node(); while (node != null) { node = node.next_node(); if (node != null) state = node.state(); } this.getLogger().debug9("..set state for parallel order job: " + state); // find positive end state spooler_task.order().set_state(state); } } } } catch (Exception e) { processResult(false, e.toString()); spooler_job.set_state_text("ftp processing failed: " + e); spooler_log.warn("ftp processing failed: " + e); return false; } }