Click here to Skip to main content
15,891,184 members
Articles / Web Development / ASP.NET

Secure Web Services via Message oriented Middleware

Rate me:
Please Sign up or sign in to vote.
4.96/5 (43 votes)
1 May 200372 min read 337K   821   198  
Describes an approach for delivery of Soap Messages serialised using ASP.NET Web Client Services over MSMQ and MQ
// --------------------------------------------------------------------------------
// Module:      ConsoleDriver.cs
// Author:      SGregory
// Date:        02 January 2003
// Description: Contains dummy back end responses to requests
// --------------------------------------------------------------------------------
// $Archive: <VSS Path To File>/ConsoleDriver.cs $
// $Revision: 1 $ changed on $Date: 02 January 2003 20:01 $
// Last changed by $Author: Administrator $
// --------------------------------------------------------------------------------
using System;
using System.Messaging;
using System.IO;
using System.Text;
using System.Xml;


// --------------------------------------------------------------------------------
// Namespace:   WSAltRouteBEFake
// Author:      SGregory
// Date:        02 January 2003
// Description: Encapsulates dummy back-end code  
// --------------------------------------------------------------------------------
namespace WSAltRouteBEFake
{
	/// <summary>
	/// Summary description for ConsoleDriver.
	/// </summary>
	class ConsoleDriver
	{
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main(string[] args)
		{
			// Log startup
			TSLog("WSAltRouteBEFake process started [Monitoring MSMQ and MQ Queues].");

			// Delete Audit Queue contents
			MessageQueue objQueue = GetQ(".\\private$\\PoCMSMQAudit");
			objQueue.Purge();
			objQueue.Close();

			// Wait on some queues - some MSMQ, and some MQ...
			for (;;)
			{
				WaitOnMSMQQ(".\\private$\\Q0");
				WaitOnMSMQQ(".\\private$\\Q2");
				WaitOnMQQ("poc1");
			}
		}


		/// <summary>WSAltRouteBEFake.ConsoleDriver.WaitOnMSMQQ</summary>
        /// <author>SGregory</author>
        /// <date>02 January 2003</date>
        /// <remarks>Reads MSMQ queue for the next message - pauses 200ms</remarks>
        /// <param name="vstrQueueName" type="string">Queue to wait on</param>
        /// <preconditions>Queue exists</preconditions>
        /// <postconditions>Message returned or exception</postconditions>
        static void WaitOnMSMQQ(
			string vstrQueueName)
		{
			try
			{
				// We'll wait 200ms
				TimeSpan tWaitResp = new TimeSpan(0, 0, 0, 0, 200);
				// Get hold of the queue
				MessageQueue objQueue = GetQ(vstrQueueName);		
				// Wait for a message
				Message msg = objQueue.Receive(tWaitResp, MessageQueueTransactionType.Single);
				// Close the Queue
				objQueue.Close();

				// Get the message content direct from the BodyStream
				string strResp = string.Empty;
				byte[] bufIn = new Byte[msg.BodyStream.Length];
				msg.BodyStream.Position = 0;
				msg.BodyStream.Read(bufIn, 0, (int)msg.BodyStream.Length);
				string strCorrelationId = msg.Id;

				// Fake out a response to the message
				strResp = BuildFakeResponseFromBytes("MSMQ", bufIn);

				// Get the response queue
				objQueue = GetQ(vstrQueueName + "_Resp");

				// Send a message back
				MemoryStream stResp = new MemoryStream();
				stResp.Write(new UTF8Encoding().GetBytes(strResp), 0, strResp.Length);
				Message objMsg = new Message();
				objMsg.BodyStream = stResp;
				objMsg.Label = "PoCMSMQBEResp";
				objMsg.Recoverable = true;
				objMsg.CorrelationId = strCorrelationId;

				// Send the message under a single MSMQ internal transaction
				objQueue.Send(objMsg, MessageQueueTransactionType.Single);

				// Free resources on response Queue
				objQueue.Close();
			}
			catch(Exception e)
			{
				if (e.Message.IndexOf("Timeout for the requested operation has expired") < 0)
					TSLog("Exception caught in WSAltRouteBEFake[MSMQ]: " + e.Message + e.StackTrace);
			}
		}

