コード例 #1
0
ファイル: DuplexFrontEnd.cs プロジェクト: umialpha/Telepathy
        /// <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;
        }
コード例 #2
0
 /// <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;
 }
コード例 #3
0
 /// <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;
 }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
 /// <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;
     }
 }
コード例 #6
0
        /// <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;
        }
コード例 #7
0
        /// <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;
        }
コード例 #8
0
 /// <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;
 }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
        /// <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);
        }
コード例 #12
0
        /// <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");
        }
コード例 #13
0
 /// <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);
 }
コード例 #14
0
        /// <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);
        }
コード例 #15
0
 /// <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;
 }
コード例 #16
0
 /// <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;
 }
コード例 #17
0
        /// <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));
        }
コード例 #18
0
        /// <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);
        }
コード例 #19
0
 /// <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)
 {
 }
コード例 #20
0
        /// <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);
        }
コード例 #21
0
 /// <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());
     }
 }
コード例 #22
0
 /// <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)
 {
 }
コード例 #23
0
 /// <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;
 }