#StackBounty: #java #tomcat Getting and saving application scope variable in Tomcat

Bounty: 50

This is a Java 1.8 and Tomcat 9 based application, with no Spring.

I want to be able to save an object in an application scope and have it fetchable by any other session. There is only one Tomcat server, it’s not federated in anyway. In this case, we have application authorization that happens based on a verified AUTH_USER and ROLE_ID header. The code runs, but every time it saves the object to the application scope, it gets forgotten or somehow not accessible to any future request. As a result, no caching happens.

My question is how do I save an object creating in one request and have it available via application scope for the next request. Please see comments in code to see where I thought it should work.

    private Map<String,AuthorizedHubRequest> getCachedAuthorizedHubRequestMap() {
        // I thought getSevletContext gave me the global application scope, but I'm somehow
        // wrong.  
        ServletContext context = this.getHttpServletRequest().getServletContext();
        Map<String,AuthorizedHubRequest> result = (Map<String, AuthorizedHubRequest>) context.getAttribute(AuthorizedHubRequest.class.getName());
        if(result == null) {
            result = new HashMap<String,AuthorizedHubRequest>();
            context.setAttribute(AuthorizedHubRequest.class.getName(),result);
        }
        return result;
    }

    private String getAuthorizedHubRequestCacheKey() {
        return this.authUser + "-"+ this.httpServletRequest.getHeader("Authorization") + "-"+ this.roleId;
    }
        
    private AuthorizedHubRequest getAuthorizedHubRequestFromCache() {
        String key = getAuthorizedHubRequestCacheKey();
        return getCachedAuthorizedHubRequestMap().get(key);  // This always returns null
    }

    private void saveAuthorizedHubRequestToCache(AuthorizedHubRequest authorizedHubRequest) {
        String key = getAuthorizedHubRequestCacheKey();
        getCachedAuthorizedHubRequestMap().put(key,authorizedHubRequest);
    }

    public AuthorizedHubRequest getAuthorizedHubRequest() throws SCExceptions {
        AuthorizedHubRequest result = getAuthorizedHubRequestFromCache();
        if(result != null) {
            logger.info("SC_TRACE_ID: "+this.traceId+" Retrieved authorization from cache");
        } else {
            logger.info("SC_TRACE_ID: "+this.traceId+" Authorization not in cache.  Creating.");
            authorizedHubRequest = new AuthorizedHubRequest().withHubRequestFilter(hubRequestFilter).withTraceId(traceId);
            if (this.pageNumber != null && this.pageSize != null) {
                authorizedHubRequest.setPageNumberRequested(pageNumber);
                authorizedHubRequest.setPageSize(pageSize);
            }

            if(this.maximumCacheDuration!=null) {
                authorizedHubRequest.setMaximumCacheDuration(maximumCacheDuration);
            }

            SCHubAuthorizationServiceHandler authHandler = new SCHubAuthorizationServiceHandler();
            authorizedHubRequest.setHubAuthorizations(authHandler.getHubAuthorization(traceId, authUser, roleId));
            saveAuthorizedHubRequestToCache(result);
        }

        return this.authorizedHubRequest;
    }

My server.xml is

<Server port="8015" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
  <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
  <GlobalNamingResources>
    <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector connectionTimeout="20000" port="8090" protocol="HTTP/1.1" redirectPort="8443"/>
    <Engine defaultHost="localhost" name="Catalina">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
      </Realm>
      <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log" suffix=".txt"/>
      </Host>
    </Engine>
  </Service>
</Server>


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.