/// <summary>
        /// Allows for update to a mapping with the updates provided in
        /// the <paramref name="update"/> parameter.
        /// </summary>
        /// <param name="currentMapping">Mapping being updated.</param>
        /// <param name="update">Updated properties of the Shard.</param>
        /// <param name="constructMapping">Delegate to construct a mapping object.</param>
        /// <param name="statusAsInt">Delegate to get the mapping status as an integer value.</param>
        /// <param name="intAsStatus">Delegate to get the mapping status from an integer value.</param>
        /// <param name="lockOwnerId">Lock owner id of this mapping</param>
        /// <param name="options">Options for validation operations to perform on opened connection to affected shard.</param>
        /// <returns>New instance of mapping with updated information.</returns>
        protected TMapping Update <TMapping, TUpdate, TStatus>(
            TMapping currentMapping,
            TUpdate update,
            Func <ShardMapManager, ShardMap, IStoreMapping, TMapping> constructMapping,
            Func <TStatus, int> statusAsInt,
            Func <int, TStatus> intAsStatus,
            Guid lockOwnerId       = default(Guid),
            MappingOptions options = MappingOptions.Validate)
            where TUpdate : class, IMappingUpdate <TStatus>
            where TMapping : class, IShardProvider, IMappingInfoProvider
            where TStatus : struct
        {
            Debug.Assert(currentMapping != null);
            Debug.Assert(update != null);

            this.EnsureMappingBelongsToShardMap <TMapping>(currentMapping, "Update", "currentMapping");

            IMappingUpdate <TStatus> mu = update as IMappingUpdate <TStatus>;

            // CONSIDER(wbasheer): Have refresh semantics for trivial case when nothing is modified.
            if (!mu.IsAnyPropertySet(MappingUpdatedProperties.All))
            {
                return(currentMapping);
            }

            bool shardChanged = mu.IsAnyPropertySet(MappingUpdatedProperties.Shard) && !mu.Shard.Equals(currentMapping.ShardInfo);

            // Ensure that shard belongs to current shard map.
            if (shardChanged)
            {
                ExceptionUtils.EnsureShardBelongsToShardMap(
                    this.Manager,
                    this.ShardMap,
                    mu.Shard,
                    "UpdateMapping",
                    currentMapping.Kind == MappingKind.PointMapping ? "PointMapping" : "RangeMapping");
            }

            IStoreShard originalShard = new DefaultStoreShard(
                currentMapping.ShardInfo.Id,
                Guid.NewGuid(),
                currentMapping.ShardInfo.StoreShard.ShardMapId,
                currentMapping.ShardInfo.StoreShard.Location,
                currentMapping.ShardInfo.StoreShard.Status);

            IStoreMapping originalMapping = new DefaultStoreMapping(
                currentMapping.StoreMapping.Id,
                currentMapping.ShardMapId,
                originalShard,
                currentMapping.StoreMapping.MinValue,
                currentMapping.StoreMapping.MaxValue,
                currentMapping.StoreMapping.Status,
                lockOwnerId);

            IStoreShard updatedShard;

            if (shardChanged)
            {
                updatedShard = new DefaultStoreShard(
                    update.Shard.ShardInfo.Id,
                    Guid.NewGuid(),
                    update.Shard.ShardInfo.StoreShard.ShardMapId,
                    update.Shard.ShardInfo.StoreShard.Location,
                    update.Shard.ShardInfo.StoreShard.Status);
            }
            else
            {
                updatedShard = originalShard;
            }

            IStoreMapping updatedMapping = new DefaultStoreMapping(
                Guid.NewGuid(),
                currentMapping.ShardMapId,
                updatedShard,
                currentMapping.StoreMapping.MinValue,
                currentMapping.StoreMapping.MaxValue,
                mu.IsAnyPropertySet(MappingUpdatedProperties.Status) ?
                statusAsInt(update.Status) :
                currentMapping.StoreMapping.Status,
                lockOwnerId);

            bool fromOnlineToOffline = mu.IsMappingBeingTakenOffline(intAsStatus(currentMapping.StoreMapping.Status));

            StoreOperationCode opCode;

            if (fromOnlineToOffline)
            {
                opCode = currentMapping.Kind == MappingKind.PointMapping ?
                         StoreOperationCode.UpdatePointMappingWithOffline :
                         StoreOperationCode.UpdateRangeMappingWithOffline;
            }
            else
            {
                opCode = currentMapping.Kind == MappingKind.PointMapping ?
                         StoreOperationCode.UpdatePointMapping :
                         StoreOperationCode.UpdateRangeMapping;
            }

            var killConnection = options == MappingOptions.Validate;

            using (IStoreOperation op = this.Manager.StoreOperationFactory.CreateUpdateMappingOperation(
                       this.Manager,
                       opCode,
                       this.ShardMap.StoreShardMap,
                       originalMapping,
                       updatedMapping,
                       this.ShardMap.ApplicationNameSuffix,
                       lockOwnerId,
                       killConnection))
            {
                op.Do();
            }

            return(constructMapping(this.Manager, this.ShardMap, updatedMapping));
        }
Example #2
0
        private static ShardMapManager CreateSqlShardMapManagerImpl(
            string connectionString,
            ShardMapManagerCreateMode createMode,
            RetryBehavior retryBehavior,
            EventHandler <RetryingEventArgs> retryEventHandler,
            Version targetVersion)
        {
            ExceptionUtils.DisallowNullArgument(connectionString, "connectionString");
            ExceptionUtils.DisallowNullArgument(retryBehavior, "retryBehavior");

            if (createMode != ShardMapManagerCreateMode.KeepExisting &&
                createMode != ShardMapManagerCreateMode.ReplaceExisting)
            {
                throw new ArgumentException(
                          StringUtils.FormatInvariant(
                              Errors._General_InvalidArgumentValue,
                              createMode,
                              "createMode"),
                          "createMode");
            }

            using (ActivityIdScope activityIdScope = new ActivityIdScope(Guid.NewGuid()))
            {
                Tracer.TraceInfo(
                    TraceSourceConstants.ComponentNames.ShardMapManagerFactory,
                    "CreateSqlShardMapManager",
                    "Start; ");

                Stopwatch stopwatch = Stopwatch.StartNew();

                SqlShardMapManagerCredentials credentials = new SqlShardMapManagerCredentials(connectionString);

                TransientFaultHandling.RetryPolicy retryPolicy = new TransientFaultHandling.RetryPolicy(
                    new ShardManagementTransientErrorDetectionStrategy(retryBehavior),
                    RetryPolicy.DefaultRetryPolicy.GetRetryStrategy());

                EventHandler <TransientFaultHandling.RetryingEventArgs> handler = (sender, args) =>
                {
                    if (retryEventHandler != null)
                    {
                        retryEventHandler(sender, new RetryingEventArgs(args));
                    }
                };

                try
                {
                    retryPolicy.Retrying += handler;

                    // specifying targetVersion as GlobalConstants.GsmVersionClient to deploy latest store by default.
                    using (IStoreOperationGlobal op = new StoreOperationFactory().CreateCreateShardMapManagerGlobalOperation(
                               credentials,
                               retryPolicy,
                               "CreateSqlShardMapManager",
                               createMode,
                               targetVersion))
                    {
                        op.Do();
                    }

                    stopwatch.Stop();

                    Tracer.TraceInfo(
                        TraceSourceConstants.ComponentNames.ShardMapManagerFactory,
                        "CreateSqlShardMapManager",
                        "Complete; Duration: {0}",
                        stopwatch.Elapsed);
                }
                finally
                {
                    retryPolicy.Retrying -= handler;
                }

                return(new ShardMapManager(
                           credentials,
                           new SqlStoreConnectionFactory(),
                           new StoreOperationFactory(),
                           new CacheStore(),
                           ShardMapManagerLoadPolicy.Lazy,
                           RetryPolicy.DefaultRetryPolicy,
                           retryBehavior,
                           retryEventHandler));
            }
        }
        /// <summary>
        /// Returns the ShardManagementException to be thrown corresponding to a StoreException.
        /// </summary>
        /// <param name="se">Store Exception that has been raised.</param>
        /// <param name="state">SQL operation state.</param>
        /// <returns>ShardManagementException to be thrown.</returns>
        public virtual ShardManagementException OnStoreException(StoreException se, StoreOperationState state)
        {
            switch (state)
            {
            case StoreOperationState.DoGlobalConnect:

            case StoreOperationState.DoGlobalPreLocalBeginTransaction:
            case StoreOperationState.DoGlobalPreLocalExecute:
            case StoreOperationState.DoGlobalPreLocalCommitTransaction:

            case StoreOperationState.DoGlobalPostLocalBeginTransaction:
            case StoreOperationState.DoGlobalPostLocalExecute:
            case StoreOperationState.DoGlobalPostLocalCommitTransaction:

            case StoreOperationState.UndoGlobalConnect:

            case StoreOperationState.UndoGlobalPreLocalBeginTransaction:
            case StoreOperationState.UndoGlobalPreLocalExecute:
            case StoreOperationState.UndoGlobalPreLocalCommitTransaction:

            case StoreOperationState.UndoGlobalPostLocalBeginTransaction:
            case StoreOperationState.UndoGlobalPostLocalExecute:
            case StoreOperationState.UndoGlobalPostLocalCommitTransaction:
                return(ExceptionUtils.GetStoreExceptionGlobal(
                           this.ErrorCategory,
                           se,
                           this.OperationName));

            case StoreOperationState.DoLocalSourceConnect:
            case StoreOperationState.DoLocalSourceBeginTransaction:
            case StoreOperationState.DoLocalSourceExecute:
            case StoreOperationState.DoLocalSourceCommitTransaction:

            case StoreOperationState.UndoLocalSourceConnect:
            case StoreOperationState.UndoLocalSourceBeginTransaction:
            case StoreOperationState.UndoLocalSourceExecute:
            case StoreOperationState.UndoLocalSourceCommitTransaction:
                return(ExceptionUtils.GetStoreExceptionLocal(
                           this.ErrorCategory,
                           se,
                           this.OperationName,
                           this.ErrorSourceLocation));

            case StoreOperationState.DoLocalTargetConnect:
            case StoreOperationState.DoLocalTargetBeginTransaction:
            case StoreOperationState.DoLocalTargetExecute:
            case StoreOperationState.DoLocalTargetCommitTransaction:

            case StoreOperationState.UndoLocalTargetConnect:
            case StoreOperationState.UndoLocalTargetBeginTransaction:
            case StoreOperationState.UndoLocalTargetExecute:
            case StoreOperationState.UndoLocalTargetCommitTransaction:

            default:
                return(ExceptionUtils.GetStoreExceptionLocal(
                           this.ErrorCategory,
                           se,
                           this.OperationName,
                           this.ErrorTargetLocation));
            }
        }
Example #4
0
        /// <summary>Checks whether the range intersects with the current range.</summary>
        /// <param name="range">The range to check.</param>
        /// <returns>True if it intersects, False otherwise.</returns>
        internal bool Intersects(ShardRange range)
        {
            ExceptionUtils.DisallowNullArgument(range, "range");

            return((range.High > Low) && (range.Low < High));
        }
Example #5
0
        public bool Contains(ShardRange range)
        {
            ExceptionUtils.DisallowNullArgument(range, "range");

            return((range.Low >= Low) && (range.High <= High));
        }
Example #6
0
        /// <summary>Checks whether the specified key is inside the range.</summary>
        /// <param name="key">The key to check</param>
        /// <returns>True if inside, false otherwise</returns>
        public bool Contains(ShardKey key)
        {
            ExceptionUtils.DisallowNullArgument(key, "key");

            return((key >= Low) && (key < High));
        }