[java-opensaml] branch main updated: IDP-2069 - Null Handling Task

Scott Cantor cantor.2 at osu.edu
Thu Mar 9 20:17:59 UTC 2023


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository java-opensaml.

View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=1710ced8f2c594decf92155d8bd8c0bd3f73c778

The following commit(s) were added to refs/heads/main by this push:
     new 1710ced8f IDP-2069 - Null Handling Task
1710ced8f is described below

commit 1710ced8f2c594decf92155d8bd8c0bd3f73c778
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Mar 9 15:17:56 2023 -0500

    IDP-2069 - Null Handling Task
    
    https://shibboleth.atlassian.net/browse/IDP-2069
    
    Clean opensaml-storage-impl.
---
 .../storage/impl/MemoryStorageService.java         |   2 +-
 .../storage/impl/StorageServiceReplayCache.java    |  11 +-
 .../impl/StorageServiceRevocationCache.java        |   4 +-
 .../client/AbstractClientStorageServiceStore.java  |   9 +-
 .../storage/impl/client/ClientStorageService.java  |   6 +-
 .../impl/client/ClientStorageServiceStore.java     |   2 +-
 .../impl/client/JSONClientStorageServiceStore.java |  15 ++-
 .../impl/client/LoadClientStorageServices.java     |  58 ++++-----
 .../impl/client/LogLocalStorageSaveResults.java    |  15 +--
 .../client/PopulateClientStorageLoadContext.java   |  10 +-
 .../client/PopulateClientStorageSaveContext.java   |  10 +-
 .../SaveCookieBackedClientStorageServices.java     |  17 ++-
 .../impl/client/XMLClientStorageServiceStore.java  |  18 ++-
 .../impl/memcached/MemcachedStorageService.java    | 130 +++++++++++----------
 .../impl/memcached/StorageRecordTranscoder.java    |  12 +-
 .../storage/impl/MemoryStorageServiceTest.java     |   5 +
 .../impl/StorageServiceReplayCacheTest.java        |   6 -
 .../impl/StorageServiceRevocationCacheTest.java    |   7 +-
 .../AbstractBaseClientStorageServiceTest.java      |   7 +-
 .../impl/client/LoadClientStorageServicesTest.java |  42 ++++---
 .../PopulateClientStorageLoadContextTest.java      |  10 +-
 .../PopulateClientStorageSaveContextTest.java      |  11 +-
 .../SaveCookieBackedClientStorageServicesTest.java |  19 +--
 .../impl/memcached/MemcachedStorageRecordTest.java |   7 +-
 .../memcached/MemcachedStorageServiceTest.java     |   4 +-
 25 files changed, 244 insertions(+), 193 deletions(-)

diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/MemoryStorageService.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/MemoryStorageService.java
index c203f10f7..d3be446b4 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/MemoryStorageService.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/MemoryStorageService.java
@@ -33,12 +33,12 @@ import net.shibboleth.shared.annotation.constraint.Live;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 import org.opensaml.storage.AbstractMapBackedStorageService;
 import org.opensaml.storage.MutableStorageRecord;
 import org.opensaml.storage.StorageCapabilities;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Implementation of {@link AbstractMapBackedStorageService} that stores data in-memory in a shared data structure 
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/StorageServiceReplayCache.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/StorageServiceReplayCache.java
index 999cd50ab..023fa34d1 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/StorageServiceReplayCache.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/StorageServiceReplayCache.java
@@ -28,7 +28,6 @@ import org.opensaml.storage.StorageCapabilities;
 import org.opensaml.storage.StorageRecord;
 import org.opensaml.storage.StorageService;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
@@ -38,6 +37,7 @@ import net.shibboleth.shared.codec.StringDigester.OutputFormat;
 import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * {@link ReplayCache} implementation backed by a {@link StorageService}.
@@ -130,6 +130,10 @@ public class StorageServiceReplayCache extends AbstractIdentifiableInitializable
             return false;
         } else if (s.length() > caps.getKeySize()) {
             key = digester.apply(s);
+            if (key == null) {
+                log.error("Result of digesting key was null");
+                return false;
+            }
         } else {
             key = s;
         }
@@ -141,9 +145,10 @@ public class StorageServiceReplayCache extends AbstractIdentifiableInitializable
                 storage.create(context, key, "x", expires.toEpochMilli());
                 return true;
             }
