From cb53fdd5912d7ba5bfba4af2dac7382e0e982b65 Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Wed, 16 May 2012 11:54:17 +0000 Subject: [PATCH] SP-39 timestamp: checking improved and tested, read SQL statement can return a list. SVN: 25277 --- .../server/task/MaterialReportingTask.java | 25 ++- .../task/MaterialReportingTaskTest.java | 149 ++++++++++++++++-- 2 files changed, 151 insertions(+), 23 deletions(-) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/MaterialReportingTask.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/MaterialReportingTask.java index 5222d54581f..1299299445a 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/MaterialReportingTask.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/MaterialReportingTask.java @@ -39,7 +39,6 @@ import java.util.TreeMap; import org.apache.commons.lang.time.DateFormatUtils; import org.apache.log4j.Logger; -import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.ColumnMapRowMapper; import org.springframework.jdbc.core.JdbcTemplate; @@ -617,6 +616,15 @@ public class MaterialReportingTask implements IMaintenanceTask + INSERT_TIMESTAMP_SQL_KEY + "' or '" + UPDATE_TIMESTAMP_SQL_KEY + "' could be invalid.", ex); } + try + { + writeTimestamp(timestamp == null ? new Date(0) : timestamp); + } catch (Exception ex) + { + throw new ConfigurationFailureException( + "Couldn't save timestamp to report database. Property '" + + UPDATE_TIMESTAMP_SQL_KEY + "' could be invalid.", ex); + } } private String readTimestamp() @@ -628,18 +636,9 @@ public class MaterialReportingTask implements IMaintenanceTask private Date tryToReadTimestamp() { - try - { - return (Date) jdbcTemplate.queryForObject(readTimestampSql, Date.class); - } catch (IncorrectResultSizeDataAccessException ex) - { - int actualSize = ex.getActualSize(); - if (actualSize == 0) - { - return null; - } - throw ex; - } + @SuppressWarnings("unchecked") + List<Date> list = jdbcTemplate.queryForList(readTimestampSql, Date.class); + return list.isEmpty() ? null : list.get(0); } private void writeTimestamp(Date newTimestamp) diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/task/MaterialReportingTaskTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/task/MaterialReportingTaskTest.java index 625b97657d3..d47c726fb22 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/task/MaterialReportingTaskTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/task/MaterialReportingTaskTest.java @@ -16,6 +16,10 @@ package ch.systemsx.cisd.openbis.generic.server.task; +import static ch.systemsx.cisd.openbis.generic.server.task.MaterialReportingTask.INSERT_TIMESTAMP_SQL_KEY; +import static ch.systemsx.cisd.openbis.generic.server.task.MaterialReportingTask.READ_TIMESTAMP_SQL_KEY; +import static ch.systemsx.cisd.openbis.generic.server.task.MaterialReportingTask.UPDATE_TIMESTAMP_SQL_KEY; + import java.io.File; import java.sql.Connection; import java.sql.SQLException; @@ -108,12 +112,9 @@ public class MaterialReportingTaskTest extends AbstractFileSystemTestCase dbConfigContext.closeConnections(); mappingFile = new File(workingDirectory, "mapping-file.txt"); properties = new Properties(); - properties.setProperty(MaterialReportingTask.READ_TIMESTAMP_SQL_KEY, - "select timestamp from timestamp"); - properties.setProperty(MaterialReportingTask.INSERT_TIMESTAMP_SQL_KEY, - "insert into timestamp values(?)"); - properties.setProperty(MaterialReportingTask.UPDATE_TIMESTAMP_SQL_KEY, - "update timestamp set timestamp = ?"); + properties.setProperty(READ_TIMESTAMP_SQL_KEY, "select timestamp from timestamp"); + properties.setProperty(UPDATE_TIMESTAMP_SQL_KEY, "update timestamp set timestamp = ?"); + properties.setProperty(INSERT_TIMESTAMP_SQL_KEY, "insert into timestamp values(?)"); properties.setProperty("database-driver", "org.postgresql.Driver"); properties.setProperty("database-url", "jdbc:postgresql://localhost/" + databaseName); properties.setProperty("database-username", "postgres"); @@ -490,6 +491,132 @@ public class MaterialReportingTaskTest extends AbstractFileSystemTestCase context.assertIsSatisfied(); } + @Test + public void testTimestampReadingWriting() throws Exception + { + FileUtilities.writeToFile(mappingFile, ""); + prepareListMaterialTypes(); + properties.setProperty(INSERT_TIMESTAMP_SQL_KEY, "insert into b values(?)"); + + try + { + materialReportingTask.setUp("", properties); + fail("ConfigurationFailureException expected"); + } catch (ConfigurationFailureException ex) + { + assertEquals("Couldn't save timestamp to report database. Property '" + + INSERT_TIMESTAMP_SQL_KEY + "' or '" + UPDATE_TIMESTAMP_SQL_KEY + + "' could be invalid.", ex.getMessage()); + assertEquals("PreparedStatementCallback; bad SQL grammar [insert into b values(?)]; " + + "nested exception is org.postgresql.util.PSQLException: " + + "ERROR: relation \"b\" does not exist\n" + " Position: 13", ex.getCause() + .getMessage()); + } + + context.assertIsSatisfied(); + } + + @Test + public void testTimestampReadingWritingForInvalidUpdateSqlStatement() throws Exception + { + FileUtilities.writeToFile(mappingFile, ""); + prepareListMaterialTypes(); + properties.setProperty(UPDATE_TIMESTAMP_SQL_KEY, "insert into b values(?)"); + + try + { + materialReportingTask.setUp("", properties); + fail("ConfigurationFailureException expected"); + } catch (ConfigurationFailureException ex) + { + assertEquals("Couldn't save timestamp to report database. Property '" + + UPDATE_TIMESTAMP_SQL_KEY + "' could be invalid.", ex.getMessage()); + assertEquals("PreparedStatementCallback; bad SQL grammar [insert into b values(?)]; " + + "nested exception is org.postgresql.util.PSQLException: " + + "ERROR: relation \"b\" does not exist\n" + " Position: 13", ex.getCause() + .getMessage()); + } + + context.assertIsSatisfied(); + } + + @Test + public void testTimestampReadingWritingForInvalidReadSqlStatement() throws Exception + { + FileUtilities.writeToFile(mappingFile, ""); + prepareListMaterialTypes(); + properties.setProperty(READ_TIMESTAMP_SQL_KEY, "select blabla from timestamp"); + properties.setProperty(UPDATE_TIMESTAMP_SQL_KEY, "insert into timestamp values(?)"); + properties.remove(INSERT_TIMESTAMP_SQL_KEY); + + try + { + materialReportingTask.setUp("", properties); + fail("ConfigurationFailureException expected"); + } catch (ConfigurationFailureException ex) + { + assertEquals("Couldn't get timestamp from report database. Property '" + + READ_TIMESTAMP_SQL_KEY + "' could be invalid.", ex.getMessage()); + assertEquals("StatementCallback; bad SQL grammar [select blabla from timestamp]; " + + "nested exception is org.postgresql.util.PSQLException: " + + "ERROR: column \"blabla\" does not exist\n" + " Position: 8", ex.getCause() + .getMessage()); + } + + context.assertIsSatisfied(); + } + + @Test + public void testTimestampReadingWritingWithDifferentSchema() throws Exception + { + FileUtilities.writeToFile(mappingFile, ""); + prepareListMaterialTypes(); + prepareListMaterialTypes(); + properties.setProperty(READ_TIMESTAMP_SQL_KEY, "select max(timestamp) from timestamp"); + properties.setProperty(UPDATE_TIMESTAMP_SQL_KEY, "insert into timestamp values(?)"); + properties.remove(INSERT_TIMESTAMP_SQL_KEY); + final RecordingMatcher<DetailedSearchCriteria> criteriaRecorder = + new RecordingMatcher<DetailedSearchCriteria>(); + final Sequence timeSequence = context.sequence("time"); + context.checking(new Expectations() + { + { + exactly(2).of(server).tryToAuthenticateAsSystem(); + SessionContextDTO session = new SessionContextDTO(); + session.setSessionToken(SESSION_TOKEN); + will(returnValue(session)); + + exactly(2).of(server).searchForMaterials(with(SESSION_TOKEN), + with(criteriaRecorder)); + + one(timeProvider).getTimeInMilliseconds(); + will(returnValue(24L * 3600L * 1000L * 60L)); + inSequence(timeSequence); + + one(timeProvider).getTimeInMilliseconds(); + will(returnValue(24L * 3600L * 1000L * 62L)); + inSequence(timeSequence); + } + }); + + materialReportingTask.setUp("", properties); + materialReportingTask.execute(); + materialReportingTask.setUp("", properties); + materialReportingTask.execute(); + + assertEquals("[{timestamp=1970-01-01 01:00:00.0}, {timestamp=1970-01-01 01:00:00.0}, " + + "{timestamp=1970-03-02 01:00:00.0}, {timestamp=1970-03-02 01:00:00.0}, " + + "{timestamp=1970-03-02 01:00:00.0}, {timestamp=1970-03-04 01:00:00.0}]", + loadTable("timestamp", false).toString()); + List<DetailedSearchCriteria> recordedObjects = criteriaRecorder.getRecordedObjects(); + assertEquals("1970-01-01 01:00:00 +0100", recordedObjects.get(0).getCriteria().get(0) + .getValue()); + assertEquals("1970-03-02 01:00:00 +0100", recordedObjects.get(1).getCriteria().get(0) + .getValue()); + assertEquals(2, recordedObjects.size()); + context.assertIsSatisfied(); + } + @Test public void testInsert() throws Exception { @@ -617,10 +744,12 @@ public class MaterialReportingTaskTest extends AbstractFileSystemTestCase + "rank=null, size=null, timestamp=null}]", result.toString()); assertEquals("[{timestamp=1970-03-04 01:00:00.0}]", loadTable("timestamp", false) .toString()); - assertEquals("1970-01-01 01:00:00 +0100", criteriaRecorder.getRecordedObjects().get(0) - .getCriteria().get(0).getValue()); - assertEquals("1970-03-02 01:00:00 +0100", criteriaRecorder.getRecordedObjects().get(1) - .getCriteria().get(0).getValue()); + List<DetailedSearchCriteria> recordedObjects = criteriaRecorder.getRecordedObjects(); + assertEquals("1970-01-01 01:00:00 +0100", recordedObjects.get(0).getCriteria().get(0) + .getValue()); + assertEquals("1970-03-02 01:00:00 +0100", recordedObjects.get(1).getCriteria().get(0) + .getValue()); + assertEquals(2, recordedObjects.size()); context.assertIsSatisfied(); } -- GitLab