Example #1
0
        /// <summary>
        /// Returns the proper ShardManagementException corresponding to given error code in
        /// <paramref name="result"/> for ShardMap operations.
        /// </summary>
        /// <param name="result">Operation result object.</param>
        /// <param name="shardMap">Shard map object.</param>
        /// <param name="location">Location of operation.</param>
        /// <param name="errorCategory">Error category to use for raised errors.</param>
        /// <param name="operationName">Operation being performed.</param>
        /// <param name="storedProcName">Stored procedure being executed.</param>
        /// <returns>ShardManagementException to be raised.</returns>
        internal static ShardManagementException OnRecoveryErrorLocal(
            IStoreResults result,
            IStoreShardMap shardMap,
            ShardLocation location,
            ShardManagementErrorCategory errorCategory,
            string operationName,
            string storedProcName)
        {
            switch (result.Result)
            {
            case StoreResult.ShardMapDoesNotExist:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.ShardMapDoesNotExist,
                           Errors._Store_ShardMap_DoesNotExistLocal,
                           shardMap.Name,
                           location,
                           storedProcName,
                           operationName));

            case StoreResult.StoreVersionMismatch:
            case StoreResult.MissingParametersForStoredProcedure:
            default:
                return(StoreOperationErrorHandler.OnCommonErrorLocal(
                           result,
                           location,
                           operationName,
                           storedProcName));
            }
        }
 /// <summary>
 /// Constructs request for obtaining mapping from GSM based on given key.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager.</param>
 /// <param name="operationName">Operation being executed.</param>
 /// <param name="shardMap">Local shard map.</param>
 /// <param name="mapping">Mapping whose Id will be used.</param>
 /// <param name="errorCategory">Error category.</param>
 internal FindMappingByIdGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, IStoreMapping mapping, ShardManagementErrorCategory errorCategory) :
     base(shardMapManager.Credentials, shardMapManager.RetryPolicy, operationName)
 {
     _manager = shardMapManager;
     _shardMap = shardMap;
     _mapping = mapping;
     _errorCategory = errorCategory;
 }
 /// <summary>
 /// Constructs request for obtaining mapping from GSM based on given key.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager.</param>
 /// <param name="operationName">Operation being executed.</param>
 /// <param name="shardMap">Local shard map.</param>
 /// <param name="mapping">Mapping whose Id will be used.</param>
 /// <param name="errorCategory">Error category.</param>
 internal FindMappingByIdGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, IStoreMapping mapping, ShardManagementErrorCategory errorCategory) :
     base(shardMapManager.Credentials, shardMapManager.RetryPolicy, operationName)
 {
     _manager       = shardMapManager;
     _shardMap      = shardMap;
     _mapping       = mapping;
     _errorCategory = errorCategory;
 }
Example #4
0
        /// <summary>
        /// Looks up the key value and returns the corresponding mapping.
        /// </summary>
        /// <typeparam name="TMapping">Mapping type.</typeparam>
        /// <typeparam name="TKey">Key type.</typeparam>
        /// <param name="key">Input key value.</param>
        /// <param name="useCache">Whether to use cache for lookups.</param>
        /// <param name="constructMapping">Delegate to construct a mapping object.</param>
        /// <param name="errorCategory">Category under which errors must be thrown.</param>
        /// <returns>Mapping that contains the key value.</returns>
        protected TMapping Lookup <TMapping, TKey>(
            TKey key,
            bool useCache,
            Func <ShardMapManager, ShardMap, IStoreMapping, TMapping> constructMapping,
            ShardManagementErrorCategory errorCategory)
            where TMapping : class, IShardProvider
        {
            ShardKey sk = new ShardKey(ShardKey.ShardKeyTypeFromType(typeof(TKey)), key);

            if (useCache)
            {
                ICacheStoreMapping cachedMapping = this.Manager.Cache.LookupMappingByKey(this.ShardMap.StoreShardMap, sk);

                if (cachedMapping != null)
                {
                    return(constructMapping(this.Manager, this.ShardMap, cachedMapping.Mapping));
                }
            }

            // Cache-miss, find mapping for given key in GSM.
            TMapping m = null;

            IStoreResults gsmResult;

            Stopwatch stopwatch = Stopwatch.StartNew();

            using (IStoreOperationGlobal op = this.Manager.StoreOperationFactory.CreateFindMappingByKeyGlobalOperation(
                       this.Manager,
                       "Lookup",
                       this.ShardMap.StoreShardMap,
                       sk,
                       CacheStoreMappingUpdatePolicy.OverwriteExisting,
                       errorCategory,
                       true,
                       false))
            {
                gsmResult = op.Do();
            }

            stopwatch.Stop();

            Tracer.TraceVerbose(
                TraceSourceConstants.ComponentNames.BaseShardMapper,
                "Lookup",
                "Lookup key from GSM complete; Key type : {0}; Result: {1}; Duration: {2}",
                typeof(TKey),
                gsmResult.Result,
                stopwatch.Elapsed);

            // If we could not locate the mapping, we return null and do nothing here.
            if (gsmResult.Result != StoreResult.MappingNotFoundForKey)
            {
                return(gsmResult.StoreMappings.Select(sm => constructMapping(this.Manager, this.ShardMap, sm)).Single());
            }

            return(m);
        }
 /// <summary>
 /// Constructs request for obtaining all the mappings from GSM based on given shard and mappings.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager.</param>
 /// <param name="operationName">Operation being executed.</param>
 /// <param name="shardMap">Local shard map.</param>
 /// <param name="shard">Local shard.</param>
 /// <param name="range">Optional range to get mappings from.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <param name="cacheResults">Whether to cache the results of the operation.</param>
 /// <param name="ignoreFailure">Ignore shard map not found error.</param>
 internal GetMappingsByRangeGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, IStoreShard shard, ShardRange range, ShardManagementErrorCategory errorCategory, bool cacheResults, bool ignoreFailure) :
     base(shardMapManager.Credentials, shardMapManager.RetryPolicy, operationName)
 {
     _manager = shardMapManager;
     _shardMap = shardMap;
     _shard = shard;
     _range = range;
     _errorCategory = errorCategory;
     _cacheResults = cacheResults;
     _ignoreFailure = ignoreFailure;
 }
 /// <summary>
 /// Constructs request for obtaining all the mappings from GSM based on given shard and mappings.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager.</param>
 /// <param name="operationName">Operation being executed.</param>
 /// <param name="shardMap">Local shard map.</param>
 /// <param name="shard">Local shard.</param>
 /// <param name="range">Optional range to get mappings from.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <param name="cacheResults">Whether to cache the results of the operation.</param>
 /// <param name="ignoreFailure">Ignore shard map not found error.</param>
 internal GetMappingsByRangeGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, IStoreShard shard, ShardRange range, ShardManagementErrorCategory errorCategory, bool cacheResults, bool ignoreFailure) :
     base(shardMapManager.Credentials, shardMapManager.RetryPolicy, operationName)
 {
     _manager       = shardMapManager;
     _shardMap      = shardMap;
     _shard         = shard;
     _range         = range;
     _errorCategory = errorCategory;
     _cacheResults  = cacheResults;
     _ignoreFailure = ignoreFailure;
 }
        /// <summary>
        /// Constructs request to lock or unlock given mappings in GSM.
        /// </summary>
        /// <param name="shardMapManager">Shard map manager object.</param>
        /// <param name="operationName">Operation name, useful for diagnostics.</param>
        /// <param name="shardMap">Shard map to add.</param>
        /// <param name="mapping">Mapping to lock or unlock. Null means all mappings.</param>
        /// <param name="lockOwnerId">Lock owner.</param>
        /// <param name="lockOpType">Lock operation type.</param>
        /// <param name="errorCategory">Error category.</param>
        internal LockOrUnLockMappingsGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, IStoreMapping mapping, Guid lockOwnerId, LockOwnerIdOpType lockOpType, ShardManagementErrorCategory errorCategory) :
            base(shardMapManager.Credentials, shardMapManager.RetryPolicy, operationName)
        {
            _shardMapManager = shardMapManager;
            _shardMap = shardMap;
            _mapping = mapping;
            _lockOwnerId = lockOwnerId;
            _lockOpType = lockOpType;
            _errorCategory = errorCategory;

            Debug.Assert(mapping != null || (lockOpType == LockOwnerIdOpType.UnlockAllMappingsForId || lockOpType == LockOwnerIdOpType.UnlockAllMappings));
        }
Example #8
0
        /// <summary>
        /// Constructs request to lock or unlock given mappings in GSM.
        /// </summary>
        /// <param name="shardMapManager">Shard map manager object.</param>
        /// <param name="operationName">Operation name, useful for diagnostics.</param>
        /// <param name="shardMap">Shard map to add.</param>
        /// <param name="mapping">Mapping to lock or unlock. Null means all mappings.</param>
        /// <param name="lockOwnerId">Lock owner.</param>
        /// <param name="lockOpType">Lock operation type.</param>
        /// <param name="errorCategory">Error category.</param>
        internal LockOrUnLockMappingsGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, IStoreMapping mapping, Guid lockOwnerId, LockOwnerIdOpType lockOpType, ShardManagementErrorCategory errorCategory) :
            base(shardMapManager.Credentials, shardMapManager.RetryPolicy, operationName)
        {
            _shardMapManager = shardMapManager;
            _shardMap        = shardMap;
            _mapping         = mapping;
            _lockOwnerId     = lockOwnerId;
            _lockOpType      = lockOpType;
            _errorCategory   = errorCategory;

            Debug.Assert(mapping != null || (lockOpType == LockOwnerIdOpType.UnlockAllMappingsForId || lockOpType == LockOwnerIdOpType.UnlockAllMappings));
        }
 /// <summary>
 /// Constructs a global store exception object based on the given input parameters.
 /// </summary>
 /// <param name="category">Error category.</param>
 /// <param name="storeException">Underlying store exception.</param>
 /// <param name="operationName">Operation name.</param>
 /// <returns>
 /// ShardManagementException corresponding to the given store exception.
 /// </returns>
 internal static ShardManagementException GetStoreExceptionGlobal(
     ShardManagementErrorCategory category,
     StoreException storeException,
     string operationName)
 {
     return(new ShardManagementException(
                category,
                ShardManagementErrorCode.StorageOperationFailure,
                Errors._Store_SqlExceptionGlobal,
                storeException.InnerException != null ? storeException.InnerException.Message : storeException.Message,
                storeException,
                operationName));
 }
 /// <summary>
 /// Constructs request for obtaining mapping from GSM based on given key.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager.</param>
 /// <param name="operationName">Operation being executed.</param>
 /// <param name="shardMap">Local shard map.</param>
 /// <param name="mapping">Mapping whose Id will be used.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <returns>The store operation.</returns>
 public virtual IStoreOperationGlobal CreateFindMappingByIdGlobalOperation(
     ShardMapManager shardMapManager,
     string operationName,
     IStoreShardMap shardMap,
     IStoreMapping mapping,
     ShardManagementErrorCategory errorCategory)
 {
     return(new FindMappingByIdGlobalOperation(
                shardMapManager,
                operationName,
                shardMap,
                mapping,
                errorCategory));
 }
