All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jscsi.initiator.connection.Connection Maven / Gradle / Ivy

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

/**
 * 

AbsConnection

*

* 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 Session instance, which contains this Connection instance. */ private final Session referenceSession; /** The Configuration 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 Session. */ 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 Connection object * with the configured layer of threading. * * @param session * Reference to the AbsSession object, which * contains this connection. * @param initConfiguration * The configuration to use within this connection. * @param inetAddress * The InetSocketAddress 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 boolean. * * @param textKey * The name of the parameter. * @return The boolean value of this parameter. So if the value * is equal to Yes, then true will be * returned. Else false 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 integer. * * @param textKey * The name of the parameter. * @return The integer 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 String. * * @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 SERIAL_BITS = 32. */ public final void incrementExpectedStatusSequenceNumber() { expectedStatusSequenceNumber.increment(); } /** * Returns the Expected Status Sequence Number of this Connection 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 IState instance of this Connection 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 Connection 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 protocolDataUnits) throws InternetSCSIException { for (final ProtocolDataUnit unit : protocolDataUnits) { send(unit); } } /** * Reads one ProtocolDataUnit instance from the receivingQueue. * * @return An instance of a ProtocolDataUnit. * @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); } } // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy