예제 #1
0
        public static bool TryReadBlob <T>(CloudBlockBlob blob, out T configurationStore)
            where T : class
        {
            configurationStore = default(T);
            try
            {
                string content = blob.DownloadText();
                if (content == Constants.ConfigurationStoreUpdatingText)
                {
                    return(false);
                }

                string blobContent = content;
                configurationStore = JsonStore <T> .Deserialize(blobContent);

                return(true);
            }
            catch (Exception e)
            {
                ReplicatedTableLogger.LogError("Error reading blob: {0}. Exception: {1}",
                                               blob.Uri,
                                               e.Message);
            }

            return(false);
        }
        public void TurnReplicaOff(string storageAccountName)
        {
            if (string.IsNullOrEmpty(storageAccountName))
            {
                throw new ArgumentNullException("storageAccountName");
            }

            ReplicatedTableConfiguration configuration = null;

            // - Retrieve configuration ...
            ReplicatedTableQuorumReadResult readResult = RetrieveConfiguration(out configuration);

            if (readResult.Code != ReplicatedTableQuorumReadCode.Success)
            {
                var msg = string.Format("TurnReplicaOff={0}: failed to read configuration, \n{1}", storageAccountName, readResult.ToString());

                ReplicatedTableLogger.LogError(msg);
                throw new Exception(msg);
            }

            // - Update all views ...
            configuration.TurnReplicaOff(storageAccountName);

            // - Write back configuration ...
            ReplicatedTableQuorumWriteResult writeResult = UpdateConfigurationInternal(configuration, true);

            if (writeResult.Code != ReplicatedTableQuorumWriteCode.Success)
            {
                var msg = string.Format("TurnReplicaOff={0}: failed to update configuration, \n{1}", storageAccountName, writeResult.ToString());

                ReplicatedTableLogger.LogError(msg);
                throw new Exception(msg);
            }
        }
예제 #3
0
파일: View.cs 프로젝트: srinathsetty/rtable
        public static View InitFromConfigVer2(string name, ReplicatedTableConfigurationStore configurationStore, Action <ReplicaInfo> SetConnectionString)
        {
            View view = new View(name);

            if (configurationStore != null)
            {
                view.ViewId = configurationStore.ViewId;

                foreach (ReplicaInfo replica in configurationStore.GetCurrentReplicaChain())
                {
                    SetConnectionString(replica);

                    CloudTableClient tableClient = ReplicatedTableConfigurationManager.GetTableClientForReplica(replica);
                    if (tableClient == null)
                    {
                        // All replicas MUST exist or View is not relevant
                        view.Chain.Clear();

                        ReplicatedTableLogger.LogError("ViewName={0} could not load replica ({1})", name, replica);
                        break;
                    }

                    view.Chain.Add(new Tuple <ReplicaInfo, CloudTableClient>(replica, tableClient));
                }

                // Infered: first readable replica
                view.ReadHeadIndex = view.Chain.FindIndex(tuple => tuple.Item1.IsReadable());
            }

            return(view);
        }
예제 #4
0
        public static List <ReplicatedTableReadBlobResult> TryReadAllBlobs <T>(List <CloudBlockBlob> blobs, out List <T> values, out List <string> eTags, Func <string, T> ParseBlobFunc)
            where T : class
        {
            int numberOfBlobs = blobs.Count;

            T[]      valuesArray = new T[numberOfBlobs];
            string[] eTagsArray  = new string[numberOfBlobs];
            ReplicatedTableReadBlobResult[] resultArray = new ReplicatedTableReadBlobResult[numberOfBlobs];

            // read from all the blobs in parallel
            Parallel.For(0, numberOfBlobs, index =>
            {
                DateTime startTime = DateTime.UtcNow;

                T currentValue;
                string currentETag;

                resultArray[index] = TryReadBlob(blobs[index], out currentValue, out currentETag, ParseBlobFunc);
                valuesArray[index] = currentValue;
                eTagsArray[index]  = currentETag;

                ReplicatedTableLogger.LogInformational("TryReadBlob #{0} took {1}", index, DateTime.UtcNow - startTime);
            });

            values = valuesArray.ToList();
            eTags  = eTagsArray.ToList();

            return(resultArray.ToList());
        }
