/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2016 by Pentaho : http://www.pentaho.com * ******************************************************************************* * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ package org.pentaho.di.www; import org.pentaho.di.core.Const; import org.pentaho.di.core.util.Utils; import org.pentaho.di.core.logging.LoggingObjectType; import org.pentaho.di.core.logging.SimpleLoggingObject; import org.pentaho.di.core.xml.XMLHandler; import org.pentaho.di.job.Job; import org.pentaho.di.job.JobAdapter; import org.pentaho.di.job.JobConfiguration; import org.pentaho.di.job.JobExecutionConfiguration; import org.pentaho.di.job.JobMeta; import org.pentaho.di.job.entry.JobEntryCopy; import org.pentaho.di.repository.Repository; import java.io.BufferedReader; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.Map; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //has been replaced by RegisterJobServlet @Deprecated public class AddJobServlet extends BaseHttpServlet implements CartePluginInterface { private static final long serialVersionUID = -6850701762586992604L; public static final String CONTEXT_PATH = "/kettle/addJob"; public AddJobServlet() { } public AddJobServlet( JobMap jobMap, SocketRepository socketRepository ) { super( jobMap, socketRepository ); } /** /** <div id="mindtouch"> <h1>/kettle/addJob</h1> <a name="POST"></a> <h2>POST</h2> <p>Uploads and executes job configuration XML file. Uploads xml file containing job and job_execution_configuration (wrapped in job_configuration tag) to be executed and executes it. Method relies on the input parameter to determine if xml or html reply should be produced. The job_configuration xml is transferred within request body. <code>Job name of the executed job </code> will be returned in the Response object or <code>message</code> describing error occurred. To determine if the call successful or not you should rely on <code>result</code> parameter in response.</p> <p><b>Example Request:</b><br /> <pre function="syntax.xml"> POST /kettle/addJob/?xml=Y </pre> <p>Request body should contain xml containing job_configuration (job + job_execution_configuration wrapped in job_configuration tag).</p> </p> <h3>Parameters</h3> <table class="pentaho-table"> <tbody> <tr> <th>name</th> <th>description</th> <th>type</th> </tr> <tr> <td>xml</td> <td>Boolean flag set to either <code>Y</code> or <code>N</code> describing if xml or html reply should be produced.</td> <td>boolean, optional</td> </tr> </tbody> </table> <h3>Response Body</h3> <table class="pentaho-table"> <tbody> <tr> <td align="right">element:</td> <td>(custom)</td> </tr> <tr> <td align="right">media types:</td> <td>text/xml, text/html</td> </tr> </tbody> </table> <p>Response wraps job name that was executed or error stack trace if an error occurred. Response has <code>result</code> OK if there were no errors. Otherwise it returns ERROR.</p> <p><b>Example Response:</b></p> <pre function="syntax.xml"> <?xml version="1.0" encoding="UTF-8"?> <webresult> <result>OK</result> <message>Job 'dummy_job' was added to the list with id 1e90eca8-4d4c-47f7-8e5c-99ec36525e7c</message> <id>1e90eca8-4d4c-47f7-8e5c-99ec36525e7c</id> </webresult> </pre> <h3>Status Codes</h3> <table class="pentaho-table"> <tbody> <tr> <th>code</th> <th>description</th> </tr> <tr> <td>200</td> <td>Request was processed and XML response is returned.</td> </tr> <tr> <td>500</td> <td>Internal server error occurs during request processing.</td> </tr> </tbody> </table> </div> */ public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { if ( isJettyMode() && !request.getRequestURI().startsWith( CONTEXT_PATH ) ) { return; } if ( log.isDebug() ) { logDebug( "Addition of job requested" ); } boolean useXML = "Y".equalsIgnoreCase( request.getParameter( "xml" ) ); PrintWriter out = response.getWriter(); BufferedReader in = request.getReader(); // read from the client if ( log.isDetailed() ) { logDetailed( "Encoding: " + request.getCharacterEncoding() ); } if ( useXML ) { response.setContentType( "text/xml" ); out.print( XMLHandler.getXMLHeader() ); } else { response.setContentType( "text/html" ); out.println( "<HTML>" ); out.println( "<HEAD><TITLE>Add job</TITLE></HEAD>" ); out.println( "<BODY>" ); } response.setStatus( HttpServletResponse.SC_OK ); try { // First read the complete transformation in memory from the request int c; StringBuilder xml = new StringBuilder(); while ( ( c = in.read() ) != -1 ) { xml.append( (char) c ); } // Parse the XML, create a job configuration // // System.out.println(xml); // JobConfiguration jobConfiguration = JobConfiguration.fromXML( xml.toString() ); JobMeta jobMeta = jobConfiguration.getJobMeta(); JobExecutionConfiguration jobExecutionConfiguration = jobConfiguration.getJobExecutionConfiguration(); jobMeta.setLogLevel( jobExecutionConfiguration.getLogLevel() ); jobMeta.injectVariables( jobExecutionConfiguration.getVariables() ); // If there was a repository, we know about it at this point in time. // final Repository repository = jobConfiguration.getJobExecutionConfiguration().getRepository(); String carteObjectId = UUID.randomUUID().toString(); SimpleLoggingObject servletLoggingObject = new SimpleLoggingObject( CONTEXT_PATH, LoggingObjectType.CARTE, null ); servletLoggingObject.setContainerObjectId( carteObjectId ); servletLoggingObject.setLogLevel( jobExecutionConfiguration.getLogLevel() ); // Create the transformation and store in the list... // final Job job = new Job( repository, jobMeta, servletLoggingObject ); // Setting variables // job.initializeVariablesFrom( null ); job.getJobMeta().setInternalKettleVariables( job ); job.injectVariables( jobConfiguration.getJobExecutionConfiguration().getVariables() ); job.setArguments( jobExecutionConfiguration.getArgumentStrings() ); // Also copy the parameters over... // job.copyParametersFrom( jobMeta ); job.clearParameters(); String[] parameterNames = job.listParameters(); for ( int idx = 0; idx < parameterNames.length; idx++ ) { // Grab the parameter value set in the job entry // String thisValue = jobExecutionConfiguration.getParams().get( parameterNames[idx] ); if ( !Utils.isEmpty( thisValue ) ) { // Set the value as specified by the user in the job entry // jobMeta.setParameterValue( parameterNames[idx], thisValue ); } } jobMeta.activateParameters(); // Check if there is a starting point specified. String startCopyName = jobExecutionConfiguration.getStartCopyName(); if ( startCopyName != null && !startCopyName.isEmpty() ) { int startCopyNr = jobExecutionConfiguration.getStartCopyNr(); JobEntryCopy startJobEntryCopy = jobMeta.findJobEntry( startCopyName, startCopyNr, false ); job.setStartJobEntryCopy( startJobEntryCopy ); } job.setSocketRepository( getSocketRepository() ); // Do we need to expand the job when it's running? // Note: the plugin (Job and Trans) job entries need to call the delegation listeners in the parent job. // if ( jobExecutionConfiguration.isExpandingRemoteJob() ) { job.addDelegationListener( new CarteDelegationHandler( getTransformationMap(), getJobMap() ) ); } getJobMap().addJob( job.getJobname(), carteObjectId, job, jobConfiguration ); // Make sure to disconnect from the repository when the job finishes. // if ( repository != null ) { job.addJobListener( new JobAdapter() { public void jobFinished( Job job ) { repository.disconnect(); } } ); } String message = "Job '" + job.getJobname() + "' was added to the list with id " + carteObjectId; if ( useXML ) { out.println( new WebResult( WebResult.STRING_OK, message, carteObjectId ) ); } else { out.println( "<H1>" + message + "</H1>" ); out.println( "<p><a href=\"" + convertContextPath( GetJobStatusServlet.CONTEXT_PATH ) + "?name=" + job.getJobname() + "&id=" + carteObjectId + "\">Go to the job status page</a><p>" ); } } catch ( Exception ex ) { if ( useXML ) { out.println( new WebResult( WebResult.STRING_ERROR, Const.getStackTracker( ex ) ) ); } else { out.println( "<p>" ); out.println( "<pre>" ); ex.printStackTrace( out ); out.println( "</pre>" ); } } if ( !useXML ) { out.println( "<p>" ); out.println( "</BODY>" ); out.println( "</HTML>" ); } } protected String[] getAllArgumentStrings( Map<String, String> arguments ) { if ( arguments == null || arguments.size() == 0 ) { return null; } String[] argNames = arguments.keySet().toArray( new String[arguments.size()] ); Arrays.sort( argNames ); String[] values = new String[argNames.length]; for ( int i = 0; i < argNames.length; i++ ) { values[i] = arguments.get( argNames[i] ); } return values; } public String toString() { return "Add Job"; } public String getService() { return CONTEXT_PATH + " (" + toString() + ")"; } public String getContextPath() { return CONTEXT_PATH; } }