Package org.jscsi.initiator.connection

Source Code of org.jscsi.initiator.connection.Connection

/**
* Copyright (c) 2012, University of Konstanz, Distributed Systems Group All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or other materials provided with the
* distribution. * Neither the name of the University of Konstanz nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jscsi.initiator.connection;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.security.DigestException;
import java.util.Queue;

import org.jscsi.exception.InternetSCSIException;
import org.jscsi.exception.NoSuchSessionException;
import org.jscsi.exception.OperationalTextKeyException;
import org.jscsi.initiator.Configuration;
import org.jscsi.initiator.connection.state.IState;
import org.jscsi.parser.ProtocolDataUnit;
import org.jscsi.parser.datasegment.OperationalTextKey;
import org.jscsi.parser.datasegment.SettingsMap;
import org.jscsi.utils.SerialArithmeticNumber;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
* <h1>AbsConnection</h1>
* <p/>
* This abstract class represents a connection, which is used in the iSCSI Standard (RFC3720). Such a connection is
* directed from the initiator to the target. It is used in Sessions.
*
* @author Volker Wildi, University of Konstanz
* @author Patrice Matthias Brend'amour, University of Konstanz
* @author Sebastian Graf, University of Konstanz
*/
public final class Connection {

    // --------------------------------------------------------------------------
    // --------------------------------------------------------------------------

    /** The logger interface. */
    private static final Logger LOGGER = LoggerFactory.getLogger(Connection.class);

    // --------------------------------------------------------------------------
    // --------------------------------------------------------------------------

    /**
     * The <code>Session</code> instance, which contains this <code>Connection</code> instance.
     */
    private final Session referenceSession;

    /** The <code>Configuration</code> instance for this connection. */
    private final Configuration configuration;

    /** The current state of this connection. */
    private IState state;

    /**
     * The ID of this connection. This must be unique within a <code>Session</code>.
     */
    private final short connectionID;

    /**
     * The Expected Status Sequence Number, which is expected to received from the target within this connection.
     */
    private final SerialArithmeticNumber expectedStatusSequenceNumber;

    // --------------------------------------------------------------------------
    // --------------------------------------------------------------------------

    /**
     * The worker caller, which handles the transmission of the packages over the network.
     */
    private final SenderWorker senderReceiver;

    /**
     * Method to create and return a new, empty <code>Connection</code> object with the configured layer of threading.
     *
     * @param session Reference to the <code>AbsSession</code> object, which contains this connection.
     * @param initConfiguration The configuration to use within this connection.
     * @param inetAddress The <code>InetSocketAddress</code> to which this connection should established.
     * @param initConnectionID The ID of this connection.
     * @throws Exception If any error occurs.
     */

    public Connection (final Session session, final Configuration initConfiguration, final InetSocketAddress inetAddress, final short initConnectionID) throws Exception {

        senderReceiver = new SenderWorker(this, inetAddress);

        configuration = initConfiguration;
        connectionID = initConnectionID;

        referenceSession = session;
        expectedStatusSequenceNumber = new SerialArithmeticNumber();

    }

    /**
     * Updates all entries of the given response key-values with the stored settings of this instance.
     *
     * @param response The settings of the response.
     * @throws NoSuchSessionException if a session with this target name is not open.
     */
    public final void update (final SettingsMap response) throws NoSuchSessionException {

        configuration.update(referenceSession.getTargetName(), connectionID, response);
    }

    /**
     * Returns the value of the given parameter, which is parsed to an <code>boolean</code>.
     *
     * @param textKey The name of the parameter.
     * @return The <code>boolean</code> value of this parameter. So if the value is equal to <code>Yes</code>, then
     *         <code>true</code> will be returned. Else <code>false</code> is returned.
     * @throws OperationalTextKeyException If the given parameter cannot be found.
     */
    public final boolean getSettingAsBoolean (final OperationalTextKey textKey) throws OperationalTextKeyException {
        return getSetting(textKey).compareTo("Yes") == 0;
    }

    /**
     * Returns the value of the given parameter, which is parsed to an <code>integer</code>.
     *
     * @param textKey The name of the parameter.
     * @return The <code>integer</code> value of this parameter.
     * @throws OperationalTextKeyException If the given parameter cannot be found.
     */
    public final int getSettingAsInt (final OperationalTextKey textKey) throws OperationalTextKeyException {

        return Integer.parseInt(getSetting(textKey));
    }

    /**
     * Returns the value of the given parameter as <code>String</code>.
     *
     * @param textKey The name of the parameter.
     * @return The value of this parameter.
     * @throws OperationalTextKeyException If the given parameter cannot be found.
     */
    public final String getSetting (final OperationalTextKey textKey) throws OperationalTextKeyException {

        return configuration.getSetting(referenceSession.getTargetName(), connectionID, textKey);
    }

