Package org.jvnet.glassfish.comms.replication.sessmgmt

Source Code of org.jvnet.glassfish.comms.replication.sessmgmt.SipApplicationSessionStoreImpl

/*
* 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);
        }
    }

}
TOP

Related Classes of org.jvnet.glassfish.comms.replication.sessmgmt.SipApplicationSessionStoreImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.