Exemple #1
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;
 }
        /// <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;
        }
Exemple #3
0
        /// <summary>
        /// Initializes a new instance of the BrokerInfo class from broker recover info
        /// </summary>
        /// <param name="recoverInfo">indicating the broker recover info</param>
        /// <param name="brokerInfo">indicating the broker start info</param>
        /// <param name="auth">indicating the broker auth</param>
        /// <param name="customBroker">indicating the custom broker configuration</param>
        /// <param name="pool">indicating the broker process pool</param>
        public BrokerInfo(BrokerRecoverInfo recoverInfo, BrokerStartInfo brokerInfo, BrokerAuthorization auth, CustomBrokerRegistration customBroker, BrokerProcessPool pool)
        {
            this.callbackToCloseBroker = new ThreadHelper <IAsyncResult>(new AsyncCallback(this.OnCloseBroker)).CallbackRoot;
            this.durable          = recoverInfo.Durable;
            this.brokerInfo       = brokerInfo;
            this.sessionId        = recoverInfo.SessionId;
            this.sessionStartInfo = recoverInfo.StartInfo;
            this.auth             = auth;
            this.customBroker     = customBroker;
            this.pool             = pool;

            this.sessionStartInfo.IpAddress = BrokerLauncherSettings.Default.SvcHostList.Cast <string>().ToArray();
            this.sessionStartInfo.RegPath   = BrokerLauncherSettings.Default.CCP_SERVICEREGISTRATION_PATH;
        }
Exemple #4
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;
 }
Exemple #5
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);
        }
Exemple #6
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);
        }
Exemple #7
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);
        }
Exemple #8
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);
        }
Exemple #9
0
        /// <summary>
        /// Create a broker appdomain
        /// </summary>
        /// <param name="recoverInfo">broker recover info</param>
        /// <param name="sessionid">session id</param>
        /// <param name="durable">indicate if the session is durable</param>
        /// <param name="attached">indicate if it is attaching</param>
        /// <returns>returns the initialization result</returns>
        private async Task <BrokerInitializationResult> CreateBrokerAndRun(BrokerRecoverInfo recoverInfo, bool attached, ClusterInfoContract clusterInfo)
        {
            // Check the brokerDic to see if the session Id already exists
            lock (this.brokerDic)
            {
                if (this.brokerDic.ContainsKey(recoverInfo.SessionId))
                {
                    ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_SessionIdAlreadyExists, SR.SessionIdAlreadyExists, recoverInfo.SessionId.ToString());
                }

                if (BrokerLauncherSettings.Default.MaxConcurrentSession > 0 && this.brokerDic.Count >= BrokerLauncherSettings.Default.MaxConcurrentSession)
                {
                    ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_TooManyBrokerRunning, SR.TooManyBrokerRunning, BrokerLauncherSettings.Default.MaxConcurrentSession.ToString());
                }
            }

            //TODO: SF: make sure the clusterInfo.NetworkTopology string can be converted to ClusterTopology enum
            //ClusterTopology topo = ClusterTopology.Public;
            // ClusterTopology topo;
            // Enum.TryParse<ClusterTopology>(clusterInfo.NetworkTopology, out topo);

            //get soa configurations
            Dictionary <string, string> soaConfig = new Dictionary <string, string>();
            List <string> keys = new List <string>()
            {
                Constant.RegistryPathEnv, Constant.AutomaticShrinkEnabled, Constant.NettcpOver443, Constant.NetworkPrefixEnv, Constant.EnableFqdnEnv
            };

            soaConfig = await this.schedulerHelper.GetSOAConfigurations(keys);

            ServiceRegistrationRepo serviceRegistration = await this.GetRegistrationRepo(soaConfig[Constant.RegistryPathEnv]);

            string serviceRegistrationPath = serviceRegistration.GetServiceRegistrationPath(recoverInfo.StartInfo.ServiceName, recoverInfo.StartInfo.ServiceVersion);

            if (serviceRegistrationPath == null)
            {
                throw new FileNotFoundException("Registration file is not found", recoverInfo.StartInfo.ServiceName);
            }

            CustomBrokerRegistration customBroker = GetCustomBroker(serviceRegistrationPath);

            // Build the broker start info
            BrokerStartInfo brokerInfo = new BrokerStartInfo();

            brokerInfo.SessionId = recoverInfo.SessionId;
#if HPCPACK
            brokerInfo.JobOwnerSID = await this.schedulerHelper.GetJobOwnerSID(brokerInfo.SessionId);
#endif

            brokerInfo.Durable  = recoverInfo.Durable;
            brokerInfo.Attached = attached;
            //this is scheduler node or cluster connection string
            brokerInfo.Headnode          = this.headnode;
            brokerInfo.PurgedFailed      = recoverInfo.PurgedFailed;
            brokerInfo.PurgedProcessed   = recoverInfo.PurgedProcessed;
            brokerInfo.PurgedTotal       = recoverInfo.PurgedTotal;
            brokerInfo.ConfigurationFile = serviceRegistrationPath;
            brokerInfo.NetworkTopology   = 0; // ClusterTopology.Public

            brokerInfo.ClusterName = clusterInfo.ClusterName;
            brokerInfo.ClusterId   = clusterInfo.ClusterId;
            brokerInfo.AzureStorageConnectionString = clusterInfo.AzureStorageConnectionString;

            brokerInfo.Standalone = BrokerLauncherEnvironment.Standalone;


            brokerInfo.UseAad      = recoverInfo.StartInfo.UseAad;
            brokerInfo.AadUserSid  = recoverInfo.AadUserSid;
            brokerInfo.AadUserName = recoverInfo.AadUserName;

            if (soaConfig.TryGetValue(Constant.AutomaticShrinkEnabled, out var v))
            {
                brokerInfo.AutomaticShrinkEnabled = Convert.ToBoolean(v);
            }
            else
            {
                brokerInfo.AutomaticShrinkEnabled = false;
            }

            if (SoaHelper.IsOnAzure())
            {
                brokerInfo.EnableDiagTrace = true;
            }
            else
            {
                brokerInfo.EnableDiagTrace = SoaDiagTraceHelper.IsDiagTraceEnabled(recoverInfo.SessionId);
            }

            if (!SoaHelper.IsSchedulerOnAzure())
            {
                // default value is true
                bool nettcpOver443 = true;

                string value = soaConfig[Constant.NettcpOver443];

                if (!string.IsNullOrEmpty(value))
                {
                    if (!bool.TryParse(value, out nettcpOver443))
                    {
                        nettcpOver443 = true;
                    }
                }

                brokerInfo.HttpsBurst = !nettcpOver443;
            }

            if (SoaHelper.IsSchedulerOnAzure())
            {
                // do not need network prefix for the Azure nodes
                brokerInfo.NetworkPrefix = string.Empty;
            }
            else
            {
                brokerInfo.NetworkPrefix = soaConfig[Constant.NetworkPrefixEnv];
            }

            // get enableFQDN setting from the cluster env var
            bool enableFQDN = false;

            string enableFqdnStr = soaConfig[Constant.EnableFqdnEnv];

            if (!string.IsNullOrEmpty(enableFqdnStr))
            {
                if (bool.TryParse(enableFqdnStr, out enableFQDN))
                {
                    brokerInfo.EnableFQDN = enableFQDN;

                    BrokerTracing.TraceVerbose(
                        "[BrokerManager].CreateBrokerAndRun: The enableFQDN setting in cluster env var is {0}",
                        enableFQDN);
                }
                else
                {
                    BrokerTracing.TraceError(
                        "[BrokerManager].CreateBrokerAndRun: The enableFQDN setting \"{0}\" in cluster env var is not a valid bool value.",
                        enableFqdnStr);
                }
            }

            // set persist version.
            if (!brokerInfo.Attached)
            {
                //if creating a new session, set persist version to BrokerVersion.PersistVersion
                brokerInfo.PersistVersion = BrokerVersion.PersistVersion;
            }
            else
            {
                //if attaching an existing session, get PersistVersion from recoverInfo
                if (recoverInfo.PersistVersion.HasValue)
                {
                    brokerInfo.PersistVersion = recoverInfo.PersistVersion.Value;
                }
                else
                {
                    // if recover info doesn't have PersistVersion info, default to DefaultPersistVersion
                    brokerInfo.PersistVersion = BrokerVersion.DefaultPersistVersion;
                }

                // if version is not supported, throw UnsupportedVersion exception
                if (!BrokerVersion.IsSupportedPersistVersion(brokerInfo.PersistVersion))
                {
                    ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_UnsupportedVersion, SR.UnsupportedVersion, brokerInfo.PersistVersion.ToString(), BrokerVersion.PersistVersion.ToString());
                }
            }
            BrokerAuthorization auth = null;
            if (recoverInfo.StartInfo.Secure)
            {
                if (recoverInfo.StartInfo.ShareSession)
                {
#if HPCPACK
                    brokerInfo.JobTemplateACL = await this.schedulerHelper.GetJobTemplateACL(recoverInfo.StartInfo.JobTemplate);

                    auth = new BrokerAuthorization(brokerInfo.JobTemplateACL, (int)JobTemplateRights.SubmitJob, (int)JobTemplateRights.Generic_Read, (int)JobTemplateRights.Generic_Write, (int)JobTemplateRights.Generic_Execute, (int)JobTemplateRights.Generic_All);
#endif
                    // TODO: support share session
                    throw new NotImplementedException();
                }
                else
                {
                    auth = new BrokerAuthorization(new SecurityIdentifier(brokerInfo.JobOwnerSID));
                }
            }

            BrokerInfo info = new BrokerInfo(recoverInfo, brokerInfo, auth, customBroker, this.pool);
            try
            {
                info.BrokerExited += new EventHandler(this.BrokerInfo_BrokerExited); // if the broker exit quickly due to short timeouts, the broker info could remain in the brokerDic, because it is added later.

                info.StartBroker();

                lock (this.brokerDic)
                {
                    if (BrokerLauncherSettings.Default.MaxConcurrentSession > 0 && this.brokerDic.Count >= BrokerLauncherSettings.Default.MaxConcurrentSession)
                    {
                        ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_TooManyBrokerRunning, SR.TooManyBrokerRunning, BrokerLauncherSettings.Default.MaxConcurrentSession.ToString());
                    }

                    if (this.brokerDic.ContainsKey(recoverInfo.SessionId))
                    {
                        ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_SessionIdAlreadyExists, SR.SessionIdAlreadyExists, recoverInfo.SessionId.ToString());
                    }

                    this.brokerDic.Add(recoverInfo.SessionId, info);
                }

                // Update broker info into job property
                await this.schedulerHelper.UpdateBrokerInfo(info);
            }
            catch (Exception e)
            {
                // Some exception happens during the call, do some clean up
                TraceHelper.TraceEvent(recoverInfo.SessionId, System.Diagnostics.TraceEventType.Error, "[BrokerManager] CreateBrokerDomainAndRun: Failed : {0}\nRevert change...", e);

                // Bug 5378: If the broker is raised because of attaching (failover), revert it to suspend but not finished state
                RevertCreateDomainAndRun(info, attached);
                throw;
            }

            return(info.InitializationResult);
        }
