Project

General

Profile

« Previous | Next » 

Revision 4971

Added by daigle over 15 years ago

Beef up comments

View differences:

lib/style/skins/sanparks/sanparks-scheduled-jobs.css
156 156
	width: 100px;
157 157
}
158 158

  
159
.result-header {
160
	margin-bottom: 5px;
161
}
162

  
159 163
.result-header-emphasis {
160 164
	font-size: 16px;
161 165
	margin-bottom: 5px;
lib/style/skins/sanparks/sanparks-tpc.css
132 132
	font-size: 16px;
133 133
}
134 134

  
135
.result-header {
136
	float: none;
137
}
138

  
135 139
/********************************************************************** 
136 140
 * tpc search result specific settings
137 141
 **********************************************************************/
138 142

  
139 143
.col1 {
140
	width: 280px;
144
	width: 250px;
141 145
	text-align: left;
142 146
	font-weight: bold;
143 147
}
144 148

  
145 149
.col2 {
146
	width: 147px;
150
	width: 130px;
147 151
}
148 152

  
149 153
.col3 {
150
	width: 110px;
154
	width: 100px;
151 155
}
152 156

  
153 157
.col4 {
154
	width: 148px;
158
	width: 190px;
155 159
	border-right: none;
156 160
}
lib/style/common/searchWorkflowSection.jsp
36 36
		<script language="JavaScript" type="text/JavaScript" src="<%=STYLE_COMMON_URL%>/ajax-utils.js"></script>
37 37
        <script language="JavaScript" type="text/JavaScript" src="<%=STYLE_COMMON_URL%>/searchWorkflow.js"></script>   
38 38
    </head>
39
    <body onload="setWorkflowQueryFormField('tpcSearch');getResultsSection('<%=SERVLET_URL%>','tpcSearch','workflow-search-results')">
39
    <body onload="setWorkflowQueryFormField('tpcSearch');submitFormIntoDiv('<%=SERVLET_URL%>','tpcSearch','workflow-search-results')">
40 40
    	<div class=content-section>    
41 41
    		<div class="content-subsection search-section" id="search-section">   
42 42
        		<form name="tpcSearch" id="tpcSearch">
......
56 56
							<option values="workflow-id" onclick="addSearchDropdownBefore('tpcSearch','Workflow-id','workflow-id','co|eq|sw|ew','form-base-row')">Workflow ID</option>
57 57
						</select>    
58 58
        		
59
        				<input class="submit-button" value="Search" type="button" onclick="setWorkflowQueryFormField('tpcSearch');getResultsSection('<%=SERVLET_URL%>','tpcSearch','workflow-search-results')">
59
        				<input class="submit-button" value="Search" type="button" onclick="setWorkflowQueryFormField('tpcSearch');submitFormIntoDiv('<%=SERVLET_URL%>','tpcSearch','workflow-search-results')">
60 60
        			</div> 
61 61
        		</form>
62 62
			</div>
lib/style/common/scheduleWorkflow.js
1
/*
2
 */
3

  
1
 /*
2
  *   '$RCSfile$'
3
  *     Purpose: Basic funtions to support showing the schedule workflows 
4
  *              pages
5
  *   Copyright: 2009 Regents of the University of California and the
6
  *               National Center for Ecological Analysis and Synthesis
7
  *     Authors: Michael Daigle
8
  *
9
  *    '$Author: leinfelder $'
10
  *      '$Date: 2008-06-17 13:16:32 -0700 (Tue, 17 Jun 2008) $'
11
  *  '$Revision: 4006 $'
12
  *
13
  * This program is free software; you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License as published by
15
  * the Free Software Foundation; either version 2 of the License, or
16
  * (at your option) any later version.
17
  *
18
  * This program is distributed in the hope that it will be useful,
19
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
  * GNU General Public License for more details.
22
  *
23
  * You should have received a copy of the GNU General Public License
24
  * along with this program; if not, write to the Free Software
25
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
  */ 
27
  
28
/* puts together the url to get the workflow section of a page given the workflow 
29
 * id.  
30
 *  Params:
31
 *    url - metacat url to hit
32
 *    workflowId - get all runs for this id 
33
 *    workflowName - used for display purposes.  
34
 *    divId - the name of the div where the results should be put
35
 */  
4 36
function getWorkflowRunSection(url, workflowId, workflowName, divId) {
5 37
	var requestUrl = url + '?action=getScheduledWorkflow&workflowid=' + workflowId + '&qformat=sanparks&workflowname=' + workflowName;
6 38
	var submitResults = submitUrlIntoDiv(requestUrl, divId);
7 39
}
8 40

  
9
function showSchedulePage(workflowId, schedulePage, qformat) {
10
	url = document.URL + '/../' + workflowRunPage + '?workflowid=' + workflowId + '?qformat=' + qformat;
11
	//alert('new url: ' + url);
12
	window.location = url;
13
}
14

  
15
function scheduleWorkflowRun(url, workflowId, startTime, interval, karId) {	
16
	requestUrl = 
17
		url + '?action=scheduleWorkflow&starttime=' + startTime 
18
			+ '&interval=' + interval + '&jobparam_karId=' + karId;
19
	//alert('new url: ' + url);
20
	window.location = url;
21
}
22

  
23 41
	
lib/style/common/searchWorkflowRunSection.jsp
37 37
        <script language="JavaScript" type="text/JavaScript" src="<%=STYLE_COMMON_URL%>/searchWorkflowRun.js"></script>
38 38
        
39 39
    </head>
40
    <body onload="setWorkflowQueryFormField('tpcSearch');getResultsSection('<%=SERVLET_URL%>','tpcSearch','workflow-search-results')">    
40
    <body onload="setWorkflowQueryFormField('tpcSearch');submitFormIntoDiv('<%=SERVLET_URL%>','tpcSearch','workflow-search-results')">    
41 41
    	<div class=content-section>    
42 42
    		<div class="content-subsection search-section" id="search-section">   
43 43
        		<form name="tpcSearch" id="tpcSearch">
......
67 67
							<option values="status" onclick="addSearchDropdownBefore('tpcSearch','Status','Status','is|in','form-base-row')">Status</option>
68 68
						</select>    
69 69
        		
70
        				<input class="submit-button" value="Search" type="button" onclick="setWorkflowQueryFormField('tpcSearch');getResultsSection('<%=SERVLET_URL%>','tpcSearch','workflow-search-results')">
70
        				<input class="submit-button" value="Search" type="button" onclick="setWorkflowQueryFormField('tpcSearch');submitFormIntoDiv('<%=SERVLET_URL%>','tpcSearch','workflow-search-results')">
71 71
        			</div> 
72 72
        		</form>
73 73
			</div>
