Click here to Skip to main content
15,891,253 members
Articles / Programming Languages / XML

WS-Transfer Service for Workflow

Rate me:
Please Sign up or sign in to vote.
4.93/5 (16 votes)
23 Nov 2006CPOL12 min read 96K   438   62  
This article describes a design and implementation of the WF workflow connectivity to the Windows Communication Foundation (WCF) Service for WS-Transfer operation contract.
//*****************************************************************************
//    Description.....Logging a MessageInspector on the Console
//                                
//    Author..........Roman Kiss, rkiss@pathcom.com
///    Copyright © 2005 ATZ Consulting Inc. (see included license.rtf file)       
//                        
//    Date Created:    06/06/05
//
//    Date        Modified By     Description
//-----------------------------------------------------------------------------
//    06/06/05    Roman Kiss     Initial Revision
//    02/22/06    Roman Kiss     Version FebCTP 2006
//    07/07/06    Roman Kiss     Version JuneCTP 2006
//*****************************************************************************
//  
#region References
using System;
using System.Configuration;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Configuration;
#endregion

namespace RKiss.Logger
{
    #region LogMessageInspector
    /// <summary>
    /// Publisher class 
    /// </summary>
    public class LogMessageInspector : IDispatchMessageInspector, IClientMessageInspector
    {
        #region Properties
        // stub
        bool _logAfterReceiveRequest = true;
        bool _logBeforeSendReply = true;
        // proxy
        bool _logAfterReceiveReply = true;
        bool _logBeforeSendRequest = true;

        public bool LogAfterReceiveRequest
        {
            get { return _logAfterReceiveRequest; }
            set { _logAfterReceiveRequest = value; }
        }
        public bool LogBeforeSendReply
        {
            get { return _logBeforeSendReply; }
            set { _logBeforeSendReply = value; }
        }
        public bool LogAfterReceiveReply
        {
            get { return _logAfterReceiveReply; }
            set { _logAfterReceiveReply = value; }
        }
        public bool LogBeforeSendRequest
        {
            get { return _logBeforeSendRequest; }
            set { _logBeforeSendRequest = value; }
        }
        #endregion

        #region IStubMessageInspector
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            if (LogAfterReceiveRequest && request != null)
            {
                using (MessageBuffer buffer = request.CreateBufferedCopy(int.MaxValue))
                {
                    Message msg = buffer.CreateMessage();
                    Console.ForegroundColor = msg.IsFault ? ConsoleColor.Red : ConsoleColor.Yellow;
                    Console.WriteLine("\n>>>>> ReceivedRequest {0}\n{1}\n", msg.Headers.MessageId, msg);
                    Console.ResetColor();
                    request = msg;
                }
            }
            return request;
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            if (LogBeforeSendReply && reply != null)
            {
                using (MessageBuffer buffer = reply.CreateBufferedCopy(int.MaxValue))
                {
                    Message msg = buffer.CreateMessage();
                    Console.ForegroundColor = msg.IsFault ? ConsoleColor.Red : ConsoleColor.Green;
                    Console.WriteLine("\n<<<<< SendReply {0}\n{1}\n", msg.Headers.ReplyTo, msg);
                    Console.ResetColor();
                    reply = msg;
                }
            }
        }
        #endregion