Example #11
0
 /// <summary>
 /// Given a key value, obtains a SqlConnection to the shard in the mapping
 /// that contains the key value.
 /// </summary>
 /// <typeparam name="TMapping">Mapping type.</typeparam>
 /// <typeparam name="TKey">Key type.</typeparam>
 /// <param name="key">Input key value.</param>
 /// <param name="constructMapping">Delegate to construct a mapping object.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <param name="connectionString">
 /// Connection string with credential information, the DataSource and Database are
 /// obtained from the results of the lookup operation for key.
 /// </param>
 /// <param name="options">Options for validation operations to perform on opened connection.</param>
 /// <returns>An opened SqlConnection.</returns>
 protected SqlConnection OpenConnectionForKey <TMapping, TKey>(
     TKey key,
     Func <ShardMapManager, ShardMap, IStoreMapping, TMapping> constructMapping,
     ShardManagementErrorCategory errorCategory,
     string connectionString,
     ConnectionOptions options = ConnectionOptions.Validate) where TMapping : class, IShardProvider
 {
     return(this.OpenConnectionForKey <TMapping, TKey>(
                key,
                constructMapping,
                errorCategory,
                connectionString,
                null,
                options));
 }
Example #12
0
        /// <summary>
        /// Asynchronously finds the mapping in store for OpenConnectionForKey operation.
        /// </summary>
        /// <param name="sk">Key to find.</param>
        /// <param name="policy">Cache update policy.</param>
        /// <param name="errorCategory">Error category.</param>
        /// <returns>Task with the Mapping corresponding to the given key if found as the result.</returns>
        private async Task <IStoreMapping> LookupMappingForOpenConnectionForKeyAsync(
            ShardKey sk,
            CacheStoreMappingUpdatePolicy policy,
            ShardManagementErrorCategory errorCategory)
        {
            IStoreResults gsmResult;

            Stopwatch stopwatch = Stopwatch.StartNew();

            using (IStoreOperationGlobal op = this.Manager.StoreOperationFactory.CreateFindMappingByKeyGlobalOperation(
                       this.Manager,
                       "Lookup",
                       this.ShardMap.StoreShardMap,
                       sk,
                       policy,
                       errorCategory,
                       true,
                       false))
            {
                gsmResult = await op.DoAsync().ConfigureAwait(false);
            }

            stopwatch.Stop();

            Tracer.TraceVerbose(
                TraceSourceConstants.ComponentNames.BaseShardMapper,
                "LookupMappingForOpenConnectionForKeyAsync",
                "Lookup key from GSM complete; Key type : {0}; Result: {1}; Duration: {2}",
                sk.DataType,
                gsmResult.Result,
                stopwatch.Elapsed);

            // If we could not locate the mapping, we throw.
            if (gsmResult.Result == StoreResult.MappingNotFoundForKey)
            {
                throw new ShardManagementException(
                          errorCategory,
                          ShardManagementErrorCode.MappingNotFoundForKey,
                          Errors._Store_ShardMapper_MappingNotFoundForKeyGlobal,
                          this.ShardMap.Name,
                          StoreOperationRequestBuilder.SpFindShardMappingByKeyGlobal,
                          "LookupMappingForOpenConnectionForKeyAsync");
            }
            else
            {
                return(gsmResult.StoreMappings.Single());
            }
        }
Example #13
0
        /// <summary>
        /// Gets all the mappings that exist within given range.
        /// </summary>
        /// <param name="range">Optional range value, if null, we cover everything.</param>
        /// <param name="shard">Optional shard parameter, if null, we cover all shards.</param>
        /// <param name="constructMapping">Delegate to construct a mapping object.</param>
        /// <param name="errorCategory">Category under which errors will be posted.</param>
        /// <param name="mappingType">Name of mapping type.</param>
        /// <returns>Read-only collection of mappings that overlap with given range.</returns>
        protected IReadOnlyList <TMapping> GetMappingsForRange <TMapping, TKey>(
            Range <TKey> range,
            Shard shard,
            Func <ShardMapManager, ShardMap, IStoreMapping, TMapping> constructMapping,
            ShardManagementErrorCategory errorCategory,
            string mappingType)
            where TMapping : class
        {
            ShardRange sr = null;

            if (shard != null)
            {
                ExceptionUtils.EnsureShardBelongsToShardMap(
                    this.Manager,
                    this.ShardMap,
                    shard,
                    "GetMappings",
                    mappingType);
            }

            if (range != null)
            {
                sr = new ShardRange(
                    new ShardKey(ShardKey.ShardKeyTypeFromType(typeof(TKey)), range.Low),
                    new ShardKey(ShardKey.ShardKeyTypeFromType(typeof(TKey)), range.HighIsMax ? null : (object)range.High));
            }

            IStoreResults result;

            using (IStoreOperationGlobal op = this.Manager.StoreOperationFactory.CreateGetMappingsByRangeGlobalOperation(
                       this.Manager,
                       "GetMappingsForRange",
                       this.ShardMap.StoreShardMap,
                       shard != null ? shard.StoreShard : null,
                       sr,
                       errorCategory,
                       true, // Always cache.
                       false))
            {
                result = op.Do();
            }

            return(result.StoreMappings
                   .Select(sm => constructMapping(this.Manager, this.ShardMap, sm))
                   .ToList()
                   .AsReadOnly());
        }
Example #14
0
        /// <summary>
        /// Gets the lock owner of a mapping.
        /// </summary>
        /// <param name="mapping">The mapping</param>
        /// <param name="errorCategory">Error category to use for the store operation</param>
        /// <returns>Lock owner for the mapping.</returns>
        internal Guid GetLockOwnerForMapping <TMapping>(TMapping mapping, ShardManagementErrorCategory errorCategory) where TMapping : class, IShardProvider, IMappingInfoProvider
        {
            this.EnsureMappingBelongsToShardMap <TMapping>(mapping, "LookupLockOwner", "mapping");

            IStoreResults result;

            using (IStoreOperationGlobal op = this.Manager.StoreOperationFactory.CreateFindMappingByIdGlobalOperation(
                       this.Manager,
                       "LookupLockOwner",
                       this.ShardMap.StoreShardMap,
                       mapping.StoreMapping,
                       errorCategory))
            {
                result = op.Do();
            }

            return(result.StoreMappings.Single().LockOwnerId);
        }
 /// <summary>
 /// Constructs request to lock or unlock given mappings in GSM.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager object.</param>
 /// <param name="operationName">Operation name, useful for diagnostics.</param>
 /// <param name="shardMap">Shard map to add.</param>
 /// <param name="mapping">Mapping to lock or unlock. Null means all mappings.</param>
 /// <param name="lockOwnerId">Lock owner.</param>
 /// <param name="lockOpType">Lock operation type.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <returns>The store operation.</returns>
 public virtual IStoreOperationGlobal CreateLockOrUnLockMappingsGlobalOperation(
     ShardMapManager shardMapManager,
     string operationName,
     IStoreShardMap shardMap,
     IStoreMapping mapping,
     Guid lockOwnerId,
     LockOwnerIdOpType lockOpType,
     ShardManagementErrorCategory errorCategory)
 {
     return(new LockOrUnLockMappingsGlobalOperation(
                shardMapManager,
                operationName,
                shardMap,
                mapping,
                lockOwnerId,
                lockOpType,
                errorCategory));
 }
Example #16
0
 /// <summary>
 /// Constructs request for obtaining mapping from GSM based on given key.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager.</param>
 /// <param name="operationName">Operation being executed.</param>
 /// <param name="shardMap">Local shard map.</param>
 /// <param name="key">Key for lookup operation.</param>
 /// <param name="policy">Policy for cache update.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <param name="cacheResults">Whether to cache the results of the operation.</param>
 /// <param name="ignoreFailure">Ignore shard map not found error.</param>
 protected internal FindMappingByKeyGlobalOperation(
     ShardMapManager shardMapManager,
     string operationName,
     IStoreShardMap shardMap,
     ShardKey key,
     CacheStoreMappingUpdatePolicy policy,
     ShardManagementErrorCategory errorCategory,
     bool cacheResults,
     bool ignoreFailure) :
     base(shardMapManager.Credentials, shardMapManager.RetryPolicy, operationName)
 {
     _manager       = shardMapManager;
     _shardMap      = shardMap;
     _key           = key;
     _policy        = policy;
     _errorCategory = errorCategory;
     _cacheResults  = cacheResults;
     _ignoreFailure = ignoreFailure;
 }
 /// <summary>
 /// Constructs request for obtaining mapping from GSM based on given key.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager.</param>
 /// <param name="operationName">Operation being executed.</param>
 /// <param name="shardMap">Local shard map.</param>
 /// <param name="key">Key for lookup operation.</param>
 /// <param name="policy">Policy for cache update.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <param name="cacheResults">Whether to cache the results of the operation.</param>
 /// <param name="ignoreFailure">Ignore shard map not found error.</param>
 protected internal FindMappingByKeyGlobalOperation(
     ShardMapManager shardMapManager,
     string operationName,
     IStoreShardMap shardMap,
     ShardKey key,
     CacheStoreMappingUpdatePolicy policy,
     ShardManagementErrorCategory errorCategory,
     bool cacheResults,
     bool ignoreFailure) :
     base(shardMapManager.Credentials, shardMapManager.RetryPolicy, operationName)
 {
     _manager = shardMapManager;
     _shardMap = shardMap;
     _key = key;
     _policy = policy;
     _errorCategory = errorCategory;
     _cacheResults = cacheResults;
     _ignoreFailure = ignoreFailure;
 }
