/// <summary> /// Initializes a new instance of the DuplexFrontEnd class /// </summary> /// <param name="listenUri">uri the frontend listen to</param> /// <param name="binding">binding that the frontend uses</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="sharedData">indicating the shared data</param> public DuplexFrontEnd(Uri listenUri, Binding binding, BrokerObserver observer, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, SharedData sharedData) : base(listenUri.AbsoluteUri, observer, clientManager, brokerAuth, sharedData) { this.binding = binding; if (sharedData.StartInfo.UseAad) { BindingParameterCollection bindingParms = new BindingParameterCollection(); var serviceCred = new ServiceCredentials(); serviceCred.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, new NonHARegistry().GetSSLThumbprint().GetAwaiter().GetResult()); bindingParms.Add(serviceCred); this.listener = binding.BuildChannelListener <IDuplexSessionChannel>(listenUri, bindingParms); } else if (sharedData.StartInfo.LocalUser.GetValueOrDefault()) { this.listener = binding.BuildChannelListener <IDuplexSessionChannel>(listenUri, new ServiceCredentials().UseInternalAuthenticationAsync(true).GetAwaiter().GetResult()); } else { this.listener = binding.BuildChannelListener <IDuplexSessionChannel>(listenUri); } this.acceptChannel = new BasicCallbackReferencedThreadHelper <IAsyncResult>(this.AcceptChannel, this).CallbackRoot; this.receiveRequest = new BasicCallbackReferencedThreadHelper <IAsyncResult>(this.ReceiveRequest, this).CallbackRoot; }
/// <summary> /// Initializes a new instance of the RequestReplyFrontEnd class /// </summary> /// <param name="listenUri">uri the frontend listen to</param> /// <param name="binding">binding that the frontend uses</param> public RequestReplyFrontEnd(Uri listenUri, Binding binding, BrokerObserver observer, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, SharedData sharedData) : base(listenUri.AbsoluteUri, observer, clientManager, brokerAuth, sharedData) { this.listener = binding.BuildChannelListener <T>(listenUri); this.acceptChannel = new BasicCallbackReferencedThreadHelper <IAsyncResult>(this.AcceptChannel, this).CallbackRoot; this.receiveRequest = new BasicCallbackReferencedThreadHelper <IAsyncResult>(this.ReceiveRequest, this).CallbackRoot; }
/// <summary> /// Initializes a new instance of the BrokerController class /// </summary> /// <param name="isSingleton">indicating whether the BrokerController is a singleton</param> /// <param name="clientManager">indicating the client manager</param> /// <param name="brokerAuth">indicating the broker authorization</param> /// <param name="observer">indicating broker observer</param> /// <param name="azureQueueProxy">the Azure storage proxy</param> public BrokerController(bool isSingleton, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, BrokerObserver observer, AzureQueueProxy azureQueueProxy) { this.isSingleton = isSingleton; this.clientManager = clientManager; this.brokerAuth = brokerAuth; this.observer = observer; this.callbackInstance = azureQueueProxy; }
/// <summary> /// Build the 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> /// <param name="azureQueueProxy">indicating the Azure storage proxy</param> /// <returns>frontend result</returns> public static FrontendResult BuildFrontEnd(SharedData sharedData, BrokerObserver observer, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, BindingsSection bindings, AzureQueueProxy azureQueueProxy) { FrontendResult result = new FrontendResult(); // Bug 9514: Do not open frontend for inprocess broker if (sharedData.StartInfo.UseInprocessBroker) { return(result); } bool flag = false; // Open frontend for different scheme // TODO: Separate HTTP frontend and Queue frontend if (azureQueueProxy != null) { flag = true; result.SetFrontendInfo(BuildHttpFrontend(sharedData, observer, clientManager, brokerAuth, bindings, azureQueueProxy), TransportScheme.Http); } else { if ((sharedData.StartInfo.TransportScheme & TransportScheme.Custom) == TransportScheme.Custom) { flag = true; result.SetFrontendInfo(BuildCustomFrontend(sharedData, observer, clientManager, brokerAuth, bindings), TransportScheme.Custom); } if ((sharedData.StartInfo.TransportScheme & TransportScheme.Http) == TransportScheme.Http) { flag = true; result.SetFrontendInfo(BuildHttpFrontend(sharedData, observer, clientManager, brokerAuth, bindings, azureQueueProxy), TransportScheme.Http); } if ((sharedData.StartInfo.TransportScheme & TransportScheme.NetTcp) == TransportScheme.NetTcp) { flag = true; result.SetFrontendInfo(BuildNetTcpFrontend(sharedData, observer, clientManager, brokerAuth, bindings), TransportScheme.NetTcp); } if ((sharedData.StartInfo.TransportScheme & TransportScheme.NetHttp) == TransportScheme.NetHttp) { flag = true; result.SetFrontendInfo(BuildNetHttpFrontend(sharedData, observer, clientManager, brokerAuth, bindings), TransportScheme.NetHttp); } } if (!flag) { BrokerTracing.TraceEvent(TraceEventType.Critical, 0, "[FrontEndBuilder] Invalid transport scheme: {0}", sharedData.StartInfo.TransportScheme); ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_NotSupportedTransportScheme, SR.NotSupportedTransportScheme, sharedData.StartInfo.TransportScheme.ToString()); } return(result); }
/// <summary> /// Initializes a new instance of the DuplexRequestContext class /// </summary> /// <param name="request">request message</param> /// <param name="defaultTimeouts">default timeouts</param> /// <param name="innerChannel">inner channel</param> /// <param name="observer">indicating the broker observer</param> /// <param name="client">indicating the broker client</param> public DuplexRequestContext(Message request, IDefaultCommunicationTimeouts defaultTimeouts, IDuplexChannel innerChannel, BrokerObserver observer, BrokerClient client) : base(request.Version, client) { this.defaultTimeouts = defaultTimeouts; this.innerChannel = innerChannel; this.observer = observer; if (request != null) { this.messageId = request.Headers.MessageId; this.replyTo = request.Headers.ReplyTo; } }
/// <summary> /// Initializes a new instance of the RequestReplyFrontEnd class /// </summary> /// <param name="listenUri">uri the frontend listen to</param> /// <param name="binding">binding that the frontend uses</param> public OutputInputFrontEnd(Uri listenUri, Binding binding, BrokerObserver observer, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, SharedData sharedData) : base(listenUri.AbsoluteUri, observer, clientManager, brokerAuth, sharedData) { List <BindingElement> elements = new List <BindingElement>(); elements.Add(new OneWayBindingElement()); elements.AddRange(binding.CreateBindingElements()); CustomBinding shapedBinding = new CustomBinding(elements); this.listener = shapedBinding.BuildChannelListener <T>(listenUri); this.acceptChannel = new ReferencedThreadHelper <IAsyncResult>(new AsyncCallback(this.AcceptChannel), this).CallbackRoot; this.receiveRequest = new ReferencedThreadHelper <IAsyncResult>(new AsyncCallback(this.ReceiveRequest), this).CallbackRoot; }
/// <summary> /// Initializes a new instance of the ControllerFrontendProvider class /// </summary> /// <param name="isSingleton">indicating whether a singleton controller class is required</param> /// <param name="clientManager">indicating the client manager</param> /// <param name="brokerAuth">indicating the broker authorization</param> /// <param name="observer">indicating broker observer</param> /// <param name="azureQueueProxy">indicating the Azure storage proxy</param> public ControllerFrontendProvider(bool isSingleton, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, BrokerObserver observer, AzureQueueProxy azureQueueProxy) { if (isSingleton && azureQueueProxy != null) { this.singletonInstance = new BrokerController(true, clientManager, brokerAuth, observer, azureQueueProxy); this.cloudQueueWatcher = new BrokerWorkerControllerQueueWatcher(this.singletonInstance, azureQueueProxy.AzureStorageConnectionString, azureQueueProxy.SessionId); } this.clientManager = clientManager; this.brokerAuth = brokerAuth; this.observer = observer; this.azureQueueProxy = azureQueueProxy; }
/// <summary> /// Initializes a new instance of the FrontEndBase class /// </summary> /// <param name="listenUri">indicate the listen uri</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="sharedData">indicating the shared data</param> public FrontEndBase(string listenUri, BrokerObserver observer, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, SharedData sharedData) { this.replySentCallback = new BasicCallbackReferencedThreadHelper <IAsyncResult>(this.ReplySent, this).CallbackRoot; this.tryToReceiveRequestCallback = new BasicCallbackReferencedThreadHelper <object>(this.TryToReceiveRequestCallback, this).CallbackRoot; this.listenUri = listenUri; this.throttlingWaitHandle = new ManualResetEvent(false); this.callbackStateQueue = new Queue <ChannelClientState>(); this.callbackStateQueueLock = new object(); this.observer = observer; this.clientManager = clientManager; this.brokerAuth = brokerAuth; this.sharedData = sharedData; this.observer.OnStartThrottling += this.StartThrottling; this.observer.OnStopThrottling += this.StopThrottling; }
/// <summary> /// Initializes a new instance of the DispatcherManager class /// </summary> /// <param name="bindings">indicating the bindings section</param> /// <param name="observer">indicating the observer</param> /// <param name="queueFactory">indicating the queue factory</param> /// <param name="sharedData">indicating the shared data</param> /// <param name="frontendResult">indicating the frontend result</param> public DispatcherManager(BindingsSection bindings, SharedData sharedData, BrokerObserver observer, ServiceJobMonitorBase monitor, BrokerQueueFactory queueFactory, ITelepathyContext context) { this.dispatcherDic = new Dictionary <string, Dispatcher>(); this.failedDispatcherList = new List <string>(); this.blockedDispatcherDic = new Dictionary <string, DispatcherInfo>(); this.blockedDispatcherQueue = new Queue <DispatcherInfo>(); this.sharedData = sharedData; this.observer = observer; this.monitor = monitor; this.queueFactory = queueFactory; this.context = context; this.defaultCapacity = this.sharedData.ServiceConfig.MaxConcurrentCalls; this.blockTimeSpan = TimeSpan.FromMilliseconds(this.sharedData.Config.LoadBalancing.EndpointNotFoundRetryPeriod); this.unblockTimer = new Timer(new ThreadHelper <object>(new TimerCallback(this.CallbackToQueryBlockedDispatcherList)).CallbackRoot, null, -1, -1); this.defaultBinding = BindingHelper.GetBackEndBinding(bindings); this.isHttp = this.defaultBinding.CreateBindingElements().Find <HttpTransportBindingElement>() != null; // Update binding's maxMessageSize settings with global maxMessageSize if its enabled (> 0) int maxMessageSize = sharedData.ServiceConfig.MaxMessageSize; if (maxMessageSize > 0) { BindingHelper.ApplyMaxMessageSize(this.defaultBinding, maxMessageSize); } // get soa burst protocol info this.httpsBurst = sharedData.BrokerInfo.HttpsBurst; if (this.httpsBurst) { this.azureQueueManager = new AzureQueueManager(sharedData.BrokerInfo.SessionId, this.sharedData.BrokerInfo.ClusterName, this.sharedData.BrokerInfo.ClusterId); } this.supportsMessageDetails = this.defaultBinding.MessageVersion.Addressing != AddressingVersion.None || this.defaultBinding is BasicHttpBinding; BrokerTracing.TraceEvent(TraceEventType.Information, 0, "[DispatcherManager] Init backend binding: OperatiomTimeout = {0}, DefaultCapacity = {1}", this.sharedData.Config.LoadBalancing.ServiceOperationTimeout, this.defaultCapacity); BrokerTracing.EtwTrace.LogBackendBindingLoaded( sharedData.BrokerInfo.SessionId, "Backend", maxMessageSize, this.defaultBinding.ReceiveTimeout.Ticks, this.defaultBinding.SendTimeout.Ticks, this.defaultBinding.MessageVersion.ToString(), this.defaultBinding.Scheme); }
/// <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> /// Initializes a new instance of the AzureHttpsDispatcher class. /// </summary> /// <param name="azureQueueManager">AzureQueueManager instance</param> /// <param name="info">indicating the dispatcher info</param> /// <param name="binding">binding information</param> /// <param name="sharedData">indicating the shared data</param> /// <param name="observer">indicating the observer</param> /// <param name="queueFactory">indicating the queue factory</param> /// <param name="schedulerAdapterClientFactory">SchedulerAdapterClientFactory instance</param> /// <param name="dispatcherIdle">set when the dispatcher enters idle status</param> public AzureHttpsDispatcher(AzureQueueManager azureQueueManager, DispatcherInfo info, Binding binding, SharedData sharedData, BrokerObserver observer, BrokerQueueFactory queueFactory, SchedulerAdapterClientFactory schedulerAdapterClientFactory, AutoResetEvent dispatcherIdle) : base(info, ProxyBinding.BrokerProxyBinding, sharedData, observer, queueFactory, schedulerAdapterClientFactory, dispatcherIdle) { AzureDispatcherInfo azureDispatcherInfo = info as AzureDispatcherInfo; this.azureServiceName = azureDispatcherInfo.AzureServiceName; this.azureQueueManager = azureQueueManager; this.azureQueueManager.CreateRequestStorage(this.azureServiceName); this.responseStorageName = this.azureQueueManager.Start(azureDispatcherInfo.JobId, azureDispatcherInfo.RequeueCount); // 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); } this.backendBindingData = new BindingData(binding); }
/// <summary> /// Start the service job monitor /// </summary> /// <param name="dispatcherManager">indicating dispatcher manager</param> /// <param name="observer">indicating the observer</param> public async Task Start(DispatcherManager dispatcherManager, BrokerObserver observer) { BrokerTracing.TraceVerbose("[ServiceJobMonitor].Start: Enter"); this.dispatcherManager = dispatcherManager; this.observer = observer; this.gracefulPreemptionHandler = new GracefulPreemptionHandler( this.dispatcherManager, this.sharedData.BrokerInfo.SessionId, taskId => this.FinishTask(taskId, isRunAwayTask: true)); this.schedulerAdapterClientFactory = new SchedulerAdapterClientFactory(this.sharedData, this, dispatcherManager, this.context); try { // Bug 14035: Need to call GetSchedulerAdapterClient() to invoke RegisterJob() operation await this.schedulerAdapterClientFactory.GetSchedulerAdapterClientAsync(); } catch (Exception e) { BrokerTracing.TraceVerbose("[ServiceJobMonitor].Start: Exception: {0}", e.ToString()); throw; } this.trigger = new RepeatableCallbackTrigger(); WaitCallback updateStatusWaitCallback = new ThreadHelper <object>(new WaitCallback(this.UpdateStatus)).CallbackRoot; WaitCallback loadSampleWaitCallback = new ThreadHelper <object>(new WaitCallback(this.LoadSample)).CallbackRoot; WaitCallback schedulerDelegationTimeoutCallback = new ThreadHelper <object>(new WaitCallback(this.SchedulerDelegationTimeout)).CallbackRoot; WaitCallback finishTaskCallback = new ThreadHelper <object>(new WaitCallback(this.FinishTasksThread)).CallbackRoot; BrokerTracing.TraceVerbose( "[ServiceJobMonitor].Start: Register updateStatusWaitCallback, interval={0}", this.sharedData.Config.Monitor.StatusUpdateInterval); this.trigger.RegisterCallback(TimeSpan.FromMilliseconds(this.sharedData.Config.Monitor.StatusUpdateInterval), TimeSpan.FromSeconds(FirstUpdateStatusSeconds), updateStatusWaitCallback, "TIMERCALLBACK"); BrokerTracing.TraceVerbose( "[ServiceJobMonitor].Start: Register loadSampleWaitCallback, interval={0}", this.sharedData.Config.Monitor.LoadSamplingInterval); this.trigger.RegisterCallback(TimeSpan.FromMilliseconds(this.sharedData.Config.Monitor.LoadSamplingInterval), loadSampleWaitCallback, null); this.trigger.RegisterCallback(TimeSpan.FromMilliseconds(FinishTasksInterval), TimeSpan.FromMilliseconds(FinishTasksInterval), finishTaskCallback, null); // Get value of automaticShrinkEnabled cluster param this.automaticShrinkEnabled = this.sharedData.BrokerInfo.AutomaticShrinkEnabled; // If the allocationAdjustInterval setting is not infinite, start timer to adjust the allocation as appropriate // Bug 10492: Disable grow/shrink in debug mode if (this.sharedData.Config.Monitor.AllocationAdjustInterval != Timeout.Infinite && this.sharedData.StartInfo.EprList == null) { BrokerTracing.TraceVerbose( "[ServiceJobMonitor].Start: start the allocation adjust thread, interval={0}", this.sharedData.Config.Monitor.AllocationAdjustInterval); this.allocationAdjustThread.Start(); } this.trigger.Start(); this.schedulerNotifyTimeoutManager.RegisterTimeout(TimeoutPeriodFromSchedulerDelegationEvent, schedulerDelegationTimeoutCallback, null); if (this.sharedData.StartInfo.IsNoSession) { await this.OpenPreDefinedServiceHosts(); } BrokerTracing.TraceVerbose("[ServiceJobMonitor].Start: Exit"); }
/// <summary> /// override the Start Method in internal service job monitor /// </summary> /// <param name="startInfo"></param> /// <param name="dispatcherManager"></param> /// <param name="observer"></param> /// <returns></returns> public override async Task Start(SessionStartInfoContract startInfo, DispatcherManager dispatcherManager, BrokerObserver observer) { await this.Start(dispatcherManager, observer); }
/// <summary> /// Initializes a new instance of the AzureDispatcher class /// </summary> /// <param name="info">indicating the dispatcher info</param> /// <param name="binding">binding information</param> /// <param name="sharedData">indicating the shared data</param> /// <param name="observer">indicating the observer</param> /// <param name="queueFactory">indicating the queue factory</param> /// <param name="dispatcherIdle">set when the dispatcher enters idle status</param> public AzureDispatcher(DispatcherInfo info, Binding binding, SharedData sharedData, BrokerObserver observer, BrokerQueueFactory queueFactory, SchedulerAdapterClientFactory schedulerAdapterClientFactory, AutoResetEvent dispatcherIdle) : base(info, ProxyBinding.BrokerProxyBinding, sharedData, observer, queueFactory, schedulerAdapterClientFactory, dispatcherIdle) { // Initialize proxy client pool this.proxyClientPool = this.AttachProxyClientPool(this.Epr, sharedData.Config.LoadBalancing.MaxConnectionCountPerAzureProxy); // 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); } this.backendBindingData = new BindingData(binding); }
/// <summary> /// Initializes a new instance of the RequestReplyRequestContext class /// </summary> /// <param name="requestContext">core request context</param> /// <param name="observer">indicating the broker observer</param> /// <param name="client">indicating the broker client</param> public RequestReplyRequestContext(RequestContext requestContext, BrokerObserver observer, BrokerClient client) : base(requestContext.RequestMessage.Version, client) { this.requestContext = requestContext; this.observer = observer; }
/// <summary> /// Initializes a new instance of the BrokerController class /// This constructor is for inprocess broker as IResponseServiceCallback is directly passed /// isSingleton is set to false and BrokerAuth is set to null for inprocess broker /// </summary> /// <param name="clientManager">indicating the client manager</param> /// <param name="callbackInstance">indicating the callback instance</param> /// <param name="observer">indicating broker observer</param> public BrokerController(BrokerClientManager clientManager, IResponseServiceCallback callbackInstance, BrokerObserver observer) : this(false, clientManager, null, observer, null) { this.callbackInstance = callbackInstance; }
/// <summary> /// Override Start method and start dummy service job monitor /// </summary> /// <param name="startInfo"></param> /// <param name="dispatcherManager"></param> /// <param name="observer"></param> /// <returns></returns> public override async Task Start(SessionStartInfoContract startInfo, DispatcherManager dispatcherManager, BrokerObserver observer) { BrokerTracing.TraceVerbose("[ServiceJobMonitor].Start: Enter"); this.dispatcherManager = dispatcherManager; this.observer = observer; this.gracefulPreemptionHandler = new GracefulPreemptionHandler(this.dispatcherManager, this.sharedData.BrokerInfo.SessionId, taskId => this.FinishTask(taskId, isRunAwayTask: true)); this.schedulerAdapterClientFactory = new SchedulerAdapterClientFactory(this.sharedData, this, dispatcherManager, this.context); if (this.sharedData.Config.Monitor.AllocationAdjustInterval != Timeout.Infinite && this.sharedData.StartInfo.EprList == null) { BrokerTracing.TraceVerbose("[ServiceJobMonitor].Start: start the allocation adjust thread, interval={0}", this.sharedData.Config.Monitor.AllocationAdjustInterval); this.allocationAdjustThread.Start(); } // await SvcHostRestModule.OpenSvcHostsAsync(this.sharedData.BrokerInfo.SessionId, startInfo, ((ISchedulerNotify)this).TaskStateChanged); await((ISchedulerNotify)this).TaskStateChanged(SvcHostRestModule.CreateDummyTaskInfos(startInfo.IpAddress)); }
/// <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> /// Initializes a new instance of the DuplexRequestContext class /// </summary> /// <param name="request">request message</param> /// <param name="defaultTimeouts">default timeouts</param> /// <param name="innerChannel">inner channel</param> /// <param name="observer">indicating the broker observer</param> public DuplexRequestContext(Message request, IDefaultCommunicationTimeouts defaultTimeouts, IDuplexChannel innerChannel, BrokerObserver observer) : this(request, defaultTimeouts, innerChannel, observer, null) { }
/// <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> /// Initializes a new instance of the WssDispatcher class /// </summary> /// <param name="info">indicating the dispatcher info</param> /// <param name="binding">binding information</param> /// <param name="sharedData">indicating the shared data</param> /// <param name="observer">indicating the observer</param> /// <param name="queueFactory">indicating the queue factory</param> /// <param name="dispatcherIdle">set when the dispatcher enters idle status</param> public WssDispatcher(DispatcherInfo info, Binding binding, SharedData sharedData, BrokerObserver observer, BrokerQueueFactory queueFactory, SchedulerAdapterClientFactory schedulerAdapterClientFactory, AutoResetEvent dispatcherIdle) : base(info, binding, sharedData, observer, queueFactory, schedulerAdapterClientFactory, dispatcherIdle) { if (binding is BasicHttpBinding) { BasicHttpBinding httpBinding = binding as BasicHttpBinding; httpBinding.Security.Mode = BasicHttpSecurityMode.Message; httpBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate; httpBinding.Security.Message.AlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Basic128; } else { BrokerTracing.TraceWarning("[WssDispatcher]. The binding type is not HTTP {0}.", binding.GetType().ToString()); } }
/// <summary> /// Initializes a new instance of the RequestReplyRequestContext class /// </summary> /// <param name="requestContext">core request context</param> /// <param name="observer">indicating the broker observer</param> public RequestReplyRequestContext(RequestContext requestContext, BrokerObserver observer) : this(requestContext, observer, null) { }
/// <summary> /// Initializes a new instance of the AzureQueueFrontEnd class /// </summary> /// <param name="listenUri">uri the frontend listen to</param> /// <param name="binding">binding that the frontend uses</param> public AzureQueueFrontEnd(AzureQueueProxy proxy, Uri listenUri, BrokerObserver observer, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, SharedData sharedData) : base(listenUri.AbsoluteUri, observer, clientManager, brokerAuth, sharedData) { this.azureQueueProxy = proxy; this.receiveRequest = new BasicCallbackReferencedThreadHelper <IAsyncResult>(this.ReceiveRequest, this).CallbackRoot; }