예제 #5
0
        private void Initialize()
        {
            if ((this.blobLocations.Count % 2) == 0)
            {
                throw new ArgumentException("Number of blob locations must be odd");
            }

            foreach (var blobLocation in blobLocations)
            {
                string accountConnectionString = String.Format(Constants.ShortConnectioStringTemplate,
                                                               ((this.useHttps == true) ? "https" : "http"),
                                                               blobLocation.StorageAccountName,
                                                               blobLocation.StorageAccountKey);

                try
                {
                    CloudBlockBlob blob = CloudBlobHelpers.GetBlockBlob(accountConnectionString, blobLocation.BlobPath);
                    this.blobs.Add(blobLocation.StorageAccountName + ';' + blobLocation.BlobPath, blob);
                }
                catch (Exception e)
                {
                    ReplicatedTableLogger.LogError("Failed to init blob Acc={0}, Blob={1}. Exception: {2}",
                                                   blobLocation.StorageAccountName,
                                                   blobLocation.BlobPath,
                                                   e.Message);
                }
            }

            int quorumSize = (this.blobLocations.Count / 2) + 1;

            if (this.blobs.Count < quorumSize)
            {
                throw new Exception(string.Format("Retrieved blobs count ({0}) is less than quorum !", this.blobs.Count));
            }
        }
예제 #6
0
        private ReplicatedTableQuorumWriteResult UpdateConfigurationInternal(ReplicatedTableConfiguration configuration, bool useConditionalUpdate)
        {
            SanitizeConfiguration(configuration);

            // - Upload configuration ...
            Func <ReplicatedTableConfiguration, ReplicatedTableConfiguration, bool> comparer = (a, b) => a.Id == b.Id;

            if (!useConditionalUpdate)
            {
                comparer = (a, b) => true;
            }

            ReplicatedTableQuorumWriteResult
                result = CloudBlobHelpers.TryWriteBlobQuorum(
                this.configManager.GetBlobs(),
                configuration,
                ReplicatedTableConfiguration.FromJson,
                comparer,
                ReplicatedTableConfiguration.GenerateNewConfigId);

            if (result.Code == ReplicatedTableQuorumWriteCode.Success)
            {
                this.configManager.Invalidate();
            }
            else
            {
                ReplicatedTableLogger.LogError("Failed to update configuration, \n{0}", result.ToString());
            }

            return(result);
        }
        public void UpdateConfiguration(List <ReplicaInfo> replicaChain, int readViewHeadIndex, bool convertXStoreTableMode = false)
        {
            Parallel.ForEach(this.blobs, blob =>
            {
                ReplicatedTableConfigurationStore configurationStore = null;
                long newViewId = 0;
                if (!CloudBlobHelpers.TryReadBlob <ReplicatedTableConfigurationStore>(blob.Value, out configurationStore))
                {
                    //This is the first time we are uploading the config
                    configurationStore = new ReplicatedTableConfigurationStore();
                }

                newViewId = configurationStore.ViewId + 1;

                configurationStore.LeaseDuration          = Constants.LeaseDurationInSec;
                configurationStore.Timestamp              = DateTime.UtcNow;
                configurationStore.ReplicaChain           = replicaChain;
                configurationStore.ReadViewHeadIndex      = readViewHeadIndex;
                configurationStore.ConvertXStoreTableMode = convertXStoreTableMode;

                configurationStore.ViewId = newViewId;

                //If the read view head index is not 0, this means we are introducing 1 or more replicas at the head. For
                //each such replica, update the view id in which it was added to the write view of the chain
                if (readViewHeadIndex != 0)
                {
                    for (int i = 0; i < readViewHeadIndex; i++)
                    {
                        replicaChain[i].ViewInWhichAddedToChain = newViewId;
                    }
                }

                try
                {
                    //Step 1: Delete the current configuration
                    blob.Value.UploadText(Constants.ConfigurationStoreUpdatingText);

                    //Step 2: Wait for L + CF to make sure no pending transaction working on old views
                    // Chunzhi: removed this, original code hangs here
                    // Matt: restore this: it's essential for consistency.
                    Thread.Sleep(TimeSpan.FromSeconds(Constants.LeaseDurationInSec +
                                                      Constants.ClockFactorInSec));

                    //Step 3: Update new config
                    blob.Value.UploadText(JsonStore <ReplicatedTableConfigurationStore> .Serialize(configurationStore));
                }
                catch (StorageException e)
                {
                    ReplicatedTableLogger.LogError("Updating the blob: {0} failed. Exception: {1}", blob.Value, e.Message);
                }
            });

            //Invalidate the lastViewRefreshTime so that updated views get returned
            this.lastViewRefreshTime = DateTime.MinValue;
        }
