Project

General

Profile

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.metacat.workflow;
28

    
29
import java.io.IOException;
30
import java.text.SimpleDateFormat;
31
import java.text.ParseException;
32
import java.util.Calendar;
33
import java.util.Date;
34
import java.util.Hashtable;
35
import java.util.HashMap;
36

    
37
import javax.servlet.http.HttpServletRequest;
38
import javax.servlet.http.HttpServletResponse;
39
import javax.servlet.ServletException;
40

    
41
import org.apache.log4j.Logger;
42

    
43
import edu.ucsb.nceas.metacat.MetaCatServlet;
44
import edu.ucsb.nceas.metacat.scheduler.BaseScheduler;
45
import edu.ucsb.nceas.metacat.scheduler.ScheduledJobAccess;
46
import edu.ucsb.nceas.metacat.scheduler.ScheduledJobDAO;
47
import edu.ucsb.nceas.metacat.scheduler.ScheduledJobParamDAO;
48
import edu.ucsb.nceas.metacat.scheduler.SchedulerService;
49
import edu.ucsb.nceas.metacat.scheduler.MetacatSchedulerException;
50
import edu.ucsb.nceas.metacat.service.ServiceException;
51
import edu.ucsb.nceas.metacat.util.ErrorSendingErrorException;
52
import edu.ucsb.nceas.metacat.util.ResponseUtil;
53
import edu.ucsb.nceas.metacat.util.RequestUtil;
54
import edu.ucsb.nceas.shared.AccessException;
55

    
56
/**
57
 * @author daigle
58
 *
59
 */
60
/**
61
 * @author daigle
62
 *
63
 */
64
public class WorkflowScheduler extends BaseScheduler {
65
	
66
	private static WorkflowScheduler workflowScheduler = null;
67
	
68
	private static Logger logMetacat = Logger.getLogger(WorkflowScheduler.class);
69
	
70
	private static String WORKFLOW_JOB_GROUP = "workflow";
71
	private static String WORKFLOW_JOB_CLASS = "edu.ucsb.nceas.metacat.workflow.WorkflowJob";
72

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

    
113
		try {
114
			SchedulerService schedulerService = SchedulerService.getInstance();
115

    
116
			// get start time or delay.  Start time takes precidence if both exist.
117
			if (startTimes != null && startTimes.length > 0) {
118
				SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z");
119
				Date startDate = dateFormat.parse(startTimes[0]);
120
				startCal = Calendar.getInstance();
121
				startCal.setTime(startDate);
122
			} else if (delays != null && delays.length > 0) {
123
				startCal = schedulerService.getStartDateFromDelay(delays[0]);
124
			} else {
125
				// if delay and starttime were not provided, set date to now.
126
				startCal = Calendar.getInstance();
127
			}
128

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

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

    
171
			String jobName = WORKFLOW_JOB_GROUP
172
					+ Calendar.getInstance().getTimeInMillis();
173

    
174
			// Schedule the job
175
			String xmlResult = schedulerService.scheduleJob(jobName, startCal, intervalValue, intervalUnit,
176
					WORKFLOW_JOB_CLASS, WORKFLOW_JOB_GROUP, jobParams, username, groups);
177

    
178
			// if there is a forwardto param on the request, then send the user to the page
179
			// referenced in that param, otherwise, just send the xml back.
180
			String forwardtos[] = params.get("forwardto");
181
			String forwardto = null;
182
			if (forwardtos != null && forwardtos.length > 0) {
183
				forwardto = forwardtos[0];
184
			}
185
			
186
			if (forwardto != null) {
187
				String qformats[] = params.get("qformat");
188
				String qformat = null;
189
				if (qformats != null && qformats.length > 0) {
190
					qformat = qformats[0];
191
				}
192
				
193
				String destination = "/style/skins/" + qformat + "/" + forwardto
194
					+ "?workflowid=" + jobParams.get("workflowid");			
195
				RequestUtil.forwardRequest(request, response, destination.toString());
196
			} else {
197
				ResponseUtil.sendSuccessXML(response, xmlResult);
198
			}
199
			
200
		} catch (ParseException pe) {
201
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - Could not " + "schedule job  : " 
202
					+ pe.getMessage());
203
		} catch (ServiceException se) {
204
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - Service issue scheduling job", se);
205
		} catch (IOException ioe) {
206
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - I/O issue scheduling job: " + ioe.getMessage());
207
		} catch (ServletException se) {
208
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - Servlet issue scheduling job: " + se.getMessage());
209
		} catch (ErrorSendingErrorException esee) {
210
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - Issue sending erro when scheduling job: " + esee.getMessage());			
211
		}
212
	}
213
	
214
	/**
215
	 * Unschedule a job
216
	 * 
217
	 * @param request
218
	 *            the servlet request object
219
	 * @param response
220
	 *            the servlet response object
221
	 * @param params
222
	 *            the request parameters
223
	 * @param username
224
	 *            the user
225
	 * @param groups
226
	 *            the user's group
227
	 */
228
	public void unScheduleJob(HttpServletRequest request, HttpServletResponse response,
229
			Hashtable<String, String[]> params, String username, String[] groups)
230
			throws MetacatSchedulerException {
231
		try {
232
			// workflow job id must exist
233
			String jobNames[] = params.get("workflowjobid");
234
			if (jobNames == null || jobNames.length == 0) {
235
				throw new MetacatSchedulerException("SchedulerService.unScheduleJob - workflowjobid " 
236
						+ "field must be populated in scheduler parameters when unscheduling job.");
237
			}
238
			String jobName = jobNames[0];
239

    
240
			// unschedule the job
241
			SchedulerService schedulerService = SchedulerService.getInstance();
242
			String xmlResult = schedulerService.unScheduleJob(jobName, username, groups);
243
			
244
			
245
			String forwardtos[] = params.get("forwardto");
246
			String forwardto = null;
247
			if (forwardtos != null && forwardtos.length > 0) {
248
				forwardto = forwardtos[0];
249
			}
250
			
251
			// if there is a forwardto param on the request, then send the user to the page
252
			// referenced in that param, otherwise, just send the xml back.
253
			if (forwardto != null) {
254
				String qformats[] = params.get("qformat");
255
				String qformat = null;
256
				if (qformats != null && qformats.length > 0) {
257
					qformat = qformats[0];
258
				}
259
				
260
				ScheduledJobAccess jobAccess = new ScheduledJobAccess();
261
				ScheduledJobDAO jobDAO = jobAccess.getJobByName(jobName);
262
				
263
				// we need to include the workflow id in the forward url
264
				String workflowId = null;
265
				ScheduledJobParamDAO jobParamDAO = jobDAO.getJobParam("workflowid");
266
				if (jobParamDAO != null) {
267
					workflowId = jobParamDAO.getValue();
268
				}				 
269
				
270
				String destination = "/style/skins/" + qformat + "/" + forwardto
271
					+ "?workflowid=" + workflowId;			
272
				RequestUtil.forwardRequest(request, response, destination.toString());
273
			} else {
274
				ResponseUtil.sendSuccessXML(response, xmlResult);
275
			}
276
			ResponseUtil.sendSuccessXML(response, xmlResult);
277
		} catch (ServiceException se) {
278
			throw new MetacatSchedulerException(
279
					"WorkflowScheduler.unScheduleJob - Service issue unscheduling job",
280
					se);
281
		} catch (Exception e) {
282
			throw new MetacatSchedulerException(
283
					"WorkflowScheduler.unScheduleJob - Generic issue unscheduling job: "
284
							+ e.getMessage());
285
		}
286
	}
287
	
288
	/**
289
	 * reschedule job
290
	 * 
291
	 * @param request
292
	 *            the servlet request object
293
	 * @param response
294
	 *            the servlet response object
295
	 * @param params
296
	 *            the request parameters
297
	 * @param username
298
	 *            the user
299
	 * @param groups
300
	 *            the user's group
301
	 */
302
	public void reScheduleJob(HttpServletRequest request, HttpServletResponse response, 
303
			Hashtable<String, String[]> params, String username,
304
			String[] groups) throws MetacatSchedulerException {
305
		 		
306
		try {
307
			// workflow job id must exist
308
			String jobNames[] = params.get("workflowjobid");	
309
			if (jobNames == null || jobNames.length == 0) {
310
				throw new MetacatSchedulerException("WorkflowScheduler.reScheduleJob - workflowjobid field must be populated "
311
						+ "in scheduler parameters when rescheduling job.");
312
			}			
313
			String jobName = jobNames[0];
314
	
315
			ScheduledJobAccess jobAccess = new ScheduledJobAccess();
316
			ScheduledJobDAO jobDAO = jobAccess.getJobByName(jobName);
317
			
318
			// reschedule the job
319
			SchedulerService schedulerService = SchedulerService.getInstance();
320
			String result = schedulerService.rescheduleJob(jobDAO, username, groups);
321

    
322
			// if there is a forwardto param on the request, then send the user to the page
323
			// referenced in that param, otherwise, just send the xml back.
324
			String forwardtos[] = params.get("forwardto");
325
			String forwardto = null;
326
			if (forwardtos != null && forwardtos.length > 0) {
327
				forwardto = forwardtos[0];
328
			}
329
			
330
			if (forwardto != null) {
331
				String qformats[] = params.get("qformat");
332
				String qformat = null;
333
				if (qformats != null && qformats.length > 0) {
334
					qformat = qformats[0];
335
				}
336
				
337
				// we need to include the workflow id in the forward url
338
				String workflowId = null;
339
				ScheduledJobParamDAO jobParamDAO = jobDAO.getAllJobParams().get("workflowid");
340
				if (jobParamDAO != null) {
341
					workflowId = jobParamDAO.getValue();
342
				}
343
				
344
				String destination = "/style/skins/" + qformat + "/" + forwardto
345
					+ "?workflowid=" + workflowId;			
346
				RequestUtil.forwardRequest(request, response, destination.toString());
347
			} else {
348
				ResponseUtil.sendSuccessXML(response, result);
349
			}
350
			
351
		} catch (AccessException ae) {
352
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - DB access issue when scheduling job  : ", ae);
353
		} catch (ServiceException se) {
354
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - Service issue scheduling job", se);
355
		} catch (IOException ioe) {
356
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - I/O issue scheduling job: " + ioe.getMessage());
357
		} catch (ServletException se) {
358
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - Servlet issue scheduling job: " + se.getMessage());
359
		} catch (ErrorSendingErrorException esee) {
360
			throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - Issue sending erro when scheduling job: " + esee.getMessage());			
361
		}
362
	}
363
	
364
	/**
365
	 * delete job - to be implemented
366
	 */
367
	public void deleteJob(HttpServletRequest request, HttpServletResponse response, 
368
			Hashtable<String, String[]> params, String username, String[] groups) throws MetacatSchedulerException {
369
		
370
	}
371
	
372
	/**
373
	 * get job information for a given workflow in xml format
374
	 * 
375
	 * @param request
376
	 *            the servlet request object
377
	 * @param response
378
	 *            the servlet response object
379
	 * @param params
380
	 *            the request parameters
381
	 * @param username
382
	 *            the user
383
	 * @param groups
384
	 *            the user's group
385
	 */
386
	public void getJobs(HttpServletRequest request, HttpServletResponse response, 
387
			Hashtable<String, String[]> params, String username, String[] groups) throws MetacatSchedulerException {
388
		
389
		String workFlowId = null;
390
		String qformat = "";
391
		
392
		String workFlowIds[] = params.get("workflowid");
393
		if (workFlowIds != null && workFlowIds.length != 0) {
394
			workFlowId = workFlowIds[0];
395
		}
396
		
397
        if (params.containsKey("qformat")) {
398
            qformat = params.get("qformat")[0];
399
        }
400
		
401
		try {
402
			// get the job info in xml format
403
			String xmlResult = SchedulerService.getInstance().getJobsInfoXML(WORKFLOW_JOB_GROUP, "workflowid", workFlowId);
404
			logMetacat.debug("WorkflowScheduler.getJobs - xmlResult: " + xmlResult);
405
			
406
			if (qformat == null || qformat.equals(MetaCatServlet.XMLFORMAT)) {
407
				ResponseUtil.send(response, xmlResult);
408
			} else {				
409
				ResponseUtil.transformAndSendXML(response, xmlResult, "-//NCEAS//scheduledWorkflowResultset//EN", 
410
					"-//W3C//HTML//EN", qformat, params);
411
			}
412
		} catch (ServiceException se) {
413
			throw new MetacatSchedulerException("WorkflowScheduler.getJobs - Service issue getting jobs", se);
414
		} catch (Exception e) {
415
			throw new MetacatSchedulerException("WorkflowScheduler.getJobs - Generic issue getting jobs: " 
416
					+ e.getMessage());
417
		}		
418
	}	
419
}
(2-2/2)