ServerSessionOperationStrategy.java revision 0f7c5b88fd04e25bea6113dfc783a05e4e2045f8
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster/**
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * Copyright 2014 ForgeRock AS.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster *
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * The contents of this file are subject to the terms of the Common Development and
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * Distribution License (the License). You may not use this file except in compliance with the
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * License.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster *
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * specific language governing permission and limitations under the License.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster *
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * When distributing Covered Software, include this CDDL Header Notice in each file and include
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * Header, with the fields enclosed by brackets [] replaced by your own identifying
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * information: "Portions copyright [year] [name of copyright owner]".
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster */
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Fosterpackage com.iplanet.dpro.session.operations;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Fosterimport com.iplanet.dpro.session.Session;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Fosterimport com.iplanet.dpro.session.SessionException;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Fosterimport com.iplanet.dpro.session.monitoring.SessionOperationsBuilder;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Fosterimport com.iplanet.dpro.session.service.SessionConstants;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Fosterimport com.iplanet.dpro.session.service.SessionService;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Fosterimport com.iplanet.services.naming.WebtopNamingQuery;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Fosterimport com.sun.identity.shared.debug.Debug;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Fosterimport javax.inject.Inject;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Fosterimport javax.inject.Named;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster/**
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * Server based SessionOperationStrategy implementation.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster *
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * SessionOperations represent the available operations that can be performed on a Session,
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * which are applicable under a number of situations. These situations correspond to the
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * number of situations Sessions can find themselves in.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster *
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * This strategy covers the following:
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster *
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * <b>local</b> - The Session is based on the current server and that server is responsible for
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * processing the request.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster *
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * <b>remote</b> - The Session is based on a remote server which will service the request and
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * respond with an appropriate response. This is performed by using a remote request and the
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * PLL signalling system.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster *
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * <b>CTS</b> - The Session is a remote session, however the Site appears to be down. The request
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * will be performed locally using the CTS instead.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster *
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * Between these strategies, the users Session should be available during fail-over of a Site.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster */
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Fosterpublic class ServerSessionOperationStrategy implements SessionOperationStrategy {
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster private final SessionService service;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster private final SessionOperations local;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster private final SessionOperations remote;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster private final SessionOperations cts;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster private final WebtopNamingQuery queryUtils;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster private final Debug debug;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster /**
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * Guice initialised constructor.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster *
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * @param service Required for local server decisions.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * @param opsBuilder Required to generate appropriate operations
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * @param queryUtils Required for Server availability decisions.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * @param debug Required for logging.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster */
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster @Inject
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster public ServerSessionOperationStrategy(SessionService service,
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster SessionOperationsBuilder opsBuilder,
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster WebtopNamingQuery queryUtils,
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster @Named(SessionConstants.SESSION_DEBUG) Debug debug) {
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster this.service = service;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster this.local = opsBuilder.createMonitoredLocalOperations();
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster this.remote = opsBuilder.createMonitoredRemoteOperations();
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster this.cts = opsBuilder.createMonitoredCTSOperations();
b93185b577f7150fec37f9999b95b246d73bf63cjeff.schenk this.queryUtils = queryUtils;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster this.debug = debug;
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster }
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster /**
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * Based on the Session, determine the appropriate SessionOperations strategy to select.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster *
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * Local - For local Sessions which are hosted on the current Server.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * Remote - The Session is from a remote Site, and the Site is up.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * CTS - When cross talk is disabled, or if the Session is from a remote Site, which is down.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster *
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * @param session Non null Session to use.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * @return A non null SessionOperations implementation to use.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster */
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster public SessionOperations getOperation(Session session) {
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster if (isLocalServer(session)) {
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster return log(session, local);
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster }
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster if (service.isSessionFailoverEnabled()) {
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster // Cross talk is disabled.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster if (!service.isCrossTalkEnabled()) {
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster return log(session, cts);
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster }
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster // Remote Site which is known to be down
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster if (!isLocalSite(session) && !isSiteUp(getSiteId(session))) {
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster return log(session, cts);
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster }
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster }
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster return log(session, remote);
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster }
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster /**
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * Fetches the Site for a Session Server ID, based on the results of WebtopNaming.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * @param session A non null Session which may or may not be part of a Site.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster * @return Null if no Site ID was found, otherwise a non null Site ID.
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster */
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster private String getSiteId(Session session) {
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster String serverID = session.getID().getSessionServerID();
4fe4e4f798a84a46e567f64ceadd3648eb0582d4Allan Foster if (queryUtils.isSite(serverID)) {
return serverID;
}
return queryUtils.getSiteID(serverID);
}
/**
* Indicates that the Site associated with the Session is up.
*
* @param siteId Site ID to test if it is up. May be null, in which case
* false will be returned.
* @return False if the Site ID is null, or if the Site was down.
* True if the Site was up.
*/
private boolean isSiteUp(String siteId) {
if (siteId == null) {
return false;
}
return service.checkSiteUp(siteId);
}
/**
* Tests if the Session should be considered local.
*
* @param session Non null Session.
* @return True if it is based on the current server.
*/
private boolean isLocalServer(Session session) {
try {
return service.checkSessionLocal(session.getID());
} catch (SessionException e) {
throw new IllegalStateException(e);
}
}
/**
* Indicates that the Session belongs to a the local Site. That is, it is
* hosted on a Server within the current cluster.
*
* @param session Non null Session.
* @return True if the Session is considered local.
*/
private boolean isLocalSite(Session session) {
return service.isLocalSite(session.getID());
}
/**
* Inline logging function.
* @param session Non null.
* @param op Non null operation selected.
* @return op.
*/
private SessionOperations log(Session session, SessionOperations op) {
if (debug.messageEnabled()) {
debug.message(session + ": " + op.getClass().getSimpleName() + " selected.");
}
return op;
}
}