예제 #8
0
        /*
         * Class functions:
         */
        static internal protected CloudTableClient GetTableClientForReplica(ReplicaInfo replica)
        {
            CloudTableClient tableClient = null;

            if (!CloudBlobHelpers.TryCreateCloudTableClient(replica.ConnectionString, out tableClient))
            {
                ReplicatedTableLogger.LogError("No table client created for replica info: {0}", replica);
            }

            return(tableClient);
        }
예제 #9
0
        public static async Task <ReplicatedTableReadBlobResult> TryReadBlobAsync <T>(CloudBlockBlob blob, Action <T, string> callback, Func <string, T> ParseBlobFunc, CancellationToken ct)
            where T : class
        {
            try
            {
                BlobRequestOptions options = new BlobRequestOptions()
                {
                    ServerTimeout        = TimeSpan.FromSeconds(5),
                    MaximumExecutionTime = TimeSpan.FromSeconds(30)
                };
                string content = await blob.DownloadTextAsync(null, null, options, null, ct);

                if (content == Constants.ConfigurationStoreUpdatingText)
                {
                    return(new ReplicatedTableReadBlobResult(ReadBlobCode.UpdateInProgress, "Blob update in progress ..."));
                }

                // ParseBlobFunc != null
                T      configuration = ParseBlobFunc(content);
                string eTag          = blob.Properties.ETag;

                // callback != null
                callback(configuration, eTag);

                return(new ReplicatedTableReadBlobResult(ReadBlobCode.Success, ""));
            }
            catch (StorageException e)
            {
                var msg = string.Format("Error reading blob: {0}. StorageException: {1}", blob.Uri, e.Message);
                ReplicatedTableLogger.LogError(msg);

                if (e.RequestInformation != null &&
                    e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound)
                {
                    return(new ReplicatedTableReadBlobResult(ReadBlobCode.NotFound, msg));
                }

                return(new ReplicatedTableReadBlobResult(ReadBlobCode.StorageException, msg));
            }
            catch (OperationCanceledException)
            {
                var msg = string.Format("TryReadBlobAsync cancelled ({0})", blob.Uri);
                ReplicatedTableLogger.LogInformational(msg);

                return(new ReplicatedTableReadBlobResult(ReadBlobCode.Exception, msg));
            }
            catch (Exception e)
            {
                var msg = string.Format("Error reading blob: {0}. Exception: {1}", blob.Uri, e.Message);
                ReplicatedTableLogger.LogError(msg);

                return(new ReplicatedTableReadBlobResult(ReadBlobCode.Exception, msg));
            }
        }
예제 #10
0
        public StopWatchInternal(string tableName, string context, IReplicatedTableConfigurationWrapper replicatedTableConfigurationWrapper)
        {
            this._tableName = tableName;
            this._context   = context;

            if (replicatedTableConfigurationWrapper.IsIntrumentationEnabled())
            {
                ReplicatedTableLogger.LogVerbose("[Instrumentation] {0}:{1} started", _tableName, _context);

                _stopWatch = Stopwatch.StartNew();
            }
        }
예제 #11
0
파일: View.cs 프로젝트: isabella232/rtable
        public static View InitFromConfigVer1(string name, ReplicatedTableConfigurationStore configurationStore, Action <ReplicaInfo> SetConnectionString)
        {
            View view = new View(name);

            if (configurationStore != null)
            {
                view.ViewId        = configurationStore.ViewId;
                view.ReadHeadIndex = configurationStore.ReadViewHeadIndex;
                view.RefreshTime   = DateTime.UtcNow;

                foreach (ReplicaInfo replica in configurationStore.ReplicaChain)
                {
                    if (replica == null)
                    {
                        continue;
                    }

                    SetConnectionString(replica);

                    CloudTableClient tableClient = ReplicatedTableConfigurationManager.GetTableClientForReplica(replica);
                    if (tableClient == null)
                    {
                        // All replicas MUST exist or View is not relevant
                        view.Chain.Clear();

                        ReplicatedTableLogger.LogError("ViewName={0} could not load replica ({1})", name, replica);
                        break;
                    }

                    view.Chain.Add(new Tuple <ReplicaInfo, CloudTableClient>(replica, tableClient));
                }

                // If not configured use Tail. Chain must be defined at this point, so don't move this code up!
                view.ReadTailIndex = configurationStore.ReadViewTailIndex;
                if (view.ReadTailIndex < 0)
                {
                    view.ReadTailIndex = view.TailIndex;
                }

                if (!view.IsEmpty)
                {
                    ReplicaInfo head = view.GetReplicaInfo(0);
                    head.Status = ReplicaStatus.WriteOnly;

                    if (view.IsStable)
                    {
                        head.Status = ReplicaStatus.ReadWrite;
                    }
                }
            }

            return(view);
        }
예제 #12
0
        internal protected void MoveReplicaToHeadAndSetViewToReadOnly(string viewName, string storageAccountName)
        {
            // Assert (storageAccountName != null)

            int matchIndex = ReplicaChain.FindIndex(r => r.StorageAccountName == storageAccountName);

            if (matchIndex == -1)
            {
                return;
            }

            // - Ensure its status is *None*
            ReplicaInfo candidateReplica = ReplicaChain[matchIndex];

            var oldStatus = candidateReplica.Status;

            candidateReplica.Status = ReplicaStatus.None;

            // First check it will be possible to modify the sequence
            foreach (ReplicaInfo replica in GetCurrentReplicaChain())
            {
                // Change is not possible
                if (replica.Status == ReplicaStatus.WriteOnly)
                {
                    // Restore previous status
                    candidateReplica.Status = oldStatus;

                    var msg = string.Format("View:\'{0}\' : can't set a WriteOnly replica to ReadOnly !!!", viewName);

                    ReplicatedTableLogger.LogError(msg);
                    throw new Exception(msg);
                }
            }

            // Do the change ...

            // - Move it to the front of the chain
            ReplicaChain.RemoveAt(matchIndex);
            ReplicaChain.Insert(0, candidateReplica);

            // Set all active replicas to *ReadOnly*
            foreach (ReplicaInfo replica in GetCurrentReplicaChain())
            {
                replica.Status = ReplicaStatus.ReadOnly;
            }

            // Update view id
            ViewId++;

            // Reset 'ReadViewTailIndex' => user has to set it again
            ResetReadViewTailIndex();
        }
예제 #13
0
        public void TurnReplicaOff(string storageAccountName)
        {
            if (string.IsNullOrEmpty(storageAccountName))
            {
                throw new ArgumentNullException("storageAccountName");
            }

            ReplicatedTableConfiguration configuration = null;

            // - Retrieve configuration ...
            ReplicatedTableQuorumReadResult readResult = RetrieveConfiguration(out configuration);

            if (readResult.Code != ReplicatedTableQuorumReadCode.Success)
            {
                var msg = string.Format("TurnReplicaOff={0}: failed to read configuration, \n{1}", storageAccountName, readResult.ToString());

                ReplicatedTableLogger.LogError(msg);
                throw new Exception(msg);
            }

            // - Parse/Update all views ...
            foreach (var viewConf in configuration.viewMap.Values)
            {
                var foundReplicas = viewConf.GetCurrentReplicaChain()
                                    .FindAll(r => r.StorageAccountName == storageAccountName);

                if (!foundReplicas.Any())
                {
                    continue;
                }

                foreach (var replica in foundReplicas)
                {
                    replica.Status            = ReplicaStatus.None;
                    replica.ViewWhenTurnedOff = viewConf.ViewId;
                }

                // Update view id
                viewConf.ViewId++;
            }

            // - Write back configuration ...
            ReplicatedTableQuorumWriteResult writeResult = UpdateConfigurationInternal(configuration, true);

            if (writeResult.Code != ReplicatedTableQuorumWriteCode.Success)
            {
                var msg = string.Format("TurnReplicaOff={0}: failed to update configuration, \n{1}", storageAccountName, writeResult.ToString());

                ReplicatedTableLogger.LogError(msg);
                throw new Exception(msg);
            }
        }
예제 #14
0
        public View GetTableView(string tableName)
        {
            ReplicatedTableConfiguredTable config;

            if (IsConfiguredTable(tableName, out config))
            {
                return(GetView(config.ViewName));
            }

            var msg = string.Format("Table={0}: is not configured!", tableName);

            ReplicatedTableLogger.LogError(msg);
            throw new Exception(msg);
        }
        private bool DoesViewNeedRefresh()
        {
            lock (this)
            {
                if ((DateTime.UtcNow - this.lastViewRefreshTime) >
                    TimeSpan.FromSeconds(Constants.LeaseRenewalIntervalInSec))
                {
                    ReplicatedTableLogger.LogInformational("Need to renew lease on the view/refresh the view");
                    return(true);
                }

                return(false);
            }
        }