Example #18
0
        /// <summary>
        /// Returns the proper ShardManagementException corresponding to given error code in
        /// <paramref name="result"/> for ShardMap operations.
        /// </summary>
        /// <param name="result">Operation result object.</param>
        /// <param name="shardMap">Shard map object.</param>
        /// <param name="location">Location of LSM operation.</param>
        /// <param name="errorCategory">Error category to use for raised errors.</param>
        /// <param name="operationName">Operation being performed.</param>
        /// <param name="storedProcName">Stored procedure being executed.</param>
        /// <returns>ShardManagementException to be raised.</returns>
        internal static ShardManagementException OnShardMapErrorLocal(
            IStoreResults result,
            IStoreShardMap shardMap,
            ShardLocation location,
            ShardManagementErrorCategory errorCategory,
            string operationName,
            string storedProcName)
        {
            switch (result.Result)
            {
            case StoreResult.UnableToKillSessions:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.MappingsKillConnectionFailure,
                           Errors._Store_ShardMapper_UnableToKillSessions,
                           location,
                           shardMap.Name,
                           operationName,
                           storedProcName,
                           location));

            case StoreResult.StoreVersionMismatch:
            case StoreResult.MissingParametersForStoredProcedure:
            case StoreResult.ShardDoesNotExist:
                // ShardDoesNotExist on local shard map can only occur in Recovery scenario.
                // For normal UpdateShard operation, we will get this error from GSM operation first.
                return(new ShardManagementException(
                           ShardManagementErrorCategory.Recovery,
                           ShardManagementErrorCode.ShardDoesNotExist,
                           Errors._Store_Validate_ShardDoesNotExist,
                           location,
                           shardMap.Name,
                           operationName,
                           storedProcName));

            default:
                return(StoreOperationErrorHandler.OnCommonErrorLocal(
                           result,
                           location,
                           operationName,
                           storedProcName));
            }
        }
 /// <summary>
 /// Constructs request for obtaining mapping from GSM based on given key.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager.</param>
 /// <param name="operationName">Operation being executed.</param>
 /// <param name="shardMap">Local shard map.</param>
 /// <param name="key">Key for lookup operation.</param>
 /// <param name="policy">Policy for cache update.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <param name="cacheResults">Whether to cache the results of the operation.</param>
 /// <param name="ignoreFailure">Ignore shard map not found error.</param>
 /// <returns>The store operation.</returns>
 public virtual IStoreOperationGlobal CreateFindMappingByKeyGlobalOperation(
     ShardMapManager shardMapManager,
     string operationName,
     IStoreShardMap shardMap,
     ShardKey key,
     CacheStoreMappingUpdatePolicy policy,
     ShardManagementErrorCategory errorCategory,
     bool cacheResults,
     bool ignoreFailure)
 {
     return(new FindMappingByKeyGlobalOperation(
                shardMapManager,
                operationName,
                shardMap,
                key,
                policy,
                errorCategory,
                cacheResults,
                ignoreFailure));
 }
 /// <summary>
 /// Constructs request for obtaining all the mappings from GSM based on given shard and mappings.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager.</param>
 /// <param name="operationName">Operation being executed.</param>
 /// <param name="shardMap">Local shard map.</param>
 /// <param name="shard">Local shard.</param>
 /// <param name="range">Optional range to get mappings from.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <param name="cacheResults">Whether to cache the results of the operation.</param>
 /// <param name="ignoreFailure">Ignore shard map not found error.</param>
 /// <returns>The store operation.</returns>
 public virtual IStoreOperationGlobal CreateGetMappingsByRangeGlobalOperation(
     ShardMapManager shardMapManager,
     string operationName,
     IStoreShardMap shardMap,
     IStoreShard shard,
     ShardRange range,
     ShardManagementErrorCategory errorCategory,
     bool cacheResults,
     bool ignoreFailure)
 {
     return(new GetMappingsByRangeGlobalOperation(
                shardMapManager,
                operationName,
                shardMap,
                shard,
                range,
                errorCategory,
                cacheResults,
                ignoreFailure));
 }
Example #21
0
        /// <summary>
        /// Creates request to add shard to given shard map.
        /// </summary>
        /// <param name="shardMapManager">Shard map manager object.</param>
        /// <param name="operationId">Operation id.</param>
        /// <param name="undoStartState">State from which Undo operation starts.</param>
        /// <param name="operationCode">Store operation code.</param>
        /// <param name="shardMap">Shard map for which to update mapping.</param>
        /// <param name="mappingSource">Mapping to update.</param>
        /// <param name="mappingTarget">Updated mapping.</param>
        /// <param name="patternForKill">Pattern for kill commands.</param>
        /// <param name="lockOwnerId">Id of lock owner.</param>
        /// <param name="originalShardVersionRemoves">Original shard version for removes.</param>
        /// <param name="originalShardVersionAdds">Original shard version for adds.</param>
        /// <param name="killConnection">Whether to kill open connections.</param>
        internal UpdateMappingOperation(
            ShardMapManager shardMapManager,
            Guid operationId,
            StoreOperationState undoStartState,
            StoreOperationCode operationCode,
            IStoreShardMap shardMap,
            IStoreMapping mappingSource,
            IStoreMapping mappingTarget,
            string patternForKill,
            Guid lockOwnerId,
            Guid originalShardVersionRemoves,
            Guid originalShardVersionAdds,
            bool killConnection) :
            base(
                shardMapManager,
                operationId,
                undoStartState,
                operationCode,
                originalShardVersionRemoves,
                originalShardVersionAdds)
        {
            _shardMap      = shardMap;
            _mappingSource = mappingSource;
            _mappingTarget = mappingTarget;
            _lockOwnerId   = lockOwnerId;

            _errorCategory = (operationCode == StoreOperationCode.UpdateRangeMapping ||
                              operationCode == StoreOperationCode.UpdateRangeMappingWithOffline) ?
                             ShardManagementErrorCategory.RangeShardMap :
                             ShardManagementErrorCategory.ListShardMap;

            _updateLocation = _mappingSource.StoreShard.Id != _mappingTarget.StoreShard.Id;

            _fromOnlineToOffline = operationCode == StoreOperationCode.UpdatePointMappingWithOffline ||
                                   operationCode == StoreOperationCode.UpdateRangeMappingWithOffline;

            _patternForKill = patternForKill;

            _killConnection = killConnection;
        }
 /// <summary>
 /// Creates request to add shard to given shard map.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager object.</param>
 /// <param name="operationId">Operation id.</param>
 /// <param name="undoStartState">State from which Undo operation starts.</param>
 /// <param name="operationCode">Store operation code.</param>
 /// <param name="shardMap">Shard map for which to add mapping.</param>
 /// <param name="mapping">Mapping to add.</param>
 /// <param name="originalShardVersionAdds">Original shard version.</param>
 internal AddMappingOperation(
     ShardMapManager shardMapManager,
     Guid operationId,
     StoreOperationState undoStartState,
     StoreOperationCode operationCode,
     IStoreShardMap shardMap,
     IStoreMapping mapping,
     Guid originalShardVersionAdds) :
     base(
         shardMapManager,
         operationId,
         undoStartState,
         operationCode,
         default(Guid),
         originalShardVersionAdds)
 {
     _shardMap      = shardMap;
     _mapping       = mapping;
     _errorCategory = operationCode == StoreOperationCode.AddRangeMapping ?
                      ShardManagementErrorCategory.RangeShardMap :
                      ShardManagementErrorCategory.ListShardMap;
 }
 /// <summary>
 /// Creates request to add shard to given shard map.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager object.</param>
 /// <param name="operationId">Operation id.</param>
 /// <param name="undoStartState">State from which Undo operation starts.</param>
 /// <param name="operationCode">Store operation code.</param>
 /// <param name="shardMap">Shard map for which to add mapping.</param>
 /// <param name="mapping">Mapping to add.</param>
 /// <param name="originalShardVersionAdds">Original shard version.</param>
 internal AddMappingOperation(
     ShardMapManager shardMapManager,
     Guid operationId,
     StoreOperationState undoStartState,
     StoreOperationCode operationCode,
     IStoreShardMap shardMap,
     IStoreMapping mapping,
     Guid originalShardVersionAdds) :
     base(
     shardMapManager,
     operationId,
     undoStartState,
     operationCode,
     default(Guid),
     originalShardVersionAdds)
 {
     _shardMap = shardMap;
     _mapping = mapping;
     _errorCategory = operationCode == StoreOperationCode.AddRangeMapping ?
         ShardManagementErrorCategory.RangeShardMap :
         ShardManagementErrorCategory.ListShardMap;
 }
Example #24
0
        /// <summary>
        /// Returns the proper ShardManagementException corresponding to given error code in
        /// <paramref name="result"/> for ShardMap operations.
        /// </summary>
        /// <param name="result">Operation result object.</param>
        /// <param name="shardMap">Shard map object.</param>
        /// <param name="shard">Shard object.</param>
        /// <param name="errorCategory">Error category to use for raised errors.</param>
        /// <param name="operationName">Operation being performed.</param>
        /// <param name="storedProcName">Stored procedure being executed.</param>
        /// <returns>ShardManagementException to be raised.</returns>
        internal static ShardManagementException OnRecoveryErrorGlobal(
            IStoreResults result,
            IStoreShardMap shardMap,
            IStoreShard shard,
            ShardManagementErrorCategory errorCategory,
            string operationName,
            string storedProcName)
        {
            switch (result.Result)
            {
            case StoreResult.ShardLocationExists:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.ShardLocationAlreadyExists,
                           Errors._Store_Shard_LocationAlreadyExistsGlobal,
                           shard.Location,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.ShardMapExists:
                Debug.Assert(shardMap != null);
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.ShardMapAlreadyExists,
                           Errors._Store_ShardMap_AlreadyExistsGlobal,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.StoreVersionMismatch:
            case StoreResult.MissingParametersForStoredProcedure:
            default:
                return(StoreOperationErrorHandler.OnCommonErrorGlobal(
                           result,
                           operationName,
                           storedProcName));
            }
        }
 /// <summary>
 /// Creates request to add shard to given shard map.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager object.</param>
 /// <param name="operationId">Operation id.</param>
 /// <param name="undoStartState">State from which Undo operation starts.</param>
 /// <param name="operationCode">Store operation code.</param>
 /// <param name="shardMap">Shard map from which to remove mapping.</param>
 /// <param name="mapping">Mapping to add.</param>
 /// <param name="lockOwnerId">Id of lock owner.</param>
 /// <param name="originalShardVersionRemoves">Original shard version.</param>
 internal RemoveMappingOperation(
     ShardMapManager shardMapManager,
     Guid operationId,
     StoreOperationState undoStartState,
     StoreOperationCode operationCode,
     IStoreShardMap shardMap,
     IStoreMapping mapping,
     Guid lockOwnerId,
     Guid originalShardVersionRemoves) :
     base(
         shardMapManager,
         operationId,
         undoStartState,
         operationCode,
         originalShardVersionRemoves,
         default(Guid))
 {
     _shardMap      = shardMap;
     _mapping       = mapping;
     _lockOwnerId   = lockOwnerId;
     _errorCategory = operationCode == StoreOperationCode.RemoveRangeMapping ?
                      ShardManagementErrorCategory.RangeShardMap :
                      ShardManagementErrorCategory.ListShardMap;
 }
 /// <summary>
 /// Constructs request for obtaining all the mappings from GSM based on given shard and mappings.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager.</param>
 /// <param name="operationName">Operation being executed.</param>
 /// <param name="shardMap">Local shard map.</param>
 /// <param name="shard">Local shard.</param>
 /// <param name="range">Optional range to get mappings from.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <param name="cacheResults">Whether to cache the results of the operation.</param>
 /// <param name="ignoreFailure">Ignore shard map not found error.</param>
 /// <returns>The store operation.</returns>
 public virtual IStoreOperationGlobal CreateGetMappingsByRangeGlobalOperation(
     ShardMapManager shardMapManager,
     string operationName,
     IStoreShardMap shardMap,
     IStoreShard shard,
     ShardRange range,
     ShardManagementErrorCategory errorCategory,
     bool cacheResults,
     bool ignoreFailure)
 {
     return new GetMappingsByRangeGlobalOperation(
         shardMapManager,
         operationName,
         shardMap,
         shard,
         range,
         errorCategory,
         cacheResults,
         ignoreFailure);
 }
 /// <summary>
 /// Initializes a new instance
 /// </summary>
 public StubFindMappingByKeyGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, ShardKey key, CacheStoreMappingUpdatePolicy policy, ShardManagementErrorCategory errorCategory, bool cacheResults, bool ignoreFailure)
     : base(shardMapManager, operationName, shardMap, key, policy, errorCategory, cacheResults, ignoreFailure)
 {
     this.InitializeStub();
 }
Example #28
0
 /// <summary>
 /// Initializes a new instance
 /// </summary>
 public StubFindMappingByKeyGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, ShardKey key, CacheStoreMappingUpdatePolicy policy, ShardManagementErrorCategory errorCategory, bool cacheResults, bool ignoreFailure)
     : base(shardMapManager, operationName, shardMap, key, policy, errorCategory, cacheResults, ignoreFailure)
 {
     this.InitializeStub();
 }
 /// <summary>
 /// Sets the stub of StoreOperationFactory.CreateFindMappingByKeyGlobalOperation(ShardMapManager shardMapManager, String operationName, IStoreShardMap shardMap, ShardKey key, CacheStoreMappingUpdatePolicy policy, ShardManagementErrorCategory errorCategory, Boolean cacheResults, Boolean ignoreFailure)
 /// </summary>
 public override IStoreOperationGlobal CreateFindMappingByKeyGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, ShardKey key, CacheStoreMappingUpdatePolicy policy, ShardManagementErrorCategory errorCategory, bool cacheResults, bool ignoreFailure)
 {
     Func<ShardMapManager, string, IStoreShardMap, ShardKey, CacheStoreMappingUpdatePolicy, ShardManagementErrorCategory, bool, bool, IStoreOperationGlobal> func1 = this.CreateFindMappingByKeyGlobalOperationShardMapManagerStringIStoreShardMapShardKeyCacheStoreMappingUpdatePolicyShardManagementErrorCategoryBooleanBoolean;
     if (func1 != null)
         return func1(shardMapManager, operationName, shardMap, key, policy, errorCategory, cacheResults, ignoreFailure);
     if (this.___callBase)
         return base.CreateFindMappingByKeyGlobalOperation(shardMapManager, operationName, shardMap, key, policy, errorCategory, cacheResults, ignoreFailure);
     return this.InstanceBehavior.Result<StubStoreOperationFactory, IStoreOperationGlobal>(this, "CreateFindMappingByKeyGlobalOperation");
 }
Example #30
0
        /// <summary>
        /// Given a key value, asynchronously obtains a SqlConnection to the shard in the mapping
        /// that contains the key value.
        /// </summary>
        /// <typeparam name="TMapping">Mapping type.</typeparam>
        /// <typeparam name="TKey">Key type.</typeparam>
        /// <param name="key">Input key value.</param>
        /// <param name="constructMapping">Delegate to construct a mapping object.</param>
        /// <param name="errorCategory">Error category.</param>
        /// <param name="connectionString">
        /// Connection string with credential information, the DataSource and Database are
        /// obtained from the results of the lookup operation for key.
        /// </param>
        /// <param name="secureCredential">Secure SQL Credential.</param>
        /// <param name="options">Options for validation operations to perform on opened connection.</param>
        /// <returns>A task encapsulating an opened SqlConnection as the result.</returns>
        protected async Task <SqlConnection> OpenConnectionForKeyAsync <TMapping, TKey>(
            TKey key,
            Func <ShardMapManager, ShardMap, IStoreMapping, TMapping> constructMapping,
            ShardManagementErrorCategory errorCategory,
            string connectionString,
            SqlCredential secureCredential,
            ConnectionOptions options = ConnectionOptions.Validate) where TMapping : class, IShardProvider
        {
            ShardKey sk = new ShardKey(ShardKey.ShardKeyTypeFromType(typeof(TKey)), key);

            // Try to find the mapping within the cache.
            ICacheStoreMapping csm = this.Manager.Cache.LookupMappingByKey(this.ShardMap.StoreShardMap, sk);

            IStoreMapping sm;

            if (csm != null)
            {
                sm = csm.Mapping;
            }
            else
            {
                sm = await this.LookupMappingForOpenConnectionForKeyAsync(
                    sk,
                    CacheStoreMappingUpdatePolicy.OverwriteExisting,
                    errorCategory).ConfigureAwait(false);
            }

            SqlConnection result;
            bool          lookupMappingOnEx = false;
            CacheStoreMappingUpdatePolicy cacheUpdatePolicyOnEx = CacheStoreMappingUpdatePolicy.OverwriteExisting;

            try
            {
                // Initially attempt to connect based on lookup results from either cache or GSM.
                result = await this.ShardMap.OpenConnectionAsync(
                    constructMapping(this.Manager, this.ShardMap, sm),
                    connectionString,
                    secureCredential,
                    options).ConfigureAwait(false);

                csm.ResetTimeToLiveIfNecessary();

                return(result);
            }
            catch (ShardManagementException smme)
            {
                // If we hit a validation failure due to stale version of mapping, we will perform one more attempt.
                if (((options & ConnectionOptions.Validate) == ConnectionOptions.Validate) &&
                    smme.ErrorCategory == ShardManagementErrorCategory.Validation &&
                    smme.ErrorCode == ShardManagementErrorCode.MappingDoesNotExist)
                {
                    // Assumption here is that this time the attempt should succeed since the cache entry
                    // has already been either evicted, or updated based on latest data from the server.
                    lookupMappingOnEx     = true;
                    cacheUpdatePolicyOnEx = CacheStoreMappingUpdatePolicy.OverwriteExisting;
                }
                else
                {
                    // The error was not due to validation but something else e.g.
                    // 1) Shard map does not exist
                    // 2) Mapping could not be found.
                    throw;
                }
            }
            catch (SqlException)
            {
                // We failed to connect. If we were trying to connect from an entry in cache and mapping expired in cache.
                if (csm != null && csm.HasTimeToLiveExpired())
                {
                    using (IdLock _idLock = new IdLock(csm.Mapping.StoreShard.Id))
                    {
                        // Similar to DCL pattern, we need to refresh the mapping again to see if we still need to go to the store
                        // to lookup the mapping after acquiring the shard lock. It might be the case that a fresh version has already
                        // been obtained by some other thread.
                        csm = this.Manager.Cache.LookupMappingByKey(this.ShardMap.StoreShardMap, sk);

                        // Only go to store if the mapping is stale even after refresh.
                        if (csm == null || csm.HasTimeToLiveExpired())
                        {
                            // Refresh the mapping in cache. And try to open the connection after refresh.
                            lookupMappingOnEx     = true;
                            cacheUpdatePolicyOnEx = CacheStoreMappingUpdatePolicy.UpdateTimeToLive;
                        }
                        else
                        {
                            sm = csm.Mapping;
                        }
                    }
                }
                else
                {
                    // Either:
                    // 1) The mapping is still within the TTL. No refresh.
                    // 2) Mapping was not in cache, we originally did a lookup for mapping in GSM and even then could not connect.
                    throw;
                }
            }

            if (lookupMappingOnEx)
            {
                sm = await this.LookupMappingForOpenConnectionForKeyAsync(
                    sk,
                    cacheUpdatePolicyOnEx,
                    errorCategory).ConfigureAwait(false);
            }

            // One last attempt to open the connection after a cache refresh
            result = await this.ShardMap.OpenConnectionAsync(
                constructMapping(this.Manager, this.ShardMap, sm),
                connectionString,
                secureCredential,
                options).ConfigureAwait(false);

            // Reset TTL on successful connection.
            csm.ResetTimeToLiveIfNecessary();

            return(result);
        }
