seleste Homepage

seleste API User's Guide

Availability

The TAP Client API allows users to access TAP service metadata pertaining to service availability through the Availability class. Metadata provided by the service may include uptime, downtime, time the service is expected back up, and notes on service availability. The Availability class models information supplied by the VOSI /availability endpoint. In the IVOA TAP Recommendation, VOSI /availability is recommended but not required. If a TAP service does not implement the /availability endpoint, the TapService.getAvailability may throw an HttpException to indicate the resource was not found.

	  
import java.io.IOException;
import edu.harvard.cfa.vo.tapclient.tap.TapService;
import edu.harvard.cfa.vo.tapclient.util.HttpException;
import edu.harvard.cfa.vo.tapclient.util.ResponseFormatException;
import edu.harvard.cfa.vo.tapclient.vosi.Availability;

void sampleCode(String baseURL) {
    try {
        // Create a TapService from the TAP service's baseURL
        TapService tapService = new TapService(baseURL);

        // Attempt to read the /availability resource.
        Availability availability = tapService.getAvailability();
        if (availability.isAvailable() {
            Calendar upSince = availability.getUpSince();
            // If a service reports that it is up, it still has no obligation 
            //   to report how long it has been up since.
            if (upSince != null) {
                DateFormat dateFormat = DateFormat.getInstance();
                logger.log(Level.INFO, "{1} has been up since {2}.", 
                           baseURL, 
                           dateFormat.format(upSince.getTime());
                
            } else {
                logger.log(Level.INFO, "{1} is available.", baseURL);
            } 
        }
    } catch (HttpException ex) {
        // The service returned an HTTP error code
        if (404 == ex.getStatusCode()) {
            logger.log(Level.INFO, "{1}: {2}", 
                       baseURL, 
                       "VOSI /availability endpoint is not implemented.");
        }
    } catch (ResponseFormatException ex) {
        // The service response was not in the expected format.
        ...
    } catch (IOException ex) {
        // An error occurred reading from or writing to the HTTP connection.
        ...
    }
}
	  
	

Capabilities

Access to TAP service capabilities meta data is provided by the Capabilities class. The Capabilities class models the information available through the VOSI /capabilities endpoint of a TAP service. By calling TapService.getCapabilities(), a user creates and populates a Capabilities instance the the service's /capabilities endpoint.

A service may choose to document which aspects of the IVOA TAP Recommendation are implemented in the /capabilities endpoint. If a service documents its capabilities with the IVOA TAP Registry Extension, the TAP Client API's TableAccess Capability can be used to inspect the /capabilities response to determine which version or version of ADQL the service supports:

	    
void sampleCode(TapService tapService) {
    Capabilities capabilities = tapService.getCapabilities();

    for (Capability capability: capabilities.getCapabilities()) {
        // A capability is an instance of the TAP Registry extension.
        if (capability instanceof TableAccess) {
            TableAccess tableAccess = (TableAccess) capability;
            for (Language language: tableAccess.getLanguages()) {
                for (Version version: language.getVersions()) {
                    logger.log(Level.INFO, "Supported language: {1} {2}",
                               language.getName(), 
                               version.getValue());
                }
            }
        }
    }
}
	    
	  

Tables

Tabular data are at the heart of a TAP service. However, when first accessing a service a user may not know anything about the contents of a service. The TAP Recommendation provides the VOSI /tables endpoint to give the user access to schema, table, column, and keys, their relationships, and their metadata. To access the /tables endpoint, TapService.getTableSet() sends a request the TAP service and returns a TableSet instance.

Assuming a TAP service provided sufficient metadata, a user could identify for tables contains equatorial positions for a possible cone search.

	  
sampleCode(TapService tapService) {
    try {
        TableSet tableSet = tapService.getTableSet();

        for (Schema schema: tableSet.getSchemas()) {
            for Table table: schema.getTables()) {
                Column ra = null;
                Column dec = null;

                for (Column column: table.getColumns()) {
                    if ("pos.eq.ra".equals(column.getUcd())) {
                        ra = column;
                    } else if ("pos.eq.dec".equals(column.getUcd())) {
                        dec = column;
                    }
                }

                if (ra != null && dec != null) {
                   StringBuilder query = new StringBuilder();
                   query.append("SELECT * FROM ");
                   query.append(table.getName());
                   query.append(" WHERE CONTAINS(POINT('ICRS GEOCENTER', ");
                   query.append(ra.getName());
                   query.append(", ");
                   query.append(dec.getName());
                   query.append("), CIRCLE('ICRS GEOCENTER', 25.4, -20.0, 1)) = 1)");
                   ...
                }
            }
        }

    } catch (HttpException ex) {
        // The service returned an HTTP error code
        if (404 == ex.getStatusCode()) {
            logger.log(Level.INFO, "{1}: {2}", 
                       baseURL, 
                       "VOSI /tables endpoint is not implemented.");
        }
    } catch (ResponseFormatException ex) {
        // The service response was not in the expected format.
        ...
    } catch (IOException ex) {
        // An error occurred reading from or writing to the HTTP connection.
        ...
    }
}
	  
	

Synchronous Query

The SyncJob class executes a synchronous query against a TAP service's /sync endpoint. The user may set the various parameters for a query as specified in the TAP Recommendation via the corresponding setter methods, e.g. setting the maxrec parameter to control the maximum number of records returned SyncJob.setMaxRec(int).

It should be noted that the TAP Recommendation requires services to return any errors encountered while executing a query in the form of a VOTable. As such, the SyncJob.run() method will return an InputStream containing the results on successful execution of the query or an InputStream containing the error on failure to execute the query.

	  
sampleCode(TapService tapService) {
    // Create a synchronous query using the SyncJob defaults for results format
    //   and query language.
    SyncJob syncJob = new SyncJob(tapService);

    // Set the query.
    syncJob.setQuery("SELECT * from TAP_SCHEMA.tables");

    try {
        InputStream inputStream = syncJob.run();
        // Process the input stream.
        //   The default results format for the SyncJob is VOTable 1.2
        //   If the query failed, this stream contains the error document.
        ...
        
    } catch (HttpException ex) {
        // Service responded with an HTTP error code
        ...
    } catch (IOException ex) {
        // An error occurred writing to or reading from the HTTP connection.
        ...
    } finally {
        inputStream.close();
    }
}
	  
	

Asynchronous Query

The AsyncJob class creates, modifies, and executes an asynchronous query against a TAP service's /async endpoint. The user may create new queries or access existing queries on a given TAP service. To create a new query, the AsyncJob is created without a job identifier. The service will create a new job and assign its identifier to this asynchronous query. Alternatively, if the user is accessing a previous created asynchronous query, the job identifier is supplied when creating the AsynJob.

For asynchronous queries, a user may monitor the execution phase of the query for completion or errors. The AsyncJob.getPhase() will indicate what phase the query is in on the TAP service. To start a query running, the user will need to AsyncJob.run() or AsyncJob.setPhase("RUN") an asynchronous query.

Upon successful completion of a query, a TAP service will make additional resources, such as the results, avaiable to the AsyncJob. The AsyncJob allows the user to retrieve the results via the AsyncJob.getResult() method. As the TAP Recommendation is based upon the IVOA UWS Recommendation, there is also access to the results list. A list of all results generated by an asynchronous query is accessible through the AsyncJob.getResults() method.

	  
sampleCode(TapService tapService) {
    // Create an asynchronous query using the AsyncJob
    AsyncJob syncJob = new AsyncJob(tapService);

    // Set the query.
    asyncJob.setFormat("votable");
    asyncJob.setLang("ADQL");
    asyncJob.setQuery("SELECT * from TAP_SCHEMA.tables");

    try {
        asyncJob.run();

        while (!asyncJob.isFinished()) {
            Thread.sleep(someAmountOfTime);
            asyncJob.synchronize();
        }
        
        if (asyncJob.isCompleted()) {
            // Get the results
            Result result = asyncJob.getResult();
            InputStream resultStream = result.openStream();
            ...

        } else if (asyncJob.isError()) {
            // Your job failed.  Let see if the service told you why...
            Error error = asyncJob.getError();
            logger.log(Level.INFO, "Error type: {1}, Error message: {2}", error.getType(), error.getMessage();
            if (error.isDetailedErrorAvailable()) {
                // The service provided additional error information through a separate resource.
                InputStream errorStream = error.openStream();
                ...
            }
        } else if (asyncJob.isAborted()) {
            // Your job was aborted...
            //   Did you give someone access to your jobId? 
        }
        
    } catch (HttpException ex) {
        // Service responded with an HTTP error code
        ...
    } catch (ResponseFormatException ex) {
        // Service sent an unexpected response
        ...
    } catch (IOException ex) {
        // An error occurred writing to or reading from the HTTP connection.
        ...
    } finally {
        inputStream.close();
    }
}