예제 #16
0
        public bool ConvertToRTable(string tableName)
        {
            ReplicatedTableConfiguredTable config;

            if (IsConfiguredTable(tableName, out config))
            {
                return(config.ConvertToRTable);
            }

            var msg = string.Format("Table={0}: is not configured!", tableName);

            ReplicatedTableLogger.LogError(msg);
            throw new Exception(msg);
        }
        private CloudTableClient GetTableClientForReplica(ReplicaInfo replica)
        {
            string connectionString = String.Format(cloudStorageAccountTemplate,
                                                    this.useHttps ? "https" : "http",
                                                    replica.StorageAccountName,
                                                    replica.StorageAccountKey);

            CloudTableClient tableClient = null;

            if (!CloudBlobHelpers.TryCreateCloudTableClient(connectionString, out tableClient))
            {
                ReplicatedTableLogger.LogError("No table client created for replica info: {0}", replica);
            }

            return(tableClient);
        }
예제 #18
0
        public static ReplicatedTableReadBlobResult TryReadBlob <T>(CloudBlockBlob blob, out T configuration, out string eTag, Func <string, T> ParseBlobFunc)
            where T : class
        {
            configuration = default(T);
            eTag          = null;

            try
            {
                BlobRequestOptions options = new BlobRequestOptions()
                {
                    ServerTimeout        = TimeSpan.FromSeconds(5),
                    MaximumExecutionTime = TimeSpan.FromSeconds(30)
                };
                string content = blob.DownloadText(null, null, options, null);
                if (content == Constants.ConfigurationStoreUpdatingText)
                {
                    return(new ReplicatedTableReadBlobResult(ReadBlobCode.UpdateInProgress, "Blob update in progress ..."));
                }

                configuration = ParseBlobFunc(content);
                eTag          = blob.Properties.ETag;

                return(new ReplicatedTableReadBlobResult(ReadBlobCode.Success, ""));
            }
            catch (StorageException e)
            {
                var msg = string.Format("Error reading blob: {0}. StorageException: {1}", blob.Uri, e.Message);
                ReplicatedTableLogger.LogError(msg);

                if (e.RequestInformation != null &&
                    e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound)
                {
                    return(new ReplicatedTableReadBlobResult(ReadBlobCode.NotFound, msg));
                }

                return(new ReplicatedTableReadBlobResult(ReadBlobCode.StorageException, msg));
            }
            catch (Exception e)
            {
                var msg = string.Format("Error reading blob: {0}. Exception: {1}", blob.Uri, e.Message);
                ReplicatedTableLogger.LogError(msg);

                return(new ReplicatedTableReadBlobResult(ReadBlobCode.Exception, msg));
            }
        }
예제 #19
0
        public static void TryWriteBlob(CloudBlockBlob blob, string content)
        {
            try
            {
                //Step 1: Delete the current configuration
                blob.UploadText(Constants.ConfigurationStoreUpdatingText);

                //Step 2: Wait for L + CF to make sure no pending transaction working on old views
                Thread.Sleep(TimeSpan.FromSeconds(Constants.LeaseDurationInSec + Constants.ClockFactorInSec));

                //Step 3: Update new config
                blob.UploadText(content);
            }
            catch (StorageException e)
            {
                ReplicatedTableLogger.LogError("Updating the blob: {0} failed. Exception: {1}", blob, e.Message);
            }
        }
예제 #20
0
        /*
         * Configuration management APIs
         */
        public ReplicatedTableQuorumReadResult RetrieveConfiguration(out ReplicatedTableConfiguration configuration)
        {
            List <string> eTags;

            ReplicatedTableQuorumReadResult
                result = CloudBlobHelpers.TryReadBlobQuorum(
                this.configManager.GetBlobs(),
                out configuration,
                out eTags,
                ReplicatedTableConfiguration.FromJson);

            if (result.Code != ReplicatedTableQuorumReadCode.Success)
            {
                ReplicatedTableLogger.LogError("Failed to read configuration, \n{0}", result.ToString());
            }

            return(result);
        }
