Project

General

Profile

« Previous | Next » 

Revision 5039

Added by daigle over 15 years ago

Added workflow scheduler directory with supporting files

View differences:

src/edu/ucsb/nceas/workflowscheduler/WorkflowJob.java
1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: a single workflow job that is schedulable 
4
 *  Copyright: 2009 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Michael Daigle
7
 *
8
 *   '$Author: daigle $'
9
 *     '$Date: 2008-07-06 21:25:34 -0700 (Sun, 06 Jul 2008) $'
10
 * '$Revision: 4080 $'
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 */
26
package edu.ucsb.nceas.workflowscheduler;
27

  
28
import java.rmi.RemoteException;
29
import javax.xml.rpc.ServiceException;
30

  
31
import org.apache.log4j.Logger;
32

  
33
import org.quartz.InterruptableJob;
34
import org.quartz.JobDetail;
35
import org.quartz.JobDataMap;
36
import org.quartz.JobExecutionContext;
37
import org.quartz.JobExecutionException;
38

  
39
import org.kepler.executionWS.KeplerWebServiceLocator;
40
import org.kepler.executionWS.KeplerWebServicePortType;
41

  
42
import edu.ucsb.nceas.metacat.scheduler.ScheduledJobAccess;
43
import edu.ucsb.nceas.metacat.scheduler.ScheduledJobDAO;
44
import edu.ucsb.nceas.metacat.scheduler.ScheduledJobParamDAO;
45

  
46
public class WorkflowJob implements InterruptableJob {
47
	
48
	private static Logger logMetacat = Logger.getLogger(WorkflowJob.class);
49
    	
50
	/**
51
	 * Required method that is called when the job is run by the scheduler.
52
	 * 
53
	 * @param executionContext
54
	 *            the context information for this job
55
	 */
56
	public void execute(JobExecutionContext executionContext) throws JobExecutionException {
57
		try {
58
			// have to be able to get the job detail
59
			JobDetail jobDetail = executionContext.getJobDetail();
60
			if (jobDetail == null) {
61
				throw new JobExecutionException("WorkflowJob.execute - Could not get job detail from execution context"); 
62
			}
63
			
64
			// have to be able to get the job data map from the job detail
65
			JobDataMap jobDataMap = jobDetail.getJobDataMap();
66
			if (jobDataMap == null) {
67
				throw new JobExecutionException("WorkflowJob.execute - Could not get job data map from job detail"); 
68
			}
69
			
70
			String jobName = jobDetail.getName();
71
			
72
			ScheduledJobAccess jobAccess = new ScheduledJobAccess();
73
			ScheduledJobDAO jobDAO = jobAccess.getJobByName(jobName);
74
			
75
			if(jobDAO == null) {
76
				String errorMessage = "WorkflowJob.execute - Could not retrieve job info from " 
77
					+ "database for job: " + jobName;
78
				logMetacat.error(errorMessage);
79
				throw new JobExecutionException(errorMessage);
80
			}
81
			
82
			// the kar lsid must be part of the job data map
83
			ScheduledJobParamDAO jobParamDAO = jobDAO.getAllJobParams().get("karid");
84
			if (jobParamDAO == null) {
85
				throw new JobExecutionException("WorkflowJob.execute - Could not get job param named karid from " 
86
						+ "job data map for job: " + jobName);
87
			}
88
			String karLSID = jobParamDAO.getValue();
89
			if (karLSID == null) {
90
				throw new JobExecutionException("WorkflowJob.execute - Could not get kar LSID for job: " + jobName);
91
			}
92
			
93
			// Locate service
94
			logMetacat.debug("WorkflowJob.execute - Getting kepler webservice Locator");
95
			KeplerWebServiceLocator serviceLocator = new KeplerWebServiceLocator();
96
			
97
			// get endpoint service
98
			logMetacat.debug("WorkflowJob.execute - Getting kepler webservice");
99
			KeplerWebServicePortType serviceEndpoint = serviceLocator.getKeplerWebServiceHttpSoap11Endpoint();
100
			
101
			// call execute against remote endpoint
102
			logMetacat.debug("WorkflowJob.execute - Executing with kar lsid:" + karLSID);
103
			String status = serviceEndpoint.execute(karLSID);		
104
			logMetacat.debug("WorkflowJob.execute - Status: " + status);
105
			
106
		} catch (RemoteException re) {
107
			String errorStr = "WorkflowJob.execute - Remote problem when trying to execute task: " + re.getMessage();
108
			logMetacat.error(errorStr);
109
			throw new JobExecutionException(errorStr); 
110
		} catch (ServiceException se) {
111
			String errorStr = "WorkflowJob.execute - Service problem when trying to execute task: " + se.getMessage();
112
			logMetacat.error(errorStr);
113
			throw new JobExecutionException(errorStr); 
114
		} catch (Exception e) {
115
			String errorStr = "WorkflowJob.execute - General problem when trying to execute task: " + e.getMessage();
116
			logMetacat.error(errorStr);
117
			throw new JobExecutionException(errorStr); 
118
		}
119
	}
120
	
121
	public void interrupt() {
122
	}
123
}
0 124

  
src/edu/ucsb/nceas/workflowscheduler/WorkflowScheduler.java
1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that handles scheduling workflow jobs 
4
 *  Copyright: 2009 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Michael Daigle
