| | 1 | | /* |
| | 2 | | * Copyright 2018 Stanislav Muhametsin. All rights Reserved. |
| | 3 | | * |
| | 4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
| | 5 | | * you may not use this file except in compliance with the License. |
| | 6 | | * You may obtain a copy of the License at |
| | 7 | | * |
| | 8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
| | 9 | | * |
| | 10 | | * Unless required by applicable law or agreed to in writing, software |
| | 11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
| | 12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| | 13 | | * implied. |
| | 14 | | * |
| | 15 | | * See the License for the specific language governing permissions and |
| | 16 | | * limitations under the License. |
| | 17 | | */ |
| | 18 | | using IOUtils.Network.Configuration; |
| | 19 | | using ResourcePooling.Async.Abstractions; |
| | 20 | | using System; |
| | 21 | | using System.Threading; |
| | 22 | | using System.Threading.Tasks; |
| | 23 | | using UtilPack; |
| | 24 | |
|
| | 25 | | #if !NETSTANDARD1_0 |
| | 26 | | using IOUtils.Network.ResourcePooling; |
| | 27 | | #endif |
| | 28 | |
|
| | 29 | | namespace CBAM.Abstractions.Implementation.NetworkStream |
| | 30 | | { |
| | 31 | |
|
| | 32 | | /// <summary> |
| | 33 | | /// The primary purpose of this class is to bind instance of <see cref="NetworkConnectionCreationInfo{TCreationData, |
| | 34 | | /// </summary> |
| | 35 | | /// <typeparam name="TConnectionCreationParameters">The type of creation parameters, must be subtype of <see cref="Ne |
| | 36 | | /// <typeparam name="TCreationData">The type of creation parameters passive data, must be subtype of <see cref="Netwo |
| | 37 | | /// <typeparam name="TConnectionConfiguration">The type of connection configuration passive data, must be subtype of |
| | 38 | | /// <typeparam name="TInitializationConfiguration">The type of initialization configuration passive data, must be sub |
| | 39 | | /// <typeparam name="TProtocolConfiguration">The type of protocol configuration passive data.</typeparam> |
| | 40 | | /// <typeparam name="TPoolingConfiguration">The type of connection pool configuration passive data, must be subtype o |
| | 41 | | /// <seealso cref="BindPublicConnectionType"/> |
| | 42 | | /// <seealso cref="ConnectionCreationParametersAndPublicTypeBinder{TConnectionCreationParameters, TCreationData, TCon |
| | 43 | | public sealed class ConnectionCreationParametersTypeBinder<TConnectionCreationParameters, TCreationData, TConnectionC |
| | 44 | | where TConnectionCreationParameters : NetworkConnectionCreationInfo<TCreationData, TConnectionConfiguration, TInit |
| | 45 | | where TCreationData : NetworkConnectionCreationInfoData<TConnectionConfiguration, TInitializationConfiguration, TP |
| | 46 | | where TConnectionConfiguration : NetworkConnectionConfiguration |
| | 47 | | where TInitializationConfiguration : NetworkInitializationConfiguration<TProtocolConfiguration, TPoolingConfigurat |
| | 48 | | where TPoolingConfiguration : NetworkPoolingConfiguration |
| | 49 | | { |
| | 50 | | private readonly TConnectionCreationParameters _creationParameters; |
| | 51 | |
|
| | 52 | | /// <summary> |
| | 53 | | /// Creates a new instance of of <see cref="ConnectionCreationParametersTypeBinder{TConnectionCreationParameters, |
| | 54 | | /// </summary> |
| | 55 | | /// <param name="creationParameters">The connection creation parameters.</param> |
| | 56 | | /// <exception cref="ArgumentNullException">If <paramref name="creationParameters"/> is <c>null</c>.</exception> |
| 27 | 57 | | public ConnectionCreationParametersTypeBinder( |
| 27 | 58 | | TConnectionCreationParameters creationParameters |
| 27 | 59 | | ) |
| | 60 | | { |
| 27 | 61 | | this._creationParameters = ArgumentValidator.ValidateNotNull( nameof( creationParameters ), creationParameters |
| 27 | 62 | | } |
| | 63 | |
|
| | 64 | | /// <summary> |
| | 65 | | /// Given one generic type argument, creates an object which can be used to create <see cref="AsyncResourceFactory |
| | 66 | | /// </summary> |
| | 67 | | /// <typeparam name="TConnection">The public type of connection.</typeparam> |
| | 68 | | /// <returns>An object which can be used to create <see cref="AsyncResourceFactory{TResource}"/>.</returns> |
| | 69 | | /// <seealso cref="ConnectionCreationParametersAndPublicTypeBinder{TConnectionCreationParameters, TCreationData, T |
| | 70 | | public ConnectionCreationParametersAndPublicTypeBinder<TConnectionCreationParameters, TCreationData, TConnectionCo |
| | 71 | | where TConnection : class |
| | 72 | | { |
| 27 | 73 | | return new ConnectionCreationParametersAndPublicTypeBinder<TConnectionCreationParameters, TCreationData, TConne |
| 27 | 74 | | this._creationParameters |
| 27 | 75 | | ); |
| | 76 | | } |
| | 77 | |
|
| | 78 | | } |
| | 79 | |
|
| | 80 | | /// <summary> |
| | 81 | | /// This class is typically acquired from <see cref="ConnectionCreationParametersTypeBinder{TConnectionCreationParame |
| | 82 | | /// </summary> |
| | 83 | | /// <typeparam name="TConnectionCreationParameters">The type of creation parameters, must be subtype of <see cref="Ne |
| | 84 | | /// <typeparam name="TCreationData">The type of creation parameters passive data, must be subtype of <see cref="Netwo |
| | 85 | | /// <typeparam name="TConnectionConfiguration">The type of connection configuration passive data, must be subtype of |
| | 86 | | /// <typeparam name="TInitializationConfiguration">The type of initialization configuration passive data, must be sub |
| | 87 | | /// <typeparam name="TProtocolConfiguration">The type of protocol configuration passive data.</typeparam> |
| | 88 | | /// <typeparam name="TPoolingConfiguration">The type of connection pool configuration passive data, must be subtype o |
| | 89 | | /// <typeparam name="TConnection">The public type of connection.</typeparam> |
| | 90 | | public sealed class ConnectionCreationParametersAndPublicTypeBinder<TConnectionCreationParameters, TCreationData, TCo |
| | 91 | | where TConnectionCreationParameters : NetworkConnectionCreationInfo<TCreationData, TConnectionConfiguration, TInit |
| | 92 | | where TCreationData : NetworkConnectionCreationInfoData<TConnectionConfiguration, TInitializationConfiguration, TP |
| | 93 | | where TConnectionConfiguration : NetworkConnectionConfiguration |
| | 94 | | where TInitializationConfiguration : NetworkInitializationConfiguration<TProtocolConfiguration, TPoolingConfigurat |
| | 95 | | where TPoolingConfiguration : NetworkPoolingConfiguration |
| | 96 | | where TConnection : class |
| | 97 | | { |
| | 98 | | private readonly TConnectionCreationParameters _creationParameters; |
| | 99 | |
|
| | 100 | | /// <summary> |
| | 101 | | /// Creates a new instance of <see cref="ConnectionCreationParametersAndPublicTypeBinder{TConnectionCreationParame |
| | 102 | | /// </summary> |
| | 103 | | /// <param name="creationParameters">The connection creation parameters.</param> |
| | 104 | | /// <exception cref="ArgumentNullException">If <paramref name="creationParameters"/> is <c>null</c>.</exception> |
| | 105 | | public ConnectionCreationParametersAndPublicTypeBinder( |
| | 106 | | TConnectionCreationParameters creationParameters |
| | 107 | | ) |
| | 108 | | { |
| | 109 | | this._creationParameters = ArgumentValidator.ValidateNotNull( nameof( creationParameters ), creationParameters |
| | 110 | | } |
| | 111 | |
|
| | 112 | | /// <summary> |
| | 113 | | /// Creates a new instance of <see cref="AsyncResourceFactory{TResource}"/> with behaviour customizable by given c |
| | 114 | | /// </summary> |
| | 115 | | /// <typeparam name="TPrivateConnection">The actual, usually internal, type of connection.</typeparam> |
| | 116 | | /// <typeparam name="TConnectionFunctionality">The type of connection functionality, which usually contains the ac |
| | 117 | | /// <param name="encodingInfo">The <see cref="IEncodingInfo"/> to use when (de)serializing strings.</param> |
| | 118 | | /// <param name="isSSLPossible">The callback to check if remote end supports SSL.</param> |
| | 119 | | /// <param name="noSSLStreamProvider">The callback to create an exception when there was not possible to create SS |
| | 120 | | /// <param name="remoteNoSSLSupport">The callback to create an exception when the remote does not support SSL. May |
| | 121 | | /// <param name="sslStreamProviderNoStream">The callback to create an exception when the SSL stream creation callb |
| | 122 | | /// <param name="sslStreamProviderNoAuthenticationCallback">The callback to create an exception when the SSL strea |
| | 123 | | /// <param name="sslStreamOtherError">The callback to create an exception when other error occurs during SSL strea |
| | 124 | | /// <param name="createFunctionality">The callback to create the connection functionality of type <typeparamref na |
| | 125 | | /// <param name="createConnection">The callback to create connection after connection functionality has been creat |
| | 126 | | /// <param name="createConnectionAcquireInfo">The callback to create connection acquire info after connection func |
| | 127 | | /// <param name="extractStreamOnConnectionAcquirementError">The callback to extract stream from connection acquire |
| | 128 | | /// <param name="dedicatedStringPoolNeedsToBeConcurrent">Optional boolean indicating whether per-connection dedica |
| | 129 | | /// <returns>A <see cref="AsyncResourceFactory{TResource}"/> which uses sockets and network stream underneath, and |
| | 130 | | /// <remarks> |
| | 131 | | /// The returned <see cref="AsyncResourceFactory{TResource}"/> is <see cref="DelegatingStatelessProtocolConnection |
| | 132 | | /// </remarks> |
| | 133 | | public AsyncResourceFactory<TConnection> CreateStatelessDelegatingConnectionFactory<TPrivateConnection, TConnectio |
| | 134 | | IEncodingInfo encodingInfo, |
| | 135 | | IsSSLPossibleDelegate<TConnectionCreationParameters> isSSLPossible, |
| | 136 | | Func<Exception> noSSLStreamProvider, |
| | 137 | | Func<Exception> remoteNoSSLSupport, |
| | 138 | | Func<Exception> sslStreamProviderNoStream, |
| | 139 | | Func<Exception> sslStreamProviderNoAuthenticationCallback, |
| | 140 | | Func<Exception, Exception> sslStreamOtherError, |
| | 141 | | CreateConnectionFunctionality<TConnectionFunctionality, TConnectionCreationParameters> createFunctionality, |
| | 142 | | CreatePrivateConnectionDelegate<TConnectionFunctionality, TPrivateConnection> createConnection, |
| | 143 | | CreateConnectionAcquireInfo<TConnectionFunctionality, TPrivateConnection> createConnectionAcquireInfo, |
| | 144 | | ExtractStreamOnConnectionAcquirementErrorDelegate<TConnectionFunctionality, TPrivateConnection> extractStreamOn |
| | 145 | | Boolean dedicatedStringPoolNeedsToBeConcurrent = false |
| | 146 | | ) |
| | 147 | | where TPrivateConnection : class, TConnection |
| | 148 | | where TConnectionFunctionality : class, PooledConnectionFunctionality |
| | 149 | | { |
| | 150 | | return new DelegatingStatelessProtocolConnectionFactory<TConnection, TPrivateConnection, TConnectionFunctionali |
| | 151 | | this._creationParameters, |
| | 152 | | encodingInfo, |
| | 153 | | isSSLPossible, |
| | 154 | | noSSLStreamProvider, |
| | 155 | | remoteNoSSLSupport, |
| | 156 | | sslStreamProviderNoStream, |
| | 157 | | sslStreamProviderNoAuthenticationCallback, |
| | 158 | | sslStreamOtherError, |
| | 159 | | dedicatedStringPoolNeedsToBeConcurrent, |
| | 160 | | createFunctionality, |
| | 161 | | createConnection, |
| | 162 | | createConnectionAcquireInfo, |
| | 163 | | extractStreamOnConnectionAcquirementError |
| | 164 | | ); |
| | 165 | | } |
| | 166 | |
|
| | 167 | | /// <summary> |
| | 168 | | /// Creates a new instance of <see cref="AsyncResourceFactory{TResource}"/> with behaviour customizable by given c |
| | 169 | | /// </summary> |
| | 170 | | /// <typeparam name="TPrivateConnection">The actual, usually internal, type of connection.</typeparam> |
| | 171 | | /// <typeparam name="TConnectionFunctionality">The type of connection functionality, which usually contains the ac |
| | 172 | | /// <typeparam name="TIntermediateState">The type of intermediate state.</typeparam> |
| | 173 | | /// <param name="encodingInfo">The <see cref="IEncodingInfo"/> to use when (de)serializing strings.</param> |
| | 174 | | /// <param name="createIntermediateState">The callback to create intermediate state.</param> |
| | 175 | | /// <param name="isSSLPossible">The callback to check if remote end supports SSL.</param> |
| | 176 | | /// <param name="noSSLStreamProvider">The callback to create an exception when there was not possible to create SS |
| | 177 | | /// <param name="remoteNoSSLSupport">The callback to create an exception when the remote does not support SSL. May |
| | 178 | | /// <param name="sslStreamProviderNoStream">The callback to create an exception when the SSL stream creation callb |
| | 179 | | /// <param name="sslStreamProviderNoAuthenticationCallback">The callback to create an exception when the SSL strea |
| | 180 | | /// <param name="sslStreamOtherError">The callback to create an exception when other error occurs during SSL strea |
| | 181 | | /// <param name="createFunctionality">The callback to create the connection functionality of type <typeparamref na |
| | 182 | | /// <param name="createConnection">The callback to create connection after connection functionality has been creat |
| | 183 | | /// <param name="createConnectionAcquireInfo">The callback to create connection acquire info after connection func |
| | 184 | | /// <param name="extractStreamOnConnectionAcquirementError">The callback to extract stream from connection acquire |
| | 185 | | /// <param name="dedicatedStringPoolNeedsToBeConcurrent">Optional boolean indicating whether per-connection dedica |
| | 186 | | /// <returns>A <see cref="AsyncResourceFactory{TResource}"/> which uses sockets and network stream underneath, and |
| | 187 | | /// <remarks> |
| | 188 | | /// The returned <see cref="AsyncResourceFactory{TResource}"/> is <see cref="DelegatingStatefulProtocolConnectionF |
| | 189 | | /// </remarks> |
| | 190 | | public AsyncResourceFactory<TConnection> CreateStatefulDelegatingConnectionFactory<TPrivateConnection, TConnection |
| | 191 | | IEncodingInfo encodingInfo, |
| | 192 | | CreateIntermediateStateDelegate<TConnectionCreationParameters, TIntermediateState> createIntermediateState, |
| | 193 | | IsSSLPossibleDelegate<TConnectionCreationParameters, TIntermediateState> isSSLPossible, |
| | 194 | | Func<Exception> noSSLStreamProvider, |
| | 195 | | Func<Exception> remoteNoSSLSupport, |
| | 196 | | Func<Exception> sslStreamProviderNoStream, |
| | 197 | | Func<Exception> sslStreamProviderNoAuthenticationCallback, |
| | 198 | | Func<Exception, Exception> sslStreamOtherError, |
| | 199 | | CreateConnectionFunctionality<TConnectionFunctionality, TIntermediateState, TConnectionCreationParameters> crea |
| | 200 | | CreatePrivateConnectionDelegate<TConnectionFunctionality, TPrivateConnection> createConnection, |
| | 201 | | CreateConnectionAcquireInfo<TConnectionFunctionality, TPrivateConnection> createConnectionAcquireInfo, |
| | 202 | | ExtractStreamOnConnectionAcquirementErrorDelegate<TConnectionFunctionality, TPrivateConnection> extractStreamOn |
| | 203 | | Boolean dedicatedStringPoolNeedsToBeConcurrent = false |
| | 204 | | ) |
| | 205 | | where TPrivateConnection : class, TConnection |
| | 206 | | where TConnectionFunctionality : class, PooledConnectionFunctionality |
| | 207 | | { |
| | 208 | | return new DelegatingStatefulProtocolConnectionFactory<TConnection, TPrivateConnection, TConnectionFunctionalit |
| | 209 | | this._creationParameters, |
| | 210 | | encodingInfo, |
| | 211 | | createIntermediateState, |
| | 212 | | isSSLPossible, |
| | 213 | | noSSLStreamProvider, |
| | 214 | | remoteNoSSLSupport, |
| | 215 | | sslStreamProviderNoStream, |
| | 216 | | sslStreamProviderNoAuthenticationCallback, |
| | 217 | | sslStreamOtherError, |
| | 218 | | dedicatedStringPoolNeedsToBeConcurrent, |
| | 219 | | createFunctionality, |
| | 220 | | createConnection, |
| | 221 | | createConnectionAcquireInfo, |
| | 222 | | extractStreamOnConnectionAcquirementError |
| | 223 | | ); |
| | 224 | | } |
| | 225 | | } |
| | 226 | |
|
| | 227 | | /// <summary> |
| | 228 | | /// This delegate is used to potentially asynchronously create a CBAM connection from close-to-protocol connection fu |
| | 229 | | /// </summary> |
| | 230 | | /// <typeparam name="TConnectionFunctionality">The type of close-to-protocol connection functionality.</typeparam> |
| | 231 | | /// <typeparam name="TPrivateConnection">The type of connection.</typeparam> |
| | 232 | | /// <param name="connectionFunctionality">The close-to-protocol connection functionality.</param> |
| | 233 | | /// <returns>Potentially asynchronously creates a CBAM connection.</returns> |
| | 234 | | public delegate ValueTask<TPrivateConnection> CreatePrivateConnectionDelegate<TConnectionFunctionality, TPrivateConne |
| | 235 | |
|
| | 236 | | /// <summary> |
| | 237 | | /// This delegate is used to create a new instance of <see cref="AsyncResourceAcquireInfo{TResource}"/> once the clos |
| | 238 | | /// </summary> |
| | 239 | | /// <typeparam name="TConnectionFunctionality">The type of close-to-protocol connection functionality.</typeparam> |
| | 240 | | /// <typeparam name="TPrivateConnection">The type of connection.</typeparam> |
| | 241 | | /// <param name="connectionFunctionality">The close-to-protocol connection functionality.</param> |
| | 242 | | /// <param name="privateConnection">The CBAM connection.</param> |
| | 243 | | /// <returns>A new instance of <see cref="AsyncResourceAcquireInfo{TResource}"/>.</returns> |
| | 244 | | /// <seealso cref="StatelessConnectionAcquireInfo{TConnection, TConnectionFunctionality, TStream}"/> |
| | 245 | | /// <seealso cref="ConnectionAcquireInfoImpl{TConnection, TConnectionFunctionality, TStream}"/> |
| | 246 | | public delegate AsyncResourceAcquireInfo<TPrivateConnection> CreateConnectionAcquireInfo<TConnectionFunctionality, TP |
| | 247 | |
|
| | 248 | | /// <summary> |
| | 249 | | /// This delegate is used to extract stream or other <see cref="IDisposable"/> after an error occurs during new conne |
| | 250 | | /// </summary> |
| | 251 | | /// <typeparam name="TConnectionFunctionality">The type of close-to-protocol connection functionality.</typeparam> |
| | 252 | | /// <typeparam name="TPrivateConnection">The type of connection.</typeparam> |
| | 253 | | /// <param name="connectionFunctionality">The close-to-protocol connection functionality.</param> |
| | 254 | | /// <param name="privateConnection">The CBAM connection.</param> |
| | 255 | | /// <param name="token">The <see cref="CancellationToken"/>.</param> |
| | 256 | | /// <param name="error">The error that occurred.</param> |
| | 257 | | /// <returns></returns> |
| | 258 | | public delegate IDisposable ExtractStreamOnConnectionAcquirementErrorDelegate<TConnectionFunctionality, TPrivateConne |
| | 259 | |
|
| | 260 | |
|
| | 261 | | /// <summary> |
| | 262 | | /// This class contains extension methods for types defined in other assemblies. |
| | 263 | | /// </summary> |
| | 264 | | public static partial class CBAMExtensions |
| | 265 | | { |
| | 266 | | /// <summary> |
| | 267 | | /// Helper method to easily create <see cref="ConnectionCreationParametersTypeBinder{TConnectionCreationParameters |
| | 268 | | /// Note: Currently, the generic parameters are for some reason required. Need to investigate whether the problem |
| | 269 | | /// </summary> |
| | 270 | | /// <typeparam name="TConnectionCreationParameters">The type of creation parameters, must be subtype of <see cref= |
| | 271 | | /// <typeparam name="TCreationData">The type of creation parameters passive data, must be subtype of <see cref="Ne |
| | 272 | | /// <typeparam name="TConnectionConfiguration">The type of connection configuration passive data, must be subtype |
| | 273 | | /// <typeparam name="TInitializationConfiguration">The type of initialization configuration passive data, must be |
| | 274 | | /// <typeparam name="TProtocolConfiguration">The type of protocol configuration passive data.</typeparam> |
| | 275 | | /// <typeparam name="TPoolingConfiguration">The type of connection pool configuration passive data, must be subtyp |
| | 276 | | /// <param name="creationParameters">This <see cref="NetworkConnectionCreationInfo{TCreationData, TConnectionConfi |
| | 277 | | /// <returns>A new instance of <see cref="ConnectionCreationParametersTypeBinder{TConnectionCreationParameters, TC |
| | 278 | | /// <exception cref="NullReferenceException">If this <see cref="NetworkConnectionCreationInfo{TCreationData, TConn |
| | 279 | | public static ConnectionCreationParametersTypeBinder<TConnectionCreationParameters, TCreationData, TConnectionConf |
| | 280 | | this TConnectionCreationParameters creationParameters |
| | 281 | | ) |
| | 282 | | where TConnectionCreationParameters : NetworkConnectionCreationInfo<TCreationData, TConnectionConfiguration, TI |
| | 283 | | where TCreationData : NetworkConnectionCreationInfoData<TConnectionConfiguration, TInitializationConfiguration, |
| | 284 | | where TConnectionConfiguration : NetworkConnectionConfiguration |
| | 285 | | where TInitializationConfiguration : NetworkInitializationConfiguration<TProtocolConfiguration, TPoolingConfigu |
| | 286 | | where TPoolingConfiguration : NetworkPoolingConfiguration |
| | 287 | | { |
| | 288 | | return new ConnectionCreationParametersTypeBinder<TConnectionCreationParameters, TCreationData, TConnectionConf |
| | 289 | | } |
| | 290 | | } |
| | 291 | | } |