Author: [log in to unmask]
Date: Fri Jul 17 16:51:55 2015
New Revision: 3266
Log:
Minor changes to crawler and run db API.
Modified:
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/Crawler.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/CrawlerConfig.java
java/trunk/record-util/src/main/java/org/hps/record/run/EpicsDataReader.java
java/trunk/record-util/src/main/java/org/hps/record/run/RunManager.java
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/Crawler.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/Crawler.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/Crawler.java Fri Jul 17 16:51:55 2015
@@ -378,6 +378,7 @@
LOGGER.config("added date filter with time stamp " + config.timestamp());
}
+ // Is the accept run list not empty? (Empty means accept all runs.)
if (!config.acceptRuns().isEmpty()) {
// List of run numbers to accept.
visitor.addFilter(new RunFilter(config.acceptRuns()));
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/CrawlerConfig.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/CrawlerConfig.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/CrawlerConfig.java Fri Jul 17 16:51:55 2015
@@ -5,6 +5,7 @@
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -26,9 +27,10 @@
private static final SimpleDateFormat TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
- * A list of run numbers to accept in the job.
- */
- private Set<Integer> acceptRuns;
+ * A list of run numbers to accept in the job; this default will probably get overridden but it is here to avoid
+ * null pointer exceptions. An empty list is assumed to mean "accept all runs" e.g. no run number filtering.
+ */
+ private Set<Integer> acceptRuns = new LinkedHashSet<Integer>();
/**
* <code>true</code> if database updates are allowed meaning existing records can be deleted and replaced.
@@ -244,8 +246,9 @@
*
* @param maxDepth the max depth
*/
- void setMaxDepth(final Integer maxDepth) {
+ CrawlerConfig setMaxDepth(final Integer maxDepth) {
this.maxDepth = maxDepth;
+ return this;
}
/**
Modified: java/trunk/record-util/src/main/java/org/hps/record/run/EpicsDataReader.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/run/EpicsDataReader.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/run/EpicsDataReader.java Fri Jul 17 16:51:55 2015
@@ -7,7 +7,7 @@
import org.hps.record.epics.EpicsData;
/**
- * Convert run database records from the <i>run_epics</i> table in to a {@link EpicsData} object.
+ * Convert run database records from the <i>run_epics</i> table into a {@link EpicsData} object.
*
* @author Jeremy McCormick, SLAC
*/
Modified: java/trunk/record-util/src/main/java/org/hps/record/run/RunManager.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/run/RunManager.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/run/RunManager.java Fri Jul 17 16:51:55 2015
@@ -1,27 +1,37 @@
package org.hps.record.run;
import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.hps.conditions.database.ConnectionParameters;
import org.lcsim.conditions.ConditionsEvent;
import org.lcsim.conditions.ConditionsListener;
import org.lcsim.util.log.DefaultLogFormatter;
import org.lcsim.util.log.LogUtil;
/**
- * Manages access to the run database and creates a {@link RunSummary} object from the data for a specific run.
+ * Manages read-only access to the run database and creates a {@link RunSummary} object from the data for a specific
+ * run.
* <p>
- * This class can also convert database records into {@link org.hps.record.epics.EpicsData},
- * {@link org.hps.record.scalers.ScalerData}, and {@link org.hps.record.evio.crawler.EvioFileList} using their
- * {@link AbstractRunDatabaseReader} implementation classes.
+ * This class converts database records into {@link RunSummary}, {@link org.hps.record.epics.EpicsData},
+ * {@link org.hps.record.scalers.ScalerData}, and {@link org.hps.record.evio.crawler.EvioFileList} objects using their
+ * corresponding {@link AbstractRunDatabaseReader} implementation classes.
*
* @author Jeremy McCormick, SLAC
*/
public final class RunManager implements ConditionsListener {
/**
+ * The default connection parameters for read-only access to the run database using the standard 'hpsuser' account.
+ */
+ private static ConnectionParameters DEFAULT_CONNECTION_PARAMETERS = new ConnectionParameters("hpsuser",
+ "darkphoton", "hps_run_db", "hpsdb.jlab.org");
+
+ /**
* The singleton instance of the RunManager.
*/
private static RunManager INSTANCE;
@@ -32,9 +42,9 @@
private static Logger LOGGER = LogUtil.create(RunManager.class, new DefaultLogFormatter(), Level.ALL);
/**
- * Get the instance of the {@link RunManager}.
- *
- * @return the instance of the {@link RunManager}.
+ * Get the global instance of the {@link RunManager}.
+ *
+ * @return the global instance of the {@link RunManager}
*/
public static RunManager getRunManager() {
if (INSTANCE == null) {
@@ -44,11 +54,16 @@
}
/**
- * The database connection.
+ * The active database connection.
*/
private Connection connection;
/**
+ * The database connection parameters, initially set to the default parameters.
+ */
+ private ConnectionParameters connectionParameters = DEFAULT_CONNECTION_PARAMETERS;
+
+ /**
* The run number; the -1 value indicates that this has not been set externally yet.
*/
private int run = -1;
@@ -58,18 +73,18 @@
*/
private RunSummary runSummary = null;
+ /**
+ * Load new run information when conditions have changed.
+ */
@Override
- public void conditionsChanged(final ConditionsEvent conditionsEvent) {
- final int newRun = conditionsEvent.getConditionsManager().getRun();
- LOGGER.info("initializing for run " + newRun + " ...");
- this.setRun(newRun);
- LOGGER.info("done initializing for run " + this.getRun());
+ public synchronized void conditionsChanged(final ConditionsEvent conditionsEvent) {
+ this.setRun(conditionsEvent.getConditionsManager().getRun());
}
/**
* Get the database connection.
*
- * @return the database connection
+ * @return the database connection or <code>null</code> if it is not set
*/
Connection getConnection() {
return this.connection;
@@ -97,28 +112,29 @@
* Read information from the run database and create a {@link RunSummary} from it.
*/
private void readRun() {
- // Load main RunSummary object.
+
+ // Read main RunSummary object but not objects that it references.
final RunSummaryReader runSummaryReader = new RunSummaryReader();
runSummaryReader.setRun(this.getRun());
runSummaryReader.setConnection(this.getConnection());
runSummaryReader.read();
this.setRunSummary(runSummaryReader.getData());
- // Set EpicsData on RunSummary.
+ // Read EpicsData and set on RunSummary.
final EpicsDataReader epicsDataReader = new EpicsDataReader();
epicsDataReader.setRun(this.getRun());
epicsDataReader.setConnection(this.getConnection());
epicsDataReader.read();
this.getRunSummary().setEpicsData(epicsDataReader.getData());
- // Set ScalerData on RunSummary.
+ // Read ScalerData and set on RunSummary.
final ScalerDataReader scalerDataReader = new ScalerDataReader();
scalerDataReader.setRun(this.getRun());
scalerDataReader.setConnection(this.getConnection());
scalerDataReader.read();
this.getRunSummary().setScalerData(scalerDataReader.getData());
- // Set ScalerData on RunSummary.
+ // Read ScalerData and set on RunSummary.
final EvioFileListReader evioFileListReader = new EvioFileListReader();
evioFileListReader.setRun(this.getRun());
evioFileListReader.setConnection(this.getConnection());
@@ -127,38 +143,83 @@
}
/**
- * Set the database connection.
- *
- * @param connection the database connection
- */
- public void setConnection(final Connection connection) {
- this.connection = connection;
+ * Check if the current run number exists in the run database.
+ *
+ * @return <code>true</code> if run exists
+ */
+ private boolean runExists() throws SQLException {
+ PreparedStatement statement = null;
+ boolean exists = false;
+ try {
+ statement = connection.prepareStatement("SELECT run FROM runs where run = ?");
+ statement.setInt(1, this.run);
+ final ResultSet resultSet = statement.executeQuery();
+ exists = resultSet.next();
+ } finally {
+ if (statement != null) {
+ try {
+ statement.close();
+ } catch (final SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return exists;
+ }
+
+ /**
+ * Set the database connection parameters.
+ */
+ public void setConnectionParameters(final ConnectionParameters connectionParameters) {
+ this.connectionParameters = connectionParameters;
}
/**
* Set the run number.
+ * <p>
+ * This is public in order for the class to be usable without the conditions system but it should not be called
+ * within a standard lcsim job as it resets the global state of the RunManager.
*
* @param run the run number
*/
- public void setRun(final int run) {
-
- // Check status of database connection (must be open).
+ public synchronized void setRun(final int run) {
+
+ if (run < 0) {
+ throw new IllegalArgumentException("invalid run number: " + run);
+ }
+
try {
- if (this.connection.isClosed()) {
- throw new IllegalStateException("The connection is closed.");
+
+ // Setup the database connection.
+ if (this.connection == null || this.connection.isClosed()) {
+ this.connection = connectionParameters.createConnection();
}
+
+ // Set the current run number.
+ this.run = run;
+
+ // Does the current run exist in the database?
+ if (this.runExists()) {
+ LOGGER.info("run record found in hps_run_db for " + run);
+ try {
+ // Read the records from the database and convert into Java objects.
+ this.readRun();
+ } catch (final Exception e) {
+ // There was some unknown error when reading in the run records.
+ LOGGER.log(Level.SEVERE, "Error reading from run database for run: " + run, e);
+ throw new RuntimeException(e);
+ }
+ } else {
+ // Run is not in the database.
+ LOGGER.warning("run database record does not exist for run " + run);
+ }
+
+ // Close the database connection.
+ this.connection.close();
+
} catch (final SQLException e) {
throw new RuntimeException(e);
}
-
- this.run = run;
-
- try {
- // Read the run records from the database and convert into Java objects.
- this.readRun();
- } catch (final Exception e) {
- LOGGER.log(Level.SEVERE, "Error reading from run database for run: " + run, e);
- }
}
/**
|