lib/style/common/searchWorkflow.js
1
 /*
2
  *   '$RCSfile$'
3
  *     Purpose: Basic funtions to support searching workflows
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: leinfelder $'
9
  *      '$Date: 2008-06-17 13:16:32 -0700 (Tue, 17 Jun 2008) $'
10
  *  '$Revision: 4006 $'
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

  
1 27
/*
2 28
 * Generate a workflow query string.  this assumes that search fields meet the
3 29
 * following criteria in the web page:
4
 * -- search input fields have an ID that starts with sf_ 
5
 * -- the search input field name is the xpath of the value to search
30
 * -- search input fields have an ID that starts with sf- 
6 31
 * -- if there is a search mode dropdown for an input field in the form, it's ID 
7
 *    should use the same convention as the input field, but start with sm_
8
 *    (i.e. the search mode input for the sf_firstname input would be sm_firstname) 
9
 * -- the value 
32
 *    should use the same convention as the input field, but start with sm-
33
 *    (i.e. the search mode input for the sf-firstname input would be sm-firstname) 
10 34
 */
11
 
12 35
function setWorkflowQueryFormField(formId) {
13 36
	var queryString = ""; 
14 37
	queryString += "<pathquery version='1.2'>";
......
46 69
	queryField.value = queryString;
47 70
}
48 71

  
72
/*
73
 * Generate individual query terms for all the search input fields in a search 
74
 * form.  There must be a case for each search field handle explicitly below.  
75
 * This assumes:
76
 * -- search input fields have an ID that starts with sf- 
77
 * -- if there is a search mode dropdown for an input field in the form, it's ID 
78
 *    should use the same convention as the input field, but start with sm-
79
 *    (i.e. the search mode input for the sf-firstname input would be sm-firstname) 
80
 */
49 81
function getQueryTerm(sfElement) {
50 82
	var baseId = sfElement.id.substring(3, sfElement.id.length);		
51 83
	var searchMode = "contains";
......
115 147
	return pathExpr;
116 148
}
117 149

  
118
function getResultsSection(url, formId, divId) {
119
	var submitResults = submitFormIntoDiv(url, formId, divId);
120
}
121

  
122
function showWorkflowRuns(workflowId, workflowRunPage) {
123
	url = document.URL + '/../' + workflowRunPage + '?workflowid=' + workflowId;
124
	//alert('new url: ' + url);
125
	window.location = url;
126
}
127

  
128 150
	
lib/style/common/scheduledWorkflowResultset.xsl
1 1
<?xml version="1.0"?>
2 2
<!--
3 3
	*  '$RCSfile$'
4
	*      Authors: Matt Jones, CHad Berkley
4
	*      Authors: Michael Daigle
5 5
	*    Copyright: 2009 Regents of the University of California and the
6 6
	*               National Center for Ecological Analysis and Synthesis
7 7
	*  For Details: http://www.nceas.ucsb.edu/
lib/style/common/searchWorkflowResultset.xsl
40 40
	
41 41
		<div class="result-header-section">      
42 42
        	<div class="result-header">TPC Workflows</div>
43
        	<div class="result-header-emphasis">(<xsl:number value="count(resultset/document)" />   
44
        		<xsl:if test="count(resultset/document) != 1"> items</xsl:if>
45
        		<xsl:if test="count(resultset/document) = 1"> item</xsl:if>
46
        	 	found)
47
        	</div>
48 43
		</div>
49 44
		<div class="row row-header" >
50 45
			<div class="col col1">TPC Name</div>
......
86 81
								<xsl:attribute name="href">./scheduleWorkflowRun.jsp?workflowid=<xsl:value-of select='./param[@name="/entity/property[@name=&apos;entityId&apos;]/@value"]' />&amp;karid=<xsl:value-of select='./param[@name="/entity/property[@name=&apos;karLSID&apos;]/@value"]' />&amp;workflowname=<xsl:value-of select='./param[@name="/entity/@name"]' /></xsl:attribute>	 
87 82
									 Schedule
88 83
							</a> 
84
							<span> | </span>
85
							<a>
86
								<xsl:attribute name="class">underlined</xsl:attribute>
87
								<xsl:attribute name="href">
88
									<xsl:value-of select='$contextURL' />/metacat?action=read&amp;docid=<xsl:value-of select='./param[@name="/entity/property[@name=&apos;karLSID&apos;]/@value"]' />
89
								</xsl:attribute>	 
90
									 Download
91
							</a> 
89 92
						</div>		
90 93
					</div>
91 94
				</xsl:if>
lib/style/common/ajax-utils.js
1 1
 /*
2 2
  *   '$RCSfile$'
3
  *     Purpose: Default style sheet for KNP project web pages 
4
  *              Using this stylesheet rather than placing styles directly in 
5
  *              the KNP web documents allows us to globally change the 
6
  *              formatting styles of the entire site in one easy place.
3
  *     Purpose: Basic Ajax utilities
7 4
  *   Copyright: 2009 Regents of the University of California and the
8 5
  *               National Center for Ecological Analysis and Synthesis
9
  *     Authors: Matt Jones
6
  *     Authors: Michael Daigle
10 7
  *
11 8
  *    '$Author: daigle $'
12 9
  *      '$Date: 2008-07-06 21:25:34 -0700 (Sun, 06 Jul 2008) $'
......
27 24
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 25
  */
29 26
 
27
/* submits a form via ajax and inserts the results into the given div  
28
 *  Params:
29
 *    url - url to hit
30
 *    formId - id of the form to submit
31
 *    divId - the name of the div where the results should be put
32
 */  
30 33
function submitFormIntoDiv(url, formId, divId) {
31 34
	//alert('Sending form: ' + formId + " to url: " + url);
32 35
	var formObj = document.getElementById(formId);
......
37 40
		});
38 41
}
39 42

  
43
/* submits a url via ajax and inserts the results into the given div  
44
 *  Params:
45
 *    url - url to hit
46
 *    divId - the name of the div where the results should be put
47
 */  
