/// <summary>
        /// Create storage blob container.
        /// </summary>
        /// <param name="container">blob container</param>
        public static void CreateContainerWithRetry(CloudBlobContainer container)
        {
            RetryHelper <object> .InvokeOperation(
                () =>
            {
                if (container.CreateIfNotExists())
                {
                    BrokerTracing.TraceInfo("[AzureQueueManager].CreateContainerWithRetry: Create the container {0}", container.Name);
                }

                return(null);
            },
                (e, count) =>
            {
                BrokerTracing.TraceError("Failed to create the container {0}: {1}. Retry Count = {2}", container.Name, e, count);

                StorageException se = e as StorageException;

                if (se != null)
                {
                    string errorCode = BurstUtility.GetStorageErrorCode(se);

                    // According to test, the error code is ResourceAlreadyExists.
                    // There is no doc about this, add ContainerAlreadyExists here.

                    // TODO: Azure storage SDK 2.0
                    if (         // errorCode == StorageErrorCodeStrings.ResourceAlreadyExists ||
                        errorCode == StorageErrorCodeStrings.ContainerAlreadyExists)
                    {
                        Thread.Sleep(TimeSpan.FromMinutes(1));
                    }
                }
            });
        }
        /// <summary>
        /// Create storage queue
        /// </summary>
        /// <param name="queue">storage queue</param>
        /// <remarks>
        /// CreateIfNotExist method throws StorageClientException when queue is
        /// being deleted, so sleep for a while before retry.
        /// </remarks>
        public static void CreateQueueWithRetry(CloudQueue queue)
        {
            RetryHelper <object> .InvokeOperation(
                () =>
            {
                if (queue.CreateIfNotExists())
                {
                    BrokerTracing.TraceInfo("[AzureQueueManager].CreateQueueWithRetry: Create the queue {0}", queue.Name);
                }

                return(null);
            },
                (e, count) =>
            {
                BrokerTracing.TraceError("Failed to create the queue {0}: {1}. Retry Count = {2}", queue.Name, e, count);

                StorageException se = e as StorageException;

                if (se != null)
                {
                    if (BurstUtility.GetStorageErrorCode(se) == QueueErrorCodeStrings.QueueAlreadyExists)
                    {
                        Thread.Sleep(TimeSpan.FromMinutes(1));
                    }
                }
            });
        }