		/// <summary>WSAltRouteBEFake.ConsoleDriver.WaitOnMQQ</summary>
		/// <author>SGregory</author>
		/// <date>02 January 2003</date>
		/// <remarks>Reads MQ queue for the next message - pauses 200ms</remarks>
		/// <param name="vstrQueueName" type="string">Queue to wait on</param>
		/// <preconditions>Queue exists</preconditions>
		/// <postconditions>Message returned or exception</postconditions>
		static void WaitOnMQQ(
			string vstrQueueName)
		{
			MQAX200.MQSession mqs = null;
			MQAX200.MQQueueManager qm = null;
			MQAX200.MQQueue q = null;
			MQAX200.MQQueue qresp = null;
			MQAX200.MQMessage msg = null;
			MQAX200.MQMessage msgresp = null;
			MQAX200.MQPutMessageOptions pmo = null;
			MQAX200.MQGetMessageOptions gmo = null;

			try
			{
				// Get a Session
				mqs = new MQAX200.MQSessionClass();
				// Get a Queue Manager (fdefault one)
				qm = (MQAX200.MQQueueManager)mqs.AccessQueueManager(string.Empty);
				// Open the Queue for read
				qresp = (MQAX200.MQQueue)qm.AccessQueue(vstrQueueName, (int)MQAX200.MQ.MQOO_INQUIRE + (int)MQAX200.MQ.MQOO_INPUT_AS_Q_DEF, string.Empty, string.Empty, string.Empty);
				// Ready a message
				msgresp = (MQAX200.MQMessage)mqs.AccessMessage();
				gmo = (MQAX200.MQGetMessageOptions)mqs.AccessGetMessageOptions();
				gmo.Options = (int)MQAX200.MQ.MQGMO_SYNCPOINT + (int)MQAX200.MQ.MQGMO_WAIT;
				gmo.WaitInterval = 200;
				// Wait a short time
				qresp.Get(msgresp, gmo, System.Reflection.Missing.Value);

				// Get value from the message
				string strResp = string.Empty;
				string strIn = msgresp.MessageData.ToString();
				string strCorrelationId = msgresp.MessageId;

				// Fake out a response
				strResp = BuildFakeResponseFromString("MQ", strIn);

				// Close Queue
				qresp.Close();

				// Write the message back
				q = (MQAX200.MQQueue)qm.AccessQueue(vstrQueueName + "_resp", (int)MQAX200.MQ.MQOO_OUTPUT, string.Empty, string.Empty, string.Empty);
				msg = (MQAX200.MQMessage)mqs.AccessMessage();
				msg.CorrelationId = strCorrelationId;
				pmo = (MQAX200.MQPutMessageOptions)mqs.AccessPutMessageOptions();
    
				// set up the contents of the output message
				msg.WriteString(strResp);
       
				// finally, put the message
				q.Put(msg, pmo);
				// Close the response Queue
				q.Close();
			}
			catch(Exception e)
			{
				if (e.Message.IndexOf("MQRC_NO_MSG_AVAILABLE") < 0)
					TSLog("Exception caught in WSAltRouteBEFake[MQ]: " + e.Message + e.StackTrace);
			}
			finally
			{
				// Tidy
				qm.Commit();
				qm.Disconnect();
				qm = null;
			}
		}


		/// <summary>WSAltRouteBEFake.ConsoleDriver.GetQ</summary>
        /// <author>SGregory</author>
        /// <date>02 January 2003</date>
        /// <remarks>Gets an MSMQ Message Queue given a name</remarks>
        /// <param name="vstrQueueName" type="string">Queue Name</param>
        /// <returns type="System.Messaging.MessageQueue">Queue object</returns>
        /// <preconditions>Valid Queue Name</preconditions>
        /// <postconditions>May create a Queue if required</postconditions>
        static private MessageQueue GetQ(string vstrQueueName)
		{
			MessageQueue msgQ = null;
			
			// Does the Queue exist?
			if (MessageQueue.Exists(vstrQueueName) == false)
			{
				// No
				// Create the Message Queue
				// Make it transactional
				msgQ = MessageQueue.Create(vstrQueueName, true);
			}
			else
			{
				// The Queue exists already.  So just open it
				msgQ = new MessageQueue(vstrQueueName);
			}

			// Either way, return the Queue object to the caller
			return msgQ;
		}