7
 * 
8
 *   '$Author: daigle $'
9
 *     '$Date: 2009-03-25 13:41:15 -0800 (Wed, 25 Mar 2009) $'
10
 * '$Revision: 4861 $'
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 */
26

  
27
package edu.ucsb.nceas.workflowscheduler;
28

  
29
import java.io.IOException;
30
import java.io.PrintWriter;
31
import java.util.Calendar;
32
import java.util.Hashtable;
33
import java.util.HashMap;
34

  
35
import javax.servlet.http.HttpServletRequest;
36
import javax.servlet.http.HttpServletResponse;
37

  
38
import org.apache.log4j.Logger;
39

  
40
import edu.ucsb.nceas.metacat.scheduler.BaseScheduler;
41
import edu.ucsb.nceas.metacat.scheduler.ScheduledJobAccess;
42
import edu.ucsb.nceas.metacat.scheduler.ScheduledJobDAO;
43
import edu.ucsb.nceas.metacat.scheduler.SchedulerService;
44
import edu.ucsb.nceas.metacat.scheduler.MetacatSchedulerException;
45
import edu.ucsb.nceas.metacat.shared.AccessException;
46
import edu.ucsb.nceas.metacat.shared.ServiceException;
47
import edu.ucsb.nceas.metacat.util.ErrorSendingErrorException;
48
import edu.ucsb.nceas.metacat.util.ResponseUtil;
49
import edu.ucsb.nceas.utilities.DateUtil;
50
import edu.ucsb.nceas.utilities.UtilException;
51

  
52
/**
53
 * @author daigle
54
 *
55
 */
56
public class WorkflowScheduler extends BaseScheduler {
57
	
58
	private static WorkflowScheduler workflowScheduler = null;
59
	
60
	private static Logger logMetacat = Logger.getLogger(WorkflowScheduler.class);
61
	
62
	private static String WORKFLOW_JOB_GROUP = "workflow";
63
	private static String WORKFLOW_JOB_CLASS = "edu.ucsb.nceas.workflowscheduler.WorkflowJob";
64

  
65
	/**
66
	 * private constructor since this is a singleton
67
	 */
68
	private WorkflowScheduler()  {}
69
	
70
	/**
71
	 * Get the single instance of SchedulerService.
72
	 * 
73
	 * @return the single instance of SchedulerService
74
	 */
75
	public static WorkflowScheduler getInstance() {
76
		if (workflowScheduler == null) {
77
			workflowScheduler = new WorkflowScheduler();
78
		}
79
		return workflowScheduler;
80
	}
81
	
82
	/**
83
	 * Scheduling a workflow
84
	 * 
85
	 * @param request
86
	 *            the servlet request object
87
	 * @param response
88
	 *            the servlet response object
89
	 * @param params
90
	 *            the request parameters
91
	 * @param username
92
	 *            the user
93
	 * @param groups
94
	 *            the user's group
95
	 */
96
	public void scheduleJob(HttpServletRequest request, HttpServletResponse response, 
97
			Hashtable<String, String[]> params, String username,
98
			String[] groups) throws MetacatSchedulerException {
99
		 		
100
		String delays[] = params.get("delay");
101
		String startTimes[] = params.get("starttime");
102
		String endTimes[] = params.get("endtime");
103
		HashMap<String, String> jobParams = new HashMap<String, String>();
104
		Calendar startCal = null;
105
		Calendar endCal = null;
106

  
107
		try {
108
			SchedulerService schedulerService = SchedulerService.getInstance();
109

  
110
			// get start time or delay.  Start time takes precedence if both exist.
111
			if (startTimes != null && startTimes.length > 0) {
112
				startCal = DateUtil.humanReadableToCalendar(startTimes[0], "MM/dd/yyyy HH:mm:ss");
113
			} else if (delays != null && delays.length > 0) {
114
				startCal = schedulerService.getStartDateFromDelay(delays[0]);
115
			} else {
116
				// if delay and starttime were not provided, set date to now.
117
				startCal = Calendar.getInstance();
118
			}
119
			
120
			// get end time.  null is fine.
121
			if (endTimes != null && endTimes.length > 0) {
122
				endCal = DateUtil.humanReadableToCalendar(endTimes[0], "MM/dd/yyyy HH:mm:ss");
123
			} 
124

  
125
			// interval value must exist
126
			String intervalValues[] = params.get("intervalvalue");
127
			if (intervalValues == null || intervalValues.length == 0) {
128
				throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - intervalvalue field must be populated "
129
								+ "in scheduler parameters when scheduling job.");
130
			}
131
			String intervalStrValue = intervalValues[0];
132
			int intervalValue = Integer.parseInt(intervalStrValue);
133
			
134
			// interval unit must exist
135
			String intervalUnits[] = params.get("intervalunit");
136
			if (intervalUnits == null || intervalUnits.length == 0) {
137
				throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - intervalunit field must be populated "
138
								+ "in scheduler parameters when scheduling job.");
139
			}
140
			String intervalUnit = intervalUnits[0];
141

  
142
			// workflow id must exist.  Add to job params
143
			String workflowids[] = params.get("workflowid");
144
			if (workflowids == null || workflowids.length == 0) {
145
				throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - workflowid field must be populated "
146
								+ "in scheduler parameters when scheduling job.");
147
			}
