Click here to Skip to main content
15,886,963 members
Articles / Hosted Services / Azure

RoutingService on Azure

Rate me:
Please Sign up or sign in to vote.
4.89/5 (10 votes)
18 Jul 2011CPOL19 min read 59.9K   429   20  
This article describes a design, implementation and usage of the WCF4 Routing Service hosted by Windows Azure.
//*****************************************************************************
//    Description.....Worfklow Helper 
//                                
//    Author..........Roman Kiss, rkiss@pathcom.com
//    Copyright © 2007 ATZ Consulting Inc.  (see included license.rtf file)     
//                        
//    Date Created:    04/04/11
//
//    Date        Modified By     Description
//-----------------------------------------------------------------------------
//    04/04/11    Roman Kiss     Initial Revision
//    07/07/11    Roman Kiss     Modify for azure channel
//*****************************************************************************
//  
#region Namespaces
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Routing;
using System.Threading;
using System.Xml.Linq;
using System.Text;
using System.IO;
using Microsoft.WindowsAzure.ServiceRuntime;
using System.Reflection;
using RKiss.RoutingManager;
using RKiss.ConfigLib;
#endregion


namespace RKiss.CustomChannels
{
    public class PublisherHelper
    {
        public static void DispatchMessage(Message message, string repositorySettingName)
        {
            //Debugger.Break();
            if (string.IsNullOrEmpty(repositorySettingName))
            {
                Trace.TraceWarning("Routing table cannot be refreshed, the endpointRepositoryName is empty");
                return;
            }

            var body = XElement.Load(message.GetReaderAtBodyContents().ReadSubtree());
            Guid ticketId = new Guid(body.Element(RoutingManagerDefaults.TicketId).Value);

            string action = message.Headers.Action;
            if (action == RoutingManagerDefaults.ActionBroadcaster)
            {
                #region Broadcaster
                string applicationFullName = body.Element(RoutingManagerDefaults.ApplicationFullName).Value;

                var endpoints = RoleEnvironment.CurrentRoleInstance.Role.Instances.Select(instance => instance.InstanceEndpoints["RouterManagerEndpoint"]);
                foreach (var endpoint in endpoints)
                {
                    ChannelFactory<IRoutingManager> factory = null;
                    try
                    {
                        EndpointAddress address = new EndpointAddress(String.Format("http://{0}/Router.svc/Agent", endpoint.IPEndpoint));
                        Binding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
                        factory = new ChannelFactory<IRoutingManager>(binding);
                        IRoutingManager channel = factory.CreateChannel(address);
                        channel.Refresh(ticketId);
                        factory.Close();
                    }
                    catch (CommunicationException)
                    {
                        if (factory != null && factory.State == CommunicationState.Faulted)
                            factory.Abort();
                        factory = null;

                    }
                    catch (Exception)
                    {
                        if (factory != null && factory.State != CommunicationState.Closed)
                            factory.Close();
                        factory = null;
                    }
                }
                #endregion
            }
            else if (action == RoutingManagerDefaults.ActionRefresh)
            {
                #region Refresh
                ThreadPool.QueueUserWorkItem(delegate
                {
                    //Debugger.Break();
                    RoutingManagerInfo info = null;

                    try
                    {
                        lock (AppDomain.CurrentDomain.FriendlyName)
                        {
                            info = AppDomain.CurrentDomain.GetData(RoleEnvironment.DeploymentId) as RoutingManagerInfo;
                        }

                        if (info == null)
                            throw new Exception(string.Format("Internal Error: missing RoutingManagerInfo in the slot '{0}'", AppDomain.CurrentDomain.FriendlyName));

                        var configuration = RKiss.RoutingManager.RuntimeRepository.GetRoutingConfiguration(repositorySettingName, info.RoutingManagerBehavior.FilterTableName);
                        if (configuration != null)
                        {
                            info.RoutingExtension.ApplyConfiguration(configuration);

                            // client endpoints
                            foreach (var filter in configuration.FilterTable)
                            {
                                foreach (var se in filter.Value as IEnumerable<ServiceEndpoint>)
                                {
                                    if (se.Behaviors.Find<TraceMessageEndpointBehavior>() == null)
                                        se.Behaviors.Add(new TraceMessageEndpointBehavior() { CopyAuthorizationHeader = info.RoutingManagerBehavior.CopyAuthorizationHeader });
                                }
                            }
                            Trace.TraceInformation("Routing table '{0}' has been updated - ticketId={1}", info.RoutingManagerBehavior.FilterTableName, ticketId);
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("Updating Routing table '{0}' failed - ticketId={1}. Error = {2}", info.RoutingManagerBehavior.FilterTableName, ticketId, ex.Message);
                    }
                });
                #endregion

            }
            else if (action == RoutingManagerDefaults.ActionSendStatus)
            {
                #region SendStatus
                string applicationFullName = body.Element(RoutingManagerDefaults.ApplicationFullName).Value;

                var endpoints = RoleEnvironment.CurrentRoleInstance.Role.Instances.Select(instance => instance.InstanceEndpoints["RouterManagerEndpoint"]);
                foreach (var endpoint in endpoints)
                {
                    ChannelFactory<IRoutingManager> factory = null;
                    try
                    {
                        EndpointAddress address = new EndpointAddress(String.Format("http://{0}/Router.svc/Agent", endpoint.IPEndpoint));
                        Binding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
                        factory = new ChannelFactory<IRoutingManager>(binding);
                        IRoutingManager channel = factory.CreateChannel(address);
                        channel.Status(ticketId);
                        factory.Close();
                    }
                    catch (CommunicationException)
                    {
                        if (factory != null && factory.State == CommunicationState.Faulted)
                            factory.Abort();
                        factory = null;

                    }
                    catch (Exception)
                    {
                        if (factory != null && factory.State != CommunicationState.Closed)
                            factory.Close();
                        factory = null;
                    }
                }
                #endregion
            }
            else if (action == RoutingManagerDefaults.ActionStatus)
            {
                #region Status
                ThreadPool.QueueUserWorkItem(delegate
                {
                    Debugger.Break();
                    RoutingManagerInfo info = null;

                    try
                    {
                        lock (AppDomain.CurrentDomain.FriendlyName)
                        {
                            info = AppDomain.CurrentDomain.GetData(RoleEnvironment.DeploymentId) as RoutingManagerInfo;
                        }

                        if (info == null)
                            throw new Exception(string.Format("Internal Error: missing RoutingManagerInfo in the slot '{0}'", AppDomain.CurrentDomain.FriendlyName));
                        
                        var configuration = info.RoutingExtension.GetType().GetProperty("RoutingConfiguration", BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(info.RoutingExtension, null) as RoutingConfiguration;
                        string xmlrc = ServiceModelConfigHelper.RoutingConfigurationToXml(configuration, info.RoutingManagerBehavior.FilterTableName).ToString();                      
                        
                        Trace.TraceInformation("Status Routing table '{0}' - ticketId={1}, RoutingConfiguration = {2}", info.RoutingManagerBehavior.FilterTableName, ticketId, xmlrc);
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("Status Routing table '{0}' failed - ticketId={1}. Error = {2}", info.RoutingManagerBehavior.FilterTableName, ticketId, ex.Message);
                    }
                });
                #endregion
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions