Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cadc-tap-schema/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ sourceCompatibility = 11

group = 'org.opencadc'

version = '1.2.18'
version = '1.2.19'

description = 'OpenCADC TAP-1.1 tap schema server library'
def git_url = 'https://github.com/opencadc/tap'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,52 @@ public void testPutGetDeleteTable() {
orig.getColumnDescs().add(new ColumnDesc(testTable, "c8", TapDataType.POINT));
orig.getColumnDescs().add(new ColumnDesc(testTable, "c9", TapDataType.CIRCLE));
orig.getColumnDescs().add(new ColumnDesc(testTable, "c10", TapDataType.POLYGON));

// timestamp variations
orig.getColumnDescs().add(new ColumnDesc(testTable, "date_only", new TapDataType("char", "10", "timestamp")));
orig.getColumnDescs().add(new ColumnDesc(testTable, "date_time", new TapDataType("char", "19", "timestamp")));
orig.getColumnDescs().add(new ColumnDesc(testTable, "date_time_ms_var", new TapDataType("char", "23*", "timestamp")));

// optional content
orig.getColumn("c0").description = "ident";
orig.getColumn("c2").indexed = true;
orig.getColumn("c4").principal = true;
orig.getColumn("c6").std = true;
orig.getColumn("c8").ucd = "main";
orig.getColumn("c10").unit = "deg";
orig.getColumn("c10").utype = "caom2:Position.bounds";
orig.getColumn("date_only").columnID = "flibble";
orig.getColumn("date_time_ms_var").columnIndex = 1;

dao.put(orig);
td = dao.getTable(testTable);
Assert.assertNotNull("created table", td);
Assert.assertEquals(orig.getSchemaName(), td.getSchemaName());
Assert.assertEquals(orig.getTableName(), td.getTableName());
Assert.assertEquals("num columns", orig.getColumnDescs().size(), td.getColumnDescs().size());

for (ColumnDesc ocd : orig.getColumnDescs()) {
ColumnDesc acd = td.getColumn(ocd.getColumnName());
log.info(ocd.getColumnName() + ": " + ocd.columnIndex + " " + acd.columnIndex);
Assert.assertNotNull(acd);
TapDataType odt = ocd.getDatatype();
TapDataType adt = acd.getDatatype();
log.info(ocd.getColumnName() + ": " + odt + " -> " + adt);
Assert.assertEquals(ocd.getDatatype().getDatatype(), acd.getDatatype().getDatatype());
Assert.assertEquals(ocd.getDatatype().arraysize, acd.getDatatype().arraysize);
Assert.assertEquals(ocd.getDatatype().xtype, acd.getDatatype().xtype);
Assert.assertEquals(ocd.description, acd.description);
Assert.assertEquals(ocd.indexed, acd.indexed);
Assert.assertEquals(ocd.principal, acd.principal);
Assert.assertEquals(ocd.std, acd.std);
Assert.assertEquals(ocd.ucd, acd.ucd);
Assert.assertEquals(ocd.unit, acd.unit);
Assert.assertEquals(ocd.utype, acd.utype);

// correct arraysizeToSize() is tested in a unit test
// this tests round trip
Integer expectedSize = TapSchemaDAO.arraysizeToSize(odt.arraysize);
log.info(ocd.getColumnName() + ": " + odt.arraysize + " -> " + expectedSize + " vs " + acd.compatSize);
Assert.assertEquals(expectedSize, acd.compatSize);
}
dao.delete(td.getTableName());
td = dao.getTable(testTable);
Assert.assertNull("delete confirmed", td);
Expand Down Expand Up @@ -427,7 +467,7 @@ public void testSetGetPermisions() {
TapPermissions tp0 = dao.getTablePermissions(td.getTableName());
Assert.assertNotNull(tp0);
Assert.assertNull("owner", tp0.owner);
Assert.assertFalse("anon", tp0.isPublic);
Assert.assertNull("anon", tp0.isPublic);
Assert.assertNull("read-only", tp0.readGroup);
Assert.assertNull("read-write", tp0.readWriteGroup);

Expand Down Expand Up @@ -472,7 +512,7 @@ public void testSetGetPermisions() {
TapPermissions sp2 = dao.getSchemaPermissions("intTest");
Assert.assertNotNull(sp2);
Assert.assertNull("null owner", sp2.owner);
Assert.assertFalse("anon", sp2.isPublic);
Assert.assertNull("anon", sp2.isPublic);
Assert.assertNull("read-only", sp2.readGroup);
Assert.assertNull("read-write", sp2.readWriteGroup);

Expand All @@ -481,7 +521,7 @@ public void testSetGetPermisions() {
TapPermissions tp4 = dao.getTablePermissions(td.getTableName());
Assert.assertNotNull(tp4);
Assert.assertNull("null owner", tp4.owner);
Assert.assertFalse("anon", tp4.isPublic);
Assert.assertNull("anon", tp4.isPublic);
Assert.assertNull("read-only", tp4.readGroup);
Assert.assertNull("read-write", tp4.readWriteGroup);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@

import ca.nrc.cadc.auth.AuthenticationUtil;
import ca.nrc.cadc.auth.IdentityManager;
import ca.nrc.cadc.dali.tables.votable.VOTableUtil;
import ca.nrc.cadc.db.DatabaseTransactionManager;
import ca.nrc.cadc.db.mappers.JdbcMapUtil;
import ca.nrc.cadc.net.ResourceNotFoundException;
import ca.nrc.cadc.profiler.Profiler;
import ca.nrc.cadc.uws.Job;
Expand Down Expand Up @@ -124,9 +126,10 @@ public class TapSchemaDAO extends AbstractDAO {
"schema_name", "table_type", "description", "utype", "table_index", "api_created", "view_target", "table_name"};
protected String orderTablesClause = " ORDER BY schema_name,table_index,table_name";

private String[] tsColumnsCols = new String[] { "description", "utype", "ucd", "unit", "datatype", "arraysize",
private String[] tsColumnsCols = new String[] { "description", "utype", "ucd", "unit", "datatype", "arraysize", "\"size\"",
"xtype", "principal", "indexed", "std", "column_id", "column_index", "table_name", "column_name" };
protected String orderColumnsClause = " ORDER BY table_name,column_index,column_name";
private static int SIZE_COL_INDEX = 7; // 1-based in the above tsColumnCols array

private String[] tsKeysCols = new String[] { "key_id", "from_table", "target_table", "description,utype" };
protected String orderKeysClause = " ORDER BY key_id,from_table,target_table";
Expand Down Expand Up @@ -196,15 +199,17 @@ public TapSchema get(int depth) {

IdentityManager identityManager = AuthenticationUtil.getIdentityManager();
log.debug("IdentityManager: " + identityManager);
TapPermissionsMapper tapPermissionsMapper = new TapPermissionsMapper(identityManager);
// gss includes tsSchemaCols + accessControlCols
int permColumnOffset = 1 + tsSchemaCols.length;
TapPermissionsMapper tapPermissionsMapper = new TapPermissionsMapper(identityManager, permColumnOffset);

// TAP_SCHEMA.schemas
GetSchemasStatement gss = new GetSchemasStatement(schemasTableName);
if (ordered) {
gss.setOrderBy(orderSchemaClause);
}
List<SchemaDesc> schemaDescs = jdbc.query(gss, new SchemaMapper(tapPermissionsMapper));
depthQuery(schemaDescs,tapPermissionsMapper, null, depth, jdbc);
depthQuery(schemaDescs, identityManager, null, depth, jdbc);

TapSchema ret = new TapSchema();
ret.getSchemaDescs().addAll(schemaDescs);
Expand All @@ -224,25 +229,25 @@ public SchemaDesc getSchema(String schemaName, int depth) {
gss.setSchemaName(schemaName);
IdentityManager identityManager = AuthenticationUtil.getIdentityManager();
log.debug("IdentityManager: " + identityManager);
TapPermissionsMapper tapPermissionsMapper = new TapPermissionsMapper(identityManager);
// gss includes tsSchemaCols + accessControlCols
int permColumnOffset = 1 + tsSchemaCols.length;
TapPermissionsMapper tapPermissionsMapper = new TapPermissionsMapper(identityManager, permColumnOffset);
JdbcTemplate jdbc = new JdbcTemplate(dataSource);
List<SchemaDesc> schemaDescs = jdbc.query(gss, new SchemaMapper(tapPermissionsMapper));
if (schemaDescs.isEmpty()) {
return null;
}
SchemaDesc ret = null;
if (schemaDescs.size() == 1) {
ret = schemaDescs.get(0);
} else {
throw new RuntimeException("BUG: found " + schemaDescs.size() + " schema matching " + schemaName);
}
depthQuery(schemaDescs, tapPermissionsMapper, schemaName, depth, jdbc);
SchemaDesc ret = schemaDescs.get(0);
//ret.tapPermissions = getSchemaPermissions(schemaName);
log.debug("schema perms: " + ret.tapPermissions);

depthQuery(schemaDescs, identityManager, schemaName, depth, jdbc);

return ret;
}

// reusable code for get(depth) and getSchema(depth)
private void depthQuery(List<SchemaDesc> schemaDescs, TapPermissionsMapper tapPermissionsMapper,
private void depthQuery(List<SchemaDesc> schemaDescs, IdentityManager identityManager,
String schemaName, int depth, JdbcTemplate jdbc) {
if (depth > MIN_DEPTH) {
// TAP_SCHEMA.tables
Expand All @@ -251,7 +256,10 @@ private void depthQuery(List<SchemaDesc> schemaDescs, TapPermissionsMapper tapPe
if (ordered) {
gts.setOrderBy(orderTablesClause);
}
List<TableDesc> tableDescs = jdbc.query(gts, new TableMapper(tapPermissionsMapper));
// gts includes tsTablesCols + accessControlCols
int permColumnOffset = 1 + tsTablesCols.length;
TapPermissionsMapper tpm = new TapPermissionsMapper(identityManager, permColumnOffset);
List<TableDesc> tableDescs = jdbc.query(gts, new TableMapper(tpm));
addTablesToSchemas(schemaDescs, tableDescs);

if (depth > TAB_DEPTH) {
Expand Down Expand Up @@ -317,6 +325,7 @@ public TableDesc getTable(String tableName, int depth) {
return null;
}
TableDesc ret = tableDescs.get(0);
ret.tapPermissions = getTablePermissions(tableName);
prof.checkpoint("get-table");

if (depth > TAB_DEPTH) {
Expand Down Expand Up @@ -412,6 +421,10 @@ public void put(SchemaDesc sd) {
log.debug("put: " + sd.getSchemaName());
sps.setSchema(sd);
jdbc.update(sps);

if (sd.tapPermissions != null) {
setSchemaPermissions(sd.getSchemaName(), sd.tapPermissions);
}

log.debug("commit transaction");
tm.commitTransaction();
Expand Down Expand Up @@ -480,6 +493,11 @@ public void put(TableDesc td) {
}
prof.checkpoint("put-columns");

log.debug("put: set permissions " + td.tapPermissions);
if (td.tapPermissions != null) {
setTablePermissions(td.getTableName(), td.tapPermissions);
}

log.debug("commit transaction");
tm.commitTransaction();
prof.checkpoint("commit-transaction");
Expand Down Expand Up @@ -740,6 +758,7 @@ public TapPermissions getTablePermissions(String tableName) {
* @throws ResourceNotFoundException
*/
public void setSchemaPermissions(String schemaName, TapPermissions tp) throws ResourceNotFoundException {
log.debug("setSchemaPermissions: " + schemaName + " " + tp);
if (tp.owner != null) {
IdentityManager im = AuthenticationUtil.getIdentityManager();
tp.ownerID = im.toOwner(tp.owner);
Expand Down Expand Up @@ -1289,6 +1308,7 @@ public PreparedStatement createPreparedStatement(Connection conn) throws SQLExce
safeSetString(sb, ps, col++, column.unit);
safeSetString(sb, ps, col++, column.getDatatype().getDatatype());
safeSetString(sb, ps, col++, column.getDatatype().arraysize);
safeSetInteger(sb, ps, col++, arraysizeToSize(column.getDatatype().arraysize));
safeSetString(sb, ps, col++, column.getDatatype().xtype);
safeSetBoolean(sb, ps, col++, column.principal);
safeSetBoolean(sb, ps, col++, column.indexed);
Expand All @@ -1302,7 +1322,19 @@ public PreparedStatement createPreparedStatement(Connection conn) throws SQLExce
return ps;
}
}


static Integer arraysizeToSize(String arraysize) {
int[] as = VOTableUtil.getArrayShape(arraysize);
if (as == null || as.length > 1) {
return null;
}
if (as[0] == -1) {
// see comment in getArrayShape
return null;
}
return as[0];
}

private class DeleteSchemaStatement implements PreparedStatementCreator {
private SchemaDesc schema;

Expand Down Expand Up @@ -1655,6 +1687,7 @@ public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
String cn = rs.getString("column_name");
String dt = rs.getString("datatype");
String as = rs.getString("arraysize");
// ignore "size"
String xt = rs.getString("xtype");

log.debug("ColumnMapper: " + tn + "," + cn + "," + dt + "," + as + "," + xt);
Expand All @@ -1667,12 +1700,14 @@ public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
col.ucd = rs.getString("ucd");
col.unit = rs.getString("unit");

col.principal = intToBoolean(rs.getInt("principal"));
col.indexed = intToBoolean(rs.getInt("indexed"));
col.std = intToBoolean(rs.getInt("std"));
col.principal = intToBoolean(JdbcMapUtil.getInteger(rs.getObject("principal")));
col.indexed = intToBoolean(JdbcMapUtil.getInteger(rs.getObject("indexed")));
col.std = intToBoolean(JdbcMapUtil.getInteger(rs.getObject("std")));
col.columnID = rs.getString("column_id");
col.columnIndex = rs.getInt("column_index");
col.columnIndex = JdbcMapUtil.getInteger(rs.getObject("column_index"));

// at least in postgresql, the quotes in "size" are not in the ResultSet so use hard-coded position
col.compatSize = JdbcMapUtil.getInteger(rs.getObject(SIZE_COL_INDEX));
return col;
}

Expand Down Expand Up @@ -1721,27 +1756,35 @@ public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
private static final class TapPermissionsMapper implements RowMapper {

private IdentityManager identityManager;
private int columnOffset = 1;

public TapPermissionsMapper(IdentityManager identityManager) {
this.identityManager = identityManager;
}

// when re-used as a partial rowmapper
public TapPermissionsMapper(IdentityManager identityManager, int columnOffset) {
this.identityManager = identityManager;
this.columnOffset = columnOffset;
}

public TapPermissions mapRow(ResultSet rs, int rowNum) throws SQLException {
String ownerVal = rs.getString(ownerCol);
int col = columnOffset;
String ownerVal = rs.getString(col++);
log.debug("found owner: " + ownerVal);
int readAnon = rs.getInt(readAnonCol);
Integer readAnon = JdbcMapUtil.getInteger(rs, col++);
log.debug("found readAnon: " + readAnon);
String rog = rs.getString(readOnlyCol);
log.debug("found readOnly: " + rog);
String rwg = rs.getString(readWriteCol);
log.debug("found readAnon: " + rwg);
String rog = rs.getString(col++);
log.debug("found rog: " + rog);
String rwg = rs.getString(col++);
log.debug("found rwg: " + rwg);

Subject owner = null;
if (ownerVal != null) {
owner = identityManager.toSubject(ownerVal);
}
// a value of zero is either null or false
boolean isPublic = readAnon != 0;
Boolean isPublic = (readAnon == null ? null : (readAnon == 1));
GroupURI readGroup = null;
GroupURI readWriteGroup = null;
if (rog != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public void doAction() throws Exception {
TablesAction.checkDropTablePermission(ts, tableName, logInfo);
dropTable(ts, tableName);
} else {
checkIsAdmin();
checkAdminPermission();
dropSchema(ts, schemaName);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@

import ca.nrc.cadc.dali.tables.votable.VOTableDocument;
import ca.nrc.cadc.dali.tables.votable.VOTableWriter;
import ca.nrc.cadc.net.HttpConstants;
import ca.nrc.cadc.net.ResourceNotFoundException;
import ca.nrc.cadc.tap.schema.SchemaDesc;
import ca.nrc.cadc.tap.schema.TableDesc;
Expand Down Expand Up @@ -165,6 +166,7 @@ public void doAction() throws Exception {
validationResult = ex.getMessage();
}
syncOutput.setCode(200);
setPermissionHeaders(td.tapPermissions);
syncOutput.setHeader("Content-Type", "text/plain");
PrintWriter w = new PrintWriter(new OutputStreamWriter(syncOutput.getOutputStream()));
w.print(tableName + ": ");
Expand All @@ -181,15 +183,17 @@ public void doAction() throws Exception {
// output the TableDesc as a VOTable
String accept = syncInput.getHeader("Accept");
if (VOTableWriter.CONTENT_TYPE.equals(accept)) {
VOTableDocument vot = TapSchemaUtil.createVOTable(td, validatorConfig);
VOTableWriter tw = new VOTableWriter();
final VOTableDocument vot = TapSchemaUtil.createVOTable(td, validatorConfig);
final VOTableWriter tw = new VOTableWriter();
syncOutput.setCode(200);
syncOutput.setHeader("Content-Type", VOTableWriter.CONTENT_TYPE);
setPermissionHeaders(td.tapPermissions);
syncOutput.setHeader(HttpConstants.HDR_CONTENT_TYPE, VOTableWriter.CONTENT_TYPE);
tw.write(vot, new OutputStreamWriter(syncOutput.getOutputStream()));
} else {
TableWriter tw = new TableWriter();
final TableWriter tw = new TableWriter();
syncOutput.setCode(200);
syncOutput.setHeader("Content-Type", "text/xml");
setPermissionHeaders(td.tapPermissions);
syncOutput.setHeader(HttpConstants.HDR_CONTENT_TYPE, "text/xml");
tw.write(td, new OutputStreamWriter(syncOutput.getOutputStream()));
}
} else if (schemaName != null) {
Expand All @@ -202,17 +206,18 @@ public void doAction() throws Exception {
TapSchema tapSchema = new TapSchema();
tapSchema.getSchemaDescs().add(sd);

TableSetWriter tsw = new TableSetWriter();
final TableSetWriter tsw = new TableSetWriter();
syncOutput.setCode(200);
syncOutput.setHeader("Content-Type", "text/xml");
setPermissionHeaders(sd.tapPermissions);
syncOutput.setHeader(HttpConstants.HDR_CONTENT_TYPE, "text/xml");
tsw.write(tapSchema, new OutputStreamWriter(syncOutput.getOutputStream()));
} else {
TapSchemaLoader loader = new TapSchemaLoader(dao);
TapSchema tapSchema = loader.load(depth);

TableSetWriter tsw = new TableSetWriter();
final TableSetWriter tsw = new TableSetWriter();
syncOutput.setCode(200);
syncOutput.setHeader("Content-Type", "text/xml");
syncOutput.setHeader(HttpConstants.HDR_CONTENT_TYPE, "text/xml");
tsw.write(tapSchema, new OutputStreamWriter(syncOutput.getOutputStream()));
}
}
Expand Down
Loading
Loading