/** * Load any available events from the database up to the configured maximum. * * @param criteria An event containing the event-selection criteria. * @return The next available event on the queue. * @exception FrameworkException Thrown on errors. */ private void loadFromDatabase(Event criteria) throws FrameworkException { Debug.log(Debug.MSG_STATUS, "QUEUE OPERATION: Loading events from database into queue ..."); if (!StringUtils.hasValue(criteria.channelName)) { throw new FrameworkException( "ERROR: Event channel name is a required queue search criteria."); } Connection dbConn = null; PreparedStatement ps = null; long startTime = -1; if (Debug.isLevelEnabled(Debug.BENCHMARK)) startTime = System.currentTimeMillis(); try { dbConn = DBConnectionPool.getInstance().acquireConnection(); if (Debug.isLevelEnabled(Debug.DB_DATA)) Debug.log(Debug.DB_DATA, "\n" + LINE + "\nExecuting SQL:\n" + QUERY_EVENT_SQL); if (Debug.isLevelEnabled(Debug.DB_DATA)) Debug.log( Debug.DB_DATA, "Criteria used in query against database:\n" + criteria.describe()); ps = dbConn.prepareStatement(QUERY_EVENT_SQL); ps.setString(1, criteria.channelName); ResultSet rs = ps.executeQuery(); for (int counter = 0; (counter < maxDatabaseEventLoadSize) && rs.next(); counter++) { Event event = new Event(); event.channelName = rs.getString(CHANNEL_NAME_COL); event.id = rs.getInt(ID_COL); event.message = DBLOBUtils.getCLOB(rs, MESSAGE_COL); if (Debug.isLevelEnabled(Debug.MSG_LIFECYCLE)) Debug.log(Debug.MSG_LIFECYCLE, "Event contents:\n" + event.message); event.arrivalTime = rs.getTimestamp(ARRIVAL_TIME_COL); event.errorStatus = rs.getString(ERROR_STATUS_COL); event.errorCount = rs.getInt(ERROR_COUNT_COL); event.lastErrorMessage = rs.getString(LAST_ERROR_MESSAGE_COL); event.lastErrorTime = rs.getTimestamp(LAST_ERROR_TIME_COL); // Add item to in-memory buffer. if (Debug.isLevelEnabled(Debug.MSG_STATUS)) Debug.log( Debug.MSG_STATUS, "Adding event [" + event.describe() + "] to in-memory queue buffer."); queue.add(event); if (Debug.isLevelEnabled(Debug.MSG_STATUS)) Debug.log(Debug.MSG_STATUS, "In-memory queue buffer size [" + queue.size() + "]."); } if (Debug.isLevelEnabled(Debug.DB_DATA)) Debug.log(Debug.DB_DATA, "\n" + LINE); } catch (SQLException sqle) { throw new DatabaseException( "ERROR: Could not execute SQL statement:\n" + DBInterface.getSQLErrorMessage(sqle)); } catch (Exception e) { throw new DatabaseException("ERROR: Could not execute SQL statement:\n" + e.toString()); } finally { releaseDatabaseResources(dbConn, ps); if (Debug.isLevelEnabled(Debug.BENCHMARK) && (startTime > 0)) { long stopTime = System.currentTimeMillis(); Debug.log( Debug.BENCHMARK, "ELAPSED TIME [" + (stopTime - startTime) + "] msec: " + "SQL: Time to load event(s) from PersistentEvent database table."); } } }
/** * Update the given event as indicated. * * @param event The event to update. * @param eventStatus The event delivery status. * @exception FrameworkException Thrown on errors. */ public void update(Event event, EventStatus eventStatus) throws FrameworkException { if (Debug.isLevelEnabled(Debug.MSG_STATUS)) Debug.log( Debug.MSG_STATUS, "QUEUE OPERATION: Updating database queue using event status [" + eventStatus.name + "] ..."); // If no consumers were available, the event delivery wasn't attempted so leave // the queue in its current state. if (eventStatus == EventStatus.NO_CONSUMERS_AVAILABLE) { Debug.log( Debug.MSG_STATUS, "Skipping queue update, as no consumers were available to process it."); return; } Connection dbConn = null; PreparedStatement ps = null; long startTime = -1; if (Debug.isLevelEnabled(Debug.BENCHMARK)) startTime = System.currentTimeMillis(); try { dbConn = DBConnectionPool.getInstance().acquireConnection(); if (eventStatus == EventStatus.DELIVERY_SUCCESSFUL) { // If the event was successfully delivered, update status in database to delivered. if (Debug.isLevelEnabled(Debug.DB_DATA)) Debug.log(Debug.DB_DATA, "\n" + LINE + "\nExecuting SQL:\n" + UPDATE_EVENT_SUCCESS_SQL); ps = dbConn.prepareStatement(UPDATE_EVENT_SUCCESS_SQL); java.sql.Timestamp ts = new java.sql.Timestamp(System.currentTimeMillis()); ps.setTimestamp(1, ts); ps.setString(2, event.channelName); ps.setInt(3, event.id); } else if (eventStatus == EventStatus.DELIVERY_FAILED) { // If the event delivery failed, we mark it as failed in the database. if (Debug.isLevelEnabled(Debug.DB_DATA)) Debug.log(Debug.DB_DATA, "\n" + LINE + "\nExecuting SQL:\n" + UPDATE_EVENT_ERROR_SQL); // Truncate error message if it's larger than database column. if ((event.lastErrorMessage != null) && (event.lastErrorMessage.length() > MAX_ERROR_MESSAGE_LENGTH)) event.lastErrorMessage = event.lastErrorMessage.substring(0, MAX_ERROR_MESSAGE_LENGTH); event.lastErrorTime = new java.sql.Timestamp(System.currentTimeMillis()); ps = dbConn.prepareStatement(UPDATE_EVENT_ERROR_SQL); ps.setTimestamp(1, event.lastErrorTime); ps.setString(2, event.lastErrorMessage); ps.setString(3, event.channelName); ps.setInt(4, event.id); } else { throw new FrameworkException( "ERROR: Invalid event update type [" + eventStatus.name + "]."); } if (Debug.isLevelEnabled(Debug.DB_DATA)) Debug.log(Debug.DB_DATA, "Event being operated on in database:\n" + event.describe()); int numRows = ps.executeUpdate(); if (numRows > 1) { String errMsg = "Execution of update SQL statement affected [" + numRows + "] rows."; Debug.error(errMsg); throw new FrameworkException(errMsg); } DBConnectionPool.getInstance().commit(dbConn); if (Debug.isLevelEnabled(Debug.DB_DATA)) Debug.log(Debug.DB_DATA, "Successfully committed SQL operation.\n" + LINE); // At this point, the event should be removed from the in-memory buffer of events as well, // irrespective of processing outcome. if (Debug.isLevelEnabled(Debug.MSG_STATUS)) Debug.log( Debug.MSG_STATUS, "Removing event [" + event.describe() + "] from in-memory queue buffer."); boolean removed = queue.remove(event); if (Debug.isLevelEnabled(Debug.MSG_STATUS)) Debug.log( Debug.MSG_STATUS, "Event removed? [" + removed + "]. In-memory queue buffer size [" + queue.size() + "]."); } catch (SQLException sqle) { throw new DatabaseException( "ERROR: Could not execute SQL statement:\n" + DBInterface.getSQLErrorMessage(sqle)); } catch (Exception e) { throw new DatabaseException("ERROR: Could not execute SQL statement:\n" + e.toString()); } finally { releaseDatabaseResources(dbConn, ps); if (Debug.isLevelEnabled(Debug.BENCHMARK) && (startTime > 0)) { long stopTime = System.currentTimeMillis(); Debug.log( Debug.BENCHMARK, "ELAPSED TIME [" + (stopTime - startTime) + "] msec: " + "SQL: Time to update event in PersistentEvent database table."); } } }