SessionCount.java revision 71ef1e179613c2e17b9ad5f1c9db6bf533941f9d
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync/**
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync *
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync *
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * The contents of this file are subject to the terms
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * of the Common Development and Distribution License
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * (the License). You may not use this file except in
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * compliance with the License.
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync *
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * You can obtain a copy of the License at
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * https://opensso.dev.java.net/public/CDDLv1.0.html or
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * opensso/legal/CDDLv1.0.txt
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * See the License for the specific language governing
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * permission and limitations under the License.
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync *
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * When distributing Covered Code, include this CDDL
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * Header Notice in each file and include the License file
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * at opensso/legal/CDDLv1.0.txt.
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * If applicable, add the following below the CDDL Header,
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * with the fields enclosed by brackets [] replaced by
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * your own identifying information:
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * "Portions Copyrighted [year] [name of copyright owner]"
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync *
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * $Id: SessionCount.java,v 1.5 2008/06/25 05:41:31 qcheng Exp $
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync *
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync */
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync/**
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * Portions Copyrighted 2011-2013 ForgeRock Inc
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync */
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncpackage com.iplanet.dpro.session.service;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.iplanet.am.util.SystemProperties;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.iplanet.dpro.session.Session;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.iplanet.dpro.session.SessionException;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.iplanet.dpro.session.SessionID;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.iplanet.dpro.session.share.SessionRequest;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.iplanet.dpro.session.share.SessionResponse;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.iplanet.services.naming.WebtopNaming;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.iplanet.sso.SSOToken;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.iplanet.sso.SSOTokenManager;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.sun.identity.common.configuration.SiteConfiguration;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.sun.identity.session.util.RestrictedTokenContext;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.sun.identity.shared.Constants;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.sun.identity.shared.debug.Debug;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport com.sun.identity.sm.ldap.CTSPersistentStore;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport java.net.URL;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport java.util.Collections;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport java.util.HashMap;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport java.util.HashSet;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport java.util.Iterator;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport java.util.Map;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncimport java.util.Set;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync /**
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * <code>SessionCount</code> represents the session count for a given user
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * in 3 different mutually exclusive deployment modes from which the user
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * sessions can be obtained.
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync *
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * <ul>
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * <li> SINGLE_SERVER_MODE :
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync *I Simply return the local sessions for the given user.
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * <li> MULTI_SERVER_MODE :
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * Query other AM servers for the sessions for the given user Add the numbers
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * up (including the local one) and return the value. If any of the AM servers
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * is down, simply ignores it since all the sessions maintained by that instance
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * are not available.
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * <li> SFO_MODE : Fetch the sessions for the given user directly from the
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * session repository.
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * </ul>
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync */
b9a21c3c91c47e090316e28d759194e46628ed49vboxsyncpublic class SessionCount {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync // SessionInfoMap: uuid -> Set (list of sids)
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync private static Map uuidSessionMap = Collections
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync .synchronizedMap(new HashMap());
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync /* Single server mode*/
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync static final int SINGLE_SERVER_MODE = 1;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync /* Multiserver mode */
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync static final int MULTI_SERVER_MODE = 2;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync /* Directly from Session repository*/
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync static final int SFO_MODE = 3;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync private static int deploymentMode = 0;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync private static Debug debug = SessionService.sessionDebug;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync private static SSOToken adminToken = null;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync private static boolean useLocalSessionsInMultiServerMode = false;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync private static boolean caseSensitiveUUID =
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync SystemProperties.getAsBoolean(Constants.CASE_SENSITIVE_UUID);
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync static {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync try {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync SSOTokenManager.getInstance();
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync } catch (Exception ssoe) {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync debug.error("SessionConstraint: Failied to get the "
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync + "SSOTokenManager instance.");
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync }
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync if (getSS().isSessionFailoverEnabled()) {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync deploymentMode = SFO_MODE;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync } else {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync try {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync int count = WebtopNaming.getAllServerIDs().size();
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync if (count == 1 || (count == 2
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync && (getSS().isSiteEnabled()
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync || !SiteConfiguration.getSites(getAdminToken()).isEmpty()))) {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync deploymentMode = SINGLE_SERVER_MODE;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync } else {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync deploymentMode = MULTI_SERVER_MODE;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync }
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync } catch (Exception ex) {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync //If an error occurs fallback to multi server mode
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync deploymentMode = MULTI_SERVER_MODE;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync }
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync }
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync // Without this property defined the default will be false which is
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync // backwards compatable.
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync useLocalSessionsInMultiServerMode =
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync SystemProperties.getAsBoolean(Constants.USE_LOCAL_SESSIONS_IN_MULTI_SERVER_MODE);
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync if (debug.messageEnabled()) {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync debug.message("SessionCount: useLocalSessionsInMultiServerMode set to " + useLocalSessionsInMultiServerMode);
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync }
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync }
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync static int getDeploymentMode() {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync return deploymentMode;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync }
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync static SessionService getSS() {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync SessionService ss = SessionService.getSessionService();
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync if (ss == null) {
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync debug.error("SessionConstraint: "
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync + " Failed to get the session service instance");
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync }
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync return ss;
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync }
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync /**
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * Returns the expiration information of all sessions belonging to a user
b9a21c3c91c47e090316e28d759194e46628ed49vboxsync * (uuid). The returned value will be a Map (sid->expiration_time).
*
* @param uuid
* User's universal unique ID.
* @return user Sessions
* @exception Exception
* if there is any problem with accessing the session
* repository.
*/
public static Map getAllSessionsByUUID(String uuid) throws Exception {
Map sessions = null;
if (!caseSensitiveUUID) {
uuid = uuid.toLowerCase();
}
switch (deploymentMode) {
case SINGLE_SERVER_MODE:
sessions = getSessionsFromLocalServer(uuid);
break;
case MULTI_SERVER_MODE:
if (useLocalSessionsInMultiServerMode()) {
sessions = getSessionsFromLocalServer(uuid);
} else {
sessions = getSessionsFromPeerServers(uuid);
}
break;
case SFO_MODE:
sessions = getSessionsFromRepository(uuid);
break;
default:
break;
}
if (sessions == null) {
sessions = Collections.EMPTY_MAP;
debug.error("Error: Unable to determine session count for user: " + uuid +
" returning empty map");
}
return sessions;
}
/*
* Return true if the Constants.USE_LOCAL_SESSIONS_IN_MULTI_SERVER_MODE property
* has been defined and set to true.
*/
static boolean useLocalSessionsInMultiServerMode() {
return useLocalSessionsInMultiServerMode;
}
/*
* Get user sessions from local server
*/
static Map<String, Long> getSessionsFromLocalServer(String uuid) {
Set<SessionID> sessions = (Set<SessionID>) uuidSessionMap.get(uuid);
Map<String, Long> retSessions = new HashMap<String, Long>();
if (sessions != null) {
synchronized (sessions) {
for (SessionID sid : sessions) {
InternalSession is = getSS().getInternalSession(sid);
if (is != null) {
retSessions.put(sid.toString(), new Long(is.getExpirationTime()));
}
}
}
}
return retSessions;
}
/*
* Get user sessions from session repository
*/
private static Map getSessionsFromPeerServers(String uuid) {
Map sessions = getSessionsFromLocalServer(uuid);
String localServerID = getSS().getLocalServerID();
Set serverIDs = null;
try {
serverIDs = WebtopNaming.getSiteNodes(localServerID);
} catch (Exception e) {
debug.error("Failed to get the serverIDs from " + "WebtopNaming.",
e);
return sessions;
}
for (Iterator m = serverIDs.iterator(); m.hasNext();) {
String serverID = (String) m.next();
if (serverID.equals(localServerID)) {
continue;
}
try {
URL svcurl = Session.getSessionServiceURL(serverID);
SessionRequest sreq = new SessionRequest(
SessionRequest.GetSessionCount, getAdminToken()
.getTokenID().toString(), false);
sreq.setUUID(uuid);
SessionResponse sres = getSessionResponse(svcurl, sreq);
sessions.putAll(sres.getSessionsForGivenUUID());
} catch (SessionException se) {
if (debug.messageEnabled()) {
debug.message("SessionConstraint: "
+ "peer AM server is down...");
}
}
}
return sessions;
}
private static Map<String, Long> getSessionsFromRepository(String uuid) throws Exception {
CTSPersistentStore repo = SessionService.getSessionService()
.getRepository();
Map<String, Long> sessions = null;
try {
sessions = repo.getTokensByUUID(uuid);
} catch (Exception e) {
debug.error("SessionCount.getSessionsFromRepository: "+
"Session repository is not available", e);
throw e;
}
return sessions;
}
/**
* Increments the session count
* @param is for the user
*
*/
public static void incrementSessionCount(InternalSession is) {
if ((deploymentMode == SINGLE_SERVER_MODE) ||
(deploymentMode == MULTI_SERVER_MODE && useLocalSessionsInMultiServerMode())) {
Set sessions = (Set) uuidSessionMap.get((caseSensitiveUUID) ? is.getUUID() : is.getUUID().toLowerCase());
if (sessions != null) {
sessions.add(is.getID());
} else {
sessions = Collections.synchronizedSet(new HashSet());
sessions.add(is.getID());
uuidSessionMap.put((caseSensitiveUUID) ? is.getUUID() : is.getUUID().toLowerCase(), sessions);
}
}
}
/**
* Decrements the session count
* @param is the <code>InternalSession</code> for the user
*
*/
static void decrementSessionCount(InternalSession is) {
String uuid = is.getUUID();
if (!caseSensitiveUUID && uuid != null) {
uuid = uuid.toLowerCase();
}
SessionID sid = is.getID();
if ((deploymentMode == SINGLE_SERVER_MODE) ||
(deploymentMode == MULTI_SERVER_MODE && useLocalSessionsInMultiServerMode())) {
Set sessions = (Set) uuidSessionMap.get(uuid);
if (sessions != null) {
sessions.remove(sid);
if (sessions.isEmpty()) {
uuidSessionMap.remove(uuid);
}
}
}
}
private static SessionResponse getSessionResponse(URL svcurl,
SessionRequest sreq) throws SessionException {
try {
Object context = RestrictedTokenContext.getCurrent();
if (context != null) {
sreq.setRequester(RestrictedTokenContext.marshal(context));
}
SessionResponse sres = Session.sendPLLRequest(svcurl, sreq);
if (sres.getException() != null) {
throw new SessionException(sres.getException());
}
return sres;
} catch (SessionException se) {
throw se;
} catch (Exception e) {
throw new SessionException(e);
}
}
/*
* Gets the admin token for checking the session constraints for the users
* @return admin <code>SSOTken</code>
*/
static SSOToken getAdminToken() {
if (adminToken == null) {
try {
adminToken = getSS().getSessionServiceToken();
} catch (Exception e) {
debug.error("Failed to get the admin token for "
+ "Session constraint checking.", e);
}
}
return adminToken;
}
}