Package sos.scheduler.managed

Source Code of sos.scheduler.managed.JobSchedulerManagedStarter

/********************************************************* 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.managed;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;


import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;

import org.w3c.dom.*;
import org.xml.sax.InputSource;

import sos.connection.SOSConnection;
import sos.connection.SOSOracleConnection;
import sos.scheduler.command.SOSSchedulerCommand;
import sos.scheduler.job.JobSchedulerJob;
import sos.settings.SOSProfileSettings;
import sos.spooler.*;
import sos.util.SOSClassUtil;
import sos.util.SOSDate;
import sos.util.SOSFile;
import sos.util.SOSLogger;
import sos.util.SOSSchedulerLogger;
import sos.util.SOSStandardLogger;
import sos.xml.SOSXMLXPath;


/**
* This class submits Managed (v2) Job Scheduler configurations from
* the database to the Job Scheduler.<br/>
* It needs to be run as a startscript.
* @version 2.0
* @author Andreas Liebert
* @since 2007-04-13
*/
public class JobSchedulerManagedStarter extends JobSchedulerJob {
 
   
  /** is the job running as a startscript? */
    private boolean startscript = true;
   
    /** id of this Scheduler */
    private String schedulerID="";
    Variable_set orderParams = null;
    private boolean once=false;
    private boolean remove=false;
   
    private static Pattern xmlEncodingPattern = Pattern.compile("\\<\\?xml.*encoding=\"(.*)\".*\\?\\>");
   
    private boolean useLiveFolder = false;
   
    private File liveFolder;
   
    private Transformer managed2liveTransformer;
   
    private final static String indicatorRegex = "(.*\\.xml)\\s([a-f0-9]+)\\s(\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}(\\.\\d)?)$";
   
    private Pattern indicatorRegexPattern;
   
   
    private final String  getWhat(String type) {
      String what="unknown type:" + type;
      if (type.equalsIgnoreCase("o"))
         what = "order";
       if (type.equalsIgnoreCase("j"))
         what = "orderjob";
       if (type.equalsIgnoreCase("i"))
         what = "job";
       if (type.equalsIgnoreCase("f"))
         what = "job.global";
       if (type.equalsIgnoreCase("l"))
        what = "lock";
       if ( type.equalsIgnoreCase("c"))
         what = "job_chain";
       if ( type.equalsIgnoreCase("p"))
         what = "process_class";
       if ( type.equalsIgnoreCase("k"))
         what = "documentation";
       return what;
    }
   
    private final String  getType(String what) {
      String type="unknown what:" + what;
     
      if (what.equalsIgnoreCase("order"))
         type = "o";
       if (what.equalsIgnoreCase("orderjob"))
         type = "j";
       if (what.equalsIgnoreCase("job"))
         type = "i";
       if (what.equalsIgnoreCase("job.global"))
         type = "f";
       if (what.equalsIgnoreCase("lock"))
         type = "l";
       if ( what.equalsIgnoreCase("job_chain"))
         type = "c";
       if ( what.equalsIgnoreCase("process_class"))
         type = "p";
     if ( what.equalsIgnoreCase("documentation"))
         type = "k";
       return type;
    }   
   
    private final String  getDirectory(String what) {
      String dir="unknown what:" + what;
           
     if ( what.equalsIgnoreCase("documentation"))
         dir = "jobs/";
       return dir;
    }
  
  
  /**
     * Spooler init is called for startscripts on Job Scheduler startup
     */
    public boolean spooler_init() {
      boolean rc = super.spooler_init();
      liveFolder = new File(spooler.configuration_directory());
      useLiveFolder = false;
      indicatorRegexPattern = Pattern.compile(indicatorRegex);
     
      startscript = spooler_job==null;
      schedulerID = spooler.id().toLowerCase();
      if (!rc) return false || startscript;     
     
      if (startscript)
      try {
        setLogger(new SOSSchedulerLogger(spooler.log()));
        getLog().info("SchedulerManagedStarter is running as startscript");
        spooler.set_var("scheduler_managed_jobs_version","2");
      } catch (Exception e2) {}
    else
      try {
        setLogger(new SOSSchedulerLogger(spooler_log));
        getLog().info("SchedulerManagedStarter is running as job");
      } catch (Exception e3) {}
     
    if (useLiveFolder){
      try{
        String key = "javax.xml.transform.TransformerFactory";
        String value = "org.apache.xalan.xsltc.trax.TransformerFactoryImpl";
        Properties props = System.getProperties();
        props.put(key, value);
        System.setProperties(props);
        TransformerFactory tFactory = TransformerFactory.newInstance();
        tFactory.setAttribute("translet-name", "managed2live");
        tFactory.setAttribute("package-name", "sos.scheduler.translet");
        tFactory.setAttribute("use-classpath", Boolean.TRUE);
        managed2liveTransformer = tFactory.newTransformer(new StreamSource("managed2live.xsl"));       
      } catch (Exception e){
        spooler_log.error("Failed to initialize translet: "+e);
        if (this.getConnection() !=  null) {
          try { this.getConnection().rollback(); } catch (Exception ex) {} // no error handling
          try { this.getConnection().disconnect(); } catch (Exception ex) {} // no error handling
          // this.setConnection(null);
        }
        return false;
      }
    }
    if (startscript){
      try {
        if (useLiveFolder){
          initializeManagedLiveFolders();
        }
        // initialize locks, jobs, job chains and orders
        initializeWhat("job.global");
          initializeWhat("lock");
          initializeWhat("process_class");
          initializeWhat("documentation");
          initializeWhat("orderjob");
          initializeWhat("job");
          initializeWhat("job_chain");
          initializeWhat("order");
         

        return true;
      }
      catch (Exception e) {
        try {
          getLog().error("error occurred in initialization: " + e.getMessage());
        } catch (Exception e1) {}
       
        return false || startscript;
      }
      finally {
        if (this.getConnection() !=  null) {
          try { this.getConnection().rollback(); } catch (Exception ex) {} // no error handling
          try { this.getConnection().disconnect(); } catch (Exception ex) {} // no error handling
          // this.setConnection(null);
        }
      }
    }
    return true;
    }
   
   
    private void initializeManagedLiveFolders() throws Exception {
    try{
      Vector folderList = SOSFile.getFolderlist(liveFolder.getAbsolutePath(), ".*", 0, true);
      Iterator folderIterator = folderList.iterator();
      while (folderIterator.hasNext()){
        File currentDir = (File) folderIterator.next();
        if (!currentDir.isDirectory()) continue;
        File managedIndicator = new File(currentDir, ".managed");
        if (!managedIndicator.exists()){
          getLog().debug3("Skipping "+currentDir.getAbsolutePath()+
              " . This is not a managed directory.");
          continue;
        }
        initializeManagedLiveFolder(currentDir);
      }
    } catch (Exception e){
      throw new Exception ("Error initializing managed live folders: "+e);
    }
  }

