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

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

/*
* 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.ObjectInput;
import java.io.ObjectOutput;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;

import javax.servlet.sip.Address;
import javax.servlet.sip.URI;
import javax.servlet.sip.ar.SipApplicationRoutingRegion;

import org.jvnet.glassfish.comms.replication.dialogmgmt.HADialogFragment;
import org.jvnet.glassfish.comms.util.LogUtil;

import com.ericsson.ssa.sip.DialogFragment;
import com.ericsson.ssa.sip.DialogSet;
import com.ericsson.ssa.sip.PersistentSipSessionManagerBase;
import com.ericsson.ssa.sip.RemoteLockException;
import com.ericsson.ssa.sip.SipApplicationSessionImpl;
import com.ericsson.ssa.sip.SipSessionDialogImpl;
import com.ericsson.ssa.sip.SipSessionManager;
import com.ericsson.ssa.sip.SipSessionManagerBase;
import com.ericsson.ssa.sip.SipApplicationSessionUtil;
import com.ericsson.ssa.sip.PathNode.Type;
import com.ericsson.ssa.sip.persistence.ReplicationUnitOfWork;
import com.sun.appserv.ha.uow.ReplicableEntity;
import com.sun.enterprise.ee.web.sessmgmt.ReplicationState;
import com.sun.enterprise.ee.web.sessmgmt.ReplicationUtil;


public class HASipSession extends SipSessionDialogImpl
    implements ReplicableEntity {

    private static final long serialVersionUID = 1L;
   
    /** The serialized format versioning. 1 = first version. */
    private static final short serializedFormVersion  = 1;

    private transient boolean isDirty = false;

    // The version of this SipSession
    private transient AtomicLong version = new AtomicLong(-1);
    private transient SipSessionExtraParams extraParams;
    private transient String previousOwnerInstanceName;
    private transient String currentOwnerInstanceName;
    private transient AtomicBoolean isSuspect
        = new AtomicBoolean(false);   
    private transient boolean wasLockedOnRemoteInstance = false;
    private transient boolean isBeingReplicated = false;
    protected transient boolean isReplicated = false;
    private transient long internalLastAccessedTime;
   
    /**
     * Constructor.
     */
    public HASipSession(SipSessionManagerBase manager, DialogSet set,
            Address to, SipApplicationSessionImpl appSession, String handler,
            Type type) {
        super(manager, set, to, appSession, handler, type);
    }

    public HASipSession() { // default constructor for externalization.
    }
   
    protected void init(SipSessionManagerBase manager,
            Address to, SipApplicationSessionImpl appSession, String handler,
            Type type) {
        super.init(manager, to, appSession, handler, type);
        version = new AtomicLong(-1);
        extraParams = new SipSessionExtraParams(this);
        currentOwnerInstanceName = ReplicationUtil.getInstanceName();
    }

    /**
     * Gets the parent SAS id
     *
     * @return The id of the parent SipApplicationSession
     */
    public String getParentSASId() {
        return sasId;
    }

    public String getBeKey() {
        return SipApplicationSessionUtil.getSipApplicationKey(getParentSASId());
    }
   
    /**
     * Gets the name of the instance.that previously owned this SipSession.
     *
     * @return The name of the instance that previously owned this SipSession
     */
    public String getPreviousOwnerInstanceName() {
        return previousOwnerInstanceName;
    }

    /**
     * Gets the name of the instance.that currently owns this SipSession.
     *
     * @return The name of the instance that currently owns this SipSession
     */
    public String getCurrentOwnerInstanceName() {
        return currentOwnerInstanceName;
    }
   
    /**
     * Gets whether this session is suspect (not trusted value)
     *
     * @return whether this session is suspect (not trusted value)
     */
    public boolean isSuspect() {
        return isSuspect.get();
    }
   
    /**
     * Sets whether this session is suspect (not trusted value)
     *
     * @param value whether this session is suspect (not trusted value)
     */
    public void setSuspect(boolean value) {
        isSuspect.set(value);
        if(!value) {
            ((SipTransactionPersistentManager)getSipSessionManager()).
                    removeSipSessionExpatListElement(getId());
        }
    }    

    /**
     * Checks whether this session is dirty or not.
     *
     * @return true if this session has been marked as dirty, false otherwise
     */
    public boolean isDirty() {
        return isDirty;
    }

    /**
     * Marks this session as dirty or non-dirty.
     *
     * @param isDirty The dirty flag
     */
    public void setDirty(boolean isDirty) {
        setDirty(isDirty, true);
    }
   
    /**
     * Marks this session as dirty or non-dirty.
     *
     * @param isDirty The dirty flag
     * @param addToUnitOfWork should we add to unit of work
     */
    public void setDirty(boolean isDirty, boolean addToUnitOfWork) {
        this.isDirty = isDirty;

        if (isDirty == true && addToUnitOfWork) {
            addToUnitOfWork();
        }
    } 
   
    /**
     * Increments the version of this SipSession.
     */
    public void incrementVersion() {
        version.incrementAndGet();
    }

    /**
     * Gets the version of this SipSession.
     *
     * @return The version of this SipSession
     */
    public long getVersion() {
        return version.get();
    }

    /**
     * Sets the version of this SipSession.
     *
     * @value The new version of this SipSession
     */
    public void setVersion(long value) {
        version.getAndSet(value);
    }

    /**
     * is the SipSession persistent
     */
    public boolean isReplicated() {
        return isReplicated;
    }

    /**
     * this sets the persistent flag
     */
    public void setReplicated(boolean value) {
        isReplicated = value;
    }

    public SipSessionExtraParams getExtraParameters() {
        return extraParams;
    }

    /**
     * Updates this SipSession with the given extra
     * parameters.
     *
     * @param extraParams The serialized SipSessionExtraParams
     * @param deserializedExtraParams The deserialized SipSessionExtraParams
     * used to update this
     * SipSession
     */
    public void update(byte[] extraParamsState, SipSessionExtraParams deserializedExtraParams) {

        SipSessionExtraParams extraParams = null;      
       
        if(deserializedExtraParams != null) {
            extraParams = deserializedExtraParams;
        } else {
            if (extraParamsState != null) {
                try {
                    extraParams
                        = (SipSessionExtraParams) ReplicationState.getObjectValue(extraParamsState, ((SipTransactionPersistentManager)getSipSessionManager()).isReplicationCompressionEnabled());
                } catch (Exception ex) {
                    LogUtil.SSR_LOGGER.getLogger().log(Level.WARNING, "ss_extraparams_deserialization_error", toString());
                    LogUtil.SSR_LOGGER.getLogger().log(Level.WARNING, ex.getMessage(), ex);
                }                   
            }
        }
        if(extraParams != null) {
            setPFieldCSeq(extraParams.getCseq(), false);
            setPFieldExpirationTime(extraParams.getExpirationTime(), false);
            setPFieldCurrentAccessedTime(extraParams.getCurrentAccessedTime(),
                                         false);
            setPFieldLastAccessedTime(extraParams.getLastAccessedTime(),
                                      false);          
        }
    }

    @Override
    protected void setPFieldExpirationTime(long expTime) {
        setPFieldExpirationTime(expTime, true);
    }

    private void setPFieldExpirationTime(long expTime,
                                         boolean addToUnitOfWork) {
        super.setPFieldExpirationTime(expTime);
        if (addToUnitOfWork) {
            // Load the DF child and update the expiration time if shorter
            // There is a problem, though: If the application invokes
            // setExpires(100) and then setExpires(10), the SAS timer will be
            // reset to 10 minutes, but the DF expiration time will remain at
            // 100 minutes, since we just take the max of the the DF and the
            // SS, not of all the SSes.
            // Taking the max of all the SSes would be possible, but would
            // require (part) of all the other trees to be loaded as well.
            // We assume that this is a rare case and the worst that can
            // happen is that the DF only times out long after all the SSes
            // have timed out, which is no big deal.
            HADialogFragment df = (HADialogFragment) getDF();
            if (df != null) {
                df.setExpirationTime(this);
            }
            addToUnitOfWork();
        }
    }

    public long getInternalLastAccessedTime() {
        return internalLastAccessedTime;
    }

    public void setInternalLastAccessedTime(long value) {
        internalLastAccessedTime = value;
    }
   
    public long getCurrentAccessedTime() {
        return getPFieldCurrentAccessedTime();
    }

    /**
     * Passivates this SipSession.
     */
    public void passivate() {
        notifySessionWillPassivate();

        // Remove from active cache
        PersistentSipSessionManagerBase mgr = (PersistentSipSessionManagerBase)
            getSipSessionManager();
        if (mgr != null) {
            mgr.removeSipSessionFromCache(this);
        }
    }

    /**
     * Validates this SipSession to see if it or its parent SAS has been
     * locked on remote instance, in which case this SipSession will not
     * be activated.
     */
    void validate(boolean loadDependencies) throws RemoteLockException {
        if (wasLockedOnRemoteInstance()) {
            throw new RemoteLockException(this +
                " has been locked on remote instance");
        }

        if (loadDependencies) {
            SipSessionManager mgr = getSipSessionManager();
            if (mgr != null) {
                // The following may throw RemoteLockException
                sipApplicationSession = mgr.findSipApplicationSession(sasId);
            }
        }
    }

    boolean wasLockedOnRemoteInstance() {
        return wasLockedOnRemoteInstance;
    }

    /**
     * @serialData See serialized form version 1 in #readExternal(ObjectInput in)
     * 
     * @param oos the stream to write the object members
     * @throws IOException
     */
    public void writeExternal(ObjectOutput oos) throws IOException {
        oos.writeShort(serializedFormVersion);
        super.writeExternal(oos);
        oos.writeObject(currentOwnerInstanceName);
        oos.writeLong(internalLastAccessedTime);
        // When doing normal replication, never mark the artifact as
        // foreground-locked. Foreground lock needs to be considered and
        // reflected in serialized representation only if artifact is being
        // served from active cache.
        if (isBeingReplicated) {
            oos.writeBoolean(false);
        } else {
            oos.writeBoolean(isForegroundLocked());
        }
    }

    /**
     * @serialData first field is an short and represents the serializedFormVersion.<br>
     * <h3>Data layout for serializedFormVersion = 1 follows</h3>
     *
     * <li>field is a <b>Externalizable</b> and represents superclass externalized data</li>
     * <li>field is a <b>String</b> and represents the name of the owner instance when this instance was serialized</li>
     * <li>field is a <b>Long</b> and represents the internal last accessed according to SIP standard</li>
     * <li>field is a <b>Boolean</b> and represents if the object is foreground locked</li>
    
     * @param in the stream to read the object members
     * @throws IOException is thrown when unsupported version is detected
     * @throws ClassNotFoundException
     */   
    public void readExternal(ObjectInput in)
        throws IOException, ClassNotFoundException {
        short readSerializedFormVersion = in.readShort();
        switch(readSerializedFormVersion) {
        case 1:
            super.readExternal(in);
            // Assumption is that version will be set from ReplicationUnit
            // immediately following deserialization
            version = new AtomicLong(-1);
            previousOwnerInstanceName = (String) in.readObject();
            currentOwnerInstanceName = ReplicationUtil.getInstanceName();
            internalLastAccessedTime = in.readLong();
            wasLockedOnRemoteInstance = in.readBoolean();
            extraParams = new SipSessionExtraParams(this);
            isSuspect = new AtomicBoolean(false);
            break;
        default:
            throw new IOException("Unable to deserialize into "
                    + this.getClass().getName()
                    + " with serialVersionUID = " + serialVersionUID
                    + " due to unknown serializedFormVersion of "
                    + readSerializedFormVersion);
        }
    }

    public String toString() {
        return super.toString() + ":version:" + getVersion();
    }

    /**
     * Sets the attribute with the given name to the given value and updates
     * the dirty flag to true
     *
     * @param name The attribute name to set
     * @param value The attribute value to set
     */
    @Override
    protected void addToPFieldSessionAttribute(String name, Object value) {
        super.addToPFieldSessionAttribute(name, value);
        setDirty(true);
    }

    /**
     * Removes the attribute with the given name and updates the dirty flag
     * to true
     *
     * @param name The name of the attribute to remove
     */
    @Override
    protected void removeFromPFieldSessionAttribute(String name) {
        super.removeFromPFieldSessionAttribute(name);
        setDirty(true);
    }

    @Override
    protected int incrementAndGetPFieldCSeq() {
        int returnValue = super.incrementAndGetPFieldCSeq();
        addToUnitOfWork();
        return returnValue;
    }

    @Override
    protected void setPField1xxReliableOngoing(boolean is1xxReliableOngoing) {
        super.setPField1xxReliableOngoing(is1xxReliableOngoing);
        setDirty(true);
    }

    @Override
    protected void setPField1xxReliableSDP(boolean is1xxReliableSDP) {
        super.setPField1xxReliableSDP(is1xxReliableSDP);
        setDirty(true);
    }

    @Override
    protected void setPFieldCSeq(int cseq) {
        setPFieldCSeq(cseq, true);
    }

    private void setPFieldCSeq(int cseq, boolean addToUnitOfWork) {
        super.setPFieldCSeq(cseq);
        if (addToUnitOfWork) {
            // we must not set the dirty flag
            // since this is an extraParam field
            addToUnitOfWork();
        }
    }

    @Override
    protected void setPFieldDerived(boolean isDerived) {
        super.setPFieldDerived(isDerived);
        setDirty(true);
    }

    @Override
    protected void setPFieldDialogFragmentId(String dialogFragmentId) {
        super.setPFieldDialogFragmentId(dialogFragmentId);
        setDirty(true);
    }

    @Override
    protected void setPFieldHandler(String handler) {
        super.setPFieldHandler(handler);
        setDirty(true);
    }

    @Override
    protected void setPFieldCurrentAccessedTime(long currentAccessedTime) {
        setPFieldCurrentAccessedTime(currentAccessedTime, true);
    }

    private void setPFieldCurrentAccessedTime(long currentAccessedTime,
                                              boolean addToUnitOfWork) {
        super.setPFieldCurrentAccessedTime(currentAccessedTime);
        if (addToUnitOfWork) {
            // we must not set the dirty flag
            // since this is an extraParam field
            addToUnitOfWork();
        }
    }

    @Override
    protected void setPFieldLastAccessedTime(long lastAccessedTime) {
        setPFieldLastAccessedTime(lastAccessedTime, true);
    }

    private void setPFieldLastAccessedTime(long lastAccessedTime,
                                           boolean addToUnitOfWork) {
        super.setPFieldLastAccessedTime(lastAccessedTime);
        if (addToUnitOfWork) { 
            // we must not set the dirty flag
            // since this is an extraParam field
            addToUnitOfWork();
        }
    }

    @Override
    protected void setPFieldLinkedSipSessionId(String linkedSipSessionId) {
        super.setPFieldLinkedSipSessionId(linkedSipSessionId);
        setDirty(true);
    }

    @Override
    protected void setPFieldRemoteTarget(URI remoteContact) {
        super.setPFieldRemoteTarget(remoteContact);
        setDirty(true);
    }

    @Override
    protected void setPFieldRoutingRegion(SipApplicationRoutingRegion routingRegion) {
        super.setPFieldRoutingRegion(routingRegion);
        setDirty(true);
    }

    @Override
    protected void setPFieldSessionState(State state) {
        super.setPFieldSessionState(state);
        setDirty(true);
    }

    @Override
    protected synchronized void setPFieldSipApplicationSession(
        SipApplicationSessionImpl sipApplicationSession) {
        super.setPFieldSipApplicationSession(sipApplicationSession);

        //setDirty(true); NOTE. sas ref is not changed during its lifetime
        // only during invalidation
        // TODO reconsider this if sas ref is changed to an id
    }

    @Override
    protected void setPFieldSubscriberURI(URI subscriberURI) {
        super.setPFieldSubscriberURI(subscriberURI);
        setDirty(true);
    }

    @Override
    protected void setPFieldSwapLocalRemote(boolean swapLocalRemote) {
        super.setPFieldSwapLocalRemote(swapLocalRemote);
        setDirty(true);
    }

    @Override
    protected void setPFieldTo(Address to) {
        super.setPFieldTo(to);
        setDirty(true);
    }

    @Override
    protected void setPFieldType(Type type) {
        super.setPFieldType(type);
        setDirty(true);
    }

    @Override
    protected void setPFieldUpdateOngoing(boolean updateOngoing) {
        super.setPFieldUpdateOngoing(updateOngoing);
        setDirty(true);
    }

    @Override
    public void setShouldBePersisted() {
        super.setShouldBePersisted();
        addToUnitOfWork();
    }

    /**
     * checks/adds this entity to unitOfWork
     */
    protected void addToUnitOfWork() {
        if (shouldBePersisted()) {
            ReplicationUnitOfWork uow =
                ReplicationUnitOfWork.getThreadLocalUnitOfWork();
            if(uow != null) {
                uow.add(this);
            } else {
                throw new IllegalStateException("HASipSession>>addToUnitOfWork: unit of work missing");
            }
        }
    }

    public void save() {
      if (!isValid()) return;
     
        PersistentSipSessionManagerBase sessionManager = (PersistentSipSessionManagerBase) getSipSessionManager();

        synchronized (getSipSessionObjectLock()) {
            try {
                sessionManager.saveSipSession(this);

                if (LogUtil.SSR_LOGGER.getLogger().isLoggable(Level.FINE)) {
                    LogUtil.SSR_LOGGER.getLogger().log(Level.FINE,
                                              "Saved " + toString());
                }
            } catch (IOException e) {
                LogUtil.SSR_LOGGER.getLogger().log(Level.WARNING, "ss_save_error", toString());
                LogUtil.SSR_LOGGER.getLogger().log(Level.WARNING, e.getMessage(), e);
            }
        }
    }

    @Override
    public void invalidate(boolean hasTimedOut) {
        super.invalidate(hasTimedOut);

        // remove from unit-of-work due its already gone from SessionManager
        if (shouldBePersisted()) {
            ReplicationUnitOfWork uow =
                ReplicationUnitOfWork.getThreadLocalUnitOfWork();
            if (uow != null) {
                uow.remove(this);
            }
        }        
    }

    void setIsBeingReplicated(boolean isBeingReplicated) {
        this.isBeingReplicated = isBeingReplicated;
    }

    boolean isBeingReplicated() {
        return isBeingReplicated;
    }
   
    @Override
    public SipApplicationSessionImpl getApplicationSessionLocally() {
        return ((PersistentSipSessionManagerBase)sipSessionManager).findSipApplicationSessionFromCacheOnly(sasId);
    }

    @Override
    protected String getIdForSerial() {
        return "";
    }

    void setId(String newId) {
        this.id = newId;
    }

    @Override
    protected SipApplicationSessionImpl getPFieldSipApplicationSession() {
        Object monitor = ((SipTransactionPersistentManager) sipSessionManager).getReplicationSessionMonitor(sasId);
        synchronized (monitor) {
            return super.getPFieldSipApplicationSession();
        }
    }

}
TOP

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

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.