/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) Ericsson AB, 2004-2008. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.jvnet.glassfish.comms.replication.sessmgmt;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.sip.*;
import javax.servlet.sip.Address;
import javax.servlet.sip.TimerListener;
import com.ericsson.ssa.sip.DialogSet;
import com.ericsson.ssa.sip.PathNode.Type;
import com.ericsson.ssa.sip.RemoteLockException;
import com.ericsson.ssa.sip.PersistentSipSessionManagerBase;
import com.ericsson.ssa.sip.SipApplicationSessionImpl;
import com.ericsson.ssa.sip.SipApplicationSessionUtil;
import com.ericsson.ssa.sip.SipSessionDialogImpl;
import com.ericsson.ssa.sip.timer.ServletTimerImpl;
import com.sun.appserv.ha.spi.BackingStore;
import com.sun.appserv.ha.spi.BackingStoreException;
import com.sun.appserv.ha.spi.BackingStoreFactory;
import com.sun.appserv.ha.spi.BackingStoreRegistry;
import com.sun.appserv.ha.util.SimpleMetadata;
import com.sun.appserv.ha.uow.ReplicableEntity;
import com.sun.appserv.util.cache.BaseCache;
import com.sun.enterprise.ee.web.sessmgmt.*;
import com.sun.enterprise.web.ServerConfigLookup;
import org.apache.catalina.Globals;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.security.SecurityUtil;
import org.jvnet.glassfish.comms.util.LogUtil;
import org.jvnet.glassfish.comms.replication.dialogmgmt.ReplicationDialogFragmentManager;
import org.jvnet.glassfish.comms.deployment.backend.SipApplication;
import org.jvnet.glassfish.comms.deployment.backend.SipBundleDescriptor;
public class SipTransactionPersistentManager
extends PersistentSipSessionManagerBase
implements ReplicationManager, DynamicOwnershipManager, PurgeCapable {
private static final Logger _logger = LogUtil.SSR_LOGGER.getLogger();
protected static final String MODE_SIP = ReplicationState.MODE_SIP;
protected static java.util.concurrent.atomic.AtomicLong unique =
new AtomicLong(0);
final static String DUPLICATE_IDS_SEMANTICS_PROPERTY
= ReplicationState.DUPLICATE_IDS_SEMANTICS_PROPERTY;
final static String COMMAND_MAP = "commandmap";
final static String SUPPRESS_LOAD_ACK_PROPERTY
= ReplicationState.SUPPRESS_LOAD_ACK_PROPERTY;
final static String REPLICATION_COMPRESSION_PROPERTY
= ReplicationState.REPLICATION_COMPRESSION_PROPERTY;
final static String SESSION_MANAGER_PROPERTY =
ReplicationState.SESSION_MANAGER_PROPERTY; // used during jxtabackingstore creation to store a reference to this session manager in jxtabackingstore.
final static String SIP_TYPE_SAS = "sip_type_sas";
final static String SIP_TYPE_SS = "sip_type_ss";
final static String SIP_TYPE_ST = "sip_type_st";
private static final Level TRACE_LEVEL = Level.FINE;
protected static int _maxBaseCacheSize = 4096;
protected static float _loadFactor = 0.75f;
protected static final int _concurrencyLevel = 100;
private static final long SLEEP_TIME = 30L * 1000L; //30 seconds
public final static String BEKEY
= ReplicationState.BEKEY;
private static boolean useReplicationUnicastLoadResponseBatching = false;
private static final Map sipApplicationSessionCommandMap = new HashMap();
private static final Map sipSessionCommandMap = new HashMap();
private static final Map servletTimerCommandMap = new HashMap();
public final static String SAVE_COMMAND
= ReplicationState.SAVE_COMMAND;
public final static String VALVE_SAVE_COMMAND
= ReplicationState.VALVE_SAVE_COMMAND;
public final static String REMOVE_COMMAND
= ReplicationState.REMOVE_COMMAND;
public final static String UNDEPLOY_COMMAND
= ReplicationState.UNDEPLOY_COMMAND;
public final static String REMOVE_EXPIRED_COMMAND
= ReplicationState.REMOVE_EXPIRED_COMMAND;
public final static String UPDATE_LAST_ACCESS_TIME_COMMAND
= ReplicationState.UPDATE_LAST_ACCESS_TIME_COMMAND;
public final static String MESSAGE_BROADCAST_QUERY
= ReplicationState.MESSAGE_BROADCAST_QUERY;
public final static String MESSAGE_BROADCAST_LOAD_RECEIVED
= ReplicationState.MESSAGE_BROADCAST_LOAD_RECEIVED;
public final static String MESSAGE_BROADCAST_LOAD_ADVISORY
= ReplicationState.MESSAGE_BROADCAST_LOAD_ADVISORY;
public final static String MESSAGE_BROADCAST_PURGE_ADVISORY
= ReplicationState.MESSAGE_BROADCAST_PURGE_ADVISORY;
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_ADVISORY
= "rollingupgradeadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_REPLICA_RECONCILIATION_COMPLETE_ADVISORY
= "rollingupgradereplicareconciliationcompleteadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RESTORATION_ADVISORY
= "rollingupgradesipapplicationsessionactivecacherestorationadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RESTORATION_RESPONSE
= "rollingupgradesipapplicationsessionactivecacherestorationresponse";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_ACTIVE_CACHE_RESTORATION_ADVISORY
= "rollingupgradesipsessionactivecacherestorationadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_ACTIVE_CACHE_RESTORATION_RESPONSE
= "rollingupgradesipsessionactivecacherestorationresponse";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_ACTIVE_CACHE_RESTORATION_ADVISORY
= "rollingupgradeservlettimeractivecacherestorationadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_ACTIVE_CACHE_RESTORATION_RESPONSE
= "rollingupgradeservlettimeractivecacherestorationresponse";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_REPLICA_CACHE_RESTORATION_ADVISORY
= "rollingupgradesipapplicationsessionreplicacacherestorationadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_REPLICA_CACHE_RESTORATION_RESPONSE
= "rollingupgradesipapplicationsessionreplicacacherestorationresponse";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_REPLICA_CACHE_RESTORATION_ADVISORY
= "rollingupgradesipsessionreplicacacherestorationadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_REPLICA_CACHE_RESTORATION_RESPONSE
= "rollingupgradesipsessionreplicacacherestorationresponse";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_REPLICA_CACHE_RESTORATION_ADVISORY
= "rollingupgradeservlettimerreplicacacherestorationadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_REPLICA_CACHE_RESTORATION_RESPONSE
= "rollingupgradeservlettimerreplicacacherestorationresponse";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RECONCILIATION_ADVISORY
= "rollingupgradegetidsforsipapplicationsessionactivecachereconciliationadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RECONCILIATION_RESPONSE
= "rollingupgradegetidsforsipapplicationsessionactivecachereconciliationresponse";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_SESSION_ACTIVE_CACHE_RECONCILIATION_ADVISORY
= "rollingupgradegetidsforsipsessionactivecachereconciliationadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_SESSION_ACTIVE_CACHE_RECONCILIATION_RESPONSE
= "rollingupgradegetidsforsipsessionactivecachereconciliationresponse";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SERVLET_TIMER_ACTIVE_CACHE_RECONCILIATION_ADVISORY
= "rollingupgradegetidsforservlettimeractivecachereconciliationadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SERVLET_TIMER_ACTIVE_CACHE_RECONCILIATION_RESPONSE
= "rollingupgradegetidsforservlettimeractivecachereconciliationresponse";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_APPLICATION_SESSION_REPLICA_CACHE_RECONCILIATION_ADVISORY
= "rollingupgradegetidsforsipapplicationsessionreplicacachereconciliationadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_APPLICATION_SESSION_REPLICA_CACHE_RECONCILIATION_RESPONSE
= "rollingupgradegetidsforsipapplicationsessionreplicacachereconciliationresponse";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_SESSION_REPLICA_CACHE_RECONCILIATION_ADVISORY
= "rollingupgradegetidsforsipsessionreplicacachereconciliationadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_SESSION_REPLICA_CACHE_RECONCILIATION_RESPONSE
= "rollingupgradegetidsforsipsessionreplicacachereconciliationresponse";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SERVLET_TIMER_REPLICA_CACHE_RECONCILIATION_ADVISORY
= "rollingupgradegetidsforservlettimerreplicacachereconciliationadvisory";
public final static String MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SERVLET_TIMER_REPLICA_CACHE_RECONCILIATION_RESPONSE
= "rollingupgradegetidsforservlettimerreplicacachereconciliationresponse";
public final static String SAVE_SAS_COMMAND = "savesas";
public final static String REMOVE_SAS_COMMAND = "removesas";
public final static String LOAD_SAS_COMMAND = "loadsas";
public final static String UPDATE_LAST_ACCESS_TIME_SAS_COMMAND
= "updatelastaccesstimesas";
public final static String MESSAGE_BROADCAST_QUERY_SAS
= "broadcastfindsas";
public final static String MESSAGE_BROADCAST_LOAD_RECEIVED_SAS
= "broadcastloadreceivedsas";
public final static String MESSAGE_LOAD_ADVISORY_SAS
= "loadadvisorysas";
public final static String MESSAGE_BROADCAST_EXPAT_QUERY_SAS
= "broadcastfindsasexpatids";
public final static String MESSAGE_BROADCAST_EXPAT_QUERY_SAS_REPLICA
= "broadcastfindsasreplicaexpatids";
public final static String MESSAGE_BROADCAST_EXPAT_RECEIVE_SAS
= "broadcastreceivesasexpatids";
public final static String MESSAGE_BROADCAST_EXPAT_RECEIVE_SAS_REPLICA
= "broadcastreceivesasreplicaexpatids";
public final static String SAVE_SIP_SESSION_COMMAND = "savesipsession";
public final static String REMOVE_SIP_SESSION_COMMAND = "removesipsession";
public final static String LOAD_SIP_SESSION_COMMAND = "loadsipsession";
public final static String UPDATE_LAST_ACCESS_TIME_SIP_SESSION_COMMAND
= "updatelastaccesstimesipsession";
public final static String MESSAGE_BROADCAST_QUERY_SIP_SESSION
= "broadcastfindsipsession";
public final static String MESSAGE_BROADCAST_LOAD_RECEIVED_SIP_SESSION
= "broadcastloadreceivedsipsession";
public final static String MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION
= "broadcastfindsipsessionexpatids";
public final static String MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION_REPLICA
= "broadcastfindsipsessionreplicaexpatids";
public final static String MESSAGE_BROADCAST_EXPAT_RECEIVE_SIP_SESSION
= "broadcastreceivesipsessionexpatids";
public final static String MESSAGE_BROADCAST_EXPAT_RECEIVE_SIP_SESSION_REPLICA
= "broadcastreceivesipsessionreplicaexpatids";
public final static String SAVE_SERVLET_TIMER_COMMAND
= "saveservlettimer";
public final static String REMOVE_SERVLET_TIMER_COMMAND
= "removeservlettimer";
public final static String LOAD_SERVLET_TIMER_COMMAND
= "loadservlettimer";
public final static String UPDATE_LAST_ACCESS_TIME_SERVLET_TIMER_COMMAND
= "updatelastaccesstimeservlettimer";
public final static String MESSAGE_BROADCAST_QUERY_SERVLET_TIMER
= "broadcastfindservlettimer";
public final static String MESSAGE_BROADCAST_LOAD_RECEIVED_SERVLET_TIMER
= "broadcastloadreceivedservlettimer";
public final static String MESSAGE_LOAD_ADVISORY_SERVLET_TIMER
= "loadadvisoryservlettimer";
public final static String MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER
= "broadcastfindservlettimerexpatids";
public final static String MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER_REPLICA
= "broadcastfindservlettimerreplicaexpatids";
public final static String MESSAGE_BROADCAST_EXPAT_RECEIVE_SERVLET_TIMER
= "broadcastreceiveservlettimerexpatids";
public final static String MESSAGE_BROADCAST_EXPAT_RECEIVE_SERVLET_TIMER_REPLICA
= "broadcastreceiveservlettimerreplicaexpatids";
private ReplicationUtil replicationUtil = null;
/**
* the list of method names that are broadcasts or unicasts
*/
private static List broadcastMethods
= Arrays.asList(
MESSAGE_BROADCAST_QUERY_SAS,
LOAD_SAS_COMMAND,
MESSAGE_BROADCAST_LOAD_RECEIVED_SAS,
MESSAGE_LOAD_ADVISORY_SAS,
MESSAGE_BROADCAST_EXPAT_QUERY_SAS,
MESSAGE_BROADCAST_EXPAT_QUERY_SAS_REPLICA,
MESSAGE_BROADCAST_EXPAT_RECEIVE_SAS,
MESSAGE_BROADCAST_EXPAT_RECEIVE_SAS_REPLICA,
MESSAGE_BROADCAST_QUERY_SIP_SESSION,
LOAD_SIP_SESSION_COMMAND,
MESSAGE_BROADCAST_LOAD_RECEIVED_SIP_SESSION,
MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION,
MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION_REPLICA,
MESSAGE_BROADCAST_EXPAT_RECEIVE_SIP_SESSION,
MESSAGE_BROADCAST_EXPAT_RECEIVE_SIP_SESSION_REPLICA,
MESSAGE_BROADCAST_QUERY_SERVLET_TIMER,
LOAD_SERVLET_TIMER_COMMAND,
MESSAGE_BROADCAST_LOAD_RECEIVED_SERVLET_TIMER,
MESSAGE_LOAD_ADVISORY_SERVLET_TIMER,
MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER,
MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER_REPLICA,
MESSAGE_BROADCAST_EXPAT_RECEIVE_SERVLET_TIMER,
MESSAGE_BROADCAST_ROLLING_UPGRADE_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RESTORATION_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RESTORATION_RESPONSE,
MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_ACTIVE_CACHE_RESTORATION_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_ACTIVE_CACHE_RESTORATION_RESPONSE,
MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_ACTIVE_CACHE_RESTORATION_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_ACTIVE_CACHE_RESTORATION_RESPONSE,
MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_REPLICA_CACHE_RESTORATION_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_REPLICA_CACHE_RESTORATION_RESPONSE,
MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_REPLICA_CACHE_RESTORATION_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_REPLICA_CACHE_RESTORATION_RESPONSE,
MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_REPLICA_CACHE_RESTORATION_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_REPLICA_CACHE_RESTORATION_RESPONSE,
MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RECONCILIATION_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RECONCILIATION_RESPONSE,
MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_SESSION_ACTIVE_CACHE_RECONCILIATION_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_SESSION_ACTIVE_CACHE_RECONCILIATION_RESPONSE,
MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SERVLET_TIMER_ACTIVE_CACHE_RECONCILIATION_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SERVLET_TIMER_ACTIVE_CACHE_RECONCILIATION_RESPONSE,
MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_APPLICATION_SESSION_REPLICA_CACHE_RECONCILIATION_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_APPLICATION_SESSION_REPLICA_CACHE_RECONCILIATION_RESPONSE,
MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_SESSION_REPLICA_CACHE_RECONCILIATION_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_SESSION_REPLICA_CACHE_RECONCILIATION_RESPONSE,
MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SERVLET_TIMER_REPLICA_CACHE_RECONCILIATION_ADVISORY,
MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SERVLET_TIMER_REPLICA_CACHE_RECONCILIATION_RESPONSE,
MESSAGE_BROADCAST_ROLLING_UPGRADE_REPLICA_RECONCILIATION_COMPLETE_ADVISORY);
/**
* the list of method names that are expensive
* i.e. should not run on single receiving thread
* e.g. load advisories when received trigger loads
* which should not occur on the same receiving thread
*/
private static List expensiveMethods
= Arrays.asList(
MESSAGE_LOAD_ADVISORY_SAS,
MESSAGE_BROADCAST_EXPAT_QUERY_SAS,
MESSAGE_BROADCAST_EXPAT_QUERY_SAS_REPLICA,
MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION,
MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION_REPLICA,
MESSAGE_LOAD_ADVISORY_SERVLET_TIMER,
MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER,
MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER_REPLICA,
MESSAGE_BROADCAST_EXPAT_RECEIVE_SAS,
MESSAGE_BROADCAST_EXPAT_RECEIVE_SAS_REPLICA,
MESSAGE_BROADCAST_EXPAT_RECEIVE_SIP_SESSION,
MESSAGE_BROADCAST_EXPAT_RECEIVE_SIP_SESSION_REPLICA,
MESSAGE_BROADCAST_EXPAT_RECEIVE_SERVLET_TIMER
);
/**
* the list of method names that are expensive
* i.e. should not run on single receiving thread
* e.g. load advisories when received trigger loads
* which should not occur on the same receiving thread
*/
private static List removeMethods
= Arrays.asList(
REMOVE_SAS_COMMAND,
REMOVE_SIP_SESSION_COMMAND,
REMOVE_SERVLET_TIMER_COMMAND);
private static List saveMethods
= Arrays.asList(
SAVE_SAS_COMMAND,
SAVE_SIP_SESSION_COMMAND,
SAVE_SERVLET_TIMER_COMMAND);
static {
checkSessionCacheProperties();
initializeCommandMaps();
registerBroadcastMethods();
registerExpensiveMethods();
registerRemoveMethods();
registerSaveMethods();
ServerConfigLookup lookup = new ServerConfigLookup();
useReplicationUnicastLoadResponseBatching
= lookup.isReplicationUnicastLoadResponseBatchingEnabled();
}
private SessionFactory sessionFactory;
private StorePool sipApplicationSessionStorePool;
private StorePool sipSessionStorePool;
private StorePool servletTimerStorePool;
private final String instanceName;
private ReplicationMessageRouter router;
protected AtomicBoolean _activeCacheReconciliationOngoing
= new AtomicBoolean(false);
protected ConcurrentHashMap stillOwnedSipApplicationSessionIdsForActiveCacheReconciliation = null;
protected ConcurrentHashMap stillOwnedSipSessionIdsForActiveCacheReconciliation = null;
protected ConcurrentHashMap stillOwnedServletTimerIdsForActiveCacheReconciliation = null;
private ReentrantReadWriteLock sasExpatReadWriteLock
= new ReentrantReadWriteLock();
private ReentrantReadWriteLock sipSessionExpatReadWriteLock
= new ReentrantReadWriteLock();
private ReentrantReadWriteLock servletTimerExpatReadWriteLock
= new ReentrantReadWriteLock();
protected String _rollingUpgradeBackupDirectory = null;
protected boolean _skipRollingUpgradeBackupRestore = false;
protected ConcurrentHashMap<String, ReplicationState> ownedReplicaListsReceivedForSipApplicationSessionActiveCacheRestoration = null;
protected ConcurrentHashMap<String, ReplicationState> ownedReplicaListsReceivedForSipSessionActiveCacheRestoration = null;
protected ConcurrentHashMap<String, ReplicationState> ownedReplicaListsReceivedForServletTimerActiveCacheRestoration = null;
protected ConcurrentHashMap<String, ReplicationState> ownedReplicaListsReceivedForSipApplicationSessionReplicaCacheRestoration = null;
protected ConcurrentHashMap<String, ReplicationState> ownedReplicaListsReceivedForSipSessionReplicaCacheRestoration = null;
protected ConcurrentHashMap<String, ReplicationState> ownedReplicaListsReceivedForServletTimerReplicaCacheRestoration = null;
protected ConcurrentHashMap<String, ReplicationState> ownedIdsForSipApplicationSessionActiveCacheReconciliation = null;
protected ConcurrentHashMap<String, ReplicationState> ownedIdsForSipSessionActiveCacheReconciliation = null;
protected ConcurrentHashMap<String, ReplicationState> ownedIdsForServletTimerActiveCacheReconciliation = null;
protected ConcurrentHashMap<String, ReplicationState> ownedIdsForSipApplicationSessionReplicaCacheReconciliation = null;
protected ConcurrentHashMap<String, ReplicationState> ownedIdsForSipSessionReplicaCacheReconciliation = null;
protected ConcurrentHashMap<String, ReplicationState> ownedIdsForServletTimerReplicaCacheReconciliation = null;
/**
* get the rollingUpgradeBackupDirectory
*/
public String getRollingUpgradeBackupDirectory() {
return _rollingUpgradeBackupDirectory;
}
/**
* set the rollingUpgradeBackupDirectory
* @param value
*/
public void setRollingUpgradeBackupDirectory(String value) {
_rollingUpgradeBackupDirectory = value;
}
/** should skip backup and restore step for rolling upgrade */
boolean isSkipRollingUpgradeBackupRestore() {
return _skipRollingUpgradeBackupRestore;
}
/**
* set the skipRollingUpgradeBackupRestore
* @param value
*/
public void setSkipRollingUpgradeBackupRestore(boolean value) {
_skipRollingUpgradeBackupRestore = value;
}
/**
* Our ReplicaCache - the receiving side for SipApplicationSession replicas
*/
protected ReplicaCache sipApplicationSessionReplicaCache = null;
/**
* Our ReplicaCache - the receiving side for SipSession replicas
*/
protected ReplicaCache sipSessionReplicaCache = null;
/**
* Our ReplicaCache - the receiving side for ServletTimer replicas
*/
protected ReplicaCache servletTimerReplicaCache = null;
/**
* Our cache of monitor objects
* keyed by id
*/
protected ReplicationSessionMonitors replicatedSessionMonitors = null;
/**
* Our Replicator instance for SipApplicationSessions (for SimpleMetadata)
*/
protected BackingStore sipApplicationSessionBackingStore = null;
/**
* Our Replicator instance SipSessions (for SimpleMetadata)
*/
protected BackingStore sipSessionBackingStore = null;
/**
* Our Replicator instance for ServletTimers (for SimpleMetadata)
*/
protected BackingStore servletTimerBackingStore = null;
protected String _passedInPersistenceType = null;
protected boolean _duplicateIdsSemanticsAllowed = false;
private ActivationHelper activationHelper;
private volatile HashMap<String, ExpatListElement> sasExpatIdsMap =
new HashMap<String, ExpatListElement>();
private volatile HashMap<String, ExpatListElement> sipSessionExpatIdsMap =
new HashMap<String, ExpatListElement>();
private volatile HashMap<String, ExpatListElement> servletTimerExpatIdsMap =
new HashMap<String, ExpatListElement>();
private boolean hasCheckedIfReady = false;
ExpatListHandler sasExpatListHandler;
ExpatListHandler sipSessionExpatListHandler;
ExpatListHandler servletTimerExpatListHandler;
ExpatListHandler sasReplicaExpatHandler;
ExpatListHandler ssReplicaExpatHandler;
ExpatListHandler stReplicaExpatHandler;
private HashMap<String,String> lastSasExpatQueryId
= new HashMap<String,String>();
private HashMap<String,String> lastSipSessionExpatQueryId
= new HashMap<String,String>();
private HashMap<String,String> lastServletTimerExpatQueryId
= new HashMap<String,String>();
private volatile CountDownLatch reconcileReplicaCacheDoneSignal = null;
private volatile CountDownLatch restoreSipApplicationSessionActiveCacheDoneSignal = null;
private volatile CountDownLatch restoreSipSessionActiveCacheDoneSignal = null;
private volatile CountDownLatch restoreServletTimerActiveCacheDoneSignal = null;
private volatile CountDownLatch restoreSipApplicationSessionReplicaCacheDoneSignal = null;
private volatile CountDownLatch restoreSipSessionReplicaCacheDoneSignal = null;
private volatile CountDownLatch restoreServletTimerReplicaCacheDoneSignal = null;
private volatile CountDownLatch getIdsForSipApplicationSessionActiveCacheReconciliationDoneSignal = null;
private volatile CountDownLatch getIdsForSipSessionActiveCacheReconciliationDoneSignal = null;
private volatile CountDownLatch getIdsForServletTimerActiveCacheReconciliationDoneSignal = null;
private volatile CountDownLatch getIdsForSipApplicationSessionReplicaCacheReconciliationDoneSignal = null;
private volatile CountDownLatch getIdsForSipSessionReplicaCacheReconciliationDoneSignal = null;
private volatile CountDownLatch getIdsForServletTimerReplicaCacheReconciliationDoneSignal = null;
/**
* There are 3 request/responses for each artifact :
*
* (a) active reconciliation
* (b) replica reconciliation
* (c) post active reconciliation.
*
* These are separated instead of one because, only (a) is applicable for
* third party backing stores. Whereas, in-memory needs all 3 steps.
*/
public static final String RECONCILE_SAS_REQUEST =
"reconcilesasrequest";
public static final String RECONCILE_SAS_RESPONSE =
"reconcilesasresponse";
public static final String RECONCILE_SAS_REPLICA_REQUEST =
"reconcilesasreplicarequest";
public static final String RECONCILE_SAS_REPLICA_RESPONSE =
"reconcilesasreplicaresponse";
public static final String POST_RECONCILE_SAS_REQUEST =
"postreconcilesasrequest";
public static final String POST_RECONCILE_SAS_RESPONSE =
"postreconcilesasresponse";
public static final String RECONCILE_SIPSESSION_REQUEST =
"reconcilesipsessionrequest";
public static final String RECONCILE_SIPSESSION_RESPONSE =
"reconcilesipsessionresponse";
public static final String RECONCILE_SIPSESSION_REPLICA_REQUEST =
"reconcilesipsessionreplicarequest";
public static final String RECONCILE_SIPSESSION_REPLICA_RESPONSE =
"reconcilesipsessionreplicaresponse";
public static final String POST_RECONCILE_SIPSESSION_REQUEST =
"postreconcilesipsessionrequest";
public static final String POST_RECONCILE_SIPSESSION_RESPONSE =
"postreconcilesipsessionresponse";
public static final String RECONCILE_SERVLETTIMER_REQUEST =
"reconcileservlettimerrequest";
public static final String RECONCILE_SERVLETTIMER_RESPONSE =
"reconcileservlettimerresponse";
public static final String RECONCILE_SERVLETTIMER_REPLICA_REQUEST =
"reconcileservlettimerreplicarequest";
public static final String RECONCILE_SERVLETTIMER_REPLICA_RESPONSE =
"reconcileservlettimerreplicaresponse";
public static final String POST_RECONCILE_SERVLETTIMER_REQUEST =
"postreconcileservlettimerrequest";
public static final String POST_RECONCILE_SERVLETTIMER_RESPONSE =
"postreconcileservlettimerresponse";
/**
* similary there are 3 countdownlatches for each artifact, and 2 responses
* for each artifact. (c) does not have a response, but only signals the
* completion of the (c) in all other instances.
*/
private volatile AtomicReference<CountDownLatch> activeSasReconcileSignal =
new AtomicReference<CountDownLatch>();
private volatile AtomicReference<CountDownLatch> replicaSasReconcileSignal =
new AtomicReference<CountDownLatch>();
private volatile AtomicReference<CountDownLatch> postSasReconcileSignal =
new AtomicReference<CountDownLatch>();
private volatile Map<String, ReplicationState> reconciledActiveSases =
new HashMap<String, ReplicationState>();
private volatile Map<String, ReplicationState> reconciledReplicaSases =
new HashMap<String, ReplicationState>();
private volatile Map<String, ReplicationState> remotelyLockedSases =
new HashMap<String, ReplicationState>();
private volatile AtomicReference<CountDownLatch> activeSipSessionReconcileSignal =
new AtomicReference<CountDownLatch>();
private volatile AtomicReference<CountDownLatch> replicaSipSessionReconcileSignal =
new AtomicReference<CountDownLatch>();
private volatile AtomicReference<CountDownLatch> postSipSessionReconcileSignal =
new AtomicReference<CountDownLatch>();
private volatile Map<String, ReplicationState> reconciledActiveSipSessions =
new HashMap<String, ReplicationState>();
private volatile Map<String, ReplicationState> reconciledReplicaSipSessions =
new HashMap<String, ReplicationState>();
private volatile Map<String, ReplicationState> remotelyLockedSipSessions =
new HashMap<String, ReplicationState>();
private volatile AtomicReference<CountDownLatch> activeServletTimerReconcileSignal =
new AtomicReference<CountDownLatch>();
private volatile AtomicReference<CountDownLatch> replicaServletTimerReconcileSignal =
new AtomicReference<CountDownLatch>();
private volatile AtomicReference<CountDownLatch> postServletTimerReconcileSignal =
new AtomicReference<CountDownLatch>();
private volatile Map<String, ReplicationState> reconciledActiveServletTimers =
new HashMap<String, ReplicationState>();
private volatile Map<String, ReplicationState> reconciledReplicaServletTimers =
new HashMap<String, ReplicationState>();
private volatile Map<String, ReplicationState> remotelyLockedServletTimers =
new HashMap<String, ReplicationState>();
private boolean appContainsHttpServlets;
/** Creates a new instance of ReplicationManagerBase */
public SipTransactionPersistentManager() {
super();
replicatedSessionMonitors = new ReplicationSessionMonitors(_logger, _maxBaseCacheSize, _loadFactor);
instanceName = ReplicationUtil.getInstanceName();
activationHelper = new ActivationHelper(this);
if (Globals.IS_SECURITY_ENABLED) {
router = (ReplicationMessageRouter)
AccessController.doPrivileged(
new PrivilegedGetReplicationMessageRouter());
} else {
router = ReplicationMessageRouter.createInstance();
}
ServerConfigLookup lookup = new ServerConfigLookup();
replicationCompressionEnabled = lookup.isReplicationCompression();
replicationUtil = ReplicationUtil.createReplicationUtil();
}
protected static boolean checkSessionCacheProperties() {
boolean result = false;
try {
Properties props = System.getProperties();
String cacheSize = props.getProperty(
"HTTP_SESSION_CACHE_MAX_BASE_CACHE_SIZE");
if (null != cacheSize) {
_maxBaseCacheSize = (new Integer(cacheSize).intValue());
}
String loadFactor = props.getProperty(
"HTTP_SESSION_CACHE_MAX_BASE_LOAD_FACTOR");
if (null != loadFactor) {
_loadFactor = (new Float(loadFactor).floatValue());
}
} catch (Exception e) {
//do nothing accept defaults
}
return result;
}
protected static void initializeCommandMaps() {
sipApplicationSessionCommandMap.put(SAVE_COMMAND, SAVE_SAS_COMMAND);
sipSessionCommandMap.put(SAVE_COMMAND, SAVE_SIP_SESSION_COMMAND);
servletTimerCommandMap.put(SAVE_COMMAND, SAVE_SERVLET_TIMER_COMMAND);
sipApplicationSessionCommandMap.put(VALVE_SAVE_COMMAND, SAVE_SAS_COMMAND);
sipSessionCommandMap.put(VALVE_SAVE_COMMAND, SAVE_SIP_SESSION_COMMAND);
servletTimerCommandMap.put(VALVE_SAVE_COMMAND, SAVE_SERVLET_TIMER_COMMAND);
sipApplicationSessionCommandMap.put(REMOVE_COMMAND, REMOVE_SAS_COMMAND);
sipSessionCommandMap.put(REMOVE_COMMAND, REMOVE_SIP_SESSION_COMMAND);
servletTimerCommandMap.put(REMOVE_COMMAND, REMOVE_SERVLET_TIMER_COMMAND);
sipApplicationSessionCommandMap.put(UPDATE_LAST_ACCESS_TIME_COMMAND, UPDATE_LAST_ACCESS_TIME_SAS_COMMAND);
sipSessionCommandMap.put(UPDATE_LAST_ACCESS_TIME_COMMAND, UPDATE_LAST_ACCESS_TIME_SIP_SESSION_COMMAND);
servletTimerCommandMap.put(UPDATE_LAST_ACCESS_TIME_COMMAND, UPDATE_LAST_ACCESS_TIME_SERVLET_TIMER_COMMAND);
sipApplicationSessionCommandMap.put(MESSAGE_BROADCAST_QUERY, MESSAGE_BROADCAST_QUERY_SAS);
sipSessionCommandMap.put(MESSAGE_BROADCAST_QUERY, MESSAGE_BROADCAST_QUERY_SIP_SESSION);
servletTimerCommandMap.put(MESSAGE_BROADCAST_QUERY, MESSAGE_BROADCAST_QUERY_SERVLET_TIMER);
sipApplicationSessionCommandMap.put(MESSAGE_BROADCAST_LOAD_RECEIVED, MESSAGE_BROADCAST_LOAD_RECEIVED_SAS);
sipSessionCommandMap.put(MESSAGE_BROADCAST_LOAD_RECEIVED, MESSAGE_BROADCAST_LOAD_RECEIVED_SIP_SESSION);
servletTimerCommandMap.put(MESSAGE_BROADCAST_LOAD_RECEIVED, MESSAGE_BROADCAST_LOAD_RECEIVED_SERVLET_TIMER);
}
private static ReplicationMessageRouter getRouter() {
ReplicationMessageRouter receiver = null;
if (Globals.IS_SECURITY_ENABLED) {
receiver = (ReplicationMessageRouter)
AccessController.doPrivileged(
new PrivilegedGetReplicationMessageRouter());
} else {
receiver = ReplicationMessageRouter.createInstance();
}
return receiver;
}
protected static void registerBroadcastMethods() {
ReplicationMessageRouter router = getRouter();
router.registerBroadcastMethodList(broadcastMethods);
}
protected static void registerExpensiveMethods() {
ReplicationMessageRouter router = getRouter();
router.registerExpensiveMethodList(expensiveMethods);
}
protected static void registerRemoveMethods() {
ReplicationMessageRouter router = getRouter();
router.registerRemoveMethodList(removeMethods);
}
protected static void registerSaveMethods() {
ReplicationMessageRouter router = getRouter();
router.registerSaveMethodList(saveMethods);
}
/**
* Checks if this manager is ready to perform its tasks.
*/
public void checkIfReady() {
if (!hasCheckedIfReady) {
checkIsInstanceStarted();
checkAppDeployment(this.getApplicationId());
hasCheckedIfReady = true;
}
}
public void checkIsInstanceStarted() {
long startTime = System.currentTimeMillis();
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
long sleepTime = 100L;
boolean shouldContinue = true;
while(shouldContinue) {
if((System.currentTimeMillis() - startTime) > 60000) {
_logger.warning("checkIsInstanceStarted: Timed out");
shouldContinue = false;
break;
}
boolean startStatus = healthChecker.isInstanceStarted();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("instance started: " + startStatus);
}
if(startStatus) {
shouldContinue = false;
} else {
try {
Thread.currentThread().sleep(sleepTime);
} catch (InterruptedException ex) {
;
}
}
sleepTime *= 2;
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("checkIsInstanceStarted for took " + (System.currentTimeMillis() - startTime) + "ms");
}
}
public void checkAppDeployment(String applicationId) {
long startTime = System.currentTimeMillis();
ApplicationStatusChecker appStatusChecker
= new ApplicationStatusChecker();
long sleepTime = 100L;
boolean shouldContinue = true;
while(shouldContinue) {
if((System.currentTimeMillis() - startTime) > 60000) {
_logger.warning("checkAppDeployment: Timed out waiting for replicas application" + applicationId + " to finished deploying");
shouldContinue = false;
break;
}
boolean appStatus = appStatusChecker.isApplicationDeployed(applicationId, "WEB");
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("app:" + applicationId + " isDeployed: " + appStatus);
}
if(appStatus) {
shouldContinue = false;
} else {
try {
Thread.currentThread().sleep(sleepTime);
} catch (InterruptedException ex) {
;
}
}
sleepTime *= 2;
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("checkAppDeployment for application " + applicationId + "took " + (System.currentTimeMillis() - startTime) + "ms");
}
}
boolean replicationCompressionEnabled = false;
boolean isReplicationCompressionEnabled() {
return replicationCompressionEnabled;
}
private void getBackingStores() {
// create backing stores so that the replica expat handlers get created
// well in advance. Otherwise the expat pushed by remote instances
// might get missed out. That can happen in the restarted instance.
try {
getSipApplicationSessionBackingStore();
getSipSessionBackingStore();
getServletTimerBackingStore();
((ReplicationDialogFragmentManager) com.ericsson.ssa.sip.DialogFragmentManager.getInstance()).
getDialogFragmentBackingStore();
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Starts this SipTransactionPersistentManager.
*/
public void start() throws LifecycleException {
super.start();
sasExpatListHandler = ExpatListHandler.getExpatListHandler(this, getApplicationId(),
MESSAGE_BROADCAST_EXPAT_QUERY_SAS, MODE_SIP, "SASActive");
sipSessionExpatListHandler = ExpatListHandler.getExpatListHandler(this, getApplicationId(),
MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION, MODE_SIP, "SipSessionActive");
servletTimerExpatListHandler = ExpatListHandler.getExpatListHandler(this, getApplicationId(),
MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER, MODE_SIP, "ServletTimerActive");
router.addReplicationManager(this.getApplicationId(), this);
getBackingStores();
checkIfReady();
//FIXME: this is for testing
//will eventually be triggered by separate admin command
//if(ReplicationUtil.isRollingUpgradeEnabled()) {
//CountDownLatch doneSignal = new CountDownLatch(1);
//doRollingUpgradePostStartupProcessing(System.currentTimeMillis(), doneSignal);
//}
appContainsHttpServlets = convergedContext.containsHttpServlets();
}
/**
* Stops this SipTransactionPersistentManager.
*/
public void stop() throws LifecycleException {
activationHelper.cancelAllMigrationTasks();
router.removeReplicationManager(this.getApplicationId());
super.stop();
}
/**
* Releases any resources held by this SipSessionManager.during
* undeployment.
*/
public void release() {
super.release();
if (stillOwnedSipApplicationSessionIdsForActiveCacheReconciliation != null) {
stillOwnedSipApplicationSessionIdsForActiveCacheReconciliation.clear();
stillOwnedSipApplicationSessionIdsForActiveCacheReconciliation = null;
}
if (stillOwnedSipSessionIdsForActiveCacheReconciliation != null) {
stillOwnedSipSessionIdsForActiveCacheReconciliation.clear();
stillOwnedSipSessionIdsForActiveCacheReconciliation = null;
}
if (stillOwnedServletTimerIdsForActiveCacheReconciliation != null) {
stillOwnedServletTimerIdsForActiveCacheReconciliation.clear();
stillOwnedServletTimerIdsForActiveCacheReconciliation = null;
}
if (sipApplicationSessionReplicaCache != null) {
sipApplicationSessionReplicaCache.release();
}
if (sipSessionReplicaCache != null) {
sipSessionReplicaCache.release();
}
if (servletTimerReplicaCache != null) {
servletTimerReplicaCache.release();
}
if (sipApplicationSessionStorePool != null) {
sipApplicationSessionStorePool.clear();
sipApplicationSessionStorePool = null;
}
if (sipSessionStorePool != null) {
sipSessionStorePool.clear();
sipSessionStorePool = null;
}
if (servletTimerStorePool != null) {
servletTimerStorePool.clear();
servletTimerStorePool = null;
}
destroyBackingStores();
}
private void destroyBackingStores() {
try {
if(sipApplicationSessionBackingStore != null) {
sipApplicationSessionBackingStore.destroy();
}
if(sipSessionBackingStore != null) {
sipSessionBackingStore.destroy();
}
if(servletTimerBackingStore != null) {
servletTimerBackingStore.destroy();
}
} catch(Exception ex) {
}
}
/**
* get the backingStore for SipApplicationSession
*/
public BackingStore getSipApplicationSessionBackingStore() {
if(sipApplicationSessionBackingStore == null) {
sipApplicationSessionBackingStore = this.createBackingStore(sipApplicationSessionCommandMap, SIP_TYPE_SAS);
}
return sipApplicationSessionBackingStore;
}
/**
* get the backingStore for SipSession
*/
public BackingStore getSipSessionBackingStore() {
if(sipSessionBackingStore == null) {
sipSessionBackingStore = this.createBackingStore(sipSessionCommandMap, SIP_TYPE_SS);
}
return sipSessionBackingStore;
}
/**
* get the backingStore for ServletTimer
*/
public BackingStore getServletTimerBackingStore() {
if(servletTimerBackingStore == null) {
servletTimerBackingStore = this.createBackingStore(servletTimerCommandMap, SIP_TYPE_ST);
}
return servletTimerBackingStore;
}
/**
* create and set the backing store
* @param commandMap map used to translate commands
*/
BackingStore createBackingStore(Map commandMap, String sipType) {
BackingStoreFactory storeFactory = new JxtaBackingStoreFactory();
BackingStoreRegistry backingStoreRegistry
= BackingStoreRegistry.getInstance();
Properties inputEnv
= backingStoreRegistry.getFactoryClassEnv(getPassedInPersistenceType());
Properties env = (Properties)inputEnv.clone();
//does this manager & backing store support duplicate id semantics
//for batch replication usage
env.put(DUPLICATE_IDS_SEMANTICS_PROPERTY, Boolean.valueOf(this.isDuplicateIdsSemanticsAllowed()));
env.put(COMMAND_MAP, commandMap);
if(sipType != null && (sipType.equals(SIP_TYPE_SAS) || sipType.equals(SIP_TYPE_SS) || sipType.equals(SIP_TYPE_ST))) {
env.put(SUPPRESS_LOAD_ACK_PROPERTY, Boolean.TRUE);
}
//does this manager & backing store support replication compression
env.put(REPLICATION_COMPRESSION_PROPERTY, Boolean.valueOf(this.isReplicationCompressionEnabled()));
env.put(SESSION_MANAGER_PROPERTY, this);
BackingStore backingStore = null;
try {
backingStore = storeFactory.createBackingStore(
this.getApplicationId(), //appid
String.class,
SimpleMetadata.class, //type
env);
} catch (BackingStoreException ex) {
//deliberate no-op
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("backingStore: " + backingStore);
}
if(backingStore != null) {
if(backingStore instanceof JxtaBackingStoreImpl) {
((JxtaBackingStoreImpl)backingStore).setMode(MODE_SIP);
}
}
return backingStore;
}
public void __createStoreExpatHandler(JxtaBackingStoreImpl jxtaBackingStore) {
// this method is called from JxtaBackingStoreImpl's constructor, so never
// use this : if(jxtaBackingStore == sipApplicationSessionBackingStore)
if (SAVE_SAS_COMMAND.equals(jxtaBackingStore.getCommand(SAVE_COMMAND))) {
if (sasReplicaExpatHandler == null) {
sasReplicaExpatHandler = ExpatListHandler.getExpatListHandler(
this, getApplicationId(),
MESSAGE_BROADCAST_EXPAT_QUERY_SAS_REPLICA, MODE_SIP, "SASReplica");
}
} else
if (SAVE_SIP_SESSION_COMMAND.equals(jxtaBackingStore.getCommand(SAVE_COMMAND))) {
// initialize ssReplicaExpatHandler for the first time.
if (ssReplicaExpatHandler == null) {
ssReplicaExpatHandler = ExpatListHandler.getExpatListHandler(
this, getApplicationId(),
MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION_REPLICA, MODE_SIP,
"SipSessionReplica");
}
} else
if (SAVE_SERVLET_TIMER_COMMAND.equals(jxtaBackingStore.getCommand(SAVE_COMMAND))) {
// initialize stReplicaExpatHandler for the first time.
stReplicaExpatHandler = ExpatListHandler.getExpatListHandler(
this, getApplicationId(),
MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER_REPLICA, MODE_SIP,
"ServletTimerReplica");
}
}
public boolean isDuplicateIdsSemanticsAllowed() {
return _duplicateIdsSemanticsAllowed;
}
public void setDuplicateIdsSemanticsAllowed(boolean value) {
_duplicateIdsSemanticsAllowed = value;
}
public String getPassedInPersistenceType() {
return _passedInPersistenceType;
}
public void setPassedInPersistenceType(String persistenceType) {
_passedInPersistenceType = persistenceType;
}
public void setSipApplicationSessionReplicaCache(ReplicaCache sasReplicaCache) {
sipApplicationSessionReplicaCache = sasReplicaCache;
}
public void setSipSessionReplicaCache(ReplicaCache ssReplicaCache) {
sipSessionReplicaCache = ssReplicaCache;
}
public void setServletTimerReplicaCache(ReplicaCache stReplicaCache) {
servletTimerReplicaCache = stReplicaCache;
}
public boolean isActiveCacheReconciliationOngoing() {
return _activeCacheReconciliationOngoing.get();
}
public void setActiveCacheReconciliationOngoing(boolean value) {
_activeCacheReconciliationOngoing.set(value);
}
//SAS cache methods
public Object getReplicationSessionMonitor(String id) {
return replicatedSessionMonitors.get(id);
}
/**
* Purges any expired SIP artifacts from this manager's active caches and
* persistent stores as a periodic task.
*/
public void backgroundProcess() {
super.backgroundProcess();
replicatedSessionMonitors.processExpired();
sipApplicationSessionReplicaCache.processExpiredReplicaRemovals();
sipSessionReplicaCache.processExpiredReplicaRemovals();
servletTimerReplicaCache.processExpiredReplicaRemovals();
}
/**
* get the replicated SipApplicationSessions cache
*/
public BaseCache getReplicatedSipApplicationSessions() {
return sipApplicationSessionReplicaCache.getReplicatedSessions();
}
/**
* Put session State in SipApplicationSession replica cache
* @param sessionState
*/
protected void putInSipApplicationSessionReplicationCache(ReplicationState sessionState) {
sipApplicationSessionReplicaCache.putInReplicationCache(sessionState);
}
/**
* get SipApplicationSession State from replica cache based on the id
* @param id
*/
protected ReplicationState getFromSipApplicationSessionReplicationCache(String id) {
return sipApplicationSessionReplicaCache.getFromReplicationCache(id);
}
/**
* remove session State from replica cache based on the id
* @param id
*/
protected ReplicationState removeFromSipApplicationSessionReplicationCache(String id) {
return sipApplicationSessionReplicaCache.removeFromReplicationCache(id);
}
//SS cache methods
/**
* get the replicated SipSessions cache
*/
public BaseCache getReplicatedSipSessions() {
return sipSessionReplicaCache.getReplicatedSessions();
}
/**
* Put session State in SipApplicationSession replica cache
* @param sessionState
*/
protected void putInSipSessionReplicationCache(ReplicationState sessionState) {
sipSessionReplicaCache.putInReplicationCache(sessionState);
}
/**
* get SipSession State from replica cache based on the id
* @param id
*/
protected ReplicationState getFromSipSessionReplicationCache(String id) {
return sipSessionReplicaCache.getFromReplicationCache(id);
}
/**
* remove session State from replica cache based on the id
* @param id
*/
protected ReplicationState removeFromSipSessionReplicationCache(String id) {
return sipSessionReplicaCache.removeFromReplicationCache(id);
}
//ServletTimer cache methods
/**
* get the replicated ServletTimers cache
*/
public BaseCache getReplicatedServletTimers() {
return servletTimerReplicaCache.getReplicatedSessions();
}
/**
* Put session timer State in ServletTimers replica cache
* @param sessionState
*/
protected void putInServletTimerReplicationCache(ReplicationState sessionState) {
servletTimerReplicaCache.putInReplicationCache(sessionState);
}
/**
* get ServletTimer State from replica cache based on the id
* @param id
*/
protected ReplicationState getFromServletTimerReplicationCache(String id) {
return servletTimerReplicaCache.getFromReplicationCache(id);
}
/**
* remove servlet timer State from replica cache based on the id
* @param id
*/
protected ReplicationState removeFromServletTimerReplicationCache(String id) {
return servletTimerReplicaCache.removeFromReplicationCache(id);
}
//end cache methods
//start receiver side process methods
//SipApplicationSession process methods
/**
* process the save of a SipApplicationSession
* @param sessionState - contains the save command
*/
public void processSavesas(ReplicationState sessionState) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN" + this.getClass().getName() + ">>processSavesas");
}
this.putInSipApplicationSessionReplicationCache(sessionState);
}
private void doLoadAdvisoryTest(ReplicationState sessionState) {
//start load advisory test
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String partnerInstanceName
= healthChecker.getReshapeReplicateToInstanceName(null, 3000L);
try {
sendLoadAdvisorySipApplicationSession((String)sessionState.getId(), partnerInstanceName);
} catch (Throwable th) {
_logger.log(Level.INFO, "error during load advisory test to " + partnerInstanceName, th);
}
//end load advisory test
}
private ReplicationState doUnicastLoadTest(HASipApplicationSession sas) {
//start unicast load test
ReplicationState resultState = null;
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String partnerInstanceName
= healthChecker.getReshapeReplicateToInstanceName(null, 3000L);
SipApplicationSessionStoreImpl sasStore = this.getSingletonSipApplicationSessionStore();
try {
resultState = sasStore.sendUnicastLoadQuery((String)sas.getId(), "" + sas.getVersion(), partnerInstanceName);
} catch (Throwable th) {
_logger.log(Level.INFO, "error during unicast load test to " + partnerInstanceName, th);
}
return resultState;
//end unicast load test
}
private ReplicationState doUnicastLoadTest(HASipSession ss) {
//start unicast load test
ReplicationState resultState = null;
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String partnerInstanceName
= healthChecker.getReshapeReplicateToInstanceName(null, 3000L);
SipSessionStoreImpl ssStore = this.getSingletonSipSessionStore();
try {
resultState = ssStore.sendUnicastLoadQuery((String)ss.getId(), "" + ss.getVersion(), partnerInstanceName);
} catch (Throwable th) {
_logger.log(Level.INFO, "error during unicast load test to " + partnerInstanceName, th);
}
return resultState;
//end unicast load test
}
/**
* process the removal of a SipApplicationSession
* @param sessionState - contains the remove command
*/
public void processRemovesas(ReplicationState sessionState) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN" + this.getClass().getName() + ">>processRemovesas");
}
if(sessionState == null) {
return;
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN" + this.getClass().getName() + ">>processRemovesas - originating instanceName = " + sessionState.getInstanceName());
}
if (sessionState.getState() != null) {
processBulkRemoveSAS(sessionState);
return;
}
String id = (String)sessionState.getId();
activationHelper.unregisterSasTimerMigrationTask(id);
//keep track of recent removals
sipApplicationSessionReplicaCache.removeFromReplicationCache(id);
//do the cyclical remove if not fronted by CLB
if (!SipReplicationUtil.isInstanceLoadBalancedByCLB()) {
int cycleCount = 0;
String cycleCountString = sessionState.getExtraParam();
if(cycleCountString != null) {
try {
cycleCount = Integer.parseInt(cycleCountString);
} catch (Exception ex) {
//ignore
}
}
cycleRemoveSipApplicationSession(id, sessionState.getInstanceName(), (cycleCount + 1));
}
}
public void processBulkRemoveSipSession(ReplicationState replicationState) {
sipSessionReplicaCache.removeFromReplicationCache(
replicationState.getState());
}
public void processBulkRemoveSAS(ReplicationState replicationState) {
sipApplicationSessionReplicaCache.removeFromReplicationCache(
replicationState.getState());
}
/**
* process the update of a SipApplicationSession
* @param sessionState - contains the updatelastaccesstime command
*/
public void processUpdatelastaccesstimesas(ReplicationState sessionState) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN" + this.getClass().getName() +
">>processUpdatelastaccesstimesas:id: " +
sessionState.getId() + ", version: " +
sessionState.getVersion());
}
sipApplicationSessionReplicaCache.processUpdatelastaccesstime(sessionState);
}
/**
* Find the SAS in the active cache, and passivate it. Passivation will
* remove the SAS from the active cache.
* @param id sip application session id
* @param cachedSASIsLocal whether the SAS still maps to this instance.
* @return SAS found in the active cache, null otherwise.
*/
public ReplicableEntity findSasAndPassivate(String id,
AtomicBoolean cachedSASIsLocal) {
cachedSASIsLocal.set(false);
HASipApplicationSession haSipApplicationSession = null;
SipApplicationSessionImpl sipApplicationSession
= findSipApplicationSessionFromCacheOnly(id);
if (sipApplicationSession instanceof HASipApplicationSession) {
haSipApplicationSession = (HASipApplicationSession) sipApplicationSession;
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
SipReplicationUtil.isLocal(haSipApplicationSession.getId())) {
cachedSASIsLocal.set(true);
} else {
// We have active SAS, but we no longer are its rightful
// owner, i.e., it is ok for us to let go of the active SAS
// and let it migrate to its new rightful owner.
try {
boolean foregroundLocked =
haSipApplicationSession.isForegroundLocked();
// Give
// passivation listeners "last-minute" opportunity to make
// any changes to the SAS before it is migrated
haSipApplicationSession.notifyWillPassivate();
// If we weren't foreground locked, then safe to remove
// from our active cache
if (!foregroundLocked)
processLoadReceivedSas(haSipApplicationSession.getId());
} catch (Throwable t) {
// Catch any Throwable (e.g., IllegalStateException if
// SAS is no longer valid, see IT 1484).
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"Exception seen during passivation of " +
"SipApplicationSession with id: " +
haSipApplicationSession.getId(),
t);
}
}
}
}
return haSipApplicationSession;
}
public Map getActiveApplicationSessions() {
return applicationSessions;
}
public Map getActiveSipSessions() {
return sipSessions;
}
public Map getActiveServletTimers() {
return servletTimers;
}
/**
* process the Findsas for SipApplicationSession
* @param queryState
* @param useUnicast
*/
public ReplicationState processFindSas(ReplicationState queryState, boolean useUnicast) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processFindSas:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processFindSas:id=" + queryState.getId());
_logger.fine("in " + this.getClass().getName() + ">>processFindSas:useUnicast=" + useUnicast);
}
//look in active cache
AtomicBoolean cachedSASIsLocal = new AtomicBoolean();
HASipApplicationSession haSipApplicationSession = (HASipApplicationSession)
findSasAndPassivate((String)queryState.getId(), cachedSASIsLocal);
//look in replica cache
ReplicationState replicaState
= getFromSipApplicationSessionReplicationCache((String)queryState.getId());
//following code checks if cached SAS isLocal and if so
//foreground locks it just for the time to generate the query response
//indicating wasRemoteLocked and then restore the lock to it's previous state
boolean wasCachedSASForegroundLocked = false;
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
cachedSASIsLocal.get()) {
wasCachedSASForegroundLocked = haSipApplicationSession.isForegroundLocked();
if(!wasCachedSASForegroundLocked) {
haSipApplicationSession.lockForeground();
}
}
ReplicationState returnState
= getBestSipApplicationSession(haSipApplicationSession, replicaState, queryState, useUnicast);
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
cachedSASIsLocal.get()) {
if(!wasCachedSASForegroundLocked) {
haSipApplicationSession.unlockForeground();
}
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processFindSas:returnState=" + returnState);
}
return returnState;
}
/**
* process the broadcastfindsas for SipApplicationSession
* @param queryState
*/
public ReplicationState processBroadcastfindsas(ReplicationState queryState) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsas:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsas:id=" + queryState.getId());
}
return processFindSas(queryState, false);
}
public void processBroadcastloadreceivedsas(ReplicationState queryState) {
//load is acknowledged safe to remove replica now
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processbroadcastloadreceivedsas:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processbroadcastloadreceivedsas:id=" + queryState.getId());
}
if(queryState == null || queryState.getId() == null) {
return;
}
if (queryState.getState() != null) {
processBulkLoadReceivedSAS(queryState);
return;
}
String id = (String)queryState.getId();
processLoadReceivedSas(id);
String ignoreInstance = (String) queryState.getProperty(ReplicationState.IGNORE_REMOVE_INSTANCE_NAME);
//only safe to remove replica if we are not the replica partner
//now determined by passed property
if(ignoreInstance != null && !ignoreInstance.equals(getInstanceName())) {
ReplicationState removed =
removeFromSipApplicationSessionReplicationCache(id);
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>processbroadcastloadreceivedsas: Removed replica=" +
removed);
}
}
}
public void processBulkLoadReceivedSAS(ReplicationState queryState) {
String from = queryState.getInstanceName();
try {
HashSet<String> ids = (HashSet<String>) ReplicationState.getObjectValue(queryState.getState());
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("Processing bulk load-acks for sas from " +
from + ", number of ids = " + ids.size());
}
for (String sasId : ids) {
processLoadReceivedSas(sasId);
ReplicationState replica = getFromSipApplicationSessionReplicationCache(sasId);
if (replica != null) {
removeFromSipApplicationSessionReplicationCache(sasId);
}
}
} catch (Exception ex) {
_logger.log(Level.WARNING, ex.getMessage(), ex);
}
}
// Presently, we short-circuit this and always call it directly.
// But I have left it as a normal process* method in case at some
// point it should be a unicast load received acknowledgement.
public void processLoadReceivedSas(String id) {
activationHelper.unregisterSasTimerMigrationTask(id);
//remove active sip application session if present and not locked
SipApplicationSessionImpl sipApplicationSession
= findSipApplicationSessionFromCacheOnly(id);
if(sipApplicationSession != null
&& !sipApplicationSession.isForegroundLocked()) {
sipApplicationSession.passivate();
}
}
/**
* process the load of a SipApplicationSession
* @param queryState - contains the load command
*/
public ReplicationState processLoadsas(ReplicationState queryState) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processLoadsas:queryState = " + queryState);
_logger.fine("in " + this.getClass().getName() + ">>processLoadsas:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processLoadsas:id=" + queryState.getId());
}
return processFindSas(queryState, true);
}
/**
* process the loadAdvisory of a SipApplicationSession
* this should trigger a load call for the SipApplicationSession
* @param extraParams
*/
public void processLoadadvisorysas(SipApplicationSessionExtraParams extraParams) {
if(extraParams == null) {
return;
}
String id = extraParams.getId();
HASipApplicationSession sas = processLoadadvisorysas(id);
if (sas != null) {
ReplicationState loadReceivedState = ReplicationState.createBroadcastLoadReceivedState(
MODE_SIP, id, this.getApplicationId(), sas.getVersion(),
instanceName, MESSAGE_BROADCAST_LOAD_RECEIVED_SAS);
this.sendLoadAcknowledgement(loadReceivedState, sas.getBeKey());
}
}
public void processLoadadvisorysas(ReplicationState replicationState) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN" + this.getClass().getName() + ">>processLoadadvisorysas");
}
if(replicationState == null) {
return;
}
if(isSASExpatInProgress()) {
return;
}
if (replicationState.getState() != null) {
processBulkLoadAdvSAS(replicationState);
return;
}
//try to load from local cache first
String id = (String)replicationState.getId();
String from = replicationState.getInstanceName();
HASipApplicationSession sas = processLoadadvisorysas(id);
if (sas != null) {
sendUnicastLoadAcknowledgementSAS(id, from, sas.getBeKey());
}
}
private boolean isSASExpatInProgress() {
return isExpatInProgress(sasExpatListHandler, sasReplicaExpatHandler);
}
private boolean isExpatInProgress(ExpatListHandler... expatHandlers) {
for (ExpatListHandler expatHandler : expatHandlers) {
if (expatHandler != null && expatHandler.isAwaitingExpatList()) {
return true;
}
}
return false;
}
// ensure that this method is called only when the SAS expat is not in progress.
void processBulkLoadAdvSAS(ReplicationState replicationState) {
String from = replicationState.getInstanceName();
byte[] bytes = replicationState.getState();
if (bytes != null) {
try {
HashSet<String> staleIds = new HashSet<String>();
HashSet<String> expiredIds =
(HashSet<String>) ReplicationState.getObjectValue(bytes);
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("Processing bulk load-advisories for sas from " +
from + ", number of ids = " + expiredIds.size());
}
for (String expiredId : expiredIds) {
if (getSipApplicationSessionExpatListElement(expiredId) == null) {
staleIds.add(expiredId);
} else {
HASipApplicationSession sas = processLoadadvisorysas(expiredId);
if (sas != null && !from.equalsIgnoreCase(
SipApplicationSessionUtil.getFailoverServerInstanceForBeKey(sas.getBeKey()))) {
staleIds.add(expiredId);
}
}
}
sendSasLoadAcks(from, staleIds);
} catch (Exception ex) {
logger.log(Level.WARNING, ex.getMessage(), ex);
}
}
}
public HASipApplicationSession processLoadadvisorysas(String id) {
HASipApplicationSession sipApplicationSession = (HASipApplicationSession)
this.findSipApplicationSessionFromCacheOnly(id);
if (sipApplicationSession != null) {
sipApplicationSession.touchAndSave();
sipApplicationSession.activateGraph();
} else {
//load and activate SipApplicationSession
try {
sipApplicationSession = (HASipApplicationSession) swapInSipApplicationSession(id, false);
if (sipApplicationSession != null) {
sipApplicationSession.activateGraph();
}
} catch (Exception ex) {
_logger.log(Level.WARNING, "sas_unable_to_load_in_response_to_loadadvisory", id);
_logger.log(Level.WARNING, ex.getMessage(), ex);
}
}
return sipApplicationSession;
}
public void handleDynamicOwnershipChanges(Event event,
String triggeringInstance,
boolean isLbChange) {
if (isBeingReleased) {
return;
}
if (!isLbChange) {
return;
}
if(!SipReplicationUtil.isInstanceLoadBalancedByCLB()) {
return;
}
sasExpatListHandler.eventReceived(event, triggeringInstance);
sipSessionExpatListHandler.eventReceived(event, triggeringInstance);
servletTimerExpatListHandler.eventReceived(event, triggeringInstance);
if(!sasExpatListHandler.shouldCalculateExpatList()) {
return; // expat calculation is already in progress.
}
long startTime = System.currentTimeMillis();
ExpatListHandler.expatCalculationStarted();
currentEvent = event;
currentTriggeringInstance = triggeringInstance;
synchronizeKeys();
CountDownLatch doneSignal = new CountDownLatch(3);
sasExpatListHandler.preInvoke(event, triggeringInstance);
sipSessionExpatListHandler.preInvoke(event, triggeringInstance);
servletTimerExpatListHandler.preInvoke(event, triggeringInstance);
boolean isExpatListLocked = false;
if (sasExpatListHandler.isAwaitingExpatList()) { // IMP :: do preInvoke before doing this check.
// if we need to await for any list to be pushed to us from
// remote instance, then only lock the list, otherwise allow
// read on the expat list.
sasExpatReadWriteLock.writeLock().lock();
sipSessionExpatReadWriteLock.writeLock().lock();
servletTimerExpatReadWriteLock.writeLock().lock();
isExpatListLocked = true;
}
ExpatListQueryTask sasExpatListQueryTask
= getExpatListAsync(sasExpatListHandler, doneSignal);
ExpatListQueryTask sipSessionExpatListQueryTask
= getExpatListAsync(sipSessionExpatListHandler, doneSignal);
ExpatListQueryTask servletTimerExpatListQueryTask
= getExpatListAsync(servletTimerExpatListHandler, doneSignal);
try {
doneSignal.await(ExpatListHandler.EXPAT_LIST_QUERY_TIMEOUT * 2, TimeUnit.MILLISECONDS);
} catch(InterruptedException ex) {}
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager>>handleDynamicOwnershipChanges after a wait: wait time = " + (System.currentTimeMillis() - startTime));
}
try {
HashMap sasResult = sasExpatListQueryTask.getExpatList();
if(sasResult != null) {
sasExpatIdsMap = sasResult;
}
HashMap sipSessionResult = sipSessionExpatListQueryTask.getExpatList();
if(sipSessionResult != null) {
sipSessionExpatIdsMap = sipSessionResult;
}
HashMap servletTimerResult = servletTimerExpatListQueryTask.getExpatList();
if(servletTimerResult != null) {
servletTimerExpatIdsMap = servletTimerResult;
}
} finally {
sasExpatIdsMap = mergeWithReplicaExpats(
sasExpatIdsMap, sasReplicaExpatHandler);
sipSessionExpatIdsMap = mergeWithReplicaExpats(
sipSessionExpatIdsMap, ssReplicaExpatHandler);
servletTimerExpatIdsMap = mergeWithReplicaExpats(
servletTimerExpatIdsMap, stReplicaExpatHandler);
sasExpatListHandler.postInvoke();
sipSessionExpatListHandler.postInvoke();
servletTimerExpatListHandler.postInvoke();
if (isExpatListLocked) {
sasExpatReadWriteLock.writeLock().unlock();
sipSessionExpatReadWriteLock.writeLock().unlock();
servletTimerExpatReadWriteLock.writeLock().unlock();
}
currentEvent = null;
currentTriggeringInstance = null;
// Print the final map after the merge to check if everything is fine.
ReplicationUtil.printExpatList(sasExpatIdsMap, "SAS(final)", startTime);
ReplicationUtil.printExpatList(sipSessionExpatIdsMap, "SipSession(final)", startTime);
ReplicationUtil.printExpatList(servletTimerExpatIdsMap, "ServletTimer(final)", startTime);
}
ExpatListHandler.expatCalculationEnded();
}
private Event currentEvent;
private String currentTriggeringInstance;
/**
* Invoke the synchronizeKeys method simultaneously on all the stores.
* Note that this method is common to all stores (in-house or third party)
*/
private void synchronizeKeys() {
// TODO :: For the third party implementation to work,
// TODO :: we need to revisit the parameters.
new SynchronizeKeysTask(getSipApplicationSessionBackingStore(), null, null, false);
new SynchronizeKeysTask(getSipSessionBackingStore(), null, null, false);
new SynchronizeKeysTask(getServletTimerBackingStore(), null, null, false);
}
/**
* JxtaBackingStoreImpl will call back this method. Hence, this is a
* in-memory implementation specific method.
*/
public void __synchronizeKeys(JxtaBackingStoreImpl jxtaBackingStore) {
ExpatListHandler expatHandler = null;
if (jxtaBackingStore == sipApplicationSessionBackingStore) {
expatHandler = sasReplicaExpatHandler;
} else if(jxtaBackingStore == sipSessionBackingStore) {
expatHandler = ssReplicaExpatHandler;
} else if(jxtaBackingStore == servletTimerBackingStore) {
expatHandler = stReplicaExpatHandler;
}
if(expatHandler != null) {
expatHandler.preInvoke(currentEvent, currentTriggeringInstance);
expatHandler.call();
// NOTE :: Since the result of the above call needs to be retained
// until the results are merged with activeExpat, hence the invocation of
// postInvoke is delayed until then. mergeWithReplicaExpats method
// calls postInvoke after merging the replica expat with active expat.
}
}
/**
* For the third party backing store implementations,
* this method will be a no-op.
*/
private HashMap mergeWithReplicaExpats(HashMap activeExpat,
ExpatListHandler replicaExpatHandler) {
HashMap result = activeExpat;
if(replicaExpatHandler != null) {
try {
HashMap replicaExpat = replicaExpatHandler.awaitAndGetResult();
if(replicaExpat != null && !replicaExpat.isEmpty()) {
if(activeExpat != null) {
replicaExpat.putAll(activeExpat);
}
result = replicaExpat;
}
} finally {
// since we have the results now, we can call postInvoke() and
// clear the memory references.
replicaExpatHandler.postInvoke();
}
}
return result;
}
boolean isExpectingExpatIdsMap() {
return sasExpatListHandler.isAwaitingExpatList() ||
sipSessionExpatListHandler.isAwaitingExpatList() ||
servletTimerExpatListHandler.isAwaitingExpatList();
}
boolean canTrustReplicaDuringExpat(String replicaSource) {
if(replicaSource == null) {
return false;
}
DynamicOwnershipManager.Event event = currentEvent;
String instance = currentTriggeringInstance;
if(DynamicOwnershipManager.Event.FAILURE.equals(event) &&
replicaSource.equalsIgnoreCase(instance)) {
return true;
}
return false;
}
private ExpatListQueryTask getExpatListAsync(ExpatListHandler expatListHandler,
CountDownLatch doneSignal) {
ExpatListQueryTask expatListQueryTask
= new ExpatListQueryTask(expatListHandler, doneSignal);
return expatListQueryTask;
}
//Begin Expat List for SAS
/**
* process the broadcastfindsasexpatids for SipApplicationSession
* @param queryState
*/
public ReplicationState processBroadcastfindsasexpatids(ReplicationState queryState) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsasexpatids:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsasexpatids:owningInstance=" + queryState.getExtraParam());
}
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
!ReplicationHealthChecker.isServerLbEnabled(
getInstanceName())) {
// Don't respond if the CLB is running but we are not CLB enabled
return null;
}
sasExpatListHandler.sendExpatQueryResponse(queryState);
return null;
}
public ReplicationState processBroadcastfindsasreplicaexpatids(ReplicationState queryState) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsasreplicaexpatids:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsasreplicaexpatids:owningInstance=" + queryState.getExtraParam());
}
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
!ReplicationHealthChecker.isServerLbEnabled(
getInstanceName())) {
// Don't respond if the CLB is running but we are not CLB enabled
return null;
}
if(sasReplicaExpatHandler != null) {
sasReplicaExpatHandler.sendExpatQueryResponse(queryState);
}
return null;
}
public int removeExpiredSessions() {
//Deliberate no op
return 0;
}
//End Expat List for SAS
//Begin Expat List for SipSessions
/*
HashSet<ExpatListElement> getSipSessionExpatIds(
String requestingInstance, boolean consultActiveCache) {
//using set to avoid dups
HashSet expatIds = new HashSet();
//iterate over sip session replicas
BaseCache replicatedSipSessionsCache = getReplicatedSipSessions();
Iterator it = replicatedSipSessionsCache.values();
long version = -1L;
while (it.hasNext()) {
ReplicationState state = (ReplicationState) it.next();
String ssId = (String) state.getId();
//use bekey for mapping instance ownership
String beKey = (String) state.getProperty(BEKEY);
if (beKey != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstanceForBeKey(beKey);
if (requestingInstance.equalsIgnoreCase(rightfulOwner)) {
version = state.getVersion();
expatIds.add(new ExpatListElement(ssId, version, instanceName));
}
}
}
if (consultActiveCache) {
try {
//iterate over active sip session cache
Iterator it2 = sipSessions.values().iterator();
while (it2.hasNext()) {
HASipSession ss = (HASipSession) it2.next();
String ssId = (String) ss.getId();
String sasId = ss.getParentSASId();
if (sasId != null) {
//use parent sas id for mapping to owning instance
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (requestingInstance.equalsIgnoreCase(rightfulOwner)) {
version = ss.getVersion();
expatIds.add(new ExpatListElement(
ssId, version, instanceName, true));
}
}
}
} catch (NoSuchFieldError e) {
;
}
}
return expatIds;
}
*/
/**
* Get the SipSession' expat list from the active cache for a given instance.
*/
HashSet<ExpatListElement> getSipSessionExpatIdsFromActive(String requestingInstance) {
//using set to avoid dups
HashSet expatIds = new HashSet();
long version = -1L;
try {
//iterate over active sip session cache
Iterator it2 = sipSessions.values().iterator();
while (it2.hasNext()) {
HASipSession ss = (HASipSession) it2.next();
String ssId = (String) ss.getId();
String sasId = ss.getParentSASId();
if (sasId != null) {
//use parent sas id for mapping to owning instance
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (requestingInstance.equalsIgnoreCase(rightfulOwner)) {
version = ss.getVersion();
expatIds.add(new ExpatListElement(
ssId, version, instanceName, true));
}
}
}
} catch (NoSuchFieldError e) {
;
}
return expatIds;
}
/**
* Get the SipSession' expat list from the replica cache for a given instance.
*/
HashSet<ExpatListElement> getSipSessionExpatIdsFromReplica(String requestingInstance) {
//using set to avoid dups
HashSet expatIds = new HashSet();
//iterate over sip session replicas
BaseCache replicatedSipSessionsCache = getReplicatedSipSessions();
Iterator it = replicatedSipSessionsCache.values();
long version = -1L;
while (it.hasNext()) {
ReplicationState state = (ReplicationState) it.next();
String ssId = (String) state.getId();
//use bekey for mapping instance ownership
String beKey = (String) state.getProperty(BEKEY);
if (beKey != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstanceForBeKey(beKey);
if (requestingInstance.equalsIgnoreCase(rightfulOwner)) {
version = state.getVersion();
expatIds.add(new ExpatListElement(ssId, version, instanceName));
}
}
}
return expatIds;
}
/**
* Get the SipSession' expat list from the active cache for all the surviving instances.
*/
private void getSipSessionExpatIdsFromActive(ExpatListQueryResults results) {
//iterate over active sip session cache
long version = -1L;
Iterator it2 = sipSessions.values().iterator();
while (it2.hasNext()) {
HASipSession ss = (HASipSession) it2.next();
String ssId = (String) ss.getId();
String sasId = ss.getParentSASId();
//use parent sas id for mapping to owning instance
if (sasId != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (rightfulOwner != null
&& !rightfulOwner.equalsIgnoreCase(instanceName)) {
version = ss.getVersion();
ExpatListElement expatElement = new ExpatListElement(ssId,
version, instanceName, true);
results.addQueryResultFor(rightfulOwner, expatElement);
}
}
}
}
/**
* Get the SipSession' expat list from the replica cache for all the surviving instances.
*/
private void getSipSessionExpatIdsFromReplica(ExpatListQueryResults results) {
//iterate over sip session replicas
BaseCache replicatedSipSessionsCache = getReplicatedSipSessions();
Iterator it = replicatedSipSessionsCache.values();
long version = -1L;
while (it.hasNext()) {
ReplicationState state = (ReplicationState) it.next();
String ssId = (String) state.getId();
//use bekey for mapping instance ownership
String beKey = (String) state.getProperty(BEKEY);
if (beKey != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstanceForBeKey(beKey);
version = state.getVersion();
ExpatListElement expatElement = new ExpatListElement(ssId,
version, instanceName);
results.addQueryResultFor(rightfulOwner, expatElement);
}
}
}
/*
private void getAllSipSessionExpatIds(ExpatListQueryResults results) {
//iterate over sip session replicas
BaseCache replicatedSipSessionsCache = getReplicatedSipSessions();
Iterator it = replicatedSipSessionsCache.values();
long version = -1L;
while (it.hasNext()) {
ReplicationState state = (ReplicationState) it.next();
String ssId = (String) state.getId();
//use bekey for mapping instance ownership
String beKey = (String) state.getProperty(BEKEY);
if (beKey != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstanceForBeKey(beKey);
version = state.getVersion();
ExpatListElement expatElement = new ExpatListElement(ssId,
version, instanceName);
results.addQueryResultFor(rightfulOwner, expatElement);
}
}
//iterate over active sip session cache
Iterator it2 = sipSessions.values().iterator();
while (it2.hasNext()) {
HASipSession ss = (HASipSession) it2.next();
String ssId = (String) ss.getId();
String sasId = ss.getParentSASId();
//use parent sas id for mapping to owning instance
if (sasId != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (rightfulOwner != null
&& !rightfulOwner.equalsIgnoreCase(instanceName)) {
version = ss.getVersion();
ExpatListElement expatElement = new ExpatListElement(ssId,
version, instanceName, true);
results.addQueryResultFor(rightfulOwner, expatElement);
}
}
}
}
*/
/*
List getSipSessionExpatIdsThirdPartySPI(String owningInstanceName) {
BackingStore sipSessionBackingStore
= this.getSipSessionBackingStore();
SipSessionExtraParams ssExtraParamCriteria
= SipSessionExtraParams.createSearchCriteria(
getApplicationId(), owningInstanceName);
Collection<SipSessionExtraParams> ssColl
= sipSessionBackingStore.findByCriteria(ssExtraParamCriteria);
List expatIds = new ArrayList();
//using set to avoid dups
HashSet expatIdsSet = new HashSet();
Iterator<SipSessionExtraParams> ssResults =
(Iterator<SipSessionExtraParams>) ssColl.iterator();
while (ssResults.hasNext()) {
SipSessionExtraParams eParam = ssResults.next();
if (owningInstanceName.equals(eParam.getCurrentOwnerInstanceName())) {
expatIdsSet.add(new ExpatListElement((String)eParam.getId(), -1L, null));
}
}
//iterate over active sas cache
long nextVersion = -1L;
Iterator it2 = sipSessions.values().iterator();
while(it2.hasNext()) {
HASipSession nextSipSession
= (HASipSession)it2.next();
String nextSipSessionId
= (String)nextSipSession.getId();
String nextSipApplicationSessionId = null;
if(nextSipSession.getExtraParameters() != null) {
//use parent sas id for mapping to owning instance
nextSipApplicationSessionId
= nextSipSession.getExtraParameters().getParentSasId();
String nextRightfulOwnerInstanceName
= SipApplicationSessionUtil.getActualServerInstance(nextSipApplicationSessionId);
if(nextRightfulOwnerInstanceName != null
&& nextRightfulOwnerInstanceName.equalsIgnoreCase(owningInstanceName)) {
nextVersion = nextSipSession.getVersion();
expatIdsSet.add(new ExpatListElement(nextSipSessionId, nextVersion, getInstanceName(), true));
}
}
}
expatIds.addAll(expatIdsSet);
return expatIds;
}
*/
/**
* process the processBroadcastfindsipsessionexpatids for SipSession
* @param queryState
*/
public ReplicationState processBroadcastfindsipsessionexpatids(ReplicationState queryState) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsipsessionexpatids:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsipsessionexpatids:owningInstance=" + queryState.getExtraParam());
}
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
!ReplicationHealthChecker.isServerLbEnabled(
getInstanceName())) {
// Don't respond if the CLB is running but we are not CLB enabled
return null;
}
sipSessionExpatListHandler.sendExpatQueryResponse(queryState);
return null;
}
public ReplicationState processBroadcastfindsipsessionreplicaexpatids(
ReplicationState queryState) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsipsessionreplicaexpatids:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsipsessionreplicaexpatids:owningInstance=" + queryState.getExtraParam());
}
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
!ReplicationHealthChecker.isServerLbEnabled(
getInstanceName())) {
// Don't respond if the CLB is running but we are not CLB enabled
return null;
}
if(ssReplicaExpatHandler != null) {
ssReplicaExpatHandler.sendExpatQueryResponse(queryState);
}
return null;
}
//End Expat List for SipSession
//Begin Expat List for ServletTimer
/*
HashSet<ExpatListElement> getServletTimerExpatIds(
String requestingInstance, boolean consultActiveCache) {
//using set to avoid dups
HashSet expatIds = new HashSet();
//iterate over servlet timer replicas
BaseCache replicatedServletTimersCache = getReplicatedServletTimers();
Iterator it = replicatedServletTimersCache.values();
long version = -1L;
while (it.hasNext()) {
ReplicationState state = (ReplicationState) it.next();
String stId = (String) state.getId();
//use bekey for mapping instance ownership
String beKey = (String) state.getProperty(BEKEY);
if (beKey != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstanceForBeKey(beKey);
if (requestingInstance.equalsIgnoreCase(rightfulOwner)) {
version = state.getVersion();
expatIds.add(new ExpatListElement(stId, version, instanceName));
}
}
}
if (consultActiveCache) {
try {
//iterate over active servlet timer cache
Iterator it2 = servletTimers.values().iterator();
while (it2.hasNext()) {
HAServletTimer st = (HAServletTimer) it2.next();
String stId = (String) st.getId();
String sasId = st.getParentSASId();
if (sasId != null) {
//use parent sas id for mapping to owning instance
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (requestingInstance.equalsIgnoreCase(rightfulOwner)) {
version = st.getVersion();
expatIds.add(new ExpatListElement(stId,
version, instanceName, true));
}
}
}
} catch (NoSuchFieldError e) {
;
}
}
return expatIds;
}
*/
/**
* Get the ServletTimer' expat list from the active cache for a given instance.
*/
HashSet<ExpatListElement> getServletTimerExpatIdsFromActive(
String requestingInstance) {
//using set to avoid dups
HashSet expatIds = new HashSet();
//iterate over servlet timer replicas
long version = -1L;
try {
//iterate over active servlet timer cache
Iterator it2 = servletTimers.values().iterator();
while (it2.hasNext()) {
HAServletTimer st = (HAServletTimer) it2.next();
String stId = (String) st.getId();
String sasId = st.getParentSASId();
if (sasId != null) {
//use parent sas id for mapping to owning instance
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (requestingInstance.equalsIgnoreCase(rightfulOwner)) {
version = st.getVersion();
expatIds.add(new ExpatListElement(stId,
version, instanceName, true));
}
}
}
} catch (NoSuchFieldError e) {
;
}
return expatIds;
}
/**
* Get the ServletTimer' expat list from the replica cache for a given instance.
*/
HashSet<ExpatListElement> getServletTimerExpatIdsFromReplica(
String requestingInstance) {
//using set to avoid dups
HashSet expatIds = new HashSet();
//iterate over servlet timer replicas
BaseCache replicatedServletTimersCache = getReplicatedServletTimers();
Iterator it = replicatedServletTimersCache.values();
long version = -1L;
while (it.hasNext()) {
ReplicationState state = (ReplicationState) it.next();
String stId = (String) state.getId();
//use bekey for mapping instance ownership
String beKey = (String) state.getProperty(BEKEY);
if (beKey != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstanceForBeKey(beKey);
if (requestingInstance.equalsIgnoreCase(rightfulOwner)) {
version = state.getVersion();
expatIds.add(new ExpatListElement(stId, version, instanceName));
}
}
}
return expatIds;
}
/**
* Get the ServletTimer' expat list from the active cache for all the surviving instances.
*/
private void getServletTimerExpatIdsFromActive(ExpatListQueryResults results) {
long version = -1L;
//iterate over active servlet timer cache
Iterator it2 = servletTimers.values().iterator();
while (it2.hasNext()) {
HAServletTimer st = (HAServletTimer) it2.next();
String stId = (String) st.getId();
String sasId = st.getParentSASId();
//use parent sas id for mapping to owning instance
if (sasId != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (rightfulOwner != null
&& !rightfulOwner.equalsIgnoreCase(instanceName)) {
version = st.getVersion();
ExpatListElement expatElement = new ExpatListElement(stId,
version, instanceName, true);
results.addQueryResultFor(rightfulOwner, expatElement);
}
}
}
}
/**
* Get the ServletTimer' expat list from the replica cache for all the surviving instances.
*/
private void getServletTimerExpatIdsFromReplica(ExpatListQueryResults results) {
//iterate over servlet timer replicas
BaseCache replicatedServletTimersCache = getReplicatedServletTimers();
Iterator it = replicatedServletTimersCache.values();
long version = -1L;
while(it.hasNext()) {
ReplicationState state = (ReplicationState)it.next();
String stId = (String)state.getId();
//use bekey for mapping instance ownership
String beKey = (String) state.getProperty(BEKEY);
if(beKey != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstanceForBeKey(beKey);
version = state.getVersion();
ExpatListElement expatElement = new ExpatListElement(stId,
version, instanceName);
results.addQueryResultFor(rightfulOwner, expatElement);
}
}
}
/*
private void getAllServletTimerExpatIds(ExpatListQueryResults results) {
//iterate over servlet timer replicas
BaseCache replicatedServletTimersCache = getReplicatedServletTimers();
Iterator it = replicatedServletTimersCache.values();
long version = -1L;
while(it.hasNext()) {
ReplicationState state = (ReplicationState)it.next();
String stId = (String)state.getId();
//use bekey for mapping instance ownership
String beKey = (String) state.getProperty(BEKEY);
if(beKey != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstanceForBeKey(beKey);
version = state.getVersion();
ExpatListElement expatElement = new ExpatListElement(stId,
version, instanceName);
results.addQueryResultFor(rightfulOwner, expatElement);
}
}
//iterate over active servlet timer cache
Iterator it2 = servletTimers.values().iterator();
while (it2.hasNext()) {
HAServletTimer st = (HAServletTimer) it2.next();
String stId = (String) st.getId();
String sasId = st.getParentSASId();
//use parent sas id for mapping to owning instance
if (sasId != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (rightfulOwner != null
&& !rightfulOwner.equalsIgnoreCase(instanceName)) {
version = st.getVersion();
ExpatListElement expatElement = new ExpatListElement(stId,
version, instanceName, true);
results.addQueryResultFor(rightfulOwner, expatElement);
}
}
}
}
*/
/*
List getServletTimerExpatIdsThirdPartySPI(String owningInstanceName) {
BackingStore servletTimerBackingStore
= this.getServletTimerBackingStore();
ServletTimerExtraParams stExtraParamCriteria
= ServletTimerExtraParams.createSearchCriteria(
getApplicationId(), owningInstanceName);
Collection<ServletTimerExtraParams> stColl
= servletTimerBackingStore.findByCriteria(stExtraParamCriteria);
List expatIds = new ArrayList();
//using set to avoid dups
HashSet expatIdsSet = new HashSet();
Iterator<ServletTimerExtraParams> stResults =
(Iterator<ServletTimerExtraParams>) stColl.iterator();
while (stResults.hasNext()) {
ServletTimerExtraParams eParam = stResults.next();
if (owningInstanceName.equals(eParam.getCurrentOwnerInstanceName())) {
expatIdsSet.add(new ExpatListElement((String)eParam.getId(), -1L, null));
}
}
//iterate over active sas cache
long nextVersion = -1L;
Iterator it2 = servletTimers.values().iterator();
while(it2.hasNext()) {
HAServletTimer nextServletTimer
= (HAServletTimer)it2.next();
String nextServletTimerId
= (String)nextServletTimer.getId();
String nextSipApplicationSessionId = null;
if(nextServletTimer.getExtraParameters() != null) {
//use parent sas id for mapping to owning instance
nextSipApplicationSessionId
= nextServletTimer.getExtraParameters().getParentSasId();
String nextRightfulOwnerInstanceName
= SipApplicationSessionUtil.getActualServerInstance(nextSipApplicationSessionId);
if(nextRightfulOwnerInstanceName != null
&& nextRightfulOwnerInstanceName.equalsIgnoreCase(owningInstanceName)) {
nextVersion = nextServletTimer.getVersion();
expatIdsSet.add(new ExpatListElement(nextServletTimerId, nextVersion, getInstanceName(), true));
}
}
}
expatIds.addAll(expatIdsSet);
return expatIds;
}
*/
/**
* process the processBroadcastfindservlettimerexpatids for SipSession
* @param queryState
*/
public ReplicationState processBroadcastfindservlettimerexpatids(ReplicationState queryState) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindservlettimerexpatids:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindservlettimerexpatids:owningInstance=" + queryState.getExtraParam());
}
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
!ReplicationHealthChecker.isServerLbEnabled(
getInstanceName())) {
// Don't respond if the CLB is running but we are not CLB enabled
return null;
}
servletTimerExpatListHandler.sendExpatQueryResponse(queryState);
return null;
}
public ReplicationState processBroadcastfindservlettimerreplicaexpatids(ReplicationState queryState) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindservlettimerreplicaexpatids:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindservlettimerreplicaexpatids:owningInstance=" + queryState.getExtraParam());
}
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
!ReplicationHealthChecker.isServerLbEnabled(
getInstanceName())) {
// Don't respond if the CLB is running but we are not CLB enabled
return null;
}
if(stReplicaExpatHandler != null) {
stReplicaExpatHandler.sendExpatQueryResponse(queryState);
}
return null;
}
//End Expat List for ServletTimer
/**
* find the best version of SipApplicationSession
* removing any stale versions and return query result
* @param activeSipApplicationSession SipApplicationSession
* from active cache
* @param replicaSipApplicationSession SipApplicationSession
* from replica cache
* @param queryState version requested in query (-1 means
* version unaware
* @param useUnicast is this for unicast or broadcast
*/
private ReplicationState getBestSipApplicationSession(HASipApplicationSession activeSipApplicationSession,
ReplicationState replicaSipApplicationSession, ReplicationState queryState, boolean useUnicast) {
ReplicationState bestResult = null;
long queryVersion = queryState.getVersion();
//first check for none found in either active or replica caches
if(replicaSipApplicationSession == null && activeSipApplicationSession == null) {
//return nack
if(useUnicast) {
return ReplicationState.createUnicastQueryResponseFrom(queryState, true);
} else {
return ReplicationState.createQueryResponseFrom(queryState, true);
}
}
//next check for artifacts found in both active and replica caches
if(replicaSipApplicationSession != null && activeSipApplicationSession != null) {
//compare and remove the lesser version
//keeping the higher version as (tentative) best
if(replicaSipApplicationSession.getVersion() <= activeSipApplicationSession.getVersion()) {
//remove stale replica - work with active
removeFromSipApplicationSessionReplicationCache((String)replicaSipApplicationSession.getId());
//create appropriate response from active
bestResult
= createSipApplicationSessionResponseFrom(activeSipApplicationSession, queryState, useUnicast);
// START IT 1550
if (activeSipApplicationSession.isForegroundLocked()) {
bestResult.setVersion(Integer.MAX_VALUE);
}
// END IT 1550
} else {
//remove stale active - work with replica
clearFromSipApplicationSessionManagerCache(activeSipApplicationSession.getId());
//create appropriate response from replica
bestResult
= createSipApplicationSessionResponseFrom(replicaSipApplicationSession, queryState, useUnicast);
}
} else {
//either replica or active is null and other is non-null
//replica is null and active is not null
if(replicaSipApplicationSession == null) {
//create appropriate response from active
bestResult
= createSipApplicationSessionResponseFrom(activeSipApplicationSession, queryState, useUnicast);
// START IT 1550
if (activeSipApplicationSession.isForegroundLocked()) {
bestResult.setVersion(Integer.MAX_VALUE);
}
// END IT 1550
} else {
//active is null & replica is not null
//create appropriate response from replica
bestResult
= createSipApplicationSessionResponseFrom(replicaSipApplicationSession, queryState, useUnicast);
}
}
return bestResult;
}
private ReplicationState createSipApplicationSessionResponseFrom(ReplicationState replicaSipApplicationSession,
ReplicationState queryState, boolean useUnicast) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("createSipApplicationSessionResponseFromReplicaAndReplica:useUnicast = " + useUnicast
+ " queryState = " + queryState + " replicaSipApplicationSession = " + replicaSipApplicationSession);
}
//create appropriate response from replica
ReplicationState result = null;
long queryVersion = queryState.getVersion();
if(queryVersion != -1 && replicaSipApplicationSession.getVersion() < queryVersion) {
//return nack & clear stale replica
removeFromSipApplicationSessionReplicationCache((String)replicaSipApplicationSession.getId());
if(useUnicast) {
result = ReplicationState.createUnicastQueryResponseFrom(queryState, true);
} else {
result = ReplicationState.createQueryResponseFrom(queryState, true);
}
} else {
//return real response based on replica
if(useUnicast) {
result = ReplicationState.createUnicastQueryResponseFrom(replicaSipApplicationSession, queryState.getCommand());
} else {
result = ReplicationState.createQueryResponseFrom(replicaSipApplicationSession);
}
}
return result;
}
private ReplicationState createSipApplicationSessionResponseFrom(HASipApplicationSession activeSipApplicationSession,
ReplicationState queryState, boolean useUnicast) {
//create appropriate response from active
ReplicationState result = null;
long queryVersion = queryState.getVersion();
if(queryVersion != -1 && activeSipApplicationSession.getVersion() < queryVersion) {
//return nack & clear stale active
clearFromSipApplicationSessionManagerCache(activeSipApplicationSession.getId());
if(useUnicast) {
result = ReplicationState.createUnicastQueryResponseFrom(queryState, true);
} else {
result = ReplicationState.createQueryResponseFrom(queryState, true);
}
} else {
//return real response based on active SAS
try {
result = createQueryResponseFrom(activeSipApplicationSession, useUnicast);
} catch (IOException ioe) {
_logger.log(Level.WARNING,
"Failed load: Unable to serialize " +
activeSipApplicationSession, ioe);
// We've been unable to serialize the given active
// SipApplicationSession.
// Clear it from the active cache and return a nack instead
clearFromSipApplicationSessionManagerCache(
activeSipApplicationSession.getId());
if(useUnicast) {
result = ReplicationState.createUnicastQueryResponseFrom(queryState, true);
} else {
result = ReplicationState.createQueryResponseFrom(queryState, true);
}
}
}
return result;
}
/**
* Converts the given SipApplicationSession to a ReplicationState.
*
* @param sas The SipApplicationSession to be converted
*
* @return The ReplicationState corresponding to the given
* SipApplicationSession
*/
private ReplicationState createQueryResponseFrom(
HASipApplicationSession sas, boolean useUnicast) throws IOException {
byte[] containerExtraParamState = null;
SipApplicationSessionExtraParams containerExtraParams
= sas.getExtraParameters();
if(containerExtraParams != null) {
try {
containerExtraParamState
= ReplicationUtil.getByteArray(containerExtraParams, isReplicationCompressionEnabled());
} catch (IOException ex) {
; //deliberate no-op
}
}
if(!useUnicast) {
return new ReplicationState(
MODE_SIP,
sas.getId(),
getApplicationId(),
sas.getVersion(),
0L,
0L,
null,
null,
null,
ReplicationState.RETURN_BROADCAST_MSG_COMMAND,
ReplicationUtil.getByteArray(sas, isReplicationCompressionEnabled()),
null,
containerExtraParamState);
} else {
return new ReplicationState(
MODE_SIP,
sas.getId(),
getApplicationId(),
sas.getVersion(),
0L,
0L,
LOAD_SAS_COMMAND, //put original command in extraParam slot
null,
null,
ReplicationState.RETURN_UNICAST_MSG_COMMAND,
ReplicationUtil.getByteArray(sas, isReplicationCompressionEnabled()),
null,
containerExtraParamState);
}
}
/**
* Gets the SipApplicationSession with the given id
* from the active cache only
*
* @return The SipApplicationSession with the given id, or null if not
* found
*/
public SipApplicationSessionImpl findSipApplicationSessionFromCacheOnly(String id) {
if (id == null)
return (null);
Object monitor = getReplicationSessionMonitor(id);
synchronized(monitor) {
HASipApplicationSession result
= (HASipApplicationSession)super.findSipApplicationSessionFromCacheOnly(id);
if(!this.isActiveCacheReconciliationOngoing()) {
return result;
} else {
if(result == null || !result.isSuspect()) {
//if null just return it
//if not suspect it has already been checked
return result;
}
if(RollingUpgradeUtil.canUseSuspectSession(result,
sasExpatIdsMap, sasExpatReadWriteLock)) {
//if it passes the check return it
return result;
} else {
removeSipApplicationSessionFromCache(result);
return null;
}
}
}
}
protected void clearFromSipApplicationSessionManagerCache(String id) {
SipApplicationSessionImpl sess
= super.findSipApplicationSessionFromCacheOnly(id);
if(sess != null) {
this.removeSipApplicationSessionFromCache(sess);
}
}
//SipSession process methods
/**
* process the save of a SipSession
* @param sessionState - contains the save command
*/
public void processSavesipsession(ReplicationState sessionState) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN" + this.getClass().getName() + ">>processSavess");
}
this.putInSipSessionReplicationCache(sessionState);
}
/**
* process the removal of a Sip Session
* @param sessionState - contains the remove command
*/
public void processRemovesipsession(ReplicationState sessionState) {
if (sessionState.getState() != null) {
processBulkRemoveSipSession(sessionState);
return;
}
sipSessionReplicaCache.processRemove(sessionState);
}
/**
* process the update of a SipSession
* @param sessionState - contains the updatelastaccesstime command
*/
public void processUpdatelastaccesstimesipsession(ReplicationState sessionState) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN" + this.getClass().getName() +
">>processUpdatelastaccesstimess:id: " +
sessionState.getId() + ", version: " +
sessionState.getVersion());
}
sipSessionReplicaCache.processUpdatelastaccesstime(sessionState);
}
public ReplicableEntity findSipSessionAndPassivate(String id,
AtomicBoolean cachedSipSessionIsLocal) {
HASipSession haSipSession = null;
SipSessionDialogImpl sipSession
= findSipSessionFromCacheOnly(id);
//SipSession is considered belonging on this instance (isLocal)
//if its parent sasId isLocal
cachedSipSessionIsLocal.set(false);
if (sipSession instanceof HASipSession) {
haSipSession = (HASipSession) sipSession;
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
SipReplicationUtil.isLocal(haSipSession.getParentSASId())) {
cachedSipSessionIsLocal.set(true);
} else {
if (!haSipSession.isForegroundLocked()) {
processLoadReceivedSipSession(haSipSession.getId());
}
}
}
return haSipSession;
}
/**
* process the broadcastfindsipsession for SipSession
* @param queryState
* @param useUnicast
*/
public ReplicationState processFindSipSession(ReplicationState queryState, boolean useUnicast) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processFindSipSession:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processFindSipSession:id=" + queryState.getId());
_logger.fine("in " + this.getClass().getName() + ">>processFindSipSession:useUnicast=" + useUnicast);
}
//look in active cache
AtomicBoolean cachedSipSessionIsLocal = new AtomicBoolean();
HASipSession haSipSession = (HASipSession)
findSipSessionAndPassivate((String)queryState.getId(), cachedSipSessionIsLocal);
//look in replica cache
ReplicationState replicaState
= getFromSipSessionReplicationCache((String)queryState.getId());
//following code checks if cached SipSession isLocal and if so
//foreground locks it just for the time to generate the query response
//indicating wasRemoteLocked and then restore the lock to it's previous state
boolean wasCachedSipSessionForegroundLocked = false;
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
cachedSipSessionIsLocal.get()) {
wasCachedSipSessionForegroundLocked = haSipSession.isForegroundLocked();
if(!wasCachedSipSessionForegroundLocked) {
haSipSession.lockForeground();
}
}
ReplicationState returnState
= getBestSipSession(haSipSession, replicaState, queryState, useUnicast);
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
cachedSipSessionIsLocal.get()) {
if(!wasCachedSipSessionForegroundLocked) {
haSipSession.unlockForeground();
}
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processFindSipSession:returnState=" + returnState);
}
return returnState;
}
/**
* process the broadcastfindsipsession for SipSession
* @param queryState
*/
public ReplicationState processBroadcastfindsipsession(ReplicationState queryState) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsipsession:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsipsession:id=" + queryState.getId());
}
return processFindSipSession(queryState, false);
}
/**
* process the load of a SipSession
* @param queryState - contains the load command
*/
public ReplicationState processLoadsipsession(ReplicationState queryState) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processLoadsipsesson:queryState = " + queryState);
_logger.fine("in " + this.getClass().getName() + ">>processLoadsipsession:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processLoadsipsession:id=" + queryState.getId());
}
return processFindSipSession(queryState, true);
}
public void processBroadcastloadreceivedsipsession(ReplicationState queryState) {
//load is acknowledged safe to remove replica now
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processbroadcastloadreceivedsipsession:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processbroadcastloadreceivedsipsession:id=" + queryState.getId());
}
if(queryState == null || queryState.getId() == null) {
return;
}
String id = (String)queryState.getId();
processLoadReceivedSipSession(id);
String ignoreInstance = (String) queryState.getProperty(ReplicationState.IGNORE_REMOVE_INSTANCE_NAME);
//only safe to remove replica if we are not the replica partner
//now determined by passed property
if(ignoreInstance != null && !ignoreInstance.equals(getInstanceName())) {
ReplicationState removed =
removeFromSipSessionReplicationCache(id);
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>processbroadcastloadreceivedsipsession: Removed replica=" +
removed);
}
}
}
public void processLoadReceivedSipSession(String id) {
//remove active sip session if present and is not locked
SipSessionDialogImpl sipSession = findSipSessionFromCacheOnly(id);
if(sipSession != null
&& !sipSession.isForegroundLocked()) {
sipSession.passivate();
}
}
/**
* find the best version of SipSession
* removing any stale versions and return query result
* @param activeSipSession SipSession from active cache
* @param replicaSipSession replica SipSession from replica cache
* @param queryState version requested in query (-1 means
* version unaware
* @param useUnicast
*/
private ReplicationState getBestSipSession(HASipSession activeSipSession,
ReplicationState replicaSipSession, ReplicationState queryState, boolean useUnicast) {
ReplicationState bestResult = null;
long queryVersion = queryState.getVersion();
//first check for none found in either active or replica caches
if(replicaSipSession == null && activeSipSession == null) {
//return nack
if(useUnicast) {
return ReplicationState.createUnicastQueryResponseFrom(queryState, true);
} else {
return ReplicationState.createQueryResponseFrom(queryState, true);
}
}
//next check for artifacts found in both active and replica caches
if(replicaSipSession != null && activeSipSession != null) {
//compare and remove the lesser version
//keeping the higher version as (tentative) best
if(replicaSipSession.getVersion() <= activeSipSession.getVersion()) {
//remove stale replica - work with active
removeFromSipSessionReplicationCache((String)replicaSipSession.getId());
//create appropriate response from active
bestResult
= createSipSessionResponseFrom(activeSipSession, queryState, useUnicast);
} else {
//remove stale active - work with replica
this.clearFromSipSessionManagerCache(activeSipSession.getId());
//create appropriate response from replica
bestResult
= createSipSessionResponseFrom(replicaSipSession, queryState, useUnicast);
}
} else {
//either replica or active is null and other is non-null
//replica is null and active is not null
if(replicaSipSession == null) {
//create appropriate response from active
bestResult
= createSipSessionResponseFrom(activeSipSession, queryState, useUnicast);
} else {
//active is null & replica is not null
//create appropriate response from replica
bestResult
= createSipSessionResponseFrom(replicaSipSession, queryState, useUnicast);
}
}
return bestResult;
}
private ReplicationState createSipSessionResponseFrom(ReplicationState replicaSipSession,
ReplicationState queryState, boolean useUnicast) {
//create appropriate response from replica
ReplicationState result = null;
long queryVersion = queryState.getVersion();
if(queryVersion != -1 && replicaSipSession.getVersion() < queryVersion) {
//return nack & clear stale replica
removeFromSipSessionReplicationCache((String)replicaSipSession.getId());
if(useUnicast) {
result = ReplicationState.createUnicastQueryResponseFrom(queryState, true);
} else {
result = ReplicationState.createQueryResponseFrom(queryState, true);
}
} else {
//return real response based on replica
if(useUnicast) {
result = ReplicationState.createUnicastQueryResponseFrom(replicaSipSession, queryState.getCommand());
} else {
result = ReplicationState.createQueryResponseFrom(replicaSipSession);
}
}
return result;
}
private ReplicationState createSipSessionResponseFrom(HASipSession activeSipSession,
ReplicationState queryState, boolean useUnicast) {
//create appropriate response from active
ReplicationState result = null;
long queryVersion = queryState.getVersion();
if(queryVersion != -1 && activeSipSession.getVersion() < queryVersion) {
//return nack & clear stale active
clearFromSipSessionManagerCache(activeSipSession.getId());
if(useUnicast) {
result = ReplicationState.createUnicastQueryResponseFrom(queryState, true);
} else {
result = ReplicationState.createQueryResponseFrom(queryState, true);
}
} else {
//return real response based on active SipSession
try {
result = createQueryResponseFrom(activeSipSession, useUnicast);
} catch (IOException ioe) {
_logger.log(Level.WARNING,
"Failed load: Unable to serialize " + activeSipSession,
ioe);
// We've been unable to serialize the given active SipSession.
// Clear it from the active cache and return a nack instead
clearFromSipSessionManagerCache(activeSipSession.getId());
if(useUnicast) {
result = ReplicationState.createUnicastQueryResponseFrom(queryState, true);
} else {
result = ReplicationState.createQueryResponseFrom(queryState, true);
}
}
}
return result;
}
/**
* Converts the given SipSession to a ReplicationState.
*
* @param ss The SipSession to be converted
*
* @return The ReplicationState corresponding to the given SipSession
*/
private ReplicationState createQueryResponseFrom(HASipSession ss, boolean useUnicast)
throws IOException {
byte[] containerExtraParamState = null;
SipSessionExtraParams containerExtraParams
= ss.getExtraParameters();
if(containerExtraParams != null) {
try {
containerExtraParamState
= ReplicationUtil.getByteArray(containerExtraParams, isReplicationCompressionEnabled());
} catch (IOException ex) {
; //deliberate no-op
}
}
if(!useUnicast) {
return new ReplicationState(
MODE_SIP,
ss.getId(),
getApplicationId(),
ss.getVersion(),
0L,
0L,
null,
null,
null,
ReplicationState.RETURN_BROADCAST_MSG_COMMAND,
ReplicationUtil.getByteArray(ss, isReplicationCompressionEnabled()),
null,
containerExtraParamState);
} else {
return new ReplicationState(
MODE_SIP,
ss.getId(),
getApplicationId(),
ss.getVersion(),
0L,
0L,
LOAD_SIP_SESSION_COMMAND, //put original command in extraParam slot
null,
null,
ReplicationState.RETURN_UNICAST_MSG_COMMAND,
ReplicationUtil.getByteArray(ss, isReplicationCompressionEnabled()),
null,
containerExtraParamState);
}
}
private static final String TEMP_MONITOR_KEY_PREFIX = "temp-diagfrag-ss-sas:";
private String getSipSessionMonitorId(String id) {
String monitorId = id;
if (SASLockStatus.isSASLocked()) {
monitorId = id;
} else if (appContainsHttpServlets) {
//Note that sas is not locked here
monitorId = TEMP_MONITOR_KEY_PREFIX + id;
} else {
SASLockStatus.resetSASLockedToDefaultValue();
}
return monitorId;
}
public SipSessionDialogImpl findSipSession(String id,
boolean loadDependencies)
throws RemoteLockException {
String monitorId = getSipSessionMonitorId(id);
Object monitor = getReplicationSessionMonitor(monitorId);
synchronized (monitor) {
return super.findSipSession(id, loadDependencies);
}
}
/**
* Gets the SipApplicationSession with the given id
* from the active cache only
*
* @return The SipSession with the given id, or null if not
* found
*/
public SipSessionDialogImpl findSipSessionFromCacheOnly(String id) {
if (id == null)
return (null);
Object monitor = getReplicationSessionMonitor(id);
synchronized(monitor) {
HASipSession result
= (HASipSession)super.findSipSessionFromCacheOnly(id);
if(!this.isActiveCacheReconciliationOngoing()) {
return result;
} else {
if(result == null || !result.isSuspect()) {
//if null just return it
//if not suspect it has already been checked
return result;
}
if(RollingUpgradeUtil.canUseSuspectSession(result,
sipSessionExpatIdsMap, sipSessionExpatReadWriteLock)) {
//if it passes the check return it
return result;
} else {
removeSipSessionFromCache(result);
return null;
}
}
}
}
protected void clearFromSipSessionManagerCache(String id) {
SipSessionDialogImpl sess
= super.findSipSessionFromCacheOnly(id);
if(sess != null) {
this.removeSipSessionFromCache(sess);
}
}
//ServletTimer process methods
/**
* process the save of a Servlet Timer
* @param timerState - contains the save command
*/
public void processSaveservlettimer(ReplicationState timerState) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN" + this.getClass().getName() + ">>processSaveservlettimer");
}
this.putInServletTimerReplicationCache(timerState);
}
private ReplicationState doUnicastLoadTest(HAServletTimer st) {
//start unicast load test
ReplicationState resultState = null;
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String partnerInstanceName
= healthChecker.getReshapeReplicateToInstanceName(null, 3000L);
ServletTimerStoreImpl stStore = this.getSingletonServletTimerStore();
try {
resultState = stStore.sendUnicastLoadQuery((String)st.getId(), "" + st.getVersion(), partnerInstanceName);
} catch (Throwable th) {
_logger.log(Level.INFO, "error during unicast load test to " + partnerInstanceName, th);
}
return resultState;
//end unicast load test
}
private void processBulkRemoveServletTimer(ReplicationState replicationState) {
servletTimerReplicaCache.removeFromReplicationCache(
replicationState.getState());
}
/**
* process the removal of a Servlet Timer
* @param timerState - contains the remove command
*/
public void processRemoveservlettimer(ReplicationState timerState) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN" + this.getClass().getName() + ">>processRemoveservlettimer");
}
if(timerState == null) {
return;
}
if (timerState.getState() != null) {
processBulkRemoveServletTimer(timerState);
return;
}
String id = (String)timerState.getId();
activationHelper.unregisterServletTimerMigrationTask(id);
//keep track of recent removals
servletTimerReplicaCache.removeFromReplicationCache(id);
//do the cyclical remove if not fronted by CLB
if (!SipReplicationUtil.isInstanceLoadBalancedByCLB()) {
int cycleCount = 0;
String cycleCountString = timerState.getExtraParam();
if(cycleCountString != null) {
try {
cycleCount = Integer.parseInt(cycleCountString);
} catch (Exception ex) {
//ignore
}
}
cycleRemoveServletTimer(id, timerState.getInstanceName(), (cycleCount + 1));
}
}
/**
* process the update of a Servlet Timer
* @param timerState - contains the updatelastaccesstime command
*/
public void processUpdatelastaccesstimeservlettimer(ReplicationState timerState) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN" + this.getClass().getName() +
">>processUpdatelastaccesstimeservlettimer:id: " +
timerState.getId() + ", version: " +
timerState.getVersion());
}
servletTimerReplicaCache.processUpdatelastaccesstime(timerState);
}
public ReplicableEntity findServletTimerAndPassivate(String id,
AtomicBoolean cachedSTIsLocal) {
HAServletTimer haServletTimer = null;
ServletTimerImpl servletTimer
= findServletTimerFromCacheOnly(id);
if (servletTimer instanceof HAServletTimer) {
haServletTimer = (HAServletTimer) servletTimer;
if (haServletTimer != null && !haServletTimer.isForegroundLocked()) {
processLoadReceivedServletTimer(haServletTimer.getId());
}
}
// TODO :: set cachedSTIsLocal value appropriately.
return haServletTimer;
}
/**
* process the FindServletTimer for ServletTimer
* @param queryState
* @param useUnicast
*/
public ReplicationState processFindServletTimer(ReplicationState queryState, boolean useUnicast) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processFindServletTimer:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processFindServletTimer:id=" + queryState.getId());
_logger.fine("in " + this.getClass().getName() + ">>processFindServletTimer:version=" + queryState.getVersion());
}
//look in active cache
AtomicBoolean cachedSTIsLocal = new AtomicBoolean();
HAServletTimer haServletTimer = (HAServletTimer)
findServletTimerAndPassivate((String)queryState.getId(), cachedSTIsLocal);
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processFindServletTimer:cachedTimer: " + haServletTimer);
}
// TODO :: why is cachedSTIsLocal not used? It is used for both SAS and SS.
//look in replica cache
ReplicationState replicaState
= getFromServletTimerReplicationCache((String)queryState.getId());
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processFindServletTimer:replicaState: " + replicaState);
}
ReplicationState returnState
= getBestServletTimer(haServletTimer, replicaState, queryState, useUnicast);
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processFindServletTimer:returnState=" + returnState);
}
return returnState;
}
/**
* process the broadcastfindservlettimer for ServletTimer
* @param queryState
*/
public ReplicationState processBroadcastfindservlettimer(ReplicationState queryState) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindservlettimer:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindservlettimer:id=" + queryState.getId());
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindservlettimer:version=" + queryState.getVersion());
}
return processFindServletTimer(queryState, false);
}
/**
* process the load of a ServletTimer
* @param queryState - contains the load command
*/
public ReplicationState processLoadservlettimer(ReplicationState queryState) {
//complete query and send back response
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processLoadservlettimer:queryState = " + queryState);
_logger.fine("in " + this.getClass().getName() + ">>processLoadservlettimer:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processLoadservlettimer:id=" + queryState.getId());
_logger.fine("in " + this.getClass().getName() + ">>processLoadservlettimer:version=" + queryState.getVersion());
}
return processFindServletTimer(queryState, true);
}
public void processBroadcastloadreceivedservlettimer(ReplicationState queryState) {
//load is acknowledged safe to remove replica now
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processbroadcastloadreceivedservlettimer:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processbroadcastloadreceivedservlettimer:id=" + queryState.getId());
}
if(queryState == null || queryState.getId() == null) {
return;
}
String id = (String)queryState.getId();
processLoadReceivedServletTimer(id);
String ignoreInstance = (String) queryState.getProperty(ReplicationState.IGNORE_REMOVE_INSTANCE_NAME);
//only safe to remove replica if we are not the replica partner
//now determined by passed property
if(ignoreInstance != null && !ignoreInstance.equals(getInstanceName())) {
ReplicationState removed =
removeFromServletTimerReplicationCache(id);
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>processBroadcastloadreceivedservlettimer: Removed replica=" +
removed);
}
}
}
public void processLoadReceivedServletTimer(String id) {
// call unregisterServletTimerExtraParam()
activationHelper.unregisterServletTimerMigrationTask(id);
//remove active timer if present and not locked
ServletTimerImpl timer = findServletTimerFromCacheOnly(id);
if(timer != null && !timer.isForegroundLocked()) {
timer.passivate();
}
}
/**
* process the loadAdvisory of a Servlet Timer
* this should trigger a load call for the ServletTimer
* @param extraParams
*/
public void processLoadadvisoryservlettimer(ServletTimerExtraParams extraParams) {
if(extraParams == null) {
return;
}
processLoadadvisoryservlettimer(extraParams.getId(), null);
//Note: processBroadcastloadreceivedservlettimer will eventually
// call unregisterServletTimerExtraParam()
}
public void processLoadadvisoryservlettimer(ReplicationState timerState) {
if(timerState == null) {
return;
}
processLoadadvisoryservlettimer((String)timerState.getId(), timerState.getInstanceName());
}
public void processLoadadvisoryservlettimer(String id, String fromInstanceName) {
this.processLoadadvisoryservlettimer(id, false, fromInstanceName);
}
public void processLoadadvisoryservlettimer(String id, boolean calledFromSelf, String fromInstanceName) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN" + this.getClass().getName() + ">>processLoadadvisoryservlettimer");
}
if(id == null) {
return;
}
//try to load from local cache first
ServletTimerImpl activeTimer = this.findServletTimerFromCacheOnly(id);
if(activeTimer != null) {
//if calledFromSelf we suppress the load received acknowledgement
if(!calledFromSelf) {
//if we already have an active timer - just short-circuit by calling
//load received
HAServletTimer haTimer = (HAServletTimer)activeTimer;
String beKey = null;
if(haTimer.getParentSASId() != null) {
beKey = SipApplicationSessionUtil.getSipApplicationKey(haTimer.getParentSASId());
}
if (fromInstanceName == null) {
ReplicationState loadReceivedState =
ReplicationState.createBroadcastLoadReceivedState(MODE_SIP, id, this.getApplicationId(), haTimer.getVersion(), instanceName, MESSAGE_BROADCAST_LOAD_RECEIVED_SERVLET_TIMER);
this.sendLoadAcknowledgement(loadReceivedState, beKey);
_logger.log(Level.INFO, "Unexpected send of broadcast loadack in servlet timer load advisory");
}
else {
sendUnicastLoadAcknowledgementST(id, fromInstanceName, beKey);
}
}
} else {
//load and activate ServletTimer
try {
swapInServletTimer(id, true);
} catch (Exception ex) {
_logger.log(Level.WARNING, "st_unable_to_load_in_response_to_loadadvisory", id);
_logger.log(Level.WARNING, ex.getMessage(), ex);
}
}
}
/**
* find the best version of ServletTimer
* removing any stale versions and return query result
* @param activeServletTimer ServletTimer
* from active cache
* @param replicaServletTimer ServletTimer replica
* from replica cache
* @param queryState version requested in query (-1 means
* version unaware
* @param useUnicast
*/
private ReplicationState getBestServletTimer(HAServletTimer activeServletTimer,
ReplicationState replicaServletTimer, ReplicationState queryState, boolean useUnicast) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>getBestServletTimer:activeServletTimer: " + activeServletTimer);
_logger.fine("in " + this.getClass().getName() + ">>getBestServletTimer:replicaServletTimer: " + replicaServletTimer);
_logger.fine("in " + this.getClass().getName() + ">>getBestServletTimer:queryState=" + queryState);
}
ReplicationState bestResult = null;
long queryVersion = queryState.getVersion();
//first check for none found in either active or replica caches
if(replicaServletTimer == null && activeServletTimer == null) {
//return nack
if(useUnicast) {
return ReplicationState.createUnicastQueryResponseFrom(queryState, true);
} else {
return ReplicationState.createQueryResponseFrom(queryState, true);
}
}
//next check for artifacts found in both active and replica caches
if(replicaServletTimer != null && activeServletTimer != null) {
//compare and remove the lesser version
//keeping the higher version as (tentative) best
if(replicaServletTimer.getVersion() <= activeServletTimer.getVersion()) {
//remove stale replica - work with active
removeFromServletTimerReplicationCache((String)replicaServletTimer.getId());
//create appropriate response from active
bestResult
= createServletTimerResponseFrom(activeServletTimer, queryState, useUnicast);
if (activeServletTimer.isForegroundLocked()) {
bestResult.setVersion(Integer.MAX_VALUE);
}
} else {
//remove stale active - work with replica
clearFromServletTimerManagerCache(activeServletTimer.getId());
//create appropriate response from replica
bestResult
= createServletTimerResponseFrom(replicaServletTimer, queryState, useUnicast);
}
} else {
//either replica or active is null and other is non-null
//replica is null and active is not null
if(replicaServletTimer == null) {
//create appropriate response from active
bestResult
= createServletTimerResponseFrom(activeServletTimer, queryState, useUnicast);
if (activeServletTimer.isForegroundLocked()) {
bestResult.setVersion(Integer.MAX_VALUE);
}
} else {
//active is null & replica is not null
//create appropriate response from replica
bestResult
= createServletTimerResponseFrom(replicaServletTimer, queryState, useUnicast);
}
}
return bestResult;
}
private ReplicationState createServletTimerResponseFrom(ReplicationState replicaServletTimer,
ReplicationState queryState, boolean useUnicast) {
//create appropriate response from replica
ReplicationState result = null;
long queryVersion = queryState.getVersion();
if(queryVersion != -1 && replicaServletTimer.getVersion() < queryVersion) {
//return nack & clear stale replica
removeFromServletTimerReplicationCache((String)replicaServletTimer.getId());
if(useUnicast) {
result = ReplicationState.createUnicastQueryResponseFrom(queryState, true);
} else {
result = ReplicationState.createQueryResponseFrom(queryState, true);
}
} else {
//return real response based on replica
if(useUnicast) {
result = ReplicationState.createUnicastQueryResponseFrom(replicaServletTimer, queryState.getCommand());
} else {
result = ReplicationState.createQueryResponseFrom(replicaServletTimer);
}
}
return result;
}
private ReplicationState createServletTimerResponseFrom(HAServletTimer activeServletTimer,
ReplicationState queryState, boolean useUnicast) {
//create appropriate response from active
ReplicationState result = null;
long queryVersion = queryState.getVersion();
if(queryVersion != -1 && activeServletTimer.getVersion() < queryVersion) {
//return nack & clear stale active
clearFromServletTimerManagerCache(activeServletTimer.getId());
if(useUnicast) {
result = ReplicationState.createUnicastQueryResponseFrom(queryState, true);
} else {
result = ReplicationState.createQueryResponseFrom(queryState, true);
}
} else {
//return real response based on active ServletTimer
try {
result = createQueryResponseFrom(activeServletTimer, useUnicast);
} catch (IOException ioe) {
_logger.log(Level.WARNING,
"Failed load: Unable to serialize " + activeServletTimer,
ioe);
// We've been unable to serialize the given active
// ServletTimer.
// Clear it from the active cache and return a nack instead
clearFromServletTimerManagerCache(activeServletTimer.getId());
result = ReplicationState.createQueryResponseFrom(queryState,
true);
}
}
return result;
}
/**
* Converts the given ServletTimer to a ReplicationState.
*
* @param timer The ServletTimer to be converted
*
* @return The ReplicationState corresponding to the given ServletTimer
*/
private ReplicationState createQueryResponseFrom(
HAServletTimer timer, boolean useUnicast) throws IOException {
byte[] containerExtraParamState = null;
ServletTimerExtraParams containerExtraParams
= timer.getExtraParameters();
if(containerExtraParams != null) {
try {
containerExtraParamState
= ReplicationUtil.getByteArray(containerExtraParams, isReplicationCompressionEnabled());
} catch (IOException ex) {
; //deliberate no-op
}
}
if(!useUnicast) {
return new ReplicationState(
MODE_SIP,
timer.getId(),
getApplicationId(),
timer.getVersion(),
0L,
0L,
null,
null,
null,
ReplicationState.RETURN_BROADCAST_MSG_COMMAND,
ReplicationUtil.getByteArray(timer, isReplicationCompressionEnabled()),
null,
containerExtraParamState);
} else {
return new ReplicationState(
MODE_SIP,
timer.getId(),
getApplicationId(),
timer.getVersion(),
0L,
0L,
LOAD_SERVLET_TIMER_COMMAND, //put original command in extraParam slot
null,
null,
ReplicationState.RETURN_UNICAST_MSG_COMMAND,
ReplicationUtil.getByteArray(timer, isReplicationCompressionEnabled()),
null,
containerExtraParamState);
}
}
/**
* Gets the ServletTimer with the given id
* from the active cache only
*
* @return The ServletTimer with the given id, or null if not
* found
*/
public ServletTimerImpl findServletTimerFromCacheOnly(String id) {
if (id == null)
return (null);
Object monitor = getReplicationSessionMonitor(id);
synchronized(monitor) {
ServletTimerImpl st = super.findServletTimerFromCacheOnly(id);
if (st != null && !st.isPersistent()) {
return st;
}
HAServletTimer result = (HAServletTimer)st;
if(!this.isActiveCacheReconciliationOngoing()) {
return result;
} else {
if(result == null || !result.isSuspect()) {
//if null just return it
//if not suspect it has already been checked
return result;
}
if(RollingUpgradeUtil.canUseSuspectSession(result,
servletTimerExpatIdsMap, servletTimerExpatReadWriteLock)) {
//if it passes the check return it
return result;
} else {
removeServletTimerFromCache(result);
return null;
}
}
}
}
protected void clearFromServletTimerManagerCache(String id) {
ServletTimerImpl timer
= super.findServletTimerFromCacheOnly(id);
if(timer != null) {
this.removeServletTimerFromCache(timer);
}
}
public void purge(String owningInstanceName, long purgeStartTime) {
//do not purge if we are the replica partner
//of the owning instance
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String replicatedFromInstanceName
= healthChecker.getReshapeReplicateFromInstanceName();
if(replicatedFromInstanceName != null && replicatedFromInstanceName.equalsIgnoreCase(owningInstanceName)) {
return;
}
purgeSipApplicationSessionsForOwningInstance(owningInstanceName);
purgeSipSessionsForOwningInstance(owningInstanceName);
purgeServletTimersForOwningInstance(owningInstanceName);
}
void purgeSipApplicationSessionsForOwningInstance(String owningInstanceName) {
List idsToRemove = new ArrayList();
BaseCache replicatedSipApplicationSessionsCache = getReplicatedSipApplicationSessions();
Iterator it = replicatedSipApplicationSessionsCache.values();
while(it.hasNext()) {
ReplicationState nextState
= (ReplicationState)it.next();
SipApplicationSessionExtraParams extraParams =
SipApplicationSessionExtraParams.getDeserializedExtraParams(
nextState, isReplicationCompressionEnabled());
if(extraParams != null) {
String nextOwningInstance = extraParams.getCurrentOwnerInstanceName();
if(nextOwningInstance != null
&& nextOwningInstance.equalsIgnoreCase(owningInstanceName)) {
idsToRemove.add((String)nextState.getId());
}
}
}
for(int i=0; i< idsToRemove.size(); i++) {
removeFromSipApplicationSessionReplicationCache((String)idsToRemove.get(i));
}
}
/*
HashSet<ExpatListElement> getSASExpatIds(
String requestingInstance, boolean consultActiveCache) {
// List expatIds = new ArrayList();
//using set to avoid dups
HashSet expatIds = new HashSet();
BaseCache replicatedSipApplicationSessionsCache = getReplicatedSipApplicationSessions();
Iterator it = replicatedSipApplicationSessionsCache.values();
long version = -1L;
while (it.hasNext()) {
ReplicationState state = (ReplicationState) it.next();
String sasId = (String) state.getId();
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (requestingInstance.equalsIgnoreCase(rightfulOwner)) {
version = state.getVersion();
expatIds.add(new ExpatListElement(sasId, version, instanceName));
}
}
if (consultActiveCache) {
try {
//iterate over active sas cache
Iterator it2 = applicationSessions.values().iterator();
while (it2.hasNext()) {
HASipApplicationSession sas = (HASipApplicationSession) it2.next();
String sasId = (String) sas.getId();
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (requestingInstance.equalsIgnoreCase(rightfulOwner)) {
version = sas.getVersion();
expatIds.add(new ExpatListElement(sasId, version,
instanceName, true));
}
}
} catch (NoSuchFieldError e) {
;
}
}
return expatIds;
}
*/
/**
* Get the SAS' expat list from the active cache for a given instance.
*/
HashSet<ExpatListElement> getSASExpatIdsFromActive(String requestingInstance) {
HashSet expatIds = new HashSet();
long version = -1L;
try {
//iterate over active sas cache
Iterator it2 = applicationSessions.values().iterator();
while (it2.hasNext()) {
HASipApplicationSession sas = (HASipApplicationSession) it2.next();
String sasId = (String) sas.getId();
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (requestingInstance.equalsIgnoreCase(rightfulOwner)) {
version = sas.getVersion();
expatIds.add(new ExpatListElement(sasId, version,
instanceName, true));
}
}
} catch (NoSuchFieldError e) {
;
}
return expatIds;
}
/**
* Get the SAS' expat list from the replica cache for a given instance.
*/
HashSet<ExpatListElement> getSASExpatIdsFromReplica(String requestingInstance) {
HashSet expatIds = new HashSet();
BaseCache replicatedSipApplicationSessionsCache = getReplicatedSipApplicationSessions();
Iterator it = replicatedSipApplicationSessionsCache.values();
long version = -1L;
while (it.hasNext()) {
ReplicationState state = (ReplicationState) it.next();
String sasId = (String) state.getId();
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (requestingInstance.equalsIgnoreCase(rightfulOwner)) {
version = state.getVersion();
expatIds.add(new ExpatListElement(sasId, version, instanceName));
}
}
return expatIds;
}
/**
* Get the SAS' expat list from the active cache for all the surviving instances.
*/
private void getSASExpatIdsFromActive(ExpatListQueryResults results) {
long version = -1L;
//iterate over active sas cache
Iterator it2 = applicationSessions.values().iterator();
while (it2.hasNext()) {
HASipApplicationSession sas = (HASipApplicationSession) it2.next();
String sasId = (String) sas.getId();
if (sasId != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (rightfulOwner != null
&& !rightfulOwner.equalsIgnoreCase(instanceName)) {
version = sas.getVersion();
ExpatListElement expatElement = new ExpatListElement(sasId,
version, instanceName, true);
results.addQueryResultFor(rightfulOwner, expatElement);
}
}
}
}
/**
* Get the SAS' expat list from the replica cache for all the surviving instances.
*/
private void getSASExpatIdsFromReplica(ExpatListQueryResults results) {
//iterate over sip application session replicas
BaseCache replicatedSipApplicationSessionsCache = getReplicatedSipApplicationSessions();
Iterator it = replicatedSipApplicationSessionsCache.values();
long version = -1L;
while (it.hasNext()) {
ReplicationState state = (ReplicationState) it.next();
String sasId = (String) state.getId();
if (sasId != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
version = state.getVersion();
ExpatListElement expatElement = new ExpatListElement(sasId,
version, instanceName);
results.addQueryResultFor(rightfulOwner, expatElement);
}
}
}
/*
private void getAllSASExpatIds(ExpatListQueryResults results) {
//iterate over sip application session replicas
BaseCache replicatedSipApplicationSessionsCache = getReplicatedSipApplicationSessions();
Iterator it = replicatedSipApplicationSessionsCache.values();
long version = -1L;
while (it.hasNext()) {
ReplicationState state = (ReplicationState) it.next();
String sasId = (String) state.getId();
if (sasId != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
version = state.getVersion();
ExpatListElement expatElement = new ExpatListElement(sasId,
version, instanceName);
results.addQueryResultFor(rightfulOwner, expatElement);
}
}
//iterate over active sas cache
Iterator it2 = applicationSessions.values().iterator();
while (it2.hasNext()) {
HASipApplicationSession sas = (HASipApplicationSession) it2.next();
String sasId = (String) sas.getId();
if (sasId != null) {
String rightfulOwner = SipApplicationSessionUtil.
getActualServerInstance(sasId);
if (rightfulOwner != null
&& !rightfulOwner.equalsIgnoreCase(instanceName)) {
version = sas.getVersion();
ExpatListElement expatElement = new ExpatListElement(sasId,
version, instanceName, true);
results.addQueryResultFor(rightfulOwner, expatElement);
}
}
}
}
*/
/*
List getSipApplicationSessionExpatIdsThirdPartySPI(String owningInstanceName) {
BackingStore sipApplicationSessionBackingStore
= this.getSipApplicationSessionBackingStore();
SipApplicationSessionExtraParams sasExtraParamCriteria
= SipApplicationSessionExtraParams.createSearchCriteria(
getApplicationId(), owningInstanceName);
Collection<SipApplicationSessionExtraParams> sasColl
= sipApplicationSessionBackingStore.findByCriteria(sasExtraParamCriteria);
List expatIds = new ArrayList();
//using set to avoid dups
HashSet expatIdsSet = new HashSet();
Iterator<SipApplicationSessionExtraParams> sasResults =
(Iterator<SipApplicationSessionExtraParams>) sasColl.iterator();
while (sasResults.hasNext()) {
SipApplicationSessionExtraParams eParam = sasResults.next();
if (owningInstanceName.equals(eParam.getCurrentOwnerInstanceName())) {
expatIdsSet.add(new ExpatListElement((String)eParam.getId(), -1L, null));
}
}
//iterate over active sas cache
long nextVersion = -1L;
Iterator it2 = applicationSessions.values().iterator();
while(it2.hasNext()) {
HASipApplicationSession nextSipApplicationSession
= (HASipApplicationSession)it2.next();
String nextSipApplicationSessionId
= (String)nextSipApplicationSession.getId();
String nextRightfulOwnerInstanceName
= SipApplicationSessionUtil.getActualServerInstance(nextSipApplicationSessionId);
if(nextRightfulOwnerInstanceName != null
&& nextRightfulOwnerInstanceName.equalsIgnoreCase(owningInstanceName)) {
nextVersion = nextSipApplicationSession.getVersion();
expatIdsSet.add(new ExpatListElement(nextSipApplicationSessionId, nextVersion, getInstanceName()));
}
}
expatIds.addAll(expatIdsSet);
return expatIds;
}
*/
void purgeSipSessionsForOwningInstance(String owningInstanceName) {
List idsToRemove = new ArrayList();
BaseCache replicatedSipSessionsCache = getReplicatedSipSessions();
Iterator it = replicatedSipSessionsCache.values();
while(it.hasNext()) {
ReplicationState nextState
= (ReplicationState)it.next();
SipSessionExtraParams extraParams =
SipSessionExtraParams.getDeserializedExtraParams(
nextState, isReplicationCompressionEnabled());
if(extraParams != null) {
String nextOwningInstance = extraParams.getCurrentOwnerInstanceName();
if(nextOwningInstance != null
&& nextOwningInstance.equalsIgnoreCase(owningInstanceName)) {
idsToRemove.add((String)nextState.getId());
}
}
}
for(int i=0; i< idsToRemove.size(); i++) {
removeFromSipSessionReplicationCache((String)idsToRemove.get(i));
}
}
void purgeServletTimersForOwningInstance(String owningInstanceName) {
List idsToRemove = new ArrayList();
BaseCache replicatedServletTimersCache = getReplicatedServletTimers();
Iterator it = replicatedServletTimersCache.values();
while(it.hasNext()) {
ReplicationState nextState
= (ReplicationState)it.next();
ServletTimerExtraParams extraParams =
ServletTimerExtraParams.getDeserializedExtraParams(
nextState, isReplicationCompressionEnabled());
if(extraParams != null) {
String nextOwningInstance = extraParams.getCurrentOwnerInstanceName();
if(nextOwningInstance != null
&& nextOwningInstance.equalsIgnoreCase(owningInstanceName)) {
idsToRemove.add((String)nextState.getId());
}
}
}
for(int i=0; i< idsToRemove.size(); i++) {
removeFromServletTimerReplicationCache((String)idsToRemove.get(i));
}
}
//end receiver side process methods
//start expiration related methods
private long deltaMillis = -1L;
/**
* a delta adjustment applied to the calculated wiggle adjustment
* this is to insure that SipSessions and DialogFragments are
* not prematurely purged by the reaper thread before an active
* SAS has possibly extended their expiration times
*/
protected long getDeltaMillis() {
if(deltaMillis == -1L) {
long reapIntervalSeconds
= this.getContext().getBackgroundProcessorDelay();
deltaMillis = Math.max(ActivationHelper.DELAYED_EXPIRATION,
(reapIntervalSeconds * 1000 * 2));
}
return deltaMillis;
}
// void processExpiredSipApplicationSessionReplicas() {
// //code assumes that isExpired works for this type of ReplicationState
// if(_logger.isLoggable(Level.FINE)) {
// _logger.fine("in " + this.getClass().getName() + ">>processExpiredSipApplicationSessionReplicas");
// }
// int expiredReplicas = 0;
// BaseCache replicatedSipApplicationSessionsCache = getReplicatedSipApplicationSessions();
// for (Iterator it = replicatedSipApplicationSessionsCache.keys();
// it.hasNext();) {
// ReplicationState nextState = (ReplicationState)
// replicatedSipApplicationSessionsCache.get((String)it.next());
// if (nextState != null) {
// if (_logger.isLoggable(Level.FINE)) {
// _logger.fine("in " + this.getClass().getName() +
// ">>processExpiredSipApplicationSessionReplicas: " +
// "nextState=" + nextState);
// }
// if (isTimeForSipApplicationSessionLoadAdvisory(nextState)) {
// //if(!LoadProcessingGovernor.isSystemUnderLoadStress()
// // && !SipReplicationUtil.isExpatInProgress()) {
// if(!ExpatListHandler.isExpatInProgress()) {
// expiredReplicas++;
// processExpiredSipApplicationSessionReplica(nextState);
// }
// }
// }
// }
// if(_logger.isLoggable(Level.FINE)) {
// _logger.fine("in " + this.getClass().getName() +
// ">>processExpiredSipApplicationSessionReplicas: expiredReplicas.size=" +
// expiredReplicas);
// }
// }
/*
private void processExpiredSipApplicationSessionReplica(
ReplicationState state) {
processExpiredSipApplicationSessionReplicaById((String) state.getId(), state.getInstanceName());
}
private void processExpiredSipApplicationSessionReplicaById(
String nextId, String fromInstanceName) {
try {
String rightfulOwnerInstanceName =
SipReplicationUtil.getCurrentServerInstance(nextId);
if (rightfulOwnerInstanceName == null) {
_logger.warning(
"in " + this.getClass().getName() +
">>processExpiredSipApplicationSessionReplica: " +
"No rightful owner instance returned by " +
"DataCentricUtil for SipApplicationSession " +
"with id: " + nextId);
// FIXME Skip this SAS id by removing it from replica cache
return;
}
if(getInstanceName().equals(rightfulOwnerInstanceName)) {
//short circuit version of load advisory
processLoadadvisorysas(nextId, true, fromInstanceName);
} else {
sendLoadAdvisorySipApplicationSession(
nextId, rightfulOwnerInstanceName);
}
} catch (Throwable t) {
_logger.log(Level.WARNING,
"in " + this.getClass().getName() +
">>processExpiredSipApplicationSessionReplica: " +
"Unable to process expiration of " +
"SipApplicationSession replica with id: " +
nextId, t);
// FIXME Skip this SAS id by removing it from replica cache
}
}
*/
private SipApplicationSessionExtraParams getSipApplicationSessionExtraParamsFrom(ReplicationState state) {
if(state == null) {
return null;
}
if(state.getDeserializedExtraParam() != null) {
return (SipApplicationSessionExtraParams)state.getDeserializedExtraParam();
} else {
//deserialize and cache result in state
SipApplicationSessionExtraParams extraParams =
SipApplicationSessionExtraParams.getDeserializedExtraParams(
state, isReplicationCompressionEnabled());
state.setDeserializedExtraParam(extraParams);
return extraParams;
}
}
protected boolean isTimeForSipApplicationSessionLoadAdvisory(ReplicationState state) {
SipApplicationSessionExtraParams extraParams
= getSipApplicationSessionExtraParamsFrom(state);
return isTimeForSipApplicationSessionLoadAdvisory(extraParams);
}
protected boolean isTimeForSipApplicationSessionLoadAdvisory(SipApplicationSessionExtraParams extraParams) {
if(extraParams == null) {
return false;
} else {
if(extraParams.getExpirationTime() <= 0) { //infinite case
long timeSinceLastAccessed
= System.currentTimeMillis() - extraParams.getInternalLastAccessedTime();
return(timeSinceLastAccessed > (ActivationHelper.SAS_TIMER_MAX_THRESHOLD_IN_MILLIS + 1));
} else {
return (System.currentTimeMillis() >= extraParams.getWiggledExpirationTime());
}
}
}
// void processExpiredSipApplicationSessionReplicasThirdPartySPI() {
// //code assumes that isExpired works for this type of ReplicationState
// if(_logger.isLoggable(Level.FINE)) {
// _logger.fine("in " + this.getClass().getName() + ">>processExpiredSipApplicationSessionReplicasThirdPartySPI");
// }
// ArrayList expiredReplicas = new ArrayList(30);
// List sasExtraParams = getSipApplicationSessionExtraParamsThirdPartySPI();
// for(Iterator it = sasExtraParams.iterator(); it.hasNext();) {
// SipApplicationSessionExtraParams nextExtraParam = (SipApplicationSessionExtraParams)it.next();
// if(_logger.isLoggable(Level.FINE)) {
// _logger.fine("in " + this.getClass().getName() + " nextExtraParam=" + nextExtraParam);
// }
// if(isTimeForSipApplicationSessionLoadAdvisory(nextExtraParam)) {
// expiredReplicas.add(nextExtraParam);
// }
// }
// if(_logger.isLoggable(Level.FINE)) {
// _logger.fine("processExpiredSipApplicationSessionReplicasThirdPartySPI:expiredReplicas.size=" + expiredReplicas.size());
// }
// for(int i=0; i<expiredReplicas.size(); i++) {
// SipApplicationSessionExtraParams nextExtraParam =
// (SipApplicationSessionExtraParams)expiredReplicas.get(i);
// String rightfulOwnerInstanceName
// = SipApplicationSessionUtil.getActualServerInstance((String)nextExtraParam.getId());
// this.sendLoadAdvisorySipApplicationSession((String)nextExtraParam.getId(), rightfulOwnerInstanceName);
// }
// }
//
//TODO: Remove processExpiredSipApplicationSessionReplicasThirdPartySPI() method
//TODO: Remove getSipApplicationSessionExtraParamsThirdPartySPI() method
//
public void sendSASLoadAdvisories(String instanceName,
HashSet<String> expiredReplicaIds) {
SipApplicationSessionStoreImpl store = null;
try {
store = getSipApplicationSessionStore();
if (store != null) {
store.sendLoadAdvisories(instanceName, expiredReplicaIds);
}
} finally {
this.putSipApplicationSessionStore(store);
}
}
void processExpiredSASReplicas(Map<String, HashSet<String>> expiredReplicaMap) {
HashSet<String> expiredInSelfReplica = new HashSet();
for(String instance : expiredReplicaMap.keySet()) {
HashSet<String> expiredReplicaIds = expiredReplicaMap.get(instance);
if(ReplicationUtil.getInstanceName().equalsIgnoreCase(instance)) {
// process our own expired replicas after sending load advisories.
expiredInSelfReplica = expiredReplicaIds;
} else {
sendSASLoadAdvisories(instance, expiredReplicaIds);
}
}
for(String expiredReplicaId : expiredInSelfReplica) {
HASipApplicationSession sas =
processLoadadvisorysas(expiredReplicaId);
if(sas != null) {
removeFromSipApplicationSessionReplicationCache(sas.getId());
}
}
}
void _processExpiredSipApplicationSessions() {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processExpiredSipApplicationSessionReplicasThirdPartySPI");
}
Map<String, HashSet<String>> expiredReplicaMap =
new HashMap<String, HashSet<String>>();
BackingStore sipApplicationSessionBackingStore
= this.getSipApplicationSessionBackingStore();
String applicationId = this.getApplicationId();
SipApplicationSessionExtraParams sasExtraParamCriteria
= SipApplicationSessionExtraParams.createSearchCriteriaAppid(this, applicationId);
Collection<SipApplicationSessionExtraParams> expiredReplicas
= (Collection<SipApplicationSessionExtraParams>)
sipApplicationSessionBackingStore.findByCriteria(null, sasExtraParamCriteria); //TODO: pass criteria
for (SipApplicationSessionExtraParams nextExtraParam : expiredReplicas) {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + " nextExtraParam=" + nextExtraParam);
}
if (this.isTimeForSipApplicationSessionLoadAdvisory(nextExtraParam)) {
String sasId = nextExtraParam.getId();
String rightfulOwnerInstanceName =
SipReplicationUtil.getCurrentServerInstance(sasId);
HashSet s = expiredReplicaMap.get(rightfulOwnerInstanceName);
if(s == null) {
s = new HashSet<String>();
expiredReplicaMap.put(rightfulOwnerInstanceName, s);
}
s.add(sasId);
}
}
processExpiredSASReplicas(expiredReplicaMap);
}
Collection<SipApplicationSessionExtraParams> _findByCriteriaExpiredSipApplicationSessions(SipApplicationSessionExtraParams criteria) {
Collection<SipApplicationSessionExtraParams> result =
new LinkedList<SipApplicationSessionExtraParams>();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processExpiredSipApplicationSessionReplicas");
}
int expiredReplicas = 0;
BaseCache replicatedSipAppSessionsCache = getReplicatedSipApplicationSessions();
for(Iterator it = replicatedSipAppSessionsCache.keys(); it.hasNext();) {
ReplicationState nextState = (ReplicationState)
replicatedSipAppSessionsCache.get((String) it.next());
if (nextState != null) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>_findByCriteria_ExpiredSAS: nextState=" +
nextState);
}
if (isTimeForSipApplicationSessionLoadAdvisory(nextState)) {
//if(!LoadProcessingGovernor.isSystemUnderLoadStress()
// && !SipReplicationUtil.isExpatExtraDurationInEffect()
// && !SipReplicationUtil.isExpatInProgress()) {
if(!ExpatListHandler.isExpatExtraDurationInEffect()
&& !ExpatListHandler.isExpatInProgress()) {
expiredReplicas++;
result.add(getSipApplicationSessionExtraParamsFrom(nextState));
}
}
}
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>processExpiredSipApplicationSessionReplicas: expiredReplicas.size=" +
expiredReplicas);
}
return result;
}
// List getSipApplicationSessionExtraParamsThirdPartySPI() {
// BackingStore sipApplicationSessionBackingStore
// = this.getSipApplicationSessionBackingStore();
// String applicationId = this.getApplicationId();
// SipApplicationSessionExtraParams sasExtraParamCriteria
// = SipApplicationSessionExtraParams.createSearchCriteriaAppid(applicationId);
// Collection<SipApplicationSessionExtraParams> sasColl
// = sipApplicationSessionBackingStore.findByCriteria(sasExtraParamCriteria);
//
// List result = new ArrayList();
// Iterator<SipApplicationSessionExtraParams> sasResults =
// (Iterator<SipApplicationSessionExtraParams>) sasColl.iterator();
// while (sasResults.hasNext()) {
// SipApplicationSessionExtraParams eParam = sasResults.next();
// if (applicationId.equals(eParam.getAppId())) {
// result.add(eParam);
// }
// }
// return result;
// }
void processExpiredSipSessionReplicas() {
//code assumes that isExpired works for this type of ReplicationState
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processExpiredSipSessionReplicas");
}
int expiredReplicas = 0;
BaseCache replicatedSipSessionsCache = getReplicatedSipSessions();
for(Iterator it = replicatedSipSessionsCache.keys(); it.hasNext();) {
ReplicationState nextState = (ReplicationState)
replicatedSipSessionsCache.get((String) it.next());
if (nextState != null) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>processExpiredSipSessionReplicas: nextState=" +
nextState);
}
if (isExpiredSipSessionReplica(nextState)) {
//if(!LoadProcessingGovernor.isSystemUnderLoadStress()
// && !SipReplicationUtil.isExpatExtraDurationInEffect()
// && !SipReplicationUtil.isExpatInProgress()) {
if(!ExpatListHandler.isExpatExtraDurationInEffect()
&& !ExpatListHandler.isExpatInProgress()) {
expiredReplicas++;
removeFromSipSessionReplicationCache((String)nextState.getId());
}
}
}
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>processExpiredSipSessionReplicas: expiredReplicas.size=" +
expiredReplicas);
}
}
private SipSessionExtraParams getSipSessionExtraParamsFrom(ReplicationState state) {
if(state == null) {
return null;
}
if(state.getDeserializedExtraParam() != null) {
return (SipSessionExtraParams)state.getDeserializedExtraParam();
} else {
//deserialize and cache result in state
SipSessionExtraParams extraParams =
SipSessionExtraParams.getDeserializedExtraParams(
state, isReplicationCompressionEnabled());
state.setDeserializedExtraParam(extraParams);
return extraParams;
}
}
void processExpiredSipSessionReplicasThirdPartySPI() {
//code assumes that isExpired works for this type of ReplicationState
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processExpiredSipSessionReplicasThirdPartySPI");
}
ArrayList expiredReplicas = new ArrayList(30);
List sipSessionExtraParams = getSipSessionExtraParamsThirdPartySPI();
for(Iterator it = sipSessionExtraParams.iterator(); it.hasNext();) {
SipSessionExtraParams nextExtraParam = (SipSessionExtraParams)it.next();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + " nextExtraParam=" + nextExtraParam);
}
if(isExpiredSipSessionReplica(nextExtraParam)) {
expiredReplicas.add(nextExtraParam);
}
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("processExpiredSipSessionReplicasThirdPartySPI:expiredReplicas.size=" + expiredReplicas.size());
}
for(int i=0; i<expiredReplicas.size(); i++) {
SipApplicationSessionExtraParams nextExtraParam =
(SipApplicationSessionExtraParams)expiredReplicas.get(i);
this.removeSipSession((String)nextExtraParam.getId());
}
}
public void _processExpiredSipSessions() {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>_process_ExpiredSipSessions");
}
BackingStore sipSessionBackingStore
= this.getSipSessionBackingStore();
String applicationId = this.getApplicationId();
SipSessionExtraParams sipSessionExtraParamCriteria
= SipSessionExtraParams.createSearchCriteriaAppid(
this, applicationId);
Collection<SipSessionExtraParams> sipSessionColl
= sipSessionBackingStore.findByCriteria(null, sipSessionExtraParamCriteria);
for (SipSessionExtraParams nextExtraParam : sipSessionColl) {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + " nextExtraParam=" + nextExtraParam);
}
if (isExpiredSipSessionReplica(nextExtraParam)) {
if (!ExpatListHandler.isExpatExtraDurationInEffect()
&& !ExpatListHandler.isExpatInProgress()) {
removeFromSipSessionReplicationCache(nextExtraParam.getId());
}
}
}
}
Collection<SipSessionExtraParams> _findByCriteriaExpiredSipSessions() {
//code assumes that isExpired works for this type of ReplicationState
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processExpiredSipSessionReplicas");
}
Collection<SipSessionExtraParams> result = new
LinkedList<SipSessionExtraParams>();
BaseCache replicatedSipSessionsCache = getReplicatedSipSessions();
for(Iterator it = replicatedSipSessionsCache.keys(); it.hasNext();) {
ReplicationState nextState = (ReplicationState)
replicatedSipSessionsCache.get((String) it.next());
if (nextState != null) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>_findByCriteria_ExpiredSipSessions: nextState=" +
nextState);
}
if (isExpiredSipSessionReplica(nextState)) {
//if(!LoadProcessingGovernor.isSystemUnderLoadStress()
// && !SipReplicationUtil.isExpatExtraDurationInEffect()
// && !SipReplicationUtil.isExpatInProgress()) {
if(!ExpatListHandler.isExpatExtraDurationInEffect()
&& !ExpatListHandler.isExpatInProgress()) {
result.add(getSipSessionExtraParamsFrom(nextState));
}
}
}
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>_findByCriteria_ExpiredSipSessions: expiredReplicas.size=" +
result.size());
}
return result;
}
List getSipSessionExtraParamsThirdPartySPI() {
BackingStore sipSessionBackingStore
= this.getSipSessionBackingStore();
String applicationId = this.getApplicationId();
SipSessionExtraParams sipSessionExtraParamCriteria
= SipSessionExtraParams.createSearchCriteriaAppid(this, applicationId);
Collection<SipSessionExtraParams> sipSessionColl
= sipSessionBackingStore.findByCriteria(null, sipSessionExtraParamCriteria);
List result = new ArrayList();
Iterator<SipSessionExtraParams> sipSessionResults =
(Iterator<SipSessionExtraParams>) sipSessionColl.iterator();
while (sipSessionResults.hasNext()) {
SipSessionExtraParams eParam = sipSessionResults.next();
if (applicationId.equals(eParam.getAppId())) {
result.add(eParam);
}
}
return result;
}
protected boolean isExpiredSipSessionReplica(ReplicationState state) {
SipSessionExtraParams extraParams
= getSipSessionExtraParamsFrom(state);
return isExpiredSipSessionReplica(extraParams);
}
protected boolean isExpiredSipSessionReplica(SipSessionExtraParams extraParams) {
if(extraParams == null) {
return false;
} else {
long nextExpirationTime = extraParams.getExpirationTime();
//expirationTime of 0 or -1 means infinite
//in this case we expire if duration since last access
//is greater than SERVLET_TIMER_MAX_THRESHOLD_IN_MILLIS
if(nextExpirationTime == 0L || nextExpirationTime == -1L) {
if( (System.currentTimeMillis() - extraParams.getInternalLastAccessedTime()) > ActivationHelper.SERVLET_TIMER_MAX_THRESHOLD_IN_MILLIS ) {
return true;
} else {
return false;
}
} else {
return (System.currentTimeMillis() >= (nextExpirationTime + getDeltaMillis()));
}
}
}
void processExpiredServletTimerReplicas() {
//code assumes that isExpired works for this type of ReplicationState
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processExpiredServletTimerReplicas");
}
int expiredReplicas = 0;
BaseCache replicatedServletTimersCache = getReplicatedServletTimers();
for (Iterator it = replicatedServletTimersCache.keys(); it.hasNext();) {
ReplicationState nextState = (ReplicationState)
replicatedServletTimersCache.get((String) it.next());
if (nextState != null) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>processExpiredServletTimerReplicas: nextState=" +
nextState);
}
if (isTimeForServletTimerLoadAdvisory(nextState)) {
//if(!LoadProcessingGovernor.isSystemUnderLoadStress()
// && !SipReplicationUtil.isExpatInProgress()) {
if(!ExpatListHandler.isExpatInProgress()) {
expiredReplicas++;
processExpiredServletTimerReplica(nextState);
}
}
}
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>processExpiredServletTimerReplicas: expiredReplicas.size=" +
expiredReplicas);
}
}
private void processExpiredServletTimerReplica(ReplicationState state) {
ServletTimerExtraParams extraParams
= (ServletTimerExtraParams)state.getContainerExtraParams();
processExpiredServletTimerReplica(extraParams, state.getInstanceName());
}
private void processExpiredServletTimerReplica(ServletTimerExtraParams extraParams, String fromInstanceName) {
if (extraParams == null || extraParams.getParentSasId() == null) {
return;
}
String sasId = extraParams.getParentSasId();
String id = extraParams.getId(); //TODO: Verify. Was: String id = (String)state.getId();
try {
String rightfulOwnerInstanceName =
SipReplicationUtil.getCurrentServerInstance(sasId);
if (rightfulOwnerInstanceName == null) {
_logger.warning(
"in " + this.getClass().getName() +
">>processExpiredServletTimerReplica: " +
"No rightful owner instance returned by " +
"DataCentricUtil for SipApplicationSession " +
"with id: " + sasId);
// FIXME Skip this ST id by removing it from replica cache
return;
}
if (getInstanceName().equals(rightfulOwnerInstanceName)) {
//short circuit version of load advisory
processLoadadvisoryservlettimer(id, true, fromInstanceName);
} else {
sendLoadAdvisoryServletTimer(id, rightfulOwnerInstanceName);
}
} catch (Throwable t) {
_logger.log(Level.WARNING,
"in " + this.getClass().getName() +
">>processExpiredServletTimerReplica: " +
"Unable to process expiration of " +
"ServletTimer replica with id: " + id, t);
// FIXME Skip this ST id by removing it from replica cache
}
}
private ServletTimerExtraParams getServletTimerExtraParamsFrom(ReplicationState state) {
if(state == null) {
return null;
}
if(state.getDeserializedExtraParam() != null) {
return (ServletTimerExtraParams)state.getDeserializedExtraParam();
} else {
//deserialize and cache result in state
ServletTimerExtraParams extraParams =
ServletTimerExtraParams.getDeserializedExtraParams(
state, isReplicationCompressionEnabled());
state.setDeserializedExtraParam(extraParams);
return extraParams;
}
}
void _processExpiredServletTimers() {
//code assumes that isExpired works for this type of ReplicationState
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processExpiredServletTimerReplicasThirdPartySPI");
}
BackingStore servletTimerBackingStore
= this.getServletTimerBackingStore();
String applicationId = this.getApplicationId();
ServletTimerExtraParams servletTimerExtraParamCriteria
= ServletTimerExtraParams.createSearchCriteriaAppid(this, applicationId);
Collection<ServletTimerExtraParams> servletTimerColl
= servletTimerBackingStore.findByCriteria(
null, servletTimerExtraParamCriteria);
int count = 0;
for (ServletTimerExtraParams nextExtraParam : servletTimerColl) {
if (_logger.isLoggable(Level.FINE)) {
if (isTimeForServletTimerLoadAdvisory(nextExtraParam)) {
//if(!LoadProcessingGovernor.isSystemUnderLoadStress()
// && !SipReplicationUtil.isExpatInProgress()) {
if (!ExpatListHandler.isExpatInProgress()) {
count++;
processExpiredServletTimerReplica(nextExtraParam, nextExtraParam.getCurrentOwnerInstanceName());
}
}
}
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("_process_ExpiredServletTimers:expiredReplicas.size=" + count);
}
}
}
Collection<ServletTimerExtraParams> _findByCriteriaExpiredServletTimers(ServletTimerExtraParams stEP) {
Collection<ServletTimerExtraParams> result = new LinkedList<ServletTimerExtraParams>();
//code assumes that isExpired works for this type of ReplicationState
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processExpiredServletTimerReplicas");
}
int expiredReplicas = 0;
BaseCache replicatedServletTimersCache = getReplicatedServletTimers();
for (Iterator it = replicatedServletTimersCache.keys(); it.hasNext();) {
ReplicationState nextState = (ReplicationState)
replicatedServletTimersCache.get((String) it.next());
if (nextState != null) {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>_findByCriteria_ExpiredServletTimers: nextState=" +
nextState);
}
if (isTimeForServletTimerLoadAdvisory(nextState)) {
//if(!LoadProcessingGovernor.isSystemUnderLoadStress()
// && !SipReplicationUtil.isExpatInProgress()) {
if (!ExpatListHandler.isExpatInProgress()) {
expiredReplicas++;
result.add(getServletTimerExtraParamsFrom(nextState));
}
}
}
}
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() +
">>_findByCriteria_ExpiredServletTimers: expiredReplicas.size=" +
expiredReplicas);
}
return result;
}
// void processExpiredServletTimerReplicasThirdPartySPI() {
// //code assumes that isExpired works for this type of ReplicationState
// if(_logger.isLoggable(Level.FINE)) {
// _logger.fine("in " + this.getClass().getName() + ">>processExpiredServletTimerReplicasThirdPartySPI");
// }
// ArrayList expiredReplicas = new ArrayList(30);
// List servletTimerExtraParams = getServletTimerExtraParamsThirdPartySPI();
// for(Iterator it = servletTimerExtraParams.iterator(); it.hasNext();) {
// ServletTimerExtraParams nextExtraParam = (ServletTimerExtraParams)it.next();
// if(_logger.isLoggable(Level.FINE)) {
// _logger.fine("in " + this.getClass().getName() + " nextExtraParam=" + nextExtraParam);
// }
// if(isTimeForServletTimerLoadAdvisory(nextExtraParam)) {
// expiredReplicas.add(nextExtraParam);
// }
// }
// if(_logger.isLoggable(Level.FINE)) {
// _logger.fine("processExpiredServletTimerReplicasThirdPartySPI:expiredReplicas.size=" + expiredReplicas.size());
// }
// for(int i=0; i<expiredReplicas.size(); i++) {
// ServletTimerExtraParams nextExtraParam =
// (ServletTimerExtraParams)expiredReplicas.get(i);
// if(nextExtraParam.getParentSasId() != null) {
// String sasId = nextExtraParam.getParentSasId();
// String rightfulOwnerInstanceName
// = SipApplicationSessionUtil.getActualServerInstance(sasId);
// this.sendLoadAdvisoryServletTimer((String)nextExtraParam.getId(), rightfulOwnerInstanceName);
// }
// }
// }
//
// List getServletTimerExtraParamsThirdPartySPI() {
// BackingStore servletTimerBackingStore
// = this.getServletTimerBackingStore();
// String applicationId = this.getApplicationId();
// ServletTimerExtraParams servletTimerExtraParamCriteria
// = ServletTimerExtraParams.createSearchCriteriaAppid(this, applicationId);
// Collection<ServletTimerExtraParams> servletTimerColl
// = servletTimerBackingStore.findByCriteria(null, servletTimerExtraParamCriteria);
//
// List result = new ArrayList();
// Iterator<ServletTimerExtraParams> servletTimerResults =
// (Iterator<ServletTimerExtraParams>) servletTimerColl.iterator();
// while (servletTimerResults.hasNext()) {
// ServletTimerExtraParams eParam = servletTimerResults.next();
// if (applicationId.equals(eParam.getAppId())) {
// result.add(eParam);
// }
// }
// return result;
// }
protected boolean isTimeForServletTimerLoadAdvisory(ReplicationState state) {
ServletTimerExtraParams extraParams
= getServletTimerExtraParamsFrom(state);
return isTimeForServletTimerLoadAdvisory(extraParams);
}
protected boolean isTimeForServletTimerLoadAdvisory(ServletTimerExtraParams extraParams) {
if(extraParams == null) {
return false;
} else {
if(extraParams.getExpirationTime() <= 0) { //infinite case
long timeSinceLastAccessed
= System.currentTimeMillis() - extraParams.getInternalLastAccessedTime();
return(timeSinceLastAccessed > (ActivationHelper.SERVLET_TIMER_MAX_THRESHOLD_IN_MILLIS + 1));
} else {
return (System.currentTimeMillis() >= extraParams.getWiggledExpirationTime());
}
}
}
private boolean applySipApplicationSessionTimingHeuristicTo(long timerExpirationTime) {
return activationHelper.calculateSasTimerTaskScheduleTime(timerExpirationTime) == 0L;
}
private boolean applyServletTimerTimingHeuristicTo(long timerExpirationTime) {
return activationHelper.calculateServletTimerTaskScheduleTime(timerExpirationTime) == 0L;
}
//end expiration related methods
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public StorePool getSipApplicationSessionStorePool() {
return sipApplicationSessionStorePool;
}
public void setSipApplicationSessionStorePool(StorePool sipApplicationSessionStorePool) {
this.sipApplicationSessionStorePool = sipApplicationSessionStorePool;
}
public StorePool getSipSessionStorePool() {
return sipSessionStorePool;
}
public void setSipSessionStorePool(StorePool sipSessionStorePool) {
this.sipSessionStorePool = sipSessionStorePool;
}
public StorePool getServletTimerStorePool() {
return servletTimerStorePool;
}
public void setServletTimerStorePool(StorePool servletTimerStorePool) {
this.servletTimerStorePool = servletTimerStorePool;
}
/**
* Creates a new SipSession.
*
* @param set
* @param to
* @param appSession
* @param handler
* @type type
*
* @return The new SipSession
*/
protected SipSessionDialogImpl createNewSipSession(
DialogSet set, Address to, SipApplicationSessionImpl appSession,
String handler, Type type) {
return getSessionFactory().createSipSession(this, set, to, appSession,
handler, type);
}
/**
* Creates a new SipApplicationSession.
*
* @param id The id of the new SipApplicationSession
*
* @return The new SipApplicationSession
*/
protected SipApplicationSessionImpl createNewSipApplicationSession(String id) {
return getSessionFactory().createSipApplicationSession(this, id);
}
/**
* Creates a new ServletTimer.
*
* @return The new ServletTimer
*/
protected ServletTimerImpl createNewServletTimer(
SipApplicationSessionImpl sas, Serializable info, long delay,
TimerListener listener, boolean isPersistent) {
if (isPersistent) {
return sessionFactory.createServletTimer(this, sas, info, delay, listener);
} else {
return super.createNewServletTimer(sas, info, delay, listener,
isPersistent);
}
}
/**
* Creates a new ServletTimer.
*
* @return The new ServletTimer
*/
protected ServletTimerImpl createNewServletTimer(
SipApplicationSessionImpl sas, Serializable info, long delay,
boolean fixedDelay, long period, TimerListener listener,
boolean isPersistent) {
if (isPersistent) {
return sessionFactory.createServletTimer(this, sas, info, delay, fixedDelay, period, listener);
} else {
return super.createNewServletTimer(sas, info, delay,
fixedDelay, period, listener, isPersistent);
}
}
/**
* Gets the persistence type of this session manager.
*/
public String getPersistenceType() {
return EEPersistenceTypeResolver.REPLICATED_TYPE;
}
//begin send-side methods
/**
* Persists the given SipApplicationSession.
*
* @param sas The SipApplicationSession to be persisted
*/
public void saveSipApplicationSession(SipApplicationSessionImpl sas)
throws IOException {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "saveSipApplicationSession", sas);
}
SipApplicationSessionStoreImpl store = null;
try {
store = getSipApplicationSessionStore();
if (store != null) {
store.save(sas);
}
}
finally {
this.putSipApplicationSessionStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "saveSipApplicationSession");
}
}
/**
* Adds the given SipApplicationSession to this session manager's
* active cache.
* This method checks for an existing version and avoids overriding
* a later version with an earlier version
*
* @param sas The SipApplicationSession to add
*
* @return the previous SipApplicationSession, or null
*/
@Override
public SipApplicationSession addSipApplicationSession(SipApplicationSessionImpl sas) {
SipApplicationSession ret = null;
HASipApplicationSession currentSas = null;
HASipApplicationSession addedSas = (HASipApplicationSession)sas;
String id = sas.getId();
Object monitor = getReplicationSessionMonitor(id);
synchronized(monitor) {
currentSas = (HASipApplicationSession)applicationSessions.get(id);
if(_logger.isLoggable(Level.FINE)) {
if(currentSas != null) {
_logger.fine("currentVersion: " + currentSas.getVersion()
+ " newVersion: " + addedSas.getVersion());
}
}
if((currentSas != null) && currentSas.getVersion() >= addedSas.getVersion()) {
return currentSas;
}
ret = applicationSessions.put(addedSas.getId(), addedSas);
}
if (_logger.isLoggable(Level.FINE)) {
String replacedVersion = "";
if (currentSas != null) {
replacedVersion = ". Replaced version " + currentSas.getVersion();
}
_logger.fine("Put in active cache appId=" + this.getApplicationId() + " id:" + id +
"[ver:" + addedSas.getVersion() + "] of instance " + getInstanceName() +
replacedVersion);
}
return ret;
}
/**
* Removes the given SipApplicationSession from only the active cache
*
* @param sas The SipApplicationSession to be removed
*/
@Override
public void removeSipApplicationSessionFromCache(SipApplicationSessionImpl sas) {
Object monitor = getReplicationSessionMonitor(sas.getId());
synchronized(monitor) {
super.removeSipApplicationSessionFromCache(sas);
}
}
/**
* Removes the given SipApplicationSession from both the active cache
* and the persistent session store of this session manager,
*
* @param sas The SipApplicationSession to be removed
*/
public void removeSipApplicationSession(SipApplicationSessionImpl sas) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "removeSipApplicationSession", sas);
}
this.removeSipApplicationSessionFromCache(sas);
if(!sasExpatListHandler.isAwaitingExpatList()) {
synchronized(sasExpatIdsMap) {
sasExpatIdsMap.remove(sas.getId());
}
}
SipApplicationSessionStoreImpl store = null;
try {
store = getSipApplicationSessionStore();
if (store != null) {
store.remove(sas.getId());
}
} catch (IOException ex) {
_logger.log(
Level.WARNING,
"unable to remove SipApplicationSession:id = " + sas.getId(),
ex);
} finally {
this.putSipApplicationSessionStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "removeSipApplicationSession");
}
}
/**
* Removes the given ServletTimer from both the active cache and the
* persistent session store of this session manager,
*
* @param sasId The id of the SipApplicationSession to be removed
* @param originatingInstanceName the name of the originating instance for this cyclical remove
* @param cycleCount the counter used to determine when a complete cycle of the cluster is complete
*/
public void cycleRemoveSipApplicationSession(String sasId, String originatingInstanceName, int cycleCount) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "cycleRemoveSipApplicationSession", sasId);
}
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
int clusterSize = healthChecker.getCurrentGroupMembersSizeViaGMS();
if(getInstanceName().equalsIgnoreCase(originatingInstanceName)
|| cycleCount >= clusterSize) {
return;
}
SipApplicationSessionStoreImpl store = null;
try {
store = getSipApplicationSessionStore();
if (store != null) {
store.remove(sasId, originatingInstanceName, cycleCount);
}
} catch (IOException ex) {
_logger.log(
Level.WARNING,
"unable to remove SipApplicationSession:id = " + sasId,
ex);
} finally {
this.putSipApplicationSessionStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "removeSipApplicationSession");
}
}
/**
* Removes the given SipApplicationSession from the
* persistent session store of this session manager,
*
* @param sasId The id SipApplicationSession replica to be removed
*/
public void removeSipApplicationSessionReplica(String sasId) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "removeSipApplicationSessionReplica", sasId);
}
SipApplicationSessionStoreImpl store = null;
try {
store = getSipApplicationSessionStore();
if (store != null) {
store.remove(sasId);
}
} catch (IOException ex) {
_logger.log(
Level.WARNING,
"unable to remove SipApplicationSession:id = " + sasId,
ex);
} finally {
this.putSipApplicationSessionStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "removeSipApplicationSessionReplica");
}
}
/**
* send a load advisory message to instance to trigger
* it to load a given id
*
* @param id The id of the SipApplicationSession to be loaded
* @param instanceName the instance to be sent the load advisory
*/
public void sendLoadAdvisorySipApplicationSession(String id, String instanceName) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager",
"sendLoadAdvisorySipApplicationSession",
new Object[] { id, instanceName});
}
SipApplicationSessionStoreImpl store = null;
try {
store = getSipApplicationSessionStore();
if (store != null) {
store.sendLoadAdvisory(id, instanceName);
}
} catch (IOException ex) {
_logger.log(Level.WARNING, "sas_send_loadadvisory_error", new Object[] { id, instanceName });
_logger.log(Level.WARNING, ex.getMessage(), ex);
} finally {
this.putSipApplicationSessionStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager",
"sendLoadAdvisorySipApplicationSession");
}
}
public <V> V __load(String id, String version, JxtaBackingStoreImpl jxtaBackingStore)
throws BackingStoreException {
V session = null;
if (jxtaBackingStore == sipApplicationSessionBackingStore) {
SipApplicationSessionStoreImpl store =
getSingletonSipApplicationSessionStore();
session = (V) store.__load(id, version);
} else if(jxtaBackingStore == sipSessionBackingStore) {
SipSessionStoreImpl store = getSingletonSipSessionStore();
session = (V) store.__load(id, version);
} else if(jxtaBackingStore == servletTimerBackingStore) {
ServletTimerStoreImpl store = getSingletonServletTimerStore();
session = (V) store.__load(id, version);
}
return session;
}
private Set<String> remotelyLoadedSessionIds =
Collections.synchronizedSet(new HashSet<String>());
public Set<String> getRemotelyLoadedSessionIds() {
return remotelyLoadedSessionIds;
}
/**
* Look for a SipApplicationSession in the Store and, if found, restore
* it in the Manager's list of active sessions if appropriate.
* The session will be removed from the Store after swapping
* in, but will not be added to the active session list if it
* is invalid or past its expiration.
* @param id the id of the SAS
*/
protected SipApplicationSessionImpl swapInSipApplicationSession(String id,
boolean force)
throws IOException, RemoteLockException {
// We always call load if
//
// 1. force -- we were asked to
// 2. we are loading the expat list, so don't know if the sas
// exists yet
// 3. the id is in our replica cache
// 4. there is no CLB to rely on
//
// The third case is an artifact of the way the CLB increases
// load: the expat list is sent when the instance comes online.
// A new call can start after that and be handled by another
// instance if the CLB hasn't migtrated that call to us yet.
// In that case, the id isn't in the expat list, but it will have
// been replicated to us.
boolean doCall =
force || sasExpatListHandler.isAwaitingExpatList() ||
(getFromSipApplicationSessionReplicationCache(id) != null) ||
!SipReplicationUtil.isInstanceLoadBalancedByCLB();
if (doCall) {
return swapInSipApplicationSession(id, null);
} else {
// Avoid unnecessary load if the requested session has never
// existed, i.e., is not contained in the expat list
ExpatListElement expat;
synchronized(sasExpatIdsMap) {
expat = sasExpatIdsMap.get(id);
}
if (expat != null) {
//return swapInSipApplicationSession(
// expat.getId(),
// Long.toString(expat.getVersion()), true);
// now using version unaware load, see IT1550
return swapInSipApplicationSession(
expat.getId(),
null, true);
} else {
return null;
}
}
}
private SipApplicationSessionImpl swapInSipApplicationSession(
String id, String version)
throws IOException, RemoteLockException {
return swapInSipApplicationSession(id, version, false);
}
/**
* Look for a SipApplicationSession in the Store and, if found, restore
* it in the Manager's list of active sessions if appropriate.
* The session will be removed from the Store after swapping
* in, but will not be added to the active session list if it
* is invalid or past its expiration.
* @param id the id of the SAS
* @param version - the version of the SAS
*/
private SipApplicationSessionImpl swapInSipApplicationSession(
String id, String version,
boolean removeFromExpat)
throws IOException, RemoteLockException {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager",
"swapInSipApplicationSession",
new Object[] { id, version});
}
SipApplicationSessionStoreImpl store = getSipApplicationSessionStore();
if (store == null) {
return null;
}
try {
SipApplicationSessionImpl session = null;
try {
if (SecurityUtil.isPackageProtectionEnabled()){
try{
session = (SipApplicationSessionImpl) AccessController.doPrivileged(new PrivilegedStoreLoadSipApplicationSession(id, version, store));
}catch(PrivilegedActionException ex){
Exception exception = ex.getException();
if (exception instanceof IOException){
throw (IOException)exception;
} else if (exception instanceof ClassNotFoundException) {
throw (ClassNotFoundException)exception;
}
}
} else {
if (version != null) {
session = store.load(id, version);
} else {
session = store.load(id);
}
}
} catch (ClassNotFoundException e) {
IOException ex1 =
(IOException) new IOException("Error during swapInSipApplicationSession: " + e.getMessage()).initCause(e);
throw ex1;
}
if (SASLockStatus.isSASLocked()) {
session = activate(session, removeFromExpat);
} else if (session != null) {
synchronized (session.getSasObjectLock()) {
SASLockStatus.resetSASLockedToDefaultValue();
session = activate(session, removeFromExpat);
}
}
return session;
} finally {
this.putSipApplicationSessionStore(store);
}
}
public SipApplicationSessionImpl activate(SipApplicationSessionImpl session,
boolean removeFromExpat) {
if (session == null) {
return (null);
}
SipApplicationSessionImpl activatedSession = null;
if (!session.isValid()) {
if (_logger.isLoggable(Level.INFO)) {
_logger.log(Level.INFO,
"SipApplicationSession with id: " +
session.getId() + " not swapped in " +
"because invalid");
}
// Cause replica to be removed
removeSipApplicationSession(session);
} else {
boolean isActivated = session.activate();
// Activate may have changed the validity of the session, so
// we need to check again
if (!isActivated || !session.isValid()) {
// Cause replica to be removed
// but leave invalid session in active cache
removeSipApplicationSessionReplica(session.getId());
} else {
activatedSession = session;
}
}
// remove from the expat at the end.
if (removeFromExpat) {
removeSipApplicationSessionExpatListElement(session.getId());
}
return activatedSession;
}
ExpatListElement getSipApplicationSessionExpatListElement(String id) {
if(sasExpatReadWriteLock.readLock().tryLock()) {
try {
synchronized(sasExpatIdsMap) {
ExpatListElement result = sasExpatIdsMap.get(id);
return result;
}
} finally {
sasExpatReadWriteLock.readLock().unlock();
}
} else {
return null;
}
}
ExpatListElement removeSipApplicationSessionExpatListElement(String id) {
if(sasExpatReadWriteLock.readLock().tryLock()) {
try {
synchronized(sasExpatIdsMap) {
ExpatListElement result = sasExpatIdsMap.remove(id);
return result;
}
} finally {
sasExpatReadWriteLock.readLock().unlock();
}
} else {
return null;
}
}
ExpatListElement getSipSessionExpatListElement(String id) {
if(sipSessionExpatReadWriteLock.readLock().tryLock()) {
try {
synchronized(sipSessionExpatIdsMap) {
ExpatListElement result = sipSessionExpatIdsMap.get(id);
return result;
}
} finally {
sipSessionExpatReadWriteLock.readLock().unlock();
}
} else {
return null;
}
}
ExpatListElement removeSipSessionExpatListElement(String id) {
if(sipSessionExpatReadWriteLock.readLock().tryLock()) {
try {
synchronized(sipSessionExpatIdsMap) {
ExpatListElement result = sipSessionExpatIdsMap.remove(id);
return result;
}
} finally {
sipSessionExpatReadWriteLock.readLock().unlock();
}
} else {
return null;
}
}
ExpatListElement getServletTimerExpatListElement(String id) {
if(servletTimerExpatReadWriteLock.readLock().tryLock()) {
try {
synchronized(servletTimerExpatIdsMap) {
ExpatListElement result = servletTimerExpatIdsMap.get(id);
return result;
}
} finally {
servletTimerExpatReadWriteLock.readLock().unlock();
}
} else {
return null;
}
}
ExpatListElement removeServletTimerExpatListElement(String id) {
if(servletTimerExpatReadWriteLock.readLock().tryLock()) {
try {
synchronized(servletTimerExpatIdsMap) {
ExpatListElement result = servletTimerExpatIdsMap.remove(id);
return result;
}
} finally {
servletTimerExpatReadWriteLock.readLock().unlock();
}
} else {
return null;
}
}
/**
* Persists the given SipSession.
*
* @param sipSession The SipSession to be persisted
*/
public void saveSipSession(SipSessionDialogImpl sipSession)
throws IOException {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "saveSipSession", sipSession);
}
SipSessionStoreImpl store = null;
try {
store = getSipSessionStore();
if (store != null) {
store.save(sipSession);
}
}
finally {
this.putSipSessionStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "saveSipSession");
}
}
/**
* Adds the given SipSession to this session manager's active cache.
* This method checks for an existing version and avoids overriding
* a later version with an earlier version
*
* @param sipSession The SipSession to add
*
* @return the previous SipSession, or null
*/
@Override
public SipSession addSipSession(SipSessionDialogImpl sipSession) {
SipSession ret = null;
HASipSession currentSipSession = null;
HASipSession addedSipSession = (HASipSession)sipSession;
String id = sipSession.getId();
Object monitor = getReplicationSessionMonitor(id);
synchronized(monitor) {
currentSipSession = (HASipSession)sipSessions.get(id);
if(_logger.isLoggable(Level.FINE)) {
if(currentSipSession != null) {
_logger.fine("currentVersion: " + currentSipSession.getVersion()
+ " newVersion: " + addedSipSession.getVersion());
}
}
if((currentSipSession != null) && currentSipSession.getVersion() >= addedSipSession.getVersion()) {
return currentSipSession;
}
ret = sipSessions.put(addedSipSession.getId(), addedSipSession);
}
if (_logger.isLoggable(Level.FINE)) {
String replacedVersion = "";
if (currentSipSession != null) {
replacedVersion = ". Replaced version " + currentSipSession.getVersion();
}
_logger.fine("Put in active cache appId=" + this.getApplicationId() + " id:" + id +
"[ver:" + addedSipSession.getVersion() + "] of instance " + getInstanceName() +
replacedVersion);
}
return ret;
}
/**
* Removes the given SipSession from only the active cache
*
* @param sipSession The SipSession to be removed
*/
@Override
public void removeSipSessionFromCache(SipSessionDialogImpl sipSession) {
Object monitor = getReplicationSessionMonitor(sipSession.getId());
synchronized(monitor) {
super.removeSipSessionFromCache(sipSession);
}
}
/**
* Removes the given SipSession from both the active cache and the
* persistent session store of this session manager,
*
* @param sipSession The SipSession to be removed
*/
public void removeSipSession(SipSessionDialogImpl sipSession) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "removeSipSession", sipSession);
}
removeSipSessionFromCache(sipSession);
SipSessionStoreImpl store = null;
try {
store = getSipSessionStore();
if (store != null) {
store.remove(sipSession.getId());
}
} catch (IOException ex) {
_logger.log(
Level.WARNING,
"unable to remove SipSession:id = " + sipSession.getId(),
ex);
} finally {
this.putSipSessionStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "removeSipSession");
}
}
/**
* Removes the given SipSession from the
* persistent session store of this session manager,
*
* @param sipSessionId The id of the SipSession replica to be removed
*/
public void removeSipSessionReplica(String sipSessionId) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "removeSipSessionReplica", sipSessionId);
}
SipSessionStoreImpl store = null;
try {
store = getSipSessionStore();
if (store != null) {
store.remove(sipSessionId);
}
} catch (IOException ex) {
_logger.log(
Level.WARNING,
"unable to remove SipSession:id = " + sipSessionId,
ex);
} finally {
this.putSipSessionStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "removeSipSessionReplica");
}
}
/**
* Removes the given SipSession from both the active cache and the
* persistent session store of this session manager,
*
* @param id The id of the SipSession to be removed
*/
public void removeSipSession(String id) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "removeSipSession", id);
}
removeSipSessionFromCache(id);
SipSessionStoreImpl store = null;
try {
store = getSipSessionStore();
if (store != null) {
store.remove(id);
}
} catch (IOException ex) {
_logger.log(
Level.WARNING,
"unable to remove SipSession:id = " + id,
ex);
} finally {
this.putSipSessionStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "removeSipSession");
}
}
/**
* Look for a SipSession in the Store and, if found, restore
* it in the Manager's list of active sessions if appropriate.
* The session will be removed from the Store after swapping
* in, but will not be added to the active session list if it
* is invalid or past its expiration.
* @param id the id of the SipSession
*/
protected SipSessionDialogImpl swapInSipSession(String id,
boolean loadDependencies)
throws IOException, RemoteLockException {
return swapInSipSession(id, null, loadDependencies);
}
/**
* Look for a SipSession in the Store and, if found, restore
* it in the Manager's list of active sessions if appropriate.
* The session will be removed from the Store after swapping
* in, but will not be added to the active session list if it
* is invalid or past its expiration.
* @param id the id of the SipSession
* @param version - the version of the SipSession
*/
private SipSessionDialogImpl swapInSipSession(String id, String version,
boolean loadDependencies)
throws IOException, RemoteLockException {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager",
"swapInSipSession",
new Object[] { id, version, loadDependencies});
}
SipSessionStoreImpl store = getSipSessionStore();
if (store == null) {
return null;
}
try {
SipSessionDialogImpl session = null;
try {
if (SecurityUtil.isPackageProtectionEnabled()){
try{
session = (SipSessionDialogImpl) AccessController.doPrivileged(new PrivilegedStoreLoadSipSession(id, version, loadDependencies, store));
} catch(PrivilegedActionException ex){
Exception exception = ex.getException();
if (exception instanceof IOException){
throw (IOException)exception;
} else if (exception instanceof ClassNotFoundException) {
throw (ClassNotFoundException)exception;
}
}
} else {
if (version != null) {
session = store.load(id, version, loadDependencies);
} else {
session = store.load(id, loadDependencies);
}
}
} catch (ClassNotFoundException e) {
IOException ex1 =
(IOException) new IOException("Error during swapInSipSession: " + e.getMessage()).initCause(e);
throw ex1;
}
return activate(session, false);
} finally {
this.putSipSessionStore(store);
}
}
public SipSessionDialogImpl activate(SipSessionDialogImpl session,
boolean removeFromExpat) {
if (session == null)
return (null);
SipSessionDialogImpl activatedSession = null;
if (!session.isValid()) {
// TODO :: shouldn't we call removeSipSessionReplica(session.getId())?
if (_logger.isLoggable(Level.INFO)) {
_logger.log(Level.INFO,
"SipSession with id: " +
session.getId() + " not swapped in " +
"because invalid");
}
} else {
boolean isActivated = session.activate();
if (isActivated) {
activatedSession = session;
} else {
// TODO :: shouldn't we call removeSipSessionReplica(session.getId())?
}
}
if (removeFromExpat) {
removeSipSessionExpatListElement(session.getId());
}
return activatedSession;
}
/**
* Persists the given ServletTimer.
*
* @param servletTimer The ServletTimer to be persisted
*/
public void saveServletTimer(ServletTimerImpl servletTimer)
throws IOException {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "saveServletTimer", servletTimer);
}
ServletTimerStoreImpl store = null;
try {
store = getServletTimerStore();
if (store != null) {
store.save(servletTimer);
}
}
finally {
this.putServletTimerStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "saveServletTimer");
}
}
/**
* Adds the given ServletTimer to this session manager's
* active cache.
* This method checks for an existing version and avoids overriding
* a later version with an earlier version
*
* @param timer The ServletTimer to add
*
* @return the previous ServletTimer, or null
*/
@Override
public ServletTimer addServletTimer(ServletTimerImpl timer) {
ServletTimer ret = null;
HAServletTimer currentTimer = null;
HAServletTimer addedTimer = (HAServletTimer)timer;
String id = timer.getId();
Object monitor = getReplicationSessionMonitor(id);
synchronized(monitor) {
currentTimer = (HAServletTimer)servletTimers.get(id);
if(_logger.isLoggable(Level.FINE)) {
if(currentTimer != null) {
_logger.fine("currentVersion: " + currentTimer.getVersion()
+ " newVersion: " + addedTimer.getVersion());
}
}
if((currentTimer != null) && currentTimer.getVersion() >= addedTimer.getVersion()) {
return currentTimer;
}
ret = servletTimers.put(addedTimer.getId(), addedTimer);
}
if (_logger.isLoggable(Level.FINE)) {
String replacedVersion = "";
if (currentTimer != null) {
replacedVersion = ". Replaced version " + currentTimer.getVersion();
}
_logger.fine("Put in active cache appId=" + this.getApplicationId() + " id:" + id +
"[ver:" + addedTimer.getVersion() + "] of instance " + getInstanceName() +
replacedVersion);
}
return ret;
}
/**
* Removes the given ServletTimer from only the active cache
*
* @param servletTimer The ServletTimer to be removed
*/
@Override
public void removeServletTimerFromCache(ServletTimerImpl servletTimer) {
Object monitor = getReplicationSessionMonitor(servletTimer.getId());
synchronized(monitor) {
super.removeServletTimerFromCache(servletTimer);
}
}
public int processExpiredSessions() {
throw new RuntimeException("processExpiredSessions in SipTransactionPersistentManager called");
}
/**
* Removes the given ServletTimer from both the active cache and the
* persistent session store of this session manager,
*
* @param servletTimer The ServletTimer to be removed
*/
public void removeServletTimer(ServletTimerImpl servletTimer) {
removeServletTimerFromCache(servletTimer);
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "removeServletTimer", servletTimer);
}
ServletTimerStoreImpl store = null;
try {
store = getServletTimerStore();
if (store != null) {
store.remove(servletTimer.getId());
}
} catch (IOException ex) {
_logger.log(Level.WARNING,
"unable to remove ServletTimer:id = " + servletTimer.getId(),
ex);
} finally {
this.putServletTimerStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "removeServletTimer");
}
}
/**
* Removes the given ServletTimer from both the active cache and the
* persistent session store of this session manager,
*
* @param timerId The id of the ServletTimer to be removed
* @param originatingInstanceName the name of the originating instance for this cyclical remove
* @param cycleCount the counter used to determine when a complete cycle of the cluster is complete
*/
public void cycleRemoveServletTimer(String timerId, String originatingInstanceName, int cycleCount) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "cycleRemoveServletTimer", timerId);
}
ServletTimerStoreImpl store = null;
try {
store = getServletTimerStore();
if (store != null) {
store.remove(timerId, originatingInstanceName, cycleCount);
}
} catch (IOException ex) {
_logger.log(Level.WARNING,
"unable to remove ServletTimer:id = " + timerId,
ex);
} finally {
this.putServletTimerStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "removeServletTimer");
}
}
/**
* Removes the given ServletTimer from the
* persistent session store of this session manager,
*
* @param servletTimerId The id of the ServletTimer replica to be removed
*/
public void removeServletTimerReplica(String servletTimerId) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "removeServletTimerReplica", servletTimerId);
}
ServletTimerStoreImpl store = null;
try {
store = getServletTimerStore();
if (store != null) {
store.remove(servletTimerId);
}
} catch (IOException ex) {
_logger.log(Level.WARNING,
"unable to remove ServletTimer:id = " + servletTimerId,
ex);
} finally {
this.putServletTimerStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "removeServletTimerReplica");
}
}
/**
* send a load advisory message to instance to trigger
* it to load a given id
*
* @param id The id of the ServletTimer to be loaded
* @param instanceName the instance to be sent the load advisory
*/
public void sendLoadAdvisoryServletTimer(String id, String instanceName) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "sendLoadAdvisoryServletTimer", new Object[] {id, instanceName});
}
ServletTimerStoreImpl store = null;
try {
store = getServletTimerStore();
if (store != null) {
store.sendLoadAdvisory(id, instanceName);
}
} catch (IOException ex) {
_logger.log(Level.WARNING, "st_send_loadadvisory_error", new Object[] { id, instanceName });
_logger.log(Level.WARNING, ex.getMessage(), ex);
} finally {
this.putServletTimerStore(store);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "sendLoadAdvisoryServletTimer");
}
}
/**
* Look for a ServletTimer in the Store and, if found, restore
* it in the Manager's list of active sessions if appropriate.
* The session will be removed from the Store after swapping
* in, but will not be added to the active session list if it
* is invalid or past its expiration.
* @param id the id of the ServletTimer
*/
protected ServletTimerImpl swapInServletTimer(String id,
boolean loadDependencies)
throws IOException, RemoteLockException {
return swapInServletTimer(id, null, loadDependencies);
}
/**
* Look for a ServletTimer in the Store and, if found, restore
* it in the Manager's list of active sessions if appropriate.
* The session will be removed from the Store after swapping
* in, but will not be added to the active session list if it
* is invalid or past its expiration.
* @param id the id of the ServletTimer
* @param version - the version of the ServletTimer
*/
private ServletTimerImpl swapInServletTimer(String id, String version,
boolean loadDependencies)
throws IOException, RemoteLockException {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager",
"swapInServletTimer",
new Object[] { id, version, loadDependencies});
}
ServletTimerStoreImpl store = getServletTimerStore();
if (store == null) {
return null;
}
try {
ServletTimerImpl timer = null;
try {
if (SecurityUtil.isPackageProtectionEnabled()){
try{
timer = (ServletTimerImpl) AccessController.doPrivileged(new PrivilegedStoreLoadServletTimer(id, version, loadDependencies, store));
}catch(PrivilegedActionException ex){
Exception exception = ex.getException();
if (exception instanceof IOException){
throw (IOException)exception;
} else if (exception instanceof ClassNotFoundException) {
throw (ClassNotFoundException)exception;
}
}
} else {
if (version != null) {
timer = store.load(id, version, loadDependencies);
} else {
timer = store.load(id, loadDependencies);
}
}
} catch (ClassNotFoundException e) {
IOException ex1 =
(IOException) new IOException("Error during swapInServletTimer: " + e.getMessage()).initCause(e);
throw ex1;
}
return activate(timer, false);
} finally {
this.putServletTimerStore(store);
}
}
public ServletTimerImpl activate(ServletTimerImpl timer, boolean removeFromExpat) {
if (timer == null) {
return (null);
}
boolean isActivated = timer.activate();
if (!isActivated) {
return null;
}
if(removeFromExpat) {
removeServletTimerExpatListElement(timer.getId());
}
return timer;
}
/** Returns a store from the pool
* This method intializes the store with right parameters
* @return returns SipApplicationSessionStoreImpl
*/
public SipApplicationSessionStoreImpl getSipApplicationSessionStore() {
if(ReplicationUtil.isSynchronousReplicationConfigured()) {
return getSipApplicationSessionStore(true);
}
return getSipApplicationSessionStore(false);
}
/** Returns a store from the pool
* This method intializes the store with right parameters
* @param useSingleton if true use a singleton store rather than obtaining from the pool
* @return returns SipApplicationSessionStoreImpl
*/
public SipApplicationSessionStoreImpl getSipApplicationSessionStore(boolean useSingleton) {
// Suppress any replication during undeployment
if (isBeingReleased) {
return null;
}
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "getSipApplicationSessionStore");
}
if(useSingleton) {
return getSingletonSipApplicationSessionStore();
}
if(sipApplicationSessionStorePool == null) {
return null;
}
SipApplicationSessionStoreImpl store = null;
try {
store = (SipApplicationSessionStoreImpl) sipApplicationSessionStorePool.take();
store.setSipSessionManager(this);
if(_logger.isLoggable(Level.FINEST)) {
_logger.log(Level.FINEST,
"SipTransactionPersistentManager.getSipApplicationSessionStore returning " + store);
}
return store;
}
catch (Exception e) {
e.printStackTrace();
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "getSipApplicationSessionStore", store);
}
return store;
}
/**
* Returns (puts) a store back to the pool
*/
private void putSipApplicationSessionStore(StorePoolElement store) {
if(ReplicationUtil.isSynchronousReplicationConfigured()) {
putSipApplicationSessionStore(store, true);
} else {
putSipApplicationSessionStore(store, false);
}
}
/**
* Returns (puts) a store back to the pool
*/
private void putSipApplicationSessionStore(StorePoolElement store, boolean useSingleton) {
if(useSingleton) {
return;
}
if (store != null) {
((SipApplicationSessionStoreImpl) store).setSipSessionManager(null);
try {
if(sipApplicationSessionStorePool != null) {
sipApplicationSessionStorePool.put(store);
}
}
catch (InterruptedException ex1) {
ex1.printStackTrace();
}
}
}
/** Returns the singleton store
* This method intializes the store with right parameters
* @return returns SipApplicationSessionStoreImpl
*/
public SipApplicationSessionStoreImpl getSingletonSipApplicationSessionStore() {
return (SipApplicationSessionStoreImpl)super.getSipApplicationSessionStore();
}
/** Returns a store from the pool
* This method intializes the store with right parameters
* @return returns SipSessionStoreImpl
*/
public SipSessionStoreImpl getSipSessionStore() {
if(ReplicationUtil.isSynchronousReplicationConfigured()) {
return getSipSessionStore(true);
}
return getSipSessionStore(false);
}
/** Returns a store from the pool.
* This method intializes the store with right parameters
* @param useSingleton if true return a singleton store rather than from the pool
* @return returns SipSessionStoreImpl
*/
public SipSessionStoreImpl getSipSessionStore(boolean useSingleton) {
// Suppress any replication during undeployment
if (isBeingReleased) {
return null;
}
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "getSipSessionStore");
}
if(useSingleton) {
return getSingletonSipSessionStore();
}
if(sipSessionStorePool == null) {
return null;
}
SipSessionStoreImpl store = null;
try {
store = (SipSessionStoreImpl) sipSessionStorePool.take();
store.setSipSessionManager(this);
if(_logger.isLoggable(Level.FINEST)) {
_logger.log(Level.FINEST,
"SipTransactionPersistentManager.getSipSessionStore returning " + store);
}
return store;
}
catch (Exception e) {
e.printStackTrace();
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "getSipSessionStore", store);
}
return store;
}
/**
* Returns (puts) a store back to the pool
*/
private void putSipSessionStore(StorePoolElement store) {
if(ReplicationUtil.isSynchronousReplicationConfigured()) {
putSipSessionStore(store, true);
} else {
putSipSessionStore(store, false);
}
}
/**
* Returns (puts) a store back to the pool
*/
private void putSipSessionStore(StorePoolElement store, boolean useSingleton) {
if(useSingleton) {
return;
}
if (store != null) {
((SipSessionStoreImpl) store).setSipSessionManager(null);
try {
if(sipSessionStorePool != null) {
sipSessionStorePool.put(store);
}
}
catch (InterruptedException ex1) {
ex1.printStackTrace();
}
}
}
/** Returns the singleton store
* This method intializes the store with right parameters
* @return returns SipSessionStoreImpl
*/
public SipSessionStoreImpl getSingletonSipSessionStore() {
return (SipSessionStoreImpl)super.getSipSessionStore();
}
/** Returns a store from the pool
* This method intializes the store with right parameters
* @return returns ServletTimerStoreImpl
*/
public ServletTimerStoreImpl getServletTimerStore() {
if(ReplicationUtil.isSynchronousReplicationConfigured()) {
return getServletTimerStore(true);
}
return getServletTimerStore(false);
}
/** Returns a store from the pool
* This method intializes the store with right parameters
* @param useSingleton if true use the singleton store rather than from the pool
* @return returns ServletTimerStoreImpl
*/
public ServletTimerStoreImpl getServletTimerStore(boolean useSingleton) {
// Suppress any replication during undeployment
if (isBeingReleased) {
return null;
}
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager", "getServletTimerStore");
}
if(useSingleton) {
return getSingletonServletTimerStore();
}
if(servletTimerStorePool == null) {
return null;
}
ServletTimerStoreImpl store = null;
try {
store = (ServletTimerStoreImpl) servletTimerStorePool.take();
store.setSipSessionManager(this);
if(_logger.isLoggable(Level.FINEST)) {
_logger.log(Level.FINEST,
"SipTransactionPersistentManager.getServletTimerStore returning " + store);
}
return store;
}
catch (Exception e) {
e.printStackTrace();
}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager", "getServletTimerStore", store);
}
return store;
}
/**
* Returns (puts) a store back to the pool
*/
private void putServletTimerStore(StorePoolElement store) {
if(ReplicationUtil.isSynchronousReplicationConfigured()) {
putServletTimerStore(store, true);
} else {
putServletTimerStore(store, false);
}
}
/**
* Returns (puts) a store back to the pool
*/
private void putServletTimerStore(StorePoolElement store, boolean useSingleton) {
if(useSingleton) {
return;
}
if (store != null) {
((ServletTimerStoreImpl) store).setSipSessionManager(null);
try {
if(servletTimerStorePool != null) {
servletTimerStorePool.put(store);
}
}
catch (InterruptedException ex1) {
ex1.printStackTrace();
}
}
}
/** Returns the singleton store
* This method intializes the store with right parameters
* @return returns ServletTimerStoreImpl
*/
public ServletTimerStoreImpl getSingletonServletTimerStore() {
return (ServletTimerStoreImpl)super.getServletTimerStore();
}
//end send-side methods
//begin implement ReplicationManager
private boolean isBroadcastState(ReplicationState state) {
return(broadcastMethods.contains(state.getCommand()));
}
public void processMessage(ReplicationState message) {
//handle broadcast methods
if(isBroadcastState(message)) {
processBroadcastMessage(message);
return;
}
//handle non-void methods
ReplicationStateQueryResponse queryResult = null;
//do process non-void message (and cannot be response either)
if(!message.isResponseState() && !message.isVoidMethodReturnState()) {
//do non-void processing including sending response
queryResult = this.doProcessQueryMessage(message);
ReplicationState qResponse = queryResult.getState();
if(qResponse != null) {
//sourceInstanceName is preserved in the response
ReplicationState response =
ReplicationState.createResponseFrom(qResponse);
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("RepMgrBase:responseState=" + response);
}
this.doSendResponse(response);
}
return;
}
//end do process non-void message
boolean isResponse = this.doProcessMessage(message);
}
//return true if message is processResponse
public boolean doProcessMessage(ReplicationState message) {
boolean result = false;
String methodName = ReplicationUtil.getProcessMethodName(message);
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>doProcessMessageName=" + methodName);
}
try {
Class myClass = this.getClass();
myClass.getMethod(
methodName,
new Class[]{ message.getClass() }).invoke(
this, new Object[]{ message });
} catch (Throwable t) {
_logger.log(Level.SEVERE, "manager_unable_to_process_replication_message", methodName);
_logger.log(Level.SEVERE, t.getMessage(), t);
}
if(methodName.equals("processResponse")) {
result = true;
}
return result;
}
/**
* send the response
*
* @param sessionState
* The replication state response
*/
public void doSendResponse(ReplicationState sessionState) {
JxtaReplicationReceiver replicationReceiver =
JxtaReplicationReceiver.createInstance();
ReplicationState resultState =
replicationReceiver.sendReplicationStateResponse(sessionState);
}
public void processBroadcastMessage(ReplicationState message) {
ReplicationStateQueryResponse response = this.doProcessQueryMessage(message);
boolean isResponse = response.isResponse();
ReplicationState responseState = response.getState();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("processBroadcastMessage:after doProcessQueryMessage:response=" + isResponse);
_logger.fine("processBroadcastMessage:after doProcessQueryMessage:responseState=" + responseState);
_logger.fine("processBroadcastMessage:after doProcessQueryMessage:responseStateTrunk=" + responseState.getTrunkState());
_logger.fine("processBroadcastMessage:after doProcessQueryMessage:responseStateAttr=" + responseState.getState());
_logger.fine("processBroadcastMessage:after doProcessQueryMessage:responseStateVer=" + responseState.getVersion());
}
//don't send a response to a response
if(!isResponse) {
//point-to-point response back to sender
//System.out.println("processBroadcastMessage - need to send back result");
//doSendQueryResponse(responseState, instanceName);
doSendQueryResponse(responseState, message.getInstanceName());
}
}
/**
* send the response
*
* @param sessionState
* The replication state response
* @param instanceName the name of the target instance
*/
public void doSendQueryResponse(ReplicationState sessionState, String instanceName) {
JxtaReplicationSender replicationSender =
JxtaReplicationSender.createInstance();
ReplicationState resultState =
replicationSender.sendReplicationStateQueryResponse(sessionState, instanceName, useReplicationUnicastLoadResponseBatching);
}
//return true if message is processQueryResponse
public ReplicationStateQueryResponse doProcessQueryMessage(ReplicationState message) {
ReplicationState resultState = null;
String methodName = ReplicationUtil.getProcessMethodName(message);
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>doProcessQueryMessage:methodName=" + methodName);
_logger.fine("in " + this.getClass().getName() + ">>doProcessQueryMessage:thisInstance=" + instanceName + " returnInstance=" + message.getInstanceName() );
}
try {
Class myClass = this.getClass();
resultState = (ReplicationState) myClass.getMethod(
methodName,
new Class[]{ message.getClass() }).invoke(
this, new Object[]{ message });
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("doProcessQueryMessage:methodName = " + methodName + " resultState =" + resultState);
}
} catch (Throwable t) {
_logger.log(Level.SEVERE, "manager_unable_to_process_replication_message", methodName);
_logger.log(Level.SEVERE, t.getMessage(), t);
}
boolean isResponse = (methodName.equals("processBroadcastresponse") || methodName.equals("processUnicastresponse"));
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("doProcessQueryMessage:message command = " + message.getCommand());
_logger.fine("doProcessQueryMessage:isResponse = " + isResponse);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>doProcessQueryMessage:resultState=" + resultState);
}
if (resultState != null) {
resultState.setRouteAdvertisement(message.getRouteAdvertisement());
}
return new ReplicationStateQueryResponse(resultState, isResponse);
}
public void processQueryMessage(ReplicationState message, String returnInstance) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processQueryMessage:returnInstance= " + returnInstance);
}
ReplicationStateQueryResponse response = this.doProcessQueryMessage(message);
boolean isResponse = response.isResponse();
ReplicationState responseState = response.getState();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("processQueryMessage:after doProcessQueryMessage:response=" + isResponse);
_logger.fine("processQueryMessage:after doProcessQueryMessage:responseState=" + responseState);
}
//don't send a response to a response
if(!isResponse && responseState != null) {
//point-to-point response back to sender
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("processQueryMessage - need to send back result to " + returnInstance);
}
doSendQueryResponse(responseState, returnInstance);
}
}
public ReplicationState processBroadcastresponse(ReplicationState queryResponseState) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastresponse:queryResponseState=" + queryResponseState);
}
ReplicationResponseRepository.putFederatedEntry(queryResponseState);
return queryResponseState;
}
public ReplicationState processUnicastresponse(ReplicationState queryResponseState) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processUnicastresponse:queryResponseState=" + queryResponseState);
}
String originalCommand = null;
ReplicationResponseRepository.putEntry(queryResponseState, originalCommand);
return queryResponseState;
}
public void repair(long repairStartTime) {
if (!isRepairDuringFailure()) {
return;
}
repairServletTimers(repairStartTime);
repairSipSessions(repairStartTime);
repairSipApplicationSessions(repairStartTime);
}
public void repair(long repairStartTime, boolean checkForStopping) {
if (!isRepairDuringFailure()) {
return;
}
if(checkForStopping && ReplicationHealthChecker.isStopping()) {
return;
}
repair(repairStartTime);
}
public void repairSipApplicationSessions(long repairStartTime) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager>>repairSipApplicationSessions");
}
if(ReplicationHealthChecker.isStopping()) {
return;
}
Iterator it = applicationSessions.values().iterator();
while (it.hasNext()) {
SipApplicationSessionImpl session = (SipApplicationSessionImpl) it.next();
//by virtue of being in the cache it is considered to
//be not expired
//but since invalidate is called before removal we must check
if(session.isValid()
&& (session.getId() != null)
&& isSipApplicationSessionOlderThan(session, repairStartTime)
&& session.lockBackground()) {
try {
((HASipApplicationSession)session).setReplicated(false);
((HASipApplicationSession)session).setDirty(true, false);
saveSipApplicationSession(session);
} catch (IOException ex) {
_logger.log(Level.WARNING,
"during repair unable to save SipApplicationSession:id = " + session.getId(),
ex);
} finally {
session.unlockBackground();
}
}
}
}
protected boolean isSipApplicationSessionOlderThan(SipApplicationSessionImpl session, long aTime) {
return (session.getLastAccessedTime() <= aTime);
}
public void repairSipSessions(long repairStartTime) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager>>repairSipSessions");
}
if(ReplicationHealthChecker.isStopping()) {
return;
}
Iterator it = sipSessions.values().iterator();
while (it.hasNext()) {
SipSessionDialogImpl session = (SipSessionDialogImpl) it.next();
//by virtue of being in the cache it is considered to
//be not expired
//but since invalidate is called before removal we must check
if(session.isValid()
&& (session.getId() != null)
&& isSipSessionOlderThan(session, repairStartTime)
&& session.lockBackground()) {
try {
((HASipSession)session).setReplicated(false);
((HASipSession)session).setDirty(true, false);
saveSipSession(session);
} catch (IOException ex) {
_logger.log(Level.WARNING,
"during repair unable to save SipSession:id = " + session.getId(),
ex);
} finally {
session.unlockBackground();
}
}
}
}
protected boolean isSipSessionOlderThan(SipSessionDialogImpl session, long aTime) {
return (session.getLastAccessedTime() <= aTime);
}
public void repairServletTimers(long repairStartTime) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager>>repairServletTimers");
}
if(ReplicationHealthChecker.isStopping()) {
return;
}
Iterator it = servletTimers.values().iterator();
while (it.hasNext()) {
ServletTimerImpl timer = (ServletTimerImpl)it.next();
//by virtue of being in the cache it is considered to
//be not expired
if(timer.getId() != null
&& timer.isPersistent()
&& isServletTimerOlderThan(timer, repairStartTime)
&& timer.lockBackground()) {
try {
((HAServletTimer)timer).setReplicated(false);
((HAServletTimer)timer).setDirty(true, false);
saveServletTimer(timer);
} catch (IOException ex) {
_logger.log(Level.WARNING,
"during repair unable to save ServletTimer:id = " + timer.getId(),
ex);
} finally {
timer.unlockBackground();
}
}
}
}
protected boolean isServletTimerOlderThan(ServletTimerImpl timer, long aTime) {
return (((HAServletTimer)timer).getInternalLastAccessedTime() <= aTime);
}
public void respondToFailure(String failedInstanceName, boolean checkForStopping) {
/*
//only do timer wakeup if failedInstanceName was replicating
//to us
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String replicatedFromInstanceName
= healthChecker.getReshapeReplicateFromInstanceName(failedInstanceName);
//when third party SPI implementation in use then only former replica partner
//responds otherwise all surviving instances each respond
if(isThirdPartyBackingStoreInUse() && !failedInstanceName.equalsIgnoreCase(replicatedFromInstanceName)) {
return;
}
if(isThirdPartyBackingStoreInUse()) {
respondToFailureThirdPartySPI(failedInstanceName);
return;
}
Iterator<String> results =
(Iterator<String>) replicatedServletTimers.keys();
while (results.hasNext()) {
String timerId = (String) results.next();
try {
ServletTimerExtraParams eParam = deserializeServletTimerExtraParams(timerId);
if (eParam != null && failedInstanceName.equals(eParam.getCurrentOwnerInstanceName())) {
activationHelper.registerServletTimerMigrationTask(eParam);
}
} catch (Exception ex) {
_logger.log(Level.WARNING, "Error during deserialization", ex);
}
}
//now do SipApplicationSessions
Iterator<String> sasResults =
(Iterator<String>) replicatedSipApplicationSessions.keys();
while (sasResults.hasNext()) {
String sasId = (String) sasResults.next();
try {
SipApplicationSessionExtraParams eParam
= deserializeSipApplicationSessionExtraParams(sasId);
if (eParam != null && failedInstanceName.equals(eParam.getCurrentOwnerInstanceName())) {
activationHelper.registerSipApplicationSessionMigrationTask(eParam);
}
} catch (Exception ex) {
_logger.log(Level.WARNING, "Error during deserialization", ex);
}
}
*/
}
void respondToFailureThirdPartySPI(String failedInstanceName) {
BackingStore servletTimerBackingStore = this.getServletTimerBackingStore();
ServletTimerExtraParams timerExtraParamCriteria
= ServletTimerExtraParams.createSearchCriteria(
this, getApplicationId(), failedInstanceName);
Collection<ServletTimerExtraParams> timerColl
= servletTimerBackingStore.findByCriteria(null, timerExtraParamCriteria);
Iterator<ServletTimerExtraParams> timerResults =
(Iterator<ServletTimerExtraParams>) timerColl.iterator();
while (timerResults.hasNext()) {
ServletTimerExtraParams eParam = timerResults.next();
if (failedInstanceName.equals(eParam.getCurrentOwnerInstanceName())) {
activationHelper.registerServletTimerMigrationTask(eParam);
}
}
BackingStore sipApplicationSessionBackingStore
= this.getSipApplicationSessionBackingStore();
SipApplicationSessionExtraParams sasExtraParamCriteria
= SipApplicationSessionExtraParams.createSearchCriteria(
this, getApplicationId(), failedInstanceName);
Collection<SipApplicationSessionExtraParams> sasColl
= sipApplicationSessionBackingStore.findByCriteria(null, sasExtraParamCriteria);
Iterator<SipApplicationSessionExtraParams> sasResults =
(Iterator<SipApplicationSessionExtraParams>) sasColl.iterator();
while (sasResults.hasNext()) {
SipApplicationSessionExtraParams eParam = sasResults.next();
if (failedInstanceName.equals(eParam.getCurrentOwnerInstanceName())) {
activationHelper.registerSipApplicationSessionMigrationTask(eParam);
}
}
}
boolean isThirdPartyBackingStoreInUse() {
BackingStore sasBackingStore
= getSipApplicationSessionBackingStore();
return (!(sasBackingStore instanceof JxtaBackingStoreImpl));
}
/**
* Gets the name of the instance.on which this session manager resides.
*
* @return The name of the instance on which this session manager
* resides
*/
String getInstanceName() {
return instanceName;
}
// begin post join reconciliation
/**
* do reconciliation processing
* used for both rolling upgrade and post network partition rejoin
* @param waitTime the waitTime in seconds
* @param ctx the RollingUpgradeContext
*/
public void doPostJoinReconciliation(long waitTime, RollingUpgradeContext ctx) {
long startTime = System.currentTimeMillis();
if (_logger.isLoggable(Level.FINE)) {
startTime = System.currentTimeMillis();
}
CountDownLatch doneSignal = new CountDownLatch(2);
//do active cache reconciliation
ReconcileActive reconcileActive
= new ReconcileActive(this, waitTime, doneSignal, ctx);
RollingUpgradeHandler.executeTask(reconcileActive);
//trigger replica cache reconciliation
TriggerReconcileReplica triggerReconcileReplica
= new TriggerReconcileReplica(this, waitTime, doneSignal, ctx);
RollingUpgradeHandler.executeTask(triggerReconcileReplica);
try {
doneSignal.await(waitTime, TimeUnit.SECONDS);
} catch(InterruptedException ex) {
;
} finally {
if(doneSignal.getCount() != 0) {
String errorMsg = "SipTransactionPersistentManager>>doPostJoinReconciliation timed out after " + waitTime + " seconds";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager doPostJoinReconciliation successful after a wait: wait time = " + (System.currentTimeMillis() - startTime));
}
}
}
}
// end post join reconciliation
// begin rolling upgrade related code
public void doRollingUpgradePreShutdownProcessing(long waitTime, CountDownLatch doneSignal, RollingUpgradeContext ctx) {
//do syncpoint save
doSyncpointSave(waitTime, doneSignal, ctx);
}
public void doRollingUpgradePostStartupProcessing(String rollingUpgradeType, long waitTime, CountDownLatch doneSignal, RollingUpgradeContext ctx) {
if(RollingUpgradeHandler.isFileBased(rollingUpgradeType)) {
//do syncpoint load
doSyncpointLoad(waitTime, doneSignal, ctx);
} else {
doMemoryLoad(waitTime, doneSignal, ctx);
}
}
public void doRollingUpgradePostStartupReconciliationProcessing(long waitTime, CountDownLatch doneSignal, RollingUpgradeContext ctx) {
//do post join reconciliation
try {
doPostJoinReconciliation(waitTime, ctx);
} finally {
doneSignal.countDown();
}
}
void doSyncpointSave(long waitTime, CountDownLatch doneSignal, RollingUpgradeContext ctx) {
try {
if(this.isSkipRollingUpgradeBackupRestore()) {
return;
}
SipFileSync syncStore = new SipFileSync((ReplicationManager)this);
try {
syncStore.save(waitTime, ctx);
} catch (IOException ex) {
ex.printStackTrace();
String errorMsg = "SipTransactionPersistentManager>>doSyncPointSave IOException";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
}
} finally {
doneSignal.countDown();
}
}
void doSyncpointLoad(long waitTime, CountDownLatch doneSignal, RollingUpgradeContext ctx) {
try {
if(this.isSkipRollingUpgradeBackupRestore()) {
return;
}
SipFileSync syncStore = new SipFileSync((ReplicationManager)this);
try {
syncStore.load(waitTime, ctx);
markActiveCacheAsSuspected(true);
} catch (IOException ex) {
String errorMsg = "SipTransactionPersistentManager>>doSyncPointLoad IOException";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
} catch (ClassNotFoundException ex2) {
String errorMsg = "SipTransactionPersistentManager>>doSyncPointLoad ClassNotFoundException";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
}
} finally {
doneSignal.countDown();
}
}
void doMemoryLoad(long waitTime, CountDownLatch doneSignal, RollingUpgradeContext ctx) {
try {
if(this.isSkipRollingUpgradeBackupRestore()) {
return;
}
SipMemorySync syncStore = new SipMemorySync((ReplicationManager)this);
try {
syncStore.load(waitTime, ctx);
markActiveCacheAsSuspected(true);
} catch (IOException ex) {
String errorMsg = "SipTransactionPersistentManager>>doMemoryLoad IOException";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
} catch (ClassNotFoundException ex2) {
String errorMsg = "SipTransactionPersistentManager>>doMemoryLoad ClassNotFoundException";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
}
} finally {
doneSignal.countDown();
}
}
void restoreSipApplicationSessionActiveCacheViaMemory(long waitTime, RollingUpgradeContext ctx) {
triggerSipApplicationSessionActiveCacheRestoration(waitTime, ctx);
}
void restoreSipSessionActiveCacheViaMemory(long waitTime, RollingUpgradeContext ctx) {
triggerSipSessionActiveCacheRestoration(waitTime, ctx);
}
void restoreServletTimerActiveCacheViaMemory(long waitTime, RollingUpgradeContext ctx) {
triggerServletTimerActiveCacheRestoration(waitTime, ctx);
}
void restoreSipApplicationSessionReplicaCacheViaMemory(long waitTime, RollingUpgradeContext ctx) {
triggerSipApplicationSessionReplicaCacheRestoration(waitTime, ctx);
}
void restoreSipSessionReplicaCacheViaMemory(long waitTime, RollingUpgradeContext ctx) {
triggerSipSessionReplicaCacheRestoration(waitTime, ctx);
}
void restoreServletTimerReplicaCacheViaMemory(long waitTime, RollingUpgradeContext ctx) {
triggerServletTimerReplicaCacheRestoration(waitTime, ctx);
}
public void triggerSipApplicationSessionActiveCacheRestoration(long waitTime, RollingUpgradeContext ctx) {
long startTime = System.currentTimeMillis();
int numberOfRespondants = RollingUpgradeUtil.getNumberOfExpectedRespondants();
restoreSipApplicationSessionActiveCacheDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateTo partner(s) to do
//active cache restoration
ownedReplicaListsReceivedForSipApplicationSessionActiveCacheRestoration
= new ConcurrentHashMap<String, ReplicationState>();
doTriggerSipApplicationSessionActiveCacheRestoration(ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
try {
restoreSipApplicationSessionActiveCacheDoneSignal.await(waitTime, TimeUnit.SECONDS);
processSipApplicationSessionActiveCacheRestorationResults(ownedReplicaListsReceivedForSipApplicationSessionActiveCacheRestoration);
} catch(InterruptedException ex) {
;
} finally {
if(restoreSipApplicationSessionActiveCacheDoneSignal.getCount() != 0) {
String errorMsg = "SipTransactionPersistentManager>>triggerSipApplicationSessionActiveCacheRestoration timed out after " + waitTime + " seconds";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerSipApplicationSessionActiveCacheRestoration successful after a wait: wait time = " + (System.currentTimeMillis() - startTime) + " active SipApplicationSessions restored: " + applicationSessions.size());
}
}
ctx.addMessage(getApplicationId(), "Active cache restoration completed for SipApplicationSession. " +
", Size of active cache = " + applicationSessions.size() +
", Time taken (ms) = " + (System.currentTimeMillis()-startTime));
}
}
protected void doTriggerSipApplicationSessionActiveCacheRestoration(boolean isInstanceLoadBalancedByCLB) {
if(!isInstanceLoadBalancedByCLB) {
//trigger replicateTo partner to do
//active cache restoration
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String replicateToInstanceName = healthChecker.getReshapeReplicateToInstanceName(null, 0L);
sendRollingUpgradeActiveCacheRestorationAdvisory(MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RESTORATION_ADVISORY, replicateToInstanceName);
} else {
//trigger all partners to do
//active cache restoration
sendRollingUpgradeActiveCacheRestorationAdvisory(MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RESTORATION_ADVISORY);
}
}
protected void processSipApplicationSessionActiveCacheRestorationResults(ConcurrentHashMap<String, ReplicationState> ownedReplicaListsReceivedForActiveCacheRestoration) {
SipApplicationSessionStoreImpl store = getSingletonSipApplicationSessionStore();
Collection<ReplicationState> ownedReplicasList = ownedReplicaListsReceivedForActiveCacheRestoration.values();
Iterator<ReplicationState> it = ownedReplicasList.iterator();
while(it.hasNext()) {
ReplicationState nextOwnedListReplicationState = it.next();
List<ReplicationState>nextOwnedListOfStates
= (List<ReplicationState>)RollingUpgradeUtil.getObject(nextOwnedListReplicationState.getState());
for(int i=0; i<nextOwnedListOfStates.size(); i++) {
ReplicationState nextState = nextOwnedListOfStates.get(i);
HASipApplicationSession nextSession = null;
try {
nextSession = store.getSipApplicationSession(nextState);
} catch (Exception ex) {}
if(nextSession != null) {
this.addSipApplicationSession(nextSession);
}
}
}
}
public void triggerSipApplicationSessionReplicaCacheRestoration(long waitTime, RollingUpgradeContext ctx) {
long startTime = System.currentTimeMillis();
int numberOfRespondants = RollingUpgradeUtil.getNumberOfExpectedRespondants();
restoreSipApplicationSessionReplicaCacheDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateFrom partner(s) to do
//replica cache restoration
ownedReplicaListsReceivedForSipApplicationSessionReplicaCacheRestoration
= new ConcurrentHashMap<String, ReplicationState>();
doTriggerSipApplicationSessionReplicaCacheRestoration(ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
try {
restoreSipApplicationSessionReplicaCacheDoneSignal.await(waitTime, TimeUnit.SECONDS);
processSipApplicationSessionReplicaCacheRestorationResults(ownedReplicaListsReceivedForSipApplicationSessionReplicaCacheRestoration);
} catch(InterruptedException ex) {
;
} finally {
if(restoreSipApplicationSessionReplicaCacheDoneSignal.getCount() != 0) {
String errorMsg = "SipTransactionPersistentManager>>triggerSipApplicationSessionReplicaCacheRestoration timed out after " + waitTime + " seconds";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerSipApplicationSessionReplicaCacheRestoration successful after a wait: wait time = " + (System.currentTimeMillis() - startTime) + " replica SipApplicationSessions restored: " + getReplicatedSipApplicationSessions().getEntryCount());
}
}
ctx.addMessage(getApplicationId(), "Replica cache restoration completed for SipApplicationSession. " +
", Size of replica cache = " + getReplicatedSipApplicationSessions().getEntryCount() +
", Time taken (ms) = " + (System.currentTimeMillis()-startTime));
}
}
protected void doTriggerSipApplicationSessionReplicaCacheRestoration(boolean isInstanceLoadBalancedByCLB) {
if(!isInstanceLoadBalancedByCLB) {
//trigger replicateTo partner to do
//replica cache restoration
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String replicateToInstanceName = healthChecker.getReshapeReplicateToInstanceName(null, 0L);
sendRollingUpgradeReplicaCacheRestorationAdvisory(MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_REPLICA_CACHE_RESTORATION_ADVISORY, replicateToInstanceName);
} else {
//trigger all partners to do
//replica cache restoration
sendRollingUpgradeReplicaCacheRestorationAdvisory(MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_REPLICA_CACHE_RESTORATION_ADVISORY);
}
}
protected void processSipApplicationSessionReplicaCacheRestorationResults(ConcurrentHashMap<String, ReplicationState> ownedReplicaListsReceivedForReplicaCacheRestoration) {
Collection<ReplicationState> ownedReplicasList = ownedReplicaListsReceivedForReplicaCacheRestoration.values();
Iterator<ReplicationState> it = ownedReplicasList.iterator();
while(it.hasNext()) {
ReplicationState nextOwnedListReplicationState = it.next();
List<ReplicationState>nextOwnedListOfStates
= (List<ReplicationState>)RollingUpgradeUtil.getObject(nextOwnedListReplicationState.getState());
for(int i=0; i<nextOwnedListOfStates.size(); i++) {
ReplicationState nextState = nextOwnedListOfStates.get(i);
this.putInSipApplicationSessionReplicationCache(nextState);
}
}
}
public void triggerSipSessionActiveCacheRestoration(long waitTime, RollingUpgradeContext ctx) {
long startTime =System.currentTimeMillis();
int numberOfRespondants = RollingUpgradeUtil.getNumberOfExpectedRespondants();
restoreSipSessionActiveCacheDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateTo partner(s) to do
//active cache restoration
ownedReplicaListsReceivedForSipSessionActiveCacheRestoration
= new ConcurrentHashMap<String, ReplicationState>();
doTriggerSipSessionActiveCacheRestoration(ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
try {
restoreSipSessionActiveCacheDoneSignal.await(waitTime, TimeUnit.SECONDS);
processSipSessionActiveCacheRestorationResults(ownedReplicaListsReceivedForSipSessionActiveCacheRestoration);
} catch(InterruptedException ex) {
;
} finally {
if(restoreSipSessionActiveCacheDoneSignal.getCount() != 0) {
String errorMsg = "SipTransactionPersistentManager>>triggerSipSessionActiveCacheRestoration timed out after " + waitTime + " seconds";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerSipSessionActiveCacheRestoration successful after a wait: wait time = " + (System.currentTimeMillis() - startTime) + " active SipSessions restored: " + sipSessions.size());
}
}
ctx.addMessage(getApplicationId(), "Active cache restoration completed for SipSession. " +
", Size of active cache = " + sipSessions.size() +
", Time taken (ms) = " + (System.currentTimeMillis()-startTime));
}
}
protected void doTriggerSipSessionActiveCacheRestoration(boolean isInstanceLoadBalancedByCLB) {
if(!isInstanceLoadBalancedByCLB) {
//trigger replicateTo partner to do
//active cache restoration
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String replicateToInstanceName = healthChecker.getReshapeReplicateToInstanceName(null, 0L);
sendRollingUpgradeActiveCacheRestorationAdvisory(MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_ACTIVE_CACHE_RESTORATION_ADVISORY, replicateToInstanceName);
} else {
//trigger all partners to do
//active cache restoration
sendRollingUpgradeActiveCacheRestorationAdvisory(MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_ACTIVE_CACHE_RESTORATION_ADVISORY);
}
}
protected void processSipSessionActiveCacheRestorationResults(ConcurrentHashMap<String, ReplicationState> ownedReplicaListsReceivedForActiveCacheRestoration) {
SipSessionStoreImpl store = getSingletonSipSessionStore();
Collection<ReplicationState> ownedReplicasList = ownedReplicaListsReceivedForActiveCacheRestoration.values();
Iterator<ReplicationState> it = ownedReplicasList.iterator();
while(it.hasNext()) {
ReplicationState nextOwnedListReplicationState = it.next();
List<ReplicationState>nextOwnedListOfStates
= (List<ReplicationState>)RollingUpgradeUtil.getObject(nextOwnedListReplicationState.getState());
for(int i=0; i<nextOwnedListOfStates.size(); i++) {
ReplicationState nextState = nextOwnedListOfStates.get(i);
HASipSession nextSession = null;
try {
nextSession = store.getSipSession(nextState);
} catch (Exception ex) {}
if(nextSession != null) {
this.addSipSession(nextSession);
}
}
}
}
public void triggerSipSessionReplicaCacheRestoration(long waitTime, RollingUpgradeContext ctx) {
long startTime = System.currentTimeMillis();
int numberOfRespondants = RollingUpgradeUtil.getNumberOfExpectedRespondants();
restoreSipSessionReplicaCacheDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateFrom partner(s) to do
//replica cache restoration
ownedReplicaListsReceivedForSipSessionReplicaCacheRestoration
= new ConcurrentHashMap<String, ReplicationState>();
doTriggerSipSessionReplicaCacheRestoration(ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
try {
restoreSipSessionReplicaCacheDoneSignal.await(waitTime, TimeUnit.SECONDS);
processSipSessionReplicaCacheRestorationResults(ownedReplicaListsReceivedForSipSessionReplicaCacheRestoration);
} catch(InterruptedException ex) {
;
} finally {
if(restoreSipSessionReplicaCacheDoneSignal.getCount() != 0) {
String errorMsg = "SipTransactionPersistentManager>>triggerSipSessionReplicaCacheRestoration timed out after " + waitTime + " seconds";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerSipSessionReplicaCacheRestoration successful after a wait: wait time = " + (System.currentTimeMillis() - startTime) + " replica SipSessions restored: " + getReplicatedSipSessions().getEntryCount());
}
}
ctx.addMessage(getApplicationId(), "Replica cache restoration completed for SipSession. " +
", Size of replica cache = " + getReplicatedSipSessions().getEntryCount() +
", Time taken (ms) = " + (System.currentTimeMillis()-startTime));
}
}
protected void doTriggerSipSessionReplicaCacheRestoration(boolean isInstanceLoadBalancedByCLB) {
if(!isInstanceLoadBalancedByCLB) {
//trigger replicateTo partner to do
//replica cache restoration
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String replicateToInstanceName = healthChecker.getReshapeReplicateToInstanceName(null, 0L);
sendRollingUpgradeReplicaCacheRestorationAdvisory(MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_REPLICA_CACHE_RESTORATION_ADVISORY, replicateToInstanceName);
} else {
//trigger all partners to do
//replica cache restoration
sendRollingUpgradeReplicaCacheRestorationAdvisory(MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_REPLICA_CACHE_RESTORATION_ADVISORY);
}
}
protected void processSipSessionReplicaCacheRestorationResults(ConcurrentHashMap<String, ReplicationState> ownedReplicaListsReceivedForReplicaCacheRestoration) {
Collection<ReplicationState> ownedReplicasList = ownedReplicaListsReceivedForReplicaCacheRestoration.values();
Iterator<ReplicationState> it = ownedReplicasList.iterator();
while(it.hasNext()) {
ReplicationState nextOwnedListReplicationState = it.next();
List<ReplicationState>nextOwnedListOfStates
= (List<ReplicationState>)RollingUpgradeUtil.getObject(nextOwnedListReplicationState.getState());
for(int i=0; i<nextOwnedListOfStates.size(); i++) {
ReplicationState nextState = nextOwnedListOfStates.get(i);
this.putInSipSessionReplicationCache(nextState);
}
}
}
public void triggerServletTimerActiveCacheRestoration(long waitTime, RollingUpgradeContext ctx) {
long startTime = System.currentTimeMillis();
int numberOfRespondants = RollingUpgradeUtil.getNumberOfExpectedRespondants();
restoreServletTimerActiveCacheDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateTo partner(s) to do
//active cache restoration
ownedReplicaListsReceivedForServletTimerActiveCacheRestoration
= new ConcurrentHashMap<String, ReplicationState>();
doTriggerServletTimerActiveCacheRestoration(ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
try {
restoreServletTimerActiveCacheDoneSignal.await(waitTime, TimeUnit.SECONDS);
processServletTimerActiveCacheRestorationResults(ownedReplicaListsReceivedForServletTimerActiveCacheRestoration);
} catch(InterruptedException ex) {
;
} finally {
if(restoreServletTimerActiveCacheDoneSignal.getCount() != 0) {
String errorMsg = "SipTransactionPersistentManager>>triggerServletTimerActiveCacheRestoration timed out after " + waitTime + " seconds";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerServletTimerActiveCacheRestoration successful after a wait: wait time = " + (System.currentTimeMillis() - startTime) + " active ServletTimers restored: " + servletTimers.size());
}
}
ctx.addMessage(getApplicationId(), "Active cache restoration completed for ServletTimer. " +
", Size of active cache = " + servletTimers.size() +
", Time taken (ms) = " + (System.currentTimeMillis()-startTime));
}
}
protected void doTriggerServletTimerActiveCacheRestoration(boolean isInstanceLoadBalancedByCLB) {
if(!isInstanceLoadBalancedByCLB) {
//trigger replicateTo partner to do
//active cache restoration
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String replicateToInstanceName = healthChecker.getReshapeReplicateToInstanceName(null, 0L);
sendRollingUpgradeActiveCacheRestorationAdvisory(MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_ACTIVE_CACHE_RESTORATION_ADVISORY, replicateToInstanceName);
} else {
//trigger all partners to do
//active cache restoration
sendRollingUpgradeActiveCacheRestorationAdvisory(MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_ACTIVE_CACHE_RESTORATION_ADVISORY);
}
}
protected void processServletTimerActiveCacheRestorationResults(ConcurrentHashMap<String, ReplicationState> ownedReplicaListsReceivedForActiveCacheRestoration) {
ServletTimerStoreImpl store = getSingletonServletTimerStore();
Collection<ReplicationState> ownedReplicasList = ownedReplicaListsReceivedForActiveCacheRestoration.values();
Iterator<ReplicationState> it = ownedReplicasList.iterator();
while(it.hasNext()) {
ReplicationState nextOwnedListReplicationState = it.next();
List<ReplicationState>nextOwnedListOfStates
= (List<ReplicationState>)RollingUpgradeUtil.getObject(nextOwnedListReplicationState.getState());
for(int i=0; i<nextOwnedListOfStates.size(); i++) {
ReplicationState nextState = nextOwnedListOfStates.get(i);
HAServletTimer nextTimer = null;
try {
nextTimer = store.getServletTimer(nextState);
} catch (Exception ex) {}
if(nextTimer != null) {
this.addServletTimer(nextTimer);
}
}
}
}
public void triggerServletTimerReplicaCacheRestoration(long waitTime, RollingUpgradeContext ctx) {
long startTime =System.currentTimeMillis();
int numberOfRespondants = RollingUpgradeUtil.getNumberOfExpectedRespondants();
restoreServletTimerReplicaCacheDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateFrom partner(s) to do
//replica cache restoration
ownedReplicaListsReceivedForServletTimerReplicaCacheRestoration
= new ConcurrentHashMap<String, ReplicationState>();
doTriggerServletTimerReplicaCacheRestoration(ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
try {
restoreServletTimerReplicaCacheDoneSignal.await(waitTime, TimeUnit.SECONDS);
processServletTimerReplicaCacheRestorationResults(ownedReplicaListsReceivedForServletTimerReplicaCacheRestoration);
} catch(InterruptedException ex) {
;
} finally {
if(restoreServletTimerReplicaCacheDoneSignal.getCount() != 0) {
String errorMsg = "SipTransactionPersistentManager>>triggerServletTimerReplicaCacheRestoration timed out after " + waitTime + " seconds";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerServletTimerReplicaCacheRestoration successful after a wait: wait time = " + (System.currentTimeMillis() - startTime) + " replica ServletTimers restored: " + getReplicatedServletTimers().getEntryCount());
}
}
ctx.addMessage(getApplicationId(), "Replica cache restoration completed for ServletTimer. " +
", Size of replica cache = " + getReplicatedServletTimers().getEntryCount() +
", Time taken (ms) = " + (System.currentTimeMillis()-startTime));
}
}
protected void doTriggerServletTimerReplicaCacheRestoration(boolean isInstanceLoadBalancedByCLB) {
if(!isInstanceLoadBalancedByCLB) {
//trigger replicateTo partner to do
//replica cache restoration
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String replicateToInstanceName = healthChecker.getReshapeReplicateToInstanceName(null, 0L);
sendRollingUpgradeReplicaCacheRestorationAdvisory(MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_REPLICA_CACHE_RESTORATION_ADVISORY, replicateToInstanceName);
} else {
//trigger all partners to do
//replica cache restoration
sendRollingUpgradeReplicaCacheRestorationAdvisory(MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_REPLICA_CACHE_RESTORATION_ADVISORY);
}
}
protected void processServletTimerReplicaCacheRestorationResults(ConcurrentHashMap<String, ReplicationState> ownedReplicaListsReceivedForReplicaCacheRestoration) {
Collection<ReplicationState> ownedReplicasList = ownedReplicaListsReceivedForReplicaCacheRestoration.values();
Iterator<ReplicationState> it = ownedReplicasList.iterator();
while(it.hasNext()) {
ReplicationState nextOwnedListReplicationState = it.next();
List<ReplicationState>nextOwnedListOfStates
= (List<ReplicationState>)RollingUpgradeUtil.getObject(nextOwnedListReplicationState.getState());
for(int i=0; i<nextOwnedListOfStates.size(); i++) {
ReplicationState nextState = nextOwnedListOfStates.get(i);
this.putInServletTimerReplicationCache(nextState);
}
}
}
void markActiveCacheAsSuspected(boolean value) {
Iterator it = applicationSessions.values().iterator();
while(it.hasNext()) {
((HASipApplicationSession)it.next()).setSuspect(value);
}
Iterator it2 = sipSessions.values().iterator();
while(it2.hasNext()) {
((HASipSession)it2.next()).setSuspect(value);
}
Iterator it3 = servletTimers.values().iterator();
while(it3.hasNext()) {
ServletTimerImpl timer = (ServletTimerImpl)it3.next();
if (timer.isPersistent()) {
((HAServletTimer) timer).setSuspect(value);
}
}
}
public void doActiveCacheReconciliation(long waitTime, RollingUpgradeContext ctx) {
long startTime = System.currentTimeMillis();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager>>begin doActiveCacheReconciliation");
startTime = System.currentTimeMillis();
}
this.setActiveCacheReconciliationOngoing(true);
CountDownLatch reconcileActiveCacheDoneSignal = new CountDownLatch(3);
ReconcileActiveSipApplicationSession reconcileActiveCacheSipApplicationSession
= new ReconcileActiveSipApplicationSession(this, waitTime, reconcileActiveCacheDoneSignal, ctx);
RollingUpgradeHandler.executeTask(reconcileActiveCacheSipApplicationSession);
ReconcileActiveSipSession reconcileActiveCacheSipSession
= new ReconcileActiveSipSession(this, waitTime, reconcileActiveCacheDoneSignal, ctx);
RollingUpgradeHandler.executeTask(reconcileActiveCacheSipSession);
ReconcileActiveServletTimer reconcileActiveCacheServletTimer
= new ReconcileActiveServletTimer(this, waitTime, reconcileActiveCacheDoneSignal, ctx);
RollingUpgradeHandler.executeTask(reconcileActiveCacheServletTimer);
try {
reconcileActiveCacheDoneSignal.await(waitTime, TimeUnit.SECONDS);
} catch(InterruptedException ex) {
;
} finally {
if(reconcileActiveCacheDoneSignal.getCount() != 0) {
String errorMsg = "SipTransactionPersistentManager>>doActiveCacheReconciliation timed out after " + waitTime + " seconds";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager>>doActiveCacheReconciliation successful after a wait: wait time = " + (System.currentTimeMillis() - startTime));
}
}
this.setActiveCacheReconciliationOngoing(false);
}
}
public void doSipApplicationSessionActiveCacheReconciliation(long waitTime, RollingUpgradeContext ctx) {
reconcileSipApplicationSessionActiveCache(waitTime, ctx);
}
public ConcurrentHashMap<String, FederatedQueryListElement> triggerGetIdsForSipApplicationSessionActiveCacheReconciliation(long waitTime) {
long startTime = System.currentTimeMillis();
if (_logger.isLoggable(Level.FINE)) {
startTime = System.currentTimeMillis();
}
//because sending to all instances
int numberOfRespondants = ReplicationUtil.getNumberExpectedRespondants();
getIdsForSipApplicationSessionActiveCacheReconciliationDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateTo partner(s) to
//provide owned session ids list(s)
ownedIdsForSipApplicationSessionActiveCacheReconciliation =
new ConcurrentHashMap<String, ReplicationState>();
doTriggerGetIdsForSipApplicationSessionActiveCacheReconciliation(ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
ConcurrentHashMap<String, FederatedQueryListElement> result = null;
try {
getIdsForSipApplicationSessionActiveCacheReconciliationDoneSignal.await(waitTime, TimeUnit.SECONDS);
result = processCacheReconciliationResults(ownedIdsForSipApplicationSessionActiveCacheReconciliation);
} catch(InterruptedException ex) {
result = new ConcurrentHashMap<String, FederatedQueryListElement>();
} finally {
if(getIdsForSipApplicationSessionActiveCacheReconciliationDoneSignal.getCount() != 0) {
_logger.log(Level.WARNING, "SipTransactionPersistentManager>>triggerGetIdsForSipApplicationSessionActiveCacheReconciliation timed out after "
+ waitTime + " seconds" + " signalCount=" + getIdsForSipApplicationSessionActiveCacheReconciliationDoneSignal.getCount());
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerGetIdsForSipApplicationSessionActiveCacheReconciliation successful after a wait: wait time = " + (System.currentTimeMillis() - startTime));
}
}
ownedIdsForSipApplicationSessionActiveCacheReconciliation = null;
}
return result;
}
protected void doTriggerGetIdsForSipApplicationSessionActiveCacheReconciliation(boolean isInstanceLoadBalancedByCLB) {
//trigger all partners to do
//active cache reconciliation
sendRollingUpgradeGetIdsForSipApplicationSessionActiveCacheReconciliationAdvisory();
}
/**
* broadcast a rolling upgrade getIds
* for replica cache reconciliation advisory message
*
*/
protected void sendRollingUpgradeGetIdsForSipApplicationSessionActiveCacheReconciliationAdvisory() {
//broadcast rolling upgrade getIds for replica cache reconciliation advisory
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RECONCILIATION_ADVISORY);
}
public void processRollingupgradegetidsforsipapplicationsessionactivecachereconciliationadvisory(ReplicationState replicationState) {
String instanceName = getInstanceName();
String owningInstanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processRollingupgradegetidsforsipapplicationsessionactivecachereconciliationadvisory:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processRollingupgradegetidsforsipapplicationsessionactivecachereconciliationadvisory:owningInstance=" + owningInstanceName);
}
List<FederatedQueryListElement> sipApplicationSessionIds = getSipApplicationSessionIds(owningInstanceName);
sendReplicasList(sipApplicationSessionIds, owningInstanceName, MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RECONCILIATION_RESPONSE);
}
public void processRollingupgradegetidsforsipapplicationsessionactivecachereconciliationresponse(ReplicationState replicationState) {
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradegetidsforsipapplicationsessionactivecachereconciliationresponse received from " + instanceName);
}
ownedIdsForSipApplicationSessionActiveCacheReconciliation.putIfAbsent(instanceName, replicationState);
getIdsForSipApplicationSessionActiveCacheReconciliationDoneSignal.countDown();
}
public void doSipSessionActiveCacheReconciliation(long waitTime, RollingUpgradeContext ctx) {
reconcileSipSessionActiveCache(waitTime, ctx);
}
public ConcurrentHashMap<String, FederatedQueryListElement> triggerGetIdsForSipSessionActiveCacheReconciliation(long waitTime) {
long startTime = System.currentTimeMillis();
if (_logger.isLoggable(Level.FINE)) {
startTime = System.currentTimeMillis();
}
//because sending to all instances
int numberOfRespondants = ReplicationUtil.getNumberExpectedRespondants();
getIdsForSipSessionActiveCacheReconciliationDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateTo partner(s) to
//provide owned session ids list(s)
ownedIdsForSipSessionActiveCacheReconciliation = new ConcurrentHashMap<String, ReplicationState>();
doTriggerGetIdsForSipSessionActiveCacheReconciliation(ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
ConcurrentHashMap<String, FederatedQueryListElement> result = null;
try {
getIdsForSipSessionActiveCacheReconciliationDoneSignal.await(waitTime, TimeUnit.SECONDS);
result = processCacheReconciliationResults(ownedIdsForSipSessionActiveCacheReconciliation);
} catch(InterruptedException ex) {
result = new ConcurrentHashMap<String, FederatedQueryListElement>();
} finally {
if(getIdsForSipSessionActiveCacheReconciliationDoneSignal.getCount() != 0) {
_logger.log(Level.WARNING, "SipTransactionPersistentManager>>triggerGetIdsForSipSessionActiveCacheReconciliation timed out after "
+ waitTime + " seconds");
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerGetIdsForSipSessionActiveCacheReconciliation successful after a wait: wait time = " + (System.currentTimeMillis() - startTime));
}
}
ownedIdsForSipSessionActiveCacheReconciliation = null;
}
return result;
}
protected void doTriggerGetIdsForSipSessionActiveCacheReconciliation(boolean isInstanceLoadBalancedByCLB) {
//trigger all partners to do
//active cache reconciliation
sendRollingUpgradeGetIdsForSipSessionActiveCacheReconciliationAdvisory();
}
/**
* broadcast a rolling upgrade getIds
* for replica cache reconciliation advisory message
*
*/
protected void sendRollingUpgradeGetIdsForSipSessionActiveCacheReconciliationAdvisory() {
//broadcast rolling upgrade getIds for replica cache reconciliation advisory
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_SESSION_ACTIVE_CACHE_RECONCILIATION_ADVISORY);
}
public void processRollingupgradegetidsforsipsessionactivecachereconciliationadvisory(ReplicationState replicationState) {
String instanceName = getInstanceName();
String owningInstanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processRollingupgradegetidsforsipsessionactivecachereconciliationadvisory:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processRollingupgradegetidsforsipsessionactivecachereconciliationadvisory:owningInstance=" + owningInstanceName);
}
List<FederatedQueryListElement> sipSessionIds = getSipSessionIds(owningInstanceName);
sendReplicasList(sipSessionIds, owningInstanceName, MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_SESSION_ACTIVE_CACHE_RECONCILIATION_RESPONSE);
}
public void processRollingupgradegetidsforsipsessionactivecachereconciliationresponse(ReplicationState replicationState) {
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradegetidsforsipsessionactivecachereconciliationresponse received from " + instanceName);
}
ownedIdsForSipSessionActiveCacheReconciliation.putIfAbsent(instanceName, replicationState);
getIdsForSipSessionActiveCacheReconciliationDoneSignal.countDown();
}
public void doServletTimerActiveCacheReconciliation(long waitTime, RollingUpgradeContext ctx) {
reconcileServletTimerActiveCache(waitTime, ctx);
}
public ConcurrentHashMap<String, FederatedQueryListElement> triggerGetIdsForServletTimerActiveCacheReconciliation(long waitTime) {
long startTime = 0L;
if (_logger.isLoggable(Level.FINE)) {
startTime = System.currentTimeMillis();
}
//because sending to all instances
int numberOfRespondants = ReplicationUtil.getNumberExpectedRespondants();
getIdsForServletTimerActiveCacheReconciliationDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateTo partner(s) to
//provide owned session ids list(s)
ownedIdsForServletTimerActiveCacheReconciliation =
new ConcurrentHashMap<String, ReplicationState>();
doTriggerGetIdsForServletTimerActiveCacheReconciliation(ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
ConcurrentHashMap<String, FederatedQueryListElement> result = null;
try {
getIdsForServletTimerActiveCacheReconciliationDoneSignal.await(waitTime, TimeUnit.SECONDS);
result = processCacheReconciliationResults(ownedIdsForServletTimerActiveCacheReconciliation);
} catch(InterruptedException ex) {
result = new ConcurrentHashMap<String, FederatedQueryListElement>();
} finally {
if(getIdsForServletTimerActiveCacheReconciliationDoneSignal.getCount() != 0) {
_logger.log(Level.WARNING, "SipTransactionPersistentManager>>triggerGetIdsForServletTimerActiveCacheReconciliation timed out after "
+ waitTime + " seconds");
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerGetIdsForServletTimerActiveCacheReconciliation successful after a wait: wait time = " + (System.currentTimeMillis() - startTime));
}
}
ownedIdsForServletTimerActiveCacheReconciliation = null;
}
return result;
}
protected void doTriggerGetIdsForServletTimerActiveCacheReconciliation(boolean isInstanceLoadBalancedByCLB) {
//trigger all partners to do
//active cache reconciliation
sendRollingUpgradeGetIdsForServletTimerActiveCacheReconciliationAdvisory();
}
/**
* broadcast a rolling upgrade getIds
* for replica cache reconciliation advisory message
*
*/
protected void sendRollingUpgradeGetIdsForServletTimerActiveCacheReconciliationAdvisory() {
//broadcast rolling upgrade getIds for replica cache reconciliation advisory
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SERVLET_TIMER_ACTIVE_CACHE_RECONCILIATION_ADVISORY);
}
public void processRollingupgradegetidsforservlettimeractivecachereconciliationadvisory(ReplicationState replicationState) {
String instanceName = getInstanceName();
String owningInstanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processRollingupgradegetidsforservlettimeractivecachereconciliationadvisory:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processRollingupgradegetidsforservlettimeractivecachereconciliationadvisory:owningInstance=" + owningInstanceName);
}
List<FederatedQueryListElement> servletTimerIds = getServletTimerIds(owningInstanceName);
sendReplicasList(servletTimerIds, owningInstanceName, MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SERVLET_TIMER_ACTIVE_CACHE_RECONCILIATION_RESPONSE);
}
public void processRollingupgradegetidsforservlettimeractivecachereconciliationresponse(ReplicationState replicationState) {
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradegetidsforservlettimeractivecachereconciliationresponse received from " + instanceName);
}
ownedIdsForServletTimerActiveCacheReconciliation.putIfAbsent(instanceName, replicationState);
getIdsForServletTimerActiveCacheReconciliationDoneSignal.countDown();
}
// temporarily keep the migrated sessions until they successully reach the destination.
ConcurrentHashMap<String, Set<String>> migratedSasIds =
new ConcurrentHashMap<String, Set<String>>();
ConcurrentHashMap<String, Set<String>> migratedSipSessionIds =
new ConcurrentHashMap<String, Set<String>>();
ConcurrentHashMap<String, Set<String>> migratedServletTimerIds =
new ConcurrentHashMap<String, Set<String>>();
public void processReconcilesasrequest(ReplicationState reconcileRequest) {
Set<String> migratedSessionIds = RollingUpgradeUtil.processActiveCacheReconciliationRequest(reconcileRequest,
getSingletonSipApplicationSessionStore(),
RECONCILE_SAS_RESPONSE, isReplicationCompressionEnabled());
migratedSasIds.put(reconcileRequest.getInstanceName(), migratedSessionIds);
}
public void processReconcilesasresponse(ReplicationState reconcileResponse) {
reconciledActiveSases.put(reconcileResponse.getInstanceName(),
reconcileResponse);
activeSasReconcileSignal.get().countDown();
}
public void processReconcilesasreplicarequest(ReplicationState reconcileRequest) {
RollingUpgradeUtil.processReplicaCacheReconciliationRequest(reconcileRequest, applicationSessions,
RECONCILE_SAS_REPLICA_RESPONSE, isReplicationCompressionEnabled());
}
public void processReconcilesasreplicaresponse(ReplicationState reconcileResponse) {
reconciledReplicaSases.put(reconcileResponse.getInstanceName(),
reconcileResponse);
replicaSasReconcileSignal.get().countDown();
}
public void processPostreconcilesasrequest(ReplicationState reconcileRequest) {
boolean saveMigratedSessionToReplicaCache = EEPersistenceTypeResolver.REPLICATED_TYPE.
equalsIgnoreCase(getPassedInPersistenceType());
RollingUpgradeUtil.processPostActiveCacheReconciliationRequest(reconcileRequest,
getSingletonSipApplicationSessionStore(),
migratedSasIds.get(reconcileRequest.getInstanceName()),
saveMigratedSessionToReplicaCache,
POST_RECONCILE_SAS_RESPONSE);
}
public void processPostreconcilesasresponse(ReplicationState reconcileResponse) {
remotelyLockedSases.put(reconcileResponse.getInstanceName(), reconcileResponse);
postSasReconcileSignal.get().countDown();
}
// Sip Session related methods.
public void processReconcilesipsessionrequest(ReplicationState reconcileRequest) {
Set<String> migratedSessionIds = RollingUpgradeUtil.processActiveCacheReconciliationRequest(reconcileRequest,
getSingletonSipSessionStore(),
RECONCILE_SIPSESSION_RESPONSE, isReplicationCompressionEnabled());
migratedSipSessionIds.put(reconcileRequest.getInstanceName(), migratedSessionIds);
}
public void processReconcilesipsessionresponse(ReplicationState reconcileResponse) {
reconciledActiveSipSessions.put(reconcileResponse.getInstanceName(),
reconcileResponse);
activeSipSessionReconcileSignal.get().countDown();
}
public void processReconcilesipsessionreplicarequest(ReplicationState reconcileRequest) {
RollingUpgradeUtil.processReplicaCacheReconciliationRequest(reconcileRequest, sipSessions,
RECONCILE_SIPSESSION_REPLICA_RESPONSE, isReplicationCompressionEnabled());
}
public void processReconcilesipsessionreplicaresponse(ReplicationState reconcileResponse) {
reconciledReplicaSipSessions.put(reconcileResponse.getInstanceName(),
reconcileResponse);
replicaSipSessionReconcileSignal.get().countDown();
}
public void processPostreconcilesipsessionrequest(ReplicationState reconcileRequest) {
boolean saveMigratedSessionToReplicaCache = EEPersistenceTypeResolver.REPLICATED_TYPE.
equalsIgnoreCase(getPassedInPersistenceType());
RollingUpgradeUtil.processPostActiveCacheReconciliationRequest(reconcileRequest,
getSingletonSipSessionStore(),
migratedSipSessionIds.get(reconcileRequest.getInstanceName()),
saveMigratedSessionToReplicaCache,
POST_RECONCILE_SIPSESSION_RESPONSE);
}
public void processPostreconcilesipsessionresponse(ReplicationState reconcileResponse) {
remotelyLockedSipSessions.put(reconcileResponse.getInstanceName(), reconcileResponse);
postSipSessionReconcileSignal.get().countDown();
}
// Servlet timer related methods.
public void processReconcileservlettimerrequest(ReplicationState reconcileRequest) {
Set<String> migratedSessionIds = RollingUpgradeUtil.processActiveCacheReconciliationRequest(reconcileRequest,
getSingletonServletTimerStore(),
RECONCILE_SERVLETTIMER_RESPONSE, isReplicationCompressionEnabled());
migratedServletTimerIds.put(reconcileRequest.getInstanceName(), migratedSessionIds);
}
public void processReconcileservlettimerresponse(ReplicationState reconcileResponse) {
reconciledActiveServletTimers.put(reconcileResponse.getInstanceName(),
reconcileResponse);
activeServletTimerReconcileSignal.get().countDown();
}
public void processReconcileservlettimerreplicarequest(ReplicationState reconcileRequest) {
RollingUpgradeUtil.processReplicaCacheReconciliationRequest(reconcileRequest, servletTimers,
RECONCILE_SERVLETTIMER_REPLICA_RESPONSE, isReplicationCompressionEnabled());
}
public void processReconcileservlettimerreplicaresponse(ReplicationState reconcileResponse) {
reconciledReplicaServletTimers.put(reconcileResponse.getInstanceName(),
reconcileResponse);
replicaServletTimerReconcileSignal.get().countDown();
}
public void processPostreconcileservlettimerrequest(ReplicationState reconcileRequest) {
boolean saveMigratedSessionToReplicaCache = EEPersistenceTypeResolver.REPLICATED_TYPE.
equalsIgnoreCase(getPassedInPersistenceType());
RollingUpgradeUtil.processPostActiveCacheReconciliationRequest(reconcileRequest,
getSingletonServletTimerStore(),
migratedServletTimerIds.get(reconcileRequest.getInstanceName()),
saveMigratedSessionToReplicaCache,
POST_RECONCILE_SERVLETTIMER_RESPONSE);
}
public void processPostreconcileservlettimerresponse(ReplicationState reconcileResponse) {
remotelyLockedServletTimers.put(reconcileResponse.getInstanceName(), reconcileResponse);
postServletTimerReconcileSignal.get().countDown();
}
private void reconcileSipApplicationSessionActiveCache(long waitTime, RollingUpgradeContext ctx) {
long startTime = System.currentTimeMillis();
SipApplicationSessionStoreImpl storeImpl = getSingletonSipApplicationSessionStore();
int reconciledSessions = RollingUpgradeUtil.doActiveCacheReconciliation(
storeImpl, RECONCILE_SAS_REQUEST, activeSasReconcileSignal,
waitTime, reconciledActiveSases);
long timeTaken = (System.currentTimeMillis() - startTime) / 1000;
int suspectSessions = RollingUpgradeUtil.doPostActiveCacheReconcilation(
storeImpl, POST_RECONCILE_SAS_REQUEST,
postSasReconcileSignal, waitTime - timeTaken, remotelyLockedSases);
timeTaken = System.currentTimeMillis() - startTime;
ctx.addMessage(getApplicationId(), "Active cache reconciliation completed for SipApplicationSession. " +
" No. of sessions reconciled = " + reconciledSessions +
", No. of sessions still in suspect = " + suspectSessions +
", Size of active cache = " + applicationSessions.size() +
", Size of expat = " + sasExpatIdsMap.size() + ", Time taken (ms) = " + timeTaken);
}
private void reconcileSipSessionActiveCache(long waitTime, RollingUpgradeContext ctx) {
long startTime = System.currentTimeMillis();
SipSessionStoreImpl storeImpl = getSingletonSipSessionStore();
int reconciledSessions = RollingUpgradeUtil.doActiveCacheReconciliation(
storeImpl, RECONCILE_SIPSESSION_REQUEST,
activeSipSessionReconcileSignal, waitTime, reconciledActiveSipSessions);
long timeTaken = (System.currentTimeMillis() - startTime)/1000;
int suspectSessions = RollingUpgradeUtil.doPostActiveCacheReconcilation(
storeImpl, POST_RECONCILE_SIPSESSION_REQUEST,
postSipSessionReconcileSignal, waitTime - timeTaken, remotelyLockedSipSessions);
timeTaken = System.currentTimeMillis() - startTime;
ctx.addMessage(getApplicationId(), "Active cache reconciliation completed for SipSessions. " +
" No. of sessions reconciled = " + reconciledSessions +
", No. of sessions still in suspect = " + suspectSessions +
", Size of active cache = " + sipSessions.size() +
", Size of expat = " + sipSessionExpatIdsMap.size() + ", Time taken (ms) = " + timeTaken);
}
private void reconcileServletTimerActiveCache(long waitTime, RollingUpgradeContext ctx) {
long startTime = System.currentTimeMillis();
ServletTimerStoreImpl storeImpl = getSingletonServletTimerStore();
int reconciledSessions = RollingUpgradeUtil.doActiveCacheReconciliation(
storeImpl, RECONCILE_SERVLETTIMER_REQUEST, activeServletTimerReconcileSignal,
waitTime, reconciledActiveServletTimers);
long timeTaken = (System.currentTimeMillis() - startTime) / 1000;
int suspectSessions = RollingUpgradeUtil.doPostActiveCacheReconcilation(
storeImpl, POST_RECONCILE_SERVLETTIMER_REQUEST,
postServletTimerReconcileSignal, waitTime - timeTaken, remotelyLockedServletTimers);
timeTaken = System.currentTimeMillis() - startTime;
ctx.addMessage(getApplicationId(), "Active cache reconciliation completed for ServletTimer. " +
" No. of timers reconciled = " + reconciledSessions +
", No. of timers still in suspect = " + suspectSessions +
", Size of active cache = " + servletTimers.size() +
", Size of expat = " + servletTimerExpatIdsMap.size() + ", Time taken (ms) = " + timeTaken);
}
protected void doTriggerReplicaCacheReconciliation(long waitTime, boolean isInstanceLoadBalancedByCLB) {
if(!isInstanceLoadBalancedByCLB) {
//trigger replicateFrom partner to do
//replica cache reconciliation
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
String replicateFromInstanceName = healthChecker.getReshapeReplicateFromInstanceName();
sendRollingUpgradeAdvisory(waitTime, replicateFromInstanceName);
} else {
//trigger all partners to do
//replica cache reconciliation
sendRollingUpgradeAdvisory(waitTime);
}
}
public void triggerReplicaCacheReconciliation(long waitTime, RollingUpgradeContext ctx) {
int numberOfRespondants = 1;
if(ReplicationUtil.checkIsInstanceLoadBalancedByCLB()) {
numberOfRespondants = ReplicationUtil.getNumberExpectedRespondants();
}
long startTime = System.currentTimeMillis();
if (_logger.isLoggable(Level.FINE)) {
startTime = System.currentTimeMillis();
}
reconcileReplicaCacheDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateFrom partner(s) to do
//replica cache reconciliation
doTriggerReplicaCacheReconciliation(waitTime, ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
try {
reconcileReplicaCacheDoneSignal.await(waitTime, TimeUnit.SECONDS);
} catch(InterruptedException ex) {
;
} finally {
if(reconcileReplicaCacheDoneSignal.getCount() != 0) {
String errorMsg = "SipTransactionPersistentManager>>triggerReplicaCacheReconciliation timed out after " + waitTime + " seconds";
ReplicationUtil.handleErrorMsg(errorMsg, _logger, ctx);
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerReplicaCacheReconciliation successful after a wait: wait time = " + (System.currentTimeMillis() - startTime));
}
}
}
}
/**
* reconcile the replica cache (of your replica partner)
* query instance1 to get a list of replica id/version data elements
* then do 2 iterations:
* iterate over the query result:
* if an id from this list does not exist in this active cache
* issue a remove message & load acknowledgment
* if an id exists and the versions match do nothing
* if an id exists and the active version is > replica version,
* - do a save
* iterate over the active cache
* if an id from active cache does not exist in the replica list
* - do a save
*/
public void doReplicaCacheReconciliation(long waitTime, RollingUpgradeContext ctx) {
CountDownLatch reconcileReplicaCacheDoneSignal = new CountDownLatch(3);
//cleanOutZombieReplicas();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager>>begin doReplicaCacheReconciliation");
}
ReconcileReplicaSipApplicationSession reconcileReplicaCacheSipApplicationSession
= new ReconcileReplicaSipApplicationSession(this, waitTime, reconcileReplicaCacheDoneSignal, ctx);
RollingUpgradeHandler.executeTask(reconcileReplicaCacheSipApplicationSession);
ReconcileReplicaSipSession reconcileReplicaCacheSipSession
= new ReconcileReplicaSipSession(this, waitTime, reconcileReplicaCacheDoneSignal, ctx);
RollingUpgradeHandler.executeTask(reconcileReplicaCacheSipSession);
ReconcileReplicaServletTimer reconcileReplicaCacheServletTimer
= new ReconcileReplicaServletTimer(this, waitTime, reconcileReplicaCacheDoneSignal, ctx);
RollingUpgradeHandler.executeTask(reconcileReplicaCacheServletTimer);
try {
reconcileReplicaCacheDoneSignal.await(waitTime, TimeUnit.SECONDS);
} catch(InterruptedException ex) {
} finally {
if(reconcileReplicaCacheDoneSignal.getCount() != 0) {
String errorMsg = "SipTransactionPersistentManager>>doReplicaCacheReconciliation timed out after " + waitTime + " seconds";
_logger.log(Level.WARNING, errorMsg);
}
}
}
protected ConcurrentHashMap<String, FederatedQueryListElement> processCacheReconciliationResults(ConcurrentHashMap<String, ReplicationState> ownedIdsForReplicaCacheReconciliation) {
ConcurrentHashMap<String, FederatedQueryListElement> result =
new ConcurrentHashMap<String, FederatedQueryListElement>();
Collection<ReplicationState> ownedReplicasList = ownedIdsForReplicaCacheReconciliation.values();
Iterator<ReplicationState> it = ownedReplicasList.iterator();
while(it.hasNext()) {
ReplicationState nextOwnedListReplicationState = it.next();
List<FederatedQueryListElement>nextOwnedListOfStates
= (List<FederatedQueryListElement>)RollingUpgradeUtil.getObject(nextOwnedListReplicationState.getState());
for(int i=0; i<nextOwnedListOfStates.size(); i++) {
FederatedQueryListElement nextElement = nextOwnedListOfStates.get(i);
String nextElementId = nextElement.getId();
if(nextElementId != null) {
FederatedQueryListElement existingElement = result.get(nextElementId);
if(existingElement == null || existingElement.getVersion() < nextElement.getVersion()) {
result.put(nextElementId, nextElement);
}
}
}
}
return result;
}
/**
* reconcile the replica cache (of your replica partner)
* query instance1 to get a list of replica id/version data elements
* then do 2 iterations:
* iterate over the query result:
* if an id from this list does not exist in this active cache
* issue a remove message & load acknowledgment
* if an id exists and the versions match do nothing
* if an id exists and the active version is > replica version,
* - do a save
* iterate over the active cache
* if an id from active cache does not exist in the replica list
* - do a save
* @param waitTime the waitTime
*/
void doSipApplicationSessionReplicaCacheReconciliation(long waitTime, RollingUpgradeContext ctx) {
reconcileSipApplicationSessionReplicaCache(waitTime, ctx);
}
public ConcurrentHashMap<String, FederatedQueryListElement> triggerGetIdsForSipApplicationSessionReplicaCacheReconciliation(long waitTime) {
long startTime = 0L;
if (_logger.isLoggable(Level.FINE)) {
startTime = System.currentTimeMillis();
}
//because sending to all instances
int numberOfRespondants = ReplicationUtil.getNumberExpectedRespondants();
getIdsForSipApplicationSessionReplicaCacheReconciliationDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateTo partner(s) to
//provide owned session ids list(s)
ownedIdsForSipApplicationSessionReplicaCacheReconciliation =
new ConcurrentHashMap<String, ReplicationState>();
doTriggerGetIdsForSipApplicationSessionReplicaCacheReconciliation(ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
ConcurrentHashMap<String, FederatedQueryListElement> result = null;
try {
getIdsForSipApplicationSessionReplicaCacheReconciliationDoneSignal.await(waitTime, TimeUnit.SECONDS);
result = processCacheReconciliationResults(ownedIdsForSipApplicationSessionReplicaCacheReconciliation);
} catch(InterruptedException ex) {
result = new ConcurrentHashMap<String, FederatedQueryListElement>();
} finally {
if(getIdsForSipApplicationSessionReplicaCacheReconciliationDoneSignal.getCount() != 0) {
_logger.log(Level.WARNING, "SipTransactionPersistentManager>>triggerGetIdsForSipApplicationSessionReplicaCacheReconciliation timed out after "
+ waitTime + " seconds");
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerGetIdsForSipApplicationSessionReplicaCacheReconciliation successful after a wait: wait time = " + (System.currentTimeMillis() - startTime));
}
}
ownedIdsForSipApplicationSessionReplicaCacheReconciliation = null;
}
return result;
}
protected void doTriggerGetIdsForSipApplicationSessionReplicaCacheReconciliation(boolean isInstanceLoadBalancedByCLB) {
//trigger all partners to do
//replica cache reconciliation
sendRollingUpgradeGetIdsForSipApplicationSessionReplicaCacheReconciliationAdvisory();
}
/**
* broadcast a rolling upgrade getIds
* for replica cache reconciliation advisory message
*
*/
protected void sendRollingUpgradeGetIdsForSipApplicationSessionReplicaCacheReconciliationAdvisory() {
//broadcast rolling upgrade getIds for replica cache reconciliation advisory
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_APPLICATION_SESSION_REPLICA_CACHE_RECONCILIATION_ADVISORY);
}
public void processRollingupgradegetidsforsipapplicationsessionreplicacachereconciliationadvisory(ReplicationState replicationState) {
String instanceName = getInstanceName();
String owningInstanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processRollingupgradegetidsforsipapplicationsessionreplicacachereconciliationadvisory:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processRollingupgradegetidsforsipapplicationsessionreplicacachereconciliationadvisory:owningInstance=" + owningInstanceName);
}
List<FederatedQueryListElement> sessionIds = null;
if(!this.isThirdPartyBackingStoreInUse()) {
sessionIds = getSipApplicationSessionIds(owningInstanceName);
} else {
sessionIds = getSipApplicationSessionIdsThirdPartySPI(owningInstanceName);
}
sendReplicasList(sessionIds, owningInstanceName, MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_APPLICATION_SESSION_REPLICA_CACHE_RECONCILIATION_RESPONSE);
}
public void processRollingupgradegetidsforsipapplicationsessionreplicacachereconciliationresponse(ReplicationState replicationState) {
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradegetidsforsipapplicationsessionreplicacachereconciliationresponse received from " + instanceName);
}
ownedIdsForSipApplicationSessionReplicaCacheReconciliation.putIfAbsent(instanceName, replicationState);
getIdsForSipApplicationSessionReplicaCacheReconciliationDoneSignal.countDown();
}
/**
* reconcile the replica cache (of your replica partner)
* query instance1 to get a list of replica id/version data elements
* then do 2 iterations:
* iterate over the query result:
* if an id from this list does not exist in this active cache
* issue a remove message & load acknowledgment
* if an id exists and the versions match do nothing
* if an id exists and the active version is > replica version,
* - do a save
* iterate over the active cache
* if an id from active cache does not exist in the replica list
* - do a save
* @param waitTime the waitTime
*/
void doSipSessionReplicaCacheReconciliation(long waitTime, RollingUpgradeContext ctx) {
reconcileSipSessionReplicaCache(waitTime, ctx);
}
public ConcurrentHashMap<String, FederatedQueryListElement> triggerGetIdsForSipSessionReplicaCacheReconciliation(long waitTime) {
long startTime = 0L;
if (_logger.isLoggable(Level.FINE)) {
startTime = System.currentTimeMillis();
}
//because sending to all instances
int numberOfRespondants = ReplicationUtil.getNumberExpectedRespondants();
getIdsForSipSessionReplicaCacheReconciliationDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateTo partner(s) to
//provide owned session ids list(s)
ownedIdsForSipSessionReplicaCacheReconciliation
= new ConcurrentHashMap<String, ReplicationState>();
doTriggerGetIdsForSipSessionReplicaCacheReconciliation(ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
ConcurrentHashMap<String, FederatedQueryListElement> result = null;
try {
getIdsForSipSessionReplicaCacheReconciliationDoneSignal.await(waitTime, TimeUnit.SECONDS);
result = processCacheReconciliationResults(ownedIdsForSipSessionReplicaCacheReconciliation);
} catch(InterruptedException ex) {
result = new ConcurrentHashMap<String, FederatedQueryListElement>();
} finally {
if(getIdsForSipSessionReplicaCacheReconciliationDoneSignal.getCount() != 0) {
_logger.log(Level.WARNING, "SipTransactionPersistentManager>>triggerGetIdsForSipSessionReplicaCacheReconciliation timed out after "
+ waitTime + " seconds");
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerGetIdsForSipSessionReplicaCacheReconciliation successful after a wait: wait time = " + (System.currentTimeMillis() - startTime));
}
}
ownedIdsForSipSessionReplicaCacheReconciliation = null;
}
return result;
}
protected void doTriggerGetIdsForSipSessionReplicaCacheReconciliation(boolean isInstanceLoadBalancedByCLB) {
//trigger all partners to do
//replica cache reconciliation
sendRollingUpgradeGetIdsForSipSessionReplicaCacheReconciliationAdvisory();
}
/**
* broadcast a rolling upgrade getIds
* for replica cache reconciliation advisory message
*
*/
protected void sendRollingUpgradeGetIdsForSipSessionReplicaCacheReconciliationAdvisory() {
//broadcast rolling upgrade getIds for replica cache reconciliation advisory
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_SESSION_REPLICA_CACHE_RECONCILIATION_ADVISORY);
}
public void processRollingupgradegetidsforsipsessionreplicacachereconciliationadvisory(ReplicationState replicationState) {
String instanceName = getInstanceName();
String owningInstanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processRollingupgradegetidsforsipsessionreplicacachereconciliationadvisory:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processRollingupgradegetidsforsipsessionreplicacachereconciliationadvisory:owningInstance=" + owningInstanceName);
}
List<FederatedQueryListElement> sessionIds = null;
if(!this.isThirdPartyBackingStoreInUse()) {
sessionIds = getSipSessionIds(owningInstanceName);
} else {
sessionIds = getSipSessionIdsThirdPartySPI(owningInstanceName);
}
sendReplicasList(sessionIds, owningInstanceName, MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SIP_SESSION_REPLICA_CACHE_RECONCILIATION_RESPONSE);
}
public void processRollingupgradegetidsforsipsessionreplicacachereconciliationresponse(ReplicationState replicationState) {
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradegetidsforsipsessionreplicacachereconciliationresponse received from " + instanceName);
}
ownedIdsForSipSessionReplicaCacheReconciliation.putIfAbsent(instanceName, replicationState);
getIdsForSipSessionReplicaCacheReconciliationDoneSignal.countDown();
}
/**
* reconcile the replica cache (of your replica partner)
* query instance1 to get a list of replica id/version data elements
* then do 2 iterations:
* iterate over the query result:
* if an id from this list does not exist in this active cache
* issue a remove message & load acknowledgment
* if an id exists and the versions match do nothing
* if an id exists and the active version is > replica version,
* - do a save
* iterate over the active cache
* if an id from active cache does not exist in the replica list
* - do a save
* @param waitTime the waitTime
*/
void doServletTimerReplicaCacheReconciliation(long waitTime, RollingUpgradeContext ctx) {
reconcileServletTimerReplicaCache(waitTime, ctx);
}
public ConcurrentHashMap<String, FederatedQueryListElement> triggerGetIdsForServletTimerReplicaCacheReconciliation(long waitTime) {
long startTime = 0L;
if (_logger.isLoggable(Level.FINE)) {
startTime = System.currentTimeMillis();
}
//because sending to all instances
int numberOfRespondants = ReplicationUtil.getNumberExpectedRespondants();
getIdsForServletTimerReplicaCacheReconciliationDoneSignal = new CountDownLatch(numberOfRespondants);
//trigger replicateTo partner(s) to
//provide owned session ids list(s)
ownedIdsForServletTimerReplicaCacheReconciliation
= new ConcurrentHashMap<String, ReplicationState>();
doTriggerGetIdsForServletTimerReplicaCacheReconciliation(ReplicationUtil.checkIsInstanceLoadBalancedByCLB());
ConcurrentHashMap<String, FederatedQueryListElement> result = null;
try {
getIdsForServletTimerReplicaCacheReconciliationDoneSignal.await(waitTime, TimeUnit.SECONDS);
result = processCacheReconciliationResults(ownedIdsForServletTimerReplicaCacheReconciliation);
} catch(InterruptedException ex) {
result = new ConcurrentHashMap<String, FederatedQueryListElement>();
} finally {
if(getIdsForServletTimerReplicaCacheReconciliationDoneSignal.getCount() != 0) {
_logger.log(Level.WARNING, "SipTransactionPersistentManager>>triggerGetIdsForServletTimerReplicaCacheReconciliation timed out after "
+ waitTime + " seconds");
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipTransactionPersistentManager triggerGetIdsForServletTimerReplicaCacheReconciliation successful after a wait: wait time = " + (System.currentTimeMillis() - startTime));
}
}
ownedIdsForServletTimerReplicaCacheReconciliation = null;
}
return result;
}
protected void doTriggerGetIdsForServletTimerReplicaCacheReconciliation(boolean isInstanceLoadBalancedByCLB) {
//trigger all partners to do
//replica cache reconciliation
sendRollingUpgradeGetIdsForServletTimerReplicaCacheReconciliationAdvisory();
}
/**
* broadcast a rolling upgrade getIds
* for replica cache reconciliation advisory message
*
*/
protected void sendRollingUpgradeGetIdsForServletTimerReplicaCacheReconciliationAdvisory() {
//broadcast rolling upgrade getIds for replica cache reconciliation advisory
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SERVLET_TIMER_REPLICA_CACHE_RECONCILIATION_ADVISORY);
}
public void processRollingupgradegetidsforservlettimerreplicacachereconciliationadvisory(ReplicationState replicationState) {
String instanceName = getInstanceName();
String owningInstanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processRollingupgradegetidsforservlettimerreplicacachereconciliationadvisory:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processRollingupgradegetidsforservlettimerreplicacachereconciliationadvisory:owningInstance=" + owningInstanceName);
}
List<FederatedQueryListElement> servletTimerIds = null;
if(!this.isThirdPartyBackingStoreInUse()) {
servletTimerIds = getServletTimerIds(owningInstanceName);
} else {
servletTimerIds = getServletTimerIdsThirdPartySPI(owningInstanceName);
}
sendReplicasList(servletTimerIds, owningInstanceName, MESSAGE_BROADCAST_ROLLING_UPGRADE_GET_IDS_FOR_SERVLET_TIMER_REPLICA_CACHE_RECONCILIATION_RESPONSE);
}
public void processRollingupgradegetidsforservlettimerreplicacachereconciliationresponse(ReplicationState replicationState) {
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradegetidsforservlettimerreplicacachereconciliationresponse received from " + instanceName);
}
ownedIdsForServletTimerReplicaCacheReconciliation.putIfAbsent(instanceName, replicationState);
getIdsForServletTimerReplicaCacheReconciliationDoneSignal.countDown();
}
void cleanOutZombieReplicas() {
//FIXME for now issue load acknowledgement for each
//active cache entry
//this is functionally correct but not optimal
//solution will be to improve query for replica
//ids to track the source instance and then only
//issue load acks to those ids that are not from
//our replicate to partner
cleanOutZombieSipApplicationSessionReplicas();
cleanOutZombieSipSessionReplicas();
cleanOutZombieServletTimerReplicas();
}
void cleanOutZombieSipApplicationSessionReplicas() {
HASipApplicationSession sas = null;
Iterator it = applicationSessions.values().iterator();
while(it.hasNext()) {
sas = (HASipApplicationSession)it.next();
String sasId = sas.getId();
long version = sas.getVersion();
this.sendLoadAcknowledgement(sasId, version, MESSAGE_BROADCAST_LOAD_RECEIVED_SAS, sas.getBeKey());
}
}
void cleanOutZombieSipSessionReplicas() {
HASipSession ss = null;
Iterator it = sipSessions.values().iterator();
while(it.hasNext()) {
ss = (HASipSession)it.next();
String ssId = ss.getId();
long version = ss.getVersion();
String beKey = null;
String sasId = ss.getParentSASId();
if(sasId != null) {
beKey = SipApplicationSessionUtil.getSipApplicationKey(sasId);
}
this.sendLoadAcknowledgement(ssId, version, MESSAGE_BROADCAST_LOAD_RECEIVED_SIP_SESSION, beKey);
}
}
void cleanOutZombieServletTimerReplicas() {
HAServletTimer st = null;
Iterator it = servletTimers.values().iterator();
while(it.hasNext()) {
st = (HAServletTimer)it.next();
if (!st.isPersistent()) {
continue;
}
String stId = st.getId();
long version = st.getVersion();
String beKey = null;
String sasId = st.getParentSASId();
if(sasId != null) {
beKey = SipApplicationSessionUtil.getSipApplicationKey(sasId);
}
this.sendLoadAcknowledgement(stId, version, MESSAGE_BROADCAST_LOAD_RECEIVED_SERVLET_TIMER, beKey);
}
}
private void reconcileSipApplicationSessionReplicaCache(long waitTime, RollingUpgradeContext ctx) {
long startTime = System.currentTimeMillis();
SipApplicationSessionStoreImpl storeImpl = getSingletonSipApplicationSessionStore();
int sessionsReconciled = RollingUpgradeUtil.doReplicaCacheReconciliation(
storeImpl, RECONCILE_SAS_REPLICA_REQUEST,
replicaSasReconcileSignal, waitTime, reconciledReplicaSases);
long timeTaken = System.currentTimeMillis() - startTime;
ctx.addMessage(getApplicationId(), "Replica cache reconciliation completed for SipApplicationSession. " +
" No of sessions reconciled = " + sessionsReconciled +
", Size of replica cache = " + getReplicatedSipApplicationSessions().getEntryCount() +
", Time taken (ms) = " + timeTaken);
}
private void reconcileSipSessionReplicaCache(long waitTime, RollingUpgradeContext ctx) {
long startTime = System.currentTimeMillis();
SipSessionStoreImpl storeImpl = getSingletonSipSessionStore();
int sessionsReconciled = RollingUpgradeUtil.doReplicaCacheReconciliation(
storeImpl, RECONCILE_SIPSESSION_REPLICA_REQUEST,
replicaSipSessionReconcileSignal, waitTime, reconciledReplicaSipSessions);
long timeTaken = System.currentTimeMillis() - startTime;
ctx.addMessage(getApplicationId(), "Replica cache reconciliation completed for SipSession. " +
" No of sessions reconciled = " + sessionsReconciled +
", Size of replica cache = " + getReplicatedSipApplicationSessions().getEntryCount() +
", Time taken (ms) = " + timeTaken);
}
private void reconcileServletTimerReplicaCache(long waitTime, RollingUpgradeContext ctx) {
long startTime = System.currentTimeMillis();
ServletTimerStoreImpl storeImpl = getSingletonServletTimerStore();
int sessionsReconciled = RollingUpgradeUtil.doReplicaCacheReconciliation(
storeImpl, RECONCILE_SERVLETTIMER_REPLICA_REQUEST,
replicaServletTimerReconcileSignal, waitTime, reconciledReplicaServletTimers);
long timeTaken = System.currentTimeMillis() - startTime;
ctx.addMessage(getApplicationId(), "Replica cache reconciliation completed for ServletTimer. " +
" No of timers reconciled = " + sessionsReconciled +
", Size of replica cache = " + getReplicatedServletTimers().getEntryCount() +
", Time taken (ms) = " + timeTaken);
}
/**
* send a load acknowledgement
*
* @param state
* @param beKey
*/
protected void sendLoadAcknowledgement(ReplicationState state, String beKey) {
SipApplicationSessionStoreImpl store = null;
try {
store = getSipApplicationSessionStore();
if (store != null) {
store.sendLoadAcknowledgement(state, beKey);
}
}
finally {
this.putSipApplicationSessionStore(store);
}
}
protected void sendUnicastLoadAcknowledgementSAS(String id, String instance, String bekey) {
SipApplicationSessionStoreImpl store = null;
try {
store = getSipApplicationSessionStore();
if (store != null) {
store.sendUnicastLoadAcknowledgement(id, instance, bekey);
}
}
finally {
this.putSipApplicationSessionStore(store);
}
}
void sendSasLoadAcks(String instance, HashSet<String> ids) {
SipApplicationSessionStoreImpl store = null;
try {
store = getSipApplicationSessionStore();
if (store != null) {
store.sendLoadAcks(instance, ids);
}
}
finally {
this.putSipApplicationSessionStore(store);
}
}
protected void sendUnicastLoadAcknowledgementST(String id, String instance, String bekey) {
ServletTimerStoreImpl store = null;
try {
store = getServletTimerStore();
if (store != null) {
store.sendUnicastLoadAcknowledgement(id, instance, bekey);
}
}
finally {
putServletTimerStore(store);
}
}
protected void sendLoadAcknowledgement(String id, long version, String command, String beKey) {
JxtaReplicationSender sender
= JxtaReplicationSender.createInstance();
ReplicationState loadReceivedState =
ReplicationState.createBroadcastLoadReceivedState(MODE_SIP, id, this.getApplicationId(), version, getInstanceName(), command);
if ((beKey != null) && replicationUtil.isInstanceLoadBalancedByCLB()){
loadReceivedState.setProperty(ReplicationState.IGNORE_REMOVE_INSTANCE_NAME,
replicationUtil.getFailoverServerInstanceForBeKey(beKey));
} else {
ReplicationHealthChecker healthChecker = ReplicationHealthChecker.getInstance();
String currentReplicaPartner = healthChecker.getCurrentPartnerInstanceName();
loadReceivedState.setProperty(ReplicationState.IGNORE_REMOVE_INSTANCE_NAME,
currentReplicaPartner);
}
sender.sendBroadcastQuery(loadReceivedState);
}
protected void readSipApplicationSessions(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
int count = ois.readInt();
for(int i=0; i<count; i++) {
HASipApplicationSession nextSas = (HASipApplicationSession)ois.readObject();
applicationSessions.put(nextSas.getId(), nextSas);
}
}
protected void readReplicatedSipApplicationSessionUpdates(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
sipApplicationSessionReplicaCache.readReplicatedSessionUpdates(ois);
}
protected void readSipSessions(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
int count = ois.readInt();
for(int i=0; i<count; i++) {
HASipSession nextSipSession = (HASipSession)ois.readObject();
sipSessions.put(nextSipSession.getId(), nextSipSession);
}
}
protected void readReplicatedSipSessionUpdates(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
sipSessionReplicaCache.readReplicatedSessionUpdates(ois);
}
protected void readServletTimers(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
int count = ois.readInt();
for(int i=0; i<count; i++) {
HAServletTimer nextServletTimer = (HAServletTimer)ois.readObject();
servletTimers.put(nextServletTimer.getId(), nextServletTimer);
}
}
protected void readReplicatedServletTimerUpdates(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
servletTimerReplicaCache.readReplicatedSessionUpdates(ois);
}
protected void writeSipApplicationSessions(ObjectOutputStream oos)
throws IOException {
ReplicationUtil.writeHashMap((AbstractMap)applicationSessions, oos);
}
protected void writeReplicatedSipApplicationSessionUpdates(ObjectOutputStream oos)
throws IOException {
sipApplicationSessionReplicaCache.writeReplicatedSessionUpdates(oos);
}
protected void writeSipSessions(ObjectOutputStream oos)
throws IOException {
ReplicationUtil.writeHashMap((AbstractMap)sipSessions, oos);
}
protected void writeReplicatedSipSessionUpdates(ObjectOutputStream oos)
throws IOException {
sipSessionReplicaCache.writeReplicatedSessionUpdates(oos);
}
protected void writeServletTimers(ObjectOutputStream oos)
throws IOException {
ReplicationUtil.writeHashMap((AbstractMap)servletTimers, oos);
}
protected void writeReplicatedServletTimerUpdates(ObjectOutputStream oos)
throws IOException {
servletTimerReplicaCache.writeReplicatedSessionUpdates(oos);
}
public HashSet<ExpatListElement> getExpatListFor(String instanceName,
String command) {
boolean isRemoteInstance = !getInstanceName().equals(instanceName);
if (MESSAGE_BROADCAST_EXPAT_QUERY_SAS.equals(command)) {
return isRemoteInstance ? getSASExpatIdsFromActive(instanceName)
: new HashSet<ExpatListElement>();
// return getSASExpatIds(instanceName, isRemoteInstance);
}
if (MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION.equals(command)) {
return isRemoteInstance ? getSipSessionExpatIdsFromActive(instanceName)
: new HashSet<ExpatListElement>();
// return getSipSessionExpatIds(instanceName, isRemoteInstance);
}
if (MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER.equals(command)) {
return isRemoteInstance ? getServletTimerExpatIdsFromActive(instanceName)
: new HashSet<ExpatListElement>();
// return getServletTimerExpatIds(instanceName, isRemoteInstance);
}
/**
* Added on behalf of __synchronizeKeys
*/
if(MESSAGE_BROADCAST_EXPAT_QUERY_SAS_REPLICA.equals(command)) {
return getSASExpatIdsFromReplica(instanceName);
}
if(MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION_REPLICA.equals(command)) {
return getSipSessionExpatIdsFromReplica(instanceName);
}
if(MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER_REPLICA.equals(command)) {
return getServletTimerExpatIdsFromReplica(instanceName);
}
throw new IllegalArgumentException("Invalid command " + command);
}
public void getExpatLists(String command, ExpatListQueryResults result) {
if(MESSAGE_BROADCAST_EXPAT_QUERY_SAS.equals(command)) {
// getAllSASExpatIds(result);
getSASExpatIdsFromActive(result);
} else if(MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION.equals(command)) {
// getAllSipSessionExpatIds(result);
getSipSessionExpatIdsFromActive(result);
} else if(MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER.equals(command)) {
// getAllServletTimerExpatIds(result);
getServletTimerExpatIdsFromActive(result);
} else if(MESSAGE_BROADCAST_EXPAT_QUERY_SAS_REPLICA.equals(command)) {
getSASExpatIdsFromReplica(result);
} else if(MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION_REPLICA.equals(command)) {
getSipSessionExpatIdsFromReplica(result);
} else if(MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER_REPLICA.equals(command)) {
getServletTimerExpatIdsFromReplica(result);
} else {
throw new IllegalArgumentException("Invalid command " + command);
}
}
// TODO :: since there is no pruning done in this method, rename it to getCurrentExpatList
public HashMap<String, ExpatListElement> pruneExpatList(String command) {
if(MESSAGE_BROADCAST_EXPAT_QUERY_SAS.equals(command)) {
// don't prune, otherwise multiple failure + restart with
// load-factor < 1 will not work. Until load-factor becomes 1,
// the requests will continue to land in the earlier instance. So,
// the expat elements are necessary until then.
return sasExpatIdsMap;
}
if(MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION.equals(command)) {
// TODO :: how to prune???
return sipSessionExpatIdsMap;
}
if(MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER.equals(command)) {
// TODO :: how to prune???
return servletTimerExpatIdsMap;
}
if(MESSAGE_BROADCAST_EXPAT_QUERY_SAS_REPLICA.equals(command) ||
MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION_REPLICA.equals(command) ||
MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER_REPLICA.equals(command)) {
return new HashMap<String, ExpatListElement>();
}
throw new IllegalArgumentException("Invalid command " + command);
}
public String getExpatPushCommandFor(String expatQueryCommand) {
if(MESSAGE_BROADCAST_EXPAT_QUERY_SAS.equals(expatQueryCommand)) {
return MESSAGE_BROADCAST_EXPAT_RECEIVE_SAS;
}
if(MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION.equals(expatQueryCommand)) {
return MESSAGE_BROADCAST_EXPAT_RECEIVE_SIP_SESSION;
}
if(MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER.equals(expatQueryCommand)) {
return MESSAGE_BROADCAST_EXPAT_RECEIVE_SERVLET_TIMER;
}
/**
* Added on behalf of __synchronizeKeys implementation
*/
if(MESSAGE_BROADCAST_EXPAT_QUERY_SAS_REPLICA.equals(expatQueryCommand)) {
return MESSAGE_BROADCAST_EXPAT_RECEIVE_SAS_REPLICA;
}
if(MESSAGE_BROADCAST_EXPAT_QUERY_SIP_SESSION_REPLICA.equals(expatQueryCommand)) {
return MESSAGE_BROADCAST_EXPAT_RECEIVE_SIP_SESSION_REPLICA;
}
if(MESSAGE_BROADCAST_EXPAT_QUERY_SERVLET_TIMER_REPLICA.equals(expatQueryCommand)) {
return MESSAGE_BROADCAST_EXPAT_RECEIVE_SERVLET_TIMER_REPLICA;
}
throw new IllegalArgumentException("Invalid command " + expatQueryCommand);
}
public void processBroadcastreceivesasexpatids(
ReplicationState expatListState) {
ExpatListListener expatListener =
sasExpatListHandler.getListener();
if(expatListener != null) {
expatListener.expatListReceived(expatListState);
}
}
public void processBroadcastreceivesipsessionexpatids(
ReplicationState expatListState) {
ExpatListListener expatListener =
sipSessionExpatListHandler.getListener();
if(expatListener != null) {
expatListener.expatListReceived(expatListState);
}
}
public void processBroadcastreceiveservlettimerexpatids(
ReplicationState expatListState) {
ExpatListListener expatListener =
servletTimerExpatListHandler.getListener();
if(expatListener != null) {
expatListener.expatListReceived(expatListState);
}
}
private void expatListReceived(ReplicationState expatListState,
ExpatListHandler expatHandler) {
if(expatHandler != null) {
ExpatListListener expatListener =
expatHandler.getListener();
if (expatListener != null) {
expatListener.expatListReceived(expatListState);
}
}
}
public void processBroadcastreceivesasreplicaexpatids(
ReplicationState expatListState) {
expatListReceived(expatListState, sasReplicaExpatHandler);
}
public void processBroadcastreceivesipsessionreplicaexpatids(
ReplicationState expatListState) {
expatListReceived(expatListState, ssReplicaExpatHandler);
}
public void processBroadcastreceiveservlettimerreplicaexpatids(
ReplicationState expatListState) {
expatListReceived(expatListState, stReplicaExpatHandler);
}
//SipApplicationSession related
List<FederatedQueryListElement> getSipApplicationSessionIds(String owningInstanceName) {
List<FederatedQueryListElement> sessionIds = new ArrayList();
//using set to avoid dups
HashSet sessionIdsSet = new HashSet();
List replicasToRemove = new ArrayList();
ReplicationHealthChecker healthChecker = ReplicationHealthChecker.getInstance();
String correctBuddyReplicaName
= healthChecker.getReshapeReplicateToInstanceName(null, owningInstanceName, 0L);
//iterate over http replicas
BaseCache replicatedSipApplicationSessionsCache = getReplicatedSipApplicationSessions();
Iterator it = replicatedSipApplicationSessionsCache.values();
while(it.hasNext()) {
ReplicationState nextState
= (ReplicationState)it.next();
if(!RollingUpgradeUtil.filterOwnership(owningInstanceName, correctBuddyReplicaName, nextState, sessionIdsSet)) {
//we remove this entry if it is not on the correct replica partner - i.e. it is a zombie
replicasToRemove.add(nextState.getId());
}
}
for(int i=0; i<replicasToRemove.size(); i++) {
String nextId = (String)replicasToRemove.get(i);
if(nextId != null) {
removeFromSipApplicationSessionReplicationCache(nextId);
}
}
sessionIds.addAll(sessionIdsSet);
return sessionIds;
}
/**
* process the broadcastfindsipapplicationsessionids for SipApplicationSession
* @param queryState
*/
public ReplicationState processBroadcastfindsipapplicationsessionids(ReplicationState queryState) {
//complete query and send back response
String instanceName = getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsipapplicationsessionids:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsipapplicationsessionids:owningInstance=" + queryState.getInstanceName());
}
String owningInstanceName = queryState.getInstanceName();
List sessionIds = null;
if(this.isThirdPartyBackingStoreInUse()) {
sessionIds
= getSipApplicationSessionIdsThirdPartySPI(owningInstanceName);
} else {
sessionIds
= getSipApplicationSessionIds(owningInstanceName);
}
byte[] resultState = null;
try {
resultState = ReplicationUtil.getByteArray((ArrayList)sessionIds);
} catch (IOException ex) {
//deliberate no-op
;
}
//first check for none found in either active or replica caches
if(sessionIds == null || sessionIds.isEmpty()) {
//return nack
return ReplicationState.createQueryResponseFrom(queryState, true);
} else {
return ReplicationState.createQueryResponseFrom(queryState, resultState);
}
}
//SipSession related
List<FederatedQueryListElement> getSipSessionIds(String owningInstanceName) {
List<FederatedQueryListElement> sessionIds = new ArrayList();
//using set to avoid dups
HashSet sessionIdsSet = new HashSet();
List replicasToRemove = new ArrayList();
ReplicationHealthChecker healthChecker = ReplicationHealthChecker.getInstance();
String correctBuddyReplicaName
= healthChecker.getReshapeReplicateToInstanceName(null, owningInstanceName, 0L);
//iterate over http replicas
BaseCache replicatedSipSessionsCache = getReplicatedSipSessions();
Iterator it = replicatedSipSessionsCache.values();
while(it.hasNext()) {
ReplicationState nextState
= (ReplicationState)it.next();
if(!RollingUpgradeUtil.filterOwnership(owningInstanceName, correctBuddyReplicaName, nextState, sessionIdsSet)) {
//we remove this entry if it is not on the correct replica partner - i.e. it is a zombie
replicasToRemove.add(nextState.getId());
}
}
for(int i=0; i<replicasToRemove.size(); i++) {
String nextId = (String)replicasToRemove.get(i);
if(nextId != null) {
removeFromSipSessionReplicationCache(nextId);
}
}
sessionIds.addAll(sessionIdsSet);
return sessionIds;
}
List<FederatedQueryListElement> getSipApplicationSessionIdsThirdPartySPI(String owningInstanceName) {
BackingStore backingStore
= this.getSipApplicationSessionBackingStore();
SipApplicationSessionExtraParams sasExtraParamCriteria
= SipApplicationSessionExtraParams.createSearchCriteria(
this, this.getApplicationId(), owningInstanceName);
Collection<SipApplicationSessionExtraParams> sasColl
= backingStore.findByCriteria(null, sasExtraParamCriteria);
List<FederatedQueryListElement> sessionIds = new ArrayList();
//using set to avoid dups
HashSet sessionIdsSet = new HashSet();
Iterator<SipApplicationSessionExtraParams> sasResults =
(Iterator<SipApplicationSessionExtraParams>) sasColl.iterator();
while (sasResults.hasNext()) {
SipApplicationSessionExtraParams eParam = sasResults.next();
if (owningInstanceName.equals(eParam.getCurrentOwnerInstanceName())) {
sessionIdsSet.add(new FederatedQueryListElement((String) eParam.getId(), -1L, getInstanceName()));
}
}
sessionIds.addAll(sessionIdsSet);
return sessionIds;
}
/**
* process the broadcastfindsipsessionids for SipSession
* @param queryState
*/
public ReplicationState processBroadcastfindsipsessionids(ReplicationState queryState) {
//complete query and send back response
String instanceName = getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsipsessionids:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindsipsessionids:owningInstance=" + queryState.getInstanceName());
}
String owningInstanceName = queryState.getInstanceName();
List sessionIds = null;
if(this.isThirdPartyBackingStoreInUse()) {
sessionIds
= getSipSessionIdsThirdPartySPI(owningInstanceName);
} else {
sessionIds
= getSipSessionIds(owningInstanceName);
}
byte[] resultState = null;
try {
resultState = ReplicationUtil.getByteArray((ArrayList)sessionIds);
} catch (IOException ex) {
//deliberate no-op
;
}
//first check for none found in either active or replica caches
if(sessionIds == null || sessionIds.isEmpty()) {
//return nack
return ReplicationState.createQueryResponseFrom(queryState, true);
} else {
return ReplicationState.createQueryResponseFrom(queryState, resultState);
}
}
List<FederatedQueryListElement> getSipSessionIdsThirdPartySPI(String owningInstanceName) {
BackingStore backingStore
= this.getSipSessionBackingStore();
SipSessionExtraParams ssExtraParamCriteria
= SipSessionExtraParams.createSearchCriteria(this, owningInstanceName);
Collection<SipSessionExtraParams> ssColl
= backingStore.findByCriteria(null, ssExtraParamCriteria);
List<FederatedQueryListElement> sessionIds = new ArrayList();
//using set to avoid dups
HashSet sessionIdsSet = new HashSet();
Iterator<SipSessionExtraParams> ssResults =
(Iterator<SipSessionExtraParams>) ssColl.iterator();
while (ssResults.hasNext()) {
SipSessionExtraParams eParam = ssResults.next();
if (owningInstanceName.equals(eParam.getCurrentOwnerInstanceName())) {
sessionIdsSet.add(new FederatedQueryListElement((String)eParam.getId(), -1L, getInstanceName()));
}
}
sessionIds.addAll(sessionIdsSet);
return sessionIds;
}
//ServletTimer related
List<FederatedQueryListElement> getServletTimerIds(String owningInstanceName) {
List<FederatedQueryListElement> servletTimerIds = new ArrayList();
//using set to avoid dups
HashSet servletTimerIdsSet = new HashSet();
List replicasToRemove = new ArrayList();
ReplicationHealthChecker healthChecker = ReplicationHealthChecker.getInstance();
String correctBuddyReplicaName
= healthChecker.getReshapeReplicateToInstanceName(null, owningInstanceName, 0L);
//iterate over http replicas
BaseCache replicatedServletTimersCache = getReplicatedServletTimers();
Iterator it = replicatedServletTimersCache.values();
while(it.hasNext()) {
ReplicationState nextState
= (ReplicationState)it.next();
if(!RollingUpgradeUtil.filterOwnership(owningInstanceName, correctBuddyReplicaName, nextState, servletTimerIdsSet)) {
//we remove this entry if it is not on the correct replica partner - i.e. it is a zombie
replicasToRemove.add(nextState.getId());
}
}
for(int i=0; i<replicasToRemove.size(); i++) {
String nextId = (String)replicasToRemove.get(i);
if(nextId != null) {
removeFromServletTimerReplicationCache(nextId);
}
}
servletTimerIds.addAll(servletTimerIdsSet);
return servletTimerIds;
}
/**
* process the broadcastfindservlettimerids for ServletTimer
* @param queryState
*/
public ReplicationState processBroadcastfindservlettimerids(ReplicationState queryState) {
//complete query and send back response
String instanceName = getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindservlettimerids:instance: " + instanceName);
_logger.fine("in " + this.getClass().getName() + ">>processBroadcastfindservlettimerids:owningInstance=" + queryState.getInstanceName());
}
String owningInstanceName = queryState.getInstanceName();
List servletTimerIds = null;
if(this.isThirdPartyBackingStoreInUse()) {
servletTimerIds
= getServletTimerIdsThirdPartySPI(owningInstanceName);
} else {
servletTimerIds
= getServletTimerIds(owningInstanceName);
}
byte[] resultState = null;
try {
resultState = ReplicationUtil.getByteArray((ArrayList)servletTimerIds);
} catch (IOException ex) {
//deliberate no-op
;
}
//first check for none found in either active or replica caches
if(servletTimerIds == null || servletTimerIds.isEmpty()) {
//return nack
return ReplicationState.createQueryResponseFrom(queryState, true);
} else {
return ReplicationState.createQueryResponseFrom(queryState, resultState);
}
}
List<FederatedQueryListElement> getServletTimerIdsThirdPartySPI(String owningInstanceName) {
BackingStore backingStore
= this.getServletTimerBackingStore();
ServletTimerExtraParams stExtraParamCriteria
= ServletTimerExtraParams.createSearchCriteria(this, owningInstanceName);
Collection<ServletTimerExtraParams> stColl
= backingStore.findByCriteria(null, stExtraParamCriteria);
List<FederatedQueryListElement> servletTimerIds = new ArrayList();
//using set to avoid dups
HashSet servletTimerIdsSet = new HashSet();
Iterator<ServletTimerExtraParams> stResults =
(Iterator<ServletTimerExtraParams>) stColl.iterator();
while (stResults.hasNext()) {
ServletTimerExtraParams eParam = stResults.next();
if (owningInstanceName.equals(eParam.getCurrentOwnerInstanceName())) {
servletTimerIdsSet.add(new FederatedQueryListElement((String)eParam.getId(), -1L, getInstanceName()));
}
}
servletTimerIds.addAll(servletTimerIdsSet);
return servletTimerIds;
}
/**
* send a rolling upgrade advisory message to instance to trigger
* it to do rolling upgrade reconciliation for the sending
* instance
*
* @param waitTime the waitTime
* @param instanceName the instance to be sent the rolling upgrade advisory
*/
public void sendRollingUpgradeAdvisory(long waitTime, String instanceName) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager",
"sendRollingUpgradeAdvisory",
new Object[] {instanceName});
}
try {
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, MESSAGE_BROADCAST_ROLLING_UPGRADE_ADVISORY, instanceName, waitTime);
} catch (IOException ex) {}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager",
"sendRollingUpgradeAdvisory");
}
}
/**
* broadcast a rolling upgrade advisory message to trigger
* rolling upgrade reconciliation for the sending
* instance
*/
protected void sendRollingUpgradeAdvisory(long waitTime) {
//broadcast rolling upgrade advisory
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, MESSAGE_BROADCAST_ROLLING_UPGRADE_ADVISORY, waitTime);
}
/**
* send a rolling upgrade advisory message to instance to trigger
* it to do rolling upgrade active cache restoration for the sending
* instance
*
* @param instanceName the instance to be sent the rolling upgrade advisory
* @param command the command
*/
public void sendRollingUpgradeActiveCacheRestorationAdvisory(String command, String instanceName) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager",
"sendRollingUpgradeActiveCacheRestorationAdvisory",
new Object[] {instanceName});
}
try {
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, command, instanceName);
} catch (IOException ex) {}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager",
"sendRollingUpgradeActiveCacheRestorationAdvisory");
}
}
/**
* broadcast a rolling upgrade active cache restoration advisory message to trigger
* rolling upgrade replica cache restoration for the sending
* instance
* @param command the command
*/
protected void sendRollingUpgradeReplicaCacheRestorationAdvisory(String command) {
//broadcast rolling upgrade active cache restoration advisory
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, command);
}
/**
* send a rolling upgrade advisory message to instance to trigger
* it to do rolling upgrade replica cache restoration for the sending
* instance
*
* @param instanceName the instance to be sent the rolling upgrade advisory
* @param command the command
*/
public void sendRollingUpgradeReplicaCacheRestorationAdvisory(String command, String instanceName) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager",
"sendRollingUpgradeReplicaCacheRestorationAdvisory",
new Object[] {instanceName});
}
try {
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, command, instanceName);
} catch (IOException ex) {}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager",
"sendRollingUpgradeReplicaCacheRestorationAdvisory");
}
}
/**
* broadcast a rolling upgrade active cache restoration advisory message to trigger
* rolling upgrade active cache restoration for the sending
* instance
* @param command the command
*/
protected void sendRollingUpgradeActiveCacheRestorationAdvisory(String command) {
//broadcast rolling upgrade active cache restoration advisory
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, command);
}
/**
* send a rolling upgrade reconciliation complete advisory message to instance to signal
* to the original caller instance that replica reconciliation is complete
*
* @param instanceName the instance to be sent the rolling upgrade reconciliation complete advisory
*/
public void sendRollingUpgradeReplicaReconciliationCompleteAdvisory(String instanceName) {
if(_logger.isLoggable(Level.FINE)) {
_logger.entering("SipTransactionPersistentManager",
"sendRollingUpgradeReplicaReconciliationCompleteAdvisory",
new Object[] {instanceName});
}
try {
RollingUpgradeUtil.sendRollingUpgradeAdvisory((ReplicationManager)this, MODE_SIP, MESSAGE_BROADCAST_ROLLING_UPGRADE_REPLICA_RECONCILIATION_COMPLETE_ADVISORY, instanceName);
} catch (IOException ex) {}
if(_logger.isLoggable(Level.FINE)) {
_logger.exiting("SipTransactionPersistentManager",
"sendRollingUpgradeReplicaReconciliationCompleteAdvisory");
}
}
public void processRollingupgradeadvisory(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradeadvisory received from " + instanceName);
}
long waitTime = ((Long)replicationState.getProperty(ReplicationState.WAIT_TIME)).longValue();
//we have been triggered to do replica
//cache reconciliation for our replicateTo partner
doReplicaCacheReconciliation(waitTime, null); // TODO :: check last param, this whole method is unused -- remove it later.
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradeadvisory sending reconciliation completed advisory to: " + instanceName);
}
sendRollingUpgradeReplicaReconciliationCompleteAdvisory(instanceName);
}
public void processRollingupgradesipapplicationsessionactivecacherestorationadvisory(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradesipapplicationsessionactivecacherestorationadvisory received from " + instanceName);
}
List<ReplicationState> ownedReplicas = getSipApplicationSessionReplicas(instanceName);
sendReplicationStateList(ownedReplicas, instanceName, MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_ACTIVE_CACHE_RESTORATION_RESPONSE);
}
public void processRollingupgradesipapplicationsessionactivecacherestorationresponse(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradesipapplicationsessionactivecacherestorationresponse received from " + instanceName);
}
ownedReplicaListsReceivedForSipApplicationSessionActiveCacheRestoration.putIfAbsent(replicationState.getInstanceName(), replicationState);
restoreSipApplicationSessionActiveCacheDoneSignal.countDown();
}
public void processRollingupgradesipapplicationsessionreplicacacherestorationadvisory(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradesipapplicationsessionreplicacacherestorationadvisory received from " + instanceName);
}
List<ReplicationState> ownedReplicas = getActiveSipApplicationSessionsToReplicateTo(instanceName);
sendReplicationStateList(ownedReplicas, instanceName, MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_APPLICATION_SESSION_REPLICA_CACHE_RESTORATION_RESPONSE);
}
public void processRollingupgradesipapplicationsessionreplicacacherestorationresponse(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradesipapplicationsessionreplicacacherestorationresponse received from " + instanceName);
}
ownedReplicaListsReceivedForSipApplicationSessionReplicaCacheRestoration.putIfAbsent(replicationState.getInstanceName(), replicationState);
restoreSipApplicationSessionReplicaCacheDoneSignal.countDown();
}
public void processRollingupgradesipsessionactivecacherestorationadvisory(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradesipsessionactivecacherestorationadvisory received from " + instanceName);
}
List<ReplicationState> ownedReplicas = getSipSessionReplicas(instanceName);
sendReplicationStateList(ownedReplicas, instanceName, MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_ACTIVE_CACHE_RESTORATION_RESPONSE);
}
public void processRollingupgradesipsessionactivecacherestorationresponse(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradesipsessionactivecacherestorationresponse received from " + instanceName);
}
ownedReplicaListsReceivedForSipSessionActiveCacheRestoration.putIfAbsent(replicationState.getInstanceName(), replicationState);
restoreSipSessionActiveCacheDoneSignal.countDown();
}
public void processRollingupgradesipsessionreplicacacherestorationadvisory(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradesipsessionreplicacacherestorationadvisory received from " + instanceName);
}
List<ReplicationState> ownedReplicas = getActiveSipSessionsToReplicateTo(instanceName);
sendReplicationStateList(ownedReplicas, instanceName, MESSAGE_BROADCAST_ROLLING_UPGRADE_SIP_SESSION_REPLICA_CACHE_RESTORATION_RESPONSE);
}
public void processRollingupgradesipsessionreplicacacherestorationresponse(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradesipsessionreplicacacherestorationresponse received from " + instanceName);
}
ownedReplicaListsReceivedForSipSessionReplicaCacheRestoration.putIfAbsent(replicationState.getInstanceName(), replicationState);
restoreSipSessionReplicaCacheDoneSignal.countDown();
}
public void processRollingupgradeservlettimeractivecacherestorationadvisory(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradeservlettimeractivecacherestorationadvisory received from " + instanceName);
}
List<ReplicationState> ownedReplicas = getServletTimerReplicas(instanceName);
sendReplicationStateList(ownedReplicas, instanceName, MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_ACTIVE_CACHE_RESTORATION_RESPONSE);
}
public void processRollingupgradeservlettimeractivecacherestorationresponse(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradeservlettimeractivecacherestorationresponse received from " + instanceName);
}
ownedReplicaListsReceivedForServletTimerActiveCacheRestoration.putIfAbsent(replicationState.getInstanceName(), replicationState);
restoreServletTimerActiveCacheDoneSignal.countDown();
}
public void processRollingupgradeservlettimerreplicacacherestorationadvisory(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradeservlettimerreplicacacherestorationadvisory received from " + instanceName);
}
List<ReplicationState> ownedReplicas = getActiveServletTimersToReplicateTo(instanceName);
sendReplicationStateList(ownedReplicas, instanceName, MESSAGE_BROADCAST_ROLLING_UPGRADE_SERVLET_TIMER_REPLICA_CACHE_RESTORATION_RESPONSE);
}
public void processRollingupgradeservlettimerreplicacacherestorationresponse(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
String instanceName = replicationState.getInstanceName();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradeservlettimerreplicacacherestorationresponse received from " + instanceName);
}
ownedReplicaListsReceivedForServletTimerReplicaCacheRestoration.putIfAbsent(replicationState.getInstanceName(), replicationState);
restoreServletTimerReplicaCacheDoneSignal.countDown();
}
public void processRollingupgradereplicareconciliationcompleteadvisory(ReplicationState replicationState) {
if(replicationState == null) {
return;
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("IN " + this.getClass().getName() + ">>processRollingupgradereplicareconciliationcompleteadvisory received from " + replicationState.getInstanceName());
}
reconcileReplicaCacheDoneSignal.countDown();
}
List<ReplicationState> getSipApplicationSessionReplicas(String owningInstanceName) {
List<ReplicationState> sessionIds = new ArrayList();
//using set to avoid dups
HashSet sessionIdsSet = new HashSet();
//iterate over sip application session replicas
BaseCache replicatedSipApplicationSessionsCache = getReplicatedSipApplicationSessions();
Iterator it = replicatedSipApplicationSessionsCache.values();
while(it.hasNext()) {
ReplicationState nextState
= (ReplicationState)it.next();
RollingUpgradeUtil.filterOwnershipOfReplicas(owningInstanceName, nextState, sessionIdsSet);
}
sessionIds.addAll(sessionIdsSet);
return sessionIds;
}
List<ReplicationState> getActiveSipApplicationSessionsToReplicateTo(String owningInstanceName) {
SipApplicationSessionStoreImpl store = this.getSingletonSipApplicationSessionStore();
List<ReplicationState> sessionIds = new ArrayList();
//using set to avoid dups
HashSet sessionIdsSet = new HashSet();
//iterate over active sessions
Iterator it = applicationSessions.values().iterator();
while(it.hasNext()) {
HASipApplicationSession nextSession = (HASipApplicationSession)it.next();
String beKey = nextSession.getBeKey();
if(RollingUpgradeUtil.shouldReplicateTo(beKey, owningInstanceName)) {
ReplicationState nextState = null;
try {
nextState = store.getTransmitState(nextSession);
} catch (IOException ex) {}
if(nextState != null) {
sessionIdsSet.add(nextState);
}
}
}
sessionIds.addAll(sessionIdsSet);
return sessionIds;
}
List<ReplicationState> getSipSessionReplicas(String owningInstanceName) {
List<ReplicationState> sessionIds = new ArrayList();
//using set to avoid dups
HashSet sessionIdsSet = new HashSet();
//iterate over sip session replicas
BaseCache replicatedSipSessionsCache = getReplicatedSipSessions();
Iterator it = replicatedSipSessionsCache.values();
while(it.hasNext()) {
ReplicationState nextState
= (ReplicationState)it.next();
RollingUpgradeUtil.filterOwnershipOfReplicas(owningInstanceName, nextState, sessionIdsSet);
}
sessionIds.addAll(sessionIdsSet);
return sessionIds;
}
List<ReplicationState> getActiveSipSessionsToReplicateTo(String owningInstanceName) {
SipSessionStoreImpl store = this.getSingletonSipSessionStore();
List<ReplicationState> sessionIds = new ArrayList();
//using set to avoid dups
HashSet sessionIdsSet = new HashSet();
//iterate over active sessions
Iterator it = sipSessions.values().iterator();
while(it.hasNext()) {
HASipSession nextSession = (HASipSession)it.next();
String beKey = null;
if(nextSession.getParentSASId() != null) {
beKey = SipApplicationSessionUtil.getSipApplicationKey(nextSession.getParentSASId());
}
if(RollingUpgradeUtil.shouldReplicateTo(beKey, owningInstanceName)) {
ReplicationState nextState = null;
try {
nextState = store.getTransmitState(nextSession);
} catch (IOException ex) {}
if(nextState != null) {
sessionIdsSet.add(nextState);
}
}
}
sessionIds.addAll(sessionIdsSet);
return sessionIds;
}
List<ReplicationState> getServletTimerReplicas(String owningInstanceName) {
List<ReplicationState> sessionIds = new ArrayList();
//using set to avoid dups
HashSet timerIdsSet = new HashSet();
//iterate over servlet timer replicas
BaseCache replicatedServletTimersCache = getReplicatedServletTimers();
Iterator it = replicatedServletTimersCache.values();
while(it.hasNext()) {
ReplicationState nextState
= (ReplicationState)it.next();
RollingUpgradeUtil.filterOwnershipOfReplicas(owningInstanceName, nextState, timerIdsSet);
}
sessionIds.addAll(timerIdsSet);
return sessionIds;
}
List<ReplicationState> getActiveServletTimersToReplicateTo(String owningInstanceName) {
ServletTimerStoreImpl store = this.getSingletonServletTimerStore();
List<ReplicationState> timerIds = new ArrayList();
//using set to avoid dups
HashSet timerIdsSet = new HashSet();
//iterate over active timers
Iterator it = servletTimers.values().iterator();
while(it.hasNext()) {
HAServletTimer nextTimer = (HAServletTimer)it.next();
String beKey = null;
if(nextTimer.getParentSASId() != null) {
beKey = SipApplicationSessionUtil.getSipApplicationKey(nextTimer.getParentSASId());
}
if(RollingUpgradeUtil.shouldReplicateTo(beKey, owningInstanceName)) {
ReplicationState nextState = null;
try {
nextState = store.getTransmitState(nextTimer);
} catch (IOException ex) {}
if(nextState != null) {
timerIdsSet.add(nextState);
}
}
}
timerIds.addAll(timerIdsSet);
return timerIds;
}
private void sendReplicationStateList(Collection<ReplicationState> ownedReplicas,
String instanceName, String command) {
byte[] ownedReplicasState = null;
try {
ownedReplicasState = ReplicationUtil.getByteArray((Serializable)ownedReplicas);
} catch (IOException ex) {}
//need a unique pseudo-id for this query
String appId = getApplicationId();
String id = appId + unique.getAndIncrement();
ReplicationState ownedReplicasListState = new ReplicationState(MODE_SIP,
id, appId, 0L, 0L, 0L, null, null, getInstanceName(),
command, ownedReplicasState, null, null);
if (ownedReplicas == null || ownedReplicas.isEmpty()) {
ownedReplicasListState.setNack(true);
}
JxtaSocketChannel channel = JxtaSocketChannel.getInstance();
channel.send(ownedReplicasListState, instanceName);
}
private void sendReplicasList(Collection ownedReplicas,
String instanceName, String command) {
byte[] ownedReplicasState = null;
try {
ownedReplicasState = ReplicationUtil.getByteArray((Serializable)ownedReplicas);
} catch (IOException ex) {}
//need a unique pseudo-id for this query
String appId = getApplicationId();
String id = appId + unique.getAndIncrement();
ReplicationState ownedReplicasListState = new ReplicationState(MODE_SIP,
id, appId, 0L, 0L, 0L, null, null, getInstanceName(),
command, ownedReplicasState, null, null);
if (ownedReplicas == null || ownedReplicas.isEmpty()) {
ownedReplicasListState.setNack(true);
}
JxtaSocketChannel channel = JxtaSocketChannel.getInstance();
channel.send(ownedReplicasListState, instanceName);
}
private class ReconcileActiveSipApplicationSession implements Runnable {
SipTransactionPersistentManager _mgr = null;
long _waitTime = -1L;
CountDownLatch _doneSignal = null;
RollingUpgradeContext _ctx = null;
public ReconcileActiveSipApplicationSession(SipTransactionPersistentManager mgr, long waitTime, CountDownLatch doneSignal, RollingUpgradeContext ctx) {
_mgr = mgr;
_waitTime = waitTime;
_doneSignal = doneSignal;
_ctx = ctx;
}
public void run() {
try {
_mgr.doSipApplicationSessionActiveCacheReconciliation(_waitTime, _ctx);
} catch (Exception ex) {
_logger.log(Level.WARNING, ex.getMessage(), ex);
} finally {
_doneSignal.countDown();
}
}
}
private class ReconcileActiveSipSession implements Runnable {
SipTransactionPersistentManager _mgr = null;
long _waitTime = -1L;
CountDownLatch _doneSignal = null;
RollingUpgradeContext _ctx = null;
public ReconcileActiveSipSession(SipTransactionPersistentManager mgr, long waitTime, CountDownLatch doneSignal, RollingUpgradeContext ctx) {
_mgr = mgr;
_waitTime = waitTime;
_doneSignal = doneSignal;
_ctx = ctx;
}
public void run() {
try {
_mgr.doSipSessionActiveCacheReconciliation(_waitTime, _ctx);
} catch (Exception ex) {
_logger.log(Level.WARNING, ex.getMessage(), ex);
} finally {
_doneSignal.countDown();
}
}
}
private class ReconcileActiveServletTimer implements Runnable {
SipTransactionPersistentManager _mgr = null;
long _waitTime = -1L;
CountDownLatch _doneSignal = null;
RollingUpgradeContext _ctx = null;
public ReconcileActiveServletTimer(SipTransactionPersistentManager mgr, long waitTime, CountDownLatch doneSignal, RollingUpgradeContext ctx) {
_mgr = mgr;
_waitTime = waitTime;
_doneSignal = doneSignal;
_ctx = ctx;
}
public void run() {
try {
_mgr.doServletTimerActiveCacheReconciliation(_waitTime, _ctx);
} catch (Exception ex) {
_logger.log(Level.WARNING, ex.getMessage(), ex);
} finally {
_doneSignal.countDown();
}
}
}
private class ReconcileReplicaSipApplicationSession implements Runnable {
SipTransactionPersistentManager _mgr = null;
long _waitTime = -1L;
CountDownLatch _doneSignal = null;
RollingUpgradeContext _ctx = null;
public ReconcileReplicaSipApplicationSession(SipTransactionPersistentManager mgr, long waitTime, CountDownLatch doneSignal, RollingUpgradeContext ctx) {
_mgr = mgr;
_waitTime = waitTime;
_doneSignal = doneSignal;
_ctx = ctx;
}
public void run() {
try {
_mgr.doSipApplicationSessionReplicaCacheReconciliation(_waitTime, _ctx);
} catch (Exception ex) {
_logger.log(Level.WARNING, ex.getMessage(), ex);
} finally {
_doneSignal.countDown();
}
}
}
private class ReconcileReplicaSipSession implements Runnable {
SipTransactionPersistentManager _mgr = null;
long _waitTime = -1L;
CountDownLatch _doneSignal = null;
RollingUpgradeContext _ctx = null;
public ReconcileReplicaSipSession(SipTransactionPersistentManager mgr, long waitTime, CountDownLatch doneSignal, RollingUpgradeContext ctx) {
_mgr = mgr;
_waitTime = waitTime;
_doneSignal = doneSignal;
_ctx = ctx;
}
public void run() {
try {
_mgr.doSipSessionReplicaCacheReconciliation(_waitTime, _ctx);
} catch (Exception ex) {
_logger.log(Level.WARNING, ex.getMessage(), ex);
} finally {
_doneSignal.countDown();
}
}
}
private class ReconcileReplicaServletTimer implements Runnable {
SipTransactionPersistentManager _mgr = null;
long _waitTime = -1L;
CountDownLatch _doneSignal = null;
RollingUpgradeContext _ctx = null;
public ReconcileReplicaServletTimer(SipTransactionPersistentManager mgr, long waitTime, CountDownLatch doneSignal, RollingUpgradeContext ctx) {
_mgr = mgr;
_waitTime = waitTime;
_doneSignal = doneSignal;
_ctx = ctx;
}
public void run() {
try {
_mgr.doServletTimerReplicaCacheReconciliation(_waitTime, _ctx);
} catch (Exception ex) {
_logger.log(Level.WARNING, ex.getMessage(), ex);
} finally {
_doneSignal.countDown();
}
}
}
// end rolling upgrade related code
private class PrivilegedStoreLoadSipApplicationSession
implements PrivilegedExceptionAction {
private String id;
private String version;
private SipApplicationSessionStoreImpl store;
PrivilegedStoreLoadSipApplicationSession(String id, String version, SipApplicationSessionStoreImpl store) {
this.id = id;
this.version = version;
this.store = store;
}
public Object run() throws Exception{
return store.load(id, version);
}
}
private class PrivilegedStoreLoadSipSession
implements PrivilegedExceptionAction {
private String id;
private String version;
private boolean loadDependencies;
private SipSessionStoreImpl store;
PrivilegedStoreLoadSipSession(String id, String version,
boolean loadDependencies,
SipSessionStoreImpl store) {
this.id = id;
this.version = version;
this.loadDependencies = loadDependencies;
this.store = store;
}
public Object run() throws Exception{
return store.load(id, version, loadDependencies);
}
}
private class PrivilegedStoreLoadServletTimer
implements PrivilegedExceptionAction {
private String id;
private String version;
private boolean loadDependencies;
private ServletTimerStoreImpl store;
PrivilegedStoreLoadServletTimer(String id, String version,
boolean loadDependencies,
ServletTimerStoreImpl store) {
this.id = id;
this.version = version;
this.loadDependencies = loadDependencies;
this.store = store;
}
public Object run() throws Exception{
return store.load(id, version, loadDependencies);
}
}
}
//