예제 #21
0
        public static bool TryCreateCloudTableClient(string storageAccountConnectionString,
                                                     out CloudTableClient cloudTableClient)
        {
            cloudTableClient = null;

            try
            {
                cloudTableClient = CloudStorageAccount.Parse(storageAccountConnectionString).CreateCloudTableClient();
                return(true);
            }
            catch (Exception e)
            {
                ReplicatedTableLogger.LogError("Error creating cloud table client: Connection string {0}. Exception: {1}",
                                               storageAccountConnectionString,
                                               e.Message);
            }

            return(false);
        }
예제 #22
0
        private void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }

            if (disposing)
            {
                if (_stopWatch != null)
                {
                    _stopWatch.Stop();

                    ReplicatedTableLogger.LogVerbose("[Instrumentation] {0}:{1} took {2} ms", _tableName, _context, _stopWatch.ElapsedMilliseconds);
                }
            }

            _disposed = true;
        }
예제 #23
0
        public ReplicatedTableQuorumWriteResult UploadConfigurationToBlobs(List <int> blobIndexes, ReplicatedTableConfiguration configuration)
        {
            if (blobIndexes == null || !blobIndexes.Any())
            {
                throw new ArgumentNullException("blobIndexes");
            }

            if (configuration == null)
            {
                throw new ArgumentNullException("configuration");
            }

            List <CloudBlockBlob> blobs = new List <CloudBlockBlob>();

            foreach (var blobIndex in blobIndexes)
            {
                if (blobIndex < this.configManager.GetBlobs().Count)
                {
                    blobs.Add(this.configManager.GetBlobs()[blobIndex]);
                    continue;
                }

                var msg = string.Format("blobIndex={0} >= BlobCount={1}", blobIndex, this.configManager.GetBlobs().Count);

                ReplicatedTableLogger.LogError(msg);
                throw new Exception(msg);
            }

            SanitizeConfiguration(configuration);

            // - Upload to blobs ...
            ReplicatedTableQuorumWriteResult result = CloudBlobHelpers.TryUploadBlobs(blobs, configuration);

            this.configManager.Invalidate();

            if (result.Code != ReplicatedTableQuorumWriteCode.Success)
            {
                ReplicatedTableLogger.LogError("Failed to upload configuration to blobs, \n{0}", result.ToString());
            }

            return(result);
        }
예제 #24
0
        public static ReplicatedTableWriteBlobResult TryWriteBlob(CloudBlockBlob blob, string content, string eTag)
        {
            try
            {
                AccessCondition condition = string.IsNullOrEmpty(eTag)
                                                ? AccessCondition.GenerateEmptyCondition()
                                                : AccessCondition.GenerateIfMatchCondition(eTag);

                blob.UploadText(content, accessCondition: condition);

                return(new ReplicatedTableWriteBlobResult(true, ""));
            }
            catch (StorageException e)
            {
                var msg = string.Format("Updating the blob: {0} failed. Exception: {1}", blob, e.Message);

                ReplicatedTableLogger.LogError(msg);
                return(new ReplicatedTableWriteBlobResult(false, msg));
            }
        }
예제 #25
0
        /// <summary>
        /// Convert SecureString to String
        /// </summary>
        /// <param name="secureText"></param>
        /// <returns></returns>
        public static string ToString(SecureString secureText)
        {
            IntPtr unmanagedPtr = IntPtr.Zero;

            try
            {
                unmanagedPtr = Marshal.SecureStringToGlobalAllocUnicode(secureText);
                return(Marshal.PtrToStringUni(unmanagedPtr));
            }
            catch (Exception ex)
            {
                ReplicatedTableLogger.LogError("Exception converting from SecureString : {0}", ex);
            }
            finally
            {
                Marshal.ZeroFreeGlobalAllocUnicode(unmanagedPtr);
            }

            return(null);
        }
예제 #26
0
        public static bool TryCreateCloudTableClient(SecureString connectionString, out CloudTableClient cloudTableClient)
        {
            cloudTableClient = null;

            try
            {
                string decryptConnectionString = SecureStringHelper.ToString(connectionString);
                cloudTableClient = CloudStorageAccount.Parse(decryptConnectionString).CreateCloudTableClient();

                return(true);
            }
            catch (Exception e)
            {
                ReplicatedTableLogger.LogError(
                    "Error creating cloud table client: Connection string {0}. Exception: {1}",
                    "********",
                    e.Message);
            }

            return(false);
        }