        #region IProxyMessageInspector
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            if (LogAfterReceiveReply && reply != null)
            {
                using (MessageBuffer buffer = reply.CreateBufferedCopy(int.MaxValue))
                {
                    Message msg = buffer.CreateMessage();
                    Console.ForegroundColor = msg.IsFault ? ConsoleColor.Red : ConsoleColor.Green;
                    if (msg.Headers.RelatesTo != null)
                        Console.WriteLine("\n>>>>>> ReceivedReply {0}\n{1}\n", msg.Headers.RelatesTo, msg);
                    else
                        Console.WriteLine("\n>>>>>> ReceivedReply {0}\n{1}\n", "?", msg);
                    Console.ResetColor();
                    reply = msg;
                }
            }
        }
        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            if (LogBeforeSendRequest && request != null)
            {
                using (MessageBuffer buffer = request.CreateBufferedCopy(int.MaxValue))
                {
                    Message msg = buffer.CreateMessage();
                    if (msg.Headers.MessageId == null)
                        msg.Headers.MessageId = new System.Xml.UniqueId();

                    Console.ForegroundColor = msg.IsFault ? ConsoleColor.Red : ConsoleColor.Yellow;
                    Console.WriteLine("\n>>>>> SendRequest {0}\n{1}\n", msg.Headers.MessageId, msg);
                    Console.ResetColor();
                    request = msg;
                }
            }
            return request;
        }
        #endregion
    }
    #endregion


    #region LoggerAttribute
    /// <summary>
    /// Plumbing class 
    /// </summary>
    [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class)]
    public class LoggerAttribute : Attribute, IEndpointBehavior, IServiceBehavior
    {
        #region Properties
        bool _enable = true;
        bool _logAfterReceiveRequest = true;
        bool _logBeforeSendReply = true;
        bool _logAfterReceiveReply = true;
        bool _logBeforeSendRequest = true;

        public bool Enable
        {
            get { return _enable; }
            set { _enable = value; }
        }
        public bool LogAfterReceiveRequest
        {
            get { return _logAfterReceiveRequest; }
            set { _logAfterReceiveRequest = value; }
        }
        public bool LogBeforeSendReply
        {
            get { return _logBeforeSendReply; }
            set { _logBeforeSendReply = value; }
        }
        public bool LogAfterReceiveReply
        {
            get { return _logAfterReceiveReply; }
            set { _logAfterReceiveReply = value; }
        }
        public bool LogBeforeSendRequest
        {
            get { return _logBeforeSendRequest; }
            set { _logBeforeSendRequest = value; }
        }
        #endregion

        #region IEndpointBehavior Members
        public void AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParameters)
        {
            //nothing to do;
        }
        public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
        {
            if (Enable)
            {
                LogMessageInspector inspector = new LogMessageInspector();
                inspector.LogAfterReceiveRequest = LogAfterReceiveRequest;
                inspector.LogBeforeSendReply = LogBeforeSendReply;
                inspector.LogAfterReceiveReply = LogAfterReceiveReply;
                inspector.LogBeforeSendRequest = LogBeforeSendRequest;
                behavior.MessageInspectors.Add(inspector);
            }
        }
        public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
        {
            LogMessageInspector inspector = new LogMessageInspector();
            inspector.LogAfterReceiveRequest = LogAfterReceiveRequest;
            inspector.LogBeforeSendReply = LogBeforeSendReply;
            inspector.LogAfterReceiveReply = LogAfterReceiveReply;
            inspector.LogBeforeSendRequest = LogBeforeSendRequest;
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
        }
        public void Validate(ServiceEndpoint serviceEndpoint)
        {
            //nothing to do;
        }
        #endregion

        #region IServiceBehavior Members
        public void AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
        {
            //nothing to do;
        }
        public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.WriteLine("Endpoints in the Service '{0}'", description.ConfigurationName);
            foreach (ServiceEndpoint se in description.Endpoints)
                Console.WriteLine(" {0}", se.Address.ToString());
            Console.WriteLine("");
            Console.ResetColor();

            foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers)
            {
                foreach (EndpointDispatcher epdispatch in cd.Endpoints)
                {
                    ApplyDispatchBehavior(null, epdispatch);
                }
            }
        }
        public void Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
            //nothing to do;
        }
        #endregion
    }
    #endregion


    #region LoggerBehaviorElement
    /// <summary>
    /// Configuration class
    /// </summary>
    public class LoggerBehaviorElement : BehaviorExtensionElement
    {
        #region Constructor(s)
        public LoggerBehaviorElement()
        {
        }
        #endregion

        #region ConfigurationProperties
        [ConfigurationProperty("enable", DefaultValue = true)]
        public bool Enable
        {
            get { return (bool)base["enable"]; }
            set { base["enable"] = value; }
        }

        [ConfigurationProperty("logAfterReceiveRequest", DefaultValue = true)]
        public bool LogAfterReceiveRequest
        {
            get { return (bool)base["logAfterReceiveRequest"]; }
            set { base["logAfterReceiveRequest"] = value; }
        }

        [ConfigurationProperty("logBeforeSendReply", DefaultValue = true)]
        public bool LogBeforeSendReply
        {
            get { return (bool)base["logBeforeSendReply"]; }
            set { base["logBeforeSendReply"] = value; }
        }

        [ConfigurationProperty("logAfterReceiveReply", DefaultValue = true)]
        public bool LogAfterReceiveReply
        {
            get { return (bool)base["logAfterReceiveReply"]; }
            set { base["logAfterReceiveReply"] = value; }
        }

        [ConfigurationProperty("logBeforeSendRequest", DefaultValue = true)]
        public bool LogBeforeSendRequest
        {
            get { return (bool)base["logBeforeSendRequest"]; }
            set { base["logBeforeSendRequest"] = value; }
        }
        #endregion

        #region BehaviorExtensionSection
        protected override object CreateBehavior()
        {
            LoggerAttribute logger = new LoggerAttribute();
            logger.Enable = (bool)this["enable"];
            logger.LogAfterReceiveRequest = (bool)this["logAfterReceiveRequest"];
            logger.LogBeforeSendReply = (bool)this["logBeforeSendReply"];
            logger.LogAfterReceiveReply = (bool)this["logAfterReceiveReply"];
            logger.LogBeforeSendRequest = (bool)this["logBeforeSendRequest"];
            return logger;
        }

        public override void CopyFrom(ServiceModelExtensionElement from)
        {
            base.CopyFrom(from);
            LoggerBehaviorElement section = (LoggerBehaviorElement)from;
            this.Enable = section.Enable;
            this.LogAfterReceiveRequest = section.LogAfterReceiveRequest;
            this.LogBeforeSendReply = section.LogBeforeSendReply;
            this.LogAfterReceiveRequest = section.LogAfterReceiveRequest;
            this.LogAfterReceiveReply = section.LogAfterReceiveReply;
            this.LogBeforeSendRequest = section.LogBeforeSendRequest;
        }

        protected override ConfigurationPropertyCollection Properties
        {
            get
            {
                ConfigurationPropertyCollection collection = new ConfigurationPropertyCollection();
                collection.Add(new ConfigurationProperty("enable", typeof(bool), true));
                collection.Add(new ConfigurationProperty("logAfterReceiveRequest", typeof(bool), true));
                collection.Add(new ConfigurationProperty("logBeforeSendReply", typeof(bool), true));
                collection.Add(new ConfigurationProperty("logAfterReceiveReply", typeof(bool), true));
                collection.Add(new ConfigurationProperty("logBeforeSendRequest", typeof(bool), true));
                return collection;
            }
        }
        #endregion

        public override Type BehaviorType
        {
            get { return typeof(LoggerAttribute); }
        }
    }
    #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