|
//*****************************************************************************
// Description.....ESB Core - Routing
//
// Author..........Roman Kiss, rkiss@pathcom.com
// Copyright © 2010 ATZ Consulting Inc.
//
// Date Created: 03/03/10
//
// Date Modified By Description
//-----------------------------------------------------------------------------
// 03/03/10 Roman Kiss Initial Revision
//
//*****************************************************************************
//
#region Namespaces
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Routing;
using System.Web.Hosting;
using RKiss.ConfigLib;
#endregion
namespace RKiss.RoutingManager
{
#region BehaviorExtension - RoutingManager
public sealed class RoutingManagerExtensionElement : BehaviorExtensionElement
{
// Methods
public RoutingManagerExtensionElement()
{
this.RouteOnHeadersOnly = true;
}
protected override object CreateBehavior()
{
return new RoutingManagerBehavior()
{
FilterTableName = this.FilterTableName,
RepositoryEndpointName = this.RepositoryEndpointName,
RouteOnHeadersOnly = this.RouteOnHeadersOnly,
SoapProcessingEnabled = this.SoapProcessingEnabled,
};
}
#region Properties
public override Type BehaviorType
{
get
{
return typeof(RoutingBehavior);
}
}
[ConfigurationProperty("filterTableName", DefaultValue = null)]
public string FilterTableName
{
get
{
return (string)base["filterTableName"];
}
set
{
base["filterTableName"] = value;
}
}
[ConfigurationProperty("routeOnHeadersOnly", DefaultValue = true, Options = ConfigurationPropertyOptions.None)]
public bool RouteOnHeadersOnly
{
get
{
return (bool)base["routeOnHeadersOnly"];
}
set
{
base["routeOnHeadersOnly"] = value;
}
}
[ConfigurationProperty("soapProcessingEnabled", DefaultValue = true)]
public bool SoapProcessingEnabled
{
get
{
return (bool)base["soapProcessingEnabled"];
}
set
{
base["soapProcessingEnabled"] = value;
}
}
[ConfigurationProperty("repositoryEndpointName", DefaultValue = null, Options = ConfigurationPropertyOptions.None)]
public string RepositoryEndpointName
{
get
{
return (string)base["repositoryEndpointName"];
}
set
{
base["repositoryEndpointName"] = value;
}
}
#endregion
}
#endregion
#region RoutingManager
public sealed class RoutingManagerBehavior : IServiceBehavior
{
public string FilterTableName { get; set; }
public string RepositoryEndpointName { get; set; }
public bool RouteOnHeadersOnly { get; set; }
public bool SoapProcessingEnabled { get; set; }
public string RouterKey { get; set; }
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { }
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { }
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
if (!HostingEnvironment.IsHosted)
throw new InvalidOperationException("ProcessNotExecutingUnderHostedContext");
string virtualPath = (string)typeof(ServiceHostingEnvironment).GetProperty("CurrentVirtualPath", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static).GetValue(null, null);
this.RouterKey = virtualPath.Trim('/');
// bootstrap for RoutingService
RoutingConfiguration configuration = null;
if (serviceDescription.ServiceType == typeof(RoutingService))
{
#region RoutingService
if (string.IsNullOrEmpty(this.RepositoryEndpointName) && string.IsNullOrEmpty(this.FilterTableName))
{
}
else if (string.IsNullOrEmpty(this.RepositoryEndpointName) && !string.IsNullOrEmpty(this.FilterTableName))
{
System.IO.Stream stream = null;
try
{
string configVirtualPath = System.IO.Path.Combine(virtualPath, "web.config");
stream = HostingEnvironment.VirtualPathProvider.GetFile(configVirtualPath).Open();
string config = new StreamReader(stream).ReadToEnd();
configuration = new RoutingConfiguration(ServiceModelConfigHelper.CreateFilterTable(config, this.FilterTableName), this.RouteOnHeadersOnly);
Trace.WriteLine(string.Format("[{0}] RoutingService has been updated by local table", this.RouterKey));
}
finally
{
if (stream != null)
stream.Close();
}
configuration.SoapProcessingEnabled = this.SoapProcessingEnabled;
}
else
{
RoutingMetadata metadata = RepositoryProxy.GetRouting(this.RepositoryEndpointName, Environment.MachineName, virtualPath.Trim('/'), this.FilterTableName);
configuration = new RoutingConfiguration(ServiceModelConfigHelper.CreateFilterTable(metadata.Config, this.FilterTableName), metadata.RouteOnHeadersOnly);
configuration.SoapProcessingEnabled = metadata.SoapProcessingEnabled;
Trace.WriteLine(string.Format("[{0}] RoutingService has been updated by Repository", this.RouterKey));
}
// logging messages
if (configuration != null)
{
// routing service endpoints
foreach (var se in serviceDescription.Endpoints)
{
if (se.Behaviors.Find<TraceMessageEndpointBehavior>() == null)
se.Behaviors.Add(new TraceMessageEndpointBehavior());
}
// 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());
}
}
}
#endregion
}
else
{
Trace.WriteLine(string.Format("[{0}] RoutingManager behavior is done", this.RouterKey));
}
#region Opened
serviceHostBase.Opened += delegate(object sender, EventArgs e)
{
ServiceHostBase host = sender as ServiceHostBase;
RoutingExtension re = host.Extensions.Find<RoutingExtension>();
if (configuration != null && re != null)
{
re.ApplyConfiguration(configuration);
lock (AppDomain.CurrentDomain.FriendlyName)
{
AppDomain.CurrentDomain.SetData(this.RouterKey, re);
}
Trace.WriteLine(string.Format("[{0}] RoutingExtension has been store in the slot", this.RouterKey));
}
};
#endregion
}
}
#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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.