40 48
function submitUrlIntoDiv(url, divId) {
41 49
	//alert('Sending url: ' + url);
42 50

  
lib/style/common/scheduleWorkflowRunSection.jsp
70 70
<%
71 71
					if (request.getParameter("workflowid") != null) {
72 72
%>
73
						<input name='jobparam_workflowid' value='<%=request.getParameter("workflowid")%>' type='hidden' />
73
						<input name='workflowid' value='<%=request.getParameter("workflowid")%>' type='hidden' />
74 74
<%
75 75
					}
76 76
					if (request.getParameter("karid") != null) {
77 77
%>
78
						<input name='jobparam_karid' value='<%=request.getParameter("karid")%>' type='hidden' />
78
						<input name='karid' value='<%=request.getParameter("karid")%>' type='hidden' />
79 79
<%
80 80
					}
81 81
					if (request.getParameter("workflowname") != null) {
82 82
%>
83
						<input name='jobparam_workflowname' value='<%=request.getParameter("workflowname")%>' type='hidden' />
83
						<input name='workflowname' value='<%=request.getParameter("workflowname")%>' type='hidden' />
84 84
<%
85 85
					}
86 86
%>	  		 
lib/style/common/searchWorkflowRun.js
18 18
	queryString += "<returnfield>/property[@name=\'WorkflowRun\']/property[@name=\'description\']/@value</returnfield>";
19 19
	queryString += "<returnfield>/property[@name=\'WorkflowRun\']/property[@name=\'startTime\']/@value</returnfield>";
20 20
	queryString += "<returnfield>/property[@name=\'WorkflowRun\']/property[@name=\'workflowLSID\']/@value</returnfield>";
21
	queryString += "<returnfield>/property[@name=\'WorkflowRun\']/property[@name=\'status\']/@value</returnfield>";
21
	queryString += "<returnfield>/property[@name=\'WorkflowRun\']/property[@name=\'tpcStatus\']/@value</returnfield>";
22 22
	queryString += "<returnfield>/property[@name=\'WorkflowRun\']/property[@name=\'workflowName\']/@value</returnfield>";
23 23
	queryString += "<returnfield>/property[@name=\'WorkflowRun\']/property[@name=\'pdfReport\']/@value</returnfield>";
24 24
	queryString += "<returnfield>/property[@name=\'WorkflowRun\']/property[@name=\'htmlReport\']/@value</returnfield>";
......
45 45
	queryField.value = queryString;
46 46
}
47 47

  
48
/*
49
 * Generate individual query terms for all the search input fields in a search 
50
 * form.  There must be a case for each search field handle explicitly below.  
51
 * This assumes:
52
 * -- search input fields have an ID that starts with sf- 
53
 * -- if there is a search mode dropdown for an input field in the form, it's ID 
54
 *    should use the same convention as the input field, but start with sm-
55
 *    (i.e. the search mode input for the sf-firstname input would be sm-firstname) 
56
 */
48 57
function getQueryTerm(sfElement) {
49 58
	var baseId = sfElement.id.substring(3, sfElement.id.length);		
50 59
	var searchMode = "contains";
......
94 103
		pathExpr += "<value>workflowLSID</value>";
95 104
		pathExpr += "<pathexpr>property/property/@name</pathexpr>";
96 105
		pathExpr += "</queryterm>"; 
97
		pathExpr += "<queryterm casesensitive='false' searchmode='" + searchMode + "'>";
98
		pathExpr += "<value>" + sfElement.value + "</value>";
99
		pathExpr += "<pathexpr>property/property/@value</pathexpr>";
100
		pathExpr += "</queryterm>";		
106
//		pathExpr += "<queryterm casesensitive='false' searchmode='" + searchMode + "'>";
107
//		pathExpr += "<value>" + sfElement.value + "</value>";
108
//		pathExpr += "<pathexpr>property/property/@value</pathexpr>";
109
//		pathExpr += "</queryterm>";		
101 110
	} else if (sfElement.name == 'workflow-run-id') {
102 111
		pathExpr += "<queryterm casesensitive='false' searchmode='" + searchMode + "'>";
103 112
		pathExpr += "<value>" + sfElement.value + "</value>";
......
114 123
	return pathExpr;
115 124
}
116 125

  
117
function getResultsSection(url, formId, divId) {
118
	var submitResults = submitFormIntoDiv(url, formId, divId);
119
}
120

  
121
function showWorkflowRuns(workflowId, workflowRunPage) {
122
	url = document.URL + '/../' + workflowRunPage + '?workflowid=' + workflowId;
123
	//alert('new url: ' + url);
124
	window.location = url;
125
}
126

  
127 126
	
lib/style/common/searchWorkflowRunResultset.xsl
39 39
	<xsl:template match="/">  
40 40
		<div class="result-header-section">      
41 41
        	<div class="result-header">TPC Workflow Runs</div>
42
        	<div class="result-header-emphasis">(<xsl:number value="count(resultset/document)" />
43
				<xsl:if test="count(resultset/document) != 1"> items</xsl:if>
44
        		<xsl:if test="count(resultset/document) = 1"> item</xsl:if> 
45
        		found)
46
        	</div>
47 42
		</div>
48 43
		<div class="row row-header" >
49 44
			<div class="col col1">TPC Workflow Name</div>
......
68 63
					</div>
69 64
					<div class="col col2">	
70 65
						<xsl:choose>
71
						<xsl:when  test="not(./param[@name=&quot;/property[@name=&apos;WorkflowRun&apos;]/property[@name=&apos;status&apos;]/@value&quot;])" >
66
						<xsl:when  test="not(./param[@name=&quot;/property[@name=&apos;WorkflowRun&apos;]/property[@name=&apos;tpcStatus&apos;]/@value&quot;])" >
72 67
							unknown
73 68
						</xsl:when>
74 69
						<xsl:otherwise>
75
							<xsl:value-of select='./param[@name="/property[@name=&apos;WorkflowRun&apos;]/property[@name=&apos;status&apos;]/@value"]' />	
70
							<xsl:value-of select='./param[@name="/property[@name=&apos;WorkflowRun&apos;]/property[@name=&apos;tpcStatus&apos;]/@value"]' />	
76 71
						</xsl:otherwise>
77 72
						</xsl:choose>
78 73
					</div>