Example #31
0
        /// <summary>
        /// Returns the proper ShardManagementException corresponding to given error code in
        /// <paramref name="result"/> for ShardMap operations.
        /// </summary>
        /// <param name="result">Operation result object.</param>
        /// <param name="shardMap">Shard map object.</param>
        /// <param name="shard">Shard object.</param>
        /// <param name="errorCategory">Error category to use for raised errors.</param>
        /// <param name="operationName">Operation being performed.</param>
        /// <param name="storedProcName">Stored procedure being executed.</param>
        /// <returns>ShardManagementException to be raised.</returns>
        internal static ShardManagementException OnShardMapErrorGlobal(
            IStoreResults result,
            IStoreShardMap shardMap,
            IStoreShard shard,
            ShardManagementErrorCategory errorCategory,
            string operationName,
            string storedProcName)
        {
            switch (result.Result)
            {
            case StoreResult.ShardMapDoesNotExist:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.ShardMapDoesNotExist,
                           Errors._Store_ShardMap_DoesNotExistGlobal,
                           shardMap.Name,
                           storedProcName,
                           operationName,
                           shard != null ? shard.Location.ToString() : "*"));

            case StoreResult.ShardExists:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.ShardAlreadyExists,
                           Errors._Store_Shard_AlreadyExistsGlobal,
                           shard.Location,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.ShardLocationExists:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.ShardLocationAlreadyExists,
                           Errors._Store_Shard_LocationAlreadyExistsGlobal,
                           shard.Location,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.ShardDoesNotExist:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.ShardDoesNotExist,
                           Errors._Store_Shard_DoesNotExistGlobal,
                           shard.Location,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.ShardVersionMismatch:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.ShardVersionMismatch,
                           Errors._Store_Shard_VersionMismatchGlobal,
                           shard.Location,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.ShardHasMappings:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.ShardHasMappings,
                           Errors._Store_Shard_HasMappingsGlobal,
                           shard.Location,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.StoreVersionMismatch:
            case StoreResult.MissingParametersForStoredProcedure:
            default:
                return(StoreOperationErrorHandler.OnCommonErrorGlobal(
                           result,
                           operationName,
                           storedProcName));
            }
        }
        /// <summary>
        /// Returns the proper ShardManagementException corresponding to given error code in 
        /// <paramref name="result"/> for ShardMap operations.
        /// </summary>
        /// <param name="result">Operation result object.</param>
        /// <param name="shardMap">Shard map object.</param>
        /// <param name="shard">Shard object.</param>
        /// <param name="errorCategory">Error category to use for raised errors.</param>
        /// <param name="operationName">Operation being performed.</param>
        /// <param name="storedProcName">Stored procedure being executed.</param>
        /// <returns>ShardManagementException to be raised.</returns>
        internal static ShardManagementException OnRecoveryErrorGlobal(
            IStoreResults result,
            IStoreShardMap shardMap,
            IStoreShard shard,
            ShardManagementErrorCategory errorCategory,
            string operationName,
            string storedProcName)
        {
            switch (result.Result)
            {
                case StoreResult.ShardLocationExists:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.ShardLocationAlreadyExists,
                        Errors._Store_Shard_LocationAlreadyExistsGlobal,
                        shard.Location,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.ShardMapExists:
                    Debug.Assert(shardMap != null);
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.ShardMapAlreadyExists,
                        Errors._Store_ShardMap_AlreadyExistsGlobal,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.StoreVersionMismatch:
                case StoreResult.MissingParametersForStoredProcedure:
                default:
                    return StoreOperationErrorHandler.OnCommonErrorGlobal(
                        result,
                        operationName,
                        storedProcName);
            }
        }
        /// <summary>
        /// Returns the proper ShardManagementException corresponding to given error code in 
        /// <paramref name="result"/> for ShardMap operations.
        /// </summary>
        /// <param name="result">Operation result object.</param>
        /// <param name="shardMap">Shard map object.</param>
        /// <param name="location">Location of operation.</param>
        /// <param name="errorCategory">Error category to use for raised errors.</param>
        /// <param name="operationName">Operation being performed.</param>
        /// <param name="storedProcName">Stored procedure being executed.</param>
        /// <returns>ShardManagementException to be raised.</returns>
        internal static ShardManagementException OnRecoveryErrorLocal(
            IStoreResults result,
            IStoreShardMap shardMap,
            ShardLocation location,
            ShardManagementErrorCategory errorCategory,
            string operationName,
            string storedProcName)
        {
            switch (result.Result)
            {
                case StoreResult.ShardMapDoesNotExist:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.ShardMapDoesNotExist,
                        Errors._Store_ShardMap_DoesNotExistLocal,
                        shardMap.Name,
                        location,
                        storedProcName,
                        operationName);

                case StoreResult.StoreVersionMismatch:
                case StoreResult.MissingParametersForStoredProcedure:
                default:
                    return StoreOperationErrorHandler.OnCommonErrorLocal(
                        result,
                        location,
                        operationName,
                        storedProcName);
            }
        }
        /// <summary>
        /// Returns the proper ShardManagementException corresponding to given error code in 
        /// <paramref name="result"/> for ShardMap operations.
        /// </summary>
        /// <param name="result">Operation result object.</param>
        /// <param name="shardMap">Shard map object.</param>
        /// <param name="shard">Shard object.</param>
        /// <param name="errorCategory">Error category to use for raised errors.</param>
        /// <param name="operationName">Operation being performed.</param>
        /// <param name="storedProcName">Stored procedure being executed.</param>
        /// <returns>ShardManagementException to be raised.</returns>
        internal static ShardManagementException OnShardMapErrorGlobal(
            IStoreResults result,
            IStoreShardMap shardMap,
            IStoreShard shard,
            ShardManagementErrorCategory errorCategory,
            string operationName,
            string storedProcName)
        {
            switch (result.Result)
            {
                case StoreResult.ShardMapDoesNotExist:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.ShardMapDoesNotExist,
                        Errors._Store_ShardMap_DoesNotExistGlobal,
                        shardMap.Name,
                        storedProcName,
                        operationName,
                        shard != null ? shard.Location.ToString() : "*");

                case StoreResult.ShardExists:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.ShardAlreadyExists,
                        Errors._Store_Shard_AlreadyExistsGlobal,
                        shard.Location,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.ShardLocationExists:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.ShardLocationAlreadyExists,
                        Errors._Store_Shard_LocationAlreadyExistsGlobal,
                        shard.Location,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.ShardDoesNotExist:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.ShardDoesNotExist,
                        Errors._Store_Shard_DoesNotExistGlobal,
                        shard.Location,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.ShardVersionMismatch:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.ShardVersionMismatch,
                        Errors._Store_Shard_VersionMismatchGlobal,
                        shard.Location,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.ShardHasMappings:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.ShardHasMappings,
                        Errors._Store_Shard_HasMappingsGlobal,
                        shard.Location,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.StoreVersionMismatch:
                case StoreResult.MissingParametersForStoredProcedure:
                default:
                    return StoreOperationErrorHandler.OnCommonErrorGlobal(
                        result,
                        operationName,
                        storedProcName);
            }
        }
 /// <summary>
 /// Constructs request for obtaining mapping from GSM based on given key.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager.</param>
 /// <param name="operationName">Operation being executed.</param>
 /// <param name="shardMap">Local shard map.</param>
 /// <param name="mapping">Mapping whose Id will be used.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <returns>The store operation.</returns>
 public virtual IStoreOperationGlobal CreateFindMappingByIdGlobalOperation(
     ShardMapManager shardMapManager,
     string operationName,
     IStoreShardMap shardMap,
     IStoreMapping mapping,
     ShardManagementErrorCategory errorCategory)
 {
     return new FindMappingByIdGlobalOperation(
         shardMapManager,
         operationName,
         shardMap,
         mapping,
         errorCategory);
 }
 /// <summary>
 /// Creates request to add shard to given shard map.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager object.</param>
 /// <param name="operationId">Operation id.</param>
 /// <param name="undoStartState">State from which Undo operation starts.</param>
 /// <param name="operationCode">Store operation code.</param>
 /// <param name="shardMap">Shard map from which to remove mapping.</param>
 /// <param name="mapping">Mapping to add.</param>
 /// <param name="lockOwnerId">Id of lock owner.</param>
 /// <param name="originalShardVersionRemoves">Original shard version.</param>
 internal RemoveMappingOperation(
     ShardMapManager shardMapManager,
     Guid operationId,
     StoreOperationState undoStartState,
     StoreOperationCode operationCode,
     IStoreShardMap shardMap,
     IStoreMapping mapping,
     Guid lockOwnerId,
     Guid originalShardVersionRemoves) :
     base(
     shardMapManager,
     operationId,
     undoStartState,
     operationCode,
     originalShardVersionRemoves,
     default(Guid))
 {
     _shardMap = shardMap;
     _mapping = mapping;
     _lockOwnerId = lockOwnerId;
     _errorCategory = operationCode == StoreOperationCode.RemoveRangeMapping ?
         ShardManagementErrorCategory.RangeShardMap :
         ShardManagementErrorCategory.ListShardMap;
 }
 /// <summary>
 /// Constructs request to lock or unlock given mappings in GSM.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager object.</param>
 /// <param name="operationName">Operation name, useful for diagnostics.</param>
 /// <param name="shardMap">Shard map to add.</param>
 /// <param name="mapping">Mapping to lock or unlock. Null means all mappings.</param>
 /// <param name="lockOwnerId">Lock owner.</param>
 /// <param name="lockOpType">Lock operation type.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <returns>The store operation.</returns>
 public virtual IStoreOperationGlobal CreateLockOrUnLockMappingsGlobalOperation(
     ShardMapManager shardMapManager,
     string operationName,
     IStoreShardMap shardMap,
     IStoreMapping mapping,
     Guid lockOwnerId,
     LockOwnerIdOpType lockOpType,
     ShardManagementErrorCategory errorCategory)
 {
     return new LockOrUnLockMappingsGlobalOperation(
         shardMapManager,
         operationName,
         shardMap,
         mapping,
         lockOwnerId,
         lockOpType,
         errorCategory);
 }
 /// <summary>
 /// Initializes a new instance with a specified error message and a reference to the inner exception
 /// that is the cause of this exception.
 /// </summary>
 /// <param name="category">Category of error.</param>
 /// <param name="code">Error code.</param>
 /// <param name="message">A message that describes the error</param>
 /// <param name="inner">The exception that is the cause of the current exception</param>
 internal ShardManagementException(ShardManagementErrorCategory category, ShardManagementErrorCode code, string message, Exception inner)
     : base(message, inner)
 {
     this.ErrorCategory = category;
     this.ErrorCode     = code;
 }
