예제 #1
0
        /// <summary>Constructs a shard key using given object.</summary>
        /// <param name="value">Input object.</param>
        public ShardKey(object value)
        {
            ExceptionUtils.DisallowNullArgument(value, "value");

            // We can't detect the type if value is null.
            if (DBNull.Value.Equals(value))
            {
                throw new ArgumentNullException("value");
            }

            ShardKey shardKey = value as ShardKey;

            if (shardKey != null)
            {
                _keyType = shardKey._keyType;
                _value   = shardKey._value;
            }
            else
            {
                _keyType = ShardKey.DetectShardKeyType(value);
                _value   = ShardKey.Normalize(_keyType, value);
            }

            _hashCode = this.CalculateHashCode();
        }
        public int CompareTo(ShardRange other)
        {
            ExceptionUtils.DisallowNullArgument(other, "other");

            if (this.Low < other.Low)
            {
                return(-1);
            }

            if (this.High > other.High)
            {
                return(1);
            }

            if (this.Low == other.Low)
            {
                if (this.High == other.High)
                {
                    return(0);
                }
                else
                {
                    return(-1);
                }
            }
            else
            {
                Debug.Assert(this.Low > other.Low);
                Debug.Assert(this.High <= other.High);
                return(1);
            }
        }
        /// <summary>
        /// Arguments used to create a point mapping.
        /// </summary>
        /// <param name="point">Point value being mapped.</param>
        /// <param name="shard">Shard used as the mapping target.</param>
        /// <param name="status">Status of the mapping.</param>
        public PointMappingCreationInfo(TKey point, Shard shard, MappingStatus status)
        {
            ExceptionUtils.DisallowNullArgument(shard, "shard");
            this.Value  = point;
            this.Shard  = shard;
            this.Status = status;

            this.Key = new ShardKey(ShardKey.ShardKeyTypeFromType(typeof(TKey)), point);
        }
예제 #4
0
        /// <summary>
        /// Creates an instance of <see cref="SqlConnectionInfo"/>.
        /// </summary>
        /// <param name="connectionString">The connection string.</param>
        /// <param name="secureCredential">The secure SQL credential.</param>
        internal SqlConnectionInfo(
            string connectionString,
            SqlCredential secureCredential)
        {
            ExceptionUtils.DisallowNullArgument(connectionString, "connectionString");

            this.ConnectionString = connectionString;
            this.Credential       = secureCredential;
        }
예제 #5
0
        public Task <SqlConnection> OpenConnectionForKeyAsync(TKey key, string connectionString, SqlCredential secureCredential, ConnectionOptions options)
        {
            ExceptionUtils.DisallowNullArgument(connectionString, "connectionString");

            using (ActivityIdScope activityIdScope = new ActivityIdScope(Guid.NewGuid()))
            {
                return(this.rsm.OpenConnectionForKeyAsync(key, connectionString, secureCredential, options));
            }
        }
