package org.beangle.security.monitor.auth.session.service;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.beangle.commons.collection.ListUtil;
import org.beangle.security.monitor.Authentication;
import org.beangle.security.monitor.OnlineActivity;
import org.beangle.security.monitor.auth.session.SessionRegistry;
import org.beangle.security.monitor.auth.session.model.OnlineActivityBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MemSessionRegistry implements SessionRegistry {
protected static final Logger logger = LoggerFactory.getLogger(MemSessionRegistry.class);
// <principal:Object,SessionIdSet>
protected Map<Object, Set<String>> principals = new ConcurrentHashMap<Object, Set<String>>();
// <sessionId:Object,OnlineActvities>
protected Map<String, OnlineActivity> sessionIds = new ConcurrentHashMap<String, OnlineActivity>();
public List<OnlineActivity> getOnlineActivities() {
return ListUtil.newArrayList(sessionIds.values());
}
public boolean isRegisted(Object principal) {
Set<String> sessionsUsedByPrincipal = principals.get(principal);
return (null != sessionsUsedByPrincipal && !sessionsUsedByPrincipal.isEmpty());
}
public List<OnlineActivity> getOnlineActivities(Object principal, boolean includeExpiredSessions) {
Set<String> sessionsUsedByPrincipal = principals.get(principal);
List<OnlineActivity> list = ListUtil.newArrayList();
if (null == sessionsUsedByPrincipal) {
return list;
}
synchronized (sessionsUsedByPrincipal) {
for (final String sessionId : sessionsUsedByPrincipal) {
OnlineActivity activity = getOnlineActivity(sessionId);
if (activity == null) {
continue;
}
if (includeExpiredSessions || !activity.isExpired()) {
list.add(activity);
}
}
}
return list;
}
public OnlineActivity getOnlineActivity(String sessionId) {
return sessionIds.get(sessionId);
}
public void refreshLastRequest(String sessionId) {
OnlineActivity info = getOnlineActivity(sessionId);
if (info != null) {
info.refreshLastRequest();
}
}
public void register(String sessionId, Object principal, OnlineActivity newActivity) {
OnlineActivityBean existed = (OnlineActivityBean) getOnlineActivity(sessionId);
if (null != existed) {
existed.addRemark(" expired with replacement.");
remove(sessionId);
}
sessionIds.put(sessionId, newActivity);
Set<String> sessionsUsedByPrincipal = principals.get(principal);
if (sessionsUsedByPrincipal == null) {
sessionsUsedByPrincipal = Collections.synchronizedSet(new HashSet<String>(4));
principals.put(principal, sessionsUsedByPrincipal);
}
sessionsUsedByPrincipal.add(sessionId);
}
public void register(String sessionId, Authentication authentication) {
OnlineActivity newOne = OnlineActivityBuilder.build(authentication.getPrincipal(),
authentication.getDetails(), sessionId, new Date());
register(sessionId, authentication.getPrincipal(), newOne);
}
public OnlineActivity remove(String sessionId) {
OnlineActivity info = getOnlineActivity(sessionId);
if (null == info) {
return null;
}
sessionIds.remove(sessionId);
logger.debug("Remove session {} for {}", sessionId, info.getPrincipal());
Set<String> sessionsUsedByPrincipal = principals.get(info.getPrincipal());
if (null != sessionsUsedByPrincipal) {
synchronized (sessionsUsedByPrincipal) {
sessionsUsedByPrincipal.remove(sessionId);
// No need to keep object in principals Map anymore
if (sessionsUsedByPrincipal.size() == 0) {
principals.remove(info.getPrincipal());
logger.debug("Remove principal {} from registry", info.getPrincipal());
}
}
}
return info;
}
public int count() {
return sessionIds.size();
}
}