Example #39
0
        /// <summary>
        /// Looks up the key value and returns the corresponding mapping.
        /// </summary>
        /// <typeparam name="TMapping">Mapping type.</typeparam>
        /// <typeparam name="TKey">Key type.</typeparam>
        /// <param name="key">Input key value.</param>
        /// <param name="lookupOptions">Whether to use cache and/or storage for lookups.</param>
        /// <param name="constructMapping">Delegate to construct a mapping object.</param>
        /// <param name="errorCategory">Category under which errors must be thrown.</param>
        /// <returns>Mapping that contains the key value.</returns>
        protected TMapping Lookup <TMapping, TKey>(
            TKey key,
            LookupOptions lookupOptions,
            Func <ShardMapManager, ShardMap, IStoreMapping, TMapping> constructMapping,
            ShardManagementErrorCategory errorCategory)
            where TMapping : class, IShardProvider
        {
            ShardKey sk = new ShardKey(ShardKey.ShardKeyTypeFromType(typeof(TKey)), key);

            // Try to lookup in cache. Note the interation with cache removal later in this method.
            bool tryLookupInCache = lookupOptions.HasFlag(LookupOptions.LookupInCache);

            if (tryLookupInCache)
            {
                ICacheStoreMapping cachedMapping = this.Manager.Cache.LookupMappingByKey(this.ShardMap.StoreShardMap, sk);
                if (cachedMapping != null)
                {
                    return(constructMapping(this.Manager, this.ShardMap, cachedMapping.Mapping));
                }
            }

            // Cache-miss (or didn't use cache), find mapping for given key in GSM.
            if (lookupOptions.HasFlag(LookupOptions.LookupInStore))
            {
                IStoreResults gsmResult;

                Stopwatch stopwatch = Stopwatch.StartNew();

                using (IStoreOperationGlobal op = this.Manager.StoreOperationFactory.CreateFindMappingByKeyGlobalOperation(
                           this.Manager,
                           "Lookup",
                           this.ShardMap.StoreShardMap,
                           sk,
                           CacheStoreMappingUpdatePolicy.OverwriteExisting,
                           errorCategory,
                           true,
                           false))
                {
                    gsmResult = op.Do();
                }

                stopwatch.Stop();

                Tracer.TraceVerbose(
                    TraceSourceConstants.ComponentNames.BaseShardMapper,
                    "Lookup",
                    "Lookup key from GSM complete; Key type : {0}; Result: {1}; Duration: {2}",
                    typeof(TKey),
                    gsmResult.Result,
                    stopwatch.Elapsed);

                // If mapping was found, return it.
                if (gsmResult.Result != StoreResult.MappingNotFoundForKey)
                {
                    return(gsmResult.StoreMappings.Select(sm => constructMapping(this.Manager, this.ShardMap, sm)).Single());
                }

                // If we could not locate the mapping, then we might need to update the cache to remove it.
                //
                // Only do this if we didn't already try to return the mapping from the cache (since, if it was found,
                // we would have already returned it earlier).
                if (!tryLookupInCache)
                {
                    ICacheStoreMapping cachedMapping =
                        this.Manager.Cache.LookupMappingByKey(this.ShardMap.StoreShardMap, sk);
                    if (cachedMapping != null)
                    {
                        this.Manager.Cache.DeleteMapping(cachedMapping.Mapping);
                    }
                }
            }

            // Mapping not found - return null
            return(null);
        }
 /// <summary>
 /// Initializes a new instance with a specified formatted error message and a reference to the
 /// inner exception that is the cause of this exception.
 /// </summary>
 /// <param name="category">Category of error.</param>
 /// <param name="code">Error code.</param>
 /// <param name="format">The format message that describes the error</param>
 /// <param name="inner">The exception that is the cause of the current exception</param>
 /// <param name="args">The arguments to the format string</param>
 internal ShardManagementException(ShardManagementErrorCategory category, ShardManagementErrorCode code, string format, Exception inner, params object[] args)
     : base(string.Format(CultureInfo.InvariantCulture, format, args), inner)
 {
     this.ErrorCategory = category;
     this.ErrorCode     = code;
 }
 /// <summary>
 /// Sets the stub of StoreOperationFactory.CreateLockOrUnLockMappingsGlobalOperation(ShardMapManager shardMapManager, String operationName, IStoreShardMap shardMap, IStoreMapping mapping, Guid lockOwnerId, LockOwnerIdOpType lockOpType, ShardManagementErrorCategory errorCategory)
 /// </summary>
 public override IStoreOperationGlobal CreateLockOrUnLockMappingsGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, IStoreMapping mapping, Guid lockOwnerId, LockOwnerIdOpType lockOpType, ShardManagementErrorCategory errorCategory)
 {
     Func<ShardMapManager, string, IStoreShardMap, IStoreMapping, Guid, LockOwnerIdOpType, ShardManagementErrorCategory, IStoreOperationGlobal> func1 = this.CreateLockOrUnLockMappingsGlobalOperationShardMapManagerStringIStoreShardMapIStoreMappingGuidLockOwnerIdOpTypeShardManagementErrorCategory;
     if (func1 != null)
         return func1(shardMapManager, operationName, shardMap, mapping, lockOwnerId, lockOpType, errorCategory);
     if (this.___callBase)
         return base.CreateLockOrUnLockMappingsGlobalOperation(shardMapManager, operationName, shardMap, mapping, lockOwnerId, lockOpType, errorCategory);
     return this.InstanceBehavior.Result<StubStoreOperationFactory, IStoreOperationGlobal>(this, "CreateLockOrUnLockMappingsGlobalOperation");
 }
        /// <summary>
        /// Returns the proper ShardManagementException corresponding to given error code in 
        /// <paramref name="result"/> for ShardMapper operations.
        /// </summary>
        /// <param name="result">Operation result object.</param>
        /// <param name="shardMap">Shard map object.</param>
        /// <param name="shard">Shard object.</param>
        /// <param name="errorCategory">Error category to use for raised errors.</param>
        /// <param name="operationName">Operation being performed.</param>
        /// <param name="storedProcName">Stored procedure being executed.</param>
        /// <returns>ShardManagementException to be raised.</returns>
        internal static ShardManagementException OnShardMapperErrorGlobal(
            IStoreResults result,
            IStoreShardMap shardMap,
            IStoreShard shard,
            ShardManagementErrorCategory errorCategory,
            string operationName,
            string storedProcName)
        {
            switch (result.Result)
            {
                case StoreResult.ShardMapDoesNotExist:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.ShardMapDoesNotExist,
                        Errors._Store_ShardMap_DoesNotExistGlobal,
                        shardMap.Name,
                        storedProcName,
                        operationName,
                        shard != null ? shard.Location.ToString() : "*");

                case StoreResult.ShardDoesNotExist:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.ShardDoesNotExist,
                        Errors._Store_Shard_DoesNotExistGlobal,
                        shard.Location,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.ShardVersionMismatch:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.ShardVersionMismatch,
                        Errors._Store_Shard_VersionMismatchGlobal,
                        shard.Location,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.MappingDoesNotExist:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.MappingDoesNotExist,
                        Errors._Store_ShardMapper_MappingDoesNotExistGlobal,
                        shard.Location,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.MappingRangeAlreadyMapped:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.MappingRangeAlreadyMapped,
                        Errors._Store_ShardMapper_MappingPointOrRangeAlreadyMapped,
                        shard.Location,
                        shardMap.Name,
                        "Range",
                        storedProcName,
                        operationName);

                case StoreResult.MappingPointAlreadyMapped:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.MappingPointAlreadyMapped,
                        Errors._Store_ShardMapper_MappingPointOrRangeAlreadyMapped,
                        shard.Location,
                        shardMap.Name,
                        "Point",
                        storedProcName,
                        operationName);

                case StoreResult.MappingNotFoundForKey:
                    Debug.Fail("MappingNotFoundForKey should not be raised during SqlOperation.");
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.MappingNotFoundForKey,
                        Errors._Store_ShardMapper_MappingNotFoundForKeyGlobal,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.MappingIsAlreadyLocked:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.MappingIsAlreadyLocked,
                        Errors._Store_ShardMapper_LockMappingAlreadyLocked,
                        shard.Location,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.MappingLockOwnerIdDoesNotMatch:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.MappingLockOwnerIdDoesNotMatch,
                        Errors._Store_ShardMapper_LockOwnerDoesNotMatch,
                        shard.Location,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.MappingIsNotOffline:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.MappingIsNotOffline,
                        Errors._Store_ShardMapper_MappingIsNotOffline,
                        shard.Location,
                        shardMap.Name,
                        storedProcName,
                        operationName);

                case StoreResult.StoreVersionMismatch:
                case StoreResult.MissingParametersForStoredProcedure:
                default:
                    return StoreOperationErrorHandler.OnCommonErrorGlobal(
                        result,
                        operationName,
                        storedProcName);
            }
        }
 /// <summary>
 /// Sets the stub of StoreOperationFactory.CreateGetMappingsByRangeGlobalOperation(ShardMapManager shardMapManager, String operationName, IStoreShardMap shardMap, IStoreShard shard, ShardRange range, ShardManagementErrorCategory errorCategory, Boolean cacheResults, Boolean ignoreFailure)
 /// </summary>
 public override IStoreOperationGlobal CreateGetMappingsByRangeGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, IStoreShard shard, ShardRange range, ShardManagementErrorCategory errorCategory, bool cacheResults, bool ignoreFailure)
 {
     Func<ShardMapManager, string, IStoreShardMap, IStoreShard, ShardRange, ShardManagementErrorCategory, bool, bool, IStoreOperationGlobal> func1 = this.CreateGetMappingsByRangeGlobalOperationShardMapManagerStringIStoreShardMapIStoreShardShardRangeShardManagementErrorCategoryBooleanBoolean;
     if (func1 != null)
         return func1(shardMapManager, operationName, shardMap, shard, range, errorCategory, cacheResults, ignoreFailure);
     if (this.___callBase)
         return base.CreateGetMappingsByRangeGlobalOperation(shardMapManager, operationName, shardMap, shard, range, errorCategory, cacheResults, ignoreFailure);
     return this.InstanceBehavior.Result<StubStoreOperationFactory, IStoreOperationGlobal>(this, "CreateGetMappingsByRangeGlobalOperation");
 }
 /// <summary>
 /// Initializes a new instance with a specified error message and a reference to the inner exception 
 /// that is the cause of this exception.
 /// </summary>
 /// <param name="category">Category of error.</param>
 /// <param name="code">Error code.</param>
 /// <param name="message">A message that describes the error</param>
 /// <param name="inner">The exception that is the cause of the current exception</param>
 internal ShardManagementException(ShardManagementErrorCategory category, ShardManagementErrorCode code, string message, Exception inner)
     : base(message, inner)
 {
     this.ErrorCategory = category;
     this.ErrorCode = code;
 }
 /// <summary>
 /// Sets the stub of StoreOperationFactory.CreateFindMappingByIdGlobalOperation(ShardMapManager shardMapManager, String operationName, IStoreShardMap shardMap, IStoreMapping mapping, ShardManagementErrorCategory errorCategory)
 /// </summary>
 public override IStoreOperationGlobal CreateFindMappingByIdGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, IStoreMapping mapping, ShardManagementErrorCategory errorCategory)
 {
     Func<ShardMapManager, string, IStoreShardMap, IStoreMapping, ShardManagementErrorCategory, IStoreOperationGlobal> func1 = this.CreateFindMappingByIdGlobalOperationShardMapManagerStringIStoreShardMapIStoreMappingShardManagementErrorCategory;
     if (func1 != null)
         return func1(shardMapManager, operationName, shardMap, mapping, errorCategory);
     if (this.___callBase)
         return base.CreateFindMappingByIdGlobalOperation(shardMapManager, operationName, shardMap, mapping, errorCategory);
     return this.InstanceBehavior.Result<StubStoreOperationFactory, IStoreOperationGlobal>(this, "CreateFindMappingByIdGlobalOperation");
 }
 /// <summary>
 /// Initializes a new instance with a specified formatted error message and a reference to the 
 /// inner exception that is the cause of this exception. 
 /// </summary>
 /// <param name="category">Category of error.</param>
 /// <param name="code">Error code.</param>
 /// <param name="format">The format message that describes the error</param>
 /// <param name="inner">The exception that is the cause of the current exception</param>
 /// <param name="args">The arguments to the format string</param>
 internal ShardManagementException(ShardManagementErrorCategory category, ShardManagementErrorCode code, string format, Exception inner, params object[] args)
     : base(string.Format(CultureInfo.InvariantCulture, format, args), inner)
 {
     this.ErrorCategory = category;
     this.ErrorCode = code;
 }
