diff --git a/WebApp/junit/resources/db_migrations/V44__last_nrt_export_2906.sql b/WebApp/junit/resources/db_migrations/V44__last_nrt_export_2906.sql new file mode 100644 index 000000000..ecc257cf8 --- /dev/null +++ b/WebApp/junit/resources/db_migrations/V44__last_nrt_export_2906.sql @@ -0,0 +1,2 @@ +-- Add field for last NRT export time +ALTER TABLE instrument ADD COLUMN last_nrt_export BIGINT NULL DEFAULT NULL AFTER `nrt`; diff --git a/WebApp/junit/resources/sql/data/DataSet/DataReduction/ControsPco2ReducerTest/dataset_both_zeros/V2000000__dataset_both_zeros.sql b/WebApp/junit/resources/sql/data/DataSet/DataReduction/ControsPco2ReducerTest/dataset_both_zeros/V2000000__dataset_both_zeros.sql index 172582a85..6effe1c9c 100644 --- a/WebApp/junit/resources/sql/data/DataSet/DataReduction/ControsPco2ReducerTest/dataset_both_zeros/V2000000__dataset_both_zeros.sql +++ b/WebApp/junit/resources/sql/data/DataSet/DataReduction/ControsPco2ReducerTest/dataset_both_zeros/V2000000__dataset_both_zeros.sql @@ -2,7 +2,7 @@ -- It consists of a sequence of ZERO, FLUSH, MEASUREMENTS, ZERO -- Instrument -INSERT INTO `instrument` VALUES (124,1,'Contros','IT-FOS-PALOMA','48MB',0,'{"depth":"0","latitude":"0.0","postFlushingTime":"0","preFlushingTime":"0","longitude":"0.0","sensorGroups":[{"name":"Default","members":["p_NDIR","p_in","Zero","Flush","Runtime","Signal_raw","Signal_ref","T_gas","TEMP","SAL"]}],"diagnosticQC":{}}','2024-02-01 15:01:57','2024-02-01 16:01:57'); +INSERT INTO `instrument` VALUES (124,1,'Contros','IT-FOS-PALOMA','48MB',0,NULL,'{"depth":"0","latitude":"0.0","postFlushingTime":"0","preFlushingTime":"0","longitude":"0.0","sensorGroups":[{"name":"Default","members":["p_NDIR","p_in","Zero","Flush","Runtime","Signal_raw","Signal_ref","T_gas","TEMP","SAL"]}],"diagnosticQC":{}}','2024-02-01 15:01:57','2024-02-01 16:01:57'); -- Instrument Variables INSERT INTO `instrument_variables` VALUES (124,6,'{"zero_flush":"0.00","zero_mode":"Continuous"}','2024-02-01 15:01:57','2024-02-01 16:01:57'); diff --git a/WebApp/junit/resources/sql/data/DataSet/DataReduction/ControsPco2ReducerTest/dataset_post_zero/V2000000__dataset_post_zero.sql b/WebApp/junit/resources/sql/data/DataSet/DataReduction/ControsPco2ReducerTest/dataset_post_zero/V2000000__dataset_post_zero.sql index 616473e88..3780e6e40 100644 --- a/WebApp/junit/resources/sql/data/DataSet/DataReduction/ControsPco2ReducerTest/dataset_post_zero/V2000000__dataset_post_zero.sql +++ b/WebApp/junit/resources/sql/data/DataSet/DataReduction/ControsPco2ReducerTest/dataset_post_zero/V2000000__dataset_post_zero.sql @@ -3,7 +3,7 @@ -- There is no pre-zero -- Instrument -INSERT INTO `instrument` VALUES (124,1,'Contros','IT-FOS-PALOMA','48MB',0,'{"depth":"0","latitude":"0.0","postFlushingTime":"0","preFlushingTime":"0","longitude":"0.0","sensorGroups":[{"name":"Default","members":["p_NDIR","p_in","Zero","Flush","Runtime","Signal_raw","Signal_ref","T_gas","TEMP","SAL"]}],"diagnosticQC":{}}','2024-02-01 15:01:57','2024-02-01 16:01:57'); +INSERT INTO `instrument` VALUES (124,1,'Contros','IT-FOS-PALOMA','48MB',0,NULL,'{"depth":"0","latitude":"0.0","postFlushingTime":"0","preFlushingTime":"0","longitude":"0.0","sensorGroups":[{"name":"Default","members":["p_NDIR","p_in","Zero","Flush","Runtime","Signal_raw","Signal_ref","T_gas","TEMP","SAL"]}],"diagnosticQC":{}}','2024-02-01 15:01:57','2024-02-01 16:01:57'); -- Instrument Variables INSERT INTO `instrument_variables` VALUES (124,6,'{"zero_flush":"0.00","zero_mode":"Continuous"}','2024-02-01 15:01:57','2024-02-01 16:01:57'); diff --git a/WebApp/junit/resources/sql/data/DataSet/DataReduction/ControsPco2ReducerTest/dataset_pre_zero/V2000000__dataset_pre_zero.sql b/WebApp/junit/resources/sql/data/DataSet/DataReduction/ControsPco2ReducerTest/dataset_pre_zero/V2000000__dataset_pre_zero.sql index e63219f40..5ed9e37ad 100644 --- a/WebApp/junit/resources/sql/data/DataSet/DataReduction/ControsPco2ReducerTest/dataset_pre_zero/V2000000__dataset_pre_zero.sql +++ b/WebApp/junit/resources/sql/data/DataSet/DataReduction/ControsPco2ReducerTest/dataset_pre_zero/V2000000__dataset_pre_zero.sql @@ -3,7 +3,7 @@ -- There is no post-zerp -- Instrument -INSERT INTO `instrument` VALUES (124,1,'Contros','IT-FOS-PALOMA','48MB',0,'{"depth":"0","latitude":"0.0","postFlushingTime":"0","preFlushingTime":"0","longitude":"0.0","sensorGroups":[{"name":"Default","members":["p_NDIR","p_in","Zero","Flush","Runtime","Signal_raw","Signal_ref","T_gas","TEMP","SAL"]}],"diagnosticQC":{}}','2024-02-01 15:01:57','2024-02-01 16:01:57'); +INSERT INTO `instrument` VALUES (124,1,'Contros','IT-FOS-PALOMA','48MB',0,NULL,'{"depth":"0","latitude":"0.0","postFlushingTime":"0","preFlushingTime":"0","longitude":"0.0","sensorGroups":[{"name":"Default","members":["p_NDIR","p_in","Zero","Flush","Runtime","Signal_raw","Signal_ref","T_gas","TEMP","SAL"]}],"diagnosticQC":{}}','2024-02-01 15:01:57','2024-02-01 16:01:57'); -- Instrument Variables INSERT INTO `instrument_variables` VALUES (124,6,'{"zero_flush":"0.00","zero_mode":"Continuous"}','2024-02-01 15:01:57','2024-02-01 16:01:57'); diff --git a/WebApp/junit/resources/sql/data/Instrument/SensorDefinition/VariableTest/flagCascade/V2000000__flagCascade.sql b/WebApp/junit/resources/sql/data/Instrument/SensorDefinition/VariableTest/flagCascade/V2000000__flagCascade.sql index 98d1499b1..b4daadf4d 100644 --- a/WebApp/junit/resources/sql/data/Instrument/SensorDefinition/VariableTest/flagCascade/V2000000__flagCascade.sql +++ b/WebApp/junit/resources/sql/data/Instrument/SensorDefinition/VariableTest/flagCascade/V2000000__flagCascade.sql @@ -68,7 +68,7 @@ INSERT INTO variable_sensors -- Now an instrument using the variable -INSERT INTO instrument VALUES (1,1,'Test Instrument','Test Instrument','TEST',0,'','2019-01-28 13:31:21','2019-01-28 14:31:21'); +INSERT INTO instrument VALUES (1,1,'Test Instrument','Test Instrument','TEST',0,NULL,'','2019-01-28 13:31:21','2019-01-28 14:31:21'); INSERT INTO instrument_variables (instrument_id, variable_id) VALUES (1, (SELECT id FROM variables WHERE name = 'testVar')); diff --git a/WebApp/junit/resources/sql/data/Instrument/SensorDefinition/VariableTest/flagCascadeDepends/V2000000__flagCascadeDepends.sql b/WebApp/junit/resources/sql/data/Instrument/SensorDefinition/VariableTest/flagCascadeDepends/V2000000__flagCascadeDepends.sql index c8fc3cea4..473ac5647 100644 --- a/WebApp/junit/resources/sql/data/Instrument/SensorDefinition/VariableTest/flagCascadeDepends/V2000000__flagCascadeDepends.sql +++ b/WebApp/junit/resources/sql/data/Instrument/SensorDefinition/VariableTest/flagCascadeDepends/V2000000__flagCascadeDepends.sql @@ -26,7 +26,7 @@ INSERT INTO variable_sensors -- Now an instrument using the variable -INSERT INTO instrument VALUES (1,1,'Test Instrument','Test Instrument','TEST',0,'','2019-01-28 13:31:21','2019-01-28 14:31:21'); +INSERT INTO instrument VALUES (1,1,'Test Instrument','Test Instrument','TEST',0,NULL,'','2019-01-28 13:31:21','2019-01-28 14:31:21'); INSERT INTO instrument_variables (instrument_id, variable_id) VALUES (1, (SELECT id FROM variables WHERE name = 'testVar')); diff --git a/WebApp/junit/resources/sql/testbase/instrument/V1000001__instruments.sql b/WebApp/junit/resources/sql/testbase/instrument/V1000001__instruments.sql index 9257ca86a..26b05c660 100644 --- a/WebApp/junit/resources/sql/testbase/instrument/V1000001__instruments.sql +++ b/WebApp/junit/resources/sql/testbase/instrument/V1000001__instruments.sql @@ -1,7 +1,7 @@ -- Benguela Stream instrument definition -- Instrument -INSERT INTO instrument VALUES (1,1,'Benguela Stream','Benguela Stream','BSBS',0,'','2019-01-28 13:31:21','2019-01-28 14:31:21'); +INSERT INTO instrument VALUES (1,1,'Benguela Stream','Benguela Stream','BSBS',0,NULL,'','2019-01-28 13:31:21','2019-01-28 14:31:21'); -- Instrument uses the basic marine pCO2 variable INSERT INTO instrument_variables (instrument_id, variable_id) diff --git a/WebApp/src/uk/ac/exeter/QuinCe/api/export/CompleteExport.java b/WebApp/src/uk/ac/exeter/QuinCe/api/export/CompleteExport.java index 3a2e155cd..ad94cddd1 100644 --- a/WebApp/src/uk/ac/exeter/QuinCe/api/export/CompleteExport.java +++ b/WebApp/src/uk/ac/exeter/QuinCe/api/export/CompleteExport.java @@ -21,6 +21,6 @@ protected int getNewStatus() { @Override protected void additionalAction(Connection conn, long id) throws Exception { - DataSetDB.setDatasetExported(conn, id); + DataSetDB.setDatasetExported(conn, id, true); } } diff --git a/WebApp/src/uk/ac/exeter/QuinCe/api/export/ExportList.java b/WebApp/src/uk/ac/exeter/QuinCe/api/export/ExportList.java index 8a335ed5d..551fcc851 100644 --- a/WebApp/src/uk/ac/exeter/QuinCe/api/export/ExportList.java +++ b/WebApp/src/uk/ac/exeter/QuinCe/api/export/ExportList.java @@ -1,6 +1,7 @@ package uk.ac.exeter.QuinCe.api.export; import java.sql.Connection; +import java.time.LocalDateTime; import java.util.Collection; import javax.ws.rs.GET; @@ -16,6 +17,7 @@ import uk.ac.exeter.QuinCe.data.Instrument.Instrument; import uk.ac.exeter.QuinCe.data.Instrument.InstrumentDB; import uk.ac.exeter.QuinCe.utils.DatabaseUtils; +import uk.ac.exeter.QuinCe.utils.DateTimeUtils; import uk.ac.exeter.QuinCe.utils.ExceptionUtils; import uk.ac.exeter.QuinCe.web.system.ResourceManager; @@ -44,6 +46,8 @@ @Path("/export/exportList") public class ExportList { + private static final long MIN_NRT_EXPORT_INTERVAL = 86400L; + /** * The main processing method for the API call. * @@ -71,22 +75,40 @@ public String getExportList() throws Exception { JsonArray json = new JsonArray(); for (DataSet dataset : datasets) { - JsonObject datasetJson = new JsonObject(); - - datasetJson.addProperty("id", dataset.getId()); - datasetJson.addProperty("name", dataset.getName()); - Instrument instrument = InstrumentDB.getInstrument(conn, dataset.getInstrumentId()); - JsonObject instrumentJson = new JsonObject(); - instrumentJson.addProperty("name", instrument.getName()); - instrumentJson.addProperty("user", instrument.getOwner().getFullName()); - datasetJson.add("instrument", instrumentJson); - json.add(datasetJson); + boolean canExport = true; + + if (dataset.isNrt()) { + if (null != instrument.getLastNrtExport()) { + long timeSinceLastNrtExport = DateTimeUtils.secondsBetween( + instrument.getLastNrtExport(), LocalDateTime.now()); + if (timeSinceLastNrtExport < MIN_NRT_EXPORT_INTERVAL) { + canExport = false; + } + } + } + + if (canExport) { + JsonObject datasetJson = new JsonObject(); + + datasetJson.addProperty("id", dataset.getId()); + datasetJson.addProperty("name", dataset.getName()); + + JsonObject instrumentJson = new JsonObject(); + instrumentJson.addProperty("name", instrument.getName()); + instrumentJson.addProperty("user", + instrument.getOwner().getFullName()); + datasetJson.add("instrument", instrumentJson); + + json.add(datasetJson); + } } result = json.toString(); - } catch (Exception e) { + } catch ( + + Exception e) { ExceptionUtils.printStackTrace(e); throw e; } finally { diff --git a/WebApp/src/uk/ac/exeter/QuinCe/data/Dataset/DataSetDB.java b/WebApp/src/uk/ac/exeter/QuinCe/data/Dataset/DataSetDB.java index ac2e2fc19..571f44fc1 100644 --- a/WebApp/src/uk/ac/exeter/QuinCe/data/Dataset/DataSetDB.java +++ b/WebApp/src/uk/ac/exeter/QuinCe/data/Dataset/DataSetDB.java @@ -113,6 +113,9 @@ public class DataSetDB { private static final String DATASET_EXPORTED_STATEMENT = "UPDATE dataset " + "SET exported = 1 WHERE id = ?"; + private static final String LAST_NRT_STATEMENT = "UPDATE instrument SET " + + "last_nrt_export = ? WHERE id = ?"; + private static final String SENSOR_OFFSETS_PROPERTY = "__SENSOR_OFFSETS"; /** @@ -1261,18 +1264,62 @@ public static Map getDataSetCounts(DataSource dataSource, return result; } - public static void setDatasetExported(Connection conn, long datasetId) - throws DatabaseException { + /** + * Mark a {@link DataSet} as having been exported. + * + * @param conn + * A database connection. + * @param datasetId + * The {@link DataSet}'s ID + * @param recordNrt + * If this is an NRT dataset, record the last NRT export time for the + * instrument. + * @throws DatabaseException + * @throws RecordNotFoundException + * @throws MissingParamException + */ + public static void setDatasetExported(Connection conn, long datasetId, + boolean recordNrt) + throws DatabaseException, MissingParamException, RecordNotFoundException { MissingParam.checkMissing(conn, "conn"); MissingParam.checkPositive(datasetId, "datasetId"); - try (PreparedStatement stmt = conn - .prepareStatement(DATASET_EXPORTED_STATEMENT)) { - stmt.setLong(1, datasetId); - stmt.execute(); + PreparedStatement setExportedStmt = null; + PreparedStatement setLastNrtStmt = null; + + try { + conn.setAutoCommit(false); + + setExportedStmt = conn.prepareStatement(DATASET_EXPORTED_STATEMENT); + setExportedStmt.setLong(1, datasetId); + setExportedStmt.execute(); + + if (recordNrt) { + DataSet dataset = getDataSet(conn, datasetId); + if (dataset.isNrt()) { + setLastNrtStmt = conn.prepareStatement(LAST_NRT_STATEMENT); + setLastNrtStmt.setLong(1, + DateTimeUtils.dateToLong(LocalDateTime.now())); + setLastNrtStmt.setLong(2, dataset.getInstrumentId()); + + setLastNrtStmt.execute(); + } + } + + conn.commit(); } catch (SQLException e) { throw new DatabaseException("Error setting dataset export status", e); + } finally { + DatabaseUtils.closeStatements(setExportedStmt, setLastNrtStmt); + + try { + conn.setAutoCommit(true); + } catch (SQLException e) { + // Close the connection so it can't be reused + DatabaseUtils.closeConnection(conn); + throw new DatabaseException("Error setting dataset export status", e); + } } } } diff --git a/WebApp/src/uk/ac/exeter/QuinCe/data/Instrument/Instrument.java b/WebApp/src/uk/ac/exeter/QuinCe/data/Instrument/Instrument.java index c77f129cf..273869465 100644 --- a/WebApp/src/uk/ac/exeter/QuinCe/data/Instrument/Instrument.java +++ b/WebApp/src/uk/ac/exeter/QuinCe/data/Instrument/Instrument.java @@ -1,5 +1,6 @@ package uk.ac.exeter.QuinCe.data.Instrument; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -136,6 +137,12 @@ public class Instrument { */ private boolean nrt = false; + /** + * The time at which the most recent automatic export of an NRT dataset was + * performed for this Instrument. + */ + private LocalDateTime lastNrtExport = null; + /** * The configuration for the behaviour of diagnostic sensors QC. */ @@ -169,8 +176,8 @@ public Instrument(User owner, long databaseId, String name, InstrumentFileSet fileDefinitions, List variables, Map variableProperties, SensorAssignments sensorAssignments, String platformName, - String platformCode, boolean nrt, String propertiesJson) - throws SensorGroupsException { + String platformCode, boolean nrt, LocalDateTime lastNrtExport, + String propertiesJson) throws SensorGroupsException { this.owner = owner; this.id = databaseId; @@ -182,6 +189,7 @@ public Instrument(User owner, long databaseId, String name, this.platformName = platformName; this.platformCode = platformCode; this.nrt = nrt; + this.lastNrtExport = lastNrtExport; parsePropertiesJson(propertiesJson); } @@ -210,8 +218,8 @@ public Instrument(User owner, long databaseId, String name, public Instrument(User owner, String name, InstrumentFileSet fileDefinitions, List variables, Map variableProperties, SensorAssignments sensorAssignments, String platformName, - String platformCode, boolean nrt, String propertiesJson) - throws SensorGroupsException { + String platformCode, boolean nrt, LocalDateTime lastNrtExport, + String propertiesJson) throws SensorGroupsException { this.owner = owner; this.name = name; @@ -222,6 +230,7 @@ public Instrument(User owner, String name, InstrumentFileSet fileDefinitions, this.platformName = platformName; this.platformCode = platformCode; this.nrt = nrt; + this.lastNrtExport = lastNrtExport; parsePropertiesJson(propertiesJson); } @@ -247,7 +256,8 @@ public Instrument(User owner, String name, InstrumentFileSet fileDefinitions, public Instrument(User owner, String name, InstrumentFileSet fileDefinitions, List variables, Map variableProperties, SensorAssignments sensorAssignments, SensorGroups sensorGroups, - String platformName, String platformCode, boolean nrt) { + String platformName, String platformCode, boolean nrt, + LocalDateTime lastNrtExport) { this.owner = owner; this.name = name; @@ -259,6 +269,7 @@ public Instrument(User owner, String name, InstrumentFileSet fileDefinitions, this.platformName = platformName; this.platformCode = platformCode; this.nrt = nrt; + this.lastNrtExport = lastNrtExport; this.properties = new Properties(); } @@ -1061,4 +1072,8 @@ public List getVariables(Collection ids) return result; } + + public LocalDateTime getLastNrtExport() { + return lastNrtExport; + } } diff --git a/WebApp/src/uk/ac/exeter/QuinCe/data/Instrument/InstrumentDB.java b/WebApp/src/uk/ac/exeter/QuinCe/data/Instrument/InstrumentDB.java index 7a18b36d7..c17202fe7 100644 --- a/WebApp/src/uk/ac/exeter/QuinCe/data/Instrument/InstrumentDB.java +++ b/WebApp/src/uk/ac/exeter/QuinCe/data/Instrument/InstrumentDB.java @@ -7,6 +7,7 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -46,6 +47,7 @@ import uk.ac.exeter.QuinCe.data.Instrument.SensorDefinition.VariableNotFoundException; import uk.ac.exeter.QuinCe.utils.DatabaseException; import uk.ac.exeter.QuinCe.utils.DatabaseUtils; +import uk.ac.exeter.QuinCe.utils.DateTimeUtils; import uk.ac.exeter.QuinCe.utils.MissingParam; import uk.ac.exeter.QuinCe.utils.MissingParamException; import uk.ac.exeter.QuinCe.utils.RecordNotFoundException; @@ -113,7 +115,7 @@ public class InstrumentDB { * SQL query to get an instrument's base record */ private static final String GET_INSTRUMENT_QUERY = "SELECT name, owner, " // 2 - + "platform_name, platform_code, nrt, properties " // 5 + + "platform_name, platform_code, nrt, last_nrt_export, properties " // 5 + "FROM instrument WHERE id = ?"; /** @@ -198,9 +200,9 @@ public class InstrumentDB { private static final String INSTRUMENT_LIST_QUERY = "SELECT " + "i.id, i.name, i.owner, i.platform_name, i.platform_code, i.nrt, " // 6 - + "i.properties, " // 7 - + "iv.variable_id, iv.properties, " // 9 - + "CONCAT(u.surname, ', ', u.firstname) AS owner_name " // 10 + + "i.last_nrt_export, i.properties, " // 8 + + "iv.variable_id, iv.properties, " // 10 + + "CONCAT(u.surname, ', ', u.firstname) AS owner_name " // 11 + "FROM instrument i LEFT JOIN instrument_variables iv ON i.id = iv.instrument_id " + "INNER JOIN user u on i.owner = u.id " + "WHERE i.id IN (" + "SELECT id FROM instrument WHERE OWNER = ? " + "UNION " @@ -209,9 +211,9 @@ public class InstrumentDB { private static final String ALL_INSTRUMENT_LIST_QUERY = "SELECT " + "i.id, i.name, i.owner, i.platform_name, i.platform_code, i.nrt, " // 6 - + "i.properties, " // 7 - + "iv.variable_id, iv.properties, " // 9 - + "CONCAT(u.surname, ', ', u.firstname) AS owner_name " // 10 + + "i.last_nrt_export, i.properties, " // 7 + + "iv.variable_id, iv.properties, " // 10 + + "CONCAT(u.surname, ', ', u.firstname) AS owner_name " // 11 + "FROM instrument i LEFT JOIN instrument_variables iv ON i.id = iv.instrument_id " + "INNER JOIN user u on i.owner = u.id " + "ORDER BY owner_name, i.owner, i.platform_name, i.name"; @@ -581,6 +583,7 @@ public static List getInstrumentList(Connection conn, String platformName = null; String platformCode = null; boolean nrt = false; + LocalDateTime lastNrtExport = null; String propertiesJson = null; List variables = null; Map variableProperties = null; @@ -593,7 +596,7 @@ public static List getInstrumentList(Connection conn, if (currentInstrument != -1) { result.add(createInstrument(conn, owner, currentInstrument, name, variables, variableProperties, platformName, platformCode, nrt, - propertiesJson)); + lastNrtExport, propertiesJson)); } currentInstrument = instrumentId; @@ -602,20 +605,21 @@ public static List getInstrumentList(Connection conn, platformName = records.getString(4); platformCode = records.getString(5); nrt = records.getBoolean(6); - propertiesJson = records.getString(7); + lastNrtExport = DateTimeUtils.longToDate(records.getLong(7)); + propertiesJson = records.getString(8); variables = new ArrayList(); variableProperties = new HashMap(); } - variables.add(records.getLong(8)); - variableProperties.put(records.getLong(8), records.getString(9)); + variables.add(records.getLong(9)); + variableProperties.put(records.getLong(9), records.getString(10)); } // Create the last instrument, if there is one if (currentInstrument != -1) { result.add(createInstrument(conn, owner, currentInstrument, name, variables, variableProperties, platformName, platformCode, nrt, - propertiesJson)); + lastNrtExport, propertiesJson)); } } catch (SQLException e) { @@ -631,7 +635,8 @@ public static List getInstrumentList(Connection conn, private static Instrument createInstrument(Connection conn, long ownerId, long id, String name, List variableIds, Map variableProperties, String platformName, - String platformCode, boolean nrt, String propertiesJson) + String platformCode, boolean nrt, LocalDateTime lastNrtExport, + String propertiesJson) throws MissingParamException, DatabaseException, RecordNotFoundException, InstrumentException, VariableNotFoundException, SensorGroupsException { @@ -661,7 +666,7 @@ private static Instrument createInstrument(Connection conn, long ownerId, return new Instrument(UserDB.getUser(conn, ownerId), id, name, files, variables, processedVariableProperties, sensorAssignments, platformName, - platformCode, nrt, propertiesJson); + platformCode, nrt, lastNrtExport, propertiesJson); } /** @@ -800,7 +805,11 @@ public static Instrument getInstrument(Connection conn, long instrumentId) String platformName = instrumentRecord.getString(3); String platformCode = instrumentRecord.getString(4); boolean nrt = instrumentRecord.getBoolean(5); - String propertiesJson = instrumentRecord.getString(6); + + LocalDateTime lastNrtExport = DateTimeUtils + .longToDate(instrumentRecord.getLong(6)); + + String propertiesJson = instrumentRecord.getString(7); // Now get the file definitions InstrumentFileSet files = getFileDefinitions(conn, instrumentId); @@ -817,7 +826,7 @@ public static Instrument getInstrument(Connection conn, long instrumentId) instrument = new Instrument(UserDB.getUser(conn, owner), instrumentId, name, files, variables, variableProperties, sensorAssignments, - platformName, platformCode, nrt, propertiesJson); + platformName, platformCode, nrt, lastNrtExport, propertiesJson); } } catch (SQLException e) { diff --git a/WebApp/src/uk/ac/exeter/QuinCe/utils/DateTimeUtils.java b/WebApp/src/uk/ac/exeter/QuinCe/utils/DateTimeUtils.java index 96b744224..3ec506b9e 100644 --- a/WebApp/src/uk/ac/exeter/QuinCe/utils/DateTimeUtils.java +++ b/WebApp/src/uk/ac/exeter/QuinCe/utils/DateTimeUtils.java @@ -97,9 +97,10 @@ public static long dateToLong(LocalDateTime date) { * The milliseconds value * @return The {@code LocalDateTime} object */ - public static LocalDateTime longToDate(long milliseconds) { - return LocalDateTime.ofInstant(Instant.ofEpochMilli(milliseconds), - ZoneOffset.UTC); + public static LocalDateTime longToDate(Long milliseconds) { + return null == milliseconds ? null + : LocalDateTime.ofInstant(Instant.ofEpochMilli(milliseconds), + ZoneOffset.UTC); } /** diff --git a/WebApp/src/uk/ac/exeter/QuinCe/web/Instrument/newInstrument/NewInstrumentBean.java b/WebApp/src/uk/ac/exeter/QuinCe/web/Instrument/newInstrument/NewInstrumentBean.java index cc1ddab2a..22452676a 100644 --- a/WebApp/src/uk/ac/exeter/QuinCe/web/Instrument/newInstrument/NewInstrumentBean.java +++ b/WebApp/src/uk/ac/exeter/QuinCe/web/Instrument/newInstrument/NewInstrumentBean.java @@ -1861,7 +1861,8 @@ public String saveInstrument() throws MissingParamException, // TODO groups in here. Instrument instrument = new Instrument(getUser(), instrumentName, instrumentFiles, instrumentVariables, storedVariableProperties, - sensorAssignments, sensorGroups, platformName, platformCode, false); + sensorAssignments, sensorGroups, platformName, platformCode, false, + null); instrument.setProperty(Instrument.PROP_PRE_FLUSHING_TIME, preFlushingTime); diff --git a/WebApp/src/uk/ac/exeter/QuinCe/web/datasets/export/ExportBean.java b/WebApp/src/uk/ac/exeter/QuinCe/web/datasets/export/ExportBean.java index a0e6e65b9..c826e21e1 100644 --- a/WebApp/src/uk/ac/exeter/QuinCe/web/datasets/export/ExportBean.java +++ b/WebApp/src/uk/ac/exeter/QuinCe/web/datasets/export/ExportBean.java @@ -199,7 +199,11 @@ private void exportDatasetWithRawFiles() { fc.responseComplete(); dataset.markExported(); - DataSetDB.setDatasetExported(conn, dataset.getId()); + + // Note that manual exports will not trigger the NRT Export recording, + // otherwise the automatic NRT export would be prevented from doing its + // job. + DataSetDB.setDatasetExported(conn, dataset.getId(), false); } catch (Exception e) { ExceptionUtils.printStackTrace(e); } finally { diff --git a/src/migrations/db_migrations/V44__last_nrt_export_2906.sql b/src/migrations/db_migrations/V44__last_nrt_export_2906.sql new file mode 100644 index 000000000..ecc257cf8 --- /dev/null +++ b/src/migrations/db_migrations/V44__last_nrt_export_2906.sql @@ -0,0 +1,2 @@ +-- Add field for last NRT export time +ALTER TABLE instrument ADD COLUMN last_nrt_export BIGINT NULL DEFAULT NULL AFTER `nrt`;