148
			jobParams.put("workflowid", workflowids[0]);
149
			
150
			// kar id must exist.  Add to job params
151
			String karids[] = params.get("karid");
152
			if (karids == null || karids.length == 0) {
153
				throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - karid field must be populated "
154
								+ "in scheduler parameters when scheduling job.");
155
			}
156
			jobParams.put("karid", karids[0]);
157
			
158
			
159
			// workflow name unit must exist.  Add to job params
160
			String workflownames[] = params.get("workflowname");
161
			if (workflownames == null || workflownames.length == 0) {
162
				throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - workflowname field must be populated "
163
								+ "in scheduler parameters when scheduling job.");
164
			}
165
			jobParams.put("workflowname", workflownames[0]);
166

  
167
			String jobName = WORKFLOW_JOB_GROUP
168
					+ Calendar.getInstance().getTimeInMillis();
169

  
170
			// Schedule the job
171
			String xmlResult = schedulerService.scheduleJob(jobName, startCal, endCal, intervalValue, intervalUnit,
172
					WORKFLOW_JOB_CLASS, WORKFLOW_JOB_GROUP, jobParams, username, groups);
173
			
174
			ResponseUtil.sendSuccessXML(response, xmlResult);
175
			
176
		} catch (UtilException ue) {
177
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - " 
178
					+ "Utility issue when scheduling job: " + ue.getMessage());
179
		} catch (ServiceException se) {
180
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - " 
181
					+ "Service issue when scheduling job", se);
182
		} catch (ErrorSendingErrorException esee) {
183
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - " 
184
					+ "Issue sending error when scheduling job: " + esee.getMessage());			
185
		}
186
	}
187
	
188
	/**
189
	 * Unschedule a job
190
	 * 
191
	 * @param request
192
	 *            the servlet request object
193
	 * @param response
194
	 *            the servlet response object
195
	 * @param params
196
	 *            the request parameters
197
	 * @param username
198
	 *            the user
199
	 * @param groups
200
	 *            the user's group
201
	 */
202
	public void unScheduleJob(HttpServletRequest request, HttpServletResponse response,
203
			Hashtable<String, String[]> params, String username, String[] groups)
204
			throws MetacatSchedulerException {
205
		try {
206
			// workflow job id must exist
207
			String jobNames[] = params.get("workflowjobid");
208
			if (jobNames == null || jobNames.length == 0) {
209
				throw new MetacatSchedulerException("SchedulerService.unScheduleJob - workflowjobid " 
210
						+ "field must be populated in scheduler parameters when unscheduling job.");
211
			}
212
			String jobName = jobNames[0];
213

  
214
			// unschedule the job
215
			SchedulerService schedulerService = SchedulerService.getInstance();
216
			String xmlResult = schedulerService.unScheduleJob(jobName, username, groups);
217
			
218
			ResponseUtil.sendSuccessXML(response, xmlResult);
219

  
220
		} catch (ServiceException se) {
221
			throw new MetacatSchedulerException("WorkflowScheduler.unScheduleJob - " 
222
					+ "Service issue unscheduling job", se);
223
		} catch (Exception e) {
224
			throw new MetacatSchedulerException("WorkflowScheduler.unScheduleJob - " 
225
					+ "Generic issue unscheduling job: " + e.getMessage());
226
		}
227
	}
228
	
229
	/**
230
	 * reschedule job
231
	 * 
232
	 * @param request
233
	 *            the servlet request object
234
	 * @param response
235
	 *            the servlet response object
236
	 * @param params
237
	 *            the request parameters
238
	 * @param username
239
	 *            the user
240
	 * @param groups
241
	 *            the user's group
242
	 */
243
	public void reScheduleJob(HttpServletRequest request, HttpServletResponse response, 
244
			Hashtable<String, String[]> params, String username,
245
			String[] groups) throws MetacatSchedulerException {
246
		 		
247
		try {
248
			// workflow job id must exist
249
			String jobNames[] = params.get("workflowjobid");	
250
			if (jobNames == null || jobNames.length == 0) {
251
				throw new MetacatSchedulerException("WorkflowScheduler.reScheduleJob - workflowjobid field must be populated "
252
						+ "in scheduler parameters when rescheduling job.");
253
			}			
254
			String jobName = jobNames[0];
255
	
256
			ScheduledJobAccess jobAccess = new ScheduledJobAccess();
257
			ScheduledJobDAO jobDAO = jobAccess.getJobByName(jobName);
258
			
259
			// reschedule the job
260
			SchedulerService schedulerService = SchedulerService.getInstance();
261
			String result = schedulerService.rescheduleJob(jobDAO, username, groups);
262

  
263
			ResponseUtil.sendSuccessXML(response, result);
264
			
265
		} catch (AccessException ae) {
266
			throw new MetacatSchedulerException("WorkflowScheduler.reScheduleJob - " 
267
					+ "DB access issue when scheduling job  : ", ae);
268
		} catch (ServiceException se) {
269
			throw new MetacatSchedulerException("WorkflowScheduler.reScheduleJob - " 
270
					+ "Service issue scheduling job", se);
271
		} catch (ErrorSendingErrorException esee) {
272
			throw new MetacatSchedulerException("WorkflowScheduler.reScheduleJob - " 
273
					+ "Issue sending erro when scheduling job: " + esee.getMessage());			
274
		}
275
	}
