Ejemplo n.º 1
0
        /// <summary>
        /// Gets the custom broker registration from service registration file
        /// </summary>
        /// <param name="serviceRegistrationPath">indicating the path of the service registration file</param>
        /// <returns>returns the instance of CustomBrokerRegistration class</returns>
        private static CustomBrokerRegistration GetCustomBroker(string serviceRegistrationPath)
        {
            try
            {
                ExeConfigurationFileMap map = new ExeConfigurationFileMap();
                map.ExeConfigFilename = serviceRegistrationPath;
                Configuration config = null;
                RetryManager.RetryOnceAsync(
                    () => config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None),
                    TimeSpan.FromSeconds(1),
                    ex => ex is ConfigurationErrorsException)
                .GetAwaiter()
                .GetResult();
                BrokerConfigurations brokerConfig = BrokerConfigurations.GetSectionGroup(config);
                if (brokerConfig == null)
                {
                    return(null);
                }
                else
                {
                    return(brokerConfig.CustomBroker);
                }
            }
            catch (ConfigurationErrorsException e)
            {
                ThrowHelper.ThrowSessionFault(SOAFaultCode.ConfigFile_Invalid,
                                              "{0}",
                                              e.ToString());

                return(null);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Initializes static members of the BlobBasedDataContainer class
        /// </summary>
        static BlobBasedDataContainer()
        {
            AppDomain.CurrentDomain.AssemblyResolve += ResolveHandler;

            ServicePointManager.DefaultConnectionLimit = ServicePointManagerConnectionLimit;
            ServicePointManager.Expect100Continue      = false;
            ServicePointManager.UseNagleAlgorithm      = false;

            ExeConfigurationFileMap map = new ExeConfigurationFileMap();

            map.ExeConfigFilename = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            Configuration config = null;

            RetryManager.RetryOnceAsync(
                () => config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None),
                TimeSpan.FromSeconds(1),
                ex => ex is ConfigurationErrorsException)
            .GetAwaiter()
            .GetResult();
            Debug.Assert(config != null, "Configuration is not opened properly.");
            DataContainerConfiguration dataProviderConfig = DataContainerConfiguration.GetSection(config);

            downloadBlobThreadCount         = dataProviderConfig.DownloadBlobThreadCount;
            downloadBlobMinBackoffInSeconds = dataProviderConfig.DownloadBlobMinBackOffInSeconds;
            downloadBlobMaxBackoffInSeconds = dataProviderConfig.DownloadBlobMaxBackOffInSeconds;
            downloadBlobRetryCount          = dataProviderConfig.DownloadBlobRetryCount;
            downloadBlobTimeoutInSeconds    = dataProviderConfig.DownloadBlobTimeoutInSeconds;

            TraceHelper.TraceSource.TraceEvent(
                TraceEventType.Information,
                0,
                "[BlobDataContainer] .static constructor: downloadBlobThreadCount={0}, downloadBlobMinBackoffInSeconds={1}, downloadBlobMaxBackoffInSeconds={2}, downloadBlobRetryCount={3}, downloadBlobTimeoutInSeconds={4}",
                downloadBlobThreadCount,
                downloadBlobMinBackoffInSeconds,
                downloadBlobMaxBackoffInSeconds,
                downloadBlobRetryCount,
                downloadBlobTimeoutInSeconds);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Try get epr list from application configuration file
        /// returns null if no such configuration section found or enabled is set to false
        /// </summary>
        /// <returns>returns the epr list if debug mode is enabled</returns>
        public static string[] TryGetEprList()
        {
            ExeConfigurationFileMap map = new ExeConfigurationFileMap();

            map.ExeConfigFilename = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            Configuration config = null;

            RetryManager.RetryOnceAsync(
                () => config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None),
                TimeSpan.FromSeconds(1),
                ex => ex is ConfigurationErrorsException)
            .GetAwaiter()
            .GetResult();
            Debug.Assert(config != null, "Configuration is not opened properly.");
            SessionConfigurations sessionConfig = SessionConfigurations.GetSectionGroup(config);

            if (sessionConfig != null && sessionConfig.DebugMode != null)
            {
                if (sessionConfig.DebugMode.Enabled)
                {
                    List <string> eprList = new List <string>();
                    foreach (object element in sessionConfig.DebugMode.EprCollection)
                    {
                        EprElement epr = element as EprElement;
                        if (epr == null)
                        {
                            continue;
                        }

                        eprList.Add(epr.Epr);
                    }

                    return(eprList.ToArray());
                }
            }

            return(null);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Allocate a new durable or non-durable session
        /// </summary>
        /// <param name="startInfo">session start info</param>
        /// <param name="durable">whether session should be durable</param>
        /// <param name="endpointPrefix">the endpoint prefix, net.tcp:// or https:// </param>
        /// <returns>the Broker Launcher EPRs, sorted by the preference.</returns>
        protected virtual async Task <SessionAllocateInfoContract> AllocateInternalAsync(SessionStartInfoContract startInfo, string endpointPrefix, bool durable)
        {
            TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] Begin: AllocateInternalAsync");
            SessionAllocateInfoContract sessionAllocateInfo = new SessionAllocateInfoContract();

            ParamCheckUtility.ThrowIfNull(startInfo, "startInfo");
            ParamCheckUtility.ThrowIfNullOrEmpty(startInfo.ServiceName, "startInfo.ServiceName");
            ParamCheckUtility.ThrowIfNullOrEmpty(endpointPrefix, "endpointPrefix");

#if HPCPACK
            // check client api version, 4.3 or older client is not supported by 4.4 server for the broken changes
            if (startInfo.ClientVersion == null || startInfo.ClientVersion < new Version(4, 4))
            {
                TraceHelper.TraceEvent(TraceEventType.Error,
                                       "[SessionLauncher] .AllocateInternalAsync: ClientVersion {0} does not match ServerVersion {1}.", startInfo.ClientVersion, ServerVersion);

                ThrowHelper.ThrowSessionFault(SOAFaultCode.ClientServerVersionMismatch,
                                              SR.SessionLauncher_ClientServerVersionMismatch,
                                              startInfo.ClientVersion == null ? "NULL" : startInfo.ClientVersion.ToString(),
                                              ServerVersion.ToString());
            }
#endif

            // Init service version to the service version passed in
            if (startInfo.ServiceVersion != null)
            {
                sessionAllocateInfo.ServiceVersion = startInfo.ServiceVersion;
                TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] .AllocateInternalAsync: Original service version is {0}", sessionAllocateInfo.ServiceVersion);
            }
            else
            {
                sessionAllocateInfo.ServiceVersion = null;
                TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] .AllocateInternalAsync: Original service version is null.");
            }

            string callId = Guid.NewGuid().ToString();
            this.CheckAccess();

            SecureString securePassword = CreateSecureString(startInfo.Password);
            startInfo.Password = null;

            // BUG 4522 : Use CCP_SCHEDULER when referencing service registration file share so HA HN virtual name is used when needed
            //var reliableRegistry = new ReliableRegistry(this.fabricClient.PropertyManager);
            //string defaultServiceRegistrationServerName = await reliableRegistry.GetValueAsync<string>(HpcConstants.HpcFullKeyName, HpcConstants.FileShareServerRegVal, this.token);

            //if (String.IsNullOrEmpty(defaultServiceRegistrationServerName))
            //{
            //    defaultServiceRegistrationServerName = "localhost";
            //}

            // the reg repo path is from scheduler environments, defaultServiceRegistrationServerName is actually not used

            string serviceConfigFile;
            ServiceRegistrationRepo serviceRegistration = this.GetRegistrationRepo(callId);
            serviceConfigFile = serviceRegistration.GetServiceRegistrationPath(startInfo.ServiceName, startInfo.ServiceVersion);

            // If the serviceConfigFile wasnt found and serviceversion isnt specified, try getitng the service config based on the service's latest version
            if (string.IsNullOrEmpty(serviceConfigFile) && (startInfo.ServiceVersion == null))
            {
                TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] .AllocateInternalAsync: Try to find out versioned service.");

                // Get service version in ServiceRegistrationRepo
                Version dynamicServiceVersion = serviceRegistration.GetServiceVersionInternal(startInfo.ServiceName, false);

                if (dynamicServiceVersion != null)
                {
                    TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] .AllocateInternalAsync: Selected dynamicServiceVersion is {0}.", dynamicServiceVersion.ToString());
                }

                serviceConfigFile = serviceRegistration.GetServiceRegistrationPath(startInfo.ServiceName, dynamicServiceVersion);

                // If a config file is found, update the serviceVersion that is returned to client and stored in recovery info
                if (!string.IsNullOrEmpty(serviceConfigFile))
                {
                    TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] .AllocateInternalAsync: serviceConfigFile is {0}.", serviceConfigFile);

                    startInfo.ServiceVersion = dynamicServiceVersion;

                    if (dynamicServiceVersion != null)
                    {
                        sessionAllocateInfo.ServiceVersion = dynamicServiceVersion;
                    }
                }
            }

            string serviceName = ServiceRegistrationRepo.GetServiceRegistrationFileName(startInfo.ServiceName, startInfo.ServiceVersion);
            TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] .AllocateInternalAsync: Service name = {0}, Configuration file = {1}", serviceName, serviceConfigFile);

            // If the service is not found and user code doesn't specify
            // version, we will use the latest version.
            if (string.IsNullOrEmpty(serviceConfigFile))
            {
                if (startInfo.ServiceVersion != null)
                {
                    ThrowHelper.ThrowSessionFault(SOAFaultCode.ServiceVersion_NotFound, SR.SessionLauncher_ServiceVersionNotFound, startInfo.ServiceName, startInfo.ServiceVersion.ToString());
                }
                else
                {
                    ThrowHelper.ThrowSessionFault(SOAFaultCode.Service_NotFound, SR.SessionLauncher_ServiceNotFound, startInfo.ServiceName);
                }
            }

            ExeConfigurationFileMap map = new ExeConfigurationFileMap();
            map.ExeConfigFilename = serviceConfigFile;

            ServiceRegistration  registration         = null;
            BrokerConfigurations brokerConfigurations = null;
            string hostpath         = null;
            string traceSwitchValue = null;

            try
            {
                Configuration config = null;

                RetryManager.RetryOnceAsync(
                    () => config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None),
                    TimeSpan.FromSeconds(1),
                    ex => ex is ConfigurationErrorsException).GetAwaiter().GetResult();

                Debug.Assert(config != null, "Configuration is not opened properly.");
                registration         = ServiceRegistration.GetSectionGroup(config);
                brokerConfigurations = BrokerConfigurations.GetSectionGroup(config);

                if (registration != null && registration.Host != null && registration.Host.Path != null)
                {
                    hostpath = registration.Host.Path;
                }
                else
                {
                    // x86 or x64
                    hostpath = registration.Service.Architecture == ServiceArch.X86 ? TaskCommandLine32 : TaskCommandLine64;
                }

                traceSwitchValue = registration.Service.SoaDiagTraceLevel;

                // TODO: should deprecate the previous settings
                if (string.IsNullOrEmpty(traceSwitchValue))
                {
                    traceSwitchValue = ConfigurationHelper.GetTraceSwitchValue(config);
                }
            }
            catch (ConfigurationErrorsException e)
            {
                ThrowHelper.ThrowSessionFault(SOAFaultCode.ConfigFile_Invalid, SR.SessionLauncher_ConfigFileInvalid, e.ToString());
            }
            catch (Exception ex)
            {
                TraceHelper.TraceEvent(TraceEventType.Error, ex.ToString());
                throw;
            }

            // after figuring out the service and version, and the session pool size, we check if the service pool already has the instance.
            sessionAllocateInfo.Id          = "0";
            sessionAllocateInfo.SessionInfo = null;
            if (startInfo.UseSessionPool)
            {
                if (this.TryGetSessionAllocateInfoFromPooled(endpointPrefix, durable, sessionAllocateInfo, serviceConfigFile, registration, out var allocateInternal))
                {
                    return(allocateInternal);
                }
            }

            // for sessions to add in session pool
            try
            {
                var sessionAllocateInfoContract = await this.CreateAndSubmitSessionJob(
                    startInfo,
                    endpointPrefix,
                    durable,
                    callId,
                    securePassword,
                    registration,
                    sessionAllocateInfo,
                    traceSwitchValue,
                    serviceName,
                    brokerConfigurations,
                    hostpath);

                if (sessionAllocateInfoContract != null)
                {
                    return(sessionAllocateInfoContract);
                }
            }
            finally
            {
                // Add the submitted job to the session pool.
                if (startInfo.UseSessionPool)
                {
                    this.AddSessionToPool(Path.GetFileNameWithoutExtension(serviceConfigFile), durable, sessionAllocateInfo.Id, registration.Service.MaxSessionPoolSize);
                }
            }

            return(null);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Load the configuration from the configuration file
        /// If no configuration is found or some part is missing, we will fill the blank with default value
        /// </summary>
        /// <param name="brokerSettings">indicate the broker settings from the session start info, this settings will override the settings load from the configuration file</param>
        /// <param name="brokerInfo">indicating the broker info</param>
        /// <param name="brokerConfig">out the broker configurations</param>
        /// <param name="serviceConfig">out the service configurations</param>
        /// <param name="bindings">output the bindings</param>
        public static void LoadConfiguration(SessionStartInfoContract brokerSettings, BrokerStartInfo brokerInfo, out BrokerConfigurations brokerConfig, out ServiceConfiguration serviceConfig, out BindingsSection bindings)
        {
            // Init config file
            string filename = brokerInfo.ConfigurationFile;

            BrokerTracing.TraceVerbose("[ConfigurationHelper] LoadConfiguration. Step 1: Load configuration file name: {0}", filename);

            brokerConfig  = null;
            serviceConfig = null;
            bindings      = null;

            try
            {
                ExeConfigurationFileMap map = new ExeConfigurationFileMap();
                map.ExeConfigFilename = filename;
                Configuration config = null;
                RetryManager.RetryOnceAsync(
                    () => config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None),
                    TimeSpan.FromSeconds(1),
                    ex => ex is ConfigurationErrorsException)
                .GetAwaiter()
                .GetResult();
                brokerConfig  = BrokerConfigurations.GetSectionGroup(config);
                serviceConfig = ServiceRegistration.GetSectionGroup(config).Service;
                bindings      = (BindingsSection)config.GetSection(BindingsSectionName);
            }
            catch (ConfigurationErrorsException e)
            {
                ThrowHelper.ThrowSessionFault(SOAFaultCode.ConfigFile_Invalid,
                                              "{0}",
                                              e.ToString());
            }

            if (brokerConfig == null)
            {
                // Set the default value
                brokerConfig = defaultBrokerConfiguration;
                BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[ConfigurationHelper] Didn't find the broker config from the configuration file, use the default configuration");
            }
            else
            {
                // Set the default configuration if the very section is not found
                if (brokerConfig.Monitor == null)
                {
                    brokerConfig.Monitor = defaultBrokerConfiguration.Monitor;
                    BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[ConfigurationHelper] Didn't find the monitor config from the configuration file, use the default configuration");
                }

                if (brokerConfig.Services == null)
                {
                    brokerConfig.Services = defaultBrokerConfiguration.Services;
                    BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[ConfigurationHelper] Didn't find the services config from the configuration file, use the default configuration");
                }

                if (brokerConfig.LoadBalancing == null)
                {
                    brokerConfig.LoadBalancing = defaultBrokerConfiguration.LoadBalancing;
                    BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[ConfigurationHelper] Didn't find the load balancing config from the configuration file, use the default configuration");
                }
            }

            BrokerTracing.TraceVerbose("[ConfigurationHelper] LoadConfiguration. Step 2: Load broker config and service config succeeded.");

            if (brokerConfig.Monitor.AllocationAdjustInterval < MinAllocationAdjustTime && brokerConfig.Monitor.AllocationAdjustInterval != System.Threading.Timeout.Infinite)
            {
                brokerConfig.Monitor.AllocationAdjustInterval = MinAllocationAdjustTime;
            }

            // Update the broker config using the session start info
            if (brokerSettings.ClientIdleTimeout.HasValue)
            {
                brokerConfig.Monitor.ClientIdleTimeout = brokerSettings.ClientIdleTimeout.Value;
                BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[ConfigurationHelper] Modified default ClientIdleTimeout to {0}", brokerConfig.Monitor.ClientIdleTimeout);
            }

            if (brokerSettings.ClientConnectionTimeout.HasValue)
            {
                brokerConfig.Monitor.ClientConnectionTimeout = brokerSettings.ClientConnectionTimeout.Value;
                BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[ConfigurationHelper] Modified default ClientConnectionTimeout to {0}", brokerConfig.Monitor.ClientConnectionTimeout);
            }

            if (brokerSettings.SessionIdleTimeout.HasValue)
            {
                brokerConfig.Monitor.SessionIdleTimeout = brokerSettings.SessionIdleTimeout.Value;
                BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[ConfigurationHelper] Modified default SessionIdleTimeout to {0}", brokerConfig.Monitor.SessionIdleTimeout);
            }

            if (brokerSettings.MessagesThrottleStartThreshold.HasValue)
            {
                brokerConfig.Monitor.MessageThrottleStartThreshold = brokerSettings.MessagesThrottleStartThreshold.Value;
                BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[ConfigurationHelper] Modified default MessageThrottleStartThreshold to {0}", brokerConfig.Monitor.MessageThrottleStartThreshold);
            }

            if (brokerSettings.MessagesThrottleStopThreshold.HasValue)
            {
                brokerConfig.Monitor.MessageThrottleStopThreshold = brokerSettings.MessagesThrottleStopThreshold.Value;
                BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[ConfigurationHelper] Modified default MessageThrottleStopThreshold to {0}", brokerConfig.Monitor.MessageThrottleStopThreshold);
            }

            if (brokerSettings.ClientBrokerHeartbeatRetryCount.HasValue)
            {
                brokerConfig.Monitor.ClientBrokerHeartbeatRetryCount = brokerSettings.ClientBrokerHeartbeatRetryCount.Value;
                BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[ConfigurationHelper] Modified default ClientBrokerHeartbeatRetryCount to {0}", brokerConfig.Monitor.ClientBrokerHeartbeatRetryCount);
            }

            if (brokerSettings.ClientBrokerHeartbeatInterval.HasValue)
            {
                brokerConfig.Monitor.ClientBrokerHeartbeatInterval = brokerSettings.ClientBrokerHeartbeatInterval.Value;
                BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[ConfigurationHelper] Modified default ClientBrokerHeartbeatInterval to {0}", brokerConfig.Monitor.ClientBrokerHeartbeatInterval);
            }

            if (brokerSettings.ServiceOperationTimeout.HasValue)
            {
                brokerConfig.LoadBalancing.ServiceOperationTimeout = brokerSettings.ServiceOperationTimeout.Value;
                BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[ConfigurationHelper] Modified default ServiceOperationTimeout to {0}", brokerConfig.LoadBalancing.ServiceOperationTimeout);
            }

            if (brokerSettings.DispatcherCapacityInGrowShrink.HasValue)
            {
                brokerConfig.LoadBalancing.DispatcherCapacityInGrowShrink = brokerSettings.DispatcherCapacityInGrowShrink.Value;
                BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[ConfigurationHelper] Modified default DispatcherCapacityInGrowShrink to {0}", brokerConfig.LoadBalancing.DispatcherCapacityInGrowShrink);
            }

            if (brokerSettings.MaxMessageSize.HasValue)
            {
                serviceConfig.MaxMessageSize = brokerSettings.MaxMessageSize.Value;
                BrokerTracing.TraceEvent(TraceEventType.Verbose, 0, "[ConfigurationHelper] Modified default MaxMessageSize to {0}", serviceConfig.MaxMessageSize);
            }

            BrokerTracing.TraceVerbose("[ConfigurationHelper] LoadConfiguration. Step 3: Override broker settings using session start info succeeded.");

            // Validate the config section
            string configError;
            bool   validateSucceeded;

            try
            {
                validateSucceeded = brokerConfig.Validate(out configError);
            }
            catch (ConfigurationErrorsException e)
            {
                validateSucceeded = false;
                configError       = e.Message;
            }

            if (!validateSucceeded)
            {
                BrokerTracing.TraceEvent(TraceEventType.Error, 0, "[ConfigurationHelper] Invalid broker configuration section. Error {0}", configError);
                ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_InvalidConfiguration, configError);
            }

            BrokerTracing.TraceVerbose("[ConfigurationHelper] LoadConfiguration. Step 4: Validate broker configuration succeeded.");

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("[Monitor]");
            BrokerTracing.WriteProperties(sb, brokerConfig.Monitor, 3, typeof(int), typeof(string));
            sb.AppendLine("[BaseAddress]");
            sb.AppendFormat("   Http = {0}\n", brokerConfig.Services.GetBrokerBaseAddress("http"));
            sb.AppendFormat("   Https = {0}\n", brokerConfig.Services.GetBrokerBaseAddress("https"));
            sb.AppendFormat("   NetTcp = {0}\n", brokerConfig.Services.GetBrokerBaseAddress("net.tcp"));
            sb.AppendLine("[LoadBalancing]");
            BrokerTracing.WriteProperties(sb, brokerConfig.LoadBalancing, 3, typeof(int), typeof(string));
            BrokerTracing.TraceVerbose("[ConfigurationHelper] BrokerConfiguration: \n{0}", sb.ToString());
            sb = new StringBuilder();
            sb.AppendLine("[Service]");
            BrokerTracing.WriteProperties(sb, serviceConfig, 3, typeof(int), typeof(string));
            BrokerTracing.TraceVerbose("[ConfigurationHelper] ServiceConfiguration: \n{0}", sb.ToString());
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Get service assembly file
        /// </summary>
        /// <param name="serviceConfigName">indicating service configuration file</param>
        /// <param name="onAzure">on azure or in on-premise cluster</param>
        /// <param name="registration">output service registration instance</param>
        /// <param name="serviceAssemblyFullPath">full path of the soa service assembly</param>
        /// <returns>returns return code</returns>
        public static int GetServiceRegistration(string serviceConfigName, bool onAzure, out ServiceRegistration registration, out string serviceAssemblyFullPath)
        {
            // Open the service registration configuration section
            ExeConfigurationFileMap map = new ExeConfigurationFileMap();

            map.ExeConfigFilename = serviceConfigName;

            Configuration config = null;

            RetryManager.RetryOnceAsync(
                () => config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None),
                TimeSpan.FromSeconds(1),
                ex => ex is ConfigurationErrorsException)
            .GetAwaiter()
            .GetResult();
            Debug.Assert(config != null, "Configuration is not opened properly.");

            registration = ServiceRegistration.GetSectionGroup(config);

            serviceAssemblyFullPath = registration.Service.AssemblyPath;
            if (!string.IsNullOrEmpty(serviceAssemblyFullPath))
            {
                serviceAssemblyFullPath = Environment.ExpandEnvironmentVariables(serviceAssemblyFullPath);
            }

            if (onAzure)
            {
                bool exists = false;

                try
                {
                    exists = File.Exists(serviceAssemblyFullPath);
                }
                catch (Exception e)
                {
                    RuntimeTraceHelper.TraceEvent(
                        TraceEventType.Error,
                        SoaHelper.CreateTraceMessage(
                            "Utility",
                            "GetServiceLocalCacheFullPath",
                            string.Format("Exception happens when check the file existence. {0}", e)));
                }

                if (!exists)
                {
                    // If we find the service registration file under the specified path, use it.
                    // Otherwise, fall back to the package root folder. The service assembly is under the same folder as the registration file.
                    serviceAssemblyFullPath = Path.Combine(Path.GetDirectoryName(serviceConfigName), Path.GetFileName(serviceAssemblyFullPath));
                }
            }

            if (string.IsNullOrEmpty(serviceAssemblyFullPath))
            {
                string message = string.Format(CultureInfo.CurrentCulture, StringTable.AssemblyFileNotRegistered, serviceConfigName);
                Console.Error.WriteLine(message);
                RuntimeTraceHelper.TraceEvent(TraceEventType.Error, message);

                return(ErrorCode.ServiceHost_AssemblyFileNameNullOrEmpty);
            }

            if (!File.Exists(serviceAssemblyFullPath))
            {
                // If the obtained service assembly path is not valid or not existing
                string message = string.Format(CultureInfo.CurrentCulture, StringTable.AssemblyFileCantFind, serviceAssemblyFullPath);
                Console.Error.WriteLine(message);
                RuntimeTraceHelper.TraceEvent(TraceEventType.Error, message);

                return(ErrorCode.ServiceHost_AssemblyFileNotFound);
            }

            return(ErrorCode.Success);
        }