/********************************************************* begin of preamble
**
** Copyright (C) 2003-2010 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.File;
import sos.hostware.Record;
import sos.scheduler.command.SOSSchedulerCommand;
import sos.spooler.Supervisor_client;
import sos.spooler.Variable_set;
import sos.xml.SOSXMLXPath;
/**
* Forward events to the Supervisor Job Scheduler instance
* should events not have previously been sent but stored
* in a temporary file (./logs/scheduler.events)
*
* @author andreas.pueschel@sos-berlin.com
* @since 1.0 2008-05-07
*/
public class JobSchedulerDequeueEventsJob extends JobSchedulerJob {
/** path and name of the event file */
private String eventFilename = "";
/** file type prefix for event file */
private String eventFilenamePrefix = "";
/** event action */
private String eventAction = "";
/** Supervisor Job Scheduler host */
private String eventSupervisorSchedulerHost = "";
/** Supervisor Job Scheduler port */
private int eventSupervisorSchedulerPort = 0;
/** Supervisor Job Scheduler connection timeout */
private int eventSupervisorSchedulerTimeout = 0;
/** name of event processing job chain in Supervisor Job Scheduler */
private String eventSupervisorSchedulerJobChainName = "";
/** Job and Order parameters */
private Variable_set parameters = null;
/**
* process single mail order
*/
public boolean spooler_process() {
boolean rc = true;
int eventCount = 0;
int eventMinFieldCount = 10;
int eventMaxFieldCount = 11;
File eventFile = null;
try {
this.setParameters(spooler.create_variable_set());
Supervisor_client supervisor = spooler.supervisor_client();
try {
if (spooler_task.params() != null) this.getParameters().merge(spooler_task.params());
if (spooler_job.order_queue() != null) this.getParameters().merge(spooler_task.order().params());
if (this.getParameters().value("event_file") != null && this.getParameters().value("event_file").length() > 0) {
this.setEventFilename(this.getParameters().value("event_file"));
spooler_log.debug1(".. parameter [event_file]: " + this.getEventFilename());
} else {
this.setEventFilename(spooler.log_dir() + "/scheduler.events");
}
if (this.getParameters().value("event_file_prefix") != null && this.getParameters().value("event_file_prefix").length() > 0) {
this.setEventFilenamePrefix(this.getParameters().value("input_file_prefix"));
spooler_log.debug1(".. parameter [event_file_prefix]: " + this.getEventFilenamePrefix());
} else {
this.setEventFilenamePrefix("-in tab -csv | ");
}
if (this.getParameters().value("supervisor_host") != null && this.getParameters().value("supervisor_host").length() > 0) {
this.setEventSupervisorSchedulerHost(this.getParameters().value("supervisor_host"));
spooler_log.debug1(".. parameter [supervisor_host]: " + this.getEventSupervisorSchedulerHost());
} else {
if (supervisor.hostname() != null && supervisor.hostname().length() > 0) {
this.setEventSupervisorSchedulerHost(supervisor.hostname());
} else {
this.setEventSupervisorSchedulerHost(spooler.hostname());
}
}
if (this.getParameters().value("supervisor_port") != null && this.getParameters().value("supervisor_port").length() > 0) {
try {
this.setEventSupervisorSchedulerPort(Integer.parseInt(this.getParameters().value("supervisor_port")));
spooler_log.debug1(".. parameter [supervisor_port]: " + this.getEventSupervisorSchedulerPort());
} catch (Exception ex) {
throw new Exception("illegal non-numeric value for Supervisor Job Scheduler port specified: " + this.getParameters().value("supervisor_port"));
}
} else {
if (supervisor.hostname() != null && supervisor.hostname().length() > 0) {
this.setEventSupervisorSchedulerPort(supervisor.tcp_port());
} else {
this.setEventSupervisorSchedulerPort(spooler.tcp_port());
}
}
if (this.getParameters().value("supervisor_timeout") != null && this.getParameters().value("supervisor_timeout").length() > 0) {
try {
this.setEventSupervisorSchedulerTimeout(Integer.parseInt(this.getParameters().value("supervisor_timeout")));
spooler_log.debug1(".. parameter [supervisor_timeout]: " + this.getEventSupervisorSchedulerTimeout());
} catch (Exception ex) {
throw new Exception("illegal non-numeric value for Supervisor Job Scheduler timeout specified: " + this.getParameters().value("supervisor_timeout"));
}
} else {
this.setEventSupervisorSchedulerTimeout(15);
}
if (this.getParameters().value("supervisor_job_chain") != null && this.getParameters().value("supervisor_job_chain").length() > 0) {
this.setEventSupervisorSchedulerJobChainName(this.getParameters().value("supervisor_job_chain"));
spooler_log.debug1(".. parameter [supervisor_job_chain]: " + this.getEventSupervisorSchedulerJobChainName());
} else {
this.setEventSupervisorSchedulerJobChainName("/sos/events/scheduler_event_service");
}
} catch (Exception e) {
throw new Exception("error occurred processing parameters: " + e.getMessage());
}
try {
eventFile = new File(this.getEventFilename());
if (!eventFile.exists()) {
this.getLogger().info("event file does not exist: " + eventFile.getCanonicalPath());
} else if (!eventFile.canWrite()) {
throw new Exception("required write permission for event file is missing: " + eventFile.getCanonicalPath());
}
File eventFileCopy = new File(this.getEventFilename() + "~");
if (!eventFileCopy.exists()) {
if (!eventFile.renameTo(eventFileCopy)) throw new Exception("could not create working copy of event file: renaming " + eventFile.getCanonicalPath() + " to " + eventFileCopy.getCanonicalPath());
} else {
spooler_log.info("working copy of event file found - starting to process this file: " + eventFileCopy.getCanonicalPath());
if (!eventFileCopy.canWrite()) throw new Exception("required write permission for event file working copy is missing: " + eventFileCopy.getCanonicalPath());
}
sos.hostware.File hwFile = new sos.hostware.File();
if (eventFileCopy.getName().startsWith("-")) {
hwFile.open( eventFileCopy.getCanonicalPath());
} else {
hwFile.open( this.getEventFilenamePrefix() + " " + eventFileCopy.getAbsolutePath());
}
SOSSchedulerCommand schedulerCommand = new SOSSchedulerCommand();
schedulerCommand.setHost(this.getEventSupervisorSchedulerHost());
schedulerCommand.setPort(this.getEventSupervisorSchedulerPort());
schedulerCommand.setTimeout(this.getEventSupervisorSchedulerTimeout());
schedulerCommand.connect();
while (!hwFile.eof())
{
Record record = hwFile.get();
spooler_log.info("--->" + record);
if (record.field_count() < 10) throw new Exception("number of fields in event file [" + eventFile.getCanonicalPath() + "] is too small: " + record.field_count());
eventCount++;
spooler_log.info("... will be processed");
spooler_log.info(record.string(0) + " event");
String command = "<add_order title=\"dequeued event\" job_chain=\"" + this.getEventSupervisorSchedulerJobChainName() + "\">";
command += "<params>";
command += "<param name=\"action\" value=\"" + getValue(record.string(0)) + "\"/>";
command += "<param name=\"scheduler_host\" value=\"" + getValue(record.string(1)) + "\"/>";
command += "<param name=\"scheduler_port\" value=\"" + getValue(record.string(2)) + "\"/>";
command += "<param name=\"job_chain\" value=\"" + getValue(record.string(3)) + "\"/>";
command += "<param name=\"order_id\" value=\"" + getValue(record.string(4)) + "\"/>";
command += "<param name=\"job_name\" value=\"" + getValue(record.string(5)) + "\"/>";
command += "<param name=\"event_class\" value=\"" + getValue(record.string(6)) + "\"/>";
command += "<param name=\"event_id\" value=\"" + getValue(record.string(7)) + "\"/>";
command += "<param name=\"exit_code\" value=\"" + getValue(record.string(8)) + "\"/>";
command += "<param name=\"created\" value=\"" + getValue(record.string(9)) + "\"/>";
int expiration_column = 1;
if (record.field_count() > eventMinFieldCount) {
spooler_log.info("--->" + record.string(10) + " " + record.string(10).indexOf(""));
if (record.string(10).indexOf("=") == -1) {// Kompatibilit�tsabfrage
if (record.string(10) != null && record.string(10).length() > 0)
command += "<param name=\"expires\" value=\"" + record.string(10) + "\"/>";
expiration_column = 0;
}
}
for(int i=eventMaxFieldCount-expiration_column; i<record.field_count(); i++) {
int posFound = record.string(i).indexOf("=");
if (posFound != -1) {
command += "<param name=\"" + record.string(i).substring(0, posFound) + "\" value=\"" + record.string(i).substring(posFound+1) + "\"/>";
}
}
command += "</params></add_order>";
this.getLogger().info(".. sending command to remote Job Scheduler [" + this.getEventSupervisorSchedulerHost() + ":" + this.getEventSupervisorSchedulerPort() + "]: " + command );
schedulerCommand.sendRequest(command);
SOSXMLXPath answer = new SOSXMLXPath(new StringBuffer(schedulerCommand.getResponse()));
String errorText = answer.selectSingleNodeValue("//ERROR/@text");
if (errorText != null && errorText.length() > 0) {
throw new Exception("could not send command to Supervisor Job Scheduler [" + this.getEventSupervisorSchedulerHost() + ":" + this.getEventSupervisorSchedulerPort() + "]: " + errorText );
}
}
schedulerCommand.disconnect();
hwFile.close();
if (!eventFileCopy.delete()) {
this.getLogger().info("could not delete temporary working copy of event file, re-trying later");
eventFileCopy.deleteOnExit();
}
} catch (Exception e) {
throw new Exception("error occurred forwarding events to Supervisor Job Scheduler [" + this.getEventSupervisorSchedulerHost() + ":" + this.getEventSupervisorSchedulerPort() + "]: " + e.getMessage());
}
if (eventCount > 0) {
this.getLogger().info(eventCount + " events dequeued to Supervisor Job Scheduler [" + this.getEventSupervisorSchedulerHost() + ":" + this.getEventSupervisorSchedulerPort() + "] from event file: " + eventFile.getCanonicalPath());
}
return ((spooler_job.order_queue() != null) ? rc : false);
} catch (Exception e) {
spooler_log.warn("error occurred dequeueing events: " + e.getMessage());
return false;
}
}
private String getValue(String s) {
if (s == null || s.equals("null")) {
return "";
}else {
return s;
}
}
/**
* @return the parameters
*/
public Variable_set getParameters() {
return parameters;
}
/**
* @param parameters the parameters to set
*/
public void setParameters(Variable_set parameters) {
this.parameters = parameters;
}
/**
* @return the eventFilename
*/
public String getEventFilename() {
return eventFilename;
}
/**
* @param eventFilename the eventFilename to set
*/
public void setEventFilename(String eventFilename) {
this.eventFilename = eventFilename;
}
/**
* @return the eventSupervisorSchedulerHost
*/
public String getEventSupervisorSchedulerHost() {
return eventSupervisorSchedulerHost;
}
/**
* @param eventSupervisorSchedulerHost the eventSupervisorSchedulerHost to set
*/
public void setEventSupervisorSchedulerHost(String eventSupervisorSchedulerHost) {
this.eventSupervisorSchedulerHost = eventSupervisorSchedulerHost;
}
/**
* @return the eventSupervisorSchedulerPort
*/
public int getEventSupervisorSchedulerPort() {
return eventSupervisorSchedulerPort;
}
/**
* @param eventSupervisorSchedulerPort the eventSupervisorSchedulerPort to set
*/
public void setEventSupervisorSchedulerPort(int eventSupervisorSchedulerPort) {
this.eventSupervisorSchedulerPort = eventSupervisorSchedulerPort;
}
/**
* @return the eventFilenamePrefix
*/
public String getEventFilenamePrefix() {
return eventFilenamePrefix;
}
/**
* @param eventFilenamePrefix the eventFilenamePrefix to set
*/
public void setEventFilenamePrefix(String eventFilenamePrefix) {
this.eventFilenamePrefix = eventFilenamePrefix;
}
/**
* @return the eventSupervisorSchedulerJobChainName
*/
public String getEventSupervisorSchedulerJobChainName() {
return eventSupervisorSchedulerJobChainName;
}
/**
* @param eventSupervisorSchedulerJobChainName the eventSupervisorSchedulerJobChainName to set
*/
public void setEventSupervisorSchedulerJobChainName(String eventSupervisorSchedulerJobChainName) {
this.eventSupervisorSchedulerJobChainName = eventSupervisorSchedulerJobChainName;
}
/**
* @return the eventAction
*/
public String getEventAction() {
return eventAction;
}
/**
* @param eventAction the eventAction to set
*/
public void setEventAction(String eventAction) {
this.eventAction = eventAction;
}
/**
* @return the eventSupervisorSchedulerTimeout
*/
public int getEventSupervisorSchedulerTimeout() {
return eventSupervisorSchedulerTimeout;
}
/**
* @param eventSupervisorSchedulerTimeout the eventSupervisorSchedulerTimeout to set
*/
public void setEventSupervisorSchedulerTimeout(int eventSupervisorSchedulerTimeout) {
this.eventSupervisorSchedulerTimeout = eventSupervisorSchedulerTimeout;
}
}