package tap;
/*
* This file is part of TAPLibrary.
*
* TAPLibrary is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* TAPLibrary is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with TAPLibrary. If not, see
* Through this object, it is possible to configure the different limits and * formats, but also to list all available tables and columns, to declare * geometry features as well as all allowed user defined functions and to say * where log and other kinds of files must be stored. *
* * @author Grégory Mantelet (CDS;ARI) * @version 2.4 (08/2020) */ public interface ServiceConnection { /** * List of possible limit units. * * @author Grégory Mantelet (CDS;ARI) * @version 2.3 (04/2019) */ public static enum LimitUnit { rows("row"), bytes("byte"), kilobytes("kilobyte"), megabytes("megabyte"), gigabytes("gigabyte"); private final String str; private LimitUnit(final String str) { this.str = str; } /** * Tells whether the given unit has the same type (bytes or rows). * * @param anotherUnit A unit. * * @returntrue
if the given unit has the same type,
* false
otherwise.
*
* @since 1.1
*/
public boolean isCompatibleWith(final LimitUnit anotherUnit) {
if (this == rows)
return anotherUnit == rows;
else
return anotherUnit != rows;
}
/**
* Gets the factor to convert into bytes the value expressed in this
* unit.
*
* Note: * if this unit is not a factor of bytes, 1 is returned (so that the * factor does not affect the value). *
* * @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) { case bytes: return 1; case kilobytes: return 1000; case megabytes: return 1000000; case gigabytes: return 1000000000l; default: return 1; } } /** * Compares the 2 given values (each one expressed in the given unit). * ** Conversions are done internally in order to make a correct * comparison between the 2 limits. *
* * @param leftLimit Value/Limit of the comparison left part. * @param leftUnit Unit of the comparison left part value. * @param rightLimit Value/Limit of the comparison right part. * @param rightUnit Unit of the comparison right part value. * * @return the value 0 if x == y; a value less than 0 if x < y; * and a value greater than 0 if x > y * * @throws TAPException If the two given units are not compatible. * * @see #compare(long, tap.ServiceConnection.LimitUnit, long, tap.ServiceConnection.LimitUnit) * * @since 1.1 */ 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); } /** * Compares the 2 given values (each one expressed in the given unit). * ** Conversions are done internally in order to make a correct * comparison between the 2 limits. *
* * @param leftLimit Value/Limit of the comparison left part. * @param leftUnit Unit of the comparison left part value. * @param rightLimit Value/Limit of the comparison right part. * @param rightUnit Unit of the comparison right part value. * * @return the value 0 if x == y; * a value less than 0 if x < y; * and a value greater than 0 if x > y * * @throws TAPException If the two given units are not compatible. * * @see tap.ServiceConnection.LimitUnit#isCompatibleWith(tap.ServiceConnection.LimitUnit) * @see #bytesFactor() * @see Integer#compare(int, int) * @see Long#compare(long, long) * * @since 2.3 */ 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!"); if (leftUnit == rows || leftUnit == rightUnit) return compare(leftLimit, rightLimit); else return compare(leftLimit * leftUnit.bytesFactor(), rightLimit * rightUnit.bytesFactor()); } /** *(Strict copy of Integer.compare(long,long) of Java 1.7)
** Compares two {@code long} values numerically. * The value returned is identical to what would be returned by: *
** Long.valueOf(x).compareTo(Long.valueOf(y)) ** * @param x the first {@code long} to compare * @param y the second {@code long} 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 */ public static int compare(long x, long y) { return (x < y) ? -1 : ((x == y) ? 0 : 1); } @Override public String toString() { return str; } } /** * [OPTIONAL] *
* Name of the service provider ; it can be an organization as an * individual person. *
* ** There is no restriction on the syntax or on the label to use ; this * information is totally free. *
* ** It will be used as additional information (INFO tag) in any VOTable and * HTML output. *
* * @return The TAP service provider or NULL to leave this field blank. */ public String getProviderName(); /** * [OPTIONAL] *Description of the service provider.
* ** It will be used as additional information (INFO tag) in any VOTable * output. *
* * @return The TAP service description or NULL to leave this field blank. */ public String getProviderDescription(); /** * [MANDATORY] ** 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). *
* ** A message explaining the current state of the TAP service could be * provided thanks to {@link #getAvailability()}. *
* * @returntrue
to enable all TAP resources,
* false
to disable all of them (except /availability)
*/
public boolean isAvailable();
/**
* [OPTIONAL]
* * 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. *
* * @return Explanation about the TAP service state. */ public String getAvailability(); /** * [MANDATORY] *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.
*
true
to enable all resources,
* false
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
*/
public void setAvailable(final boolean isAvailable, final String message);
/**
* [OPTIONAL]
* Get the limit of the retention period (in seconds).
* ** It is the maximum period while an asynchronous job can leave in the jobs * list and so can stay on the server. *
* *Important notes:
*Get the limit of the job execution duration (in milliseconds).
* ** It is the duration of a running job (including the query execution). * The two first values are used for asynchronous jobs, and the last one * (if provided) for synchronous jobs. *
* *Important notes:
*Get the limit of the job execution result.
* ** 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()}. *
* *Important notes:
*Important note:
* Currently, the default implementations of the library is only able to
* deal with output limits in ROWS.
* 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.
*
* Get the type of each output limit set by this service connection (and * accessible with {@link #getOutputLimit()}). *
* *Important notes:
*Important note:
* Currently, the default implementations of the library is only able to
* deal with output limits in ROWS.
* 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.
*
* Get the object to use in order to identify users at the origin of * requests. *
* * @return NULL if no user identification should be done, * a {@link UserIdentifier} instance otherwise. */ public UserIdentifier getUserIdentifier(); public QueryExecutor getQueryExecutor(); /** * [MANDATORY] *This function lets enable or disable the upload capability of this TAP * service.
* *Note: * If the upload is disabled, the request is aborted and an HTTP-400 error * is thrown each time some tables are uploaded. *
* * @return true to enable the upload capability, * false to disable it. */ public boolean uploadEnabled(); /** * [OPTIONAL] *Get the maximum size of EACH uploaded table.
* ** This value is expressed either in rows or in bytes. * The unit limit is defined by the function {@link #getUploadLimitType()}. *
* *Important notes:
*Important note: * To save performances, it is recommended to use BYTES limit rather than * in rows. Indeed, the bytes limit can be taken into account at directly * when reading the bytes of the request, on the contrary of the rows limit * which requires to parse the uploaded tables. *
* * @return NULL if no limit must be set, * or a two-items array ([0]: default value, [1]: maximum value). * * @see #getUploadLimitType() */ public long[] getUploadLimit(); /** * [OPTIONAL] *Get the type of each upload limit set by this service connection (and * accessible with {@link #getUploadLimit()}).
* *Important notes:
*Important note: * To save performances, it is recommended to use BYTES limit rather than * in rows. Indeed, the bytes limit can be taken into account at directly * when reading the bytes of the request, on the contrary of the rows limit * which requires to parse the uploaded tables. *
* * @return NULL if limits should be expressed in ROWS, * or a two-items array ([0]: type of getUploadLimit()[0], * [1]: type of getUploadLimit()[1]). * * @see #getUploadLimit() */ public LimitUnit[] getUploadLimitType(); /** * [OPTIONAL] *Get the maximum size of the whole set of all tables uploaded in one * request. This size is expressed in bytes.
* *NOTE: * This value can be negative. In such case, there will be no limit on the * size of an HTTP request. *
* * @return A positive value (>0) corresponding to the maximum number of * bytes of all uploaded tables sent in one request. * A negative value (≤0) means "unlimited". */ public long getMaxUploadSize(); /** * [MANDATORY] *Get the list of all available tables and columns.
* ** 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. *
* * @return A TAPMetadata object. NULL is not allowed and will throw a * grave error at the service initialization. */ public TAPMetadata getTAPMetadata(); /** * [OPTIONAL] *Get the list of all allowed coordinate systems.
* * Special values * *Two special values can be returned by this function:
** Each item of this list is a pattern and not a simple coordinate * system. Thus each item MUST respect the following syntax: *
*{framePattern} {refposPattern} {flavorPattern}*
* Contrary to a coordinate system expression, all these 3 information are * required. Each may take 3 kinds of value: *
*({value1}|{value2}|...)
(i.e. "(ICRS|FK4)"),
* For instance: (ICRS|FK4) HELIOCENTER *
is a good syntax,
* but not ICRS
or ICRS HELIOCENTER
.
*
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. *
* * @return NULL to allow ALL coordinate systems, an empty list to allow NO * coordinate system, * or a list of coordinate system patterns otherwise. */ public CollectionGet the list of all allowed geometrical functions.
* * Special values * *Two special values can be returned by this function:
** 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"). *
* *The given names are not case sensitive.
* * @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 */ public CollectionGet the list of all allowed User Defined Functions (UDFs).
* * Special values * *Two special values can be returned by this function:
** Each item of the returned list MUST be an instance of * {@link FunctionDef}. *
* * @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 */ public Collection* Get the maximum number of asynchronous jobs that can run in the same * time. *
* ** A null or negative value means no limit on the number of running * asynchronous jobs. *
* * @return Maximum number of running jobs (≤0 => no limit). * * @since 2.0 */ public int getNbMaxAsyncJobs(); /** * [MANDATORY] ** Get the logger to use in the whole service when any error, warning or * info happens. *
* *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. *
* *Piece of advice: * A default implementation like {@link DefaultTAPLog} would be most of * time largely enough. *
* * @return An instance of {@link TAPLog}. */ public TAPLog getLogger(); /** * [MANDATORY] ** Get the object able to build other objects essentials to configure the * TAP service or to run every queries. *
* *IMPORTANT: * If NULL is returned by this function, grave errors will occur while * initializing the service. *
* *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. *
* * @return An instance of {@link TAPFactory}. * * @see AbstractTAPFactory */ public TAPFactory getFactory(); /** * [MANDATORY] ** Get the object in charge of the files management. * This object manages log, error, result and backup files of the whole * service. *
* *IMPORTANT: * If NULL is returned by this function, grave errors will occur while * initializing the service. *
* *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. *
* * @return An instance of {@link UWSFileManager}. */ public UWSFileManager getFileManager(); /** * [MANDATORY] *Get the list of all available output formats.
* *IMPORTANT:
** Get the output format having the given MIME type * (or short MIME type ~ alias). *
* *IMPORTANT: * This function MUST always return an {@link OutputFormat} instance when * the MIME type "votable" is given in parameter. *
* * @param mimeOrAlias MIME type or short MIME type of the format to get. * * @return The corresponding {@link OutputFormat} or NULL if not found. */ public OutputFormat getOutputFormat(final String mimeOrAlias); /** * [OPTIONAL] *Get the size of result blocks to fetch from the database.
* ** 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). *
* *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. *
* * @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. * * @since 2.0 */ public int[] getFetchSize(); /** * [MANDATORY] ** 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. *
* * @returntrue
to allow automatic fix attempt in case of
* error,
* false
to disable this option.
*
* @since 2.3
*/
public boolean fixOnFailEnabled();
}