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.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("workflowjobname");
208
			if (jobNames == null || jobNames.length == 0) {
209
				throw new MetacatSchedulerException("SchedulerService.unScheduleJob - workflowjobname " 
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("workflowjobname");	
250
			if (jobNames == null || jobNames.length == 0) {
251
				throw new MetacatSchedulerException("WorkflowScheduler.reScheduleJob - workflowjobname 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("workflowjobname");
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
}
(2-2/3)