| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| TargetSession |
|
| 1.4666666666666666;1.467 |
| 1 | package org.jscsi.target.connection; | |
| 2 | ||
| 3 | ||
| 4 | import org.jscsi.parser.ProtocolDataUnit; | |
| 5 | import org.jscsi.parser.login.ISID; | |
| 6 | import org.jscsi.target.Target; | |
| 7 | import org.jscsi.target.TargetServer; | |
| 8 | import org.jscsi.target.settings.SessionSettingsNegotiator; | |
| 9 | import org.jscsi.target.storage.IStorageModule; | |
| 10 | import org.jscsi.target.util.SerialArithmeticNumber; | |
| 11 | ||
| 12 | ||
| 13 | /** | |
| 14 | * A class for objects representing an iSCSI session with all necessary variables. | |
| 15 | * <p> | |
| 16 | * Currently, a {@link TargetSession} can only have <b>one</b> {@link Connection}, i.e. <code>MaxConnections=1</code>. | |
| 17 | * | |
| 18 | * @author Andreas Ergenzinger, University of Konstanz | |
| 19 | */ | |
| 20 | public class TargetSession { | |
| 21 | ||
| 22 | /** | |
| 23 | * Returns the value of the next {@link TargetSession} object's {@link #targetSessionIdentifyingHandle} variable. | |
| 24 | * | |
| 25 | * @return the value of the next {@link TargetSession} object's {@link #targetSessionIdentifyingHandle} variable | |
| 26 | */ | |
| 27 | private static short getNextTargetSessionIdentifyingHandle () { | |
| 28 | 0 | short handle = nextTargetSessionIdentifyingHandle++;// no concurrency |
| 29 | // necessary | |
| 30 | 0 | if (handle == 0) {// is reserved |
| 31 | 0 | handle = nextTargetSessionIdentifyingHandle++; |
| 32 | } | |
| 33 | 0 | return handle; |
| 34 | } | |
| 35 | ||
| 36 | /** | |
| 37 | * The {@link TargetServer} that this session is associated with | |
| 38 | */ | |
| 39 | private TargetServer targetServer; | |
| 40 | ||
| 41 | /** | |
| 42 | * The {@link Target} that this session is associated with | |
| 43 | */ | |
| 44 | private Target target; | |
| 45 | ||
| 46 | /** | |
| 47 | * The {@link TargetConnection} used for exchanging messages and data with the session's initiator endpoint. | |
| 48 | */ | |
| 49 | private Connection connection; | |
| 50 | ||
| 51 | /** | |
| 52 | * The {@link ISID} used by the initiator for identifying this session. | |
| 53 | */ | |
| 54 | private ISID initiatorSessionID; | |
| 55 | ||
| 56 | /** | |
| 57 | * Keeps track of the value to expect in the <code>ExpCmdSN</code> field of the next received | |
| 58 | * {@link ProtocolDataUnit} | |
| 59 | */ | |
| 60 | private SerialArithmeticNumber expectedCommandSequenceNumber; | |
| 61 | ||
| 62 | /** | |
| 63 | * Determines the number of iSCSI Command {@link ProtocolDataUnit}s the initiator may send without having the wait | |
| 64 | * for confirmation from the target that the command has finished. | |
| 65 | * <p> | |
| 66 | * A value of <code>1</code> means that the initiator must wait for each command to finish before issuing the next | |
| 67 | * one. | |
| 68 | * | |
| 69 | * @see #getExpectedCommandSequenceNumber() | |
| 70 | * @see #getMaximumCommandSequenceNumber() | |
| 71 | */ | |
| 72 | 0 | private final int commandWindowSize = 1; |
| 73 | ||
| 74 | /** | |
| 75 | * The {@link SessionSettingsNegotiator} responsible managing connection parameters with session scope. | |
| 76 | */ | |
| 77 | private SessionSettingsNegotiator sessionSettingsNegotiator; | |
| 78 | ||
| 79 | /** | |
| 80 | * A value used by the target to identify this session. | |
| 81 | */ | |
| 82 | private short targetSessionIdentifyingHandle; | |
| 83 | ||
| 84 | /** | |
| 85 | * A counter for {@link #targetSessionIdentifyingHandle}s. | |
| 86 | * | |
| 87 | * @see #getNextTargetSessionIdentifyingHandle() | |
| 88 | */ | |
| 89 | 0 | private static short nextTargetSessionIdentifyingHandle = 1; |
| 90 | ||
| 91 | /** | |
| 92 | * This value determines if this {@link TargetSession} is a discovery session or a regular (operational) session. | |
| 93 | */ | |
| 94 | private SessionType sessionType; | |
| 95 | ||
| 96 | /** | |
| 97 | * Constructs a new {@link TargetSession} | |
| 98 | * | |
| 99 | * @param connection the session's (first) {@link Connection} | |
| 100 | * @param initiatorSessionID the {@link ISID} specified by the initiator | |
| 101 | * @param expectedCommandSequenceNumber initialization value of {@link #expectedCommandSequenceNumber} | |
| 102 | * @param statusSequenceNumber the value expected by the initiator in the next {@link ProtocolDataUnit}'s | |
| 103 | * <code>StatSN</code> field | |
| 104 | */ | |
| 105 | 0 | public TargetSession (final TargetServer target, final Connection connection, final ISID initiatorSessionID, final int expectedCommandSequenceNumber, final int statusSequenceNumber) { |
| 106 | 0 | this.targetServer = target; |
| 107 | // set connection variables and parameters | |
| 108 | 0 | connection.setSession(this); |
| 109 | 0 | this.connection = connection; |
| 110 | 0 | connection.setStatusSequenceNumber(statusSequenceNumber); |
| 111 | ||
| 112 | // initialize ConnectionSettingsNegotiator (makes sure that settings are | |
| 113 | // initialized) | |
| 114 | 0 | sessionSettingsNegotiator = new SessionSettingsNegotiator(); |
| 115 | 0 | connection.initializeConnectionSettingsNegotiator(sessionSettingsNegotiator); |
| 116 | ||
| 117 | // set session variables | |
| 118 | 0 | this.initiatorSessionID = initiatorSessionID; |
| 119 | 0 | targetSessionIdentifyingHandle = getNextTargetSessionIdentifyingHandle(); |
| 120 | 0 | this.expectedCommandSequenceNumber = new SerialArithmeticNumber(expectedCommandSequenceNumber); |
| 121 | 0 | } |
| 122 | ||
| 123 | /** | |
| 124 | * Returns the session's {@link TargetServer}. | |
| 125 | * | |
| 126 | * @return the session's {@link TargetServer} | |
| 127 | */ | |
| 128 | public TargetServer getTargetServer () { | |
| 129 | 0 | return targetServer; |
| 130 | } | |
| 131 | ||
| 132 | /** | |
| 133 | * Returns the session's {@link Connection}. | |
| 134 | * | |
| 135 | * @return the session's {@link Connection} | |
| 136 | */ | |
| 137 | public Connection getConnection () { | |
| 138 | 0 | return connection; |
| 139 | } | |
| 140 | ||
| 141 | /** | |
| 142 | * Returns the session's {@link Target} | |
| 143 | * | |
| 144 | * @return the session's {@link Target} | |
| 145 | */ | |
| 146 | public Target getTarget () { | |
| 147 | 0 | return target; |
| 148 | } | |
| 149 | ||
| 150 | /** | |
| 151 | * Returns the session's {@link IStorageModule}. | |
| 152 | * | |
| 153 | * @return the session's {@link IStorageModule} | |
| 154 | */ | |
| 155 | public IStorageModule getStorageModule () { | |
| 156 | 0 | return target.getStorageModule(); |
| 157 | } | |
| 158 | ||
| 159 | /** | |
| 160 | * Returns the {@link SerialArithmeticNumber} representing the next expected command sequence number. | |
| 161 | * <p> | |
| 162 | * This value will be used both during sending (<code>ExpCmdSN</code> field) and receiving ( <code>CmdSN</code>) of | |
| 163 | * {@link ProtocolDataUnit}s. | |
| 164 | * | |
| 165 | * @return the {@link SerialArithmeticNumber} representing the next expected command sequence number | |
| 166 | * @see #expectedCommandSequenceNumber | |
| 167 | */ | |
| 168 | SerialArithmeticNumber getExpectedCommandSequenceNumber () { | |
| 169 | 0 | return expectedCommandSequenceNumber; |
| 170 | } | |
| 171 | ||
| 172 | /** | |
| 173 | * Returns the {@link ISID} used by the initiator to identify this session. | |
| 174 | * | |
| 175 | * @return the {@link ISID} used by the initiator to identify this session | |
| 176 | */ | |
| 177 | public ISID getInitiatorSessionID () { | |
| 178 | 0 | return initiatorSessionID; |
| 179 | } | |
| 180 | ||
| 181 | /** | |
| 182 | * Returns a {@link SerialArithmeticNumber} representing the maximum command sequence number the target will accept. | |
| 183 | * <p> | |
| 184 | * This value will be used both during sending (<code>MaxCmdSN</code> field) and receiving (checking if PDU's | |
| 185 | * <code>CmdSN</code> lies in the command sequence number window resulting from | |
| 186 | * {@link #expectedCommandSequenceNumber} and {@link #commandWindowSize}) of {@link ProtocolDataUnit}s. | |
| 187 | * | |
| 188 | * @return the {@link SerialArithmeticNumber} representing the next expected command sequence number | |
| 189 | */ | |
| 190 | SerialArithmeticNumber getMaximumCommandSequenceNumber () { | |
| 191 | 0 | return new SerialArithmeticNumber(expectedCommandSequenceNumber.getValue() + commandWindowSize - 1); |
| 192 | } | |
| 193 | ||
| 194 | /** | |
| 195 | * Returns the value used by the jSCSI Target to identify this session. | |
| 196 | * | |
| 197 | * @return the value used by the jSCSI Target to identify this session | |
| 198 | */ | |
| 199 | public short getTargetSessionIdentifyingHandle () { | |
| 200 | 0 | return targetSessionIdentifyingHandle; |
| 201 | } | |
| 202 | ||
| 203 | /** | |
| 204 | * Returns <code>true</code> if this session is a regular (operational) session, and <code>false</code> if it is s | |
| 205 | * discovery session. | |
| 206 | * | |
| 207 | * @return <code>true</code> if and only if this is not a regular (operational) session | |
| 208 | */ | |
| 209 | public boolean isNormalSession () { | |
| 210 | 0 | return sessionType == SessionType.NORMAL; |
| 211 | } | |
| 212 | ||
| 213 | /** | |
| 214 | * Removes a {@link TargetConnection} from the session's list of open connections. If this reduces the number of | |
| 215 | * connections to zero, the session will be removed from the {@link TargetServer}'s list of active sessions. | |
| 216 | * | |
| 217 | * @param connection the connection to be removed | |
| 218 | */ | |
| 219 | void removeTargetConnection (Connection connection) { | |
| 220 | // do this only if connection count == 0, currently it always is | |
| 221 | 0 | targetServer.removeTargetSession(this); |
| 222 | 0 | } |
| 223 | ||
| 224 | /** | |
| 225 | * Sets the session's type (discovery or operational). | |
| 226 | * <p> | |
| 227 | * The type may and must be set just once. Repeated calls of this method will fail. <code>true</code> will be | |
| 228 | * returned if the session type was set successfully, <code>false</code> if not. | |
| 229 | * | |
| 230 | * @param sessionType the session type | |
| 231 | * @return <code>true</code> if the session type was set successfully, <code>false</code> if not | |
| 232 | */ | |
| 233 | boolean setSessionType (SessionType sessionType) { | |
| 234 | // allow just once, accept only non-null parameter | |
| 235 | 0 | if (sessionType == null || this.sessionType != null) return false; |
| 236 | 0 | this.sessionType = sessionType; |
| 237 | 0 | return true; |
| 238 | } | |
| 239 | ||
| 240 | /** | |
| 241 | * Sets the target name and retrieves the target (if it exists) from the TargetServer | |
| 242 | * | |
| 243 | * @param targetName | |
| 244 | */ | |
| 245 | public void setTargetName (String targetName) { | |
| 246 | 0 | if (targetName == null) target = null; |
| 247 | 0 | target = targetServer.getTarget(targetName); |
| 248 | 0 | } |
| 249 | ||
| 250 | public String getTargetName () { | |
| 251 | 0 | if (target != null) return target.getTargetName(); |
| 252 | 0 | return null; |
| 253 | } | |
| 254 | } |