Skip to content
Snippets Groups Projects
Commit 9eaf1026 authored by gmantele's avatar gmantele
Browse files

[TAP] Add ADQL geometry restriction inside the configuration file.

parent b1a27998
No related merge requests found
......@@ -13,6 +13,7 @@ import static tap.config.TAPConfiguration.KEY_DEFAULT_UPLOAD_LIMIT;
import static tap.config.TAPConfiguration.KEY_DIRECTORY_PER_USER;
import static tap.config.TAPConfiguration.KEY_FILE_MANAGER;
import static tap.config.TAPConfiguration.KEY_FILE_ROOT_PATH;
import static tap.config.TAPConfiguration.KEY_GEOMETRIES;
import static tap.config.TAPConfiguration.KEY_GROUP_USER_DIRECTORIES;
import static tap.config.TAPConfiguration.KEY_MAX_ASYNC_JOBS;
import static tap.config.TAPConfiguration.KEY_MAX_EXECUTION_DURATION;
......@@ -31,6 +32,7 @@ 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_NONE;
import static tap.config.TAPConfiguration.VALUE_SV;
import static tap.config.TAPConfiguration.VALUE_TSV;
import static tap.config.TAPConfiguration.VALUE_XML;
......@@ -97,7 +99,10 @@ public final class DefaultServiceConnection implements ServiceConnection {
private UserIdentifier userIdentifier = null;
private final Collection<FunctionDef> udfs = new ArrayList<FunctionDef>(0);
private ArrayList<String> geometries = null;
private final String GEOMETRY_REGEXP = "(AREA|BOX|CENTROID|CIRCLE|CONTAINS|DISTANCE|COORD1|COORD2|COORDSYS|INTERSECTS|POINT|POLYGON|REGION)";
private Collection<FunctionDef> udfs = new ArrayList<FunctionDef>(0);
public DefaultServiceConnection(final Properties tapConfig) throws NullPointerException, TAPException, UWSException{
// 1. INITIALIZE THE FILE MANAGER:
......@@ -139,7 +144,10 @@ public final class DefaultServiceConnection implements ServiceConnection {
// 8. SET A USER IDENTIFIER:
initUserIdentifier(tapConfig);
// 9. MAKE THE SERVICE AVAILABLE:
// 9. CONFIGURE ADQL:
initADQLGeometries(tapConfig);
// 10. MAKE THE SERVICE AVAILABLE:
setAvailable(true, "TAP service available.");
}
......@@ -445,6 +453,47 @@ public final class DefaultServiceConnection implements ServiceConnection {
}
}
private void initADQLGeometries(final Properties tapConfig) throws TAPException{
// Get the property value:
String propValue = getProperty(tapConfig, KEY_GEOMETRIES);
// NO VALUE => ALL FCT ALLOWED!
if (propValue == null)
geometries = null;
// "NONE" => ALL FCT FORBIDDEN (= none of these functions are allowed)!
else if (propValue.equalsIgnoreCase(VALUE_NONE))
geometries = new ArrayList<String>(0);
// OTHERWISE, JUST THE ALLOWED ONE ARE LISTED:
else{
// split all the list items:
String[] items = propValue.split(",");
if (items.length > 0){
geometries = new ArrayList<String>(items.length);
for(String item : items){
item = item.trim();
// empty item => ignored
if (item.length() <= 0)
continue;
// if it is a name of known ADQL geometrical function, add it to the list:
else if (item.toUpperCase().matches(GEOMETRY_REGEXP))
geometries.add(item.toUpperCase());
// "NONE" is not allowed inside a list => error!
else if (item.toUpperCase().equals(VALUE_NONE))
throw new TAPException("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.");
// unknown value => error!
else
throw new TAPException("Unknown ADQL geometrical function: \"" + item + "\"!");
}
// if finally no item has been specified, consider it as "all functions allowed":
if (geometries.size() == 0)
geometries = null;
}else
geometries = null;
}
}
@Override
public String getProviderName(){
return providerName;
......@@ -668,7 +717,7 @@ public final class DefaultServiceConnection implements ServiceConnection {
@Override
public Collection<String> getGeometries(){
return null; // ALL GEOMETRIES ALLOWED
return geometries;
}
@Override
......
......@@ -86,6 +86,10 @@ public final class TAPConfiguration {
/* USER IDENTIFICATION */
public final static String KEY_USER_IDENTIFIER = "user_identifier";
/* ADQL RESTRICTIONS */
public final static String KEY_GEOMETRIES = "geometries";
public final static String VALUE_NONE = "NONE";
/**
* <p>Read the asked property from the given Properties object.</p>
* <ul>
......
......@@ -454,6 +454,23 @@
</td>
<td>{apackage.FooUserIdentifier}</td>
</tr>
<tr><td colspan="5">ADQL restrictions</td></tr>
<tr>
<td class="done">geometries</td>
<td></td>
<td>text</td>
<td>
<p>Comma-separated list of all allowed geometries.</p>
<p>
Each item of the list must be the name (whatever is the case) of an ADQL geometrical function (e.g. INTERSECTS, COORDSYS, POINT) to allow.
If the list is empty (no item), all functions are allowed. And if the special value <em>NONE</em> is given, no ADQL function will be allowed.
</p>
<p><em>By default, all ADQL geometrical functions are allowed.</em></p>
</td>
<td><ul><li>ø <em>(default)</em></li><li>NONE</li><li>CONTAINS, intersects, Point, Box, CIRCLE</li></ul></td>
</tr>
</table>
</body>
</html>
\ No newline at end of file
......@@ -8,6 +8,7 @@ import static org.junit.Assert.fail;
import static tap.config.TAPConfiguration.DEFAULT_MAX_ASYNC_JOBS;
import static tap.config.TAPConfiguration.KEY_DEFAULT_OUTPUT_LIMIT;
import static tap.config.TAPConfiguration.KEY_FILE_MANAGER;
import static tap.config.TAPConfiguration.KEY_GEOMETRIES;
import static tap.config.TAPConfiguration.KEY_MAX_ASYNC_JOBS;
import static tap.config.TAPConfiguration.KEY_MAX_OUTPUT_LIMIT;
import static tap.config.TAPConfiguration.KEY_METADATA;
......@@ -18,12 +19,14 @@ 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_NONE;
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.ArrayList;
import java.util.Map;
import java.util.Properties;
......@@ -52,7 +55,8 @@ public class TestDefaultServiceConnection {
badSVFormat2Prop, unknownFormatProp, maxAsyncProp,
negativeMaxAsyncProp, notIntMaxAsyncProp, defaultOutputLimitProp,
maxOutputLimitProp, bothOutputLimitGoodProp,
bothOutputLimitBadProp, userIdentProp, notClassPathUserIdentProp;
bothOutputLimitBadProp, userIdentProp, notClassPathUserIdentProp,
geometriesProp, noneGeomProp, noneInsideGeomProp, unknownGeomProp;
@Before
public void setUp() throws Exception{
......@@ -126,6 +130,18 @@ public class TestDefaultServiceConnection {
notClassPathUserIdentProp = (Properties)validProp.clone();
notClassPathUserIdentProp.setProperty(KEY_USER_IDENTIFIER, "foo");
geometriesProp = (Properties)validProp.clone();
geometriesProp.setProperty(KEY_GEOMETRIES, "point, CIRCle , cONTAins,intersECTS");
noneGeomProp = (Properties)validProp.clone();
noneGeomProp.setProperty(KEY_GEOMETRIES, VALUE_NONE);
noneInsideGeomProp = (Properties)validProp.clone();
noneInsideGeomProp.setProperty(KEY_GEOMETRIES, "POINT, Box, none, circle");
unknownGeomProp = (Properties)validProp.clone();
unknownGeomProp.setProperty(KEY_GEOMETRIES, "POINT, Contains, foo, circle,Polygon");
}
/**
......@@ -167,6 +183,7 @@ public class TestDefaultServiceConnection {
assertTrue(connection.getRetentionPeriod()[0] <= connection.getRetentionPeriod()[1]);
assertTrue(connection.getExecutionDuration()[0] <= connection.getExecutionDuration()[1]);
assertNull(connection.getUserIdentifier());
assertNull(connection.getGeometries());
// finally, save metadata in an XML file for the other tests:
writer = new PrintWriter(new File(XML_FILE));
......@@ -195,6 +212,7 @@ public class TestDefaultServiceConnection {
assertTrue(connection.getRetentionPeriod()[0] <= connection.getRetentionPeriod()[1]);
assertTrue(connection.getExecutionDuration()[0] <= connection.getExecutionDuration()[1]);
assertNull(connection.getUserIdentifier());
assertNull(connection.getGeometries());
}catch(Exception e){
e.printStackTrace();
fail("This MUST have succeeded because the property file is valid! \nCaught exception: " + getPertinentMessage(e));
......@@ -413,6 +431,46 @@ public class TestDefaultServiceConnection {
assertEquals(e.getClass(), TAPException.class);
assertEquals(e.getMessage(), "Class path expected for the property \"" + KEY_USER_IDENTIFIER + "\", instead of: \"foo\"!");
}
// Valid geometry list:
try{
ServiceConnection connection = new DefaultServiceConnection(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 DefaultServiceConnection(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));
}
// "NONE" inside a geometry list:
try{
new DefaultServiceConnection(noneInsideGeomProp);
fail("This MUST have failed because the given geometry list contains at least 2 items, whose one is NONE!");
}catch(Exception e){
assertEquals(e.getClass(), TAPException.class);
assertEquals(e.getMessage(), "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.");
}
// Unknown geometrical function:
try{
new DefaultServiceConnection(unknownGeomProp);
fail("This MUST have failed because the given geometry list contains at least 1 unknown ADQL geometrical function!");
}catch(Exception e){
assertEquals(e.getClass(), TAPException.class);
assertEquals(e.getMessage(), "Unknown ADQL geometrical function: \"foo\"!");
}
}
public static final String getPertinentMessage(final Exception ex){
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment