MultiServerClusterMonitor.java revision 1d407e39b7d8f68d9a2b1e178f35fab037d9835a
/**
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at opensso/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id: SessionService.java,v 1.37 2010/02/03 03:52:54 bina Exp $
*
* Portions Copyrighted 2010-2015 ForgeRock AS.
*/
/**
* API for querying status of servers in cluster.
*
* Extracted from SessionService class as part of first-pass refactoring to improve SessionService adherence to SRP.
*
* @since 13.0.0
*/
/*
* Further refactoring is warranted.
*/
public class MultiServerClusterMonitor implements ClusterMonitor {
private final SessionService sessionService;
private final Debug sessionDebug;
private final SessionServiceConfig serviceConfig;
private final SessionServerConfig serverConfig;
private final ConcurrentMap<String, String> clusterMemberMap = new ConcurrentHashMap<String, String>();
private final ClusterStateServiceFactory clusterStateServiceFactory;
/**
*
* @param sessionService
* @param sessionDebug
* @param serviceConfig
* @param serverConfig
* @throws Exception
*/
public MultiServerClusterMonitor(
}
/**
* Chained constructor to allow ClusterStateServiceFactory to be mocked from tests.
*/
if (!serviceConfig.isSessionFailoverEnabled()) {
throw new IllegalStateException("MultiServerClusterMonitoring only required if Session Fail-Over enabled.");
}
this.sessionService = sessionService;
this.sessionDebug = sessionDebug;
this.serviceConfig = serviceConfig;
this.serverConfig = serverConfig;
// Next, must be in this Order!
// Initialize our Cluster Member Map, first!
// Initialize the Cluster State Service, second!
// (As Cluster Service uses Cluster Member Map).
}
/**
* {@inheritDoc}
*/
}
/**
* {@inheritDoc}
*/
return ((serverID == null) || (serverID.isEmpty())) ? false : clusterStateService.checkServerUp(serverID);
}
/**
* {@inheritDoc}
*/
// Is this block necessary? Can locateCurrentHostServer ever return null?
return sid.getSessionServerID();
}
return serverID;
} else {
return sid.getSessionServerID();
}
}
/**
* Initialise the ClusterStateService to monitor all Servers within the current
* Site, and also all Sites except the current Site. This will allow the
* ClusterStateService to provide an answer to whether a Site is up or down.
*
* @throws Exception If there was an unexpected error during initialisation.
*/
private synchronized void initializeClusterService() throws Exception {
// Initialize Our Cluster State Service
// Ensure we place our Server in Member Map.
// Collect all Sites to monitor
// Instantiate the State Service.
clusterStateService = clusterStateServiceFactory.createClusterStateService(sessionService, serverConfig,
// Show our State Server Info Map
if (sessionDebug.messageEnabled()) {
"SessionService's ClusterStateService Initialized Successfully, " + clusterStateService.toString());
}
}
/**
* Obtain a mapping of site ID to primary URL for all other sites
*
* @return
*/
// Excluding the current local site, as it is not needed for intra-cluster failover.
continue;
}
}
}
return siteMemberMap;
}
/**
* Initialize the cluster server map given the server IDs in Set (AM70).
*/
private void initClusterMemberMap() throws Exception {
continue;
}
// ************************************************************
// This if Clause is very important, please do not think it is
// not. If we pollute the cluster map with duplicate URLs
// There is a very good chance Login processing will
// automatically fail, since it can not determine
// which serverId is which.
// Only Associate one Server URL to a Single ServerID.
// @since 10.1
//
// Further investigate, as we should not get duplicates here...
//
}
}
/**
* A convenience method to get the cluster server list in delimiter
* separated String format. This is currently used in message debug log.
*/
private String getClusterServerList() {
}
return clusterServerList.toString();
}
/**
* Determines current hosting server instance for internal request routing
* mode.
*
* @param sid session id
* @return server id for the server instance determined to be the current
* host
* @throws com.iplanet.dpro.session.SessionException
*/
// if this is our local Server
return serverID;
}
// if session is from remote site
return serverID;
}
// Ensure we have a Cluster State Service Available.
synchronized (this) {
if (clusterStateService == null) {
try {
} catch (Exception e) {
sessionDebug.error("Unable to Initialize the Cluster Service, please review Configuration settings.", e);
throw new SessionException(e);
}
}
}
// Check for Service Available.
return primaryID;
} else {
throw new SessionException("SessionService.locateCurrentHostServer: StorageKey is null");
}
for (int i = 0; i < selectionListSize; ++i) {
if (selectedServerId == null) {
continue;
}
break;
}
}
// since current server is also part of the selection list
// selection process is guaranteed to succeed
return selectedServerId;
}
}
/**
* Factory to allow ClusterStateService to be mocked from tests
*/
static class ClusterStateServiceFactory {
return new ClusterStateService(
}
}
/**
* Signals that this ClusterMonitor should be shutdown.
* Will signal the underlying {@link ClusterStateService} to cancel
* its runnable thread.
*
* Thread Safety: Synchronized to prevent possible multiple calls which
* would break state in the underlying GeneralRunnableTask framework.
*/
public synchronized void shutdown() {
}
}