276
	
277
	/**
278
	 * delete job - to be implemented
279
	 */
280
	public void deleteJob(HttpServletRequest request, HttpServletResponse response, 
281
			Hashtable<String, String[]> params, String username, String[] groups) throws MetacatSchedulerException {
282
		 try {
283
			// workflow job id must exist
284
			String jobNames[] = params.get("workflowjobid");
285
			if (jobNames == null || jobNames.length == 0) {
286
				throw new MetacatSchedulerException(
287
						"WorkflowScheduler.deleteJob - workflowname field must be populated "
288
								+ "in scheduler parameters when deleting job.");
289
			}
290
			String jobName = jobNames[0];
291

  
292
			ScheduledJobAccess jobAccess = new ScheduledJobAccess();
293
			ScheduledJobDAO jobDAO = jobAccess.getJobByName(jobName);
294

  
295
			// delete the job
296
			SchedulerService schedulerService = SchedulerService.getInstance();
297
			String result = schedulerService.deleteJob(jobDAO, username, groups);
298

  
299
			ResponseUtil.sendSuccessXML(response, result);
300

  
301
		} catch (AccessException ae) {
302
			throw new MetacatSchedulerException("WorkflowScheduler.deleteJob - "
303
					+ "DB access issue when deleting job  : ", ae);
304
		} catch (ServiceException se) {
305
			throw new MetacatSchedulerException("WorkflowScheduler.deleteJob - "
306
					+ "Service issue deleting job", se);
307
		} catch (ErrorSendingErrorException esee) {
308
			throw new MetacatSchedulerException("WorkflowScheduler.deleteJob - "
309
					+ "Issue sending erro when deleting job: " + esee.getMessage());
310
		}
311
	}
312
	
313
	/**
314
	 * get job information for a given workflow in xml format
315
	 * 
316
	 * @param request
317
	 *            the servlet request object
318
	 * @param response
319
	 *            the servlet response object
320
	 * @param params
321
	 *            the request parameters
322
	 * @param username
323
	 *            the user
324
	 * @param groups
325
	 *            the user's group
326
	 */
327
	public void getJobs(HttpServletRequest request, HttpServletResponse response, 
328
			Hashtable<String, String[]> params, String username, String[] groups) throws MetacatSchedulerException {
329
		
330
		String workflowId = null;
331
		
332
		String workflowIds[] = params.get("workflowid");
333
		if (workflowIds != null && workflowIds.length != 0) {
334
			workflowId = workflowIds[0];
335
		}
336
		
337
		logMetacat.debug("WorkflowScheduler.getJobs - getting jobs for workflow:" + workflowId);
338
		
339
        PrintWriter out = null;
340
		try {
341
			// get the job info in xml format
342
			out = response.getWriter();
343
			SchedulerService.getInstance().getJobsInfoXML(WORKFLOW_JOB_GROUP,
344
					"workflowid", workflowId, out);
345
		} catch (ServiceException se) {
346
			throw new MetacatSchedulerException("WorkflowScheduler.getJobs - " 
347
					+ "Service error when transforming XML for workflow id: " 
348
					+ workflowId + " : " + se.getMessage());
349
		} catch (IOException ioe) {
350
			throw new MetacatSchedulerException("WorkflowScheduler.getJobs - " 
351
					+ "I/O error when transforming XML for workflow id: " 
352
					+ workflowId + " : " + ioe.getMessage());
353
		} finally {
354
			if (out != null) {
355
				out.close();
356
			}
357
		}
358
	}
359
}
0 360

  
src/edu/ucsb/nceas/workflowscheduler/WorkflowSchedulerServlet.java
1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements a metadata catalog as a java Servlet
4
 *  Copyright: 2006 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Matt Jones, Dan Higgins, Jivka Bojilova, Chad Berkley, Matthew Perry
7
 *
8
 *   '$Author: daigle $'
9
 *     '$Date: 2009-08-07 10:35:18 -0700 (Fri, 07 Aug 2009) $'