Example #47
0
        internal void LockOrUnlockMappings <TMapping>(TMapping mapping, Guid lockOwnerId, LockOwnerIdOpType lockOwnerIdOpType, ShardManagementErrorCategory errorCategory) where TMapping : class, IShardProvider, IMappingInfoProvider
        {
            string operationName = lockOwnerIdOpType == LockOwnerIdOpType.Lock ? "Lock" : "UnLock";

            if (lockOwnerIdOpType != LockOwnerIdOpType.UnlockAllMappingsForId && lockOwnerIdOpType != LockOwnerIdOpType.UnlockAllMappings)
            {
                this.EnsureMappingBelongsToShardMap <TMapping>(mapping, operationName, "mapping");

                if (lockOwnerIdOpType == LockOwnerIdOpType.Lock &&
                    lockOwnerId == MappingLockToken.ForceUnlock.LockOwnerId)
                {
                    throw new ArgumentException(
                              StringUtils.FormatInvariant(
                                  Errors._ShardMapping_LockIdNotSupported,
                                  mapping.ShardInfo.Location,
                                  this.ShardMap.Name,
                                  lockOwnerId),
                              "lockOwnerId");
                }
            }
            else
            {
                Debug.Assert(mapping == null);
            }

            using (IStoreOperationGlobal op = this.Manager.StoreOperationFactory.CreateLockOrUnLockMappingsGlobalOperation(
                       this.Manager,
                       operationName,
                       this.ShardMap.StoreShardMap,
                       mapping != null ? mapping.StoreMapping : null,
                       lockOwnerId,
                       lockOwnerIdOpType,
                       errorCategory))
            {
                op.Do();
            }
        }
        /// <summary>
        /// Returns the proper ShardManagementException corresponding to given error code in 
        /// <paramref name="result"/> for ShardMap operations.
        /// </summary>
        /// <param name="result">Operation result object.</param>
        /// <param name="shardMap">Shard map object.</param>
        /// <param name="location">Location of LSM operation.</param>
        /// <param name="errorCategory">Error category to use for raised errors.</param>
        /// <param name="operationName">Operation being performed.</param>
        /// <param name="storedProcName">Stored procedure being executed.</param>
        /// <returns>ShardManagementException to be raised.</returns>
        internal static ShardManagementException OnShardMapErrorLocal(
            IStoreResults result,
            IStoreShardMap shardMap,
            ShardLocation location,
            ShardManagementErrorCategory errorCategory,
            string operationName,
            string storedProcName)
        {
            switch (result.Result)
            {
                case StoreResult.UnableToKillSessions:
                    return new ShardManagementException(
                        errorCategory,
                        ShardManagementErrorCode.MappingsKillConnectionFailure,
                        Errors._Store_ShardMapper_UnableToKillSessions,
                        location,
                        shardMap.Name,
                        operationName,
                        storedProcName,
                        location);

                case StoreResult.StoreVersionMismatch:
                case StoreResult.MissingParametersForStoredProcedure:
                case StoreResult.ShardDoesNotExist:
                    // ShardDoesNotExist on local shard map can only occur in Recovery scenario.
                    // For normal UpdateShard operation, we will get this error from GSM operation first.
                    return new ShardManagementException(
                        ShardManagementErrorCategory.Recovery,
                        ShardManagementErrorCode.ShardDoesNotExist,
                        Errors._Store_Validate_ShardDoesNotExist,
                        location,
                        shardMap.Name,
                        operationName,
                        storedProcName);
                default:
                    return StoreOperationErrorHandler.OnCommonErrorLocal(
                        result,
                        location,
                        operationName,
                        storedProcName);
            }
        }
        /// <summary>
        /// Creates request to add shard to given shard map.
        /// </summary>
        /// <param name="shardMapManager">Shard map manager object.</param>
        /// <param name="operationId">Operation id.</param>
        /// <param name="undoStartState">State from which Undo operation starts.</param>
        /// <param name="operationCode">Store operation code.</param>
        /// <param name="shardMap">Shard map for which to update mapping.</param>
        /// <param name="mappingSource">Mapping to update.</param>
        /// <param name="mappingTarget">Updated mapping.</param>
        /// <param name="patternForKill">Pattern for kill commands.</param>
        /// <param name="lockOwnerId">Id of lock owner.</param>
        /// <param name="originalShardVersionRemoves">Original shard version for removes.</param>
        /// <param name="originalShardVersionAdds">Original shard version for adds.</param>
        internal UpdateMappingOperation(
            ShardMapManager shardMapManager,
            Guid operationId,
            StoreOperationState undoStartState,
            StoreOperationCode operationCode,
            IStoreShardMap shardMap,
            IStoreMapping mappingSource,
            IStoreMapping mappingTarget,
            string patternForKill,
            Guid lockOwnerId,
            Guid originalShardVersionRemoves,
            Guid originalShardVersionAdds) :
            base(
            shardMapManager,
            operationId,
            undoStartState,
            operationCode,
            originalShardVersionRemoves,
            originalShardVersionAdds)
        {
            _shardMap = shardMap;
            _mappingSource = mappingSource;
            _mappingTarget = mappingTarget;
            _lockOwnerId = lockOwnerId;

            _errorCategory = (operationCode == StoreOperationCode.UpdateRangeMapping ||
                                  operationCode == StoreOperationCode.UpdateRangeMappingWithOffline) ?
                ShardManagementErrorCategory.RangeShardMap :
                ShardManagementErrorCategory.ListShardMap;

            _updateLocation = _mappingSource.StoreShard.Id != _mappingTarget.StoreShard.Id;

            _fromOnlineToOffline = operationCode == StoreOperationCode.UpdatePointMappingWithOffline ||
                                       operationCode == StoreOperationCode.UpdateRangeMappingWithOffline;

            _patternForKill = patternForKill;
        }
