Skip to content
Snippets Groups Projects
Commit a5ddcb1e authored by gmantele's avatar gmantele
Browse files

[TAP,UWS] Set the same ID for the job (asynchronous or not) and for the HTTP

request which has initiated the job creation. Actually the HTTP request is
generated as before, and then, if a job is created, it is set to the ID of the
HTTP request. This modification aims to greatly help the log analysis.
parent 8ae75e57
No related branches found
No related tags found
No related merge requests found
......@@ -16,7 +16,7 @@ package tap;
* You should have received a copy of the GNU Lesser General Public License
* along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Astronomisches Rechen Institut (ARI)
*/
......@@ -39,6 +39,7 @@ import uws.UWSException;
import uws.job.ErrorSummary;
import uws.job.Result;
import uws.job.user.JobOwner;
import uws.service.UWS;
import uws.service.UWSService;
import uws.service.backup.UWSBackupManager;
import uws.service.error.ServiceErrorWriter;
......@@ -54,7 +55,7 @@ import adql.query.ADQLQuery;
* Only the functions related with the database connection stay abstract.
*
* @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 2.0 (04/2015)
* @version 2.1 (01/2016)
*/
public abstract class AbstractTAPFactory extends TAPFactory {
......@@ -256,8 +257,16 @@ public abstract class AbstractTAPFactory extends TAPFactory {
@Override
protected TAPJob createTAPJob(final HttpServletRequest request, final JobOwner owner) throws UWSException{
try{
// Extract the HTTP request ID (the job ID should be the same, if not already used by another job):
String requestID = null;
if (request.getAttribute(UWS.REQ_ATTRIBUTE_ID) != null && request.getAttribute(UWS.REQ_ATTRIBUTE_ID) instanceof String)
requestID = request.getAttribute(UWS.REQ_ATTRIBUTE_ID).toString();
// Extract the TAP parameters from the HTTP request:
TAPParameters tapParams = createTAPParameters(request);
return new TAPJob(owner, tapParams);
// Create the job:
return new TAPJob(owner, tapParams, requestID);
}catch(TAPException te){
if (te.getCause() != null && te.getCause() instanceof UWSException)
throw (UWSException)te.getCause();
......
......@@ -16,7 +16,7 @@ package tap;
* You should have received a copy of the GNU Lesser General Public License
* along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Astronomisches Rechen Institut (ARI)
*/
......@@ -45,7 +45,7 @@ import uws.service.log.UWSLog.LogLevel;
* </p>
*
* @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 2.1 (11/2015)
* @version 2.1 (01/2016)
*/
public class TAPJob extends UWSJob {
private static final long serialVersionUID = 1L;
......@@ -111,6 +111,28 @@ public class TAPJob extends UWSJob {
tapParams.check();
}
/**
* <p>Build a pending TAP job with the given parameters.
* The given HTTP request ID will be used as Job ID if not already used by another job.</p>
*
* <p><i><u>Note:</u> if the parameter {@link #PARAM_PHASE} (</i>phase<i>) is given with the value {@link #PHASE_RUN}
* the job execution starts immediately after the job has been added to a job list or after {@link #applyPhaseParam(JobOwner)} is called.</i></p>
*
* @param owner User who owns this job. <i>MAY BE NULL</i>
* @param tapParams Set of parameters.
* @param requestID ID of the HTTP request which has initiated the creation of this job.
* <i>Note: if NULL, empty or already used, a job ID will be generated thanks to {@link #generateJobId()}.</i>
*
* @throws TAPException If one of the given parameters has a forbidden or wrong value.
*
* @since 2.1
*/
public TAPJob(final JobOwner owner, final TAPParameters tapParams, final String requestID) throws TAPException{
super(owner, tapParams, requestID);
this.tapParams = tapParams;
tapParams.check();
}
/**
* <p>Restore a job in a state defined by the given parameters.
* The phase must be set separately with {@link #setPhase(uws.job.ExecutionPhase, boolean)}, where the second parameter is true.</p>
......
......@@ -16,7 +16,7 @@ package tap;
* You should have received a copy of the GNU Lesser General Public License
* along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Astronomisches Rechen Institut (ARI)
*/
......@@ -48,7 +48,7 @@ import uws.service.log.UWSLog.LogLevel;
* </p>
*
* @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 2.0 (02/2015)
* @version 2.1 (01/2016)
*/
public class TAPSyncJob {
......@@ -56,7 +56,7 @@ public class TAPSyncJob {
protected long waitForStop = 1000;
/** Last generated ID of a synchronous job. */
protected static String lastId = null;
protected static String lastId = "S" + System.currentTimeMillis() + "A";
/** Description of the TAP service in charge of this synchronous job. */
protected final ServiceConnection service;
......@@ -100,6 +100,39 @@ public class TAPSyncJob {
ID = generateId();
}
/**
* Create a synchronous TAP job.
* The given HTTP request ID will be used as Job ID if not already used by another job.
*
* @param service Description of the TAP service which is in charge of this synchronous job.
* @param params Parameters of the query to execute. It must mainly contain the ADQL query to execute.
* @param requestID ID of the HTTP request which has initiated the creation of this job.
* <i>Note: if NULL, empty or already used, a job ID will be generated thanks to {@link #generateId()}.</i>
*
* @throws NullPointerException If one of the 2 first parameters is NULL.
*
* @since 2.1
*/
public TAPSyncJob(final ServiceConnection service, final TAPParameters params, final String requestID) throws NullPointerException{
if (params == null)
throw new NullPointerException("Missing TAP parameters ! => Impossible to create a synchronous TAP job.");
tapParams = params;
tapParams.init();
if (service == null)
throw new NullPointerException("Missing the service description ! => Impossible to create a synchronous TAP job.");
this.service = service;
synchronized(lastId){
if (requestID == null || requestID.trim().length() == 0 || lastId.equals(requestID))
ID = generateId();
else{
ID = requestID;
lastId = requestID;
}
}
}
/**
* <p>This function lets generating a unique ID.</p>
*
......@@ -112,6 +145,7 @@ public class TAPSyncJob {
* @return A unique job identifier.
*/
protected String generateId(){
synchronized(lastId){
String generatedId = "S" + System.currentTimeMillis() + "A";
if (lastId != null){
while(lastId.equals(generatedId))
......@@ -120,6 +154,7 @@ public class TAPSyncJob {
lastId = generatedId;
return generatedId;
}
}
/**
* Get the ID of this synchronous job.
......
......@@ -16,7 +16,7 @@ package tap.resource;
* You should have received a copy of the GNU Lesser General Public License
* along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Astronomisches Rechen Institut (ARI)
*/
......@@ -33,6 +33,7 @@ import tap.TAPJob;
import tap.TAPSyncJob;
import tap.parameters.TAPParameters;
import uws.UWSException;
import uws.service.UWS;
/**
* <p>Synchronous resource of a TAP service.</p>
......@@ -44,7 +45,7 @@ import uws.UWSException;
* </p>
*
* @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 2.0 (09/2014)
* @version 2.1 (01/2016)
*/
public class Sync implements TAPResource {
......@@ -105,8 +106,13 @@ public class Sync implements TAPResource {
if (!service.isAvailable())
throw new TAPException("Can not execute a query: this TAP service is not available! " + service.getAvailability(), UWSException.SERVICE_UNAVAILABLE);
// Extract the HTTP request ID (if any):
String requestID = null;
if (request != null && request.getAttribute(UWS.REQ_ATTRIBUTE_ID) != null && request.getAttribute(UWS.REQ_ATTRIBUTE_ID) instanceof String)
requestID = (String)request.getAttribute(UWS.REQ_ATTRIBUTE_ID);
// Execute synchronously the given job:
TAPSyncJob syncJob = new TAPSyncJob(service, params);
TAPSyncJob syncJob = new TAPSyncJob(service, params, requestID);
syncJob.start(response);
return true;
......
......@@ -16,7 +16,7 @@ package tap.resource;
* You should have received a copy of the GNU Lesser General Public License
* along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Astronomisches Rechen Institut (ARI)
*/
......@@ -53,7 +53,7 @@ import adql.db.FunctionDef;
* <p>At its creation it is creating and configuring the other resources in function of the given description of the TAP service.</p>
*
* @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 2.0 (06/2015)
* @version 2.1 (01/2016)
*/
public class TAP implements VOSIResource {
......@@ -737,8 +737,9 @@ public class TAP implements VOSIResource {
*/
protected synchronized String generateRequestID(final HttpServletRequest request){
String id;
String prefix = (request != null && request.getRequestURI() != null && request.getRequestURI().contains("/sync") ? "S" : "");
do{
id = System.currentTimeMillis() + "";
id = prefix + System.currentTimeMillis() + "";
}while(lastRequestID != null && lastRequestID.startsWith(id));
lastRequestID = id;
return id;
......
......@@ -16,7 +16,7 @@ package uws.job;
* You should have received a copy of the GNU Lesser General Public License
* along with UWSLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Astronomisches Rechen Institut (ARI)
*/
......@@ -89,7 +89,8 @@ import uws.service.request.UploadFile;
* <b>{@link #generateJobId()}:</b>
* This function is called at the construction of any {@link UWSJob}. It allows to generate a unique job ID.
* By default: time (in milliseconds) + a upper-case letter (A, B, C, ....).
* <u>If you want customizing the job ID of your jobs</u>, you need to override this function.
* <u>If you want customizing the job ID of your jobs</u>, you need to override this function or to use the new function
* {@link #UWSJob(JobOwner, UWSParameters, String)}.
* </li>
* <br />
* <li>
......@@ -113,7 +114,7 @@ import uws.service.request.UploadFile;
* </ul>
*
* @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 4.1 (12/2014)
* @version 4.2 (01/2016)
*/
public class UWSJob extends SerializableUWSObject {
private static final long serialVersionUID = 1L;
......@@ -310,6 +311,52 @@ public class UWSJob extends SerializableUWSObject {
}
}
/**
* <p>Builds a job of the given owner and from a map of all parameters (UWS and additional parameters).
* The given HTTP request ID will be used as Job ID if not already used by another job.</p>
*
* <p><i><u>Note:</u> if the parameter {@link #PARAM_PHASE} (</i>phase<i>) is given with the value {@link #PHASE_RUN}
* the job execution starts immediately after the job has been added to a job list or after {@link #applyPhaseParam(JobOwner)} is called.</i></p>
*
* @param owner Job.owner ({@link #PARAM_OWNER}).
* @param params UWS standard and non-standard parameters.
* @param requestID ID of the HTTP request which has initiated the creation of this job.
* <i>Note: if NULL, empty or already used, a job ID will be generated thanks to {@link #generateJobId()}.</i>
*
* @see UWSParameters#init()
*
* @since 4.2
*/
public UWSJob(JobOwner owner, final UWSParameters params, final String requestID){
this.owner = owner;
phase = new JobPhase(this);
results = new HashMap<String,Result>();
inputParams = params;
inputParams.init();
// Set the Job ID with the value of the HTTP request ID (if not already used by a job):
synchronized(lastId){
if (requestID == null || requestID.trim().length() == 0 || lastId.equals(requestID))
jobId = generateJobId();
else{
jobId = requestID;
lastId = requestID;
}
}
restorationDate = null;
// Move all uploaded files in a location related with this job:
Iterator<UploadFile> files = inputParams.getFiles();
while(files.hasNext()){
try{
files.next().move(this);
}catch(IOException ioe){}
}
}
/**
* <p><b>CONSTRUCTOR TO USE TO RESTORE A JOB whatever is its phase.</b></p>
*
......@@ -383,7 +430,7 @@ public class UWSJob extends SerializableUWSObject {
/**
* <p>This function lets generating a unique ID.</p>
*
* <p><i><b>By default:</b> System.currentTimeMillis()+UpperCharacter (UpperCharacter: one upper-case character: A, B, C, ....)</i></p>
* <p><i><b>By default:</b> System.currentTimeMillis()+UpperCharacter (UpperCharacter: one upper-case character chosen in order to guarantee the unicity of the ID: A, B, C, ....)</i></p>
*
* <p><i><u>note: </u> DO NOT USE in this function any of the following functions: {@link #getLogger()},
* {@link #getFileManager()} and {@link #getFactory()}. All of them will return NULL, because this job does not
......
......@@ -16,7 +16,7 @@ package uws.service;
* You should have received a copy of the GNU Lesser General Public License
* along with UWSLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Astronomisches Rechen Institut (ARI)
*/
......@@ -48,7 +48,7 @@ import uws.service.request.UWSRequestParser;
* Only the function which creates a {@link JobThread} from a {@link UWSJob} needs to be implemented.</p>
*
* @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 4.1 (11/2014)
* @version 4.2 (01/2016)
*/
public abstract class AbstractUWSFactory implements UWSFactory {
......@@ -84,7 +84,13 @@ public abstract class AbstractUWSFactory implements UWSFactory {
@Override
public UWSJob createJob(final HttpServletRequest request, final JobOwner user) throws UWSException{
return new UWSJob(user, createUWSParameters(request));
// Extract the HTTP request ID (the job ID should be the same, if not already used by another job):
String requestID = null;
if (request != null && request.getAttribute(UWS.REQ_ATTRIBUTE_ID) != null && request.getAttribute(UWS.REQ_ATTRIBUTE_ID) instanceof String)
requestID = request.getAttribute(UWS.REQ_ATTRIBUTE_ID).toString();
// Create the job:
return new UWSJob(user, createUWSParameters(request), requestID);
}
@Override
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment