/********************************************************* 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*/
/*
* JobSchedulerSubmitEventMonitor.java
* Created on 19.05.2008
*
*/
package sos.scheduler.job;
import java.io.File;
import java.io.StringWriter;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import sos.scheduler.command.SOSSchedulerCommand;
import sos.spooler.Job;
import sos.spooler.Job_impl;
import sos.spooler.Log;
import sos.spooler.Spooler;
import sos.spooler.Supervisor_client;
import sos.spooler.Task;
import sos.spooler.Variable_set;
import sos.util.SOSDate;
import sos.xml.SOSXMLXPath;
public class JobSchedulerSubmitEventJob extends Job_impl {
public boolean spooler_process() throws Exception {
boolean result = true;
boolean orderJob = !(spooler_task.job().order_queue() == null);
try{
processEvent(spooler, spooler_job, spooler_task, spooler_log);
} catch(Exception e){
result = false;
spooler_log.warn("Error occured in event job: "+e);
}
if (orderJob) return result;
return false;
}
protected static void processEvent(Spooler spooler, Job spooler_job, Task spooler_task, Log spooler_log) throws Exception{
// event attributes
boolean orderJob = !(spooler_task.job().order_queue() == null);
String supervisorJobChain = "/sos/events/scheduler_event_service";
String jobChain = "";
String orderId = "";
File jobPath = new File(spooler_job.name());
String jobName = jobPath.getName();
String schedulerHost = spooler.hostname();
String schedulerTCPPort = ""+spooler.tcp_port();
String eventHandlerHost="";
int eventHandlerTCPPort=0;
String action = "add";
HashMap eventParameters = new HashMap();
String expires = "";
String expCycle = "";
String expPeriod = "";
String exitCode = ""+spooler_task.exit_code();
String eventClass = "";
String eventId = ""+spooler_task.id();
Variable_set parameters = spooler.create_variable_set();
parameters.merge(spooler_task.params());
if(orderJob){
jobChain = spooler_task.order().job_chain().name();
orderId = spooler_task.order().id();
parameters.merge(spooler_task.order().params());
eventId = orderId;
}
try{
HashSet parameterNames = new HashSet();
spooler_log.debug1("reading parameters:");
eventClass = parameters.var("scheduler_event_class");
if (eventClass==null || eventClass.length()==0){
throw new Exception("Parameter scheduler_event_class is missing.");
}
if (parameters.var("scheduler_event_action")!=null && parameters.var("scheduler_event_action").length()>0){
action=parameters.var("scheduler_event_action");
spooler_log.debug1("...parameter[scheduler_event_action]: "+action);
parameterNames.add("scheduler_event_action");
}
if (action.equalsIgnoreCase("remove")){
orderId = "";
jobChain="";
jobName="";
schedulerHost="";
schedulerTCPPort="";
exitCode="";
eventId="";
if (parameters.var("scheduler_event_job")!=null && parameters.var("scheduler_event_job").length()>0){
jobName=parameters.var("scheduler_event_job");
spooler_log.debug1("...parameter[scheduler_event_job]: "+jobName);
parameterNames.add("scheduler_event_job");
}
if (parameters.var("scheduler_event_host")!=null && parameters.var("scheduler_event_host").length()>0){
schedulerHost=parameters.var("scheduler_event_host");
spooler_log.debug1("...parameter[scheduler_event_host]: "+schedulerHost);
parameterNames.add("scheduler_event_host");
}
if (parameters.var("scheduler_event_port")!=null && parameters.var("scheduler_event_port").length()>0){
schedulerTCPPort=parameters.var("scheduler_event_port");
spooler_log.debug1("...parameter[scheduler_event_port]: "+schedulerTCPPort);
parameterNames.add("scheduler_event_port");
}
if (parameters.var("scheduler_event_exit_code")!=null && parameters.var("scheduler_event_exit_code").length()>0){
exitCode=parameters.var("scheduler_event_exit_code");
spooler_log.debug1("...parameter[scheduler_event_exit_code]: "+exitCode);
parameterNames.add("scheduler_event_exit_code");
}
}
parameterNames.add("scheduler_event_class");
spooler_log.debug1("...parameter[scheduler_event]: "+eventClass);
if (parameters.var("scheduler_event_id")!=null && parameters.var("scheduler_event_id").length()>0){
eventId=parameters.var("scheduler_event_id");
spooler_log.debug1("...parameter[scheduler_event_id]: "+eventId);
parameterNames.add("scheduler_event_id");
}
if (parameters.var("supervisor_job_chain")!=null && parameters.var("supervisor_job_chain").length()>0){
supervisorJobChain=parameters.var("supervisor_job_chain");
spooler_log.debug1("...parameter[supervisor_job_chain]: "+supervisorJobChain);
parameterNames.add("supervisor_job_chain");
}
if (parameters.var("scheduler_event_expires")!=null && parameters.var("scheduler_event_expires").length()>0){
expires=parameters.var("scheduler_event_expires");
spooler_log.debug1("...parameter[scheduler_event_expires]: "+expires);
parameterNames.add("scheduler_event_expires");
}
if (parameters.var("scheduler_event_expiration_cycle")!=null && parameters.var("scheduler_event_expiration_cycle").length()>0){
expCycle=parameters.var("scheduler_event_expiration_cycle");
spooler_log.debug1("...parameter[scheduler_event_expiration_cycle]: "+expCycle);
parameterNames.add("scheduler_event_expiration_cycle");
}
if (parameters.var("scheduler_event_expiration_period")!=null && parameters.var("scheduler_event_expiration_period").length()>0){
expPeriod=parameters.var("scheduler_event_expiration_period");
spooler_log.debug1("...parameter[scheduler_event_expiration_period]: "+expPeriod);
parameterNames.add("scheduler_event_expiration_period");
}
if (parameters.var("scheduler_event_handler_host")!=null && parameters.var("scheduler_event_handler_host").length()>0){
eventHandlerHost=parameters.var("scheduler_event_handler_host");
spooler_log.debug1("...parameter[scheduler_event_handler_host]: "+eventHandlerHost);
parameterNames.add("scheduler_event_handler_host");
}
if (parameters.var("scheduler_event_handler_port")!=null && parameters.var("scheduler_event_handler_port").length()>0){
eventHandlerTCPPort=Integer.parseInt(parameters.var("scheduler_event_handler_port"));
spooler_log.debug1("...parameter[scheduler_event_handler_port]: "+eventHandlerTCPPort);
parameterNames.add("scheduler_event_handler_port");
}
if (expires.length()==0 && (expCycle.length()>0 || expPeriod.length()>0)){
Calendar exp = JobSchedulerEventJob.calculateExpirationDate(expCycle, expPeriod);
expires = SOSDate.getTimeAsString(exp.getTime());
}
// use all other parameters as event parameters:
String[] paramNames = parameters.names().split(";");
for (int i = 0; i < paramNames.length; i++) {
String paramName = paramNames[i];
if (!parameterNames.contains(paramName)){
String paramValue = parameters.var(paramName);
spooler_log.debug1("...event parameter["+paramName+"]: "+paramValue);
eventParameters.put(paramName, paramValue);
}
}
} catch(Exception e){
throw new Exception("Error reading parameters: "+e,e);
}
try{
String addOrder = createAddOrder(eventClass, eventId, jobChain, orderId, jobName, schedulerHost, schedulerTCPPort,
action, expires, exitCode, eventParameters, supervisorJobChain);
submitToSupervisor(addOrder, spooler_log, spooler, eventHandlerHost, eventHandlerTCPPort);
} catch(Exception e){
throw new Exception("Error submitting event order: "+e,e);
}
}
private static String createAddOrder(String eventClass, String eventId,
String jobChain, String orderId, String jobName,
String schedulerHost, String schedulerTCPPort, String action,
String expires, String exitCode, Map eventParameters, String supervisorJobChain) throws Exception {
try{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document addOrderDocument = docBuilder.newDocument();
Element addOrderElement = addOrderDocument.createElement("add_order");
addOrderDocument.appendChild(addOrderElement);
addOrderElement.setAttribute("job_chain", supervisorJobChain);
Element paramsElement = addOrderDocument.createElement("params");
addOrderElement.appendChild(paramsElement);
addParam(paramsElement, "action", action);
addParam(paramsElement, "remote_scheduler_host", schedulerHost);
addParam(paramsElement, "remote_scheduler_port", ""+schedulerTCPPort);
addParam(paramsElement, "job_chain", jobChain);
addParam(paramsElement, "order_id", orderId);
addParam(paramsElement, "job_name", jobName);
addParam(paramsElement, "event_class", eventClass);
addParam(paramsElement, "event_id", eventId);
addParam(paramsElement, "exit_code", exitCode);
String now = SOSDate.getCurrentTimeAsString();
addParam(paramsElement, "created", now);
addParam(paramsElement, "expires", expires);
Iterator keyIterator = eventParameters.keySet().iterator();
while (keyIterator.hasNext()){
String name = keyIterator.next().toString();
String value = eventParameters.get(name).toString();
addParam(paramsElement, name, value);
}
StringWriter out = new StringWriter();
OutputFormat of = new OutputFormat(addOrderDocument);
of.setEncoding("iso-8859-1");
XMLSerializer serializer = new XMLSerializer(out, of);
serializer.serialize(addOrderDocument);
return out.toString();
} catch (Exception e) {
throw new Exception("Error creating add_order xml: "+e,e);
}
}
private static void addParam(Element paramsElement, String name, String value) {
if (value!=null && value.length()>0){
Element paramElement = paramsElement.getOwnerDocument().createElement("param");
paramElement.setAttribute("name", name);
paramElement.setAttribute("value", value);
paramsElement.appendChild(paramElement);
}
}
private static void submitToSupervisor(String xml, Log spooler_log, Spooler spooler, String host, int port) throws Exception{
try{
if ( xml.indexOf("<?xml") == -1 ) {
xml = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>" + xml;
}
spooler_log.debug7("Sending xml:\n"+xml);
Supervisor_client supervisor=null;
try{
supervisor=spooler.supervisor_client();
} catch(Exception e){} // there is no supervisor
String answer;
if (host.length()>0 && port!=0){
SOSSchedulerCommand schedulerCommand = new SOSSchedulerCommand();
schedulerCommand.setHost(host);
schedulerCommand.setPort(port);
schedulerCommand.setProtocol("tcp");
spooler_log.debug1(".. connecting to Job Scheduler " + schedulerCommand.getHost() + ":" + schedulerCommand.getPort());
schedulerCommand.connect();
schedulerCommand.sendRequest(xml);
answer = schedulerCommand.getResponse();
} else if (supervisor!=null && supervisor.hostname()!=null && supervisor.hostname().length()>0){
SOSSchedulerCommand schedulerCommand = new SOSSchedulerCommand();
schedulerCommand.setHost(supervisor.hostname());
schedulerCommand.setPort(supervisor.tcp_port());
schedulerCommand.setProtocol("tcp");
spooler_log.debug1(".. connecting to Job Scheduler " + schedulerCommand.getHost() + ":" + schedulerCommand.getPort());
schedulerCommand.connect();
schedulerCommand.sendRequest(xml);
answer = schedulerCommand.getResponse();
}else{
spooler_log.info("No supervisor configured, submitting event to this Job Scheduler.");
answer = spooler.execute_xml(xml);
}
SOSXMLXPath xAnswer = new SOSXMLXPath(new StringBuffer(answer));
String errorText = xAnswer.selectSingleNodeValue("//ERROR/@text");
if (errorText != null && errorText.length() > 0) {
throw new Exception("supervisor returned error: " + errorText );
}
} catch(Exception e){
throw new Exception("Failed to submit event: "+e,e);
}
}
}