diff --git a/src/tap/config/DefaultServiceConnection.java b/src/tap/config/DefaultServiceConnection.java index f2470d0332de7fd8cc84aa8337f338dae0b34ae8..c6598a0417ae37fb30c98d128e8c133fb9d409b7 100644 --- a/src/tap/config/DefaultServiceConnection.java +++ b/src/tap/config/DefaultServiceConnection.java @@ -17,22 +17,27 @@ import static tap.config.TAPConfiguration.KEY_MAX_EXECUTION_DURATION; import static tap.config.TAPConfiguration.KEY_MAX_OUTPUT_LIMIT; import static tap.config.TAPConfiguration.KEY_MAX_RETENTION_PERIOD; import static tap.config.TAPConfiguration.KEY_MAX_UPLOAD_LIMIT; +import static tap.config.TAPConfiguration.KEY_METADATA; +import static tap.config.TAPConfiguration.KEY_METADATA_FILE; 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_UPLOAD_ENABLED; import static tap.config.TAPConfiguration.KEY_UPLOAD_MAX_FILE_SIZE; import static tap.config.TAPConfiguration.VALUE_CSV; +import static tap.config.TAPConfiguration.VALUE_DB; import static tap.config.TAPConfiguration.VALUE_JSON; import static tap.config.TAPConfiguration.VALUE_LOCAL; import static tap.config.TAPConfiguration.VALUE_SV; import static tap.config.TAPConfiguration.VALUE_TSV; +import static tap.config.TAPConfiguration.VALUE_XML; import static tap.config.TAPConfiguration.fetchClass; import static tap.config.TAPConfiguration.getProperty; import static tap.config.TAPConfiguration.isClassPath; import static tap.config.TAPConfiguration.parseLimit; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -41,6 +46,7 @@ import java.util.Properties; import tap.ServiceConnection; import tap.TAPException; import tap.TAPFactory; +import tap.db.DBConnection; import tap.formatter.JSONFormat; import tap.formatter.OutputFormat; import tap.formatter.SVFormat; @@ -48,6 +54,7 @@ import tap.formatter.VOTableFormat; import tap.log.DefaultTAPLog; import tap.log.TAPLog; import tap.metadata.TAPMetadata; +import tap.metadata.TableSetParser; import uws.UWSException; import uws.service.UserIdentifier; import uws.service.file.LocalUWSFileManager; @@ -62,6 +69,8 @@ public final class DefaultServiceConnection implements ServiceConnection { private DefaultTAPFactory tapFactory; + private final TAPMetadata metadata; + private final String providerName; private final String serviceDescription; @@ -93,13 +102,16 @@ public final class DefaultServiceConnection implements ServiceConnection { // 3. BUILD THE TAP FACTORY: tapFactory = new DefaultTAPFactory(this, tapConfig); - // 4. SET ALL GENERAL SERVICE CONNECTION INFORMATION: + // 4. GET THE METADATA: + metadata = initMetadata(tapConfig); + + // 5. SET ALL GENERAL SERVICE CONNECTION INFORMATION: providerName = getProperty(tapConfig, KEY_PROVIDER_NAME); serviceDescription = getProperty(tapConfig, KEY_SERVICE_DESCRIPTION); initRetentionPeriod(tapConfig); initExecutionDuration(tapConfig); - // 5. CONFIGURE OUTPUT: + // 6. CONFIGURE OUTPUT: // default output format = VOTable: outputFormats = new ArrayList<OutputFormat>(1); outputFormats.add(new VOTableFormat(this)); @@ -108,7 +120,7 @@ public final class DefaultServiceConnection implements ServiceConnection { // set output limits: initOutputLimits(tapConfig); - // 6. CONFIGURE THE UPLOAD: + // 7. CONFIGURE THE UPLOAD: // is upload enabled ? isUploadEnabled = Boolean.parseBoolean(getProperty(tapConfig, KEY_UPLOAD_ENABLED)); // set upload limits: @@ -116,7 +128,7 @@ public final class DefaultServiceConnection implements ServiceConnection { // set the maximum upload file size: initMaxUploadSize(tapConfig); - // 7. MAKE THE SERVICE AVAILABLE: + // 8. MAKE THE SERVICE AVAILABLE: setAvailable(true, "TAP service available."); } @@ -168,6 +180,56 @@ public final class DefaultServiceConnection implements ServiceConnection { } } + private TAPMetadata initMetadata(final Properties tapConfig) throws TAPException{ + // Get the fetching method to use: + String metaFetchType = getProperty(tapConfig, KEY_METADATA); + if (metaFetchType == null) + throw new TAPException("The property \"" + KEY_METADATA + "\" is missing! It is required to create a TAP Service. Two possible values: " + VALUE_XML + " (to get metadata from a TableSet XML document) or " + VALUE_DB + " (to fetch metadata from the database schema TAP_SCHEMA)."); + + TAPMetadata metadata = null; + + // GET METADATA FROM XML & UPDATE THE DATABASE (schema TAP_SCHEMA only): + if (metaFetchType.equalsIgnoreCase(VALUE_XML)){ + // Get the XML file path: + String xmlFilePath = getProperty(tapConfig, KEY_METADATA_FILE); + if (xmlFilePath == null) + throw new TAPException("The property \"" + KEY_METADATA_FILE + "\" is missing! According to the property \"" + KEY_METADATA + "\", metadata must be fetched from an XML document. The local file path of it MUST be provided using the property \"" + KEY_METADATA_FILE + "\"."); + + // Parse the XML document and build the corresponding metadata: + try{ + metadata = (new TableSetParser()).parse(new File(xmlFilePath)); + }catch(IOException ioe){ + throw new TAPException("A grave error occurred while reading/parsing the TableSet XML document: \"" + xmlFilePath + "\"!", ioe); + } + + // Update the database: + DBConnection conn = null; + try{ + conn = tapFactory.getConnection("SET_TAP_SCHEMA"); + conn.setTAPSchema(metadata); + }finally{ + if (conn != null) + tapFactory.freeConnection(conn); + } + } + // GET METADATA FROM DATABASE (schema TAP_SCHEMA): + else if (metaFetchType.equalsIgnoreCase(VALUE_DB)){ + DBConnection conn = null; + try{ + conn = tapFactory.getConnection("GET_TAP_SCHEMA"); + metadata = conn.getTAPSchema(); + }finally{ + if (conn != null) + tapFactory.freeConnection(conn); + } + } + // INCORRECT VALUE => ERROR! + else + throw new TAPException("Unsupported value for the property \"" + KEY_METADATA + "\": \"" + metaFetchType + "\"! Only two values are allowed: " + VALUE_XML + " (to get metadata from a TableSet XML document) or " + VALUE_DB + " (to fetch metadata from the database schema TAP_SCHEMA)."); + + return metadata; + } + private void initRetentionPeriod(final Properties tapConfig){ retentionPeriod = new int[2]; @@ -550,8 +612,7 @@ public final class DefaultServiceConnection implements ServiceConnection { @Override public TAPMetadata getTAPMetadata(){ - // TODO GET METADATA - return null; + return metadata; } @Override diff --git a/src/tap/config/DefaultTAPFactory.java b/src/tap/config/DefaultTAPFactory.java index ee3e3d24909b0eff16ec4ef749e66c2b5ab587d1..399c891d52775ad264e5c4d050c4240bf5060771 100644 --- a/src/tap/config/DefaultTAPFactory.java +++ b/src/tap/config/DefaultTAPFactory.java @@ -52,7 +52,7 @@ public final class DefaultTAPFactory extends AbstractTAPFactory { String dbUrl = getProperty(tapConfig, KEY_JDBC_URL); if (jdbcDriver == null){ if (dbUrl == null) - throw new TAPException("JDBC URL missing."); + throw new TAPException("The property \"" + KEY_JDBC_URL + "\" is missing!"); else if (!dbUrl.startsWith(JDBCConnection.JDBC_PREFIX + ":")) throw new TAPException("JDBC URL format incorrect! It MUST begins with " + JDBCConnection.JDBC_PREFIX + ":"); else{ @@ -70,8 +70,8 @@ public final class DefaultTAPFactory extends AbstractTAPFactory { /* 1. Set the ADQLTranslator to use in function of the sql_translator property */ String sqlTranslator = getProperty(tapConfig, KEY_SQL_TRANSLATOR); // case a.) no translator specified - if (sqlTranslator == null || sqlTranslator.isEmpty()) - throw new TAPException("No SQL translator specified !"); + if (sqlTranslator == null) + throw new TAPException("The property \"" + KEY_SQL_TRANSLATOR + "\" is missing! ADQL queries can not be translated without it. Allowed values: \"" + VALUE_POSTGRESQL + "\", \"" + VALUE_PGSPHERE + "\" or a class path of a class implementing SQLTranslator."); // case b.) PostgreSQL translator else if (sqlTranslator.equalsIgnoreCase(VALUE_POSTGRESQL)) diff --git a/src/tap/config/TAPConfiguration.java b/src/tap/config/TAPConfiguration.java index 4c9debc4fc42c283a85dd77293ad26b85c3041f8..96f42fbde362e12b8e8a023767613ed43a8afb40 100644 --- a/src/tap/config/TAPConfiguration.java +++ b/src/tap/config/TAPConfiguration.java @@ -53,6 +53,12 @@ public final class TAPConfiguration { public final static String KEY_DB_USERNAME = "db_username"; public final static String KEY_DB_PASSWORD = "db_password"; + /* METADATA KEYS */ + public final static String KEY_METADATA = "metadata"; + public final static String VALUE_XML = "xml"; + public final static String VALUE_DB = "db"; + public final static String KEY_METADATA_FILE = "metadata_file"; + /* PROVIDER KEYS */ public final static String KEY_PROVIDER_NAME = "provider_name"; public final static String KEY_SERVICE_DESCRIPTION = "service_description"; @@ -74,9 +80,11 @@ public final class TAPConfiguration { public final static String KEY_MAX_OUTPUT_LIMIT = "output_max_limit"; /** - * Read the asked property from the given Properties object. - * - The returned property value is trimmed (no space at the beginning and at the end of the string). - * - If the value is empty (length=0), NULL is returned. + * <p>Read the asked property from the given Properties object.</p> + * <ul> + * <li>The returned property value is trimmed (no space at the beginning and at the end of the string).</li> + * <li>If the value is empty (length=0), NULL is returned.</li> + * </ul> * * @param prop List of property * @param key Property whose the value is requested. @@ -242,7 +250,7 @@ public final class TAPConfiguration { FileInputStream configFileStream = null; try{ - final File configFile = new File("src/ext/tap_min.properties"); + final File configFile = new File("src/tap/config/tap_min.properties"); configFileStream = new FileInputStream(configFile); Properties config = new Properties(); diff --git a/src/tap/config/tap_configuration_file.html b/src/tap/config/tap_configuration_file.html index 30d3d6bfb7750052b3732f57fb249d4cc6a11dca..94954c46e898d2bbb46675e3fc50681b01270a86 100644 --- a/src/tap/config/tap_configuration_file.html +++ b/src/tap/config/tap_configuration_file.html @@ -161,6 +161,19 @@ <td></td> </tr> <tr class="mandatory"> + <td class="done">sql_translator</td> + <td>M</td> + <td>text</td> + <td> + <p>The translator to use in order to translate ADQL to a SQL compatible with the used DBMS and its spatial extension.</p> + <p>The TAP library supports only Postgresql (without spatial extension) and PgSphere for the moment. But you can provide your own SQL translator + (even if it does not have spatial features), by providing a path to a class (within brackets: {...}) that implements ADQLTranslator and which have at least an empty constructor.</p> + </td> + <td><ul><li>postgres</li><li>pgsphere</li><li>{apackage.MyADQLTranslator}</li></ul></td> + </tr> + + <tr><td colspan="5">Metadata</td></tr> + <!-- tr class="mandatory"> <td class="later">db_tables</td> <td>M</td> <td>text</td> @@ -171,17 +184,30 @@ This list is not mandatory, but if provided it must be within parenthesis and comma separated.</p> </td> <td>schema1.*, schema2.table1, table2, table3(col1, col2, col4, ...)</td> - </tr> + </tr --> <tr class="mandatory"> - <td class="done">sql_translator</td> + <td class="done">metadata</td> <td>M</td> <td>text</td> <td> - <p>The translator to use in order to translate ADQL to a SQL compatible with the used DBMS and its spatial extension.</p> - <p>The TAP library supports only Postgresql (without spatial extension) and PgSphere for the moment. But you can provide your own SQL translator - (even if it does not have spatial features), by providing a path to a class (within brackets: {...}) that implements ADQLTranslator and which have at least an empty constructor.</p> + <p>Define the way the library must get the list of all schemas, tables and columns to publish and all their metadata (e.g. utype, description, type, ...)</p> + <p>In its current state, the library proposes two methods:</p> + <ol> + <li>Parse a TableSet XML document and load its content into the database schema TAP_SCHEMA (note: this schema is first erased and rebuilt by the library).</li> + <li>Get all metadata from the database schema TAP_SCHEMA.</li> + </ol> </td> - <td><ul><li>postgres</li><li>pgsphere</li><li>{apackage.MyADQLTranslator}</li></ul></td> + <td><ul><li>xml</li><li>db</li></ul> + </tr> + <tr> + <td class="done">metadata_file</td> + <td></td> + <td>text</td> + <td> + <p><b>Mandatory if</b> the value of "metadata" is "xml".</p> + <p>Local file path to the TableSet XML document. This XML must implement the schema TableSet defined by <a href="http://www.ivoa.net/xml/VODataService/v1.1">VODataService</a>.</p> + </td> + <td>/home/foo/my_metadata.xml</td> </tr> <tr><td colspan="5">Files</td></tr> diff --git a/src/tap/config/tap_full.properties b/src/tap/config/tap_full.properties index c12b28306542566b39df8e5fdd982230a1a96a32..886c6a293952e1708a67add32454ba8d40e1918b 100644 --- a/src/tap/config/tap_full.properties +++ b/src/tap/config/tap_full.properties @@ -2,7 +2,7 @@ # FULL TAP CONFIGURATION FILE # # # # TAP Version: 2.0 # -# Date: 27 Jan. 2015 # +# Date: 09 Feb. 2015 # # Author: Gregory Mantelet (ARI) # # # # See the TAP documentation for more details: ...TODO... # @@ -56,17 +56,6 @@ db_username = # Note: No password encryption can be done in this configuration file for the moment. db_password = -# [MANDATORY] -# List all tables that must be accessed thanks to this TAP Service. -# -# Table names must be separated by a comma. A table name may explicitly specify the schema (if not, the table will be considered as part of the "public" schema). -# -# For each table, you can restrict the list of columns that you to expose via the TAP Service. This list is not mandatory, but if provided it must be -# within parenthesis and comma separated. -# -# Example: schema1.*, schema2.table1, table2, table3(col1, col2, col4, ...) -db_tables = - # [MANDATORY] # The translator to use in order to translate ADQL to a SQL compatible with the used DBMS and its spatial extension. # The TAP library supports only Postgresql (without spatial extension) and PgSphere for the moment. But you can provide your own SQL translator @@ -75,6 +64,23 @@ db_tables = # Allowed values: postgres, pgsphere, a class path sql_translator = postgres +############ +# METADATA # +############ + +# [MANDATORY] +# Metadata fetching method. The value of this key defines the way the library will get the list of all schemas, tables and columns to publish and all their metadata (e.g. utype, description, type, ...) +# In its current state, the library proposes two methods: +# 1/ Parse a TableSet XML document and load its content into the database schema TAP_SCHEMA (note: this schema is first erased and rebuilt by the library). +# 2/ Get all metadata from the database schema TAP_SCHEMA. +# Allowed values: xml, db. +metadata = + +# [MANDATORY] +# Mandatory if the value of "metadata" is "xml". +# Local file path to the TableSet XML document. This XML must implement the schema TableSet defined by VODataService (http://www.ivoa.net/xml/VODataService/v1.1). +metadata_file = + ######### # FILES # ######### diff --git a/src/tap/config/tap_min.properties b/src/tap/config/tap_min.properties index 29de929620a46ca868480b2ad13f1ed2ed4d54a8..62dffb56b3d6174800942bb88a00d799b2ea10e1 100644 --- a/src/tap/config/tap_min.properties +++ b/src/tap/config/tap_min.properties @@ -1,8 +1,8 @@ ########################################################## # MINIMUM TAP CONFIGURATION FILE # # # -# TAP Version: 1.1 # -# Date: 20 Nov. 2013 # +# TAP Version: 2.0 # +# Date: 09 Feb. 2015 # # Author: Gregory Mantelet (ARI) # # # # See the TAP documentation for more details: ...TODO... # @@ -30,17 +30,7 @@ db_user = # Mandatory if the password is not already provided in jdbc_url # Password used by db_username to access to the database. # Note: No password encryption can be done in this configuration file for the moment. -db_password = - -# List all tables that must be accessed thanks to this TAP Service. -# -# Table names must be separated by a comma. A table name may explicitly specify the schema (if not, the table will be considered as part of the "public" schema). -# -# For each table, you can restrict the list of columns that you to expose via the TAP Service. This list is not mandatory, but if provided it must be -# within parenthesis and comma separated. -# -# Example: schema1.*, schema2.table1, table2, table3(col1, col2, col4, ...) -db_tables = +db_password = # The translator to use in order to translate ADQL to a SQL compatible with the used DBMS and its spatial extension. # The TAP library supports only Postgresql (without spatial extension) and PgSphere for the moment. But you can provide your own SQL translator @@ -49,6 +39,21 @@ db_tables = # Allowed values: postgres, pgsphere, a class path sql_translator = postgres +############ +# METADATA # +############ + +# Metadata fetching method. The value of this key defines the way the library will get the list of all schemas, tables and columns to publish and all their metadata (e.g. utype, description, type, ...) +# In its current state, the library proposes two methods: +# 1/ Parse a TableSet XML document and load its content into the database schema TAP_SCHEMA (note: this schema is first erased and rebuilt by the library). +# 2/ Get all metadata from the database schema TAP_SCHEMA. +# Allowed values: xml, db. +metadata = + +# Mandatory if the value of "metadata" is "xml". +# Local file path to the TableSet XML document. This XML must implement the schema TableSet defined by VODataService (http://www.ivoa.net/xml/VODataService/v1.1). +metadata_file = + ######### # FILES # ######### diff --git a/test/tap/config/AllTests.java b/test/tap/config/AllTests.java index e3a5b989e71ca3cd2d62f0101bcd353e3b99daa8..dffc3cf400393a0431b9c6a62de55c8560930eea 100644 --- a/test/tap/config/AllTests.java +++ b/test/tap/config/AllTests.java @@ -18,8 +18,8 @@ public class AllTests { validProp.setProperty("jdbc_driver", "org.postgresql.Driver"); validProp.setProperty("db_username", "gmantele"); validProp.setProperty("db_password", "pwd"); - validProp.setProperty("db_tables", ""); validProp.setProperty("sql_translator", "postgres"); + validProp.setProperty("metadata", "db"); validProp.setProperty("file_manager", "local"); validProp.setProperty("file_root_path", "bin/ext/test/tap"); return validProp; diff --git a/test/tap/config/TestDefaultServiceConnection.java b/test/tap/config/TestDefaultServiceConnection.java index 03465f7bd2857cd917e27972c0afb7f0c7a2960d..fc0cd960b6e2376ee0ded492a3dc7fa763b8a369 100644 --- a/test/tap/config/TestDefaultServiceConnection.java +++ b/test/tap/config/TestDefaultServiceConnection.java @@ -7,14 +7,19 @@ import static org.junit.Assert.fail; import static tap.config.TAPConfiguration.KEY_DEFAULT_OUTPUT_LIMIT; import static tap.config.TAPConfiguration.KEY_FILE_MANAGER; import static tap.config.TAPConfiguration.KEY_MAX_OUTPUT_LIMIT; +import static tap.config.TAPConfiguration.KEY_METADATA; +import static tap.config.TAPConfiguration.KEY_METADATA_FILE; import static tap.config.TAPConfiguration.KEY_OUTPUT_FORMATS; import static tap.config.TAPConfiguration.VALUE_CSV; +import static tap.config.TAPConfiguration.VALUE_DB; import static tap.config.TAPConfiguration.VALUE_JSON; import static tap.config.TAPConfiguration.VALUE_LOCAL; import static tap.config.TAPConfiguration.VALUE_SV; import static tap.config.TAPConfiguration.VALUE_TSV; +import static tap.config.TAPConfiguration.VALUE_XML; import java.io.File; +import java.io.PrintWriter; import java.util.Properties; import org.junit.Before; @@ -28,10 +33,14 @@ import uws.service.file.LocalUWSFileManager; public class TestDefaultServiceConnection { + private final static String XML_FILE = "test/tap/config/tables.xml"; + private Properties validProp, noFmProp, fmClassPathProp, incorrectFmProp, - validFormatsProp, badSVFormat1Prop, badSVFormat2Prop, - unknownFormatProp, defaultOutputLimitProp, maxOutputLimitProp, - bothOutputLimitGoodProp, bothOutputLimitBadProp; + xmlMetaProp, missingMetaProp, missingMetaFileProp, wrongMetaProp, + wrongMetaFileProp, validFormatsProp, badSVFormat1Prop, + badSVFormat2Prop, unknownFormatProp, defaultOutputLimitProp, + maxOutputLimitProp, bothOutputLimitGoodProp, + bothOutputLimitBadProp; @Before public void setUp() throws Exception{ @@ -47,6 +56,24 @@ public class TestDefaultServiceConnection { incorrectFmProp = (Properties)validProp.clone(); incorrectFmProp.setProperty(KEY_FILE_MANAGER, "foo"); + xmlMetaProp = (Properties)validProp.clone(); + xmlMetaProp.setProperty(KEY_METADATA, VALUE_XML); + xmlMetaProp.setProperty(KEY_METADATA_FILE, XML_FILE); + + missingMetaProp = (Properties)validProp.clone(); + missingMetaProp.remove(KEY_METADATA); + + wrongMetaProp = (Properties)validProp.clone(); + wrongMetaProp.setProperty(KEY_METADATA, "foo"); + + wrongMetaFileProp = (Properties)validProp.clone(); + wrongMetaFileProp.setProperty(KEY_METADATA, VALUE_XML); + wrongMetaFileProp.setProperty(KEY_METADATA_FILE, "foo"); + + missingMetaFileProp = (Properties)validProp.clone(); + missingMetaFileProp.setProperty(KEY_METADATA, VALUE_XML); + missingMetaFileProp.remove(KEY_METADATA_FILE); + validFormatsProp = (Properties)validProp.clone(); validFormatsProp.setProperty(KEY_OUTPUT_FORMATS, VALUE_JSON + "," + VALUE_CSV + " , " + VALUE_TSV + ",, , " + VALUE_SV + "([])" + ", " + VALUE_SV + "(|):text/psv:psv" + ", " + VALUE_SV + "($)::test" + ", \t " + VALUE_SV + "(@):text/arobase:"); @@ -95,18 +122,89 @@ public class TestDefaultServiceConnection { @Test public void testDefaultServiceConnectionProperties(){ // Valid Configuration File: + PrintWriter writer = null; + int nbSchemas = -1, nbTables = -1; try{ + // build the ServiceConnection: ServiceConnection connection = new DefaultServiceConnection(validProp); + + // tests: + assertNotNull(connection.getLogger()); + assertNotNull(connection.getFileManager()); + assertNotNull(connection.getFactory()); + assertNotNull(connection.getTAPMetadata()); + assertTrue(connection.getTAPMetadata().getNbSchemas() >= 1); + assertTrue(connection.getTAPMetadata().getNbTables() >= 5); + assertTrue(connection.isAvailable()); + assertTrue(connection.getRetentionPeriod()[0] <= connection.getRetentionPeriod()[1]); + assertTrue(connection.getExecutionDuration()[0] <= connection.getExecutionDuration()[1]); + + // finally, save metadata in an XML file for the other tests: + writer = new PrintWriter(new File(XML_FILE)); + connection.getTAPMetadata().write(writer); + nbSchemas = connection.getTAPMetadata().getNbSchemas(); + nbTables = connection.getTAPMetadata().getNbTables(); + + }catch(Exception e){ + fail("This MUST have succeeded because the property file is valid! \nCaught exception: " + getPertinentMessage(e)); + }finally{ + if (writer != null) + writer.close(); + } + + // Valid XML metadata: + try{ + ServiceConnection connection = new DefaultServiceConnection(xmlMetaProp); assertNotNull(connection.getLogger()); assertNotNull(connection.getFileManager()); assertNotNull(connection.getFactory()); + assertNotNull(connection.getTAPMetadata()); + assertEquals(nbSchemas, connection.getTAPMetadata().getNbSchemas()); + assertEquals(nbTables, connection.getTAPMetadata().getNbTables()); assertTrue(connection.isAvailable()); assertTrue(connection.getRetentionPeriod()[0] <= connection.getRetentionPeriod()[1]); assertTrue(connection.getExecutionDuration()[0] <= connection.getExecutionDuration()[1]); }catch(Exception e){ + e.printStackTrace(); fail("This MUST have succeeded because the property file is valid! \nCaught exception: " + getPertinentMessage(e)); } + // Missing metadata property: + try{ + new DefaultServiceConnection(missingMetaProp); + fail("This MUST have failed because the property 'metadata' is missing!"); + }catch(Exception e){ + assertEquals(e.getClass(), TAPException.class); + assertEquals(e.getMessage(), "The property \"" + KEY_METADATA + "\" is missing! It is required to create a TAP Service. Two possible values: " + VALUE_XML + " (to get metadata from a TableSet XML document) or " + VALUE_DB + " (to fetch metadata from the database schema TAP_SCHEMA)."); + } + + // Missing metadata_file property: + try{ + new DefaultServiceConnection(missingMetaFileProp); + fail("This MUST have failed because the property 'metadata_file' is missing!"); + }catch(Exception e){ + assertEquals(e.getClass(), TAPException.class); + assertEquals(e.getMessage(), "The property \"" + KEY_METADATA_FILE + "\" is missing! According to the property \"" + KEY_METADATA + "\", metadata must be fetched from an XML document. The local file path of it MUST be provided using the property \"" + KEY_METADATA_FILE + "\"."); + } + + // Wrong metadata property: + try{ + new DefaultServiceConnection(wrongMetaProp); + fail("This MUST have failed because the property 'metadata' has a wrong value!"); + }catch(Exception e){ + assertEquals(e.getClass(), TAPException.class); + assertEquals(e.getMessage(), "Unsupported value for the property \"" + KEY_METADATA + "\": \"foo\"! Only two values are allowed: " + VALUE_XML + " (to get metadata from a TableSet XML document) or " + VALUE_DB + " (to fetch metadata from the database schema TAP_SCHEMA)."); + } + + // Wrong metadata_file property: + try{ + new DefaultServiceConnection(wrongMetaFileProp); + fail("This MUST have failed because the property 'metadata_file' has a wrong value!"); + }catch(Exception e){ + assertEquals(e.getClass(), TAPException.class); + assertEquals(e.getMessage(), "A grave error occurred while reading/parsing the TableSet XML document: \"foo\"!"); + } + // No File Manager: try{ new DefaultServiceConnection(noFmProp); @@ -122,6 +220,7 @@ public class TestDefaultServiceConnection { assertNotNull(connection.getLogger()); assertNotNull(connection.getFileManager()); assertNotNull(connection.getFactory()); + assertNotNull(connection.getTAPMetadata()); assertTrue(connection.isAvailable()); /* Retention periods and execution durations are different in this configuration file from the valid one (validProp). diff --git a/test/tap/config/TestDefaultTAPFactory.java b/test/tap/config/TestDefaultTAPFactory.java index 895d55821f087bd8981c9d758093f50ee40e504a..69d7eeecea9953f80b9d0a0835f6d0375d9e8ebd 100644 --- a/test/tap/config/TestDefaultTAPFactory.java +++ b/test/tap/config/TestDefaultTAPFactory.java @@ -10,6 +10,8 @@ import static tap.config.TAPConfiguration.KEY_DB_USERNAME; import static tap.config.TAPConfiguration.KEY_JDBC_DRIVER; import static tap.config.TAPConfiguration.KEY_JDBC_URL; import static tap.config.TAPConfiguration.KEY_SQL_TRANSLATOR; +import static tap.config.TAPConfiguration.VALUE_PGSPHERE; +import static tap.config.TAPConfiguration.VALUE_POSTGRESQL; import java.io.File; import java.util.Collection; @@ -37,7 +39,8 @@ import adql.db.FunctionDef; public class TestDefaultTAPFactory { private Properties validProp, noJdbcProp1, noJdbcProp2, badJdbcProp, - badTranslatorProp, badDBNameProp, badUsernameProp, badPasswordProp; + missingTranslatorProp, badTranslatorProp, badDBNameProp, + badUsernameProp, badPasswordProp; private ServiceConnection serviceConnection = null; @@ -59,6 +62,9 @@ public class TestDefaultTAPFactory { badJdbcProp.setProperty(KEY_JDBC_DRIVER, "foo"); badJdbcProp.setProperty(KEY_JDBC_URL, "jdbc:foo:gmantele"); + missingTranslatorProp = (Properties)validProp.clone(); + missingTranslatorProp.remove(KEY_SQL_TRANSLATOR); + badTranslatorProp = (Properties)validProp.clone(); badTranslatorProp.setProperty(KEY_SQL_TRANSLATOR, "foo"); @@ -108,6 +114,15 @@ public class TestDefaultTAPFactory { assertTrue(ex.getMessage().matches("Impossible to find the JDBC driver \"[^\\\"]*\" !")); } + // Missing Translator: + try{ + new DefaultTAPFactory(serviceConnection, missingTranslatorProp); + fail("This MUST have failed because the provided SQL translator is missing!"); + }catch(Exception ex){ + assertEquals(TAPException.class, ex.getClass()); + assertTrue(ex.getMessage().matches("The property \"" + KEY_SQL_TRANSLATOR + "\" is missing! ADQL queries can not be translated without it. Allowed values: \"" + VALUE_POSTGRESQL + "\", \"" + VALUE_PGSPHERE + "\" or a class path of a class implementing SQLTranslator.")); + } + // Bad Translator: try{ new DefaultTAPFactory(serviceConnection, badTranslatorProp);