Newer
Older
try {
ServiceConnection connection = new ConfigurableServiceConnection(geometriesProp);
assertNotNull(connection.getGeometries());
assertEquals(4, connection.getGeometries().size());
assertEquals("POINT", ((ArrayList<String>)connection.getGeometries()).get(0));
assertEquals("CIRCLE", ((ArrayList<String>)connection.getGeometries()).get(1));
assertEquals("CONTAINS", ((ArrayList<String>)connection.getGeometries()).get(2));
assertEquals("INTERSECTS", ((ArrayList<String>)connection.getGeometries()).get(3));
} catch(Exception e) {
fail("This MUST have succeeded because the given list of geometries is correct! \nCaught exception: " + getPertinentMessage(e));
}
// "NONE" as geometry list:
try {
ServiceConnection connection = new ConfigurableServiceConnection(noneGeomProp);
assertNotNull(connection.getGeometries());
assertEquals(0, connection.getGeometries().size());
} catch(Exception e) {
fail("This MUST have succeeded because the given list of geometries is correct (reduced to only NONE)! \nCaught exception: " + getPertinentMessage(e));
}
// "ANY" as geometry list:
try {
ServiceConnection connection = new ConfigurableServiceConnection(anyGeomProp);
assertNull(connection.getGeometries());
} catch(Exception e) {
fail("This MUST have succeeded because the given list of geometries is correct (reduced to only ANY)! \nCaught exception: " + getPertinentMessage(e));
}
// "NONE" inside a geometry list:
try {
new ConfigurableServiceConnection(noneInsideGeomProp);
fail("This MUST have failed because the given geometry list contains at least 2 items, whose one is NONE!");
} catch(Exception e) {
assertEquals(TAPException.class, e.getClass());
assertEquals("The special value \"" + VALUE_NONE + "\" can not be used inside a list! It MUST be used in replacement of a whole list to specify that no value is allowed.", e.getMessage());
}
// Unknown geometrical function:
try {
new ConfigurableServiceConnection(unknownGeomProp);
fail("This MUST have failed because the given geometry list contains at least 1 unknown ADQL geometrical function!");
} catch(Exception e) {
assertEquals(TAPException.class, e.getClass());
assertEquals("Unknown ADQL geometrical function: \"foo\"!", e.getMessage());
}
// Valid coordinate systems list:
try {
ServiceConnection connection = new ConfigurableServiceConnection(coordSysProp);
assertNotNull(connection.getCoordinateSystems());
assertEquals(2, connection.getCoordinateSystems().size());
assertEquals("icrs * *", ((ArrayList<String>)connection.getCoordinateSystems()).get(0));
assertEquals("ICrs * (Spherical2| CARTEsian2)", ((ArrayList<String>)connection.getCoordinateSystems()).get(1));
} catch(Exception e) {
fail("This MUST have succeeded because the given list of coordinate systems is correct! \nCaught exception: " + getPertinentMessage(e));
}
// "NONE" as coordinate systems list:
try {
ServiceConnection connection = new ConfigurableServiceConnection(noneCoordSysProp);
assertNotNull(connection.getCoordinateSystems());
assertEquals(0, connection.getCoordinateSystems().size());
} catch(Exception e) {
fail("This MUST have succeeded because the given list of coordinate systems is correct (reduced to only NONE)! \nCaught exception: " + getPertinentMessage(e));
}
// "ANY" as coordinate systems list:
try {
ServiceConnection connection = new ConfigurableServiceConnection(anyCoordSysProp);
assertNull(connection.getCoordinateSystems());
} catch(Exception e) {
fail("This MUST have succeeded because the given list of coordinate systems is correct (reduced to only ANY)! \nCaught exception: " + getPertinentMessage(e));
}
// "NONE" inside a coordinate systems list:
try {
new ConfigurableServiceConnection(noneInsideCoordSysProp);
fail("This MUST have failed because the given coordinate systems list contains at least 3 items, whose one is NONE!");
} catch(Exception e) {
assertEquals(TAPException.class, e.getClass());
assertEquals("The special value \"" + VALUE_NONE + "\" can not be used inside a list! It MUST be used in replacement of a whole list to specify that no value is allowed.", e.getMessage());
}
// Unknown coordinate system function:
try {
new ConfigurableServiceConnection(unknownCoordSysProp);
fail("This MUST have failed because the given coordinate systems list contains at least 1 unknown coordinate system!");
} catch(Exception e) {
assertEquals(TAPException.class, e.getClass());
assertEquals("Incorrect coordinate system regular expression (\"ICRS foo *\"): Wrong allowed coordinate system syntax for the 1-th item: \"ICRS foo *\"! Expected: \"frameRegExp refposRegExp flavorRegExp\" ; where each xxxRegExp = (xxx | '*' | '('xxx ('|' xxx)*')'), frame=\"" + Frame.regexp + "\", refpos=\"" + RefPos.regexp + "\" and flavor=\"" + Flavor.regexp + "\" ; an empty string is also allowed and will be interpreted as '*' (so all possible values).", e.getMessage());
}
// "ANY" as UDFs list:
try {
ServiceConnection connection = new ConfigurableServiceConnection(anyUdfsProp);
assertNull(connection.getUDFs());
} catch(Exception e) {
fail("This MUST have succeeded because the given list of UDFs is correct (reduced to only ANY)! \nCaught exception: " + getPertinentMessage(e));
}
// "NONE" as UDFs list:
try {
ServiceConnection connection = new ConfigurableServiceConnection(noneUdfsProp);
assertNotNull(connection.getUDFs());
assertEquals(0, connection.getUDFs().size());
} catch(Exception e) {
fail("This MUST have succeeded because the given list of UDFs is correct (reduced to only NONE)! \nCaught exception: " + getPertinentMessage(e));
}
// Valid list of UDFs:
try {
ServiceConnection connection = new ConfigurableServiceConnection(udfsProp);
assertNotNull(connection.getUDFs());
assertEquals(2, connection.getUDFs().size());
Iterator<FunctionDef> it = connection.getUDFs().iterator();
assertEquals("toto(a VARCHAR)", it.next().toString());
assertEquals("titi(b REAL) -> DOUBLE", it.next().toString());
} catch(Exception e) {
fail("This MUST have succeeded because the given list of UDFs contains valid items! \nCaught exception: " + getPertinentMessage(e));
}
// Valid list of UDFs containing UDFs with translation pattern:
try {
ServiceConnection connection = new ConfigurableServiceConnection(udfsWithTranslationProp);
assertNotNull(connection.getUDFs());
assertEquals(2, connection.getUDFs().size());
Iterator<FunctionDef> it = connection.getUDFs().iterator();
FunctionDef def = it.next();
assertEquals("lower(a VARCHAR) -> VARCHAR", def.toString());
assertEquals("toLowerCase($1)", def.getTranslationPattern());
assertNull(def.description);
def = it.next();
assertEquals("substring(str VARCHAR, sub VARCHAR, startIndex INTEGER) -> VARCHAR", def.toString());
assertEquals("substr($1, $2, $3)", def.getTranslationPattern());
assertEquals("Extract a substring.", def.description);
} catch(Exception e) {
fail("This MUST have succeeded because the given list of UDFs contains valid items! \nCaught exception: " + getPertinentMessage(e));
}
// Valid list of UDFs containing one UDF with a class name:
try {
ServiceConnection connection = new ConfigurableServiceConnection(udfsWithClassNameProp);
assertNotNull(connection.getUDFs());
assertEquals(1, connection.getUDFs().size());
FunctionDef def = connection.getUDFs().iterator().next();
assertEquals("toto(a VARCHAR) -> VARCHAR", def.toString());
assertEquals(UDFToto.class, def.getUDFClass());
assertNull(def.description);
} catch(Exception e) {
fail("This MUST have succeeded because the given list of UDFs contains valid items! \nCaught exception: " + getPertinentMessage(e));
}
// Valid list of UDFs containing one UDF with a class name AND a description:
try {
ServiceConnection connection = new ConfigurableServiceConnection(udfsWithClassNameAndDescriptionProp);
assertNotNull(connection.getUDFs());
assertEquals(2, connection.getUDFs().size());
Iterator<FunctionDef> itUdfs = connection.getUDFs().iterator();
FunctionDef def = itUdfs.next();
assertEquals("toto(a VARCHAR) -> VARCHAR", def.toString());
assertEquals(UDFToto.class, def.getUDFClass());
assertEquals("Bla \\\"bla\\\".", def.description);
def = itUdfs.next();
assertEquals("titi(b REAL) -> DOUBLE", def.toString());
assertEquals(UDFToto.class, def.getUDFClass());
assertEquals("Function titi.", def.description);
} catch(Exception e) {
fail("This MUST have succeeded because the given list of UDFs contains valid items! \nCaught exception: " + getPertinentMessage(e));
}
// Valid list of UDFs containing one UDF with empty optional parameters:
try {
ServiceConnection connection = new ConfigurableServiceConnection(udfsWithEmptyOptParamsProp);
assertNotNull(connection.getUDFs());
assertEquals(1, connection.getUDFs().size());
FunctionDef def = connection.getUDFs().iterator().next();
assertEquals("toto(a VARCHAR) -> VARCHAR", def.toString());
assertNull(def.getUDFClass());
assertNull(def.description);
} catch(Exception e) {
fail("This MUST have succeeded because the given list of UDFs contains valid items! \nCaught exception: " + getPertinentMessage(e));
}
// "NONE" inside a UDFs list:
try {
new ConfigurableServiceConnection(udfsListWithNONEorANYProp);
fail("This MUST have failed because the given UDFs list contains at least 2 items, whose one is ANY!");
} catch(Exception e) {
assertEquals(TAPException.class, e.getClass());
assertEquals("Wrong UDF declaration syntax: \"ANY\"! (position in the property " + KEY_UDFS + ": 27-30)", e.getMessage());
}
// UDF with no brackets:
try {
new ConfigurableServiceConnection(udfsWithMissingBracketsProp);
fail("This MUST have failed because one UDFs list item has no brackets!");
} catch(Exception e) {
assertEquals(TAPException.class, e.getClass());
assertEquals("Wrong UDF declaration syntax: \"toto(a string)->VARCHAR\"! (position in the property " + KEY_UDFS + ": 1-24)", e.getMessage());
}
// UDF with a badly formatted description:
try {
new ConfigurableServiceConnection(udfsWithWrongDescriptionFormatProp);
fail("This MUST have failed because one UDFs list item has too many parameters!");
} catch(Exception e) {
assertEquals(TAPException.class, e.getClass());
assertEquals("Wrong UDF declaration syntax: \"[toto(a string)->VARCHAR, {adql.db.TestDBChecker$UDFToto}, Blabla]\"! (position in the property " + KEY_UDFS + ": 1-67)", e.getMessage());
}
// UDFs whose one item have more parts than supported:
try {
new ConfigurableServiceConnection(udfsWithWrongParamLengthProp);
fail("This MUST have failed because one UDFs list item has too many parameters!");
} catch(Exception e) {
assertEquals(TAPException.class, e.getClass());
assertEquals("Wrong UDF declaration syntax: \"[toto(a string)->VARCHAR, {adql.db.TestDBChecker$UDFToto}, \"Blabla\", foo]\"! (position in the property " + KEY_UDFS + ": 1-74)", e.getMessage());
}
// UDF with missing definition part (or wrong since there is no comma):
try {
new ConfigurableServiceConnection(udfsWithMissingDefProp1);
fail("This MUST have failed because one UDFs list item has a wrong signature part (it has been forgotten)!");
} catch(Exception e) {
assertEquals(TAPException.class, e.getClass());
assertEquals("Wrong UDF declaration syntax: Wrong function definition syntax! Expected syntax: \"<regular_identifier>(<parameters>?) <return_type>?\", where <regular_identifier>=\"[a-zA-Z]+[a-zA-Z0-9_]*\", <return_type>=\" -> <type_name>\", <parameters>=\"(<regular_identifier> <type_name> (, <regular_identifier> <type_name>)*)\", <type_name> should be one of the types described in the UPLOAD section of the TAP documentation. Examples of good syntax: \"foo()\", \"foo() -> VARCHAR\", \"foo(param INTEGER)\", \"foo(param1 INTEGER, param2 DOUBLE) -> DOUBLE\" (position in the property " + KEY_UDFS + ": 2-33)", e.getMessage());
}
// UDF with missing definition part (or wrong since there is no comma):
try {
new ConfigurableServiceConnection(udfsWithMissingDefProp2);
fail("This MUST have failed because one UDFs list item has no signature part!");
} catch(Exception e) {
assertEquals(TAPException.class, e.getClass());
assertEquals("Missing UDF declaration! (position in the property " + KEY_UDFS + ": 2-2)", e.getMessage());
}
// Empty UDF item (without comma):
try {
ServiceConnection connection = new ConfigurableServiceConnection(emptyUdfItemProp1);
assertNotNull(connection.getUDFs());
assertEquals(0, connection.getUDFs().size());
} catch(Exception e) {
fail("This MUST have succeeded because the given list of UDFs contains one empty UDF (which should be merely ignored)! \nCaught exception: " + getPertinentMessage(e));
}
// Empty UDF item (with comma):
try {
ServiceConnection connection = new ConfigurableServiceConnection(emptyUdfItemProp2);
assertNotNull(connection.getUDFs());
assertEquals(0, connection.getUDFs().size());
} catch(Exception e) {
fail("This MUST have succeeded because the given list of UDFs contains one empty UDF (which should be merely ignored)! \nCaught exception: " + getPertinentMessage(e));
}
// UDF item without its closing bracket:
try {
new ConfigurableServiceConnection(udfWithMissingEndBracketProp);
fail("This MUST have failed because one UDFs list item has no closing bracket!");
} catch(Exception e) {
assertEquals(TAPException.class, e.getClass());
assertEquals("Wrong UDF declaration syntax: \"[toto(a string)->VARCHAR\"! (position in the property " + KEY_UDFS + ": 1-25)", e.getMessage());
// Valid custom TAPFactory:
try {
ServiceConnection connection = new ConfigurableServiceConnection(customFactoryProp);
assertNotNull(connection.getFactory());
assertEquals(CustomTAPFactory.class, connection.getFactory().getClass());
} catch(Exception e) {
fail("This MUST have succeeded because the given custom TAPFactory exists and have the required constructor (ServiceConnection)! \nCaught exception: " + getPertinentMessage(e));
}
// Valid custom "configurable" TAPFactory:
try {
ServiceConnection connection = new ConfigurableServiceConnection(customConfigurableFactoryProp);
assertNotNull(connection.getFactory());
assertEquals(CustomConfigurableTAPFactory.class, connection.getFactory().getClass());
} catch(Exception e) {
fail("This MUST have succeeded because the given custom configurable TAPFactory exists and have the required constructor (ServiceConnection, Properties)! \nCaught exception: " + getPertinentMessage(e));
}
// Bad custom TAPFactory (required constructor missing):
try {
new ConfigurableServiceConnection(badCustomFactoryProp);
fail("This MUST have failed because the specified TAPFactory extension does not have a constructor with ServiceConnection!");
} catch(Exception e) {
assertEquals(TAPException.class, e.getClass());
assertEquals("Missing constructor tap.config.TestConfigurableServiceConnection$BadCustomTAPFactory(tap.ServiceConnection)! See the value \"{tap.config.TestConfigurableServiceConnection$BadCustomTAPFactory}\" of the property \"" + KEY_TAP_FACTORY + "\".", e.getMessage());
}
}
@Test
public void testGetFile() {
final String rootPath = "/ROOT", propertyName = "SuperProperty";
String path;
try {
// NULL test => NULL must be returned.
assertNull(ConfigurableServiceConnection.getFile(null, rootPath, propertyName));
// Valid absolute file path:
path = "/custom/user/dir";
assertEquals(path, ConfigurableServiceConnection.getFile(path, rootPath, propertyName).getAbsolutePath());
// File name relative to the given rootPath:
path = "dir";
assertEquals(rootPath + File.separator + path, ConfigurableServiceConnection.getFile(path, rootPath, propertyName).getAbsolutePath());
// Idem but with a relative file path:
path = "gmantele/workspace";
assertEquals(rootPath + File.separator + path, ConfigurableServiceConnection.getFile(path, rootPath, propertyName).getAbsolutePath());
} catch(Exception ex) {
ex.printStackTrace();
fail("None of these tests should have failed!");
}
// Test with a file URI:
path = "file:/custom/user/dir";
try {
ConfigurableServiceConnection.getFile(path, rootPath, propertyName);
fail("This test should have failed, because URIs are no longer supported!");
} catch(Exception ex) {
assertEquals(TAPException.class, ex.getClass());
assertEquals("Incorrect file path for the property \"" + propertyName + "\": \"" + path + "\"! URI/URLs are not expected here.", ex.getMessage());
}
// Test with an URL:
path = "http://www.google.com";
try {
ConfigurableServiceConnection.getFile(path, rootPath, propertyName);
fail("This test should have failed, because the given URI uses the HTTP protocol (actually, it uses a protocol different from \"file\"!");
} catch(Exception ex) {
assertEquals(TAPException.class, ex.getClass());
assertEquals("Incorrect file path for the property \"" + propertyName + "\": \"" + path + "\"! URI/URLs are not expected here.", ex.getMessage());
}
}
public static final String getPertinentMessage(final Exception ex) {
return (ex.getCause() == null || ex.getMessage().equals(ex.getCause().getMessage())) ? ex.getMessage() : ex.getCause().getMessage();
}
/**
gmantele
committed
* A UWSFileManager to test the load of a UWSFileManager from the configuration file with a class path.
* @author Grégory Mantelet (ARI)
gmantele
committed
* @version 01/2015
* @see TestConfigurableServiceConnection#testDefaultServiceConnectionProperties()
*/
gmantele
committed
public static class FileManagerTest extends LocalUWSFileManager {
public FileManagerTest(Properties tapConfig) throws UWSException {
super(new File(tapConfig.getProperty("file_root_path")), true, false);
}
}
/**
* A UserIdentifier which always return the same user...that's to say, all users are in a way still anonymous :-)
* This class is only for test purpose.
* @author Grégory Mantelet (ARI)
* @version 02/2015
*/
public static class UserIdentifierTest implements UserIdentifier {
private static final long serialVersionUID = 1L;
private final JobOwner everybody = new DefaultJobOwner("everybody");
@Override
public JobOwner extractUserId(UWSUrl urlInterpreter, HttpServletRequest request) throws UWSException {
return everybody;
}
@Override
public JobOwner restoreUser(String id, String pseudo, Map<String, Object> otherData) throws UWSException {
return everybody;
}
}
/**
* TAPFactory just to test whether the property tap_factory works well.
* @author Grégory Mantelet (ARI)
* @version 03/2017
*/
private static class CustomTAPFactory extends AbstractTAPFactory {
private final JDBCConnection dbConn;
public CustomTAPFactory(final ServiceConnection conn) throws DBException {
super(conn);
dbConn = new JDBCConnection(DBTools.DB_TEST_JDBC_DRIVER, DBTools.DB_TEST_URL, DBTools.DB_TEST_USER, DBTools.DB_TEST_PWD, new AstroH2Translator(), "TheOnlyConnection", new QueryExecutor(), conn.getLogger());
}
@Override
public DBConnection getConnection(final String jobID) throws TAPException {
return dbConn;
}
@Override
public void freeConnection(final DBConnection conn) {
@Override
public void destroy() {
try {
dbConn.getInnerConnection().close();
} catch(Exception ex) {
}
}
/**
* ConfigurableTAPFactory just to test whether the property tap_factory allows TAPFactory
* with a constructor (ServiceConnection, Properties).
* @author Grégory Mantelet (ARI)
* @version 03/2017
*/
private static class CustomConfigurableTAPFactory extends AbstractTAPFactory {
private final JDBCConnection dbConn;
public CustomConfigurableTAPFactory(final ServiceConnection conn, final Properties prop) throws DBException {
super(conn);
dbConn = new JDBCConnection(DBTools.DB_TEST_JDBC_DRIVER, DBTools.DB_TEST_URL, DBTools.DB_TEST_USER, DBTools.DB_TEST_PWD, new AstroH2Translator(), "TheOnlyConnection", new QueryExecutor(), conn.getLogger());
}
@Override
public DBConnection getConnection(final String jobID) throws TAPException {
return dbConn;
}
@Override
public void freeConnection(final DBConnection conn) {
@Override
public void destroy() {
try {
dbConn.getInnerConnection().close();
} catch(Exception ex) {
}
}
/**
* TAPFactory just to test whether the property tap_factory is rejected when no constructor with a single parameter of type ServiceConnection exists.
* @author Grégory Mantelet (ARI)
* @version 02/2015
*/
private static class BadCustomTAPFactory extends AbstractTAPFactory {
public BadCustomTAPFactory() throws DBException {
super(null);
}
@Override
public DBConnection getConnection(final String jobID) throws TAPException {
return null;
}
@Override
public void freeConnection(final DBConnection conn) {
@Override
public void destroy() {
}
/**
* TAPMetadata extension just to test whether it is possible to customize the output class of ConfigurableServiceConnection with the
* metadata fetching methods "db" and "xml".
* @author Grégory Mantelet (ARI)
* @version 08/2015
*/
private static class MyCustomTAPMetadata extends TAPMetadata {
public MyCustomTAPMetadata(TAPMetadata meta) {
for(TAPSchema s : meta) {
this.addSchema(s);
}
}
}
/**
* TAPMetadata extension just to test whether it is possible to customize the output class of ConfigurableServiceConnection with the
* metadata fetching methods "db" and "xml".
* <strong>This extension is however bad because it does not have any of the required constructor.</strong>
* @author Grégory Mantelet (ARI)
* @version 08/2015
*/
private static class MyBadCustomTAPMetadata extends TAPMetadata {
public MyBadCustomTAPMetadata() {
}
}
/**
* Custom TAPLog implementation.
* <p><i>
* Actually, for quick implementation, this class just extends
* {@link DefaultTAPLog} (and so, implements TAPLog).
* </i></p>
* @author Grégory Mantelet (ARI)
* @version 09/2017
*/
private static class CustomLogger extends DefaultTAPLog {
public CustomLogger(final UWSFileManager fm) {
super(fm);
}
@Override
public void logTAP(LogLevel level, Object obj, String event, String message, Throwable error) {
super.logTAP(level, obj, event, "[MY] " + message, error);
}
}