  private void initializeManagedLiveFolder(File currentDir) throws Exception {
    try{
      getLog().debug2("Processing managed live folder: "+currentDir.getAbsolutePath());
      Vector xmlFileList = SOSFile.getFilelist(currentDir.getAbsolutePath(), ".*\\.(job|order|job_chain|process_class|lock)\\.xml$", 0);
      Iterator fileIterator = xmlFileList.iterator();
      while (fileIterator.hasNext()){
        File currentFile = (File) fileIterator.next();
        if (currentFile.isDirectory()) continue;
        getLog().debug3("Deleting managed file "+currentFile.getAbsolutePath());
        if (!currentFile.delete()){
          throw new Exception("Failed to delete file "+currentFile.getAbsolutePath());
        }
      }
    } catch (Exception e){
      throw new Exception("Error initializing "+currentDir.getAbsolutePath()+
          ": "+e,e);
    }   
  }

  private void handleOnce(String what, String name, String path,String xml, String answer) throws Exception {
    if (path.length()>0) name= path+"/"+name;
      if (orderParams != null)
        once = orderParams.var("once") != null && orderParams.var("once").equalsIgnoreCase("yes");

        if(oncegetLog().debug3("once: " + what + " will be started");
        else      getLog().debug3("NOT once: " + what + " will NOT be started");
        
      if(once){
        //Wenn ein Repeat-Intervall angegeben ist, nicht starten.
        //Repeat f�r bestimmte Tage werden nicht ausgewertet.
       
        SOSXMLXPath xpath = new SOSXMLXPath(new StringBuffer(xml));
        SOSXMLXPath xpath_answer = new SOSXMLXPath(new StringBuffer(answer));
   
         
          boolean start = true;
          String nodeQuery = "//add_order[@at]";
          Node runtime;
          if (what.equals("order")){
           
            Node atNode = xpath.selectSingleNode(nodeQuery);
            nodeQuery = "//run_time";
            runtime = xpath.selectSingleNode(nodeQuery);
           
            if(atNode == null && runtime == null){
              start = false;
              getLog().debug1("handleOnce:" + name + " Once=yes. Order will not be modified because 'no at and no runtime' is given in <add_order>");
            }
           
          }
         
          nodeQuery = "//run_time[@repeat]";
          runtime = xpath.selectSingleNode(nodeQuery);
          if(runtime != null){
              start = false;
              getLog().debug1("handleOnce:" + name + " Once=yes. "+what+" will not be modified because 'repeat' is given in <runtime>");
          }
         
         
          nodeQuery = "//run_time/period[@repeat]";
          runtime = xpath.selectSingleNode(nodeQuery);
          if(runtime != null && start){
              start = false;
              getLog().debug1("handleOnce:" + name + " Once=yes. "+what+" will not be startet because 'repeat' is given in <runtime>");
          }
          if(start){
              String command = "";
              if (what.equals("order")){
                String job_chain = xpath.selectSingleNodeValue("//add_order/@job_chain");
                String id = xpath_answer.selectSingleNodeValue("//spooler/answer/ok/order/@id");
                 
                command = "<modify_order at=\"now\" job_chain=\"" + job_chain + "\"  order=\"" + id + "\"/>";
               
              }
              if (what.equals("job")){
                command = "<start_job job=\"" + name + "\" at=\"now\"/>";
              }

              getLog().debug3(command);
              if(useLiveFolder){
                // load changes from files first
                execute_xml("<check_folders/>");
              }
              execute_xml(command);
              getLog().debug1("handleOnce:  " + what + " " + name + " was startet");
          }     
      }
    }
  
   
    private void handleJobInit(String name, String xml)throws Exception {
      // Job ist evtl. in vorigem Job-Lauf angelegt worden
      try {
      if(!useLiveFolder && spooler.job(name) != null){
         getLog().debug1("handleJobInit:Job " + name + " will be removed");
         execute_xml("<modify_job job=\"" + name + "\" cmd=\"remove\"/>");
       }
       } catch (Exception e) {} // gracefully ignore this error
    }

    private void handleJobClose(String name, String path, String xml, String answer) throws Exception {
      handleOnce("job",name, path, xml, answer)
    }

 
    private void addParam(Document params, Element p, String name, String value) {
        Element param = params.createElement("param");
        param.setAttribute("name", name);
        param.setAttribute("value", value);
        p.appendChild(param);
    }

    private void handleProcessClassInit(String name, String xml) throws Exception {
      String removeProcessClass = "<process_class.remove   process_class    = \"" + name + "\"/>";
       try {
        execute_xml(removeProcessClass);
      } catch (Exception e) {}      
    }
   
    private String handleOrderInit(String name, String xml) throws Exception {
        getLog().debug3("handleOrderInit(" + name + ")");
       
      
       
        String scheduler_order_id = "";
        String scheduler_order_title = "";
        String scheduler_order_job_chain = "";
        String scheduler_order_state = "";
       
        SOSXMLXPath xpath = new SOSXMLXPath(new StringBuffer(xml));
        NamedNodeMap nodeMapSettings = null;
        String nodeQuery = "//add_order";
        Node add_order = xpath.selectSingleNode(nodeQuery);
      
        if (add_order != null){

           nodeMapSettings = add_order.getAttributes();
          
            if(nodeMapSettings != null && nodeMapSettings.getNamedItem("title") != null)
                scheduler_order_title = nodeMapSettings.getNamedItem("title").getNodeValue();
            if(nodeMapSettings != null && nodeMapSettings.getNamedItem("job_chain") != null)
                scheduler_order_job_chain = nodeMapSettings.getNamedItem("job_chain").getNodeValue();
            if(nodeMapSettings != null && nodeMapSettings.getNamedItem("state") != null)
                scheduler_order_state = nodeMapSettings.getNamedItem("state").getNodeValue();
        }

        getLogger().debug3("add_order: title=" + scheduler_order_title);
        getLogger().debug3("add_order: job_chain=" + scheduler_order_job_chain);
        getLogger().debug3("add_order: state=" + scheduler_order_state);

       
        if (remove){
          String removeOrder = "<remove_order  job_chain    = \"" + scheduler_order_job_chain + "\" order = \"" + name + "\"/>" ;
          try {
            execute_xml(removeOrder);
          } catch (Exception e) {}
        }       
       
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        ByteArrayInputStream bai = new ByteArrayInputStream(xml.getBytes("UTF-8"));
        InputSource source = new InputSource(bai);
       
        Document xmlDoc = docBuilder.parse(source);
        Element p = null;
        NodeList params = xmlDoc.getElementsByTagName("params");
       
        if(params == null || params.item(0) == null) {
            p = xmlDoc.createElement("params");
            NodeList r = xmlDoc.getElementsByTagName("run_time");
            NodeList addOrder = xmlDoc.getElementsByTagName("add_order");
            if (addOrder != null) {
               addOrder.item(0).insertBefore(p, r.item(0));
            }
        } else {
            p = (Element)params.item(0);
        }
       
       
        addParam(xmlDoc, p, "scheduler_order_id", scheduler_order_id);
        addParam(xmlDoc, p, "scheduler_order_title", scheduler_order_title);
        addParam(xmlDoc, p, "scheduler_order_job_chain", scheduler_order_job_chain);
        addParam(xmlDoc, p, "scheduler_order_state", scheduler_order_state);
       
        boolean ignore_runtime = false;
        if (orderParams != null)
           ignore_runtime = orderParams.var("ignore_runtime") != null && orderParams.var("ignore_runtime").equalsIgnoreCase("yes");
      

          if (ignore_runtime)  {
            getLog().debug3("ignore_runtime: yes");
            NodeList r = xmlDoc.getElementsByTagName("run_time");           
            if (r!=null && r.item(0)!=null && r.item(0).getParentNode()!=null){
              Element e = (Elementr.item(0).getParentNode();             
              e.removeAttribute("id");    
              e.removeAttribute("at");
              r.item(0).getParentNode().removeChild(r.item(0));             
            }
         

          }
          else  getLog().debug3("ignore_runtime: No");
      
         
         
        StringWriter out = new StringWriter();
        XMLSerializer serializer = new XMLSerializer(out, new OutputFormat(xmlDoc));
        serializer.serialize(xmlDoc);
        getLog().info("adding order [" + scheduler_order_id + "] to job chain [" + scheduler_order_job_chain + "]: ");
        getLog().debug3(out.toString());

        return  out.toString();
    }


    private void handleOrderClose(String name, String path, String xml, String answer) throws Exception {
      handleOnce("order",name, path,xml, answer)
    }
   
    private void handleJobchainClose(String name, String path, String xml) throws Exception {
      if (path.length()>0) name= path+"/"+name;
      if (!useLiveFolder){
        boolean exist = spooler.job_chain_exists(name);
     
        if(!exist){
          throw new Exception("Job_chain "+name+" could not be created");
        }
      }
    } 
   
    private void handleJobchainInit(String name, String xml) throws Exception {
    boolean exist = spooler.job_chain_exists(name);
     
    getLog().debug3("looking for Job_chain " + name);
    if(exist && !useLiveFolder){
        Job_chain j = spooler.job_chain(name);
        j.remove();
        getLog().debug3("Job_chain " + name + " was deleted for replacement");
      }
    }

    private String handleInit(String xml, String what, String name) throws Exception {
       getLog().debug3("handleInit(" + what + "," + name + ")");
     
       if (orderParams != null)
       remove = orderParams.var("remove") != null && orderParams.var("remove").equalsIgnoreCase("yes");
     
      //if(what.equals("job"))
        //    handleJobInit(name, xml);
      if(what.equals("order"))
           xml = handleOrderInit(name, xml);
      if(what.equals("job_chain"))
           handleJobchainInit(name, xml);
      if(what.equals("process_class"))
           handleProcessClassInit(name, xml);
      return xml;
    }

    private void handleClose(String xml, String answer, String what, String name, String path) throws Exception {
        if(what.equals("job"))
            handleJobClose(name, path, xml, answer);
        if(what.equals("order"))
          handleOrderClose(name, path, xml, answer);
        if(what.equals("job_chain"))
          handleJobchainClose(name, path, xml);
    }

    private void initializeWhat(String what) throws Exception {
   
        String type = getType(what);
        try {
          getLog().info("initializing " + what + "s...");
          String query = "SELECT ";
          query += " o.\"NAME\", o.\"ID\", t.\"MODIFIED\" ";
          if (useLiveFolder) query += ", t.\"PATH\"";
         
          if(!(getConnection() instanceof SOSOracleConnection)){
            query += " FROM " + JobSchedulerManagedObject.tableManagedObjects +" o LEFT OUTER JOIN "
                  + " "+JobSchedulerManagedObject.tableManagedTree+" t ON o.\"ID\"=t.\"ITEM_ID\""
              + " WHERE (t.\"LINK_ID\"=0 OR t.\"LINK_ID\" IS NULL)";
          }else{
            query += " FROM " + JobSchedulerManagedObject.tableManagedObjects +" o,"
            + " "+JobSchedulerManagedObject.tableManagedTree+" t"
            + " WHERE o.\"ID\"=t.\"ITEM_ID\"(+) AND t.\"LINK_ID\"(+)=0";
          }

          query+= " AND o.\"SUSPENDED\"=0 AND o.\"TYPE\"='" + type + "' AND " + "(\"SPOOLER_ID\"='"
        + schedulerID + "' OR \"SPOOLER_ID\" IS NULL)";
         
          ArrayList results = getConnection().getArray(query);
          Iterator iter = results.iterator();
          while (iter != null && iter.hasNext()) {
            HashMap result = (HashMap) iter.next();
            String name = null;
            if (result.get("name") != null) {

                String blob_query = "SELECT \"XML\"";
                 blob_query += " FROM " + JobSchedulerManagedObject.tableManagedObjects
                  + " WHERE \"ID\" = " + result.get("id").toString();
             
                 String xml = getConnection().getClob(blob_query);
             
             
                 name = result.get("name").toString();
                 String modified = result.get("modified").toString();
                 String path = "";
                 if (useLiveFolder){
                   path = result.get("path").toString();
                   path = path.substring(0, path.lastIndexOf("/"));
                 }
                 getLog().debug1("Initializing " + what + " \"" + name + "\"");
                 try{
                 submitXml(xml, what, name, modified, path);
                 } catch (Exception e){
                   getLog().warn("Error occurred initializing " + what + " \"" + name + "\": "+e);
                 }
            }else {
              getLog().warn("NAME is null");
            }
          }
        } catch (Exception e) {
          throw new Exception("Error occured initializing " + what + ": " + e);
        }
      } 

  private void remove(String type, String name){
    if (type.equalsIgnoreCase("f")){
      removeSection(name);
    }
    if (type.equalsIgnoreCase("k")){
      removeSchedulerFile(name, getWhat(type));
    }
  }
 
 

private void initialize(String id) throws Exception {
    String what = "managed object";
    try {
      String query = "SELECT o.\"REFERENCE\", o.\"TYPE\", o.\"NAME\", t.\"MODIFIED\"";
      if (useLiveFolder) query += ", t.\"PATH\"";
      String blob_query = "SELECT \"XML\"";
     
      /*String name = "managedChain2";
      String reference = "44";
      String type = "j";
      */
      if(!(getConnection() instanceof SOSOracleConnection)){
        query += " FROM " + JobSchedulerManagedObject.tableManagedObjects +" o LEFT OUTER JOIN "
              + " "+JobSchedulerManagedObject.tableManagedTree+" t ON o.\"ID\"=t.\"ITEM_ID\""
          + " WHERE (t.\"LINK_ID\"=0 OR t.\"LINK_ID\" IS NULL)";
      }else{
        query += " FROM " + JobSchedulerManagedObject.tableManagedObjects +" o,"
        + " "+JobSchedulerManagedObject.tableManagedTree+" t"
        + " WHERE o.\"ID\"=t.\"ITEM_ID\"(+) AND t.\"LINK_ID\"(+)=0";
      }

      query+= " AND o.\"ID\"=" + id ;
     
           
      blob_query += " FROM " + JobSchedulerManagedObject.tableManagedObjects + " o "
      + "WHERE o.\"ID\"=" + id;

        ArrayList results = getConnection().getArray(query);
       Iterator iter = results.iterator();
      
       if (!iter.hasNext()) {
         throw new Exception("no configuration found with id=" + id);
       } else{
        
         String xml = getConnection().getClob(blob_query);

         HashMap result = (HashMap) iter.next();
         String name = result.get("name").toString();
         String type = result.get("type").toString();
         String modified = result.get("modified").toString();
         String path = "";
         if (useLiveFolder){
           path = result.get("path").toString();
           path = path.substring(0, path.lastIndexOf("/"));
         }
  
    
             
         what = getWhat(type);

         getLog().debug1("Initializing " + what + " \"" + name + "\"");

      // String xml = "<add_order id=\"myOrder\" job_chain=\"jobchain\"
      // title=\"Test fuer Managed Starter\" state=\"100\"> <run_time
      // let_run=\"no\"/></add_order>";
      // String xml = "<job_chain name=\"managedChain2\"
      // orders_recoverable=\"yes\" visible=\"yes\"> <job_chain_node
      // state=\"100\" job=\"job100\" next_state=\"200\"/> <job_chain_node
      // state=\"200\"/></job_chain>";
     
      //String xml = "<email_settings  to=\"re@sos-berlin.com\"  cc=\"oh@sos-berlin.com\"  bcc=\"ur@sos-berlin.com\"></email_settings>";

//      String xml = "<job name=\"job100\" order=\"yes\" title=\"Shellscript auf 8of9 ausfuehren\"> <script language=\"javascript\"> <![CDATA[ function spooler_process(){ spooler_log.info(\"100: Replaced\"); return true; } ]]> </script> <delay_after_error error_count=\"10\" delay=\"00:01\"/> <run_time let_run=\"no\"/> </job> ";
      submitXml(xml, what, name, modified, path);
      }
    } catch (Exception e) {
      throw new Exception("Error occured initializing " + what + ": " + e);
    }
  }
 
  private void writeSection(String source, String section,Properties entries) throws Exception {
    /** section pattern */
    Pattern SECTION_PATTERN = Pattern.compile("^\\s*\\[([^\\]]*)\\].*$");

    
    String sectionName = null;
    BufferedReader in  = null;
    BufferedWriter out = null;
    String line        = null;
    boolean sectionStart = false;
    boolean otherSectionStart = false;
    boolean haveSection = false;
    String newIni      = "";

      try {

        File file = new File(source);
        if ( !file.exists() )
        throw (new Exception( "couldn't find profile [" + source + "]."));

        in = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
       
        while (true) {
          line = in.readLine();
          if (line == null)
            break;
          Matcher matcher = SECTION_PATTERN.matcher(line);
          if (matcher.matches()) {
            sectionName = matcher.group(1);
            if (sectionName.equalsIgnoreCase(section)) {
              sectionStart = true//Damit Sektion �berlesen werden kann.
              otherSectionStart = false;
            } else otherSectionStart = true;
          }
          if (sectionStart) {
            haveSection=true;
            if (entries.isEmpty()){//Sektion l�schen
              getLog().debug3("Found section "+section+". Deleting section...");
            } else{
              getLog().debug3("Found section "+section+". Modifying section...");
              newIni += line + "\n"//Die Sektion [job ... ]schreiben
              Enumeration keyNames = entries.propertyNames();
              while (keyNames.hasMoreElements()){  //Die Entries schreiben.
                String keyName= keyNames.nextElement().toString();     
                String keyValue= entries.getProperty(keyName);     
                newIni += keyName + "=" + keyValue + "\n";
              }
            }
            sectionStart = false; //Jetzt werden die bisherigen Eintr�ge der Sektion geschrieben oder gel�scht
          }else {
            if (haveSection && !otherSectionStart) {
              //Die Entries aus den Properties nicht schreiben
              if (line.startsWith(";")){ //Kommentarzeilen immer schreiben
                newIni += line + "\n";
              }else {
                 StringTokenizer t = new StringTokenizer(line, "=");
                 if (t.hasMoreTokens()){
                   String token = t.nextToken();
                   if (!entries.containsKey(token) && !entries.isEmpty()){// entries empty: Sektion soll gel�scht werden
                     newIni += line + "\n";
                   }
                 } else{ //keine name=wert Zeile-->uebernehmen, ausser wenn Sektion gel�scht wird
                   if (!entries.isEmpty()){
                     newIni += line + "\n";
                   }
                 }
                     
              }
             
            }else {
              newIni += line + "\n";
            }
//            System.out.println(line);
          }
        }
       
       
        if (!haveSection) {
          newIni += "\n[" + section + "]" + "\n"//Die Sektion [job ... ]schreiben
          Enumeration keyNames = entries.propertyNames();
          while (keyNames.hasMoreElements()){  //Die Entries schreiben.
             String keyName= keyNames.nextElement().toString();     
             String keyValue= entries.getProperty(keyName);     
             newIni += keyName + "=" + keyValue + "\n";
           }
        }
       
       
        out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
        out.write(newIni);
        out.close();
       
        if (getLog() != null) getLog().debug3(SOSClassUtil.getMethodName() + ": profile [" + source + "] successfully loaded.");
      } catch(Exception e) {
        throw (new Exception( SOSClassUtil.getMethodName() + ": " + e.toString()));
      } finally {
        if ( in == null) try { in.close(); } catch(Exception e) {}
      }
    }
 
  private void removeSection(String name) {
    try{
      String section = "job " + name;
      String factoryIni = spooler.ini_path();
      SOSProfileSettings p = new SOSProfileSettings(factoryIni, "emptySection");
      Properties job = p.getSection();
      writeSection(factoryIni, section, job);
    } catch (Exception e){
      try{
        getLog().warn("Error occured removing job settings \""+name+"\": "+e);
      } catch (Exception ex) {}
    }
   
  }
 
  private void updateFactoryIni(String xml, String name) throws Exception {
    String to="";
    String cc= "";
    String bcc="";
    String subject="";
    String body="";
    String factoryIni = spooler.ini_path();
    // String factoryIni = "c:\\scheduler.al\\config\\factory.ini";
   
    String section = "job " + name;
   
    SOSXMLXPath xpath = new SOSXMLXPath(new StringBuffer(xml));
    NamedNodeMap nodeMapSettings = null;
    String nodeQuery = "//email_settings";
    Node emailSettings = xpath.selectSingleNode(nodeQuery);
    if(emailSettings != null){
        nodeMapSettings = emailSettings.getAttributes();
        if(nodeMapSettings != null && nodeMapSettings.getNamedItem("to") != null)
          to = nodeMapSettings.getNamedItem("to").getNodeValue();
        if(nodeMapSettings != null && nodeMapSettings.getNamedItem("cc") != null)
          cc = nodeMapSettings.getNamedItem("cc").getNodeValue();
        if(nodeMapSettings != null && nodeMapSettings.getNamedItem("bcc") != null)
          bcc = nodeMapSettings.getNamedItem("bcc").getNodeValue();
        if(nodeMapSettings != null && nodeMapSettings.getNamedItem("subject") != null)
          subject = nodeMapSettings.getNamedItem("subject").getNodeValue();
    }
   
    getLog().debug3("Update factory.ini:" + factoryIni + " Section=" + section);
   
    //
   
    SOSProfileSettings p = new SOSProfileSettings(factoryIni, "emptySection");
   
   
//    SOSProfileSettings p = new SOSProfileSettings(factoryIni, section, getLogger());
   
    Properties job = p.getSection();
   
   
    job.setProperty("log_mail_to", to);
    job.setProperty("log_mail_cc", cc);
    job.setProperty("log_mail_bcc", bcc);
    job.setProperty("log_mail_subject", subject);
    //job.setProperty("body", body);
   
    writeSection(factoryIni, section, job);
   
   
  }

    private String execute_xml(String xml) throws Exception {
      if (xml.indexOf("<?xml version")==-1){
        xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"+xml;
      }
      String response = spooler.execute_xml(xml);
      getLog().debug3("...executed");
      getLogger().debug9("Response from Job Scheduler: "+response);
     
      SOSXMLXPath xpath = new SOSXMLXPath(new StringBuffer(response));

   
      String errorMsg = "";
      if (xpath.selectSingleNodeValue("//spooler/answer/ERROR") != null) {
         String errorCode = xpath.selectSingleNodeValue("//spooler/answer/ERROR/@code");
         String errorText = xpath.selectSingleNodeValue("//spooler/answer/ERROR/@text");
         errorMsg = errorCode + ":"  + errorText;
      }
     
      if (!errorMsg.equals("")){
        throw new Exception ("Scheduler answer ERROR:" + errorMsg);
      }
      return response;
    }
   
    private void submitXml(String xml, String what, String name, String modified, String path) throws Exception {
    
      String answer="";
            xml = handleInit(xml, what, name);
            if (what.equalsIgnoreCase("job.global")) {
            updateFactoryIni(xml,name);
          } else if (what.equalsIgnoreCase("documentation")){
            updateSchedulerFile(xml,name, modified, what);
          }
            else {
              if (!remove) {
                if (!useLiveFolder){
                  getLog().debug3("execute_xml: " + xml);
                  answer = execute_xml(xml);
                } else{
                  writeConfigFile(xml, what, name, path, modified);
                }
              }
            }
            handleClose(xml,answer, what, name, path);
    }
   
    private void writeConfigFile(String xml, String what, String name, String path, String modified) throws Exception{
      try{
        String fileName="";
        SOSXMLXPath xpath = new SOSXMLXPath(new StringBuffer(xml));
        if (what.equalsIgnoreCase("order")){
          String job_chain = xpath.selectSingleNodeValue("//add_order/@job_chain");
          fileName=job_chain+",";
        }
        fileName+=name+".";
        String fileIdentifier = what;
        if(fileIdentifier.equalsIgnoreCase("orderjob")) fileIdentifier="job";
        fileName+=fileIdentifier + ".xml";
        File managedDir = new File(liveFolder,path);
        File managedFile = new File(managedDir,fileName);
        if (!managedDir.exists()) createManagedDir(managedDir);
        getLog().debug3("Filename for configuration file: "+fileName);       
        writeLiveFile(xpath, what, managedFile);
        updateManagedIndicator(managedFile, modified);
      } catch(Exception e){
        throw new Exception("Error occured updating config file in hot folder: "+e);
      }
    }
   
   

    private void updateManagedIndicator(File managedFile, String dbModified) throws Exception{
      File managedIndicator = new File(managedFile.getParentFile(), ".managed");
      try{
        getLog().debug5("Updating "+managedIndicator.getAbsolutePath());
        String md5 = sos.util.SOSCrypt.MD5encrypt(managedFile);
        String lineWithMD5 = managedFile.getName()+" "+md5+" "+dbModified;
        BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(managedIndicator)));
            String line = null;
            String output="";
            boolean found = false;
            while (true) {
              line = in.readLine();
              if (line == null)
                break;
              //getLog().debug9("current line: "+line);
              if (line.startsWith(managedFile.getName())){
                found = true;
                //getLog().debug9(" overwriting with "+lineWithMD5);
                output += lineWithMD5+"\n";
              } else{
                if (line.trim().length()>0){
                  output += line+"\n";
                //getLog().debug9(" keeping line");
                }
              }
          }
            if (!found) {
              //getLog().debug9(" adding line "+lineWithMD5);
              output += lineWithMD5;
            }
            in.close();
            //getLog().debug9(" complete content:\n"+output);
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(managedIndicator)));
          out.write(output);
          out.close();
      }catch (Exception e){
        throw new Exception("Error updating "+managedIndicator.getAbsolutePath()+" for file "+managedFile.getName()+": "+e);
      }
    }
   
   
    private void createManagedDir(File managedDir) throws Exception{
    if (managedDir.equals(liveFolder)) return;
    try{
      File parent = managedDir.getParentFile();
      if (!parent.exists()) createManagedDir(parent);
      getLog().debug3("creating managed folder "+managedDir.getAbsolutePath());
      if(!managedDir.mkdir()) throw new Exception("mkdir failed");
      File managedIndicator = new File(managedDir, ".managed");
      getLog().debug5("Creating file "+managedIndicator.getAbsolutePath());
      if(!managedIndicator.createNewFile()){
        throw new Exception("Failed to create file "+managedIndicator.getAbsolutePath());
      }
    } catch(Exception e){
      throw new Exception("Error creating managed folder "+managedDir.getAbsolutePath()+": "+e,e);
    }   
  }

  private void writeLiveFile(SOSXMLXPath xpath, String what, File xmlFile) throws Exception{
    try{
      if (!xmlFile.exists()){
        if (!xmlFile.createNewFile()) throw new Exception("Failed to create "+xmlFile.getAbsolutePath());
      }
      FileOutputStream fos = new FileOutputStream(xmlFile);
      DOMResult domResult = new DOMResult();
      StreamResult result = new StreamResult(fos);
      DOMSource source = new DOMSource(xpath.document);
      getLog().debug9("managed2liveTransformer: "+managed2liveTransformer);
     
      managed2liveTransformer.transform(source, result);
      /*getLog().debug9("Nodename: "+result.getNode().getNodeName());
      getLog().debug9("ChildNodes: "+result.getNode().getChildNodes());
      getLog().debug9("ChildNodes length: "+result.getNode().getChildNodes().getLength());
      getLog().debug9("ChildNodes [1]: "+result.getNode().getChildNodes().item(0).getNodeName());
      */
    } catch(Exception e){
      throw new Exception("Error preparing xml: "+e);
    }   
  }

  private void removeSchedulerFile(String name, String what){
      try{
        File schedulerFile = new File(getDirectory(what)+name);
        getLog().info("removing "+what+" "+schedulerFile.getAbsolutePath());
        schedulerFile.delete();
      }catch (Exception e){
        try{
          getLog().warn("Error occured removing "+what+" \""+name+"\": "+e);
        } catch (Exception ex) {}
      }
    }
   
    private void updateSchedulerFile(String xml, String name, String modified, String what) throws Exception {
      try{
        // compare File and XML Date     
        Date modDate = SOSDate.getTime(modified);
        getLog().debug5("modDate: "+modDate);
        File schedulerFile = new File(getDirectory(what)+name);
        boolean update = false;
        if (schedulerFile.exists()){
          Date fileDate = new Date(schedulerFile.lastModified());
          getLog().debug5("fileDate: "+fileDate);
          if (fileDate.before(modDate)){
            update=true;
            getLog().debug1(what+" "+schedulerFile.getAbsolutePath()+" is older than "+what+" in database. " +
                "Updating file.");
          }else{
            getLog().debug1(what+" "+schedulerFile.getAbsolutePath()+" is newer than "+what+" in database. " +
          "Doing nothing.");
          }
         
        }
        else{
          getLog().debug1(what+" "+schedulerFile.getAbsolutePath()+" doesn't exist. Creating new file.");
          update=true;         
        }
        // if XML is newer, update file
        if (update){
          // read XML
          /*DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
              DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
              ByteArrayInputStream bai = new ByteArrayInputStream(xml.getBytes());
              InputSource source = new InputSource(bai);
             
              Document xmlDoc = docBuilder.parse(source);*/
          ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes("UTF-8"));
              //SOSXMLXPath xpath = new SOSXMLXPath(new StringBuffer(xml));
          SOSXMLXPath xpath = new SOSXMLXPath(bis);
              if (what.equalsIgnoreCase("documentation")){
                String xmlContent = xpath.selectSingleNodeValue("/documentation");
                getLog().debug9("Content of /documentation:\n"+xmlContent);
                String outputEncoding = parseEncoding(xmlContent);
                if (outputEncoding==null || outputEncoding.length()==0) {
                  outputEncoding="UTF-8";
                  xmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+xmlContent;
                }
               
                /*BufferedWriter wri = new BufferedWriter(
                    new FileWriter(schedulerFile,false));
                */
                /*
                PrintWriter target = new PrintWriter(new FileWriter(schedulerFile,false));
                target.print(xmlContent);
                target.close();
                */
               
                OutputStream fout = new FileOutputStream(schedulerFile,false);
                //OutputStream bout= new BufferedOutputStream(fout);
                OutputStreamWriter out = new OutputStreamWriter(fout, outputEncoding);
                out.write(xmlContent);
                out.flush();
                out.close();
              }
        }
      } catch (Exception e){
        throw new Exception("Error occured updating job documentation file \""+name+"\": "+e);
      }
   
  }

  private String parseEncoding(String xmlContent) {
    Matcher matcher = xmlEncodingPattern.matcher(xmlContent);
    if (matcher.find()){
      if (matcher.groupCount()>0) return matcher.group(1);     
    }
    return null;
  }

  public SOSLogger getLog(){
    return getLogger();
    /*
        if(startscript) return spooler.log();
        else            return spooler_log;
        */
    }

    public boolean spooler_process() throws Exception  {
        try {
            Order order = spooler_task.order();
            orderParams = order.params();
            String managedObjectID = orderParams.var("managed_object_id");
            getLog().debug3("managed_object_id: " + managedObjectID);
           
            String remove = orderParams.var("remove");
            if (remove!=null && remove.equalsIgnoreCase("yes")){
              String type = orderParams.var("managed_object_type");
              String name = orderParams.var("managed_object_name");
              remove(type, name);
            }else {
              try{
                  Integer.parseInt(managedObjectID);
                } catch(Exception e){
                  throw new Exception("Missing or illegal value for parameter managed_object_id: \""+managedObjectID+"\"");
                }
              initialize(managedObjectID);
            }
            return true;
        }catch(Exception e) {
            getLog().warn("Error processing order: " + e.getMessage());
            spooler_task.order().setback();
            spooler_task.order().params().set_var("message", e.getMessage());
            spooler_task.end();
            return false;
        } finally {
            if (this.getConnection() !=  null) {
                try { this.getConnection().rollback(); } catch (Exception ex) {} // no error handling
            }
           
        }
    }

    private void testOrder() {
      startscript=false;
      String name = "Testorder";
      String xml = "<add_order id=\"myOrder\"  job_chain=\"jobchain\"   title=\"Test fuer Managed Starter\"  state=\"100\">       <run_time let_run=\"no\"/></add_order>";
      try  {
          handleOrderInit(name, xml);
      }catch(Exception e){
          e.printStackTrace();
      }
  }
    private void testFactoryIni() throws Exception{
      startscript=false;
      SOSLogger log = new SOSStandardLogger(SOSLogger.DEBUG9);
      //setLogger(log);
      String name = "TestJob_new";
      String xml = "<email_settings to=\"oh@sos-berlin.com\"/>";
      try  {
        updateFactoryIni(xml,name);
      }catch(Exception e){
          e.printStackTrace();
      }
  }
   
    private void testDocumentation() throws Exception{
      startscript=false;
      SOSLogger log = new SOSStandardLogger(SOSLogger.DEBUG9);
      SOSConnection conn = SOSConnection.createInstance("j:/e/java/al/sos.scheduler/config/sos_setup_settings.ini", log);
      //setLogger(log);
      try{
     
      conn.connect();
    String xml = conn.getClob("SELECT \"XML\" FROM SCHEDULER_MANAGED_OBJECTS WHERE \"ID\" = 347");
   
      try  {
        updateSchedulerFile(xml, "New_job_documentation.xml", SOSDate.getCurrentTimeAsString(), "documentation");
         
      }catch(Exception e){
          e.printStackTrace();
      }
      } catch(Exception e){
        e.printStackTrace();
      } finally{
        if (conn!=null) conn.disconnect();
      }
  }

    public static void main(String args[]) throws Exception {
        JobSchedulerManagedStarter x = new JobSchedulerManagedStarter();
        //x.testDocumentation();
//        x.testOrder();
        x.testFactoryIni();
    }

   
}
TOP

Related Classes of sos.scheduler.managed.JobSchedulerManagedStarter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.