Exemple #10
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;
 }
Exemple #11
0
        /// <summary>
        /// Run the broker
        /// </summary>
        /// <param name="startInfo">session start info</param>
        /// <param name="brokerInfo">indicate the broker start info</param>
        /// <returns>initialization result</returns>
        public BrokerInitializationResult Run(SessionStartInfoContract startInfo, BrokerStartInfo brokerInfo)
        {
            BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerEntry] Broker is starting initialization, ID = {0}", brokerInfo.SessionId);

            try
            {
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: ClusterTopology is {0}", brokerInfo.NetworkTopology);

                // Step 1: Initialize configuration and shared data
                ServiceConfiguration serviceConfig;
                BrokerConfigurations brokerConfig;
                BindingsSection      bindings;
                SoaCommonConfig.WithoutSessionLayer = startInfo.IsNoSession; // TODO: this is a hack. Working mode should be decided by something like a *SchedulerType* filed.

                ConfigurationHelper.LoadConfiguration(startInfo, brokerInfo, out brokerConfig, out serviceConfig, out bindings);
                this.sharedData = new SharedData(brokerInfo, startInfo, brokerConfig, serviceConfig);
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 1: Loading configuration and shared data succeeded.");
                Debug.WriteLine($"[BrokerEntry](Debug) UseAad:{startInfo.UseAad}");

                // Step 2: Initialize broker queue
                ClientInfo[] clientInfo;
                this.brokerQueueFactory = BrokerEntry.InitBrokerQueue(this.sharedData, out clientInfo);
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 2: Initialize broker queue succeeded.");

                // Step 3: Initialize observer
                this.observer            = new BrokerObserver(this.sharedData, clientInfo);
                this.sharedData.Observer = this.observer;
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 3: Initialize broker observer succeeded.");

                // Step 4: Initialize state manager
                this.stateManager = new BrokerStateManager(this.sharedData, clientInfo.Length != 0);
                this.stateManager.UnloadBroker += this.UnloadBroker;
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 4: Initialize broker state manager succeeded.");

                // Step 5: Initialize service job monitor
                var context = TelepathyContext.GetOrAdd(this.sharedData.BrokerInfo.Headnode);

                if (SoaCommonConfig.WithoutSessionLayer)
                {
                    this.monitor = new DummyServiceJobMonitor(this.sharedData, this.stateManager, this.nodeMappingData, context);
                }
                else
                {
                    this.monitor = new ServiceJobMonitor.ServiceJobMonitor(this.sharedData, this.stateManager, this.nodeMappingData, context);
                }
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 5: Initialize service job monitor succeeded.");

                // Step 6: Initalize broker authorization
                this.brokerAuth = BrokerEntry.BuildBrokerAuthorization(this.sharedData);
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 6: Initialize broker authorization succeeded.");

                // Step 7: Initialize dispatcher manager
                DispatcherManager dispatcherManager = new DispatcherManager(bindings, this.sharedData, this.observer, this.monitor, this.brokerQueueFactory, context);
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 7: Initialize dispatcher manager succeeded.");

                // Step 8: Start service job monitor
                this.monitor.Start(startInfo, dispatcherManager, this.observer).GetAwaiter().GetResult();
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 8: Start service job monitor succeeded.");

                // Step 9: Initailize client manager
                this.clientManager = new BrokerClientManager(clientInfo, this.brokerQueueFactory, this.observer, this.stateManager, this.monitor, this.sharedData);
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 9: Initialize client manager succeeded.");

                // if using AzureQueue, retrieve the connection string and build the request and response message queues if not exist
                string[] requestQueueUris           = { };
                string   requestBlobUri             = string.Empty;
                string   controllerRequestQueueUri  = string.Empty;
                string   controllerResponseQueueUri = string.Empty;
                if (startInfo.UseAzureStorage)
                {
                    int clusterHash = 0;
                    if (!string.IsNullOrEmpty(brokerInfo.ClusterId))
                    {
                        string clusterIdString = brokerInfo.ClusterId.ToLowerInvariant();
                        clusterHash = clusterIdString.GetHashCode();
                    }
                    else if (!string.IsNullOrEmpty(brokerInfo.ClusterName))
                    {
                        string clusterNameString = brokerInfo.ClusterName.ToLowerInvariant();
                        clusterHash = clusterNameString.GetHashCode();
                    }
                    else
                    {
                        throw new InvalidOperationException($"Both {nameof(brokerInfo.ClusterId)} and {nameof(brokerInfo.ClusterName)} are null or empty. No {nameof(clusterHash)} can be determined.");
                    }

                    if (!string.IsNullOrEmpty(brokerInfo.AzureStorageConnectionString))
                    {
                        this.azureQueueProxy = new AzureQueueProxy(brokerInfo.ClusterName, clusterHash, this.SessionId, brokerInfo.AzureStorageConnectionString);
                        requestQueueUris     = this.azureQueueProxy.RequestQueueUris;
                        requestBlobUri       = this.azureQueueProxy.RequestBlobUri;
                        var requestQName  = CloudQueueConstants.GetBrokerWorkerControllerRequestQueueName(this.SessionId);
                        var responseQName = CloudQueueConstants.GetBrokerWorkerControllerResponseQueueName(this.SessionId);
                        controllerRequestQueueUri = CloudQueueCreationModule.CreateCloudQueueAndGetSas(
                            brokerInfo.AzureStorageConnectionString,
                            requestQName,
                            CloudQueueCreationModule.AddMessageSasPolicy).GetAwaiter().GetResult();
                        controllerResponseQueueUri = CloudQueueCreationModule.CreateCloudQueueAndGetSas(
                            brokerInfo.AzureStorageConnectionString,
                            responseQName,
                            CloudQueueCreationModule.ProcessMessageSasPolicy).GetAwaiter().GetResult();
                        if (this.SessionId == SessionStartInfo.StandaloneSessionId)
                        {
                            CloudQueueCreationModule.ClearCloudQueuesAsync(brokerInfo.AzureStorageConnectionString, new[] { requestQName, responseQName });
                        }
                    }
                    else
                    {
                        BrokerTracing.TraceError("[BrokerEntry] Initialization: Use Azure Queue is specified, however the Azure connection string is not set.");
                        ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_AzureConnectionStringNotAvailable, SR.Broker_AzureConnectionStringNotAvailable);
                    }
                }

                // Step 10: Initialize frontend
                this.frontendResult = FrontEndBuilder.BuildFrontEnd(this.sharedData, this.observer, this.clientManager, this.brokerAuth, bindings, this.azureQueueProxy);
                ////this.maxMessageSize = (int)this.frontendResult.MaxMessageSize;
                ////this.readerQuotas = this.frontendResult.ReaderQuotas;
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 10: Initialize frontend succeeded.");

                // Step 11: Start frontend, Initialization finished after this step
                this.OpenFrontend();
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 11: Open frontend succeeded.");

                // Step 12: Build initialization result and retrun to client
                BrokerInitializationResult result = BrokerEntry.BuildInitializationResult(
                    this.frontendResult,
                    dispatcherManager,
                    this.sharedData.Config.LoadBalancing.ServiceOperationTimeout,
                    this.sharedData.Config.Monitor.ClientBrokerHeartbeatInterval,
                    this.sharedData.Config.Monitor.ClientBrokerHeartbeatRetryCount,
                    requestQueueUris,
                    requestBlobUri,
                    controllerRequestQueueUri,
                    controllerResponseQueueUri,
                    startInfo.UseAzureStorage);
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 12: Build initialization result suceeded.");
                BrokerTracing.TraceInfo("[BrokerEntry] Initialization succeeded.");
                return(result);
            }
            catch (Exception ex)
            {
                BrokerTracing.TraceError(ex.ToString());
                throw;
            }
            finally
            {
                if (this.sharedData != null)
                {
                    this.sharedData.InitializationFinished();
                }
            }
        }
Exemple #12
0
        /// <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 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 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;
 }