    /**
     * Returns the settings of the given session and connection.
     *
     * @return The settings of this specific connection.
     */
    public final SettingsMap getSettings () {

        return configuration.getSettings(referenceSession.getTargetName(), connectionID);
    }

    // --------------------------------------------------------------------------
    // --------------------------------------------------------------------------

    /**
     * Increments the Expected Status Sequence Number as defined in RFC1982 where <code>SERIAL_BITS = 32</code>.
     */
    public final void incrementExpectedStatusSequenceNumber () {

        expectedStatusSequenceNumber.increment();
    }

    /**
     * Returns the Expected Status Sequence Number of this <code>Connection</code> object.
     *
     * @return The current Expected Status Sequence Number.
     */
    public final SerialArithmeticNumber getExpectedStatusSequenceNumber () {

        return expectedStatusSequenceNumber;
    }

    /**
     * Sets the expected Status Sequence Number to the given one from the leading Login Response.
     *
     * @param newExpectedStatusSequenceNumber The new value.
     */
    public final void setExpectedStatusSequenceNumber (final int newExpectedStatusSequenceNumber) {

        expectedStatusSequenceNumber.setValue(newExpectedStatusSequenceNumber);

        LOGGER.trace("Set ExpStatSN to " + expectedStatusSequenceNumber);
    }

    // --------------------------------------------------------------------------
    // --------------------------------------------------------------------------

    /**
     * Switch to the new state. Start point of the state pattern. All states are computed one after another.
     *
     * @param newState The new state.
     * @throws InternetSCSIException of any kind
     */
    public final void nextState (final IState newState) throws InternetSCSIException {

        this.state = newState;
        if (this.state != null) {
            do {
                this.state.execute();
                LOGGER.info("State is following: " + this.state.nextStateFollowing());
            } while (this.state.nextStateFollowing());
        }

    }

    /**
     * Returns the current state of this connection.
     *
     * @return The current <code>IState</code> instance of this <code>Connection</code> instance.
     */
    public final IState getState () {

        return state;
    }

    /**
     * Returns the session, which contains this connection instance.
     *
     * @return The parent session instance.
     */
    public final Session getSession () {

        return referenceSession;
    }

    /**
     * Returns the ID of this <code>Connection</code> object.
     *
     * @return The connection ID.
     */
    public final short getConnectionID () {

        return connectionID;
    }

    // --------------------------------------------------------------------------
    // --------------------------------------------------------------------------

    /**
     * This method does all the necessary steps, which are needed when a connection should be closed.
     *
     * @throws IOException if an I/O error occurs.
     */
    public final void close () throws IOException {

        senderReceiver.close();
        LOGGER.debug("Connection with ID " + connectionID + " closed.");
    }

    /**
     * Enqueue this protocol data unit to the end of the sending queue.
     *
     * @param protocolDataUnit The protocol data unit to add.
     * @throws InternetSCSIException for nearly everything
     */
    public final void send (final ProtocolDataUnit protocolDataUnit) throws InternetSCSIException {

        try {
            senderReceiver.sendOverWire(protocolDataUnit);
        } catch (IOException e) {
            throw new InternetSCSIException(e);
        } catch (InterruptedException e) {
            throw new InternetSCSIException(e);
        }
    }

    /**
     * Enqueue all protocol data units to the end of the sending queue.
     *
     * @param protocolDataUnits The list with all protocol data units to add.
     * @throws InternetSCSIException for nearly everything
     */
    public final void send (final Queue<ProtocolDataUnit> protocolDataUnits) throws InternetSCSIException {

        for (final ProtocolDataUnit unit : protocolDataUnits) {
            send(unit);
        }
    }

    /**
     * Reads one <code>ProtocolDataUnit</code> instance from the <code>receivingQueue</code>.
     *
     * @return An instance of a <code>ProtocolDataUnit</code>.
     * @throws InternetSCSIException for nearly everything
     */
    public final ProtocolDataUnit receive () throws InternetSCSIException {

        try {
            return senderReceiver.receiveFromWire();
        } catch (DigestException e) {
            throw new InternetSCSIException(e);
        } catch (IOException e) {
            throw new InternetSCSIException(e);
        }
    }

    // --------------------------------------------------------------------------
    // --------------------------------------------------------------------------
    // --------------------------------------------------------------------------
    // --------------------------------------------------------------------------
}
TOP

Related Classes of org.jscsi.initiator.connection.Connection

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.