/// <summary> /// Ensures that the provided connection string is valid and builds the connection string /// to be used for DDR connection to the given shard provider. /// </summary> /// <param name="shardProvider">Shard provider containing shard to be connected to.</param> /// <param name="connectionString">Input connection string.</param> /// <returns>Connection string for DDR connection.</returns> private string ValidateAndPrepareConnectionString(IShardProvider shardProvider, string connectionString) { Debug.Assert(shardProvider != null); Debug.Assert(connectionString != null); // Devnote: If connection string specifies Active Directory authentication and runtime is not // .NET 4.6 or higher, then below call will throw. SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder(connectionString); // DataSource must not be set. if (!string.IsNullOrEmpty(connectionStringBuilder.DataSource)) { throw new ArgumentException( StringUtils.FormatInvariant( Errors._ShardMap_OpenConnection_ConnectionStringPropertyDisallowed, "DataSource"), "connectionString"); } // InitialCatalog must not be set. if (!string.IsNullOrEmpty(connectionStringBuilder.InitialCatalog)) { throw new ArgumentException( StringUtils.FormatInvariant( Errors._ShardMap_OpenConnection_ConnectionStringPropertyDisallowed, "Initial Catalog"), "connectionString"); } // ConnectRetryCount must not be set (default value is 1) if (ShardMapUtils.IsConnectionResiliencySupported && (int)connectionStringBuilder[ShardMapUtils.ConnectRetryCount] > 1) { throw new ArgumentException( StringUtils.FormatInvariant( Errors._ShardMap_OpenConnection_ConnectionStringPropertyDisallowed, ShardMapUtils.ConnectRetryCount), "connectionString"); } // Verify that either UserID/Password or provided or integrated authentication is enabled. SqlShardMapManagerCredentials.EnsureCredentials(connectionStringBuilder, "connectionString"); Shard s = shardProvider.ShardInfo; connectionStringBuilder.DataSource = s.Location.DataSource; connectionStringBuilder.InitialCatalog = s.Location.Database; // Append the proper post-fix for ApplicationName connectionStringBuilder.ApplicationName = ApplicationNameHelper.AddApplicationNameSuffix( connectionStringBuilder.ApplicationName, this.ApplicationNameSuffix); // Disable connection resiliency if necessary if (ShardMapUtils.IsConnectionResiliencySupported) { connectionStringBuilder[ShardMapUtils.ConnectRetryCount] = 0; } return(connectionStringBuilder.ConnectionString); }
internal async Task <SqlConnection> OpenConnectionAsync( IShardProvider shardProvider, string connectionString, ConnectionOptions options = ConnectionOptions.Validate) { return(await this.OpenConnectionAsync(shardProvider, connectionString, null, options)); }
/// <summary> /// Opens a connection to the given shard provider. /// </summary> /// <param name="shardProvider">Shard provider containing shard to be connected to.</param> /// <param name="connectionString">Connection string for connection. Must have credentials.</param> /// <param name="options">Options for validation operations to perform on opened connection.</param> internal SqlConnection OpenConnection( IShardProvider shardProvider, string connectionString, ConnectionOptions options = ConnectionOptions.Validate) { return(this.OpenConnection(shardProvider, connectionString, null, options)); }
internal async Task <SqlConnection> OpenConnectionAsync( IShardProvider shardProvider, string connectionString, SqlCredential secureCredential, ConnectionOptions options = ConnectionOptions.Validate) { Debug.Assert(shardProvider != null, "Expecting IShardProvider."); ExceptionUtils.DisallowNullArgument(connectionString, "connectionString"); string connectionStringFinal = this.ValidateAndPrepareConnectionString( shardProvider, connectionString, secureCredential); ExceptionUtils.EnsureShardBelongsToShardMap( this.Manager, this, shardProvider.ShardInfo, "OpenConnectionAsync", "Shard"); IUserStoreConnection conn = this.Manager.StoreConnectionFactory.GetUserConnection(connectionStringFinal, secureCredential); Tracer.TraceInfo( TraceSourceConstants.ComponentNames.ShardMap, "OpenConnectionAsync", "Start; Shard: {0}; Options: {1}; ConnectionString: {2}", shardProvider.ShardInfo.Location, options, connectionStringFinal); using (ConditionalDisposable <IUserStoreConnection> cd = new ConditionalDisposable <IUserStoreConnection>(conn)) { Stopwatch stopwatch = Stopwatch.StartNew(); await conn.OpenAsync().ConfigureAwait(false); stopwatch.Stop(); // If validation is requested. if ((options & ConnectionOptions.Validate) == ConnectionOptions.Validate) { await shardProvider.ValidateAsync(this.StoreShardMap, conn.Connection).ConfigureAwait(false); } cd.DoNotDispose = true; Tracer.TraceInfo( TraceSourceConstants.ComponentNames.ShardMap, "OpenConnectionAsync", "Complete; Shard: {0}; Options: {1}; Open Duration: {2}", shardProvider.ShardInfo.Location, options, stopwatch.Elapsed); } return(conn.Connection); }