/*
* 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 org.apache.catalina.*;
import com.ericsson.ssa.sip.RemoteLockException;
import com.ericsson.ssa.sip.SipApplicationSessionImpl;
import com.ericsson.ssa.sip.SipApplicationSessionStore;
import com.ericsson.ssa.sip.SipApplicationSessionUtil;
import com.ericsson.ssa.sip.SipSessionManager;
import com.sun.appserv.ha.spi.BackingStore;
import com.sun.appserv.ha.spi.BackingStoreException;
import com.sun.appserv.ha.util.SimpleMetadata;
import com.sun.appserv.ha.util.SimpleMetadataFactory;
import com.sun.appserv.ha.uow.ReplicableEntity;
import com.sun.appserv.util.cache.BaseCache;
import com.sun.enterprise.web.ServerConfigLookup;
import com.sun.enterprise.ee.web.sessmgmt.ExpatListElement;
import com.sun.enterprise.ee.web.sessmgmt.JxtaBackingStoreImpl;
import com.sun.enterprise.ee.web.sessmgmt.JxtaReplicationSender;
import com.sun.enterprise.ee.web.sessmgmt.ReplicationUtil;
import com.sun.enterprise.ee.web.sessmgmt.ReplicationState;
import com.sun.enterprise.ee.web.sessmgmt.StorePoolElement;
import com.sun.enterprise.ee.web.sessmgmt.SessionStoreInterface;
import java.io.*;
import java.util.logging.Level;
import java.util.zip.GZIPInputStream;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.Map;
import java.util.HashSet;
import org.apache.catalina.session.IOUtilsCaller;
/**
*
* @author Larry White
*/
public class SipApplicationSessionStoreImpl extends SipStoreBase
implements StorePoolElement, SipApplicationSessionStore, SessionStoreInterface {
protected static final String MODE_SIP = ReplicationState.MODE_SIP;
private static boolean useReplicationUnicastLoadBatching = false;
static {
ServerConfigLookup lookup = new ServerConfigLookup();
useReplicationUnicastLoadBatching
= lookup.isReplicationUnicastLoadBatchingEnabled();
}
/** Creates a new instance of SipApplicationSessionStoreImpl */
public SipApplicationSessionStoreImpl() {
}
/**
* gets the BackingStore used for replicating SipApplicationSessions
*
* @return the BackingStore initialized for SipApplicationSessions
*
*/
protected BackingStore getBackingStore() {
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager)this.getSipSessionManager();
return mgr.getSipApplicationSessionBackingStore();
}
/**
* Loads and returns the SipApplicationSession with the given id from
* this store.
*
* @param id The id of the SipApplicationSession to load
*
* @return The SipApplicationSession with the given id, or null if not
* found
*
* @throws IOException
* @throws RemoteLockException
*/
public SipApplicationSessionImpl load(String id)
throws IOException, RemoteLockException {
return load(id, null);
}
/**
* Loads and returns the SipApplicationSession with the given id from
* this store.
*
* @param id The id of the SipApplicationSession to load
* @param version The version of the SipApplicationSession to load
*
* @return The SipApplicationSession with the given id, or null if not
* found
*
* @throws IOException
* @throws RemoteLockException
*/
public SipApplicationSessionImpl load(String id, String version)
throws IOException , RemoteLockException {
if (SipReplicationUtil.isInstanceLoadBalancedByCLB() &&
!SipReplicationUtil.isLocal(id)) {
throw new RemoteLockException("load of SipApplicationSession id:" +
id + " aborted. Does not map to this instance");
}
if (id == null) {
throw new IOException("load of SipApplicationSession failed. The id is null.");
}
try {
ExpatListElement expat = this.getExpatListElementFor(id);
if (expat != null && expat.isFromActive()) {
/**
* Irrespective of the backing store implementation, if the session
* is activated in the remote instance, then we should load it from there.
*/
return loadFromRemoteActiveCache(id, expat);
} else {
return loadFromBackingStore(id, version);
}
} catch(BackingStoreException ex) {
IOException ex1 =
(IOException) new IOException("Error during load: " + ex.getMessage()).initCause(ex);
throw ex1;
}
}
/**
* This will use the Jxta channel to load the session from remote instance's
* active cache.
*/
private HASipApplicationSession loadFromRemoteActiveCache(String id,
ExpatListElement expat)
throws IOException, BackingStoreException, RemoteLockException {
/**
* For the in-memory implementation, the restarted instance might
* have the session in its replica cache, if the load-factor is used.
*/
BaseCache replicaCache = getReplicaCache();
if(replicaCache != null) {
replicaCache.remove(id);
}
ReplicationState sessionState = loadSessionFromRemoteActiveCache(
id, String.valueOf(expat.getVersion()), expat.getInstanceName());
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipApplicationSessionStoreImpl>>loadFromActiveCache:id="
+ id + ", sessionState=" + sessionState);
}
HASipApplicationSession session = getSipApplicationSession(sessionState);
validateAndSave(session);
return session;
}
private HASipApplicationSession loadFromBackingStore(String id, String version)
throws IOException, BackingStoreException, RemoteLockException {
SimpleMetadata metaData = (SimpleMetadata) getBackingStore().load(id, version);
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipApplicationSessionStoreImpl>>loadFromBackingStore:id=" +
id + ", metaData=" + metaData);
}
HASipApplicationSession session = getSipApplicationSession(metaData);
validateAndSave(session);
return session;
}
private void validateAndSave(HASipApplicationSession session)
throws IOException, RemoteLockException {
if (session != null) {
boolean isLoadedFromRemote =
__removeFromRemotelyLoadedSessionIds(session.getId());
if (session.isValid()) {
// For SipApplicationSession this sending of load received ack
// has been postponed to this point so we can check the
// deserialized session to see if it was locked on the remote
// side (this is done inside validate(), which may throw a
// RemoteLockedException).
// For most other artifacts the load received ack is done
// immediately in JxtaBackingStoreImpl
session.validate();
// no need to do immediate save if it is loaded from third party backing store.
if (isLoadedFromRemote) {
//save session - save will reset dirty to false
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("SipApplicationSessionStoreImpl>>validateAndSave saving " +
"the sip application session after loading it. SipApplicationSession=" + session);
}
session.setDirty(true, false);
/*
* In order to avoid a race condition, we're granting the
* replica additional time to live to give the container
* time to determine its ultimate fate: If the lifetime of
* the SAS is not going to be extended, it and its replica
* will be removed. Otherwise, its new expiration time will
* be wiggled along with that of its children.
*/
session.wiggleExpirationTime();
save(session);
}
}
}
}
/**
* This method will be called from JxtaBackingStoreImpl. So, it is specific
* only to in-memory replication store.
*/
SimpleMetadata __load(String id, String version)
throws BackingStoreException {
SimpleMetadata result = null;
SipTransactionPersistentManager repMgr
= (SipTransactionPersistentManager)this.getSipSessionManager();
ReplicationState localCachedState
= repMgr.removeFromSipApplicationSessionReplicationCache(id);
//check if we got a hit from our own replica cache
//and check if we can trust it. If so save and return it immediately
boolean trustCachedState = canTrustLocallyCachedState(id, version, localCachedState);
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipApplicationSessionStoreImpl>>__load:id= " + id + ", localCachedState=" +
localCachedState + ", trustCachedState=" + trustCachedState);
}
ReplicationState bestState = null;
if(trustCachedState) {
bestState = localCachedState;
} else {
ReplicationState broadcastResultState =
findSessionViaBroadcastOrUnicast(id, version);
bestState = ReplicationState.getBestResult(localCachedState, broadcastResultState);
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipApplicationSessionStoreImpl>>__load:id=" + id + ", broadcastResultState " +
"from broadcast or unicast=" + broadcastResultState + ", bestState = " + bestState);
}
}
if(bestState != null && bestState.getState() != null) {
__addToRemotelyLoadedSessionIds(id);
}
result = ReplicationState.createSimpleMetadataFrom(
bestState, isReplicationCompressionEnabled());
return result;
}
protected ExpatListElement getExpatListElementFor(String id) {
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager)getSipSessionManager();
if(mgr.isExpectingExpatIdsMap()) {
//in this period do not trust expatIdsMap
return null;
} else {
return mgr.getSipApplicationSessionExpatListElement(id);
}
}
protected ReplicationState findSessionViaBroadcastOrUnicast(String id, String version)
throws BackingStoreException {
//this is for the replication unit tests that run without CLB
if(!SipReplicationUtil.isInstanceLoadBalancedByCLB()) {
return findSessionViaBroadcast(id, version);
}
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager)this.getSipSessionManager();
if(mgr.isExpectingExpatIdsMap()) {
return findSessionViaBroadcast(id, version);
} else {
ExpatListElement expat = this.getExpatListElementFor(id);
if(expat == null) {
return null;
} else {
if(expat.getInstanceName() == null) {
return findSessionViaBroadcast(id, version);
} else {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("doing unicast load id = " + id
+ " version = " + version
+ "to instance: " + expat.getInstanceName());
}
return findSessionViaUnicast(id, version, expat.getInstanceName());
}
}
}
}
private ReplicationState findSessionViaBroadcast(String id, String version)
throws BackingStoreException {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipApplicationSessionStoreImpl>>findSessionViaBroadcast " +
"id = " + id + " version = " + version);
}
BackingStore replicator = this.getBackingStore();
JxtaBackingStoreImpl jxtaReplicator = null;
if(replicator instanceof JxtaBackingStoreImpl) {
jxtaReplicator = (JxtaBackingStoreImpl)replicator;
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipApplicationSessionStoreImpl>>" +
"findSessionViaBroadcast: jxtaReplicator: " + jxtaReplicator);
}
ReplicationState queryResult = jxtaReplicator != null ?
jxtaReplicator.__load(id, version) : null;
return queryResult;
}
private ReplicationState loadSessionFromRemoteActiveCache(String id,
String version,
String instanceName)
throws BackingStoreException {
ReplicationState returnState = findSessionViaUnicast(id, version, instanceName);
if (returnState != null && returnState.getState() != null) {
__addToRemotelyLoadedSessionIds(id);
}
return returnState;
}
private ReplicationState findSessionViaUnicast(String id, String version, String instanceName)
throws BackingStoreException {
if(ReplicationUtil.getInstanceName().equalsIgnoreCase(instanceName)) {
return null;
}
return sendUnicastLoadQuery(id, version, instanceName);
}
/**
* Given a byte[] containing session data, return a session
* object
* if isReplicationCompressionEnabled() returns true the
* input byte[] will be assumed compressed and treated
* accordingly
*
* @param replicationState
* The byte[] with the session data
*
* @return
* A newly created SipApplicationSession for the given session data, and associated
* with this Manager
*/
protected HASipApplicationSession getSipApplicationSession(ReplicationState replicationState)
throws IOException {
if (replicationState == null || replicationState.getState() == null) {
return null;
} else {
return getSipApplicationSession(replicationState.getState(),
replicationState.getVersion(),
replicationState.getContainerExtraParamsState(),
null);
}
}
protected HASipApplicationSession getSipApplicationSession(SimpleMetadata metadata)
throws IOException {
if (metadata == null || metadata.getState() == null) {
return null;
} else {
return getSipApplicationSession(metadata.getState(),
metadata.getVersion(),
null,
(SipApplicationSessionExtraParams) metadata.getExtraParam());
}
}
protected HASipApplicationSession getSipApplicationSession(byte[] state,
long version,
byte[] extraParamState,
SipApplicationSessionExtraParams extraParams)
throws IOException {
HASipApplicationSession _session = null;
InputStream is = null;
BufferedInputStream bis = null;
ByteArrayInputStream bais = null;
Loader loader = null;
ClassLoader classLoader = null;
ObjectInputStream ois = null;
SipSessionManager manager
= this.getSipSessionManager();
Container container = manager.getContext();
IOUtilsCaller utilsCaller = null;
bais = new ByteArrayInputStream(state);
bis = new BufferedInputStream(bais);
if(isReplicationCompressionEnabled()) {
is = new GZIPInputStream(bis);
} else {
is = bis;
}
if(_logger.isLoggable(Level.FINEST)) {
_logger.finest("loaded session from replicationstore, length = "+state.length);
}
if (container != null) {
loader = container.getLoader();
}
if (loader != null) {
classLoader = loader.getClassLoader();
}
if (classLoader != null) {
if( (utilsCaller = ReplicationUtil.getWebUtilsCaller()) != null) {
try {
ois = utilsCaller.createObjectInputStream(is, true, classLoader);
} catch (Exception ex) {}
}
}
if (ois == null) {
ois = new ObjectInputStream(is);
}
if(ois != null) {
try {
_session = (HASipApplicationSession)ois.readObject();
} catch (ClassNotFoundException ex) {
IOException ex1 = (IOException) new IOException(
"Error during deserialization: " + ex.getMessage()).initCause(ex);
throw ex1;
} finally {
if (ois != null) {
try {
ois.close();
bis = null;
}
catch (IOException e) {
}
}
}
}
_session.setSipSessionManager(manager);
_session.update(extraParamState, extraParams);
//currentOwnerInstanceName is in the manager already
_session.setInternalLastAccessedTime(System.currentTimeMillis());
if(version != Integer.MAX_VALUE) {
//if version == Integer.MAX_VALUE it is an active SAS so it's version
// is correct
_session.setVersion(version);
}
_session.setDirty(false);
_session.setReplicated(false);
return _session;
}
/**
* Saves the given SipApplicationSession to this store.
*
* If a SipApplicationSession with the same id already exists in this
* store, it will be replaced.
*
* @param sas The SipApplicationSession to be saved
*
* @exception IOException
*/
public void save(SipApplicationSessionImpl sas) throws IOException {
HASipApplicationSession haSas = (HASipApplicationSession)sas;
long previousVersion = haSas.getVersion();
haSas.incrementVersion();
haSas.setInternalLastAccessedTime(System.currentTimeMillis());
try {
if( haSas.isReplicated() && !haSas.isDirty() ) {
this.updateContainerExtraParam(haSas);
} else {
haSas.setIsBeingReplicated(true);
this.doSave(haSas);
haSas.setReplicated(true);
}
haSas.setDirty(false);
} catch (IOException ex) {
haSas.setVersion(previousVersion);
throw ex;
} finally {
haSas.setIsBeingReplicated(false);
}
}
boolean isReplicationCompressionEnabled() {
SipTransactionPersistentManager repMgr
= (SipTransactionPersistentManager)this.getSipSessionManager();
return repMgr.isReplicationCompressionEnabled();
}
/**
* Saves the given SipApplicationSession to this store.
*
* If a SipApplicationSession with the same id already exists in this
* store, it will be replaced.
*
* @param haSas The SipApplicationSession to be saved
*
* @exception IOException
*/
public void doSave(HASipApplicationSession haSas) throws IOException {
byte[] sessionState = ReplicationUtil.getByteArray(haSas, isReplicationCompressionEnabled());
BackingStore replicator = this.getBackingStore();
SimpleMetadata simpleMetadata =
SimpleMetadataFactory.createSimpleMetadata(
haSas.getVersion(),
haSas.getInternalLastAccessedTime(),
0L, //maxinactiveinterval
sessionState,
haSas.getExtraParameters() //containerExtraParam
);
simpleMetadata.setBeKey(haSas.getBeKey());
simpleMetadata.setOwningInstanceName(ReplicationUtil.getInstanceName());
try {
replicator.save(haSas.getId(), //id
simpleMetadata, haSas.isReplicated());
} catch (BackingStoreException ex) {
IOException ex1 =
(IOException) new IOException("Error during save: " + ex.getMessage()).initCause(ex);
throw ex1;
}
}
public ReplicationState getTransmitState(HASipApplicationSession haSas) throws IOException {
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager)this.getSipSessionManager();
BackingStore replicator = mgr.getSipApplicationSessionBackingStore();
if(!(replicator instanceof JxtaBackingStoreImpl)) {
return null;
}
JxtaBackingStoreImpl jxtaReplicator = (JxtaBackingStoreImpl)replicator;
ReplicationState transmitState = null;
byte[] sessionState = ReplicationUtil.getByteArray(haSas, isReplicationCompressionEnabled());
SimpleMetadata simpleMetadata =
SimpleMetadataFactory.createSimpleMetadata(
haSas.getVersion(),
haSas.getInternalLastAccessedTime(),
0L, //maxinactiveinterval
sessionState,
haSas.getExtraParameters() //containerExtraParam
);
simpleMetadata.setBeKey(haSas.getBeKey());
//need this here because save not called
simpleMetadata.setOwningInstanceName(ReplicationUtil.getInstanceName());
try {
transmitState = jxtaReplicator.getSimpleTransmitState(haSas.getId(), simpleMetadata);
} catch (BackingStoreException ex) {}
return transmitState;
}
/**
* Removes the SipApplicationSession with the given id from this store.
*
* @param id The id of the SipApplicationSession to be removed
*
* @exception IOException
*/
public void remove(String id) throws IOException {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipApplicationSessionStoreImpl>>remove" + " id: " + id);
}
BackingStore replicator = this.getBackingStore();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipApplicationSessionStoreImpl>>remove: replicator: " + replicator);
}
try {
replicator.remove(id);
} catch (BackingStoreException ex) {
IOException ex1 =
(IOException) new IOException("Error during remove: " + ex.getMessage()).initCause(ex);
throw ex1;
}
}
/**
* Removes the SipApplicationSession with the given id from this store.
*
* @param id The id of the SipApplicationSession to be removed
* @param originatingInstanceName the name of the originating instance
* @param count a counter to track the number of hops in this cycle
*
* @exception IOException
*/
public void remove(String id, String originatingInstanceName, int count) throws IOException {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipApplicationSessionStoreImpl>>remove" + " id: " + id + " originatingInstanceName: " + originatingInstanceName);
}
BackingStore replicator = this.getBackingStore();
if(!(replicator instanceof JxtaBackingStoreImpl)) {
return;
}
JxtaBackingStoreImpl jxtaReplicator
= (JxtaBackingStoreImpl)replicator;
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipApplicationSessionStoreImpl>>remove: jxtaReplicator: " + jxtaReplicator);
}
try {
jxtaReplicator.remove(id, originatingInstanceName, count);
} catch (BackingStoreException ex) {
IOException ex1 =
(IOException) new IOException("Error during remove: " + ex.getMessage()).initCause(ex);
throw ex1;
}
}
void sendLoadAdvisory(String id, String instanceName, HashSet<String> expiredIds) {
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager)getSipSessionManager();
String theCommand = mgr.MESSAGE_LOAD_ADVISORY_SAS;
ReplicationState loadAdvisoryState
= ReplicationState.createUnicastLoadAdvisoryState(MODE_SIP, id,
this.getApplicationId(), 0L, mgr.getInstanceName(), theCommand);
if(expiredIds != null && !expiredIds.isEmpty()) {
try {
byte[] bytes = ReplicationUtil.getByteArray(expiredIds);
loadAdvisoryState.setState(bytes);
} catch(IOException ex) {}
}
JxtaReplicationSender sender
= JxtaReplicationSender.createInstance();
//sender.sendOverPropagatedPipe(loadAdvisoryState, instanceName, false);
sender.sendReplicationAdvisoryState(loadAdvisoryState, instanceName);
}
void sendLoadAdvisory(String id, String instanceName)
throws IOException {
sendLoadAdvisory(id, instanceName, null);
}
void sendLoadAdvisories(String instanceName,
HashSet<String> expiredReplicaIds) {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("Sending bulk load-advisories for sas to " +
instanceName + ", number of ids = " + expiredReplicaIds.size());
}
String id = getSipSessionManager().getApplicationId() + System.currentTimeMillis();
sendLoadAdvisory(id, instanceName, expiredReplicaIds);
}
void sendUnicastLoadAcknowledgement(String id,
String instanceName,
String bekey,
HashSet<String> ids) {
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager) getSipSessionManager();
String theCommand = mgr.MESSAGE_BROADCAST_LOAD_RECEIVED_SAS;
ReplicationState loadReceivedState =
ReplicationState.createBroadcastLoadReceivedState(MODE_SIP, id,
this.getApplicationId(), 0L, mgr.getInstanceName(), theCommand);
if (bekey != null) {
String ignoreInstance =
SipApplicationSessionUtil.getFailoverServerInstanceForBeKey(bekey);
if (ignoreInstance != null) {
loadReceivedState.setProperty(ReplicationState.IGNORE_REMOVE_INSTANCE_NAME, ignoreInstance);
}
}
if (ids != null && !ids.isEmpty()) {
try {
byte[] bytes = ReplicationUtil.getByteArray(ids);
loadReceivedState.setState(bytes);
} catch (IOException ex) {
}
}
JxtaReplicationSender sender
= JxtaReplicationSender.createInstance();
sender.sendOverPropagatedPipe(loadReceivedState, instanceName, false);
}
void sendUnicastLoadAcknowledgement(String id, String instanceName, String bekey) {
sendUnicastLoadAcknowledgement(id, instanceName, bekey, null);
}
void sendLoadAcks(String instanceName, HashSet<String> ids) {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("Sending bulk load-acks for sas to " + instanceName +
", number of ids = " + ids.size());
}
String id = getSipSessionManager().getApplicationId() + System.currentTimeMillis();
sendUnicastLoadAcknowledgement(id, instanceName, null, ids);
}
public ReplicationState sendUnicastLoadQuery(String id, String version, String instanceName) {
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager)getSipSessionManager();
String theCommand = mgr.LOAD_SAS_COMMAND;
ReplicationState loadState
= ReplicationState.createUnicastLoadState(MODE_SIP, id, this.getApplicationId(), ReplicationUtil.parseLong(version), mgr.getInstanceName(), theCommand);
JxtaReplicationSender sender
= JxtaReplicationSender.createInstance();
ReplicationState returnState
= sender.sendReplicationLoadState(loadState, instanceName, useReplicationUnicastLoadBatching);
return returnState;
}
/**
* update the lastaccess time of the specified SipApplicationSession into this Store.
*
* @param sas SipApplicationSession to be saved
*
* @exception IOException if an input/output error occurs
*/
public void updateContainerExtraParam(HASipApplicationSession sas) throws IOException {
BackingStore replicator = this.getBackingStore();
JxtaBackingStoreImpl jxtaReplicator = null;
if(replicator instanceof JxtaBackingStoreImpl) {
jxtaReplicator = (JxtaBackingStoreImpl)replicator;
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("SipApplicationSessionStoreImpl>>updateContainerExtraParam: replicator: " + replicator);
}
try {
SimpleMetadata smd = SimpleMetadataFactory.createSimpleMetadata(sas.getInternalLastAccessedTime(), //internallastaccesstime
sas.getVersion(), //version
sas.getExtraParameters());
replicator.save(sas.getId(), smd, sas.isReplicated()); //containerExtraParams
} catch (BackingStoreException ex) {
IOException ex1 =
(IOException) new IOException("Error during updateContainerExtraParam: " + ex.getMessage()).initCause(ex);
throw ex1;
}
}
/**
* Removes all SipApplicationSessions from this store.
*/
public void clear() throws IOException {
//FIXME
}
/**
* clean up resources
*/
public void cleanup() {
//FIXME
}
/**
* Removes any expired SipApplicationSessions from this store.
*
* This method is invoked by the background reaper thread.
*/
public void processExpires() {
SipTransactionPersistentManager replicationMgr =
(SipTransactionPersistentManager) this.getSipSessionManager();
// if(!(replicationMgr.isThirdPartyBackingStoreInUse())) {
// replicationMgr.processExpiredSipApplicationSessionReplicas();
// } else {
// replicationMgr.processExpiredSipApplicationSessionReplicasThirdPartySPI();
// }
replicationMgr._processExpiredSipApplicationSessions();
}
// put the state in the local replica cache.
public void putInReplicaCache(ReplicationState state) {
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager)this.getSipSessionManager();
mgr.putInSipApplicationSessionReplicationCache(state);
}
public void removeFromReplicaCache(String id) {
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager)this.getSipSessionManager();
mgr.removeFromSipApplicationSessionReplicationCache(id);
}
// find the session in local active cache, passivate it and remove from local cache.
public ReplicableEntity findSessionAndPassivate(String id) {
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager)this.getSipSessionManager();
return mgr.findSasAndPassivate(id, new AtomicBoolean());
}
public Map<String,ReplicableEntity> getActiveCache() {
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager)this.getSipSessionManager();
return mgr.getActiveApplicationSessions();
}
public BaseCache getReplicaCache() {
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager)this.getSipSessionManager();
return mgr.getReplicatedSipApplicationSessions();
}
public ReplicableEntity deserialize(ReplicationState state) {
try {
return getSipApplicationSession(state);
} catch (IOException ex) {
return null;
}
}
public void activate(ReplicableEntity session) {
if(session instanceof HASipApplicationSession) {
SipTransactionPersistentManager mgr
= (SipTransactionPersistentManager)this.getSipSessionManager();
mgr.activate((HASipApplicationSession)session, true);
}
}
}