10
 * '$Revision: 5018 $'
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 */
26

  
27
package edu.ucsb.nceas.workflowscheduler;
28

  
29
import java.io.IOException;
30
import java.io.PrintWriter;
31
import java.sql.SQLException;
32
import java.util.Enumeration;
33
import java.util.Hashtable;
34
import java.util.Timer;
35

  
36
import javax.servlet.ServletConfig;
37
import javax.servlet.ServletContext;
38
import javax.servlet.ServletException;
39
import javax.servlet.http.HttpServlet;
40
import javax.servlet.http.HttpServletRequest;
41
import javax.servlet.http.HttpServletResponse;
42
import javax.servlet.http.HttpSession;
43

  
44
import org.apache.log4j.Logger;
45
import org.apache.log4j.PropertyConfigurator;
46

  
47
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
48
import edu.ucsb.nceas.metacat.properties.PropertyService;
49
import edu.ucsb.nceas.metacat.scheduler.SchedulerService;
50
import edu.ucsb.nceas.metacat.service.ServiceService;
51
import edu.ucsb.nceas.metacat.service.SessionService;
52
import edu.ucsb.nceas.metacat.shared.BaseException;
53
import edu.ucsb.nceas.metacat.shared.ServiceException;
54
import edu.ucsb.nceas.metacat.util.ErrorSendingErrorException;
55
import edu.ucsb.nceas.metacat.util.RequestUtil;
56
import edu.ucsb.nceas.metacat.util.ResponseUtil;
57
import edu.ucsb.nceas.metacat.util.SessionData;
58
import edu.ucsb.nceas.utilities.FileUtil;
59

  
60
/**
61
 * A workflow scheduling server implemented as a Java Servlet
62
 *
63
 * Valid actions are:
64
 * 
65
 * action=scheduleWorkflow -- Schedule a workflow to be run.  Scheduling a workflow 
66
 *                            registers it with the scheduling engine and creates a row
67
 *                            in the scheduled_job table.  Note that this may be 
68
 *                            extracted into a separate servlet.
69
 *     delay -- The amount of time from now before the workflow should be run.  The 
70
 *              delay can be expressed in number of seconds, minutes, hours and days, 
71
 *              for instance 30s, 2h, etc.
72
 *     starttime -- The time that the workflow should first run.  If both are provided
73
 *                  this takes precedence over delay.  The time should be expressed as: 
74
 *                  MM/dd/yyyy HH:mm:ss with the timezone assumed to be that of the OS.
75
 *     endtime -- The time when the workflow should end. The time should be expressed as: 
76
 *                  MM/dd/yyyy HH:mm:ss with the timezone assumed to be that of the OS.
77
 *     intervalvalue -- The numeric value of the interval between runs
78
 *     intervalunit -- The unit of the interval between runs.  Can be s, m, h, d for 
79
 *                     seconds, minutes, hours and days respectively
80
 *     workflowid -- The lsid of the workflow that we want to schedule.  This workflow
81
 *                   must already exist in the database.
82
 *     karid -- The karid for the workflow that we want to schedule.
83
 *     workflowname -- The name of the workflow.
84
 *     forwardto -- If provided, forward to this page when processing is done.
85
 *     qformat -- If provided, render results using the stylesheets associated with
86
 *                this skin.  Default is xml.
87
 * action=unscheduleWorkflow -- Unschedule a workflow.  Unscheduling a workflow 
88
 *                            removes it from the scheduling engine and changes the 
89
 *                            status in the scheduled_job table to " unscheduled.  Note 
90
 *                            that this may be extracted into a separate servlet.
91
 *     workflowjobid -- The job ID for the workflow run that we want to unschedule.  This
92
 *                      is held in the database as scheduled_job.name
93
 *     forwardto -- If provided, forward to this page when processing is done.
94
 *     qformat -- If provided, render results using the stylesheets associated with
95
 *                this skin.  Default is xml.
96
 * action=rescheduleWorkflow -- Unschedule a workflow.  Rescheduling a workflow 
97
 *                            registers it with the scheduling engine and changes the 
98
 *                            status in the scheduled_job table to " scheduled.  Note 
99
 *                            that this may be extracted into a separate servlet.
100
 *     workflowjobid -- The job ID for the workflow run that we want to reschedule.  This
101
 *                      is held in the database as scheduled_job.name
102
 *     forwardto -- If provided, forward to this page when processing is done.
103
 *     qformat -- If provided, render results using the stylesheets associated with
104
 *                this skin.  Default is xml.
105
 * action=deleteScheduledWorkflow -- Delete a workflow.  Deleting a workflow 
106
 *                            removes it from the scheduling engine and changes the 
107
 *                            status in the scheduled_job table to " deleted.  Note 
108
 *                            that this may be extracted into a separate servlet.
109
 *     workflowjobid -- The job ID for the workflow run that we want to delete.  This
110
 *                      is held in the database as scheduled_job.name
111
 *     forwardto -- If provided, forward to this page when processing is done.
112
 *     qformat -- If provided, render results using the stylesheets associated with
113
 *                this skin.  Default is xml.
114
 *     
115
 */