Example #50
0
        /// <summary>
        /// Returns the proper ShardManagementException corresponding to given error code in
        /// <paramref name="result"/> for ShardMapper operations.
        /// </summary>
        /// <param name="result">Operation result object.</param>
        /// <param name="shardMap">Shard map object.</param>
        /// <param name="shard">Shard object.</param>
        /// <param name="errorCategory">Error category to use for raised errors.</param>
        /// <param name="operationName">Operation being performed.</param>
        /// <param name="storedProcName">Stored procedure being executed.</param>
        /// <returns>ShardManagementException to be raised.</returns>
        internal static ShardManagementException OnShardMapperErrorGlobal(
            IStoreResults result,
            IStoreShardMap shardMap,
            IStoreShard shard,
            ShardManagementErrorCategory errorCategory,
            string operationName,
            string storedProcName)
        {
            switch (result.Result)
            {
            case StoreResult.ShardMapDoesNotExist:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.ShardMapDoesNotExist,
                           Errors._Store_ShardMap_DoesNotExistGlobal,
                           shardMap.Name,
                           storedProcName,
                           operationName,
                           shard != null ? shard.Location.ToString() : "*"));

            case StoreResult.ShardDoesNotExist:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.ShardDoesNotExist,
                           Errors._Store_Shard_DoesNotExistGlobal,
                           shard.Location,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.ShardVersionMismatch:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.ShardVersionMismatch,
                           Errors._Store_Shard_VersionMismatchGlobal,
                           shard.Location,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.MappingDoesNotExist:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.MappingDoesNotExist,
                           Errors._Store_ShardMapper_MappingDoesNotExistGlobal,
                           shard.Location,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.MappingRangeAlreadyMapped:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.MappingRangeAlreadyMapped,
                           Errors._Store_ShardMapper_MappingPointOrRangeAlreadyMapped,
                           shard.Location,
                           shardMap.Name,
                           "Range",
                           storedProcName,
                           operationName));

            case StoreResult.MappingPointAlreadyMapped:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.MappingPointAlreadyMapped,
                           Errors._Store_ShardMapper_MappingPointOrRangeAlreadyMapped,
                           shard.Location,
                           shardMap.Name,
                           "Point",
                           storedProcName,
                           operationName));

            case StoreResult.MappingNotFoundForKey:
                Debug.Fail("MappingNotFoundForKey should not be raised during SqlOperation.");
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.MappingNotFoundForKey,
                           Errors._Store_ShardMapper_MappingNotFoundForKeyGlobal,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.MappingIsAlreadyLocked:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.MappingIsAlreadyLocked,
                           Errors._Store_ShardMapper_LockMappingAlreadyLocked,
                           shard.Location,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.MappingLockOwnerIdDoesNotMatch:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.MappingLockOwnerIdDoesNotMatch,
                           Errors._Store_ShardMapper_LockOwnerDoesNotMatch,
                           shard.Location,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.MappingIsNotOffline:
                return(new ShardManagementException(
                           errorCategory,
                           ShardManagementErrorCode.MappingIsNotOffline,
                           Errors._Store_ShardMapper_MappingIsNotOffline,
                           shard.Location,
                           shardMap.Name,
                           storedProcName,
                           operationName));

            case StoreResult.StoreVersionMismatch:
            case StoreResult.MissingParametersForStoredProcedure:
            default:
                return(StoreOperationErrorHandler.OnCommonErrorGlobal(
                           result,
                           operationName,
                           storedProcName));
            }
        }
        /// <summary>
        /// Given a key value, obtains a SqlConnection to the shard in the mapping
        /// that contains the key value.
        /// </summary>
        /// <typeparam name="TMapping">Mapping type.</typeparam>
        /// <typeparam name="TKey">Key type.</typeparam>
        /// <param name="key">Input key value.</param>
        /// <param name="constructMapping">Delegate to construct a mapping object.</param>
        /// <param name="errorCategory">Error category.</param>
        /// <param name="connectionInfo">
        /// Connection info with credential information, the DataSource and Database are
        /// obtained from the results of the lookup operation for key.
        /// </param>
        /// <param name="options">Options for validation operations to perform on opened connection.</param>
        /// <returns>An opened SqlConnection.</returns>
        protected SqlConnection OpenConnectionForKey <TMapping, TKey>(
            TKey key,
            Func <ShardMapManager, ShardMap, IStoreMapping, TMapping> constructMapping,
            ShardManagementErrorCategory errorCategory,
            SqlConnectionInfo connectionInfo,
            ConnectionOptions options = ConnectionOptions.Validate) where TMapping : class, IShardProvider
        {
            ShardKey sk = new ShardKey(ShardKey.ShardKeyTypeFromType(typeof(TKey)), key);

            // Try to find the mapping within the cache.
            ICacheStoreMapping csm = this.Manager.Cache.LookupMappingByKey(this.ShardMap.StoreShardMap, sk);

            IStoreMapping sm;

            if (csm != null)
            {
                sm = csm.Mapping;
            }
            else
            {
                sm = this.LookupMappingForOpenConnectionForKey(
                    sk,
                    CacheStoreMappingUpdatePolicy.OverwriteExisting,
                    errorCategory);
            }

            SqlConnection result;

            try
            {
                // Initially attempt to connect based on lookup results from either cache or GSM.
                result = this.ShardMap.OpenConnection(
                    constructMapping(this.Manager, this.ShardMap, sm),
                    connectionInfo,
                    options);

                // Reset TTL on successful connection.
                if (csm != null && csm.TimeToLiveMilliseconds > 0)
                {
                    csm.ResetTimeToLive();
                }

                this.Manager.Cache.IncrementPerformanceCounter(this.ShardMap.StoreShardMap, PerformanceCounterName.DdrOperationsPerSec);
                return(result);
            }
            catch (ShardManagementException smme)
            {
                // If we hit a validation failure due to stale version of mapping, we will perform one more attempt.
                if (((options & ConnectionOptions.Validate) == ConnectionOptions.Validate) &&
                    smme.ErrorCategory == ShardManagementErrorCategory.Validation &&
                    smme.ErrorCode == ShardManagementErrorCode.MappingDoesNotExist)
                {
                    // Assumption here is that this time the attempt should succeed since the cache entry
                    // has already been either evicted, or updated based on latest data from the server.
                    sm = this.LookupMappingForOpenConnectionForKey(
                        sk,
                        CacheStoreMappingUpdatePolicy.OverwriteExisting,
                        errorCategory);

                    result = this.ShardMap.OpenConnection(
                        constructMapping(this.Manager, this.ShardMap, sm),
                        connectionInfo,
                        options);
                    this.Manager.Cache.IncrementPerformanceCounter(this.ShardMap.StoreShardMap, PerformanceCounterName.DdrOperationsPerSec);
                    return(result);
                }
                else
                {
                    // The error was not due to validation but something else e.g.
                    // 1) Shard map does not exist
                    // 2) Mapping could not be found.
                    throw;
                }
            }
            catch (SqlException)
            {
                // We failed to connect. If we were trying to connect from an entry in cache and mapping expired in cache.
                if (csm != null && TimerUtils.ElapsedMillisecondsSince(csm.CreationTime) >= csm.TimeToLiveMilliseconds)
                {
                    using (IdLock _idLock = new IdLock(csm.Mapping.StoreShard.Id))
                    {
                        // Similar to DCL pattern, we need to refresh the mapping again to see if we still need to go to the store
                        // to lookup the mapping after acquiring the shard lock. It might be the case that a fresh version has already
                        // been obtained by some other thread.
                        csm = this.Manager.Cache.LookupMappingByKey(this.ShardMap.StoreShardMap, sk);

                        // Only go to store if the mapping is stale even after refresh.
                        if (csm == null || TimerUtils.ElapsedMillisecondsSince(csm.CreationTime) >= csm.TimeToLiveMilliseconds)
                        {
                            // Refresh the mapping in cache. And try to open the connection after refresh.
                            sm = this.LookupMappingForOpenConnectionForKey(
                                sk,
                                CacheStoreMappingUpdatePolicy.UpdateTimeToLive,
                                errorCategory);
                        }
                        else
                        {
                            sm = csm.Mapping;
                        }
                    }

                    result = this.ShardMap.OpenConnection(
                        constructMapping(this.Manager, this.ShardMap, sm),
                        connectionInfo,
                        options);

                    // Reset TTL on successful connection.
                    if (csm != null && csm.TimeToLiveMilliseconds > 0)
                    {
                        csm.ResetTimeToLive();
                    }

                    this.Manager.Cache.IncrementPerformanceCounter(this.ShardMap.StoreShardMap, PerformanceCounterName.DdrOperationsPerSec);
                    return(result);
                }
                else
                {
                    // Either:
                    // 1) The mapping is still within the TTL. No refresh.
                    // 2) Mapping was not in cache, we originally did a lookup for mapping in GSM and even then could not connect.
                    throw;
                }
            }
        }
 /// <summary>
 /// Constructs request for obtaining mapping from GSM based on given key.
 /// </summary>
 /// <param name="shardMapManager">Shard map manager.</param>
 /// <param name="operationName">Operation being executed.</param>
 /// <param name="shardMap">Local shard map.</param>
 /// <param name="key">Key for lookup operation.</param>
 /// <param name="policy">Policy for cache update.</param>
 /// <param name="errorCategory">Error category.</param>
 /// <param name="cacheResults">Whether to cache the results of the operation.</param>
 /// <param name="ignoreFailure">Ignore shard map not found error.</param>
 /// <returns>The store operation.</returns>
 public virtual IStoreOperationGlobal CreateFindMappingByKeyGlobalOperation(
     ShardMapManager shardMapManager,
     string operationName,
     IStoreShardMap shardMap,
     ShardKey key,
     CacheStoreMappingUpdatePolicy policy,
     ShardManagementErrorCategory errorCategory,
     bool cacheResults,
     bool ignoreFailure)
 {
     return new FindMappingByKeyGlobalOperation(
         shardMapManager,
         operationName,
         shardMap,
         key,
         policy,
         errorCategory,
         cacheResults,
         ignoreFailure);
 }