/// <summary> /// Start session launcher service /// </summary> private void StartSessionLauncherService() { try { string sessionLauncherAddress = SoaHelper.GetSessionLauncherAddress("localhost"); this.launcherHost = new ServiceHost(this.sessionLauncher, new Uri(sessionLauncherAddress)); BindingHelper.ApplyDefaultThrottlingBehavior(this.launcherHost); #if AZURE_STORAGE_BINDING if (SessionLauncherRuntimeConfiguration.OpenAzureStorageListener) { this.launcherHost.AddServiceEndpoint( typeof(ISessionLauncher), new TableTransportBinding() { ConnectionString = SessionLauncherRuntimeConfiguration.SessionLauncherStorageConnectionString, TargetPartitionKey = "all" }, TelepathyConstants.SessionLauncherAzureTableBindingAddress); TraceHelper.TraceEvent(TraceEventType.Information, "Add session launcher service endpoint {0}", TelepathyConstants.SessionLauncherAzureTableBindingAddress); } #endif if (SessionLauncherRuntimeConfiguration.SchedulerType == SchedulerType.HpcPack) { this.launcherHost.AddServiceEndpoint(typeof(ISessionLauncher), BindingHelper.HardCodedSessionLauncherNetTcpBinding, string.Empty); this.launcherHost.AddServiceEndpoint(typeof(ISessionLauncher), BindingHelper.HardCodedNoAuthSessionLauncherNetTcpBinding, "AAD"); this.launcherHost.AddServiceEndpoint(typeof(ISessionLauncher), BindingHelper.HardCodedInternalSessionLauncherNetTcpBinding, "Internal"); TraceHelper.TraceEvent(TraceEventType.Information, "Open session launcher find cert {0}", TelepathyContext.Get().GetSSLThumbprint().GetAwaiter().GetResult()); this.launcherHost.Credentials.UseInternalAuthenticationAsync().GetAwaiter().GetResult(); TraceHelper.TraceEvent(TraceEventType.Information, "Add session launcher service endpoint {0}", sessionLauncherAddress); } else { this.launcherHost.AddServiceEndpoint(typeof(ISessionLauncher), BindingHelper.HardCodedUnSecureNetTcpBinding, string.Empty); this.launcherHost.AddServiceEndpoint(typeof(ISessionLauncher), BindingHelper.HardCodedUnSecureNetTcpBinding, "Internal"); TraceHelper.TraceEvent(TraceEventType.Information, "Add session launcher service endpoint {0}", sessionLauncherAddress); } this.launcherHost.Faulted += this.SessionLauncherHostFaultHandler; ServiceAuthorizationBehavior myServiceBehavior = this.launcherHost.Description.Behaviors.Find <ServiceAuthorizationBehavior>(); myServiceBehavior.PrincipalPermissionMode = PrincipalPermissionMode.None; this.launcherHost.Open(); TraceHelper.TraceEvent(TraceEventType.Information, "Open session launcher service"); } catch (Exception ex) { Trace.TraceError(ex.ToString()); throw; } }
/// <summary> /// Open a ServiceHost for NodeMappingCache service /// </summary> private void StartNodeMappingCacheService() { try { this.nodeMappingCacheHost = new ServiceHost(typeof(NodeMappingCache), new Uri(NodeMappingCacheEpr)); BindingHelper.ApplyDefaultThrottlingBehavior(this.nodeMappingCacheHost); this.nodeMappingCacheHost.AddServiceEndpoint(typeof(INodeMappingCache), BindingHelper.HardCodedNamedPipeBinding, string.Empty); this.nodeMappingCacheHost.Open(); TraceHelper.TraceEvent(TraceEventType.Information, "[LauncherHostService] .StartNodeMappingCacheService: open NodeMappingCache service succeeded"); } catch (Exception e) { TraceHelper.TraceEvent(TraceEventType.Critical, "[LauncherHostService] .StartNodeMappingCacheService: Failed to start node mapping cache service. Exception = {0}", e); throw; } }
/// <summary> /// Start data service /// </summary> private void StartDataWcfService() { string dataServiceAddress = SoaHelper.GetDataServiceAddress(); this.dataServiceHost = new ServiceHost(this.dataService, new Uri(dataServiceAddress)); BindingHelper.ApplyDefaultThrottlingBehavior(this.dataServiceHost); Binding binding = BindingHelper.HardCodedDataServiceNetTcpBinding; binding.SendTimeout = TimeSpan.FromMinutes(Microsoft.Hpc.Scheduler.Session.Data.Internal.Constant.DataProxyOperationTimeoutInMinutes); binding.ReceiveTimeout = TimeSpan.FromMinutes(Microsoft.Hpc.Scheduler.Session.Data.Internal.Constant.DataProxyOperationTimeoutInMinutes); this.dataServiceHost.AddServiceEndpoint(typeof(Microsoft.Hpc.Scheduler.Session.Data.Internal.IDataService), binding, string.Empty); // Bug 14900: for some unknown reason, service host may enter into Faulted state and // become unresponsive to client requests. Here register the Faulted event. If it // occurs, restart the service host. this.dataServiceHost.Faulted += DataServiceHostFaultHandler; this.dataServiceHost.Open(); TraceHelper.TraceEvent(TraceEventType.Information, "Open SOA data service at {0}", dataServiceAddress); }
/// <summary> /// Start scheduler delegation service /// </summary> private void StartSchedulerDelegationService() { string schedulerDelegationAddress = SoaHelper.GetSchedulerDelegationAddress("localhost"); this.delegationHost = new ServiceHost(this.schedulerDelegation, new Uri(schedulerDelegationAddress)); BindingHelper.ApplyDefaultThrottlingBehavior(this.delegationHost); #if HPCPACK if (this.schedulerDelegation is IHpcSchedulerAdapterInternal) { this.delegationHost.AddServiceEndpoint(typeof(IHpcSchedulerAdapterInternal), BindingHelper.HardCodedInternalSchedulerDelegationBinding, "Internal"); this.delegationHost.AddServiceEndpoint(typeof(IHpcSchedulerAdapter), BindingHelper.HardCodedInternalSchedulerDelegationBinding, string.Empty); this.delegationHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust; this.delegationHost.Credentials.ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck; this.delegationHost.Credentials.ServiceCertificate.SetCertificate( StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, TelepathyContext.Get().GetSSLThumbprint().GetAwaiter().GetResult()); } else #endif { // Use insecure binding until unified authentication logic is implemented this.delegationHost.AddServiceEndpoint(typeof(ISchedulerAdapter), BindingHelper.HardCodedUnSecureNetTcpBinding, string.Empty); // if (SessionLauncherRuntimeConfiguration.OpenAzureStorageListener) // { // this.delegationHost.AddServiceEndpoint( // typeof(ISchedulerAdapter), // new TableTransportBinding() { ConnectionString = SessionLauncherRuntimeConfiguration.SessionLauncherStorageConnectionString, TargetPartitionKey = "all" }, // TelepathyConstants.SessionSchedulerDelegationAzureTableBindingAddress); // } } this.delegationHost.Faulted += SchedulerDelegationHostFaultHandler; this.delegationHost.Open(); TraceHelper.TraceEvent(TraceEventType.Information, "Open scheduler delegation service at {0}", schedulerDelegationAddress); }
/// <summary> /// Build the custom frontend /// </summary> /// <param name="sharedData">indicating the shared data</param> /// <param name="observer">indicating the broker observer</param> /// <param name="clientManager">indicating the client manager</param> /// <param name="brokerAuth">indicating the broker authorization</param> /// <param name="bindings">indicating the bindings</param> /// <returns>frontend info</returns> private static FrontendInfo BuildCustomFrontend(SharedData sharedData, BrokerObserver observer, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, BindingsSection bindings) { FrontendInfo result = new FrontendInfo(); BrokerTracing.TraceVerbose("[FrontEndBuilder] Start building custom frontend..."); // Get binding from configuration file Binding binding = BindingHelper.GetBinding(TransportScheme.Custom, sharedData.StartInfo.Secure, bindings); // Get message size and reader quotas BindingElementCollection collection = binding.CreateBindingElements(); // Sync frontend binding.receiveTimeout with loadBalancing.ServiceOperationTimeout if its enabled (>0) int serviceOperationTimeout = sharedData.Config.LoadBalancing.ServiceOperationTimeout; if (serviceOperationTimeout > 0) { binding.SendTimeout = TimeSpan.FromMilliseconds(serviceOperationTimeout); } // Set frontend binding.ReceiveTimeout to max binding.ReceiveTimeout = TimeSpan.MaxValue; TransportBindingElement transportBindingElement = collection.Find <TransportBindingElement>(); XmlDictionaryReaderQuotas quotas = binding.GetProperty <XmlDictionaryReaderQuotas>(new BindingParameterCollection()); if (sharedData.ServiceConfig.MaxMessageSize > 0) { transportBindingElement.MaxReceivedMessageSize = sharedData.Config.LoadBalancing.ServiceOperationTimeout; quotas.MaxBytesPerRead = XmlDictionaryReaderQuotas.Max.MaxBytesPerRead; quotas.MaxDepth = XmlDictionaryReaderQuotas.Max.MaxDepth; quotas.MaxNameTableCharCount = XmlDictionaryReaderQuotas.Max.MaxNameTableCharCount; quotas.MaxStringContentLength = Convert.ToInt32(sharedData.ServiceConfig.MaxMessageSize); quotas.MaxArrayLength = Convert.ToInt32(sharedData.ServiceConfig.MaxMessageSize); } result.MaxMessageSize = transportBindingElement.MaxReceivedMessageSize; result.ReaderQuotas = quotas; // Check if the custom binding supports duplex binding bool duplex = false; if (binding.CanBuildChannelListener <IDuplexSessionChannel>()) { duplex = true; } StringBuilder sb = new StringBuilder(); BrokerTracing.WriteProperties(sb, result.ReaderQuotas, 3, typeof(int)); BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 1: Load binding data:\nMaxMessageSize = {0}\n[ReaderQuotas]\n{1}\nDuplex = {2}", result.MaxMessageSize, sb.ToString(), duplex); result.Binding = binding; BrokerTracing.EtwTrace.LogFrontendBindingLoaded( sharedData.BrokerInfo.SessionId, "Custom", result.MaxMessageSize, binding.ReceiveTimeout.Ticks, binding.SendTimeout.Ticks, binding.MessageVersion.ToString(), binding.Scheme); // Generate the net.tcp uri Uri baseUri = sharedData.Config.Services.GetBrokerBaseAddress(binding.Scheme); if (baseUri == null) { baseUri = GetDefaultUriByScheme(binding.Scheme); } BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 2: Load base address: {0}", baseUri); Uri brokerUri = ApplySessionId(baseUri, sharedData.BrokerInfo.SessionId, "Custom", sharedData.BrokerInfo.EnableFQDN); BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 3: Generate broker uri: {0}", brokerUri); // Build the frontend if (duplex) { result.FrontEnd = new DuplexFrontEnd(brokerUri, binding, observer, clientManager, brokerAuth, sharedData); } else { if (binding.CanBuildChannelListener <IReplySessionChannel>()) { result.FrontEnd = new RequestReplyFrontEnd <IReplySessionChannel>(brokerUri, binding, observer, clientManager, brokerAuth, sharedData); } else if (binding.CanBuildChannelListener <IReplyChannel>()) { result.FrontEnd = new RequestReplyFrontEnd <IReplyChannel>(brokerUri, binding, observer, clientManager, brokerAuth, sharedData); } else { ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BindingNotSupported, SR.BindingNotSupported, binding.Name); } } BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 4: Build broker frontend succeeded."); BrokerTracing.EtwTrace.LogFrontendCreated( sharedData.BrokerInfo.SessionId, "Custom", result.FrontEnd.ListenUri); Uri controllerUri = ApplySessionId(baseUri, sharedData.BrokerInfo.SessionId, "Custom", sharedData.BrokerInfo.EnableFQDN); BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 5: Generate controller base address: {0}", controllerUri); result.ControllerFrontend = new ServiceHost(typeof(BrokerController), controllerUri); BindingHelper.ApplyDefaultThrottlingBehavior(result.ControllerFrontend); ServiceEndpoint controllerEndpoint = result.ControllerFrontend.AddServiceEndpoint(typeof(IController), binding, DefaultControllerPostfix); controllerEndpoint.Behaviors.Add(new ControllerFrontendProvider(false, clientManager, brokerAuth, observer, null)); result.ControllerUri = controllerEndpoint.ListenUri.AbsoluteUri; // Check if the binding supports duplex channel // If so, create GetResponse frontend if (binding.CanBuildChannelListener <IDuplexChannel>() || binding.CanBuildChannelListener <IDuplexSessionChannel>()) { ServiceEndpoint getResponseEndpoint = result.ControllerFrontend.AddServiceEndpoint(typeof(IResponseService), binding, DefaultGetResponsePostfix); getResponseEndpoint.Behaviors.Add(new ControllerFrontendProvider(false, clientManager, brokerAuth, observer, null)); result.GetResponseUri = getResponseEndpoint.ListenUri.AbsoluteUri; BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 6: Build controller frontend succeeded: ControllerUri = {0}, GetResponseUri = {1}", result.ControllerUri, result.GetResponseUri); } else { BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 6: Build controller frontend succeeded: ControllerUri = {0}", result.ControllerUri); } BrokerTracing.TraceVerbose("[FrontEndBuilder] Building custom frontend succeeded."); BrokerTracing.EtwTrace.LogFrontendControllerCreated( sharedData.BrokerInfo.SessionId, "Custom", result.ControllerUri, result.GetResponseUri ?? String.Empty); return(result); }
/// <summary> /// Build the http frontend /// </summary> /// <param name="sharedData">indicating the shared data</param> /// <param name="observer">indicating the broker observer</param> /// <param name="clientManager">indicating the client manager</param> /// <param name="brokerAuth">indicating the broker authorization</param> /// <param name="bindings">indicating the bindings</param> /// <returns>frontend info</returns> private static FrontendInfo BuildHttpFrontend(SharedData sharedData, BrokerObserver observer, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, BindingsSection bindings, AzureQueueProxy azureQueueProxy) { FrontendInfo result = new FrontendInfo(); BrokerTracing.TraceVerbose("[FrontEndBuilder] Start building http frontend..."); // Get binding from configuration file Binding binding = BindingHelper.GetBinding(TransportScheme.Http, sharedData.StartInfo.Secure, bindings); // Sync frontend binding.receiveTimeout with loadBalancing.ServiceOperationTimeout if its enabled (>0) int serviceOperationTimeout = sharedData.Config.LoadBalancing.ServiceOperationTimeout; if (serviceOperationTimeout > 0) { binding.SendTimeout = TimeSpan.FromMilliseconds(serviceOperationTimeout); } // Set frontend binding.ReceiveTimeout to max binding.ReceiveTimeout = TimeSpan.MaxValue; // Get message size and reader quotas int maxMessageSize = sharedData.ServiceConfig.MaxMessageSize; if (maxMessageSize > 0) { BindingHelper.ApplyMaxMessageSize(binding, maxMessageSize); result.MaxMessageSize = maxMessageSize; BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 1: Apply global MaxMessageSize:{0}\n", result.MaxMessageSize); } else { BindingElementCollection collection = binding.CreateBindingElements(); result.MaxMessageSize = collection.Find <TransportBindingElement>().MaxReceivedMessageSize; result.ReaderQuotas = binding.GetProperty <XmlDictionaryReaderQuotas>(new BindingParameterCollection()); StringBuilder sb = new StringBuilder(); BrokerTracing.WriteProperties(sb, result.ReaderQuotas, 3, typeof(int)); BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 1: Load binding data:\nMaxMessageSize = {0}\n[ReaderQuotas]\n{1}", result.MaxMessageSize, sb.ToString()); } result.Binding = binding; BrokerTracing.EtwTrace.LogFrontendBindingLoaded( sharedData.BrokerInfo.SessionId, "Http", result.MaxMessageSize, binding.ReceiveTimeout.Ticks, binding.SendTimeout.Ticks, binding.MessageVersion.ToString(), binding.Scheme); // Generate the http uri Uri basehttpUri = sharedData.Config.Services.GetBrokerBaseAddress(sharedData.StartInfo.Secure ? HttpsScheme : HttpScheme); if (basehttpUri == null) { basehttpUri = new Uri(sharedData.StartInfo.Secure ? DefaultHttpsFrontEndServiceUri : DefaultHttpFrontEndServiceUri); } BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 2: Load base address: {0}", basehttpUri); Uri brokerHttpUri = ApplySessionId(basehttpUri, sharedData.BrokerInfo.SessionId, "Http", sharedData.BrokerInfo.EnableFQDN); BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 3: Generate broker uri: {0}", brokerHttpUri); // Build the frontend if (sharedData.StartInfo.UseAzureStorage == true) { BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: AzureQueueFrontEnd"); result.FrontEnd = new AzureQueueFrontEnd(azureQueueProxy, brokerHttpUri, observer, clientManager, brokerAuth, sharedData); } else { BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: HttpFrontEnd"); result.FrontEnd = new RequestReplyFrontEnd <IReplyChannel>(brokerHttpUri, binding, observer, clientManager, brokerAuth, sharedData); //result.FrontEnd = new OutputInputFrontEnd<IInputChannel>(brokerHttpUri, binding, observer, clientManager, brokerAuth, sharedData); } BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 4: Build broker frontend succeeded."); BrokerTracing.EtwTrace.LogFrontendCreated( sharedData.BrokerInfo.SessionId, "Http", result.FrontEnd.ListenUri); Uri controllerHttpUri = ApplySessionId(basehttpUri, sharedData.BrokerInfo.SessionId, "Http", sharedData.BrokerInfo.EnableFQDN); BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 5: Generate controller base address: {0}", controllerHttpUri); // Bug 3012: Force the http frontend using the singleton instance result.ControllerFrontend = new ServiceHost(typeof(BrokerController), controllerHttpUri); BindingHelper.ApplyDefaultThrottlingBehavior(result.ControllerFrontend); ServiceBehaviorAttribute behavior = result.ControllerFrontend.Description.Behaviors.Find <ServiceBehaviorAttribute>(); Debug.Assert(behavior != null, "BrokerController must have a behavior."); behavior.InstanceContextMode = InstanceContextMode.Single; ServiceEndpoint endpoint = result.ControllerFrontend.AddServiceEndpoint(typeof(IController), binding, DefaultControllerPostfix); if (sharedData.StartInfo.UseAzureStorage == true) { endpoint.Behaviors.Add(new ControllerFrontendProvider(true, clientManager, brokerAuth, observer, azureQueueProxy)); } else { endpoint.Behaviors.Add(new ControllerFrontendProvider(true, clientManager, brokerAuth, observer, null)); } result.ControllerUri = endpoint.ListenUri.AbsoluteUri; BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 6: Build controller frontend succeeded: ControllerUri = {0}", result.ControllerUri); result.GetResponseUri = null; BrokerTracing.TraceVerbose("[FrontEndBuilder] Building http frontend succeeded."); BrokerTracing.EtwTrace.LogFrontendControllerCreated( sharedData.BrokerInfo.SessionId, "Http", result.ControllerUri, String.Empty); return(result); }
/// <summary> /// Build the NetHttp frontend /// </summary> /// <param name="sharedData">indicating the shared data</param> /// <param name="observer">indicating the broker observer</param> /// <param name="clientManager">indicating the client manager</param> /// <param name="brokerAuth">indicating the broker authorization</param> /// <param name="bindings">indicating the bindings</param> /// <returns>frontend info</returns> private static FrontendInfo BuildNetHttpFrontend(SharedData sharedData, BrokerObserver observer, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, BindingsSection bindings) { FrontendInfo result = new FrontendInfo(); BrokerTracing.TraceVerbose("[FrontEndBuilder] Start building NetHttp frontend..."); // Get binding from configuration file Binding binding = BindingHelper.GetBinding(TransportScheme.NetHttp, sharedData.StartInfo.Secure, bindings); // Sync frontend binding.receiveTimeout with loadBalancing.ServiceOperationTimeout if its enabled (>0) int serviceOperationTimeout = sharedData.Config.LoadBalancing.ServiceOperationTimeout; if (serviceOperationTimeout > 0) { binding.SendTimeout = TimeSpan.FromMilliseconds(serviceOperationTimeout); } // Set frontend binding.ReceiveTimeout to max binding.ReceiveTimeout = TimeSpan.MaxValue; // Update backend binding's maxMessageSize settings with global maxMessageSize if its enabled (> 0) int maxMessageSize = sharedData.ServiceConfig.MaxMessageSize; if (maxMessageSize > 0) { BindingHelper.ApplyMaxMessageSize(binding, maxMessageSize); result.MaxMessageSize = maxMessageSize; BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 1: Apply global MaxMessageSize:{0}\n", result.MaxMessageSize); } else { // Get message size and reader quotas BindingElementCollection collection = binding.CreateBindingElements(); result.MaxMessageSize = collection.Find <TransportBindingElement>().MaxReceivedMessageSize; result.ReaderQuotas = binding.GetProperty <XmlDictionaryReaderQuotas>(new BindingParameterCollection()); StringBuilder sb = new StringBuilder(); BrokerTracing.WriteProperties(sb, result.ReaderQuotas, 3, typeof(int)); BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 1: Load binding data:\nMaxMessageSize = {0}\n[ReaderQuotas]\n{1}", result.MaxMessageSize, sb.ToString()); } result.Binding = binding; BrokerTracing.EtwTrace.LogFrontendBindingLoaded( sharedData.BrokerInfo.SessionId, "NetHttp", result.MaxMessageSize, binding.ReceiveTimeout.Ticks, binding.SendTimeout.Ticks, binding.MessageVersion.ToString(), binding.Scheme); // Generate the http uri Uri basehttpUri = sharedData.Config.Services.GetBrokerBaseAddress(sharedData.StartInfo.Secure ? HttpsScheme : HttpScheme); if (basehttpUri == null) { basehttpUri = new Uri(sharedData.StartInfo.Secure ? DefaultHttpsFrontEndServiceUri : DefaultHttpFrontEndServiceUri); } BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 2: Load base address: {0}", basehttpUri); Uri brokerNetHttpUri = ApplySessionId(basehttpUri, sharedData.BrokerInfo.SessionId, "NetHttp", sharedData.BrokerInfo.EnableFQDN); BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 3: Generate broker uri: {0}", brokerNetHttpUri); // Build the frontend result.FrontEnd = new DuplexFrontEnd(brokerNetHttpUri, binding, observer, clientManager, brokerAuth, sharedData); BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 4: Build broker frontend succeeded."); BrokerTracing.EtwTrace.LogFrontendCreated( sharedData.BrokerInfo.SessionId, "NetHttp", result.FrontEnd.ListenUri); Uri controllerNetHttpUri = ApplySessionId(basehttpUri, sharedData.BrokerInfo.SessionId, "NetHttp", sharedData.BrokerInfo.EnableFQDN); BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 5: Generate controller base address: {0}", controllerNetHttpUri); result.ControllerFrontend = new ServiceHost(typeof(BrokerController), controllerNetHttpUri); BindingHelper.ApplyDefaultThrottlingBehavior(result.ControllerFrontend); ServiceEndpoint controllerEndpoint = result.ControllerFrontend.AddServiceEndpoint(typeof(IController), binding, DefaultControllerPostfix); controllerEndpoint.Behaviors.Add(new ControllerFrontendProvider(false, clientManager, brokerAuth, observer, null)); result.ControllerUri = controllerEndpoint.ListenUri.AbsoluteUri; ServiceEndpoint getResponseEndpoint = result.ControllerFrontend.AddServiceEndpoint(typeof(IResponseService), binding, DefaultGetResponsePostfix); getResponseEndpoint.Behaviors.Add(new ControllerFrontendProvider(false, clientManager, brokerAuth, observer, null)); result.GetResponseUri = getResponseEndpoint.ListenUri.AbsoluteUri; BrokerTracing.TraceVerbose("[FrontEndBuilder] Build frontend: Step 6: Build controller frontend succeeded: ControllerUri = {0}, GetResponseUri = {1}", result.ControllerUri, result.GetResponseUri); BrokerTracing.TraceVerbose("[FrontEndBuilder] Building NetHttp frontend succeeded."); BrokerTracing.EtwTrace.LogFrontendControllerCreated( sharedData.BrokerInfo.SessionId, "NetHttp", result.ControllerUri, result.GetResponseUri); return(result); }
/// <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; } }