[ 
https://issues.apache.org/jira/browse/SHIRO-317?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13608368#comment-13608368
 ] 

Benjamin Marwell edited comment on SHIRO-317 at 2/1/21, 9:20 AM:
-----------------------------------------------------------------

{code}
package com.blah.account.security.shiro.cache;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.subject.PrincipalCollection;

import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * User: Mark Spritzler
 *
 * First Serializable is the Key in the cache
 * Second Serializable is the Session object.
 *
 */
public class ConcurrentHashMapDelegatingCache implements Cache<Serializable, 
Serializable> {

  Cache<Serializable, Serializable> wrappedCache;

  private static ConcurrentHashMap<Serializable, Serializable> sessions = new 
ConcurrentHashMap<>();

  public void setWrappedCache(Cache<Serializable, Serializable> wrappedCache) {
    this.wrappedCache = wrappedCache;
  }

  @Override
  public void clear() throws CacheException {
    wrappedCache.clear();
  }

  // Parameter is the SessionId to find in the cache object.
  @Override
  public Serializable get(Serializable o) throws CacheException {
    Serializable session = getSessionFromMap(o);
    if (session != null) {
      return session;
    } else {
      session = wrappedCache.get(o);
      setSessionInMap(o, session);
      return session;
    }
  }

  // Parameters are key and value to put into the Session
  @Override
  public Serializable put(Serializable key, Serializable session) throws 
CacheException {
    Serializable currentSession = getSessionFromMap(key);

    if (currentSession != null) {
      // Check to see if there are any changes, if not, why put into Cache again
      if (currentSession.equals(session)) {
        return  currentSession;
      }
    }
    Serializable returnValue = wrappedCache.put(key, session);
    setSessionInMap(key, session);

    return returnValue;
  }

  @Override
  public Serializable remove(Serializable key) throws CacheException {
    Serializable returnValue;
    if (key instanceof PrincipalCollection) {
      String primaryPrincipal = (String)((PrincipalCollection) 
key).getPrimaryPrincipal();
      // Will need to find someway to convert this to a sessionId
      returnValue = wrappedCache.remove(primaryPrincipal);
      removeSessionFromMap(primaryPrincipal);
    } else {
      returnValue = wrappedCache.remove(key);
      removeSessionFromMap(key);
    }
    return returnValue;
  }

  @Override
  public int size() {
    return wrappedCache.size();
  }

  @Override
  public Set<Serializable> keys() {
    return wrappedCache.keys();
  }

  @Override
  public Collection<Serializable> values() {
    return wrappedCache.values();
  }

  public static Serializable getSessionFromMap(Serializable key) {
    return sessions.get(key);
  }

  public static void setSessionInMap(Serializable key, Serializable session) {
    sessions.put(key, session);
  }

  public static void removeSessionFromMap(Serializable key) {
    sessions.remove(key);
  }
}
{code}


was (Author: bytor99999):
package com.blah.account.security.shiro.cache;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.subject.PrincipalCollection;

import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * User: Mark Spritzler
 *
 * First Serializable is the Key in the cache
 * Second Serializable is the Session object.
 *
 */
public class ConcurrentHashMapDelegatingCache implements Cache<Serializable, 
Serializable> {

  Cache<Serializable, Serializable> wrappedCache;

  private static ConcurrentHashMap<Serializable, Serializable> sessions = new 
ConcurrentHashMap<>();

  public void setWrappedCache(Cache<Serializable, Serializable> wrappedCache) {
    this.wrappedCache = wrappedCache;
  }

  @Override
  public void clear() throws CacheException {
    wrappedCache.clear();
  }

  // Parameter is the SessionId to find in the cache object.
  @Override
  public Serializable get(Serializable o) throws CacheException {
    Serializable session = getSessionFromMap(o);
    if (session != null) {
      return session;
    } else {
      session = wrappedCache.get(o);
      setSessionInMap(o, session);
      return session;
    }
  }

  // Parameters are key and value to put into the Session
  @Override
  public Serializable put(Serializable key, Serializable session) throws 
CacheException {
    Serializable currentSession = getSessionFromMap(key);

    if (currentSession != null) {
      // Check to see if there are any changes, if not, why put into Cache again
      if (currentSession.equals(session)) {
        return  currentSession;
      }
    }
    Serializable returnValue = wrappedCache.put(key, session);
    setSessionInMap(key, session);

    return returnValue;
  }

  @Override
  public Serializable remove(Serializable key) throws CacheException {
    Serializable returnValue;
    if (key instanceof PrincipalCollection) {
      String primaryPrincipal = (String)((PrincipalCollection) 
key).getPrimaryPrincipal();
      // Will need to find someway to convert this to a sessionId
      returnValue = wrappedCache.remove(primaryPrincipal);
      removeSessionFromMap(primaryPrincipal);
    } else {
      returnValue = wrappedCache.remove(key);
      removeSessionFromMap(key);
    }
    return returnValue;
  }

  @Override
  public int size() {
    return wrappedCache.size();
  }

  @Override
  public Set<Serializable> keys() {
    return wrappedCache.keys();
  }

  @Override
  public Collection<Serializable> values() {
    return wrappedCache.values();
  }

  public static Serializable getSessionFromMap(Serializable key) {
    return sessions.get(key);
  }

  public static void setSessionInMap(Serializable key, Serializable session) {
    sessions.put(key, session);
  }

  public static void removeSessionFromMap(Serializable key) {
    sessions.remove(key);
  }
}


> Read session from cache once per request
> ----------------------------------------
>
>                 Key: SHIRO-317
>                 URL: https://issues.apache.org/jira/browse/SHIRO-317
>             Project: Shiro
>          Issue Type: New Feature
>    Affects Versions: 1.1.0, 1.2.0, 1.2.1
>            Reporter: Luke Biddell
>            Assignee: Les Hazlewood
>            Priority: Minor
>
> As per our discussion on the mailing thread, I've wired up my sessions to be 
> stored in memcached (membase in the longer term). On a per request basis I'm 
> seeing approximately 5 hits on my cache to retrieve the session. I would 
> expect to see only one hit per threaded request, with the session stored as a 
> thread local.
> For distributed caches this saves on network calls and for local caches it 
> will save on potential lock contention.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to