Exemple #3
0
        /// <summary>
        /// Open the broker launcher service
        /// </summary>
        public void OpenService()
        {
            Trace.TraceInformation("Open service.");
            //TODO: SF: remove the singleton implementation
            //SingletonRegistry.Initialize(SingletonRegistry.RegistryMode.WindowsNonHA);

            // for debug attach
            //Thread.Sleep(60 * 1000);
            bool isOnAzure = SoaHelper.IsOnAzure();

            if (isOnAzure)
            {
                this.StartNodeMappingCacheService();
            }

            try
            {
                // richci: if this is a console application we are running in MSCS in production. Make
                // sure only one instance of the console app is running at a time.
                if (!isOnAzure && IsConsoleApplication && !AcquireSingleProcessLock())
                {
                    // If another instance already created the mutex, release this handle
                    ReleaseSingleProcessLock();
                    throw new InvalidOperationException("Only one instance of the process can be run a time");
                }

                if (false) //!isOnAzure && !IsConsoleApplication && Win32API.IsFailoverBrokerNode())
                {
                    //
                    // If this is a brokerlauncher service running as service on a failover BN, dont
                    // open WCF endpoints. In this configuration, the broker launcher windows service is
                    // for mgmt operations only. All application traffic will go through brokerlaunchers
                    // running as console apps in MSCS resource groups
                    //
                    // Otherwise this a HpcBroker windows service on FO BN handling mgmt operations only
                    //

                    this.launcherInstance = new BrokerLauncher(true, this.context);
                }
                else
                {
                    Trace.TraceInformation("Open broker launcher service host.");
                    this.launcherInstance = new BrokerLauncher(false, this.context);
                    this.launcherHost     = new ServiceHost(this.launcherInstance, new Uri(SoaHelper.GetBrokerLauncherAddress(HostName)));
                    BindingHelper.ApplyDefaultThrottlingBehavior(this.launcherHost);
                    this.launcherHost.AddServiceEndpoint(typeof(IBrokerLauncher), BindingHelper.HardCodedUnSecureNetTcpBinding, string.Empty);
                    this.launcherHost.AddServiceEndpoint(typeof(IBrokerLauncher), BindingHelper.HardCodedUnSecureNetTcpBinding, "Internal");
                    this.launcherHost.AddServiceEndpoint(typeof(IBrokerLauncher), BindingHelper.HardCodedUnSecureNetTcpBinding, "AAD");
                    // this.launcherHost.Credentials.UseInternalAuthenticationAsync(true).GetAwaiter().GetResult();
                    string addFormat = SoaHelper.BrokerLauncherAadAddressFormat;
                    ServiceAuthorizationBehavior myServiceBehavior = this.launcherHost.Description.Behaviors.Find <ServiceAuthorizationBehavior>();
                    myServiceBehavior.PrincipalPermissionMode = PrincipalPermissionMode.None;
                    this.launcherHost.Open();

                    if (BrokerLauncherSettings.Default.EnableAzureStorageQueueEndpoint)
                    {
                        if (string.IsNullOrEmpty(BrokerLauncherSettings.Default.AzureStorageConnectionString))
                        {
                            Trace.TraceError("AzureStorageConnectionString is null or empty while EnableAzureStorageQueueEndpoint is set to true");
                        }
                        else
                        {
                            this.watcher = new BrokerLauncherCloudQueueWatcher(this.launcherInstance, BrokerLauncherSettings.Default.AzureStorageConnectionString);
                        }
                    }

                    Trace.TraceInformation("Open broker launcher service succeeded.");
                    TraceHelper.TraceEvent(TraceEventType.Information, "Open broker launcher service succeeded.");

                    if (SoaHelper.IsSchedulerOnAzure())
                    {
                        // Broker service is enabled on scheduler node for on-premise and scheduler on Azure cluster.
                        // SoaDiagSvc is not expected to run on the Azure cluster.
                        return;
                    }

                    ISchedulerHelper helper = SchedulerHelperFactory.GetSchedulerHelper(this.context);
#if HPCPACK
                    ThreadPool.QueueUserWorkItem(
                        (object state) =>
                    {
                        try
                        {
                            RetryHelper <object> .InvokeOperation(
                                () =>
                            {
                                this.soaDiagAuthenticator          = new SoaDiagAuthenticator();
                                SoaDiagService diagServiceInstance = new SoaDiagService(helper.GetClusterInfoAsync, this.soaDiagAuthenticator);
                                this.diagServiceHost = new ServiceHost(
                                    diagServiceInstance,
#if DEBUG
                                    new Uri("http://localhost/SoaDiagService"),
#endif
                                    new Uri(SoaHelper.GetDiagServiceAddress(HostName)));

                                BindingHelper.ApplyDefaultThrottlingBehavior(this.diagServiceHost, SoaDiagSvcMaxConcurrentCalls);
                                var endpoint = this.diagServiceHost.AddServiceEndpoint(typeof(ISoaDiagService), BindingHelper.HardCodedDiagServiceNetTcpBinding, string.Empty);
                                endpoint.Behaviors.Add(new SoaDiagServiceErrorHandler());
#if DEBUG
                                var httpEndpoint = this.diagServiceHost.AddServiceEndpoint(typeof(ISoaDiagService), new BasicHttpBinding(), string.Empty);
                                httpEndpoint.Behaviors.Add(new SoaDiagServiceErrorHandler());
#endif
                                this.diagServiceHost.Open();
                                TraceHelper.TraceEvent(TraceEventType.Information, "Open soa diag service succeeded.");

                                this.cleanupService = new DiagCleanupService(helper.GetClusterInfoAsync);
                                this.cleanupService.Start();
                                TraceHelper.TraceEvent(TraceEventType.Information, "Open soa diag cleanup service succeeded.");
                                return(null);
                            },
                                (ex, count) =>
                            {
                                TraceHelper.TraceEvent(TraceEventType.Error, "Failed to open soa diag service: {0}. Retry Count = {1}", ex, count);
                                this.CloseSoaDiagService();
                                Thread.Sleep(RetryPeriod);
                            });
                        }
                        catch (Exception e)
                        {
                            TraceHelper.TraceEvent(TraceEventType.Error, "Failed to open soa diag service after all retry: {0}", e);
                        }
                    });
#endif

#if HPCPACK
                    ThreadPool.QueueUserWorkItem((object state) =>
                    {
                        try
                        {
                            RetryHelper <object> .InvokeOperation(
                                () =>
                            {
                                this.azureStorageCleaner = new AzureStorageCleaner(helper);

                                this.azureStorageCleaner.Start();

                                TraceHelper.TraceEvent(TraceEventType.Information,
                                                       "Open Azure storage cleanup service succeeded.");

                                return(null);
                            },
                                (ex, count) =>
                            {
                                TraceHelper.TraceEvent(
                                    TraceEventType.Error,
                                    "Failed to open Azure storage cleanup service: {0}. Retry Count = {1}",
                                    ex,
                                    count);

                                if (this.azureStorageCleaner != null)
                                {
                                    this.azureStorageCleaner.Close();
                                }

                                Thread.Sleep(RetryPeriod);
                            });
                        }
                        catch (Exception e)
                        {
                            TraceHelper.TraceEvent(TraceEventType.Error,
                                                   "Failed to open Azure storage cleanup service after all retry: {0}", e);
                        }
                    });
#endif
                }
            }
            catch (Exception e)
            {
                TraceHelper.TraceEvent(TraceEventType.Critical, "Failed to open service: {0}", e);
                throw;
            }
        }