예제 #6
0
        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);
        }
        /// <summary>
        /// Instantiates the object that holds the credentials for accessing SQL Servers
        /// containing the shard map manager data.
        /// </summary>
        /// <param name="connectionString">
        /// Connection string for shard map manager data source.
        /// </param>
        /// <param name="secureCredential">
        ///  Secure credential for shard map manager data source.
        /// </param>
        public SqlShardMapManagerCredentials(string connectionString, SqlCredential secureCredential)
        {
            ExceptionUtils.DisallowNullArgument(connectionString, "connectionString");

            this._secureCredential = secureCredential;

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

            #region GSM Validation

            // DataSource must be set.
            if (string.IsNullOrEmpty(connectionStringBuilder.DataSource))
            {
                throw new ArgumentException(
                          StringUtils.FormatInvariant(
                              Errors._SqlShardMapManagerCredentials_ConnectionStringPropertyRequired,
                              "DataSource"),
                          "connectionString");
            }

            // InitialCatalog must be set.
            if (string.IsNullOrEmpty(connectionStringBuilder.InitialCatalog))
            {
                throw new ArgumentException(
                          StringUtils.FormatInvariant(
                              Errors._SqlShardMapManagerCredentials_ConnectionStringPropertyRequired,
                              "Initial Catalog"),
                          "connectionString");
            }

            // Ensure credentials are specified for GSM connectivity.
            SqlShardMapManagerCredentials.EnsureCredentials(
                connectionStringBuilder,
                "connectionString",
                this._secureCredential);

            #endregion GSM Validation

            // Copy the input connection strings.
            _connectionStringShardMapManager = new SqlConnectionStringBuilder(connectionStringBuilder.ConnectionString);

            _connectionStringShardMapManager.ApplicationName = ApplicationNameHelper.AddApplicationNameSuffix(
                _connectionStringShardMapManager.ApplicationName,
                GlobalConstants.ShardMapManagerInternalConnectionSuffixGlobal);

            _connectionStringShard = new SqlConnectionStringBuilder(connectionStringBuilder.ConnectionString);

            _connectionStringShard.Remove("Data Source");
            _connectionStringShard.Remove("Initial Catalog");

            _connectionStringShard.ApplicationName = ApplicationNameHelper.AddApplicationNameSuffix(
                _connectionStringShard.ApplicationName,
                GlobalConstants.ShardMapManagerInternalConnectionSuffixLocal);
        }
        /// <summary>
        /// Creates an instance of <see cref="SqlConnectionInfo"/>.
        /// </summary>
        /// <param name="connectionString">The connection string.</param>
        /// <param name="secureCredential">The secure SQL credential.</param>
        /// <param name="accessTokenFactory">A function that returns an access token.</param>
        internal SqlConnectionInfo(
            string connectionString,
            SqlCredential secureCredential   = null,
            Func <string> accessTokenFactory = null)
        {
            ExceptionUtils.DisallowNullArgument(connectionString, "connectionString");

            this.ConnectionString   = connectionString;
            this.Credential         = secureCredential;
            this.AccessTokenFactory = accessTokenFactory;
        }
        /// <summary>
        /// Validates the input shard map. This includes:
        /// * Ensuring that shard map belongs to this instance of shard map manager.
        /// </summary>
        /// <param name="shardMap">Input shard map.</param>
        private void ValidateShardMap(ShardMap shardMap)
        {
            ExceptionUtils.DisallowNullArgument(shardMap, "shardMap");

            if (shardMap.Manager != this)
            {
                throw new InvalidOperationException(
                          StringUtils.FormatInvariant(
                              Errors._ShardMapManager_DifferentShardMapManager,
                              shardMap.Name,
                              this.Credentials.ShardMapManagerLocation));
            }
        }
        /// <summary>Returns the intersection of two ranges.</summary>
        /// <param name="range">Range to intersect with.</param>
        /// <returns>
        /// The intersection of the current range and the specified range, null if ranges dont intersect.
        /// </returns>
        internal ShardRange Intersect(ShardRange range)
        {
            ExceptionUtils.DisallowNullArgument(range, "range");

            ShardKey intersectLow  = ShardKey.Max(Low, range.Low);
            ShardKey intersectHigh = ShardKey.Min(High, range.High);

            if (intersectLow >= intersectHigh)
            {
                return(null);
            }

            return(new ShardRange(intersectLow, intersectHigh));
        }
        public Task <SqlConnection> OpenConnectionForKeyAsync(
            TKey key,
            SqlConnectionInfo connectionInfo,
            ConnectionOptions options)
        {
            ExceptionUtils.DisallowNullArgument(connectionInfo, "connectionInfo");

            using (ActivityIdScope activityIdScope = new ActivityIdScope(Guid.NewGuid()))
            {
                return(_lsm.OpenConnectionForKeyAsync(
                           key,
                           connectionInfo,
                           options));
            }
        }
예제 #12
0
        public static ShardKeyType DetectShardKeyType(object value)
        {
            ExceptionUtils.DisallowNullArgument(value, "value");

            ShardKeyType keyType;

            if (!ShardKey.s_typeToShardKeyType.Value.TryGetValue(value.GetType(), out keyType))
            {
                throw new ArgumentException(
                          StringUtils.FormatInvariant(
                              Errors._ShardKey_UnsupportedValue,
                              value.GetType()),
                          "value");
            }

            return(keyType);
        }
예제 #13
0
        public void DeleteMapping(RangeMapping <TKey> mapping, MappingLockToken mappingLockToken)
        {
            ExceptionUtils.DisallowNullArgument(mapping, "mapping");
            ExceptionUtils.DisallowNullArgument(mappingLockToken, "mappingLockToken");

            using (ActivityIdScope activityIdScope = new ActivityIdScope(Guid.NewGuid()))
            {
                Tracer.TraceInfo(TraceSourceConstants.ComponentNames.RangeShardMap,
                                 "DeleteMapping", "Start; Shard: {0}", mapping.Shard.Location);

                Stopwatch stopwatch = Stopwatch.StartNew();

                this.rsm.Remove(mapping, mappingLockToken.LockOwnerId);

                stopwatch.Stop();

                Tracer.TraceInfo(TraceSourceConstants.ComponentNames.RangeShardMap,
                                 "DeleteMapping", "Complete; Shard: {0}; Duration: {1}",
                                 mapping.Shard.Location, stopwatch.Elapsed);
            }
        }
        /// <summary>Constructs a shard range from low boundary (inclusive) to high high boundary (exclusive)</summary>
        /// <param name="low">Low boundary (inclusive)</param>
        /// <param name="high">High boundary (exclusive)</param>
        public ShardRange(ShardKey low, ShardKey high)
        {
            ExceptionUtils.DisallowNullArgument(low, "low");
            ExceptionUtils.DisallowNullArgument(high, "high");

            if (low >= high)
            {
                throw new ArgumentOutOfRangeException(
                          "low",
                          low,
                          string.Format(
                              Errors._ShardRange_LowGreaterThanOrEqualToHigh,
                              low,
                              high));
            }

            this.Low     = low;
            this.High    = high;
            this.KeyType = Low.KeyType;
            _hashCode    = this.CalculateHashCode();
        }