116
public class WorkflowSchedulerServlet extends HttpServlet {
117

  
118
	private static final long serialVersionUID = 1L;
119

  
120
	private Timer timer = null;
121
    
122
    // Constants -- these should be final in a servlet
123
    private static String LOG_CONFIG_NAME = null;
124
    
125
    public static final String APPLICATION_NAME = "workflowscheduler";
126
    
127
    /**
128
     * Initialize the servlet by creating appropriate database connections
129
     */
130
    public void init(ServletConfig config) throws ServletException {
131
    	Logger logMetacat = Logger.getLogger(WorkflowSchedulerServlet.class);
132
    	try {
133
    		
134
            super.init(config);
135
            
136
            ServletContext context = config.getServletContext();
137
            context.setAttribute("APPLICATION_NAME", APPLICATION_NAME);
138
            
139
            // Initialize the properties file
140
            String dirPath = context.getRealPath("./WEB-INF");
141
            
142
            LOG_CONFIG_NAME = dirPath + FileUtil.getFS() + "log4j.properties";
143
        	PropertyConfigurator.configureAndWatch(LOG_CONFIG_NAME);
144
            
145
            PropertyService.getInstance(context);
146
            SessionService.getInstance();
147
            SchedulerService.getInstance();
148
            
149
			// initialize DBConnection pool
150
			DBConnectionPool connPool = DBConnectionPool.getInstance();
151
			logMetacat.debug("DBConnection pool initialized: " + connPool.toString());
152
            
153
    	} catch (ServiceException se) {
154
        	String errorMessage = 
155
        		"Service problem while intializing WorkflowScheduler Servlet: " + se.getMessage();
156
            logMetacat.error(errorMessage);
157
            throw new ServletException(errorMessage);
158
        } catch (SQLException e) {
159
			String errorMessage = "SQL problem while intializing MetaCat Servlet: "
160
					+ e.getMessage();
161
			logMetacat.error(errorMessage);
162
			throw new ServletException(errorMessage);
163
        } 
164
    }
165
    
166
    /**
167
	 * Close all db connections from the pool
168
	 */
169
    public void destroy() {
170
    	Logger logMetacat = Logger.getLogger(WorkflowSchedulerServlet.class);
171
    	
172
    	ServiceService.stopAllServices();
173
    	
174
        // Close all db connection
175
        logMetacat.warn("Destroying WorkflowSchedulerServlet");
176
        timer.cancel();
177
//        IndexingQueue.getInstance().setMetacatRunning(false);
178
        DBConnectionPool.release();
179
    }
180
    
181
    /** Handle "GET" method requests from HTTP clients */
182
    public void doGet(HttpServletRequest request, HttpServletResponse response)
183
    throws ServletException, IOException {
184
        
185
        // Process the data and send back the response
186
        handleGetOrPost(request, response);
187
    }
188
    
189
    /** Handle "POST" method requests from HTTP clients */
190
    public void doPost(HttpServletRequest request, HttpServletResponse response)
191
    throws ServletException, IOException {
192
        
193
        // Process the data and send back the response
194
        handleGetOrPost(request, response);
195
    }
196
    
197
    /**
198
	 * Control servlet response depending on the action parameter specified
199
	 */
200
	private void handleGetOrPost(HttpServletRequest request, HttpServletResponse response)
201
			throws ServletException, IOException {
202
		Logger logMetacat = Logger.getLogger(WorkflowSchedulerServlet.class);
203

  
204
		// Update the last update time for this user if they are not new
205
		HttpSession httpSession = request.getSession(false);
206
		if (httpSession != null) {
207
			SessionService.touchSession(httpSession.getId());
208
		}
209

  
210
		/*
211
		 * logMetacat.debug("Connection pool size: "
212
		 * +connPool.getSizeOfDBConnectionPool(),10); logMetacat.debug("Free
213
		 * DBConnection number: "
214
		 */
215
		// If all DBConnection in the pool are free and DBConnection pool
216
		// size is greater than initial value, shrink the connection pool
217
		// size to initial value
218
		DBConnectionPool.shrinkDBConnectionPoolSize();
219

  
220
		// Debug message to print out the method which have a busy DBConnection
221
		try {
222
			DBConnectionPool pool = DBConnectionPool.getInstance();
223
			pool.printMethodNameHavingBusyDBConnection();
224
		} catch (SQLException sqle) {
225
			logMetacat.error("WorkflowSchedulerServlet.handleGetOrPost - error getting DBConnectionPool: "
226
					+ sqle.getMessage());
227
			sqle.printStackTrace();
228
		}
229

  
230
		try {
231

  
232
			String name = null;
233
			String[] value = null;
234
			Hashtable<String, String[]> params = new Hashtable<String, String[]>();
235

  
236
			Enumeration<String> paramlist = 
237
				(Enumeration<String>) request.getParameterNames();
238
			while (paramlist.hasMoreElements()) {
239

  
240
				name = paramlist.nextElement();
241
				value = request.getParameterValues(name);
242

  
243
				params.put(name, value);
244
			}
245

  
246
			// handle param is emptpy
247
			if (params.isEmpty() || params == null) {
248
				return;
249
			}
250

  
251
			// if the user clicked on the input images, decode which image
252
			// was clicked then set the action.
253
			if (params.get("action") == null) {
254
				PrintWriter out = response.getWriter();
255
				response.setContentType("text/xml");
256
				out.println("<?xml version=\"1.0\"?>");
257
				out.println("<error>");
258
				out.println("Action not specified");
259
				out.println("</error>");
260
				out.close();
261
				return;
262
			}
263

  
264
			String action = (params.get("action"))[0];
265
			logMetacat.info("WorkflowSchedulerServlet.handleGetOrPost - Action is: " + action);
266

  
267
			// This block handles session management for the servlet
268
			// by looking up the current session information for all actions
269
			// other than "login" and "logout"
270
			String userName = null;
271
			String[] groupNames = null;
272
			name = null;
273

  
274
			// handle login action
275
			if (action.equals("login")) {
276
				// PrintWriter out = response.getWriter();
277
				// handleLoginAction(out, params, request, response);
278
				// out.close();
279

  
280
				// handle logout action
281
			} else if (action.equals("logout")) {
282
				// PrintWriter out = response.getWriter();
283
				// handleLogoutAction(out, params, request, response);
284
				// out.close();
285

  
286
				// handle shrink DBConnection request
287
			} else if (action.equals("shrink")) {
288
				PrintWriter out = response.getWriter();
289
				boolean success = false;
290
				// If all DBConnection in the pool are free and DBConnection
291
				// pool
292
				// size is greater than initial value, shrink the connection
293
				// pool
294
				// size to initial value
295
				success = DBConnectionPool.shrinkConnectionPoolSize();
296
				if (success) {
297
					// if successfully shrink the pool size to initial value
298
					out.println("DBConnection Pool shrunk successfully.");
299
				}// if
300
				else {
301
					out.println("DBConnection pool not shrunk successfully.");
302
				}
303
				// close out put
304
				out.close();
305

  
306
				// aware of session expiration on every request
307
			} else {
308
				SessionData sessionData = RequestUtil.getSessionData(request);
309

  
310
				userName = sessionData.getUserName();
311
				// password = sessionData.getPassword();
312
				groupNames = sessionData.getGroupNames();
313
				// sessionId = sessionData.getId();
314

  
315
				logMetacat.info("WorkflowSchedulerServlet.handleGetOrPost - The user is : " + userName);
316
			}
317

  
318
			if (action.equals("scheduleWorkflow")) {
319
				try {
320
					WorkflowScheduler.getInstance().scheduleJob(request, response,
321
							params, userName, groupNames);
322
					return;
323
				} catch (BaseException be) {
324
					logMetacat.error("WorkflowSchedulerServlet.handleGetOrPost - error when scheduling" 
325
							+ "workflow", be);
326
					ResponseUtil.sendErrorXML(response,
327
							ResponseUtil.SCHEDULE_WORKFLOW_ERROR, be);
328
					return;
329
				}
330
			} else if (action.equals("unscheduleWorkflow")) {
331
				try {
332
					WorkflowScheduler.getInstance().unScheduleJob(request, response,
333
							params, userName, groupNames);
334
					return;
335
				} catch (BaseException be) {
336
					logMetacat.error("WorkflowSchedulerServlet.handleGetOrPost - error when unscheduling" 
337
							+ "workflow", be);
338
					ResponseUtil.sendErrorXML(response,
339
							ResponseUtil.UNSCHEDULE_WORKFLOW_ERROR, be);
340
					return;
341
				}
342
			} else if (action.equals("rescheduleWorkflow")) {
343
				try {
344
					WorkflowScheduler.getInstance().reScheduleJob(request, response,
345
							params, userName, groupNames);
346
					return;
347
				} catch (BaseException be) {
348
					logMetacat.error("WorkflowSchedulerServlet.handleGetOrPost - error when rescheduling" 
349
							+ "workflow", be);
350
					ResponseUtil.sendErrorXML(response,
351
							ResponseUtil.RESCHEDULE_WORKFLOW_ERROR, be);
352
					return;
353
				}
354
			} else if (action.equals("getScheduledWorkflow")) {
355
				try {
356
					WorkflowScheduler.getInstance().getJobs(request, response, params,
357
							userName, groupNames);
358
					return;
359
				} catch (BaseException be) {
360
					logMetacat.error("WorkflowSchedulerServlet.handleGetOrPost - error when getting" 
361
							+ "scheduled workflows", be);
362
					ResponseUtil.sendErrorXML(response,
363
							ResponseUtil.GET_SCHEDULED_WORKFLOW_ERROR, be);
364
					return;
365
				}
366
			} else if (action.equals("deleteScheduledWorkflow")) {
367
				try {
368
					WorkflowScheduler.getInstance().deleteJob(request, response, params,
369
							userName, groupNames);
370
					return;
371
				} catch (BaseException be) {
372
					logMetacat.error("WorkflowSchedulerServlet.handleGetOrPost - error when deleting" 
373
							+ "workflow", be);
374
					ResponseUtil.sendErrorXML(response,
375
							ResponseUtil.DELETE_SCHEDULED_WORKFLOW_ERROR, be);
376
					return;
377
				}
378
			} else {
379
				logMetacat.error("WorkflowSchedulerServlet.handleGetOrPost - unregistered action: " 
380
						+ action);
381
				PrintWriter out = response.getWriter();
382
				out.println("<?xml version=\"1.0\"?>");
383
				out.println("<error>");
384
				out.println("Error: action not registered.  Please report this error.");
385
				out.println("</error>");
386
				out.close();
387
			}
388
		} catch (ErrorSendingErrorException esee) {
389
			String errorString = "WorkflowSchedulerServlet.handleGetOrPost - Error sending error message: " + esee.getMessage();
390
			logMetacat.error(errorString);
391
			throw new ServletException(errorString);
392
		}
393
	}
394
    
395
// // LOGIN & LOGOUT SECTION
396
// /**
397
// * Handle the login request. Create a new session object. Do user
398
//	 * authentication through the session.
399
//	 */
400
//    private void handleLoginAction(PrintWriter out, Hashtable<String, String[]> params,
401
//            HttpServletRequest request, HttpServletResponse response) {
402
//        Logger logMetacat = Logger.getLogger(WorkflowSchedulerServlet.class);
403
//        AuthSession sess = null;
404
//        
405
//        if(params.get("username") == null){
406
//            response.setContentType("text/xml");
407
//            out.println("<?xml version=\"1.0\"?>");
408
//            out.println("<error>");
409
//            out.println("Username not specified");
410
//            out.println("</error>");
411
//            return;
412
//        }
413
//        
414
//        // }
415
//        
416
//        if(params.get("password") == null){
417
//            response.setContentType("text/xml");
418
//            out.println("<?xml version=\"1.0\"?>");
419
//            out.println("<error>");
420
//            out.println("Password not specified");
421
//            out.println("</error>");
422
//            return;
423
//        }
424
//        
425
//        String un = (params.get("username"))[0];
426
//        logMetacat.info("user " + un + " is trying to login");
427
//        String pw = (params.get("password"))[0];
428
//        
429
//        String qformat = "xml";
430
//        if(params.get("qformat") != null){
431
//            qformat = (params.get("qformat"))[0];
432
//        }
433
//        
434
//        try {
435
//            sess = new AuthSession();
436
//        } catch (Exception e) {
437
//        	String errorMsg = "Problem in WorkflowSchedulerServlet.handleLoginAction() authenicating session: "
438
//                + e.getMessage();
439
//            logMetacat.error(errorMsg);
440
//            out.println(errorMsg);
441
//            return;
442
//        }
443
//        boolean isValid = sess.authenticate(request, un, pw);
444
//        
445
//        //if it is authernticate is true, store the session
446
//        if (isValid) {
447
//            HttpSession session = sess.getSessions();
448
//            String id = session.getId();
449
//            logMetacat.debug("Store session id " + id
450
//                    + " which has username" + session.getAttribute("username")
451
//                    + " into hash in login method");
452
//            try {
453
//				SessionService.registerSession(id, (String) session
454
//						.getAttribute("username"), (String[]) session
455
//						.getAttribute("groupnames"), (String) session
456
//						.getAttribute("password"));
457
//			} catch (ServiceException se) {
458
//				String errorMsg = "Problem in WorkflowSchedulerServlet.handleLoginAction() registering session: "
459
//						+ se.getMessage();
460
//				logMetacat.error(errorMsg);
461
//				out.println(errorMsg);
462
//				return;
463
//			}
464
//        }
465
//        
466
//        // format and transform the output
467
//        if (qformat.equals("xml")) {
468
//            response.setContentType("text/xml");
469
//            out.println(sess.getMessage());
470
//        } else {
471
//            try {
472
//                DBTransform trans = new DBTransform();
473
//                response.setContentType("text/html");
474
//                trans.transformXMLDocument(sess.getMessage(),
475
//                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
476
//                        out, null, null);
477
//            } catch (Exception e) {               
478
//                logMetacat.error("Error in WorkflowSchedulerServlet.handleLoginAction: "
479
//                        + e.getMessage());
480
//            }
481
//        }
482
//    }
483
//    
484
//    /**
485
//     * Handle the logout request. Close the connection.
486
//     */
487
//    private void handleLogoutAction(PrintWriter out, Hashtable<String, String[]> params,
488
//            HttpServletRequest request, HttpServletResponse response) {
489
//        Logger logMetacat = Logger.getLogger(WorkflowSchedulerServlet.class);
490
//        String qformat = "xml";
491
//        if(params.get("qformat") != null){
492
//            qformat = params.get("qformat")[0];
493
//        }
494
//        
495
//        // close the connection
496
//        HttpSession sess = request.getSession(false);
497
//        logMetacat.info("After get session in logout request");
498
//        if (sess != null) {
499
//            logMetacat.info("The session id " + sess.getId()
500
//            + " will be invalidate in logout action");
501
//            logMetacat.info("The session contains user "
502
//                    + sess.getAttribute("username")
503
//                    + " will be invalidate in logout action");
504
//            sess.invalidate();
505
//            SessionService.unRegisterSession(sess.getId());
506
//        }
507
//        
508
//        // produce output
509
//        StringBuffer output = new StringBuffer();
510
//        output.append("<?xml version=\"1.0\"?>");
511
//        output.append("<logout>");
512
//        output.append("User logged out");
513
//        output.append("</logout>");
514
//        
515
//        //format and transform the output
516
//        if (qformat.equals("xml")) {
517
//            response.setContentType("text/xml");
518
//            out.println(output.toString());
519
//        } else {
520
//            try {
521
//                DBTransform trans = new DBTransform();
522
//                response.setContentType("text/html");
523
//                trans.transformXMLDocument(output.toString(),
524
//                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
525
//                        out, null, null);
526
//            } catch (Exception e) {
527
//                logMetacat.error(
528
//                        "Error in WorkflowSchedulerServlet.handleLogoutAction"
529
//                        + e.getMessage());
530
//            }
531
//        }
532
//    }
533
}
0 534

  

Also available in: Unified diff