예제 #27
0
파일: View.cs 프로젝트: isabella232/rtable
        public static View InitFromConfigVer2(string name, ReplicatedTableConfigurationStore configurationStore, Action <ReplicaInfo> SetConnectionString)
        {
            View view = new View(name);

            if (configurationStore != null)
            {
                view.ViewId      = configurationStore.ViewId;
                view.RefreshTime = DateTime.UtcNow;

                foreach (ReplicaInfo replica in configurationStore.GetCurrentReplicaChain())
                {
                    SetConnectionString(replica);

                    CloudTableClient tableClient = ReplicatedTableConfigurationManager.GetTableClientForReplica(replica);
                    if (tableClient == null)
                    {
                        // All replicas MUST exist or View is not relevant
                        view.Chain.Clear();

                        ReplicatedTableLogger.LogError("ViewName={0} could not load replica ({1})", name, replica);
                        break;
                    }

                    view.Chain.Add(new Tuple <ReplicaInfo, CloudTableClient>(replica, tableClient));
                }

                // Infered: first readable replica
                view.ReadHeadIndex = view.Chain.FindIndex(tuple => tuple.Item1.IsReadable());

                // If not configured use Tail. Chain must be defined at this point, so don't move this code up!
                view.ReadTailIndex = configurationStore.ReadViewTailIndex;
                if (view.ReadTailIndex < 0)
                {
                    view.ReadTailIndex = view.TailIndex;
                }
            }

            return(view);
        }
        public bool IsTableViewStable(string tableName, string viewToUse = null)
        {
            ReplicatedTableConfiguredTable config;

            if (IsConfiguredTable(tableName, out config))
            {
                // Use table default view
                if (string.IsNullOrEmpty(viewToUse))
                {
                    viewToUse = config.ViewName;
                }

                if (config.IsViewReferenced(viewToUse))
                {
                    return(IsViewStable(viewToUse));
                }
            }

            var msg = string.Format("Table={0}: is not configured or ViewToUse={1} is not referenced!", tableName, viewToUse);

            ReplicatedTableLogger.LogError(msg);
            throw new Exception(msg);
        }
        internal protected void MoveReplicaToHeadAndSetViewToReadOnly(string viewName, string storageAccountName)
        {
            // Assert (storageAccountName != null)

            int matchIndex = ReplicaChain.FindIndex(r => r.StorageAccountName == storageAccountName);

            if (matchIndex == -1)
            {
                return;
            }

            // - Ensure its status is *None*
            ReplicaInfo candidateReplica = ReplicaChain[matchIndex];

            candidateReplica.Status = ReplicaStatus.None;

            // - Move it to the front of the chain
            ReplicaChain.RemoveAt(matchIndex);
            ReplicaChain.Insert(0, candidateReplica);

            // Set all active replicas to *ReadOnly*
            foreach (ReplicaInfo replica in GetCurrentReplicaChain())
            {
                if (replica.Status == ReplicaStatus.WriteOnly)
                {
                    var msg = string.Format("View:\'{0}\' : can't set a WriteOnly replica to ReadOnly !!!", viewName);

                    ReplicatedTableLogger.LogError(msg);
                    throw new Exception(msg);
                }

                replica.Status = ReplicaStatus.ReadOnly;
            }

            // Update view id
            ViewId++;
        }
예제 #30
0
        private void SaveConfigAndRefreshItsIdAndValidateIsLoaded(ReplicatedTableConfiguration configuration, string iteration, bool validateConfigIsLoaded = true)
        {
            string msg = "";

            ReplicatedTableQuorumWriteResult writeResult = UpdateConfigurationInternal(configuration, true);

            if (writeResult.Code != ReplicatedTableQuorumWriteCode.Success)
            {
                msg = string.Format("{0} : Failed to update configuration, \n{1}", iteration, writeResult.ToString());

                ReplicatedTableLogger.LogError(msg);
                throw new Exception(msg);
            }

            // Update config with new Id
            configuration.Id = new Guid(writeResult.Message);

            // do we need to validate if the config is loaded by the config manager ?
            if (!validateConfigIsLoaded)
            {
                return;
            }

            // - Confirm the new config is the current loaded into the RTable config manager
            if (configuration.Id == this.configManager.GetCurrentRunningConfigId())
            {
                return;
            }

            msg = string.Format("{0} : ConfigId({1}) != currently running configurationId({2})",
                                iteration,
                                configuration.Id,
                                this.configManager.GetCurrentRunningConfigId());

            ReplicatedTableLogger.LogError(msg);
            throw new Exception(msg);
        }