Repository: uportal-project/uportal
Issue: Guest user occasionally receives a portal page without a skin when using the dynamic-respondr-skin portlet

## Describe the bug

Occasionally (but typically uncommonly) unauthenticated users will start receiving a portal page that does not include the `dynamic-respondr-skin` portlet and therefore has no skin.  The affected page is completely unusable.

This issue has been encountered by several, and has been discussed more than once on the `uportal-user` list:  https://groups.google.com/a/apereo.org/forum/#!topic/uportal-user/JBy0Mp7YvG0

The issue stems from the `ThemeNameEqualsIgnoreCaseTester`.  This PAGS tester requires an active `HttpServletRequest` to function, otherwise it always returns `false` (i.e. the user is not a member of the group).  The problem is that this tester can be invoked within the Event Aggregation processes, which happen on a worker (non-request) thread.

In a typical data set (since the portlet was introduced), users receive the `dynamic-respondr-skin` portlet by virtue of their membership in the `Respondr Theme Users` group -- a PAGS group based on the `ThemeNameEqualsIgnoreCaseTester`.

Membership evaluations are cached in the portal.  When a test for membership in the `Respondr Theme Users` group for the `guest` user returns `false`, that result will be cached for a period.  During that period, real guest users will not receive the `dynamic-respondr-skin` portlet.

## How To Fix

Clearly the `ThemeNameEqualsIgnoreCaseTester` has issues, and (furthermore) we don't need it the way we did when it was introduced.  (The Universality theme has been removed.)  We should deprecate it, remove all usages of it from data sets in uPortal-start, and publish the solution in the released notes.


Changed files:
uPortal-events/src/main/java/org/apereo/portal/events/aggr/PortalEventProcessingManagerImpl.java
uPortal-persondir/src/main/java/org/apereo/portal/persondir/support/PersonManagerCurrentUserProvider.java
uPortal-groups/uPortal-groups-pags/src/main/java/org/apereo/portal/groups/pags/testers/ThemeNameEqualsIgnoreCaseTester.java

diff --git a/uPortal-events/src/main/java/org/apereo/portal/events/aggr/PortalEventProcessingManagerImpl.java b/uPortal-events/src/main/java/org/apereo/portal/events/aggr/PortalEventProcessingManagerImpl.java
index 0dc3abb71..65cd976e1 100644
--- a/uPortal-events/src/main/java/org/apereo/portal/events/aggr/PortalEventProcessingManagerImpl.java
+++ b/uPortal-events/src/main/java/org/apereo/portal/events/aggr/PortalEventProcessingManagerImpl.java
@@ -63,7 +63,7 @@ public class PortalEventProcessingManagerImpl
             new ThreadLocal<Map<Class<?>, Collection<Serializable>>>() {
                 @Override
                 protected Map<Class<?>, Collection<Serializable>> initialValue() {
-                    return new HashMap<Class<?>, Collection<Serializable>>();
+                    return new HashMap<>();
                 }
             };
     private volatile boolean shutdown = false;
@@ -122,7 +122,7 @@ public class PortalEventProcessingManagerImpl
     }
 
     @Override
-    public void destroy() throws Exception {
+    public void destroy() {
         this.shutdown = true;
     }
 
@@ -426,7 +426,7 @@ public class PortalEventProcessingManagerImpl
         final Map<Class<?>, Collection<Serializable>> evictedEntities = evictedEntitiesHolder.get();
         Collection<Serializable> ids = evictedEntities.get(entityClass);
         if (ids == null) {
-            ids = new ArrayList<Serializable>();
+            ids = new ArrayList<>();
             evictedEntities.put(entityClass, ids);
         }
         ids.add(identifier);
diff --git a/uPortal-groups/uPortal-groups-pags/src/main/java/org/apereo/portal/groups/pags/testers/ThemeNameEqualsIgnoreCaseTester.java b/uPortal-groups/uPortal-groups-pags/src/main/java/org/apereo/portal/groups/pags/testers/ThemeNameEqualsIgnoreCaseTester.java
index 6241c4597..950a48b52 100644
--- a/uPortal-groups/uPortal-groups-pags/src/main/java/org/apereo/portal/groups/pags/testers/ThemeNameEqualsIgnoreCaseTester.java
+++ b/uPortal-groups/uPortal-groups-pags/src/main/java/org/apereo/portal/groups/pags/testers/ThemeNameEqualsIgnoreCaseTester.java
@@ -33,7 +33,11 @@ import org.springframework.context.ApplicationContext;
 /**
  * This Group tester checks the current session's user profile theme against the test value ignoring
  * case.
+ *
+ * @deprecated Avoid this PAGS tester because (1) it doesn't function outside of a container request
+ *     thread; and (2) it isn't necessary any longer (without Universality).
  */
+@Deprecated
 public class ThemeNameEqualsIgnoreCaseTester implements IPersonTester {
 
     protected Logger logger = LoggerFactory.getLogger(getClass());
@@ -77,23 +81,26 @@ public class ThemeNameEqualsIgnoreCaseTester implements IPersonTester {
         try {
             currentPortalRequest = portalRequestUtils.getCurrentPortalRequest();
         } catch (IllegalStateException e) {
-            logger.warn("No portal request to test ui theme");
+            logger.warn(
+                    "No HttpServletRequest is available for testing, which may lead to "
+                            + "surprising outcomes;  ThemeNameEqualsIgnoreCaseTester is deprecated and should "
+                            + "not be used.",
+                    e);
         }
         return currentPortalRequest;
     }
 
     private IStylesheetDescriptor getCurrentUserProfileStyleSheetDescriptor(
             IPerson person, HttpServletRequest currentPortalRequest) {
-        final String currentFname =
-                this.profileMapper.getProfileFname(person, currentPortalRequest);
-        IUserProfile profile = this.userLayoutStore.getSystemProfileByFname(currentFname);
+        final String currentFname = profileMapper.getProfileFname(person, currentPortalRequest);
+        IUserProfile profile = userLayoutStore.getSystemProfileByFname(currentFname);
         int profileId = profile.getThemeStylesheetId();
-        return this.stylesheetDescriptorDao.getStylesheetDescriptor(profileId);
+        return stylesheetDescriptorDao.getStylesheetDescriptor(profileId);
     }
 
     private void logDebugMessages(String uiTheme) {
         if (logger.isDebugEnabled()) {
-            logger.debug("themeTestValue: {}", this.themeTestValue);
+            logger.debug("themeTestValue: {}", themeTestValue);
             logger.debug("uiTheme: {}", uiTheme);
             logger.debug("getStringCompareResults(uiTheme): {}", getStringCompareResults(uiTheme));
         }
diff --git a/uPortal-persondir/src/main/java/org/apereo/portal/persondir/support/PersonManagerCurrentUserProvider.java b/uPortal-persondir/src/main/java/org/apereo/portal/persondir/support/PersonManagerCurrentUserProvider.java
index 5ee3109ef..7364ac4b0 100644
--- a/uPortal-persondir/src/main/java/org/apereo/portal/persondir/support/PersonManagerCurrentUserProvider.java
+++ b/uPortal-persondir/src/main/java/org/apereo/portal/persondir/support/PersonManagerCurrentUserProvider.java
@@ -45,9 +45,6 @@ public class PersonManagerCurrentUserProvider implements ICurrentUserProvider {
         this.portalRequestUtils = portalRequestUtils;
     }
 
-    /* (non-Javadoc)
-     * @see org.jasig.services.persondir.support.ICurrentUserProvider#getCurrentUserName()
-     */
     @Override
     public String getCurrentUserName() {
         final HttpServletRequest portalRequest;