		/// <summary>WSAltRouteBEFake.ConsoleDriver.BuildFakeResponseFromBytes</summary>
        /// <author>Cheese</author>
        /// <date>12 January 2003</date>
		/// <remarks>If we can find a marker (HelloWorld / createColour etc.) then return a stock response</remarks>
		/// <param name="strScheme" type="string">Indicates MSMQ vs. MQ etc.</param>
		/// <param name="strIn" type="string">Soap 'request' message</param>
		/// <returns type="string">Dummy Soap return message</returns>
        static private string BuildFakeResponseFromBytes(
			string vstrScheme,
			byte[] vbytIn)
		{
			string strResp = string.Empty;
			string vstrIn = new UTF8Encoding().GetString(vbytIn);

			// If we can find a marker (HelloWorld / createColour) then return a stock response
			if (vstrIn.IndexOf("HelloWorldArr") >= 0)
			{
				TSLog("  Spotted inbound " + vstrScheme + " [HelloWorldArr] message");
				strResp = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><HelloWorldArrResponse xmlns=\"http://tempuri.org/\"><HelloWorldArrResult><string>Hello</string><string>World</string><string>of</string><string>Simon" + vstrScheme + "[Arr]</string></HelloWorldArrResult></HelloWorldArrResponse></soap:Body></soap:Envelope>";
			}
			else
			if (vstrIn.IndexOf("HelloWorld") >= 0)
			{
				TSLog("  Spotted inbound " + vstrScheme + " [HelloWorld] message");
				strResp = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><HelloWorldResponse xmlns=\"http://tempuri.org/\"><HelloWorldResult>Hello World of Simon" + vstrScheme + "</HelloWorldResult></HelloWorldResponse></soap:Body></soap:Envelope>";
			}
			else
			if (vstrIn.IndexOf("ReturnImage") >= 0)
			{
				TSLog("  Spotted inbound " + vstrScheme + " [ReturnImage] message");
				strResp = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><ReturnImageResponse xmlns=\"http://tempuri.org/\"><ReturnImageResult>";

				byte[] bytImage = null;
				FileStream fs = null;

				// Read a file and convert to base64
				fs = new FileStream("C:\\Help.gif", FileMode.Open);
				bytImage = new byte[fs.Length];
				fs.Read(bytImage, 0, bytImage.Length);
				fs.Close();
				string strBase64EncString = Convert.ToBase64String(bytImage);
				strResp += strBase64EncString;
				strResp += "</ReturnImageResult></ReturnImageResponse></soap:Body></soap:Envelope>";
			}
			else
			if (vstrIn.IndexOf("SendImage") >= 0)
			{
				TSLog("  Spotted inbound " + vstrScheme + " [SendImage] message");
				strResp = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><SendImageResponse xmlns=\"http://tempuri.org/\" /></soap:Body></soap:Envelope>";
				int intImgStart = vstrIn.IndexOf("<bytImage>")+10;
				int intImgEnd = vstrIn.IndexOf("</bytImage>");
				byte[] b = Convert.FromBase64String(vstrIn.Substring(intImgStart, intImgEnd-intImgStart));
				FileStream fs = new FileStream("C:\\SendImage" + vstrScheme + ".gif", FileMode.Create);
				fs.Write(b, 0, b.Length);
				fs.Close();
			}
			else
			if (vstrIn.IndexOf("createColour") >= 0)
			{
				TSLog("  Spotted inbound " + vstrScheme + " [createColour] message");
				// Need to change this soon!!
				strResp = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><HelloWorldResponse xmlns=\"http://tempuri.org/\"><HelloWorldResult>Hello World of Simon" + vstrScheme + "</HelloWorldResult></HelloWorldResponse></soap:Body></soap:Envelope>";
			}
			else
			{
				TSLog("  *** (BuildFakeResponseFromBytes) Spotted inbound " + vstrScheme + " [UNKNOWN near " + vstrIn.Substring(vstrIn.IndexOf("<soap:Body>")) + "] message");
			}

			return strResp;
		}


		/// <summary>WSAltRouteBEFake.ConsoleDriver.BuildFakeResponseFromString</summary>
        /// <author>SGregory</author>
        /// <date>02 January 2003</date>
        /// <remarks>If we can find a marker (HelloWorld / createColour etc.) then return a stock response</remarks>
        /// <param name="strScheme" type="string">Indicates MSMQ vs. MQ etc.</param>
        /// <param name="strIn" type="string">Soap 'request' message</param>
        /// <returns type="string">Dummy Soap return message</returns>
        static private string BuildFakeResponseFromString(
			string vstrScheme,
			string vstrIn)
		{
			byte[] bytIn = new UTF8Encoding().GetBytes(vstrIn);
			return BuildFakeResponseFromBytes(vstrScheme, bytIn);
		}


		/// <summary>WSAltRouteBEFake.ConsoleDriver.TSLog</summary>
        /// <author>SGregory</author>
        /// <date>02 January 2003</date>
        /// <remarks>Logs to Console with a timestamp</remarks>
        /// <param name="vstrMsg" type="string">Message to log</param>
        static private void TSLog(
			string strMsg)
		{
			Console.WriteLine(DateTime.Now.ToString("dd MMM yyyy, HH:mm:ss") + ":  " + strMsg);
		}
	}
}

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United Kingdom United Kingdom
I am the Technical Director for Myphones.com, which specialises in developing integrated VoIP products and services for the consumer and SME markets. Technology-wise, we are heavily into the 2nd generation WS stack atop .NET, and basically most things Microsoft, as well as C++ on Linux.

Comments and Discussions