Skip to content
Snippets Groups Projects
Commit 08624eaf authored by Grégory Mantelet's avatar Grégory Mantelet
Browse files

[TAP] Add possibility to set the execution duration of synchronous queries.

Fixes #78
Fixes #60
parent ccd563d2
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-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Copyright 2012-2020 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Astronomisches Rechen Institut (ARI)
*/
......@@ -44,7 +44,7 @@ import uws.service.file.UWSFileManager;
* </p>
*
* @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 2.3 (04/2019)
* @version 2.4 (08/2020)
*/
public interface ServiceConnection {
......@@ -59,7 +59,7 @@ public interface ServiceConnection {
private final String str;
private LimitUnit(final String str){
private LimitUnit(final String str) {
this.str = str;
}
......@@ -68,11 +68,12 @@ public interface ServiceConnection {
*
* @param anotherUnit A unit.
*
* @return true if the given unit has the same type, false otherwise.
* @return <code>true</code> if the given unit has the same type,
* <code>false</code> otherwise.
*
* @since 1.1
*/
public boolean isCompatibleWith(final LimitUnit anotherUnit){
public boolean isCompatibleWith(final LimitUnit anotherUnit) {
if (this == rows)
return anotherUnit == rows;
else
......@@ -80,15 +81,21 @@ public interface ServiceConnection {
}
/**
* Gets the factor to convert into bytes the value expressed in this unit.
* <i>Note: if this unit is not a factor of bytes, 1 is returned (so that the factor does not affect the value).</i>
* Gets the factor to convert into bytes the value expressed in this
* unit.
*
* @return The factor need to convert a value expressed in this unit into bytes, or 1 if not a bytes derived unit.
* <p><i><b>Note:</b>
* if this unit is not a factor of bytes, 1 is returned (so that the
* factor does not affect the value).
* </i></p>
*
* @return The factor need to convert a value expressed in this unit
* into bytes, or 1 if not a bytes derived unit.
*
* @since 1.1
*/
public long bytesFactor(){
switch(this){
public long bytesFactor() {
switch(this) {
case bytes:
return 1;
case kilobytes:
......@@ -124,7 +131,7 @@ public interface ServiceConnection {
*
* @since 1.1
*/
public static int compare(final int leftLimit, final LimitUnit leftUnit, final int rightLimit, final LimitUnit rightUnit) throws TAPException{
public static int compare(final int leftLimit, final LimitUnit leftUnit, final int rightLimit, final LimitUnit rightUnit) throws TAPException {
return compare((long)leftLimit, leftUnit, (long)rightLimit, rightUnit);
}
......@@ -154,7 +161,7 @@ public interface ServiceConnection {
*
* @since 2.3
*/
public static int compare(final long leftLimit, final LimitUnit leftUnit, final long rightLimit, final LimitUnit rightUnit) throws TAPException{
public static int compare(final long leftLimit, final LimitUnit leftUnit, final long rightLimit, final LimitUnit rightUnit) throws TAPException {
if (!leftUnit.isCompatibleWith(rightUnit))
throw new TAPException("Limit units (" + leftUnit + " and " + rightUnit + ") are not compatible!");
......@@ -164,28 +171,6 @@ public interface ServiceConnection {
return compare(leftLimit * leftUnit.bytesFactor(), rightLimit * rightUnit.bytesFactor());
}
/**
* <p><i>(Strict copy of Integer.compare(int,int) of Java 1.7)</i></p>
* <p>
* Compares two {@code int} values numerically.
* The value returned is identical to what would be returned by:
* </p>
* <pre>
* Integer.valueOf(x).compareTo(Integer.valueOf(y))
* </pre>
*
* @param x the first {@code int} to compare
* @param y the second {@code int} to compare
* @return the value {@code 0} if {@code x == y};
* a value less than {@code 0} if {@code x < y}; and
* a value greater than {@code 0} if {@code x > y}
*
* @since 1.1
*/
private static int compare(int x, int y){
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
/**
* <p><i>(Strict copy of Integer.compare(long,long) of Java 1.7)</i></p>
* <p>
......@@ -204,23 +189,32 @@ public interface ServiceConnection {
*
* @since 1.1
*/
public static int compare(long x, long y){
public static int compare(long x, long y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
@Override
public String toString(){
public String toString() {
return str;
}
}
/**
* <i>[OPTIONAL]</i>
* <p>Name of the service provider ; it can be an organization as an individual person.</p>
* <p>
* Name of the service provider ; it can be an organization as an
* individual person.
* </p>
*
* <p>There is no restriction on the syntax or on the label to use ; this information is totally free</p>
* <p>
* There is no restriction on the syntax or on the label to use ; this
* information is totally free.
* </p>
*
* <p>It will be used as additional information (INFO tag) in any VOTable and HTML output.</p>
* <p>
* It will be used as additional information (INFO tag) in any VOTable and
* HTML output.
* </p>
*
* @return The TAP service provider or NULL to leave this field blank.
*/
......@@ -230,7 +224,10 @@ public interface ServiceConnection {
* <i>[OPTIONAL]</i>
* <p>Description of the service provider.</p>
*
* <p>It will be used as additional information (INFO tag) in any VOTable output.</p>
* <p>
* It will be used as additional information (INFO tag) in any VOTable
* output.
* </p>
*
* @return The TAP service description or NULL to leave this field blank.
*/
......@@ -238,22 +235,30 @@ public interface ServiceConnection {
/**
* <i><b>[MANDATORY]</b></i>
* <p>This function tells whether the TAP service is available
* (that's to say, "able to execute requests" ; resources like /availability, /capabilities and /tables may still work).</p>
* <p>
* This function tells whether the TAP service is available (that's to say,
* "able to execute requests" ; resources like /availability, /capabilities
* and /tables may still work).
* </p>
*
* <p>
* A message explaining the current state of the TAP service could be provided thanks to {@link #getAvailability()}.
* A message explaining the current state of the TAP service could be
* provided thanks to {@link #getAvailability()}.
* </p>
*
* @return <i>true</i> to enable all TAP resources, <i>false</i> to disable all of them (except /availability).
* @return <code>true</code> to enable all TAP resources,
* <code>false</code> to disable all of them (except /availability)
*/
public boolean isAvailable();
/**
* <i>[OPTIONAL]</i>
* <p>Get an explanation about the current TAP service state (working or not).
* This message aims to provide more details to the users about the availability of this service,
* or more particularly about its unavailability.</p>
* <p>
* Get an explanation about the current TAP service state (working or not).
* This message aims to provide more details to the users about the
* availability of this service, or more particularly about its
* unavailability.
* </p>
*
* @return Explanation about the TAP service state.
*/
......@@ -262,13 +267,17 @@ public interface ServiceConnection {
/**
* <i><b>[MANDATORY]</b></i>
* <p>This function sets the state of the whole TAP service.
* If true, all TAP resources will be able to execute resources.
* If false, /sync and /async won't answer any more to requests and a HTTP-503 (Service unavailable)
* error will be returned.
* If <code>true</code>, all TAP resources will be able to execute
* resources. If <code>false</code>, /sync and /async won't answer any more
* to requests and a HTTP-503 (Service unavailable) error will be returned.
* </p>
*
* @param isAvailable <i>true</i> to enable all resources, <i>false</i> to forbid /sync and /async (all other resources will still be available).
* @param message A message describing the current state of the service. If NULL, a default message may be set by the library.
* @param isAvailable <code>true</code> to enable all resources,
* <code>false</code> to forbid /sync and /async (all
* other resources will still be available).
* @param message A message describing the current state of the
* service. If NULL, a default message may be set by
* the library.
*
* @since 2.0
*/
......@@ -279,8 +288,8 @@ public interface ServiceConnection {
* <p>Get the limit of the retention period (in seconds).</p>
*
* <p>
* It is the maximum period while an asynchronous job can leave in the jobs list
* and so can stay on the server.
* It is the maximum period while an asynchronous job can leave in the jobs
* list and so can stay on the server.
* </p>
*
* <p><b>Important notes:</b></p>
......@@ -288,15 +297,21 @@ public interface ServiceConnection {
* <li><b>Exactly 2 values or a NULL object is expected here.</b></li>
* <li><b>If NULL</b>, the retention period is not limited and jobs will
* theoretically stay infinitely on the server.</li>
* <li><b>If not NULL</b>, the 2 values must correspond to the default retention period
* and the maximum retention period.</li>
* <li><b>The default value</b> is used to set the retention period when a job is created with no user defined retention period.</li>
* <li><b>The maximum value</b> is used to limit the retention period when specified by the user while creating a job.</li>
* <li><b>The default value</b> MUST be less or equals the maximum value.</li>
* <li><b>Both values must be positive</b>. If a negative value is given it will be interpreted as "no limit".</li>
* <li><b>If not NULL</b>, the 2 values must correspond to the default
* retention period and the maximum retention period.</li>
* <li><b>The default value</b> is used to set the retention period when a
* job is created with no user defined retention period.</li>
* <li><b>The maximum value</b> is used to limit the retention period when
* specified by the user while creating a job.</li>
* <li><b>The default value</b> MUST be less or equals the maximum
* value.</li>
* <li><b>Both values must be positive</b>. If a negative value is given it
* will be interpreted as "no limit".</li>
* </ul>
*
* @return NULL if no limit must be set, or a two-items array ([0]: default value, [1]: maximum value).
* @return NULL if no limit must be set, or a two-items array
* ([0]: default value,
* [1]: maximum value).
*/
public int[] getRetentionPeriod();
......@@ -306,23 +321,38 @@ public interface ServiceConnection {
*
* <p>
* It is the duration of a running job (including the query execution).
* This duration is used for synchronous AND asynchronous jobs.
* The two first values are used for asynchronous jobs, and the last one
* (if provided) for synchronous jobs.
* </p>
*
* <p><b>Important notes:</b></p>
* <ul>
* <li><b>Exactly 2 values or a NULL object is expected here.</b></li>
* <li><b>Exactly 2 or 3 values or a NULL object is expected here.</b></li>
* <li><b>If NULL</b>, the execution duration is not limited and jobs could
* theoretically run infinitely.</li>
* <li><b>If not NULL</b>, the 2 values must correspond to the default execution duration
* and the maximum execution duration.</li>
* <li><b>The default value</b> is used to set the execution duration when a job is created with no user defined execution duration.</li>
* <li><b>The maximum value</b> is used to limit the execution duration when specified by the user while creating a job.</li>
* <li><b>The default value</b> MUST be less or equals the maximum value.</li>
* <li><b>Both values must be positive</b>. If a negative value is given it will be interpreted as "no limit".</li>
* <li><b>If not NULL</b>, the 2 or values must correspond to the default
* execution duration, the maximum execution duration and the execution
* duration for synchronous jobs.</li>
* <li><b>The default value</b> is used to set the execution duration when
* a job is created with no user defined execution duration.</li>
* <li><b>The maximum value</b> is used to limit the execution duration
* when specified by the user while creating a job.</li>
* <li><b>The synchronous value</b> is used to set the maximum execution
* duration for synchronous job. If not set, the default value will be
* used instead.</li>
* <li><b>The default value</b> MUST be less or equals the maximum
* value.</li>
* <li><b>The synchronous value</b> MUST be less or equals the default
* value.</li>
* <li><b>All three values must be positive</b>. If a negative value is
* given it will be interpreted as either the default or maximum value
* or to "no limit".</li>
* </ul>
*
* @return NULL if no limit must be set, or a two-items array ([0]: default value, [1]: maximum value).
* @return NULL if no limit must be set, or a two- or three-items array
* ([0]: default value,
* [1]: maximum value,
* [2]: value for sync queries).
*/
public int[] getExecutionDuration();
......@@ -331,33 +361,46 @@ public interface ServiceConnection {
* <p>Get the limit of the job execution result.</p>
*
* <p>
* This value will limit the size of the query results, either in rows or in bytes.
* The type of limit is defined by the function {@link #getOutputLimitType()}.
* This value will limit the size of the query results, either in rows or
* in bytes. The type of limit is defined by the function
* {@link #getOutputLimitType()}.
* </p>
*
* <p><b>Important notes:</b></p>
* <ul>
* <li><b>Exactly 2 values or a NULL object is expected here.</b></li>
* <li><b>If NULL</b>, the output limit is not limited and jobs could theoretically
* return very big files.</li>
* <li><b>If not NULL</b>, the 2 values must correspond to the default output limit
* and the maximum output limit.</li>
* <li><b>The default value</b> is used to set the output limit when a job is created with no user defined output limit.</li>
* <li><b>The maximum value</b> is used to limit the output limit when specified by the user while creating a job.</li>
* <li><b>The structure of the object</b> returned by this function MUST be the same as the object returned by {@link #getOutputLimitType()}.
* Particularly, the type given by the N-th item of {@link #getOutputLimitType()} must correspond to the N-th limit returned by this function.</li>
* <li><b>The default value</b> MUST be less or equals the maximum value.</li>
* <li><b>Both values must be positive</b>. If a negative value is given it will be interpreted as "no limit".</li>
* <li><b>If NULL</b>, the output limit is not limited and jobs could
* theoretically return very big files.</li>
* <li><b>If not NULL</b>, the 2 values must correspond to the default
* output limit and the maximum output limit.</li>
* <li><b>The default value</b> is used to set the output limit when a job
* is created with no user defined output limit.</li>
* <li><b>The maximum value</b> is used to limit the output limit when
* specified by the user while creating a job.</li>
* <li><b>The structure of the object</b> returned by this function MUST be
* the same as the object returned by {@link #getOutputLimitType()}.
* Particularly, the type given by the N-th item of
* {@link #getOutputLimitType()} must correspond to the N-th limit
* returned by this function.</li>
* <li><b>The default value</b> MUST be less or equals the maximum
* value.</li>
* <li><b>Both values must be positive</b>. If a negative value is given it
* will be interpreted as "no limit".</li>
* </ul>
*
* <p><i><b>Important note:</b>
* Currently, the default implementations of the library is only able to deal with output limits in ROWS.<br/>
* Anyway, in order to save performances, it is strongly recommended to use ROWS limit rather than in bytes. Indeed, the rows limit can be taken
* into account at the effective execution of the query (so before getting the result), on the contrary of the bytes limit which
* will be applied on the query result.
* Currently, the default implementations of the library is only able to
* deal with output limits in ROWS.<br/>
* Anyway, in order to save performances, it is strongly recommended to use
* ROWS limit rather than in bytes. Indeed, the rows limit can be taken
* into account at the effective execution of the query (so before getting
* the result), on the contrary of the bytes limit which will be applied on
* the query result.
* </i></p>
*
* @return NULL if no limit must be set, or a two-items array ([0]: default value, [1]: maximum value).
* @return NULL if no limit must be set, or a two-items array
* ([0]: default value,
* [1]: maximum value).
*
* @see #getOutputLimitType()
*/
......@@ -365,24 +408,36 @@ public interface ServiceConnection {
/**
* <i>[OPTIONAL]</i>
* <p>Get the type of each output limit set by this service connection (and accessible with {@link #getOutputLimit()}).</p>
* <p>
* Get the type of each output limit set by this service connection (and
* accessible with {@link #getOutputLimit()}).
* </p>
*
* <p><b>Important notes:</b></p>
* <ul>
* <li><b>Exactly 2 values or a NULL object is expected here.</b></li>
* <li><b>If NULL</b>, the output limit will be considered as expressed in ROWS.</li>
* <li><b>The structure of the object</b> returned by this function MUST be the same as the object returned by {@link #getOutputLimit()}.
* Particularly, the type given by the N-th item of this function must correspond to the N-th limit returned by {@link #getOutputLimit()}.</li>
* <li><b>If NULL</b>, the output limit will be considered as expressed in
* ROWS.</li>
* <li><b>The structure of the object</b> returned by this function MUST be
* the same as the object returned by {@link #getOutputLimit()}.
* Particularly, the type given by the N-th item of this function must
* correspond to the N-th limit returned by
* {@link #getOutputLimit()}.</li>
* </ul>
*
* <p><i><b>Important note:</b>
* Currently, the default implementations of the library is only able to deal with output limits in ROWS.<br/>
* Anyway, in order to save performances, it is strongly recommended to use ROWS limit rather than in bytes. Indeed, the rows limit can be taken
* into account at the effective execution of the query (so before getting the result), on the contrary of the bytes limit which
* will be applied on the query result.
* Currently, the default implementations of the library is only able to
* deal with output limits in ROWS.<br/>
* Anyway, in order to save performances, it is strongly recommended to use
* ROWS limit rather than in bytes. Indeed, the rows limit can be taken
* into account at the effective execution of the query (so before getting
* the result), on the contrary of the bytes limit which will be applied on
* the query result.
* </i></p>
*
* @return NULL if limits should be expressed in ROWS, or a two-items array ([0]: type of getOutputLimit()[0], [1]: type of getOutputLimit()[1]).
* @return NULL if limits should be expressed in ROWS, or a two-items array
* ([0]: type of getOutputLimit()[0],
* [1]: type of getOutputLimit()[1]).
*
* @see #getOutputLimit()
*/
......@@ -390,9 +445,13 @@ public interface ServiceConnection {
/**
* <i>[OPTIONAL]</i>
* <p>Get the object to use in order to identify users at the origin of requests.</p>
* <p>
* Get the object to use in order to identify users at the origin of
* requests.
* </p>
*
* @return NULL if no user identification should be done, a {@link UserIdentifier} instance otherwise.
* @return NULL if no user identification should be done,
* a {@link UserIdentifier} instance otherwise.
*/
public UserIdentifier getUserIdentifier();
......@@ -512,11 +571,13 @@ public interface ServiceConnection {
* <p>Get the list of all available tables and columns.</p>
*
* <p>
* This object is really important since it lets the library check ADQL queries properly and set the good type
* and formatting in the query results.
* This object is really important since it lets the library check ADQL
* queries properly and set the good type and formatting in the query
* results.
* </p>
*
* @return A TAPMetadata object. <b>NULL is not allowed and will throw a grave error at the service initialization.</b>
* @return A TAPMetadata object. <b>NULL is not allowed and will throw a
* grave error at the service initialization.</b>
*/
public TAPMetadata getTAPMetadata();
......@@ -528,25 +589,28 @@ public interface ServiceConnection {
*
* <p>Two special values can be returned by this function:</p>
* <ul>
* <li><b>NULL</b> which means that all coordinate systems are allowed,</li>
* <li><b>NULL</b> which means that all coordinate systems are
* allowed,</li>
* <li><b>the empty list</b> which means that no coordinate system - except
* the default one (which can be reduced to an empty string) - is allowed.</li>
* the default one (which can be reduced to an empty string) - is
* allowed.</li>
* </ul>
*
* <u><b>List item syntax</b></u>
*
* <p>
* Each item of this list is a <b>pattern</b> and not a simple coordinate system.
* Thus each item MUST respect the following syntax:
* Each item of this list is a <b>pattern</b> and not a simple coordinate
* system. Thus each item MUST respect the following syntax:
* </p>
* <pre>{framePattern} {refposPattern} {flavorPattern}</pre>
* <p>
* Contrary to a coordinate system expression, all these 3 information are required.
* Each may take 3 kinds of value:
* Contrary to a coordinate system expression, all these 3 information are
* required. Each may take 3 kinds of value:
* </p>
* <ul>
* <li>a single value (i.e. "ICRS"),</li>
* <li>a list of values with the syntax <code>({value1}|{value2}|...)</code> (i.e. "(ICRS|FK4)"),</li>
* <li>a list of values with the syntax
* <code>({value1}|{value2}|...)</code> (i.e. "(ICRS|FK4)"),</li>
* <li>a "*" which means that all values are possible.
* </ul>
* <p>
......@@ -554,12 +618,15 @@ public interface ServiceConnection {
* but not <code>ICRS</code> or <code>ICRS HELIOCENTER</code>.
* </p>
*
* <p><i>Note:
* Even if not explicitly part of the possible values, the default value of each part (i.e. UNKNOWNFRAME for frame) is always taken into account by the library.
* Particularly, the empty string will always be allowed even if not explicitly listed in the list returned by this function.
* <p><i><b>Note:</b>
* Even if not explicitly part of the possible values, the default value of
* each part (i.e. UNKNOWNFRAME for frame) is always taken into account by
* the library. Particularly, the empty string will always be allowed even
* if not explicitly listed in the list returned by this function.
* </i></p>
*
* @return NULL to allow ALL coordinate systems, an empty list to allow NO coordinate system,
* @return NULL to allow ALL coordinate systems, an empty list to allow NO
* coordinate system,
* or a list of coordinate system patterns otherwise.
*/
public Collection<String> getCoordinateSystems();
......@@ -572,20 +639,24 @@ public interface ServiceConnection {
*
* <p>Two special values can be returned by this function:</p>
* <ul>
* <li><b>NULL</b> which means that all geometrical functions are allowed,</li>
* <li><b>the empty list</b> which means that no geometrical functions is allowed.</li>
* <li><b>NULL</b> which means that all geometrical functions are
* allowed,</li>
* <li><b>the empty list</b> which means that no geometrical functions is
* allowed.</li>
* </ul>
*
* <u><b>List item syntax</b></u>
*
* <p>
* Each item of the returned list MUST be a function name (i.e. "CONTAINS", "POINT").
* It can also be a type of STC region to forbid (i.e. "POSITION", "UNION").
* Each item of the returned list MUST be a function name
* (i.e. "CONTAINS", "POINT"). It can also be a type of STC region to
* forbid (i.e. "POSITION", "UNION").
* </p>
*
* <p>The given names are not case sensitive.</p>
*
* @return NULL to allow ALL geometrical functions, an empty list to allow NO geometrical function,
* @return NULL to allow ALL geometrical functions, an empty list to allow
* NO geometrical function,
* or a list of geometrical function names otherwise.
*
* @since 2.0
......@@ -600,17 +671,21 @@ public interface ServiceConnection {
*
* <p>Two special values can be returned by this function:</p>
* <ul>
* <li><b>NULL</b> which means that all unknown functions (which should be UDFs) are allowed,</li>
* <li><b>the empty list</b> which means that no unknown functions (which should be UDFs) is allowed.</li>
* <li><b>NULL</b> which means that all unknown functions (which should be
* UDFs) are allowed,</li>
* <li><b>the empty list</b> which means that no unknown functions (which
* should be UDFs) is allowed.</li>
* </ul>
*
* <u><b>List item syntax</b></u>
*
* <p>
* Each item of the returned list MUST be an instance of {@link FunctionDef}.
* Each item of the returned list MUST be an instance of
* {@link FunctionDef}.
* </p>
*
* @return NULL to allow ALL unknown functions, an empty list to allow NO unknown function,
* @return NULL to allow ALL unknown functions, an empty list to allow NO
* unknown function,
* or a list of user defined functions otherwise.
*
* @since 2.0
......@@ -620,9 +695,15 @@ public interface ServiceConnection {
/**
* <i>[OPTIONAL]</i>
*
* <p>Get the maximum number of asynchronous jobs that can run in the same time.</p>
* <p>
* Get the maximum number of asynchronous jobs that can run in the same
* time.
* </p>
*
* <p>A null or negative value means <b>no limit</b> on the number of running asynchronous jobs.</p>
* <p>
* A null or negative value means <b>no limit</b> on the number of running
* asynchronous jobs.
* </p>
*
* @return Maximum number of running jobs (&le;0 => no limit).
*
......@@ -632,15 +713,20 @@ public interface ServiceConnection {
/**
* <i><b>[MANDATORY]</b></i>
* <p>Get the logger to use in the whole service when any error, warning or info happens.</p>
* <p>
* Get the logger to use in the whole service when any error, warning or
* info happens.
* </p>
*
* <p><b>IMPORTANT:
* If NULL is returned by this function, grave errors will occur while executing a query or managing an error.
* It is strongly recommended to provide a logger, even a basic implementation.
* If NULL is returned by this function, grave errors will occur while
* executing a query or managing an error. It is strongly recommended to
* provide a logger, even a basic implementation.
* </b></p>
*
* <p><i>Piece of advice:
* A default implementation like {@link DefaultTAPLog} would be most of time largely enough.
* <p><i><b>Piece of advice:</b>
* A default implementation like {@link DefaultTAPLog} would be most of
* time largely enough.
* </i></p>
*
* @return An instance of {@link TAPLog}.
......@@ -649,17 +735,23 @@ public interface ServiceConnection {
/**
* <i><b>[MANDATORY]</b></i>
* <p>Get the object able to build other objects essentials to configure the TAP service or to run every queries.</p>
* <p>
* Get the object able to build other objects essentials to configure the
* TAP service or to run every queries.
* </p>
*
* <p><b>IMPORTANT:
* If NULL is returned by this function, grave errors will occur while initializing the service.
* If NULL is returned by this function, grave errors will occur while
* initializing the service.
* </b></p>
*
* <p><i>Piece of advice:
* The {@link TAPFactory} is an interface which contains a lot of functions to implement.
* It is rather recommended to extend {@link AbstractTAPFactory}: just 2 functions
* ({@link AbstractTAPFactory#freeConnection(DBConnection)} and {@link AbstractTAPFactory#getConnection(String)})
* will have to be implemented.
* The {@link TAPFactory} is an interface which contains a lot of functions
* to implement. It is rather recommended to extend
* {@link AbstractTAPFactory}: just 2 functions
* ({@link AbstractTAPFactory#freeConnection(DBConnection)} and
* {@link AbstractTAPFactory#getConnection(String)}) will have to be
* implemented.
* </i></p>
*
* @return An instance of {@link TAPFactory}.
......@@ -670,16 +762,21 @@ public interface ServiceConnection {
/**
* <i><b>[MANDATORY]</b></i>
* <p>Get the object in charge of the files management.
* This object manages log, error, result and backup files of the whole service.</p>
* <p>
* Get the object in charge of the files management.
* This object manages log, error, result and backup files of the whole
* service.
* </p>
*
* <p><b>IMPORTANT:
* If NULL is returned by this function, grave errors will occur while initializing the service.
* If NULL is returned by this function, grave errors will occur while
* initializing the service.
* </b></p>
*
* <p><i>Piece of advice:
* The library provides a default implementation of the interface {@link UWSFileManager}:
* {@link LocalUWSFileManager}, which stores all files on the local file-system.
* <p><i><b>Piece of advice:</b>
* The library provides a default implementation of the interface
* {@link UWSFileManager}: {@link LocalUWSFileManager}, which stores all
* files on the local file-system.
* </i></p>
*
* @return An instance of {@link UWSFileManager}.
......@@ -694,7 +791,8 @@ public interface ServiceConnection {
* <ul>
* <li>All formats of this list MUST have a different MIME type.</li>
* <li>At least one item must correspond to the MIME type "votable".</li>
* <li>If NULL is returned by this function, grave errors will occur while writing the capabilities of this service.</li>
* <li>If NULL is returned by this function, grave errors will occur while
* writing the capabilities of this service.</li>
* </li>
*
* @return An iterator on the list of all available output formats.
......@@ -703,10 +801,14 @@ public interface ServiceConnection {
/**
* <i><b>[MANDATORY]</b></i>
* <p>Get the output format having the given MIME type (or short MIME type ~ alias).</p>
* <p>
* Get the output format having the given MIME type
* (or short MIME type ~ alias).
* </p>
*
* <p><b>IMPORTANT:
* This function MUST always return an {@link OutputFormat} instance when the MIME type "votable" is given in parameter.
* This function MUST always return an {@link OutputFormat} instance when
* the MIME type "votable" is given in parameter.
* </b></p>
*
* @param mimeOrAlias MIME type or short MIME type of the format to get.
......@@ -720,25 +822,31 @@ public interface ServiceConnection {
* <p>Get the size of result blocks to fetch from the database.</p>
*
* <p>
* Rather than fetching a query result in a whole, it may be possible to specify to the database
* that results may be retrieved by blocks whose the size can be specified by this function.
* If supported by the DBMS and the JDBC driver, this feature may help sparing memory and avoid
* too much waiting time from the TAP /sync users (and thus, avoiding some HTTP client timeouts).
* Rather than fetching a query result in a whole, it may be possible to
* specify to the database that results may be retrieved by blocks whose
* the size can be specified by this function. If supported by the DBMS and
* the JDBC driver, this feature may help sparing memory and avoid too much
* waiting time from the TAP /sync users (and thus, avoiding some HTTP
* client timeouts).
* </p>
*
* <p><i>Note:
* Generally, this feature is well supported by DBMS. But for that, the used JDBC driver must use
* the V3 protocol. If anyway, this feature is supported neither by the DBMS, the JDBC driver nor your
* {@link DBConnection}, no error will be thrown if a value is returned by this function: it will be silently
* ignored by the library.
* <p><i><b>Note:</b>
* Generally, this feature is well supported by DBMS. But for that, the
* used JDBC driver must use the V3 protocol. If anyway, this feature is
* supported neither by the DBMS, the JDBC driver nor your
* {@link DBConnection}, no error will be thrown if a value is returned by
* this function: it will be silently ignored by the library.
* </i></p>
*
* @return <i>null</i> or an array of 1 or 2 integers.
* If <i>null</i> (or empty array), no attempt to set fetch size will be done and so, ONLY the default
* value of the {@link DBConnection} will be used.
* [0]=fetchSize for async queries, [1]=fetchSize for sync queries.
* @return NULL or an array of 1 or 2 integers.
* If NULL (or empty array), no attempt to set fetch size
* will be done and so, ONLY the default value of the
* {@link DBConnection} will be used.
* [0]=fetchSize for async queries,
* [1]=fetchSize for sync queries.
* If [1] is omitted, it will be considered as equals to [0].
* If a fetchSize is negative or null, the default value of your JDBC driver will be used.
* If a fetchSize is negative or null, the default value of your
* JDBC driver will be used.
*
* @since 2.0
*/
......@@ -746,12 +854,15 @@ public interface ServiceConnection {
/**
* <i><b>[MANDATORY]</b></i>
* <p>This function tells whether TAP-Lib should automatically try to fix a
* query whose parsing failed because of a token error. After this fix
* attempt the query is parsed again for a last time.</p>
* <p>
* This function tells whether TAP-Lib should automatically try to fix a
* query whose parsing failed because of a token error. After this fix
* attempt the query is parsed again for a last time.
* </p>
*
* @return <i>true</i> to allow automatic fix attempt in case of error,
* <i>false</i> to disable this option.
* @return <code>true</code> to allow automatic fix attempt in case of
* error,
* <code>false</code> to disable this option.
*
* @since 2.3
*/
......
This diff is collapsed.
......@@ -56,6 +56,7 @@ import static tap.config.TAPConfiguration.KEY_MIN_LOG_LEVEL;
import static tap.config.TAPConfiguration.KEY_OUTPUT_FORMATS;
import static tap.config.TAPConfiguration.KEY_PROVIDER_NAME;
import static tap.config.TAPConfiguration.KEY_SERVICE_DESCRIPTION;
import static tap.config.TAPConfiguration.KEY_SYNC_EXECUTION_DURATION;
import static tap.config.TAPConfiguration.KEY_SYNC_FETCH_SIZE;
import static tap.config.TAPConfiguration.KEY_TAP_FACTORY;
import static tap.config.TAPConfiguration.KEY_UDFS;
......@@ -170,9 +171,9 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
/** Maximum number of asynchronous jobs that can run simultaneously. */
private int maxAsyncJobs = DEFAULT_MAX_ASYNC_JOBS;
/** Array of 2 integers: resp. default and maximum execution duration.
* <em>Both duration are expressed in milliseconds.</em> */
private int[] executionDuration = new int[2];
/** Array of 3 integers: resp. default, maximum and sync. execution
* durations. <em>All durations are expressed in milliseconds.</em> */
private int[] executionDuration = new int[3];
/** Array of 2 integers: resp. default and maximum retention period.
* <em>Both period are expressed in seconds.</em> */
private int[] retentionPeriod = new int[2];
......@@ -682,7 +683,7 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
* @throws TAPException If the corresponding TAP configuration properties are wrong.
*/
private void initExecutionDuration(final Properties tapConfig) throws TAPException {
executionDuration = new int[2];
executionDuration = new int[3];
// Set the default duration:
String propValue = getProperty(tapConfig, KEY_DEFAULT_EXECUTION_DURATION);
......@@ -700,10 +701,28 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
throw new TAPException("Integer expected for the property \"" + KEY_MAX_EXECUTION_DURATION + "\", instead of: \"" + propValue + "\"!");
}
// The maximum duration MUST be greater or equals than the default duration.
// If not, the default duration is set (so decreased) to the maximum duration.
// Set the synchronous duration:
propValue = getProperty(tapConfig, KEY_SYNC_EXECUTION_DURATION);
try {
executionDuration[2] = (propValue == null) ? DEFAULT_EXECUTION_DURATION : Integer.parseInt(propValue);
} catch(NumberFormatException nfe) {
throw new TAPException("Integer expected for the property \"" + KEY_SYNC_EXECUTION_DURATION + "\", instead of: \"" + propValue + "\"!");
}
/* The maximum duration MUST be greater or equals than the default
* duration. If not, the default duration is set (so decreased) to the
* maximum duration: */
if (executionDuration[1] > 0 && executionDuration[1] < executionDuration[0])
executionDuration[0] = executionDuration[1];
/* The synchronous duration MUST be less or equals than the default
* duration (or the max if no default is set). If not, the sync.
* duration is set (so decreased) to the default duration (or max if no
* default): */
if (executionDuration[0] > 0 && executionDuration[0] < executionDuration[2])
executionDuration[2] = executionDuration[0];
else if (executionDuration[0] <= 0 && executionDuration[1] > 0 && executionDuration[1] < executionDuration[2])
executionDuration[2] = executionDuration[1];
}
/**
......
This diff is collapsed.
......@@ -637,6 +637,40 @@
</td>
<td>3600000 <em>(1 hour)</em></td>
</tr>
<tr class="optional">
<td class="done">sync_execution_duration</td>
<td></td>
<td>integer</td>
<td>
<p>Execution duration (in milliseconds) for SYNCHRONOUS queries.</p>
<p>
If this property is set, it will be used as default and maximum execution
duration for synchronous queries. For asynchronous queries,
<code>default_execution_duration</code> and <code>max_execution_duration</code>
will still be used as expected.
</p>
<p>
<code>sync_execution_duration</code> MUST be less or equals to default_execution_duration.
Why? Because synchronous queries are supposed to be quicker than asynchronous
ones. If this rule is not respected, this execution duration is immediately
set to <code>default_execution_duration</code>.
</p>
<p>
A negative or null value means that the default execution duration will be
used instead. Float values are not allowed.
</p>
<p><em>Default: same as <code>default_execution_duration</code>.
But if <code>default_execution_duration</code> is not set, <code>max_execution_duration</code>
will be used.
If <code>max_execution_duration</code> is not set, the duration specified in the
HTTP request will be used.
And if no such duration is given either, an hard coded duration of
10 seconds will be applied in order to avoid unlimited synchronous
query.
</em></p>
</td>
<td>5000 <em>(5 seconds)</em></td>
</tr>
<tr><td colspan="5">Output</td></tr>
<tr class="optional">
......
......@@ -518,6 +518,32 @@ default_execution_duration = 0
# Default: there is no restriction => max_execution_duration=0.
max_execution_duration = 0
# [OPTIONAL]
# Execution duration (in milliseconds) for SYNCHRONOUS queries.
#
# If this property is set, it will be used as default and maximum execution
# duration for synchronous queries. For asynchronous queries,
# default_execution_duration and max_execution_duration will still be used as
# expected.
#
# sync_execution_duration MUST be less or equals to default_execution_duration.
# Why? Because synchronous queries are supposed to be quicker than asynchronous
# ones. If this rule is not respected, this execution duration is immediately
# set to default_execution_duration.
#
# A negative or null value means that the default execution duration will be
# used instead. Float values are not allowed.
#
# Default: same as default_execution_duration.
# But if default_execution_duration is not set, max_execution_duration
# will be used.
# If max_execution_duration is not set, the duration specified in the
# HTTP request will be used.
# And if no such duration is given either, an hard coded duration of
# 10 seconds will be applied in order to avoid unlimited synchronous
# query.
sync_execution_duration = 0
##########
# OUTPUT #
##########
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment