[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