-            
+
+            final Long existingExp = entry.getExpiration();
             log.debug("Replay of value '{}' detected in cache, expires at {}", s,
-                    Instant.ofEpochMilli(entry.getExpiration()));
+                    Instant.ofEpochMilli(existingExp != null ? existingExp : 0));
             return false;
             
         } catch (final IOException e) {
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/StorageServiceRevocationCache.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/StorageServiceRevocationCache.java
index e036bc0d9..438aed178 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/StorageServiceRevocationCache.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/StorageServiceRevocationCache.java
@@ -30,7 +30,6 @@ import org.opensaml.storage.StorageCapabilities;
 import org.opensaml.storage.StorageRecord;
 import org.opensaml.storage.StorageService;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
@@ -39,6 +38,7 @@ import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
 import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * Stores and checks for revocation entries via a {@link StorageService}.
@@ -78,7 +78,7 @@ public class StorageServiceRevocationCache extends AbstractIdentifiableInitializ
      * 
      * @param entryExpiration lifetime of an revocation entry in milliseconds
      */
-    public void setEntryExpiration(@Positive final Duration entryExpiration) {
+    public void setEntryExpiration(@Positive @Nonnull final Duration entryExpiration) {
         checkSetterPreconditions();
         
         Constraint.isTrue(entryExpiration != null && !entryExpiration.isNegative() && !entryExpiration.isZero(),
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/AbstractClientStorageServiceStore.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/AbstractClientStorageServiceStore.java
index 2c2e596a1..1b34fe4bb 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/AbstractClientStorageServiceStore.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/AbstractClientStorageServiceStore.java
@@ -26,8 +26,6 @@ import javax.annotation.Nullable;
 
 import org.opensaml.storage.MutableStorageRecord;
 import org.opensaml.storage.impl.client.ClientStorageService.ClientStorageSource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.Live;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
@@ -41,14 +39,11 @@ import net.shibboleth.shared.logic.Constraint;
  */
 public abstract class AbstractClientStorageServiceStore implements ClientStorageServiceStore {
 
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractClientStorageServiceStore.class);
-
     /** The underlying map of data records. */
     @Nonnull @NonnullElements private final Map<String, Map<String, MutableStorageRecord<?>>> contextMap;
     
     /** Data source. */
-    @Nonnull private ClientStorageSource source;
+    @Nullable private ClientStorageSource source;
     
     /** Dirty bit. */
     private boolean dirty;
@@ -61,7 +56,7 @@ public abstract class AbstractClientStorageServiceStore implements ClientStorage
     }
 
     /** {@inheritDoc} */
-    @Nonnull public ClientStorageSource getSource() {
+    @Nullable public ClientStorageSource getSource() {
         return source;
     }
 
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/ClientStorageService.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/ClientStorageService.java
index eb434fde3..df9f9c219 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/ClientStorageService.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/ClientStorageService.java
@@ -36,7 +36,6 @@ import org.opensaml.storage.StorageCapabilities;
 import org.opensaml.storage.impl.client.ClientStorageServiceStore.Factory;
 import org.opensaml.storage.impl.client.JSONClientStorageServiceStore.JSONClientStorageServiceStoreFactory;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import jakarta.servlet.Filter;
 import jakarta.servlet.FilterChain;
@@ -54,6 +53,7 @@ import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.logic.ConstraintViolationException;
 import net.shibboleth.shared.net.CookieManager;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.NonnullSupplier;
 import net.shibboleth.shared.primitive.StringSupport;
 import net.shibboleth.shared.security.DataExpiredException;
@@ -382,7 +382,7 @@ public class ClientStorageService extends AbstractMapBackedStorageService implem
      * 
      * @throws IOException to signal an error
      */
-    @Nonnull ClientStorageSource getSource() throws IOException {
+    @Nullable ClientStorageSource getSource() throws IOException {
        final Lock lock = getLock().readLock();
        try {
            lock.lock();
@@ -451,7 +451,7 @@ public class ClientStorageService extends AbstractMapBackedStorageService implem
                 
                 if (keyStrategy != null) {
                     try {
-                        if (!keyStrategy.getDefaultKey().getFirst().equals(keyAliasUsed.toString())) {
+                        if (!keyStrategy.getDefaultKeyRecord().name().equals(keyAliasUsed.toString())) {
                             storageObject.setDirty(true);
                         }
                     } catch (final KeyException e) {
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/ClientStorageServiceStore.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/ClientStorageServiceStore.java
index 37a33e5ec..6ad0b978f 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/ClientStorageServiceStore.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/ClientStorageServiceStore.java
@@ -42,7 +42,7 @@ public interface ClientStorageServiceStore {
      * 
      * @return data source
      */
-    @Nonnull ClientStorageSource getSource();
+    @Nullable ClientStorageSource getSource();
 
     /**
      * Get the dirty bit for the current data.
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/JSONClientStorageServiceStore.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/JSONClientStorageServiceStore.java
index a5d75581e..3fde289a7 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/JSONClientStorageServiceStore.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/JSONClientStorageServiceStore.java
@@ -38,9 +38,9 @@ import javax.json.stream.JsonGenerator;
 import org.opensaml.storage.MutableStorageRecord;
 import org.opensaml.storage.impl.client.ClientStorageService.ClientStorageSource;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.security.DataSealerException;
 
 /**
@@ -102,10 +102,15 @@ public class JSONClientStorageServiceStore extends AbstractClientStorageServiceS
             return null;
         }
         
+        final ClientStorageSource source = getSource();
+        if (source == null) {
+            throw new IOException("Client storage medium not set");
+        }
+        
         if (getContextMap().isEmpty()) {
             log.trace("{} Data is empty", storageService.getLogPrefix());
             return new ClientStorageServiceOperation(storageService.getId(), storageService.getStorageName(), null,
-                    getSource());
+                    source);
         }
 
         long exp = 0L;
@@ -129,7 +134,7 @@ public class JSONClientStorageServiceStore extends AbstractClientStorageServiceS
                             gen.writeStartObject(entry.getKey())
                                 .write("v", record.getValue());
                             if (recexp != null) {
-                                gen.write("x", record.getExpiration());
+                                gen.write("x", recexp);
                                 exp = Math.max(exp, recexp);
                             }
                             gen.writeEnd();
@@ -143,7 +148,7 @@ public class JSONClientStorageServiceStore extends AbstractClientStorageServiceS
             if (empty) {
                 log.trace("{} Data is empty", storageService.getLogPrefix());
                 return new ClientStorageServiceOperation(storageService.getId(), storageService.getStorageName(), null,
-                        getSource());
+                        source);
             }
             
             final String raw = sink.toString();
@@ -156,7 +161,7 @@ public class JSONClientStorageServiceStore extends AbstractClientStorageServiceS
                 log.trace("{} Size of data after encryption is {}", storageService.getLogPrefix(), wrapped.length());
                 setDirty(false);
                 return new ClientStorageServiceOperation(storageService.getId(), storageService.getStorageName(),
-                        wrapped, getSource());
+                        wrapped, source);
             } catch (final DataSealerException e) {
                 throw new IOException(e);
             }
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/LoadClientStorageServices.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/LoadClientStorageServices.java
index 10d4a94fd..4cb03cdc6 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/LoadClientStorageServices.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/LoadClientStorageServices.java
@@ -19,9 +19,7 @@ package org.opensaml.storage.impl.client;
 
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
@@ -34,7 +32,6 @@ import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.storage.impl.client.ClientStorageService.ClientStorageSource;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Strings;
 
@@ -42,8 +39,10 @@ import jakarta.servlet.http.Cookie;
 import jakarta.servlet.http.HttpServletRequest;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.net.URISupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * An action that loads any number of {@link ClientStorageService} instances from a POST submission
@@ -81,7 +80,7 @@ public class LoadClientStorageServices extends AbstractProfileAction {
     /** Constructor. */
     public LoadClientStorageServices() {
         useLocalStorage = false;
-        storageServices = Collections.emptyMap();
+        storageServices = CollectionSupport.emptyMap();
     }
 
     /**
@@ -105,8 +104,10 @@ public class LoadClientStorageServices extends AbstractProfileAction {
         
         Constraint.isNotNull(services, "StorageService collection cannot be null");
         storageServices = new HashMap<>(services.size());
-        for (final ClientStorageService ss : List.copyOf(services)) {
-            storageServices.put(ss.getStorageName(), ss);
+        for (final ClientStorageService ss : services) {
+            if (ss != null) {
+                storageServices.put(ss.getStorageName(), ss);
+            }
         }
     }
     
@@ -129,27 +130,30 @@ public class LoadClientStorageServices extends AbstractProfileAction {
             return false;
         }
         
-        if (getHttpServletRequest() == null) {
-            log.error("{} HttpServletRequest not available", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
-            return false;
-        }
-        
         return true;
     }
 
     /** {@inheritDoc} */
     @Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+        final HttpServletRequest httpRequest = getHttpServletRequest(); 
+        if (httpRequest == null) {
+            log.error("{} HttpServletRequest not available", getLogPrefix());
+            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+            return;
+        }
         
+
         boolean useLS = useLocalStorage;
         if (useLS) {
-            final String param = getHttpServletRequest().getParameter(SUPPORT_FORM_FIELD);
+            final String param = httpRequest.getParameter(SUPPORT_FORM_FIELD);
             if (param == null || !Boolean.valueOf(param)) {
                 log.debug("{} Local storage not available, backing off to cookies", getLogPrefix());
                 useLS = false;
             }
         }
         
+        assert clientStorageLoadCtx != null;
         for (final String storageKey : clientStorageLoadCtx.getStorageKeys()) {
             
             final ClientStorageService storageService = storageServices.get(storageKey);
@@ -160,28 +164,30 @@ public class LoadClientStorageServices extends AbstractProfileAction {
             }
             
             if (useLS) {
-                loadFromLocalStorage(storageService);
+                loadFromLocalStorage(httpRequest, storageService);
             } else {
-                loadFromCookie(storageService, ClientStorageSource.COOKIE);
+                loadFromCookie(httpRequest, storageService, ClientStorageSource.COOKIE);
             }
         }
         
+        assert clientStorageLoadCtx != null;
         profileRequestContext.removeSubcontext(clientStorageLoadCtx);
     }
 
     /**
      * Load the specified storage service from a cookie.
      * 
+     * @param httpRequest servlet request
      * @param storageService service to load
      * @param source source to apply to load operation
      */
-    private void loadFromCookie(@Nonnull final ClientStorageService storageService,
-            @Nonnull final ClientStorageSource source) {
+    private void loadFromCookie(@Nonnull final HttpServletRequest httpRequest,
+            @Nonnull final ClientStorageService storageService, @Nonnull final ClientStorageSource source) {
         
         Optional<Cookie> cookie = Optional.empty();
         
         // Search for our cookie.
-        final Cookie[] cookies = getHttpServletRequest().getCookies();
+        final Cookie[] cookies = httpRequest.getCookies();
         if (cookies != null) {
             cookie = Arrays.asList(cookies).stream().filter(
                     c -> c != null && c.getName().equals(storageService.getStorageName())
@@ -201,26 +207,26 @@ public class LoadClientStorageServices extends AbstractProfileAction {
     /**
      * Load the specified storage service from local storage data supplied in the POST.
      * 
+     * @param httpRequest servlet request
      * @param storageService service to load
      */
-    private void loadFromLocalStorage(@Nonnull final ClientStorageService storageService) {
-        
-        final HttpServletRequest request = getHttpServletRequest();
+    private void loadFromLocalStorage(@Nonnull final HttpServletRequest httpRequest,
+            @Nonnull final ClientStorageService storageService) {
         
-        String param = request.getParameter(SUCCESS_FORM_FIELD + '.' + storageService.getStorageName());
+        String param = httpRequest.getParameter(SUCCESS_FORM_FIELD + '.' + storageService.getStorageName());
         if (param == null || !Boolean.valueOf(param)) {
-            param = request.getParameter(EXCEPTION_FORM_FIELD + '.' + storageService.getStorageName());
+            param = httpRequest.getParameter(EXCEPTION_FORM_FIELD + '.' + storageService.getStorageName());
             log.debug("{} Load from local storage failed ({}), initializing StorageService '{}' to empty state",
                     getLogPrefix(), param, storageService.getId());
             storageService.load(null, ClientStorageSource.HTML_LOCAL_STORAGE);
             return;
         }
         
-        param = request.getParameter(VALUE_FORM_FIELD + '.' + storageService.getStorageName());
+        param = httpRequest.getParameter(VALUE_FORM_FIELD + '.' + storageService.getStorageName());
         if (param == null || param.isEmpty()) {
             log.debug("{} No local storage data present, checking for a cookie set by older storage implementation",
                     getLogPrefix(), storageService.getId());
-            loadFromCookie(storageService, ClientStorageSource.HTML_LOCAL_STORAGE);
+            loadFromCookie(httpRequest, storageService, ClientStorageSource.HTML_LOCAL_STORAGE);
         } else {
             log.debug("{} Initializing StorageService '{}' from local storage data", getLogPrefix(),
                     storageService.getId());
@@ -228,4 +234,4 @@ public class LoadClientStorageServices extends AbstractProfileAction {
         }
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/LogLocalStorageSaveResults.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/LogLocalStorageSaveResults.java
index b18b41148..2cf742e6e 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/LogLocalStorageSaveResults.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/LogLocalStorageSaveResults.java
@@ -24,10 +24,10 @@ import org.opensaml.profile.action.AbstractProfileAction;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.storage.impl.client.ClientStorageService.ClientStorageSource;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import jakarta.servlet.http.HttpServletRequest;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * An action that logs the results of Local Storage-based {@link ClientStorageService} save operations.
@@ -60,11 +60,6 @@ public class LogLocalStorageSaveResults extends AbstractProfileAction {
             return false;
         }
         
-        if (getHttpServletRequest() == null) {
-            log.error("{} HttpServletRequest not available", getLogPrefix());
-            return false;
-        }
-        
         return true;
     }
 
@@ -72,7 +67,13 @@ public class LogLocalStorageSaveResults extends AbstractProfileAction {
     @Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
         
         final HttpServletRequest request = getHttpServletRequest();
+        if (request == null) {
+            log.error("{} HttpServletRequest not available", getLogPrefix());
+            return;
+        }
+        
 
+        assert clientStorageSaveCtx != null;
         for (final ClientStorageServiceOperation operation : clientStorageSaveCtx.getStorageOperations()) {
             if (operation.getStorageSource() == ClientStorageSource.HTML_LOCAL_STORAGE) {
                 String param = request.getParameter(
@@ -89,4 +90,4 @@ public class LogLocalStorageSaveResults extends AbstractProfileAction {
         }
     }
     
-}
+}
\ No newline at end of file
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/PopulateClientStorageLoadContext.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/PopulateClientStorageLoadContext.java
index aedae64f0..5c7e28ac5 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/PopulateClientStorageLoadContext.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/PopulateClientStorageLoadContext.java
@@ -20,8 +20,6 @@ package org.opensaml.storage.impl.client;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
 
 import javax.annotation.Nonnull;
 
@@ -29,11 +27,12 @@ import org.opensaml.profile.action.AbstractProfileAction;
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * An action that creates and populates a {@link ClientStorageLoadContext} with any storage keys identified
@@ -58,7 +57,7 @@ public class PopulateClientStorageLoadContext extends AbstractProfileAction {
     
     /** Constructor. */
     public PopulateClientStorageLoadContext() {
-        storageServices = Collections.emptyList();
+        storageServices = CollectionSupport.emptyList();
     }
     
     /**
@@ -69,7 +68,8 @@ public class PopulateClientStorageLoadContext extends AbstractProfileAction {
     public void setStorageServices(@Nonnull @NonnullElements final Collection<ClientStorageService> services) {
         checkSetterPreconditions();
         
-        storageServices = List.copyOf(Constraint.isNotNull(services, "StorageService collection cannot be null"));
+        storageServices = CollectionSupport.copyToList(
+                Constraint.isNotNull(services, "StorageService collection cannot be null"));
     }
     
     /** {@inheritDoc} */
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/PopulateClientStorageSaveContext.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/PopulateClientStorageSaveContext.java
index a031c8db4..d1a4088e0 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/PopulateClientStorageSaveContext.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/PopulateClientStorageSaveContext.java
@@ -18,8 +18,6 @@
 package org.opensaml.storage.impl.client;
 
 import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
 import java.util.stream.Collectors;
 
 import javax.annotation.Nonnull;
@@ -28,11 +26,12 @@ import org.opensaml.profile.action.AbstractProfileAction;
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * An action that creates and populates a {@link ClientStorageSaveContext} with any storage operations
@@ -57,7 +56,7 @@ public class PopulateClientStorageSaveContext extends AbstractProfileAction {
     
     /** Constructor. */
     public PopulateClientStorageSaveContext() {
-        storageServices = Collections.emptyList();
+        storageServices = CollectionSupport.emptyList();
     }
     
     /**
@@ -68,7 +67,8 @@ public class PopulateClientStorageSaveContext extends AbstractProfileAction {
     public void setStorageServices(@Nonnull @NonnullElements final Collection<ClientStorageService> services) {
         checkSetterPreconditions();
         
-        storageServices = List.copyOf(Constraint.isNotNull(services, "StorageService collection cannot be null"));
+        storageServices = CollectionSupport.copyToList(
+                Constraint.isNotNull(services, "StorageService collection cannot be null"));
     }
     
     /** {@inheritDoc} */
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/SaveCookieBackedClientStorageServices.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/SaveCookieBackedClientStorageServices.java
index ea68e0e0c..d7154830f 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/SaveCookieBackedClientStorageServices.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/SaveCookieBackedClientStorageServices.java
@@ -18,9 +18,7 @@
 package org.opensaml.storage.impl.client;
 
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 import javax.annotation.Nonnull;
@@ -32,13 +30,14 @@ import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.storage.impl.client.ClientStorageService.ClientStorageSource;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.escape.Escaper;
 import com.google.common.net.UrlEscapers;
 
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * An action that performs any number of {@link ClientStorageServiceOperation} instances sourced from
@@ -67,7 +66,7 @@ public class SaveCookieBackedClientStorageServices
     
     /** Constructor. */
     public SaveCookieBackedClientStorageServices() {
-        storageServices = Collections.emptyMap();
+        storageServices = CollectionSupport.emptyMap();
         escaper = UrlEscapers.urlFormParameterEscaper();
     }
     
@@ -81,8 +80,10 @@ public class SaveCookieBackedClientStorageServices
         
         Constraint.isNotNull(services, "StorageService collection cannot be null");
         storageServices = new HashMap<>(services.size());
-        for (final ClientStorageService ss : List.copyOf(services)) {
-            storageServices.put(ss.getId(), ss);
+        for (final ClientStorageService ss : services) {
+            if (ss != null) {
+                storageServices.put(ss.getId(), ss);
+            }
         }
     }
     
@@ -105,8 +106,10 @@ public class SaveCookieBackedClientStorageServices
             return false;
         }
         
+        assert clientStorageSaveCtx != null;
         if (!clientStorageSaveCtx.isSourceRequired(ClientStorageSource.COOKIE)) {
             log.debug("{} No cookie operations required", getLogPrefix());
+            assert clientStorageSaveCtx != null;
             profileRequestContext.removeSubcontext(clientStorageSaveCtx);
             return false;
         }
@@ -117,6 +120,7 @@ public class SaveCookieBackedClientStorageServices
     /** {@inheritDoc} */
     @Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
         
+        assert clientStorageSaveCtx != null;
         for (final ClientStorageServiceOperation operation : clientStorageSaveCtx.getStorageOperations()) {
             
             final ClientStorageService storageService = storageServices.get(operation.getStorageServiceID());
@@ -137,6 +141,7 @@ public class SaveCookieBackedClientStorageServices
             }
         }
         
+        assert clientStorageSaveCtx != null;
         profileRequestContext.removeSubcontext(clientStorageSaveCtx);
     }
 
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/XMLClientStorageServiceStore.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/XMLClientStorageServiceStore.java
index 73a530c99..ac6f78412 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/XMLClientStorageServiceStore.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/client/XMLClientStorageServiceStore.java
@@ -30,7 +30,7 @@ import javax.annotation.Nullable;
 import org.opensaml.storage.MutableStorageRecord;
 import org.opensaml.storage.impl.client.ClientStorageService.ClientStorageSource;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -40,6 +40,7 @@ import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.AbstractInitializableComponent;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.security.DataSealerException;
 import net.shibboleth.shared.xml.ElementSupport;
 import net.shibboleth.shared.xml.ParserPool;
@@ -125,10 +126,15 @@ public class XMLClientStorageServiceStore extends AbstractClientStorageServiceSt
             return null;
         }
         
+        final ClientStorageSource source = getSource();
+        if (source == null) {
+            throw new IOException("Client storage medium not set");
+        }
+        
         if (getContextMap().isEmpty()) {
             log.trace("{} Data is empty", storageService.getLogPrefix());
             return new ClientStorageServiceOperation(storageService.getId(), storageService.getStorageName(), null,
-                    getSource());
+                    source);
         }
 
         long exp = 0L;
@@ -139,8 +145,7 @@ public class XMLClientStorageServiceStore extends AbstractClientStorageServiceSt
             final Document doc = parserPool.newDocument();
             final Element rootElement = doc.createElement("map");
             
-            for (final Map.Entry<String,Map<String, MutableStorageRecord<?>>> context
-                    : getContextMap().entrySet()) {
+            for (final Map.Entry<String,Map<String,MutableStorageRecord<?>>> context : getContextMap().entrySet()) {
                 if (!context.getValue().isEmpty()) {
                     final Element contextElement = doc.createElement("c");
                     contextElement.setAttribute("id", context.getKey());
@@ -169,9 +174,10 @@ public class XMLClientStorageServiceStore extends AbstractClientStorageServiceSt
             if (empty) {
                 log.trace("{} Data is empty", storageService.getLogPrefix());
                 return new ClientStorageServiceOperation(storageService.getId(), storageService.getStorageName(), null,
-                        getSource());
+                        source);
             }
             
+            assert rootElement != null;
             final String raw = SerializeSupport.nodeToString(rootElement);
             
             log.trace("{} Size of data before encryption is {}", storageService.getLogPrefix(), raw.length());
@@ -182,7 +188,7 @@ public class XMLClientStorageServiceStore extends AbstractClientStorageServiceSt
                 log.trace("{} Size of data after encryption is {}", storageService.getLogPrefix(), wrapped.length());
                 setDirty(false);
                 return new ClientStorageServiceOperation(storageService.getId(), storageService.getStorageName(),
-                        wrapped, getSource());
+                        wrapped, source);
             } catch (final DataSealerException e) {
                 throw new IOException(e);
             }
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/memcached/MemcachedStorageService.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/memcached/MemcachedStorageService.java
index 20e2df550..de70578be 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/memcached/MemcachedStorageService.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/memcached/MemcachedStorageService.java
@@ -22,6 +22,7 @@ import net.shibboleth.shared.annotation.constraint.Positive;
 import net.shibboleth.shared.collection.Pair;
 import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 import net.spy.memcached.CASResponse;
 import net.spy.memcached.CASValue;
@@ -38,7 +39,6 @@ import org.opensaml.storage.StorageService;
 import org.opensaml.storage.VersionMismatchException;
 import org.opensaml.storage.annotation.AnnotationSupport;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -164,9 +164,7 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
-    @Nonnull
-    public StorageCapabilities getCapabilities() {
+    @Nonnull public StorageCapabilities getCapabilities() {
         return storageCapabilities;
     }
 
@@ -182,7 +180,6 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
     public boolean create(@Nonnull @NotEmpty final String context,
                           @Nonnull @NotEmpty final String key,
                           @Nonnull @NotEmpty final String value,
@@ -216,7 +213,6 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
     public <T> boolean create(@Nonnull @NotEmpty final String context,
                           @Nonnull @NotEmpty final String key,
                           @Nonnull final T value,
@@ -227,18 +223,20 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
     public boolean create(@Nonnull final Object value) throws IOException {
         Constraint.isNotNull(value, "Value cannot be null");
-        return create(
-                AnnotationSupport.getContext(value),
-                AnnotationSupport.getKey(value),
-                AnnotationSupport.getValue(value),
-                AnnotationSupport.getExpiration(value));
+
+        final String context = AnnotationSupport.getContext(value);
+        final String key = AnnotationSupport.getKey(value);
+        final String val = AnnotationSupport.getValue(value);
+        if (context == null || key == null || val == null) {
+            throw new IOException("Context, key, and value must be non-null");
+        }
+
+        return create(context, key, val, AnnotationSupport.getExpiration(value));
     }
 
     /** {@inheritDoc} */
-    @Override
     public <T> StorageRecord<T> read(@Nonnull @NotEmpty final String context,
                               @Nonnull @NotEmpty final String key) throws IOException {
         Constraint.isNotNull(StringSupport.trimOrNull(context), "Context cannot be null or empty");
@@ -264,15 +262,19 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
     public Object read(@Nonnull final Object value) throws IOException {
         Constraint.isNotNull(value, "Value cannot be null");
-        return read(AnnotationSupport.getContext(value), AnnotationSupport.getKey(value));
+
+        final String context = AnnotationSupport.getContext(value);
+        final String key = AnnotationSupport.getKey(value);
+        if (context == null || key == null) {
+            throw new IOException("Context and key must be non-null");
+        }
+        return read(context, key);
     }
 
     /** {@inheritDoc} */
-    @Override
-    public <T> Pair<Long, StorageRecord<T>> read(@Nonnull @NotEmpty final String context,
+    @Nonnull public <T> Pair<Long, StorageRecord<T>> read(@Nonnull @NotEmpty final String context,
                                            @Nonnull @NotEmpty final String key,
                                            @Positive final long version) throws IOException {
         Constraint.isGreaterThan(0, version, "Version must be positive");
@@ -289,7 +291,6 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
     public boolean update(@Nonnull @NotEmpty final String context,
                           @Nonnull @NotEmpty final String key,
                           @Nonnull @NotEmpty final String value,
@@ -311,7 +312,6 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
     public <T> boolean update(@Nonnull @NotEmpty final String context,
                           @Nonnull @NotEmpty final String key,
                           @Nonnull final T value,
@@ -322,18 +322,20 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
     public boolean update(@Nonnull final Object value) throws IOException {
         Constraint.isNotNull(value, "Value cannot be null");
-        return update(
-                AnnotationSupport.getContext(value),
-                AnnotationSupport.getKey(value),
-                AnnotationSupport.getValue(value),
-                AnnotationSupport.getExpiration(value));
+
+        final String context = AnnotationSupport.getContext(value);
+        final String key = AnnotationSupport.getKey(value);
+        final String val = AnnotationSupport.getValue(value);
+        if (context == null || key == null || val == null) {
+            throw new IOException("Context, key, and value must be non-null");
+        }
+
+        return update(context, key, val, AnnotationSupport.getExpiration(value));
     }
 
     /** {@inheritDoc} */
-    @Override
     public Long updateWithVersion(@Positive final long version,
                                   @Nonnull @NotEmpty final String context,
                                   @Nonnull @NotEmpty final String key,
@@ -373,7 +375,6 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
 
 // Checkstyle: ParameterNumber OFF
     /** {@inheritDoc} */
-    @Override
     @Nullable public <T> Long updateWithVersion(@Positive final long version,
                                   @Nonnull @NotEmpty final String context,
                                   @Nonnull @NotEmpty final String key,
@@ -388,21 +389,21 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
 // Checkstyle: ParameterNumber ON
 
     /** {@inheritDoc} */
-    @Override
     @Nullable public Long updateWithVersion(@Positive final long version, @Nonnull final Object value)
             throws IOException, VersionMismatchException {
-
         Constraint.isNotNull(value, "Value cannot be null");
-        return updateWithVersion(
-                version,
-                AnnotationSupport.getContext(value),
-                AnnotationSupport.getKey(value),
-                AnnotationSupport.getValue(value),
-                AnnotationSupport.getExpiration(value));
+
+        final String context = AnnotationSupport.getContext(value);
+        final String key = AnnotationSupport.getKey(value);
+        final String val = AnnotationSupport.getValue(value);
+        if (context == null || key == null || val == null) {
+            throw new IOException("Context, key, and value must be non-null");
+        }
+
+        return updateWithVersion(version, context, key, val, AnnotationSupport.getExpiration(value));
     }
 
     /** {@inheritDoc} */
-    @Override
     public boolean updateExpiration(@Nonnull @NotEmpty final String context,
                                     @Nonnull @NotEmpty final String key,
                                     @Nullable @Positive final Long expiration) throws IOException {
@@ -421,17 +422,19 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
     public boolean updateExpiration(@Nonnull final Object value) throws IOException {
         Constraint.isNotNull(value, "Value cannot be null");
-        return updateExpiration(
-                AnnotationSupport.getContext(value),
-                AnnotationSupport.getKey(value),
-                AnnotationSupport.getExpiration(value));
+
+        final String context = AnnotationSupport.getContext(value);
+        final String key = AnnotationSupport.getKey(value);
+        if (context == null || key == null) {
+            throw new IOException("Context and key must be non-null");
+        }
+
+        return updateExpiration(context, key, AnnotationSupport.getExpiration(value));
     }
 
     /** {@inheritDoc} */
-    @Override
     public boolean delete(@Nonnull @NotEmpty final String context, @Nonnull @NotEmpty final String key)
             throws IOException {
 
@@ -455,16 +458,19 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
     public boolean delete(@Nonnull final Object value) throws IOException {
         Constraint.isNotNull(value, "Value cannot be null");
-        return delete(
-                AnnotationSupport.getContext(value),
-                AnnotationSupport.getKey(value));
+
+        final String context = AnnotationSupport.getContext(value);
+        final String key = AnnotationSupport.getKey(value);
+        if (context == null || key == null) {
+            throw new IOException("Context and key must be non-null");
+        }
+
+        return delete(context, key);
     }
 
     /** {@inheritDoc} */
-    @Override
     public boolean deleteWithVersion(@Positive final long version,
                                      @Nonnull @NotEmpty final String context,
                                      @Nonnull @NotEmpty final String key) throws IOException, VersionMismatchException {
@@ -489,26 +495,26 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
     public boolean deleteWithVersion(@Positive final long version, @Nonnull final Object value)
             throws IOException, VersionMismatchException {
-
         Constraint.isNotNull(value, "Value cannot be null");
-        return deleteWithVersion(
-                version,
-                AnnotationSupport.getContext(value),
-                AnnotationSupport.getKey(value));
+
+        final String context = AnnotationSupport.getContext(value);
+        final String key = AnnotationSupport.getKey(value);
+        if (context == null || key == null) {
+            throw new IOException("Context and key must be non-null");
+        }
+
+        return deleteWithVersion(version, context, key);
     }
 
     /** {@inheritDoc} */
-    @Override
     public void reap(@Nonnull @NotEmpty final String context) throws IOException {
         return;
     }
 
 // Checkstyle: ReturnCount OFF
     /** {@inheritDoc} */
-    @Override
     public void updateContextExpiration(@Nonnull @NotEmpty final String context, @Nullable final Long expiration)
             throws IOException {
         if (!trackContextKeys) {
@@ -546,7 +552,6 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
 // Checkstyle: ReturnCount ON
 
     /** {@inheritDoc} */
-    @Override
     public void deleteContext(@Nonnull @NotEmpty final String context) throws IOException {
         Constraint.isNotNull(StringSupport.trimOrNull(context), "Context cannot be null or empty");
         final String namespace = lookupNamespace(context);
@@ -583,7 +588,7 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
      *
      * @throws java.io.IOException On memcached operation errors.
      */
-    protected String lookupNamespace(final String context) throws IOException {
+    @Nullable protected String lookupNamespace(@Nonnull @NotEmpty final String context) throws IOException {
         try {
             final CASValue<String> result = handleAsyncResult(
                     memcacheClient.asyncGets(memcachedKey(context), stringTranscoder));
@@ -603,7 +608,7 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
      *
      * @throws java.io.IOException On memcached operation errors.
      */
-    protected String createNamespace(final String context) throws IOException {
+    @Nonnull protected String createNamespace(@Nonnull @NotEmpty final String context) throws IOException {
         String namespace =  null;
         boolean success = false;
         // Perform successive add operations until success to ensure unique namespace
@@ -616,6 +621,7 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
         if (!handleAsyncResult(memcacheClient.add(memcachedKey(context), 0, namespace, stringTranscoder))) {
             throw new IllegalStateException(context + " already exists");
         }
+        assert namespace != null;
         return namespace;
     }
 
@@ -626,7 +632,7 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
      *
      * @return Key comprised of 250 characters or less.
      */
-    private String memcachedKey(final String ... parts) {
+    private String memcachedKey(@Nonnull final String ... parts) {
         final String key;
         if (parts.length > 0) {
             final StringBuilder sb = new StringBuilder();
@@ -655,7 +661,7 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
      * @return the result
      * @throws IOException if an error occurs
      */
-    private <T> T handleAsyncResult(final OperationFuture<T> result) throws IOException {
+    private <T> T handleAsyncResult(@Nonnull final OperationFuture<T> result) throws IOException {
         try {
             return result.get(operationTimeout, TimeUnit.SECONDS);
         } catch (final InterruptedException e) {
@@ -676,8 +682,8 @@ public class MemcachedStorageService extends AbstractIdentifiableInitializableCo
      * @return whether the update was a success
      * @throws IOException if an error occurs
      */
-    private boolean updateContextKeyList(final String suffix, final String namespace, final String key)
-            throws IOException {
+    private boolean updateContextKeyList(@Nonnull final String suffix, @Nonnull final String namespace,
+            @Nonnull final String key) throws IOException {
         final String listKey = namespace + suffix;
         final String newItem = key + CTX_KEY_LIST_DELIMITER;
         final boolean success = handleAsyncResult(memcacheClient.append(listKey, newItem, stringTranscoder));
diff --git a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/memcached/StorageRecordTranscoder.java b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/memcached/StorageRecordTranscoder.java
index 1d5d84904..eeec74735 100644
--- a/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/memcached/StorageRecordTranscoder.java
+++ b/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/memcached/StorageRecordTranscoder.java
@@ -33,22 +33,22 @@ public class StorageRecordTranscoder implements Transcoder<MemcachedStorageRecor
     /** Max size is maximum default memcached value size, 1MB. */
     private static final int MAX_SIZE = 1024 * 1024;
 
-
-    @Override
+    /** {@inheritDoc} */
     public boolean asyncDecode(final CachedData d) {
         return false;
     }
 
-    @Override
+    /** {@inheritDoc} */
     public CachedData encode(final MemcachedStorageRecord<?> o) {
         final byte[] value = o.getValue().getBytes(StandardCharsets.UTF_8);
         final byte[] encoded = new byte[value.length + 8];
-        ByteUtil.toBytes(o.getExpiration() == null ? 0 : o.getExpiration().longValue(), encoded, 0);
+        final Long exp = o.getExpiration();
+        ByteUtil.toBytes(exp == null ? 0 : exp.longValue(), encoded, 0);
         System.arraycopy(value, 0, encoded, 8, value.length);
         return new CachedData(0, encoded, MAX_SIZE);
     }
 
-    @Override
+    /** {@inheritDoc} */
     public MemcachedStorageRecord<?> decode(final CachedData d) {
         final byte[] bytes = d.getData();
         final String value = new String(bytes, 8, bytes.length - 8, StandardCharsets.UTF_8);
@@ -59,7 +59,7 @@ public class StorageRecordTranscoder implements Transcoder<MemcachedStorageRecor
         return new MemcachedStorageRecord<>(value, exp == 0 ? null : exp);
     }
 
-    @Override
+    /** {@inheritDoc} */
     public int getMaxSize() {
         return MAX_SIZE;
     }
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/MemoryStorageServiceTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/MemoryStorageServiceTest.java
index 2db56090b..147789c59 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/MemoryStorageServiceTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/MemoryStorageServiceTest.java
@@ -41,6 +41,11 @@ public class MemoryStorageServiceTest extends StorageServiceTest {
         return ss;
     }
         
+    /**
+     * Test config.
+     * 
+     * @throws ComponentInitializationException
+     */
     @Test
     public void validConfig() throws ComponentInitializationException {
         MemoryStorageService ss = new MemoryStorageService();
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/StorageServiceReplayCacheTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/StorageServiceReplayCacheTest.java
index 4827561b5..3c5f5f09c 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/StorageServiceReplayCacheTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/StorageServiceReplayCacheTest.java
@@ -70,12 +70,6 @@ public class StorageServiceReplayCacheTest {
     @Test
     public void testInit() {
         replayCache = new StorageServiceReplayCache();
-        try {
-            replayCache.setStorage(null);
-            Assert.fail("Null StorageService should have caused constraint violation");
-        } catch (Exception e) {
-        }
-
         try {
             replayCache.setStorage(new ClientStorageService());
             Assert.fail("ClientStorageService should have caused constraint violation");
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/StorageServiceRevocationCacheTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/StorageServiceRevocationCacheTest.java
index 3581a82f6..06d4ce2ad 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/StorageServiceRevocationCacheTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/StorageServiceRevocationCacheTest.java
@@ -36,6 +36,7 @@ import org.testng.annotations.BeforeMethod;
 /**
  * Tests for {@link StorageServiceRevocationCache}.
  */
+ at SuppressWarnings("javadoc")
 public class StorageServiceRevocationCacheTest {
     
     private MemoryStorageService storageService;
@@ -66,12 +67,6 @@ public class StorageServiceRevocationCacheTest {
     @Test
     public void testInit() {
         revocationCache = new StorageServiceRevocationCache();
-        try {
-            revocationCache.setStorage(null);
-            fail("Null StorageService should have caused constraint violation");
-        } catch (final Exception e) {
-        }
-
         try {
             revocationCache.setStorage(new ClientStorageService());
             
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/AbstractBaseClientStorageServiceTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/AbstractBaseClientStorageServiceTest.java
index 89f0125df..515d0a263 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/AbstractBaseClientStorageServiceTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/AbstractBaseClientStorageServiceTest.java
@@ -17,6 +17,8 @@
 
 package org.opensaml.storage.impl.client;
 
+import javax.annotation.Nonnull;
+
 import org.springframework.core.io.ClassPathResource;
 import org.testng.Assert;
 
@@ -32,7 +34,8 @@ import net.shibboleth.shared.spring.resource.ResourceHelper;
 /** Base class for client storage tests. */
 public class AbstractBaseClientStorageServiceTest {
 
-    public static final String STORAGE_NAME = "foo";
+    /** Storage name. */
+    @Nonnull public static final String STORAGE_NAME = "foo";
     
     private Resource keystoreResource;
     private Resource versionResource;
@@ -47,7 +50,7 @@ public class AbstractBaseClientStorageServiceTest {
         versionResource = ResourceHelper.of(resource);
     }
 
-    protected ClientStorageService getStorageService() throws ComponentInitializationException {
+    @Nonnull protected ClientStorageService getStorageService() throws ComponentInitializationException {
         final ClientStorageService ss = new ClientStorageService();
         ss.setId("test");
         ss.setStorageName(STORAGE_NAME);
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/LoadClientStorageServicesTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/LoadClientStorageServicesTest.java
index 7cb13ed9c..c613b2e34 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/LoadClientStorageServicesTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/LoadClientStorageServicesTest.java
@@ -18,7 +18,6 @@
 package org.opensaml.storage.impl.client;
 
 import java.io.IOException;
-import java.util.Collections;
 import java.util.concurrent.locks.Lock;
 
 import org.opensaml.profile.action.EventIds;
@@ -38,11 +37,13 @@ import org.testng.annotations.Test;
 import com.google.common.net.UrlEscapers;
 
 import jakarta.servlet.http.Cookie;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.servlet.impl.HttpServletRequestResponseContext;
 import net.shibboleth.shared.servlet.impl.ThreadLocalHttpServletRequestSupplier;
 
 /** Unit test for {@link LoadClientStorageServices}. */
+ at SuppressWarnings("javadoc")
 public class LoadClientStorageServicesTest extends AbstractBaseClientStorageServiceTest {
 
     private ProfileRequestContext prc;
@@ -56,7 +57,7 @@ public class LoadClientStorageServicesTest extends AbstractBaseClientStorageServ
 
     @BeforeMethod public void setUp() {
         prc = new RequestContextBuilder().buildProfileRequestContext();
-        loadCtx = prc.getSubcontext(ClientStorageLoadContext.class, true);
+        loadCtx = prc.getOrCreateSubcontext(ClientStorageLoadContext.class);
         loadCtx.getStorageKeys().add(STORAGE_NAME);
         
         action = new LoadClientStorageServices();
@@ -65,7 +66,7 @@ public class LoadClientStorageServicesTest extends AbstractBaseClientStorageServ
     }
 
     @Test public void testNoContext() throws ComponentInitializationException {
-        action.setStorageServices(Collections.singletonList(getStorageService()));
+        action.setStorageServices(CollectionSupport.singletonList(getStorageService()));
         action.initialize();
         
         prc.removeSubcontext(loadCtx);
@@ -102,11 +103,13 @@ public class LoadClientStorageServicesTest extends AbstractBaseClientStorageServ
             lock.unlock();
         }
 
-        action.setStorageServices(Collections.singletonList(ss));
+        action.setStorageServices(CollectionSupport.singletonList(ss));
         action.initialize();
 
         final Cookie cookie = new Cookie("bar", "ignored");
-        ((MockHttpServletRequest) HttpServletRequestResponseContext.getRequest()).setCookies(cookie);
+        final MockHttpServletRequest request = (MockHttpServletRequest) HttpServletRequestResponseContext.getRequest();
+        assert request != null;
+        request.setCookies(cookie);
         
         action.execute(prc);
         ActionTestingSupport.assertProceedEvent(prc);
@@ -122,11 +125,13 @@ public class LoadClientStorageServicesTest extends AbstractBaseClientStorageServ
 
     @Test public void testInvalid() throws ComponentInitializationException, IOException {
         final ClientStorageService ss = getStorageService();
-        action.setStorageServices(Collections.singletonList(ss));
+        action.setStorageServices(CollectionSupport.singletonList(ss));
         action.initialize();
 
         final Cookie cookie = new Cookie(STORAGE_NAME, "error");
-        ((MockHttpServletRequest) HttpServletRequestResponseContext.getRequest()).setCookies(cookie);
+        final MockHttpServletRequest request = (MockHttpServletRequest) HttpServletRequestResponseContext.getRequest();
+        assert request != null;
+        request.setCookies(cookie);
         
         action.execute(prc);
         ActionTestingSupport.assertProceedEvent(prc);
@@ -155,11 +160,14 @@ public class LoadClientStorageServicesTest extends AbstractBaseClientStorageServ
 
         Assert.assertFalse(ss.isLoaded());
         
+        assert saved != null;
         final Cookie cookie = new Cookie("foo", UrlEscapers.urlFormParameterEscaper().escape(saved.getValue()));
-        ((MockHttpServletRequest) HttpServletRequestResponseContext.getRequest()).setCookies(cookie);
+        final MockHttpServletRequest request = (MockHttpServletRequest) HttpServletRequestResponseContext.getRequest();
+        assert request != null;
+        request.setCookies(cookie);
 
         action.setUseLocalStorage(true);
-        action.setStorageServices(Collections.singletonList(ss));
+        action.setStorageServices(CollectionSupport.singletonList(ss));
         action.initialize();
 
         action.execute(prc);
@@ -176,19 +184,23 @@ public class LoadClientStorageServicesTest extends AbstractBaseClientStorageServ
         ss.create("context2", "key", "value", null);
         
         final ClientStorageServiceOperation saved = ss.save();
-        Assert.assertNotNull(saved);
+        assert saved != null;
 
+        final String value = saved.getValue();
+        assert value != null;
+        
         HttpServletRequestResponseContext.loadCurrent(new MockHttpServletRequest(), new MockHttpServletResponse());
 
         Assert.assertFalse(ss.isLoaded());
         
         final MockHttpServletRequest request = (MockHttpServletRequest) HttpServletRequestResponseContext.getRequest();
+        assert request != null;
         request.setParameter(LoadClientStorageServices.SUPPORT_FORM_FIELD, "true");
         request.setParameter(LoadClientStorageServices.SUCCESS_FORM_FIELD + '.' + ss.getStorageName(), "true");
-        request.setParameter(LoadClientStorageServices.VALUE_FORM_FIELD + '.' + ss.getStorageName(), saved.getValue());
+        request.setParameter(LoadClientStorageServices.VALUE_FORM_FIELD + '.' + ss.getStorageName(), value);
 
         action.setUseLocalStorage(true);
-        action.setStorageServices(Collections.singletonList(ss));
+        action.setStorageServices(CollectionSupport.singletonList(ss));
         action.initialize();
 
         action.execute(prc);
@@ -201,17 +213,17 @@ public class LoadClientStorageServicesTest extends AbstractBaseClientStorageServ
         Assert.assertNull(loadCtx.getParent());
 
         StorageRecord<?> record = ss.read("context1", "key1");
-        Assert.assertNotNull(record);
+        assert record != null;
         Assert.assertEquals(record.getValue(), "value1");
         Assert.assertNull(record.getExpiration());
         
         record = ss.read("context1", "key2");
-        Assert.assertNotNull(record);
+        assert record != null;
         Assert.assertEquals(record.getValue(), "value2");
         Assert.assertNull(record.getExpiration());
 
         record = ss.read("context2", "key");
-        Assert.assertNotNull(record);
+        assert record != null;
         Assert.assertEquals(record.getValue(), "value");
         Assert.assertNull(record.getExpiration());
     }
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/PopulateClientStorageLoadContextTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/PopulateClientStorageLoadContextTest.java
index f179cb610..1f223cdd2 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/PopulateClientStorageLoadContextTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/PopulateClientStorageLoadContextTest.java
@@ -17,8 +17,6 @@
 
 package org.opensaml.storage.impl.client;
 
-import java.util.Collections;
-
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.profile.testing.ActionTestingSupport;
 import org.opensaml.profile.testing.RequestContextBuilder;
@@ -30,10 +28,12 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.servlet.impl.HttpServletRequestResponseContext;
 
 /** Unit test for {@link PopulateClientStorageLoadContext}. */
+ at SuppressWarnings("javadoc")
 public class PopulateClientStorageLoadContextTest extends AbstractBaseClientStorageServiceTest {
 
     private ProfileRequestContext prc;
@@ -58,7 +58,7 @@ public class PopulateClientStorageLoadContextTest extends AbstractBaseClientStor
     }
  
     @Test public void testUnloaded() throws ComponentInitializationException {
-        action.setStorageServices(Collections.singletonList(getStorageService()));
+        action.setStorageServices(CollectionSupport.singletonList(getStorageService()));
         action.initialize();
         
         HttpServletRequestResponseContext.loadCurrent(new MockHttpServletRequest(), new MockHttpServletResponse());
@@ -67,14 +67,14 @@ public class PopulateClientStorageLoadContextTest extends AbstractBaseClientStor
         ActionTestingSupport.assertProceedEvent(prc);
         
         final ClientStorageLoadContext ctx = prc.getSubcontext(ClientStorageLoadContext.class);
-        Assert.assertNotNull(ctx);
+        assert ctx != null;
         Assert.assertEquals(ctx.getStorageKeys().size(), 1);
         Assert.assertTrue(ctx.getStorageKeys().contains(STORAGE_NAME));
     }
 
     @Test public void testLoaded() throws ComponentInitializationException {
         final ClientStorageService ss = getStorageService();
-        action.setStorageServices(Collections.singletonList(ss));
+        action.setStorageServices(CollectionSupport.singletonList(ss));
         action.initialize();
         
         HttpServletRequestResponseContext.loadCurrent(new MockHttpServletRequest(), new MockHttpServletResponse());
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/PopulateClientStorageSaveContextTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/PopulateClientStorageSaveContextTest.java
index 7174963b9..c408c2e6c 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/PopulateClientStorageSaveContextTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/PopulateClientStorageSaveContextTest.java
@@ -18,7 +18,6 @@
 package org.opensaml.storage.impl.client;
 
 import java.io.IOException;
-import java.util.Collections;
 
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.profile.testing.ActionTestingSupport;
@@ -31,10 +30,12 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.servlet.impl.HttpServletRequestResponseContext;
 
 /** Unit test for {@link PopulateClientStorageSaveContext}. */
+ at SuppressWarnings("javadoc")
 public class PopulateClientStorageSaveContextTest extends AbstractBaseClientStorageServiceTest {
 
     private ProfileRequestContext prc;
@@ -59,7 +60,7 @@ public class PopulateClientStorageSaveContextTest extends AbstractBaseClientStor
     }
  
     @Test public void testUnloaded() throws ComponentInitializationException {
-        action.setStorageServices(Collections.singletonList(getStorageService()));
+        action.setStorageServices(CollectionSupport.singletonList(getStorageService()));
         action.initialize();
         
         HttpServletRequestResponseContext.loadCurrent(new MockHttpServletRequest(), new MockHttpServletResponse());
@@ -72,7 +73,7 @@ public class PopulateClientStorageSaveContextTest extends AbstractBaseClientStor
 
     @Test public void testClean() throws ComponentInitializationException {
         final ClientStorageService ss = getStorageService();
-        action.setStorageServices(Collections.singletonList(ss));
+        action.setStorageServices(CollectionSupport.singletonList(ss));
         action.initialize();
         
         HttpServletRequestResponseContext.loadCurrent(new MockHttpServletRequest(), new MockHttpServletResponse());
@@ -87,7 +88,7 @@ public class PopulateClientStorageSaveContextTest extends AbstractBaseClientStor
 
     @Test public void testDirty() throws ComponentInitializationException, IOException {
         final ClientStorageService ss = getStorageService();
-        action.setStorageServices(Collections.singletonList(ss));
+        action.setStorageServices(CollectionSupport.singletonList(ss));
         action.initialize();
         
         HttpServletRequestResponseContext.loadCurrent(new MockHttpServletRequest(), new MockHttpServletResponse());
@@ -99,7 +100,7 @@ public class PopulateClientStorageSaveContextTest extends AbstractBaseClientStor
         ActionTestingSupport.assertProceedEvent(prc);
         
         final ClientStorageSaveContext saveCtx = prc.getSubcontext(ClientStorageSaveContext.class); 
-        Assert.assertNotNull(saveCtx);
+        assert saveCtx != null;
         Assert.assertTrue(saveCtx.isSourceRequired(ClientStorageSource.HTML_LOCAL_STORAGE));
         Assert.assertEquals(saveCtx.getStorageOperations().size(), 1);
         
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/SaveCookieBackedClientStorageServicesTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/SaveCookieBackedClientStorageServicesTest.java
index 5e3167b96..16e8cc796 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/SaveCookieBackedClientStorageServicesTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/client/SaveCookieBackedClientStorageServicesTest.java
@@ -18,7 +18,6 @@
 package org.opensaml.storage.impl.client;
 
 import java.io.IOException;
-import java.util.Collections;
 
 import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
@@ -32,10 +31,12 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.servlet.impl.HttpServletRequestResponseContext;
 
 /** Unit test for {@link SaveCookieBackedClientStorageServices}. */
+ at SuppressWarnings("javadoc")
 public class SaveCookieBackedClientStorageServicesTest extends AbstractBaseClientStorageServiceTest {
 
     private ProfileRequestContext prc;
@@ -50,8 +51,7 @@ public class SaveCookieBackedClientStorageServicesTest extends AbstractBaseClien
 
     @BeforeMethod public void setUp() {
         prc = new RequestContextBuilder().buildProfileRequestContext();
-        saveCtx = new ClientStorageSaveContext();
-        prc.addSubcontext(saveCtx);
+        saveCtx = prc.getOrCreateSubcontext(ClientStorageSaveContext.class);
         action = new SaveCookieBackedClientStorageServices();
     }
         
@@ -63,7 +63,7 @@ public class SaveCookieBackedClientStorageServicesTest extends AbstractBaseClien
     }
 
     @Test public void testNoContext() throws ComponentInitializationException {
-        action.setStorageServices(Collections.singletonList(getStorageService()));
+        action.setStorageServices(CollectionSupport.singletonList(getStorageService()));
         action.initialize();
         
         prc.removeSubcontext(saveCtx);
@@ -74,7 +74,7 @@ public class SaveCookieBackedClientStorageServicesTest extends AbstractBaseClien
     
     @Test public void testNoCookieSources() throws ComponentInitializationException {
         final ClientStorageService ss = getStorageService();
-        action.setStorageServices(Collections.singletonList(ss));
+        action.setStorageServices(CollectionSupport.singletonList(ss));
         action.initialize();
         
         HttpServletRequestResponseContext.loadCurrent(new MockHttpServletRequest(), new MockHttpServletResponse());
@@ -85,12 +85,16 @@ public class SaveCookieBackedClientStorageServicesTest extends AbstractBaseClien
         action.execute(prc);
         ActionTestingSupport.assertProceedEvent(prc);
         Assert.assertNull(saveCtx.getParent());
-        Assert.assertEquals(((MockHttpServletResponse) HttpServletRequestResponseContext.getResponse()).getCookies().length, 0);
+        
+        final MockHttpServletResponse response = (MockHttpServletResponse) HttpServletRequestResponseContext.getResponse();
+        assert response != null;
+        
+        Assert.assertEquals(response.getCookies().length, 0);
     }
     
     @Test public void testSave() throws ComponentInitializationException, IOException {
         final ClientStorageService ss = getStorageService();
-        action.setStorageServices(Collections.singletonList(ss));
+        action.setStorageServices(CollectionSupport.singletonList(ss));
         action.initialize();
         
         HttpServletRequestResponseContext.loadCurrent(new MockHttpServletRequest(), new MockHttpServletResponse());
@@ -103,6 +107,7 @@ public class SaveCookieBackedClientStorageServicesTest extends AbstractBaseClien
         Assert.assertNull(saveCtx.getParent());
         
         final MockHttpServletResponse response = (MockHttpServletResponse) HttpServletRequestResponseContext.getResponse();
+        assert response != null;
         Assert.assertEquals(response.getCookies().length, 1);
         Assert.assertEquals(response.getCookies()[0].getName(), ss.getStorageName());
         Assert.assertEquals(response.getCookies()[0].getValue(), "the+value");
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/memcached/MemcachedStorageRecordTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/memcached/MemcachedStorageRecordTest.java
index 09e0de655..5d01e77a5 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/memcached/MemcachedStorageRecordTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/memcached/MemcachedStorageRecordTest.java
@@ -25,12 +25,17 @@ import static org.testng.Assert.assertNull;
 /**
  * Unit test for {@link MemcachedStorageRecord} class.
  */
+ at SuppressWarnings("javadoc")
 public class MemcachedStorageRecordTest {
 
     @Test
     public void testNumericExpiration() {
         final MemcachedStorageRecord<?> record = new MemcachedStorageRecord<>("r1", 5031757792L);
-        assertEquals(record.getExpiration().longValue(), 5031757792L);
+        
+        final Long exp = record.getExpiration();
+        assert exp != null;
+        
+        assertEquals(exp.longValue(), 5031757792L);
         assertEquals(record.getExpiry(), 5031757);
     }
 
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/memcached/MemcachedStorageServiceTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/memcached/MemcachedStorageServiceTest.java
index 98e91901f..b0c129a07 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/memcached/MemcachedStorageServiceTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/memcached/MemcachedStorageServiceTest.java
@@ -18,6 +18,7 @@
 package org.opensaml.storage.impl.memcached;
 
 import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.logic.Constraint;
 import net.spy.memcached.BinaryConnectionFactory;
 import net.spy.memcached.MemcachedClient;
 import org.cryptacular.generator.IdGenerator;
@@ -47,6 +48,7 @@ import static org.testng.Assert.*;
  * profile if a local memcached service is available.
  */
 @Test(groups = {"needs-external-fixture"}, enabled=false)
+ at SuppressWarnings("javadoc")
 public class MemcachedStorageServiceTest {
 
     private MemcachedStorageService service;
@@ -135,7 +137,7 @@ public class MemcachedStorageServiceTest {
         assertTrue((updatedVersion > r1.getVersion()));
         final Pair<Long, StorageRecord<String>> pair1 = service.read(context, key, r1.getVersion());
         assertEquals(pair1.getFirst(), updatedVersion);
-        assertEquals(pair1.getSecond().getValue(), updatedValue);
+        assertEquals(Constraint.isNotNull(pair1.getSecond(), "Value was null").getValue(), updatedValue);
         final Pair<Long, StorageRecord<String>> pair2 = service.read(context, key, updatedVersion);
         assertEquals(pair2.getFirst(), updatedVersion);
         assertNull(pair2.getSecond());

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list