src/edu/ucsb/nceas/metacat/workflow/WorkflowJob.java
42 42
public class WorkflowJob implements InterruptableJob {
43 43
	
44 44
	private static Logger logMetacat = Logger.getLogger(WorkflowJob.class);
45
	
45
    	
46
	/**
47
	 * Required method that is called when the job is run by the scheduler.
48
	 * 
49
	 * @param executionContext
50
	 *            the context information for this job
51
	 */
46 52
	public void execute(JobExecutionContext executionContext) throws JobExecutionException {
47 53
		try {
54
			// have to be able to get the job detail
48 55
			JobDetail jobDetail = executionContext.getJobDetail();
49 56
			if (jobDetail == null) {
50 57
				throw new JobExecutionException("WorkflowJob.execute - Could not get job detail from execution context"); 
51 58
			}
52 59
			
60
			// have to be able to get the job data map from the job detail
53 61
			JobDataMap jobDataMap = jobDetail.getJobDataMap();
54 62
			if (jobDataMap == null) {
55 63
				throw new JobExecutionException("WorkflowJob.execute - Could not get job data map from job detail"); 
56 64
			}
57 65
			
66
			// the kar lsid must be part of the job data map
58 67
			String karLSID = jobDataMap.getString("karid");
59 68
			if (karLSID == null) {
60 69
				throw new JobExecutionException("WorkflowJob.execute - Could not get kar LSID from job data map");
61 70
			}
62 71
			
72
			// Locate service
63 73
			logMetacat.debug("WorkflowJob.execute - Getting serviceLocator");
64 74
			KeplerWebServiceLocator serviceLocator = new KeplerWebServiceLocator();
65 75
			
76
			// get endpoint service
66 77
			logMetacat.debug("WorkflowJob.execute - Getting service");
67 78
			KeplerWebServicePortType serviceEndpoint = serviceLocator.getKeplerWebServiceHttpSoap11Endpoint();
68 79
			
80
			// call execute against remote endpoint
69 81
			logMetacat.debug("WorkflowJob.execute - Executing with kar lsid:" + karLSID);
70 82
			String status = serviceEndpoint.execute(karLSID);
71 83
			//String status = serviceEndpoint.getStatus(karLSID);		
src/edu/ucsb/nceas/metacat/workflow/WorkflowScheduler.java
1 1
/**
2 2
 *  '$RCSfile$'
3
 *    Purpose: A Class that handles scheduling tasks 
3
 *    Purpose: A Class that handles scheduling workflow jobs 
4 4
 *  Copyright: 2009 Regents of the University of California and the
5 5
 *             National Center for Ecological Analysis and Synthesis
6 6
 *    Authors: Michael Daigle
......
31 31
import java.text.ParseException;
32 32
import java.util.Calendar;
33 33
import java.util.Date;
34
import java.util.Enumeration;
35 34
import java.util.Hashtable;
36 35
import java.util.HashMap;
37 36

  
......
54 53
import edu.ucsb.nceas.metacat.util.RequestUtil;
55 54
import edu.ucsb.nceas.shared.AccessException;
56 55

  
56
/**
57
 * @author daigle
58
 *
59
 */
60
/**
61
 * @author daigle
62
 *
63
 */
57 64
public class WorkflowScheduler extends BaseScheduler {
58 65
	
59 66
	private static WorkflowScheduler workflowScheduler = null;
......
80 87
		return workflowScheduler;
81 88
	}
82 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
	 */
83 104
	public void scheduleJob(HttpServletRequest request, HttpServletResponse response, 
84 105
			Hashtable<String, String[]> params, String username,
85 106
			String[] groups) throws MetacatSchedulerException {
......
92 113
		try {
93 114
			SchedulerService schedulerService = SchedulerService.getInstance();
94 115

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

  
129
			// interval value must exist
107 130
			String intervalValues[] = params.get("intervalvalue");
108 131
			if (intervalValues == null || intervalValues.length == 0) {
109 132
				throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - intervalvalue field must be populated "
......
112 135
			String intervalStrValue = intervalValues[0];
113 136
			int intervalValue = Integer.parseInt(intervalStrValue);
114 137
			
138
			// interval unit must exist
115 139
			String intervalUnits[] = params.get("intervalunit");
116 140
			if (intervalUnits == null || intervalUnits.length == 0) {
117 141
				throw new MetacatSchedulerException("WorkflowScheduler.scheduleJob - intervalunit field must be populated "
......
119 143
			}
120 144
			String intervalUnit = intervalUnits[0];
121 145

  
122
			Enumeration<String> paramNames = params.keys();
123
			while (paramNames.hasMoreElements()) {
124
				String paramName = paramNames.nextElement();
125
				if (paramName.startsWith("jobparam_")) {
126
					jobParams.put(paramName.substring(9), params.get(paramName)[0]);
127
				}
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.");
128 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]);
129 170

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

  
174
			// Schedule the job
133 175
			String xmlResult = schedulerService.scheduleJob(jobName, startCal, intervalValue, intervalUnit,
134 176
					WORKFLOW_JOB_CLASS, WORKFLOW_JOB_GROUP, jobParams, username, groups);
135 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.
136 180
			String forwardtos[] = params.get("forwardto");
137 181
			String forwardto = null;
138 182
			if (forwardtos != null && forwardtos.length > 0) {
......
167 211
		}
168 212
	}
169 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
	 */
170 228
	public void unScheduleJob(HttpServletRequest request, HttpServletResponse response,
171 229
			Hashtable<String, String[]> params, String username, String[] groups)
172 230
			throws MetacatSchedulerException {
173 231
		try {
232
			// workflow job id must exist
174 233
			String jobNames[] = params.get("workflowjobid");
175 234
			if (jobNames == null || jobNames.length == 0) {
176 235
				throw new MetacatSchedulerException("SchedulerService.unScheduleJob - workflowjobid " 
......
178 237
			}
179 238
			String jobName = jobNames[0];
180 239

  
240
			// unschedule the job
181 241
			SchedulerService schedulerService = SchedulerService.getInstance();
182 242
			String xmlResult = schedulerService.unScheduleJob(jobName, username, groups);
183 243
			
244
			
184 245
			String forwardtos[] = params.get("forwardto");
185 246
			String forwardto = null;
186 247
			if (forwardtos != null && forwardtos.length > 0) {
187 248
				forwardto = forwardtos[0];
188 249
			}
189 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.
190 253
			if (forwardto != null) {
191 254
				String qformats[] = params.get("qformat");
192 255
				String qformat = null;
......
197 260
				ScheduledJobAccess jobAccess = new ScheduledJobAccess();
198 261
				ScheduledJobDAO jobDAO = jobAccess.getJobByName(jobName);
199 262
				
263
				// we need to include the workflow id in the forward url
200 264
				String workflowId = null;
201 265
				ScheduledJobParamDAO jobParamDAO = jobDAO.getJobParam("workflowid");
202 266
				if (jobParamDAO != null) {
......
221 285
		}
222 286
	}
223 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
	 */
224 302
	public void reScheduleJob(HttpServletRequest request, HttpServletResponse response, 
225 303
			Hashtable<String, String[]> params, String username,
226 304
			String[] groups) throws MetacatSchedulerException {
227 305
		 		
228 306
		try {
229
			String jobNames[] = params.get("workflowjobid");
230
	
307
			// workflow job id must exist
308
			String jobNames[] = params.get("workflowjobid");	
231 309
			if (jobNames == null || jobNames.length == 0) {
232 310
				throw new MetacatSchedulerException("WorkflowScheduler.reScheduleJob - workflowjobid field must be populated "
233 311
						+ "in scheduler parameters when rescheduling job.");
234
			}
235
			
312
			}			
236 313
			String jobName = jobNames[0];
237 314
	
238 315
			ScheduledJobAccess jobAccess = new ScheduledJobAccess();
239 316
			ScheduledJobDAO jobDAO = jobAccess.getJobByName(jobName);
240 317
			
318
			// reschedule the job
241 319
			SchedulerService schedulerService = SchedulerService.getInstance();
242 320
			String result = schedulerService.rescheduleJob(jobDAO, username, groups);
243 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.
244 324
			String forwardtos[] = params.get("forwardto");
245 325
			String forwardto = null;
246 326
			if (forwardtos != null && forwardtos.length > 0) {
......
254 334
					qformat = qformats[0];
255 335
				}
256 336
				
337
				// we need to include the workflow id in the forward url
257 338
				String workflowId = null;
258 339
				ScheduledJobParamDAO jobParamDAO = jobDAO.getAllJobParams().get("workflowid");
259 340
				if (jobParamDAO != null) {
......
280 361
		}
281 362
	}
282 363
	
364
	/**
365
	 * delete job - to be implemented
366
	 */
283 367
	public void deleteJob(HttpServletRequest request, HttpServletResponse response, 
284 368
			Hashtable<String, String[]> params, String username, String[] groups) throws MetacatSchedulerException {
285 369
		
286 370
	}
287 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
	 */
288 386
	public void getJobs(HttpServletRequest request, HttpServletResponse response, 
289 387
			Hashtable<String, String[]> params, String username, String[] groups) throws MetacatSchedulerException {
290 388
		
......
301 399
        }
302 400
		
303 401
		try {
402
			// get the job info in xml format
304 403
			String xmlResult = SchedulerService.getInstance().getJobsInfoXML(WORKFLOW_JOB_GROUP, "workflowid", workFlowId);
305 404
			logMetacat.debug("WorkflowScheduler.getJobs - xmlResult: " + xmlResult);
306 405
			
src/edu/ucsb/nceas/metacat/scheduler/ScheduledJobDAO.java
1 1
/**
2 2
 *  '$RCSfile$'
3
 *    Purpose: A Class that holds the data from the scheduled_task 
3
 *    Purpose: A Class that holds the data from the scheduled_job 
4 4
 *             table in the database. 
5 5
 *  Copyright: 2009 Regents of the University of California and the
6 6
 *             National Center for Ecological Analysis and Synthesis
......
34 34

  
35 35
public class ScheduledJobDAO extends BaseDAO {
36 36
	
37
	
38
	public static String SECONDLY = "secondly";
39
	public static String MINUTELY = "minutely";
40
	public static String HOURLY = "hourly";
41
	public static String DAILY = "daily";
42
	public static String WEEKLY = "weekly";
37
	public static String SECONDLY = "s";
38
	public static String MINUTELY = "m";
39
	public static String HOURLY = "h";
40
	public static String DAILY = "d";
41
	public static String WEEKLY = "w";
43 42

  
44 43
	private String _name;
45 44
	private String _triggerName;
......
50 49
	private String _intervalUnit;
51 50
	private HashMap<String, ScheduledJobParamDAO> _jobParams = new HashMap<String, ScheduledJobParamDAO>();
52 51
	
52
	// get the name
53 53
	public String getName() {
54 54
		return _name;
55 55
	}
56 56
	
57
	// set the name
57 58
	public void setName(String name) {
58 59
		_name = name;
59 60
	}
60 61
	
62
	// get the trigger name
61 63
	public String getTriggerName() {
62 64
		return _triggerName;
63 65
	}
64 66
	
67
	// set the trigger name
65 68
	public void setTriggerName(String triggerName) {
66 69
		_triggerName = triggerName;
67 70
	}
68 71
	
72
	// get the group name
69 73
	public String getGroupName() {
70 74
		return _groupName;
71 75
	}
72 76
	
77
	// set the group name
73 78
	public void setGroupName(String groupName) {
74 79
		_groupName = groupName;
75 80
	}
76 81
	
82
	// get the class name
77 83
	public String getClassName() {
78 84
		return _className;
79 85
	}
80 86
	
87
	// set the class name
81 88
	public void setClassName(String className) {
82 89
		_className = className;
83 90
	}
84 91
	
92
	// get the start time
85 93
	public Timestamp getStartTime() {
86 94
		return _startTime;
87 95
	}
88 96
	
97
	// set the start time
89 98
	public void setStartTime(Timestamp startTime) {
90 99
		_startTime = startTime;
91 100
	}
92 101
	
102
	// get the interval value
93 103
	public int getIntervalValue() {
94 104
		return _intervalValue;
95 105
	}
96 106
	
107
	// set the interval value
97 108
	public void setIntervalValue(int intervalValue) {
98 109
		_intervalValue = intervalValue;
99 110
	}
100 111
	
112
	// get the interval unit
101 113
	public String getIntervalUnit() {
102 114
		return _intervalUnit;
103 115
	}
104 116
	
117
	// set the interval unit
105 118
	public void setIntervalUnit(String intervalUnit) {
106 119
		_intervalUnit = intervalUnit;
107 120
	}
108 121
	
122
	// get the job param with the given key
109 123
	public ScheduledJobParamDAO getJobParam(String key) {
110 124
		return _jobParams.get(key);
111 125
	}
112 126
	
127
	// get all the job params for this job
113 128
	public HashMap<String, ScheduledJobParamDAO> getAllJobParams() {
114 129
		return _jobParams;
115 130
	}
116 131
	
132
	// add a job param to this job
117 133
	public void addJobParam(ScheduledJobParamDAO jobParamDAO) {
118 134
		_jobParams.put(jobParamDAO.getKey(), jobParamDAO);
119 135
	}
src/edu/ucsb/nceas/metacat/scheduler/SchedulerService.java
73 73
		return schedulerService;
74 74
	}
75 75
	
76
	// this is a refreshable class
76 77
	public boolean refreshable() {
77 78
		return true;
78 79
	}
79
	
80

  
81
	// do the refresh
80 82
	protected void doRefresh() throws ServiceException {
81 83
		stop();
84
		start();
82 85
	}
83 86

  
87
	// initialize the service
84 88
	protected void start() throws ServiceException {
85 89
		try {
90
			// get the Quartz scheduler factory
86 91
			SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
87 92
			
93
			// get the scheduler
88 94
			sched = schedFact.getScheduler();
89 95
			sched.start();
90 96
			
97
			// get all existing jobs from the database
91 98
			ScheduledJobAccess jobAccess = new ScheduledJobAccess();
92 99
			HashMap<Long, ScheduledJobDAO> allJobsMap = jobAccess.getAllJobs(null);
93 100
			
101
			// reschedule each job that is in a SCHEDULED state.  
94 102
			for (Long jobId : allJobsMap.keySet()) {
95 103
				ScheduledJobDAO jobDAO = allJobsMap.get(jobId);
96 104
				String[] groups = {"scheduler_group"};
97 105
				if (jobDAO.getStatus().equals(StatusUtil.SCHEDULED)) {
106
					// send false as the last param so the reschedule method will not 
107
					// complain that the job is already in a SCHEDULED state.
98 108
					rescheduleJob(jobDAO, "scheduler_user", groups, false);
99 109
				}
100 110
			}			
101 111
			
102 112
		} catch (AccessException ae) {
103
			throw new ServiceException("DB Access issue when starting scheduler: ", ae);
113
			throw new ServiceException("SchedulerService.start - DB Access issue when starting scheduler: ", ae);
104 114
		} catch (SchedulerException se) {
105
			throw new ServiceException("Scheduler engine issue when starting scheduler: " + se.getMessage());
115
			throw new ServiceException("SchedulerService.start - Scheduler engine issue when starting scheduler: " + se.getMessage());
106 116
		}		
107 117
	}
108 118
	
119
	// Stop the scheduler
109 120
	protected void stop() throws ServiceException {
110 121
		try {
111 122
			sched.shutdown(true);
112 123
			sched = null;
113 124
		} catch (SchedulerException se) {
114
			throw new ServiceException("Could not shut down scheduler: " + se.getMessage());
125
			throw new ServiceException("SchedulerService.stop - Could not shut down scheduler: " + se.getMessage());
115 126
		}		
116 127
	}
117 128
	
129
	// this will eventually return the scheduler status
118 130
	protected Vector<String> getStatus() throws ServiceException {
119 131
		return new Vector<String>();
120 132
	}
121 133
	
134
	/**
135
	 * Schedule a job
136
	 * 
137
	 * @param jobDAO
138
	 *            the job data object to schedule
139
	 * @param username
140
	 *            the user that we will use to schedule
141
	 * @param groups
142
	 *            the user group that we will use to schedule
143
	 * @return a message saying that the job was scheduled
144
	 */
122 145
	public String scheduleJob(ScheduledJobDAO jobDAO, String username, String[] groups) throws ServiceException {
123 146
        
147
		// convert the start time to a calendar object
124 148
		Calendar startTimeCal = Calendar.getInstance();
125 149
        startTimeCal.setTime(jobDAO.getStartTime());
126 150
        
151
        // extract the job parameters from their data objects and put into a string map
127 152
        HashMap<String, String> jobParams = new HashMap<String, String>();
128 153
        HashMap<String, ScheduledJobParamDAO> jobParamDAOs = jobDAO.getAllJobParams();
129 154
        for (String paramName : jobParamDAOs.keySet()) {
130 155
        	jobParams.put(paramName, jobParamDAOs.get(paramName).getValue());   	
131 156
        }
132 157
        
158
        // schedule the job
133 159
		return scheduleJob(jobDAO.getName(), startTimeCal, jobDAO.getIntervalValue(), jobDAO.getIntervalUnit(),
134 160
				jobDAO.getClassName(), jobDAO.getGroupName(), jobParams, username, groups);
135 161
	}
136 162
	
163
	/**
164
	 * schedule a job
165
	 * 
166
	 * @param jobName
167
	 *            the name of the job
168
	 * @param startCal
169
	 *            a calendar holding the start date of the job
170
	 * @param intervalValue
171
	 *            the run interval for the job
172
	 * @param intervalUnit
173
	 *            the unit of the run interval for the job
174
	 * @param jobClassName
175
	 *            the job class name
176
	 * @param jobGroup
177
	 *            the job group name
178
	 * @param jobParams
179
	 *            a map of additional job parameters
180
	 * @param username
181
	 *            the user name
182
	 * @param groups
183
	 *            the user's group name
184
	 * @return a message saying that the job was scheduled
185
	 */
137 186
	public String scheduleJob(String jobName, Calendar startCal, int intervalValue, String intervalUnit,
138 187
			String jobClassName, String jobGroup, HashMap<String, String> jobParams, 
139 188
			String username, String[] groups) throws ServiceException {
......
146 195
        			+ jobClassName + " : " + cnfe.getMessage());
147 196
        } 
148 197
        
149
        logMetacat.info("Scheduling job -- name: " + jobName + ", class: " + jobClassName 
198
        logMetacat.info("SchedulerService.scheduleJob - Scheduling job -- name: " + jobName + ", class: " + jobClassName 
150 199
        		+ ", start time: " + startCal.toString() + ", interval value: " + intervalValue 
151 200
        		+ ", interval unit: " + intervalUnit);  
152 201
		
202
        // start the job in the job scheduler
153 203
		startJob(jobName, startCal, intervalValue, intervalUnit, jobClass, jobGroup, jobParams);
154 204
		
205
		// get a database access object and create the job in the database
155 206
		try {
156 207
			ScheduledJobAccess jobAccess = new ScheduledJobAccess();
157 208
			jobAccess.createJob(jobName, jobName, jobGroup, jobClass, startCal, intervalValue, intervalUnit, jobParams);
......
160 211
				deleteJob(jobName, username, groups);
161 212
			} catch (Exception e) {
162 213
				// Not much we can do here but log this
163
				logMetacat.error("An access exception was thrown when writing job: " + jobName 
214
				logMetacat.error("SchedulerService.scheduleJob - An access exception was thrown when writing job: " + jobName 
164 215
						+ "to the db, and another exception was thrown when trying to remove the " 
165 216
						+ "job from the scheduler.  The db and scheduler may be out of sync: " + e.getMessage());
166 217
			}
......
170 221
		return "Scheduled: " + jobName;
171 222
	}
172 223
	
173

  
174
	
224
	/**
225
	 * Unschedule a job. This removed it from the scheduler in memory and
226
	 * changed it's status to unscheduled in the database.
227
	 * 
228
	 * @param jobName
229
	 *            the name of the job to unschedule
230
	 * @param username
231
	 *            the user name
232
	 * @param groups
233
	 *            the user's group name
234
	 * @return a message saying the job was unscheduled
235
	 */
175 236
	public String unScheduleJob(String jobName, String username,
176 237
			String[] groups) throws ServiceException {
177 238
		try {
......
182 243
						+ "not find job with name: " + jobName);
183 244
			}
184 245

  
246
			// remove the job from the scheduler
185 247
			sched.deleteJob(jobDAO.getName(), jobDAO.getGroupName());
186 248

  
249
			// change the status of the job to unscheduled in the database.
187 250
			jobDAO.setStatus(StatusUtil.UNSCHEDULED);
188 251
			jobAccess.updateJobStatus(jobDAO);
189 252
		} catch (SchedulerException se) {
......
197 260
		return "Unscheduled: " + jobName;
198 261
	}
199 262
	
263
	/**
264
	 * Reschedule a job. This call will always check to make sure the status is not SCHEDULED
265
	 * @param jobDAO the job data object holding the information about the job to reschedule
266
	 * @param username
267
	 *            the user name
268
	 * @param groups
269
	 *            the user's group name
270
	 * @return a message saying that the job was rescheduled
271
	 */
200 272
	public String rescheduleJob(ScheduledJobDAO jobDAO, String username, String[] groups) throws ServiceException {
201 273
		return rescheduleJob(jobDAO, username, groups, true);
202 274
	}
203 275
	
276
	/**
277
	 * Reschedule a job.
278
	 * 
279
	 * @param jobDAO
280
	 *            the job data object holding the information about the job to
281
	 *            reschedule
282
	 * @param username
283
	 *            the user name
284
	 * @param groups
285
	 *            the user's group name
286
	 * @param checkStatus
287
	 *            if set to true, the method will check to make sure the status
288
	 *            is UNSCHEDULED before restarting. Otherwise, the method will
289
	 *            not check. This is so that we can restart a service at startup
290
	 *            that was running when metacat was shut down.
291
	 * @return a message saying that the job was rescheduled
292
	 */
204 293
	public String rescheduleJob(ScheduledJobDAO jobDAO, String username, String[] groups, boolean checkStatus) throws ServiceException {
205 294
		
206 295
		try {
......
210 299
				throw new ServiceException("SchedulerService.reScheduleJob - Cannot reschedule nonexistant job.");
211 300
			}
212 301
        
302
			// if we are checking status, make sure the job is in an UNSCHEDULED state in the db
213 303
			if (checkStatus && !jobDAO.getStatus().equals(StatusUtil.UNSCHEDULED)) {
214 304
				throw new ServiceException("SchedulerService.reScheduleJob - Cannot reschedule a job with status: " 
215 305
						+ jobDAO.getStatus() + ". Status must be 'unscheduled'.");
......
237 327
	        		+ ", start time: " + startCal.toString() + ", interval value: " + jobDAO.getIntervalValue() 
238 328
	        		+ ", interval unit: " + jobDAO.getIntervalUnit());  
239 329
			
330
	        // start the job in the scheduler
240 331
			startJob(jobDAO.getName(), startCal, jobDAO.getIntervalValue(), jobDAO.getIntervalUnit(), jobClass, jobDAO.getGroupName(), jobParams);
241 332
	        
333
			// update the status in the database
242 334
			jobDAO.setStatus(StatusUtil.SCHEDULED);
243 335
			jobAccess.updateJobStatus(jobDAO);
244 336
			
......
250 342
		return "Resheduled: " + jobDAO.getName();
251 343
	}
252 344
	
345
	/**
346
	 * Remove the job from the scheduler and set the job status to deleted in the database
347
	 * @param jobDAO
348
	 *            the job data object holding the information about the job to
349
	 *            delete
350
	 * @param username
351
	 *            the user name
352
	 * @param groups
353
	 *            the user's group name
354
	 * @return a message saying that the job was deleted
355
	 */
253 356
	public String deleteJob(String jobName, String username,
254 357
			String[] groups) throws ServiceException {
255 358

  
......
274 377
		return "Deleted: " + jobName;
275 378
	}
276 379
	
380
	/**
381
	 * Get information about the job in XML format
382
	 * 
383
	 * @param jobId
384
	 *            the job for which we want the information
385
	 * @return an XML representation of the job
386
	 */
277 387
	public String getJobInfoXML(Long jobId) throws ServiceException {
278 388
		String jobInfoXML = "";
279 389
		
......
292 402
		return jobInfoXML;
293 403
	}
294 404
	
405
	/**
406
	 * Get the information for jobs in a group in an xml format. A parameter
407
	 * key/value pair can be provided as well to limit the jobs returned.
408
	 * 
409
	 * @param groupName
410
	 *            the job group that we are searching for
411
	 * @param paramName
412
	 *            the parameter name that we are looking for. this is ignored if
413
	 *            null
414
	 * @param paramValue
415
	 *            the parameter value that we are looking for. this is ignored
416
	 *            if null
417
	 * @return an XML representation of the jobs.
418
	 */
295 419
	public String getJobsInfoXML(String groupName, String paramName, String paramValue) throws ServiceException {
296 420
		String jobInfoXML = "";
297 421
		
......
319 443
		return jobInfoXML;
320 444
	}
321 445
	
446
	/**
447
	 * Convert a single job to XML
448
	 * @param scheduledJobDAO the job we want to convert
449
	 * @return an XML representation of the job
450
	 */
322 451
	public String jobToXML(ScheduledJobDAO scheduledJobDAO) throws ServiceException {
323 452
		String jobXML = "";
324 453

  
......
361 490
		return jobXML;
362 491
	}
363 492
	
364
	
493
	/**
494
	 * Start a job in the scheduler
495
	 * 
496
	 * @param jobName
497
	 *            the name of the job
498
	 * @param startCal
499
	 *            a calendar holding the start date of the job
500
	 * @param intervalValue
501
	 *            the run interval for the job
502
	 * @param intervalUnit
503
	 *            the unit of the run interval for the job
504
	 * @param jobClassName
505
	 *            the job class name
506
	 * @param jobGroup
507
	 *            the job group name
508
	 * @param jobParams
509
	 *            a map of additional job parameters
510
	 * @param username
511
	 *            the user name
512
	 * @param groups
513
	 *            the user's group name
514
	 */
365 515
	private void startJob(String jobName, Calendar startCal, int intervalValue, String intervalUnit,
366 516
			Class<Job> jobClass, String jobGroup, HashMap<String, String> jobParams) throws ServiceException { 
367 517
		
......
370 520
		
371 521
		char intervalChar = intervalUnit.charAt(0);
372 522
		
523
		// call the appropriate scheduling method depending on the schedule interval unit
373 524
		switch (intervalChar) {
374 525
		case 's':
375 526
		case 'S':
......
393 544
		}	
394 545
	}
395 546
	
547
	/**
548
	 * Schedule a job in the scheduler that has an interval based in seconds
549
	 * 
550
	 * @param jobName
551
	 *            the name of the job
552
	 * @param jobClass
553
	 *            the job class object
554
	 * @param startTime
555
	 *            the time of the first run
556
	 * @param interval
557
	 *            the interval in seconds between runs
558
	 * @param jobGroup
559
	 *            the group of this job
560
	 * @param jobDetail
561
	 *            the job detail object
562
	 */
396 563
	private void scheduleSecondlyJob(String jobName, Class<Job> jobClass, Calendar startTime, int interval, String jobGroup, JobDetail jobDetail) throws ServiceException {
397 564

  
398 565
		Trigger trigger = TriggerUtils.makeSecondlyTrigger(interval);
......
407 574
		}
408 575
	}
409 576
	
577
	/**
578
	 * Schedule a job in the scheduler that has an interval based in minutes
579
	 * 
580
	 * @param jobName
581
	 *            the name of the job
582
	 * @param jobClass
583
	 *            the job class object
584
	 * @param startTime
585
	 *            the time of the first run
586
	 * @param interval
587
	 *            the interval in minutes between runs
588
	 * @param jobGroup
589
	 *            the group of this job
590
	 * @param jobDetail
591
	 *            the job detail object
592
	 */
410 593
	private void scheduleMinutelyJob(String jobName, Class<Job> jobClass, Calendar startTime, int interval, String jobGroup, JobDetail jobDetail) throws ServiceException {
411 594

  
412 595
		Trigger trigger = TriggerUtils.makeMinutelyTrigger(interval);
......
421 604
		}
422 605
	}
423 606
	
607
	/**
608
	 * Schedule a job in the scheduler that has an interval based in hours
609
	 * 
610
	 * @param jobName
611
	 *            the name of the job
612
	 * @param jobClass
613
	 *            the job class object
614
	 * @param startTime
615
	 *            the time of the first run
616
	 * @param interval
617
	 *            the interval in hours between runs
618
	 * @param jobGroup
619
	 *            the group of this job
620
	 * @param jobDetail
621
	 *            the job detail object
622
	 */
424 623
	private void scheduleHourlyJob(String jobName, Class<Job> jobClass, Calendar startTime, int interval, String jobGroup, JobDetail jobDetail) throws ServiceException {
425 624

  
426 625
		Trigger trigger = TriggerUtils.makeHourlyTrigger(interval);
......
435 634
		}
436 635
	}
437 636
	
637
	/**
638
	 * Schedule a job in the scheduler that has an interval based in days
639
	 * 
640
	 * @param jobName
641
	 *            the name of the job
642
	 * @param jobClass
643
	 *            the job class object
644
	 * @param startTime
645
	 *            the time of the first run
646
	 * @param interval
647
	 *            the interval in days between runs
648
	 * @param jobGroup
649
	 *            the group of this job
650
	 * @param jobDetail
651
	 *            the job detail object
652
	 */
438 653
	private void scheduleDailyJob(String jobName, Class<Job> jobClass, Calendar startTime, int interval, String jobGroup, JobDetail jobDetail) throws ServiceException {
439 654

  
440 655
		Trigger trigger = TriggerUtils.makeHourlyTrigger(interval * 24);
......
449 664
		}
450 665
	}
451 666
	
452

  
453
	
667
	/**
668
	 * Extract the start date from the delay value
669
	 * 
670
	 * @param delay
671
	 *            a string representing the start delay in <value><unit>
672
	 *            notation where value is an integer and unit is one of s,m,h or
673
	 *            d
674
	 * @return the calendar object holding the start date
675
	 */
454 676
	public Calendar getStartDateFromDelay(String delay) throws ServiceException {
455 677
		Calendar cal = Calendar.getInstance();
456 678
	
......
487 709
		}
488 710
		
489 711
		return cal;
490
	}
491
	
492

  
493

  
494
	
495
	
496
	
712
	}	
497 713
}
src/edu/ucsb/nceas/metacat/scheduler/ScheduledJobParamDAO.java
1 1
/**
2 2
 *  '$RCSfile$'
3
 *    Purpose: A Class that holds the data from the scheduled_task 
3
 *    Purpose: A Class that holds the data from the scheduled_job_params 
4 4
 *             table in the database. 
5 5
 *  Copyright: 2009 Regents of the University of California and the
6 6
 *             National Center for Ecological Analysis and Synthesis
......
35 35
	private String _key;
36 36
	private String _value;
37 37
	
38
	// get parent job id
38 39
	public Long getJobId() {
39 40
		return _jobId;
40 41
	}
41 42
	
43
	// set parent job id
42 44
	public void setJobId(Long jobId) {
43 45
		_jobId = jobId;
44 46
	}
45 47
	
48
	// get parameter key
46 49
	public String getKey() {
47 50
		return _key;
48 51
	}
49 52
	
53
	// set parameter key
50 54
	public void setKey(String key) {
51 55
		_key = key;
52 56
	}
53 57
	
58
	// get parameter value
54 59
	public String getValue() {
55 60
		return _value;
56 61
	}
57 62
	
63
	// set parameter value
58 64
	public void setValue(String value) {
59 65
		_value = value;
60 66
	}
src/edu/ucsb/nceas/metacat/scheduler/BaseScheduler.java
1 1
/**
2 2
 *  '$RCSfile$'
3
 *    Purpose: A Class that runs a single scheduled report task 
3
 *    Purpose: An abstract base class for scheduler classes.
4 4
 *  Copyright: 2009 Regents of the University of California and the
5 5
 *             National Center for Ecological Analysis and Synthesis
6 6
 *    Authors: Michael Daigle
......
33 33

  
34 34
public abstract class BaseScheduler {
35 35
	
36
	// Schedule a job by extracting job specific information and registering it with the scheduler 
37
	// service.  
36 38
	public abstract void scheduleJob(HttpServletRequest request, HttpServletResponse response, 
37 39
            Hashtable<String, String[]> params, String username, String[] groups) throws MetacatSchedulerException;
38 40
	
41
	// Unschedule a job in the scheduler service. 
39 42
	public abstract void unScheduleJob(HttpServletRequest request, HttpServletResponse response, 
40 43
			Hashtable<String, String[]> params, String username, String[] groups) throws MetacatSchedulerException;
41 44
	
45
	// Delete a job in the scheduler service. 
42 46
	public abstract void deleteJob(HttpServletRequest request, HttpServletResponse response, 
43 47
			Hashtable<String, String[]> params, String username, String[] groups) throws MetacatSchedulerException;
44 48
	
49
	// get all jobs frpm the scheduler service for a specific type of scheduler.
45 50
	public abstract void getJobs(HttpServletRequest request, HttpServletResponse response, 
46 51
			Hashtable<String, String[]> params, String username, String[] groups) throws MetacatSchedulerException;
47 52
}
src/edu/ucsb/nceas/metacat/scheduler/MetacatSchedulerException.java
1 1
/**
2 2
 *  '$RCSfile$'
3
 *    Purpose: An Exception thrown when an error occurs because an 
4
 *             AccessionNumber was invalid or used incorrectly
3
 *    Purpose: An Exception thrown when an error occurs in the metacat scheduling
4
 *    system.  Note that this is not called SchedulerException to avoid conflicts 
5
 *    with an exception in Quartz with the same name.
5 6
 *  Copyright: 2008 Regents of the University of California and the
6 7
 *             National Center for Ecological Analysis and Synthesis
7 8
 *    Authors: Michael Daigle
src/edu/ucsb/nceas/metacat/scheduler/ScheduledJobAccess.java
47 47
	
48 48
	private Logger logMetacat = Logger.getLogger(ScheduledJobAccess.class);
49 49
	
50
	// Constructor
50 51
	public ScheduledJobAccess() throws AccessException {
51 52
		super("ScheduledJobAccess");
52 53
	}
53 54
	
55
	/**
56
	 * Get a job based on it's id
57
	 * 
58
	 * @param jobId
59
	 *            the id of the job in the database
60
	 * @return the scheduled job data object that represents the desired job
61
	 */ 
54 62
	public ScheduledJobDAO getJob(Long jobId) throws AccessException {
55 63
		ScheduledJobDAO jobDAO = null;
56 64

  
65
		// first get the job from the db and put it into a DAO
57 66
		PreparedStatement pstmt = null;
58 67
		try {
59 68
			String sql = "SELECT * FROM scheduled_job WHERE id = ? AND status != 'deleted'"; 
......
85 94
			} 
86 95
		}	
87 96
		
97
		// Now get all the job parameters and put those into a list of job parameter
98
		// DAOs and add that list to the job DAO
88 99
		ScheduledJobParamAccess jobParamAccess = new ScheduledJobParamAccess();
89 100
		Vector<ScheduledJobParamDAO> jobParamList = 
90 101
			jobParamAccess.getJobParamsForJobId(jobDAO.getId());
......
96 107
		return jobDAO;		
97 108
	}
98 109
	
110
	/**
111
	 * Get a job by it's name
112
	 * @param jobName the name of the job to get
113
	 * @return the scheduled job data object that represents the desired job
114
	 */
99 115
	public ScheduledJobDAO getJobByName(String jobName) throws AccessException {
100 116
		ScheduledJobDAO jobDAO = null;
101 117

  
118
		// first get the job from the db and put it into a DAO
102 119
		PreparedStatement pstmt = null;
103 120
		try {
104 121
			String sql = "SELECT * FROM scheduled_job WHERE name = ? AND status != 'deleted'"; 
......
130 147
			} 
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff