[java-opensaml] 06/06: OSJ-342 Investigate Strategies to end of life our use of Hibernate in V5
Rod Widdowson
rdw at steadingsoftware.com
Thu May 12 16:15:45 UTC 2022
This is an automated email from the git hooks/post-receive script.
rdw pushed a commit to branch dev/OSJ-342
in repository java-opensaml.
View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=41f8e238396d88b6f51f0a997dcaf99666bc7b4f
commit 41f8e238396d88b6f51f0a997dcaf99666bc7b4f
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Thu May 12 17:08:59 2022 +0100
OSJ-342 Investigate Strategies to end of life our use of Hibernate in V5
https://shibboleth.atlassian.net/browse/OSJ-342
Start to productize the code: Parameterize all the SQL and exbed
the storage record.
---
.../opensaml/storage/impl/JDBCStorageRecord.java | 48 +++
.../opensaml/storage/impl/JDBCStorageService.java | 368 +++++++++++++++++----
2 files changed, 360 insertions(+), 56 deletions(-)
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/JDBCStorageRecord.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/JDBCStorageRecord.java
new file mode 100644
index 000000000..e08682e70
--- /dev/null
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/JDBCStorageRecord.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opensaml.storage.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.storage.MutableStorageRecord;
+
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+
+/** Storage record used by {@link JDBCStorageService}.
+ * This is notable in that it allows creation with a specified version (from
+ * the database).
+ * @param <T> type of record
+ */
+class JDBCStorageRecord<T> extends MutableStorageRecord<T> {
+
+ /**
+ * Constructor.
+ *
+ * @param val The value to store
+ * @param exp The expiration
+ * @param version The version.
+ */
+ public JDBCStorageRecord(@Nonnull @NotEmpty final String val,
+ @Nullable final Long exp, @Nullable final Long version) {
+ super(val, exp);
+ if (version != null) {
+ setVersion(version);
+ }
+ }
+}
\ No newline at end of file
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/JDBCStorageService.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/JDBCStorageService.java
index e424db6e6..73dbb5c4f 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/JDBCStorageService.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/JDBCStorageService.java
@@ -1,3 +1,4 @@
+// Checkstyle: FileLength|Header OFF
/*
* Licensed to the University Corporation for Advanced Internet Development,
* Inc. (UCAID) under one or more contributor license agreements. See the
@@ -49,13 +50,68 @@ import net.shibboleth.utilities.java.support.collection.Pair;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.logic.ConstraintViolationException;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
/**
- *
+ * Implementation of {@link org.opensaml.storage.StorageService} that uses native JDBC to persist to a database.
*/
public final class JDBCStorageService extends AbstractStorageService implements StorageCapabilitiesEx {
+ /* Default SQL. Keep it here to keep it together and to allow isertion into javadoc */
+ /** The SQL to get all the contexts.*/
+ static final String DEFAULT_READ_CONTEXTS_SQL = "SELECT context FROM StorageRecords";
+
+ /** The SQL to get all the records.*/
+ static final String DEFAULT_READ_ALL_SQL = "SELECT context, id, expires, value, version FROM StorageRecords";
+
+ /** The SQL to get all the records for a specific context.*/
+ static final String DEFAULT_READ_ALL_BY_CONTEXT_SQL =
+ "SELECT id, expires, value, version FROM StorageRecords WHERE context = ?";
+
+ /** The SQL to get check whether this record already exists and is unexpired prior to a create.*/
+ static final String DEFAULT_PRE_CREATE_QUERY_SQL = "SELECT expires FROM StorageRecords WHERE context =? AND id=?";
+
+ /** The SQL to create a new record. */
+ static final String DEFAULT_CREATE_CREATE_RECORD_SQL = "INSERT INTO StorageRecords VALUES (?, ?, ?, ?, 1)";
+
+ /** The SQL to update an expired record as part of a create. */
+ static final String DEFAULT_CREATE_UPDATE_RECORD_SQL =
+ "UPDATE StorageRecords SET value=?, version=1, expires=? WHERE context=? AND id=?";
+
+ /** The SQL to read a single record.*/
+ static final String DEFAULT_READ_RECORD_SQL =
+ "SELECT version, expires, value FROM StorageRecords WHERE context =? AND id=?";
+
+ /** The SQL to check whether a record exists prior to updating it. */
+ static final String DEFAULT_PRE_UPDATE_QUERY_SQL =
+ "SELECT version, expires FROM StorageRecords WHERE context =? AND id=?";
+
+ /** The SQL to update a record. */
+ static final String DEFAULT_UPDATE_RECORD_SQL =
+ "UPDATE StorageRecords SET value=?, version=?, expires=? WHERE context=? AND id=?";
+
+ /** The SQL to check whether a record exists prior to deleting it.*/
+ static final String DEFAULT_PRE_DELETE_QUERY_SQL ="SELECT version FROM StorageRecords WHERE context =? AND id=?";
+
+ /** The SQL to delete a record. */
+ static final String DEFAULT_DELETE_RECORD_SQL = "DELETE FROM StorageRecords WHERE context=? AND id=?";
+
+ /** The SQL to delete all records by specified expiration. */
+ static final String DEFAULT_DELETE_BY_EXPIRED_SQL = "DELETE FROM StorageRecords WHERE expires < ? ";
+
+ /** The SQL to delete all records by specified context and expiration. */
+ static final String DEFAULT_DELETE_BY_CONTEXT_EXPIRED_SQL =
+ "DELETE FROM StorageRecords WHERE context = ? AND expires < ?";
+
+ /** The SQL to update the expiration for a given context. */
+ static final String DEFAULT_UPDATE_EXPIRES_BY_CONTEXT_SQL =
+ "UPDATE StorageRecords SET expires = ? WHERE context = ? AND expires > ? ";
+
+ /** The SQL to delete a given context. */
+ static final String DEFAULT_DELETE_BY_CONTEXT_SQL = "DELETE FROM StorageRecords WHERE context = ? ";
+
+
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(JDBCStorageService.class);
@@ -68,12 +124,97 @@ public final class JDBCStorageService extends AbstractStorageService implements
/** The Data Source. */
@NonnullAfterInit private DataSource dataSource;
- /** {@inheritDoc} */
- protected void doInitialize() throws ComponentInitializationException {
- Constraint.isNotNull(dataSource, "data source must be specified and nonnul");
- super.doInitialize();
- }
+ /* SQL Statements */
+ /**
+ * The SQL to get all the contexts.
+ * Default: {@value #DEFAULT_READ_CONTEXTS_SQL}.
+ */
+ @Nonnull @NotEmpty private String readContextsSQL = DEFAULT_READ_CONTEXTS_SQL;
+
+ /**
+ * The SQL to get all the records.
+ * Default: {@value #DEFAULT_READ_ALL_SQL}.
+ */
+ @Nonnull @NotEmpty private String readAllSQL = DEFAULT_READ_ALL_SQL;
+
+ /**
+ * The SQL to get all the records for a specific context.
+ * Default: {@value #DEFAULT_READ_ALL_BY_CONTEXT_SQL}
+ */
+ @Nonnull @NotEmpty private String readAllByContextSQL = DEFAULT_READ_ALL_BY_CONTEXT_SQL;
+
+ /**
+ * The SQL to get check whether this record already exists and is unexpired prior to a create.
+ * Default: {@value #DEFAULT_PRE_CREATE_QUERY_SQL}
+ */
+ @Nonnull @NotEmpty private String preCreateQuerySQL = DEFAULT_PRE_CREATE_QUERY_SQL;
+
+ /**
+ * The SQL to create a new record (transactional with {@link #preCreateQuerySQL}.
+ * Default: {@value #DEFAULT_CREATE_CREATE_RECORD_SQL}
+ */
+ @Nonnull @NotEmpty private String createCreateRecordSQL = DEFAULT_CREATE_CREATE_RECORD_SQL;
+
+ /**
+ * The SQL to update an expired record as part of a create (transactional with {@link #preCreateQuerySQL}.
+ * Default: {@value #DEFAULT_CREATE_UPDATE_RECORD_SQL}
+ */
+ @Nonnull @NotEmpty private String createUpdateRecordSQL = DEFAULT_CREATE_UPDATE_RECORD_SQL;
+
+ /**
+ * The SQL to read a single record.
+ * Default: {@value #DEFAULT_READ_RECORD_SQL}
+ */
+ @Nonnull @NotEmpty private String readRecordSQL = DEFAULT_READ_RECORD_SQL;
+ /**
+ * The SQL to check whether a record exists prior to updating it.
+ * Default: {@value #DEFAULT_PRE_UPDATE_QUERY_SQL}
+ */
+ @Nonnull @NotEmpty private String preUpdateQuerySQL = DEFAULT_PRE_UPDATE_QUERY_SQL;
+
+ /** The SQL to update a record. Transactional with {@link #preUpdateQuerySQL}.
+ * Default: {@value #DEFAULT_UPDATE_RECORD_SQL}
+ */
+ @Nonnull @NotEmpty private String updateRecordSQL = DEFAULT_UPDATE_RECORD_SQL;
+
+ /**
+ * The SQL to check whether a record exists prior to deleting it.
+ * Default: {@value #DEFAULT_PRE_DELETE_QUERY_SQL}
+ */
+ @Nonnull @NotEmpty private String preDeleteQuerySQL = DEFAULT_PRE_DELETE_QUERY_SQL;
+
+ /**
+ * The SQL to delete a record. Transactional with {@link #preDeleteQuerySQL}
+ * Default: {@value #DEFAULT_DELETE_RECORD_SQL}
+ */
+ @Nonnull @NotEmpty private String deleteRecordSQL = DEFAULT_DELETE_RECORD_SQL;
+
+ /**
+ * The SQL to delete expired record. Used as part of the {@link #getCleanupTask()}.
+ * Default: {@value #DEFAULT_DELETE_BY_EXPIRED_SQL}
+ */
+ @Nonnull @NotEmpty private String deleteByExpiredSQL = DEFAULT_DELETE_BY_EXPIRED_SQL;
+
+ /**
+ * The SQL to delete expired record with specified context. Used as part of {@link #reap(String)}.
+ * Default: {@value #DEFAULT_DELETE_BY_CONTEXT_EXPIRED_SQL}
+ */
+ @Nonnull @NotEmpty private String deleteByContextExpiredSQL = DEFAULT_DELETE_BY_CONTEXT_EXPIRED_SQL;
+
+ /**
+ * The SQL to update the expiration of a given context.
+ * Default: {@value #DEFAULT_UPDATE_EXPIRES_BY_CONTEXT_SQL}
+ */
+ @Nonnull @NotEmpty private String updateExpiresByContextSQL = DEFAULT_UPDATE_EXPIRES_BY_CONTEXT_SQL;
+
+ /**
+ * The SQL to to delete a given context. .
+ * Default: {@value #DEFAULT_DELETE_BY_CONTEXT_SQL}
+ */
+ @Nonnull @NotEmpty private String deleteByContextSQL = DEFAULT_DELETE_BY_CONTEXT_SQL;
+
+ /* Bean Setters*/
/** set {@link #transactionRetry}.
* @param count how many time to try before we bail.
*/
@@ -88,7 +229,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
* @param source what to set.
*/
public void setDataSource(@Nonnull final DataSource source) {
- dataSource = source;
+ dataSource = Constraint.isNotNull(source, "DataSource should be non null");
}
/** What errors do we retry?
@@ -98,7 +239,137 @@ public final class JDBCStorageService extends AbstractStorageService implements
retryableErrors = Constraint.isNotNull(errors, "errors must not be null");
Constraint.noNullItems(errors, "errors must not have null members");
}
+
+ /** SQL to read contexts.
+ * @param what the SQL to set.
+ */
+ public void setReadContextsSQL(@Nonnull @NotEmpty final String what) {
+ readContextsSQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "Read Context SQL should be non-null and non empty");
+ }
+ /** SQL to read all contexts.
+ * @param what the SQL to set.
+ */
+ public void setReadAllByContextSQL(@Nonnull @NotEmpty final String what) {
+ readAllByContextSQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "Read All By Context SQL should be non-null and non empty");
+ }
+
+ /** SQL to read all contexts.
+ * @param what the SQL to set.
+ */
+ public void setReadAllSQL(@Nonnull @NotEmpty final String what) {
+ readAllSQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "Read All SQL should be non-null and non empty");
+ }
+
+ /** Set the SQL to get check whether this record already exists and is unexpired prior to a create.
+ * This starts a transaction which will be completed after either the SQL in
+ * {@link #createCreateRecordSQL} or {@link #createUpdateRecordSQL}.
+ * @param what the SQL to set.
+ */
+ public void setPreCreateQuerySQL(@Nonnull @NotEmpty final String what) {
+ preCreateQuerySQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "PreCreateQuerySQL should be non-null and non empty");
+ }
+
+ /** Set the SQL to create a new record (transactional with {@link #preCreateQuerySQL}.
+ * @param what the SQl to set.
+ */
+ public void setCreateCreateRecordSQL(@Nonnull @NotEmpty final String what) {
+ createCreateRecordSQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "CreateCreateRecordSQL should be non-null and non empty");
+ }
+
+ /** Set the SQL to update an expired record as part of a create (transactional with {@link #preCreateQuerySQL}.
+ * @param what the SQL to set.
+ */
+ public void setCreateUpdateRecordSQL(@Nonnull @NotEmpty final String what) {
+ createUpdateRecordSQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "CreateUpdateRecordSQL should be non-null and non empty");
+ }
+
+ /** Set the SQL to read a single record.
+ * @param what what to set.
+ */
+ public void setReadRecordSQL(@Nonnull @NotEmpty final String what) {
+ readRecordSQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "ReadRecordSQL should be non-null and non empty");
+ }
+
+ /** Set the SQL to get check whether this record already exists and is unexpired prior to an update.
+ * @param what The preUpdateQuerySQL to set.
+ */
+ public void setPreUpdateQuerySQL(@Nonnull @NotEmpty final String what) {
+ preUpdateQuerySQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "PreUpdateQuerySQL should be non-null and non empty");
+ }
+
+ /** Set the SQL to update a record. Transactional with {@link #preUpdateQuerySQL}
+ * @param what The updateQuerySQL to set.
+ */
+ public void setUpdateRecordSQL(@Nonnull @NotEmpty final String what) {
+ updateRecordSQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "UpdateRecordSQL should be non-null and non empty");
+ }
+
+ /** Set the SQL to check whether a record exists prior to deleting it.
+ * @param what The SQL to set.
+ */
+ public void setPreDeleteQuerySQL(final String what) {
+ preDeleteQuerySQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "PreDeleteSQL should be non-null and non empty");
+ }
+
+ /** Set the SQL to delete a record. Transactional with {@link #preDeleteQuerySQL}.
+ * @param what The SQL to set.
+ */
+ public void setDeleteRecordSQL(final String what) {
+ deleteRecordSQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "DeleteRecordSQL should be non-null and non empty");
+ }
+
+ /** Set the SQL to delete expired record.
+ * Used as part of the {@link #getCleanupTask()}.
+ * @param what The SQL to set.
+ */
+ public void setDeleteByExpiredSQL(final String what) {
+ deleteByExpiredSQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "DeleteByExpiredSQL should be non-null and non empty");
+ }
+
+ /** Set the SQL to delete expired record with specified context.
+ * Used as part of {@link #reap(String)}.
+ * @param what The SQL to set.
+ */
+ public void setDeleteByContextExpiredSQL(final String what) {
+ deleteByContextExpiredSQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "DeleteByContextExpiredSQL should be non-null and non empty");
+ }
+
+ /** Set the SQL to update the expiration of a record specified by context.
+ * @param what The SQL to set.
+ */
+ public void setUpdateExpiresByContextSQL(final String what) {
+ updateExpiresByContextSQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "UpdateExpiresByContextSQL should be non-null and non empty");
+ }
+
+ /** Set the SQL to Delete a specified Context.
+ * @param what The SQL to set.
+ */
+ public void setDeleteByContextSQL(final String what) {
+ deleteByContextSQL = Constraint.isNotNull(StringSupport.trimOrNull(what),
+ "DeleteByContextSQL should be non-null and non empty");
+ }
+
+ /** {@inheritDoc} */
+ protected void doInitialize() throws ComponentInitializationException {
+ Constraint.isNotNull(dataSource, "data source must be specified and nonnul");
+ super.doInitialize();
+ }
+
/**
* Returns all contexts from the store (for testing only).
*
@@ -109,7 +380,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
final List<String> result = new ArrayList<>();
log.trace("Getting Context");
try (final Connection connection = getConnection(true)) {
- final PreparedStatement query = connection.prepareStatement("SELECT context FROM StorageRecords");
+ final PreparedStatement query = connection.prepareStatement(readContextsSQL);
final ResultSet results = query.executeQuery();
while (results.next()) {
final String context = results.getString(1);
@@ -131,10 +402,10 @@ public final class JDBCStorageService extends AbstractStorageService implements
* @throws IOException if errors occur in the read process
*/
@Nonnull @NonnullElements protected List<?> readAll() throws IOException {
- final List<MyStorageRecord<?>> result = new ArrayList<>();
+ final List<JDBCStorageRecord<?>> result = new ArrayList<>();
log.trace("Getting all Records");
try (final Connection connection = getConnection(true)) {
- final PreparedStatement query = connection.prepareStatement("SELECT context, id, expires, value, version FROM StorageRecords");
+ final PreparedStatement query = connection.prepareStatement(readAllSQL);
final ResultSet results = query.executeQuery();
while (results.next()) {
final String context = results.getString(1);
@@ -144,7 +415,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
final Long version = results.getLong(5);
log.trace("Record: Context = {}, Id = {}, value = {}, verion = {}, expires = {}",
context, id, value, version, expires == null ? "<never>": expires);
- result.add(new MyStorageRecord<>(value, expires, version));
+ result.add(new JDBCStorageRecord<>(value, expires, version));
}
return result;
@@ -164,10 +435,10 @@ public final class JDBCStorageService extends AbstractStorageService implements
*/
@Nonnull @NonnullElements protected List<?> readAll(@Nonnull @NotEmpty final String context)
throws IOException {
- final List<MyStorageRecord<?>> result = new ArrayList<>();
+ final List<JDBCStorageRecord<?>> result = new ArrayList<>();
log.trace("Getting all Records for context {}", context);
try (final Connection connection = getConnection(true)) {
- final PreparedStatement query = connection.prepareStatement("SELECT id, expires, value, version FROM StorageRecords WHERE context = ?");
+ final PreparedStatement query = connection.prepareStatement(readAllByContextSQL);
query.setString(1, context);
final ResultSet results = query.executeQuery();
while (results.next()) {
@@ -177,7 +448,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
final Long version = results.getLong(4);
log.trace("Record: Id = {}, value = {}, verion = {}, expires = {}",
id, value, version, expires == null ? "<never>": expires);
- result.add(new MyStorageRecord<>(value, expires, version));
+ result.add(new JDBCStorageRecord<>(value, expires, version));
}
return result;
@@ -187,8 +458,8 @@ public final class JDBCStorageService extends AbstractStorageService implements
}
}
-
/** {@inheritDoc} */
+ // Checkstyle: CyclomaticComplexity OFF
public boolean create(@Nonnull @NotEmpty final String context, @Nonnull @NotEmpty final String key,
@Nonnull @NotEmpty final String value, @Nullable @Positive final Long expiration) throws IOException {
//
@@ -202,13 +473,13 @@ public final class JDBCStorageService extends AbstractStorageService implements
// If so check expiration
// If not expired complain
// otherwise update
- final PreparedStatement query = connection.prepareStatement("SELECT expires FROM StorageRecords WHERE context =? AND id=?");
+ final PreparedStatement query = connection.prepareStatement(preCreateQuerySQL);
query.setString(1, context);
query.setString(2, key);
log.debug("Querying {}", query);
final ResultSet resultSet = query.executeQuery();
if (!resultSet.next()) {
- final PreparedStatement insert = connection.prepareStatement("INSERT INTO StorageRecords VALUES (?, ?, ?, ?, 1)");
+ final PreparedStatement insert = connection.prepareStatement(createCreateRecordSQL);
insert.setString(1, context);
insert.setString(2, key);
setExpires(insert, 3, expiration);
@@ -222,7 +493,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
log.debug("Duplicate record '{}' in context '{}'", key, context);
return false;
}
- final PreparedStatement update = connection.prepareStatement("UPDATE StorageRecords SET value=?, version=0, expires=? WHERE context=? AND id=?");
+ final PreparedStatement update = connection.prepareStatement(createCreateRecordSQL);
update.setString(1, value);
setExpires(update, 2, expiration);
update.setString(3,context);
@@ -230,8 +501,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
update.executeUpdate();
connection.commit();
return true;
- }
- catch (final SQLException e) {
+ } catch (final SQLException e) {
boolean retry = false;
for (final String msg : retryableErrors) {
if (e.getSQLState() != null && e.getSQLState().contains(msg)) {
@@ -253,6 +523,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
}
}
}
+ // Checkstyle: CyclomaticComplexity ON
/** {@inheritDoc} */
@Override @Nullable public <T> StorageRecord<T> read(@Nonnull @NotEmpty final String context,
@@ -278,6 +549,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
* @return pair of version and storage record
* @throws IOException if errors occur in the read process
*/
+ // Checkstyle: CyclomaticComplexity OFF
@Nonnull protected <T> Pair<Long, StorageRecord<T>> readImpl(@Nonnull @NotEmpty final String context,
@Nonnull @NotEmpty final String key, @Positive final Long version) throws IOException {
//
@@ -286,7 +558,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
int retries = transactionRetry;
while(true) {
try (final Connection connection = getConnection(true)) {
- final PreparedStatement stmnt = connection.prepareStatement("SELECT version, expires, value FROM StorageRecords WHERE context =? AND id=?");
+ final PreparedStatement stmnt = connection.prepareStatement(readRecordSQL);
stmnt.setString(1, context);
stmnt.setString(2, key);
log.debug("Querying {}", stmnt);
@@ -298,7 +570,8 @@ public final class JDBCStorageService extends AbstractStorageService implements
final Long returnedVersion = resultSet.getLong(1);
final Long returnedExpires = getExpires(resultSet, 2);
final String returnedValue = resultSet.getString(3);
- log.debug("Considering Version {}, Expires {}, Value {}", returnedVersion, returnedValue, returnedExpires);
+ log.debug("Considering Version {}, Expires {}, Value {}",
+ returnedVersion, returnedValue, returnedExpires);
if (returnedExpires != null && System.currentTimeMillis() >= returnedExpires) {
log.debug("Read failed, key '{}' expired in context '{}'", key, context);
return new Pair<>();
@@ -310,7 +583,8 @@ public final class JDBCStorageService extends AbstractStorageService implements
if (resultSet.next()) {
log.error("Multiple values returned?");
}
- final MutableStorageRecord<T> result = new MyStorageRecord<>(returnedValue, returnedExpires, returnedVersion);
+ final MutableStorageRecord<T> result =
+ new JDBCStorageRecord<>(returnedValue, returnedExpires, returnedVersion);
return new Pair<>(version, result);
} catch (final SQLException e) {
boolean retry = false;
@@ -334,6 +608,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
}
}
}
+ // Checkstyle: CyclomaticComplexity ON
/** {@inheritDoc} */
@Override public boolean update(@Nonnull @NotEmpty final String context, @Nonnull @NotEmpty final String key,
@@ -376,6 +651,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
* @throws IOException if errors occur in the update process
* @throws VersionMismatchException if the record found contains a version that does not match the parameter
*/
+ // Checkstyle: CyclomaticComplexity OFF
@Nullable protected Long updateImpl(@Nullable final Long version, @Nonnull @NotEmpty final String context,
@Nonnull @NotEmpty final String key, @Nonnull @NotEmpty final String value,
@Nullable @Positive final Long expires) throws IOException, VersionMismatchException {
@@ -386,7 +662,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
int retries = transactionRetry;
while (true) {
try (Connection connection = getConnection(false)) {
- final PreparedStatement selectStmnt = connection.prepareStatement("SELECT version, expires FROM StorageRecords WHERE context =? AND id=?");
+ final PreparedStatement selectStmnt = connection.prepareStatement(preUpdateQuerySQL);
selectStmnt.setString(1, context);
selectStmnt.setString(2, key);
log.debug("Querying {}", selectStmnt);
@@ -407,7 +683,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
// Caller is out of sync.
throw new VersionMismatchException();
}
- final PreparedStatement updateStmnt = connection.prepareStatement("UPDATE StorageRecords SET value=?, version=?, expires=? WHERE context=? AND id=?");
+ final PreparedStatement updateStmnt = connection.prepareStatement(updateRecordSQL);
updateStmnt.setString(1, value);
final Long newVersion = Long.valueOf(returnedVersion + 1);
updateStmnt.setLong(2, newVersion);
@@ -439,6 +715,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
}
}
}
+ // Checkstyle: CyclomaticComplexity ON
/** {@inheritDoc} */
@Override public boolean deleteWithVersion(@Positive final long version, @Nonnull @NotEmpty final String context,
@@ -467,6 +744,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
* @throws IOException if errors occur in the delete process
* @throws VersionMismatchException if the record found contains a version that does not match the parameter
*/
+ // Checkstyle: CyclomaticComplexity OFF
protected boolean deleteImpl(@Nullable @Positive final Long version, @Nonnull @NotEmpty final String context,
@Nonnull @NotEmpty final String key) throws IOException, VersionMismatchException {
//
@@ -475,11 +753,10 @@ public final class JDBCStorageService extends AbstractStorageService implements
int retries = transactionRetry;
while (true) {
try (Connection connection = getConnection(false)) {
- final PreparedStatement selectStmnt = connection.prepareStatement("SELECT version FROM StorageRecords WHERE context =? AND id=?");
+ final PreparedStatement selectStmnt = connection.prepareStatement(preDeleteQuerySQL);
selectStmnt.setString(1, context);
selectStmnt.setString(2, key);
log.debug("Querying {}", selectStmnt);
- final String s = selectStmnt.toString();
final ResultSet resultSet = selectStmnt.executeQuery();
if (!resultSet.next()) {
log.debug("Nothing returned");
@@ -489,7 +766,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
if (version != null && returnedVersion != version) {
throw new VersionMismatchException();
}
- final PreparedStatement deleteStmnt = connection.prepareStatement("DELETE FROM StorageRecords WHERE context=? AND id=?");
+ final PreparedStatement deleteStmnt = connection.prepareStatement(deleteRecordSQL);
deleteStmnt.setString(1, context);
deleteStmnt.setString(2, key);
deleteStmnt.execute();
@@ -517,6 +794,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
}
}
}
+ // Checkstyle: CyclomaticComplexity ON
/**
* Deletes every record with an expiration before the supplied expiration.
@@ -532,7 +810,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
int retries = transactionRetry;
while (true) {
try (Connection connection = getConnection(false)) {
- final PreparedStatement updateStmnt = connection.prepareStatement("DELETE FROM StorageRecords WHERE expires < ? ");
+ final PreparedStatement updateStmnt = connection.prepareStatement(deleteByExpiredSQL);
updateStmnt.setLong(1, expiration);
updateStmnt.execute();
connection.commit();
@@ -562,14 +840,14 @@ public final class JDBCStorageService extends AbstractStorageService implements
}
/** {@inheritDoc} */
- public void reap(String context) throws IOException {
+ public void reap(final String context) throws IOException {
//
// Constraints, Logging
//
int retries = transactionRetry;
while (true) {
try (Connection connection = getConnection(true)) {
- final PreparedStatement updateStmnt = connection.prepareStatement("DELETE FROM StorageRecords WHERE context = ? AND expires <= ?");
+ final PreparedStatement updateStmnt = connection.prepareStatement(deleteByContextExpiredSQL);
updateStmnt.setString(1, context);
setExpires(updateStmnt, 2, System.currentTimeMillis());
updateStmnt.execute();
@@ -606,7 +884,7 @@ public final class JDBCStorageService extends AbstractStorageService implements
int retries = transactionRetry;
while (true) {
try (Connection connection = getConnection(true)) {
- final PreparedStatement updateStmnt = connection.prepareStatement("UPDATE StorageRecords SET expires = ? WHERE context = ? AND expires > ? ");
+ final PreparedStatement updateStmnt = connection.prepareStatement(updateExpiresByContextSQL);
setExpires(updateStmnt, 1, expires);
updateStmnt.setString(2, context);
setExpires(updateStmnt, 3, System.currentTimeMillis());
@@ -644,13 +922,12 @@ public final class JDBCStorageService extends AbstractStorageService implements
int retries = transactionRetry;
while (true) {
try (Connection connection = getConnection(true)) {
- final PreparedStatement updateStmnt = connection.prepareStatement("DELETE FROM StorageRecords WHERE context = ? ");
+ final PreparedStatement updateStmnt = connection.prepareStatement(deleteByContextSQL);
updateStmnt.setString(1, context);
updateStmnt.execute();
connection.commit();
return;
- }
- catch (final SQLException e) {
+ } catch (final SQLException e) {
boolean retry = false;
for (final String msg : retryableErrors) {
if (e.getSQLState() != null && e.getSQLState().contains(msg)) {
@@ -721,7 +998,6 @@ public final class JDBCStorageService extends AbstractStorageService implements
}
}
-
/** {@inheritDoc} */
public boolean isServerSide() {
return true;
@@ -749,24 +1025,4 @@ public final class JDBCStorageService extends AbstractStorageService implements
}
};
}
-
-
- private static class MyStorageRecord<T> extends MutableStorageRecord<T> {
-
- /**
- * Constructor.
- *
- * @param val
- * @param exp
- */
- public MyStorageRecord(String val, Long exp, Long version) {
- super(val, exp);
- if (version != null) {
- setVersion(version);
- }
- }
-
- }
-
-
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list