Monday, April 30, 2012

Fiddler & redirecting local traffic

Because I always forget the rule for redirecting requests that Fiddler receives while listening on port 8888 here it is below:

static function OnBeforeRequest(oSession: Session) {

//other statements

if (oSession.host == "localhost:8888") { oSession.host = "localhost:80" }

}

... where you can change localhost:80 to where the request needs to be redirected to

Monday, March 12, 2012

AppFabric, No monitoring data, and an empty ASEventSourcesTable table

A few months back, on some developer machines, their local install of AppFabric was failing to populate the local AppFabric monitoring database. I wrote at length here the trouble shooting I went through - i.e. all the typical components were working as expected, services, sql agents etc.... and no errors / warnings were being logged. 

The reason the monitoring events where not arriving at the monitoring database was because the ASEventSourcesTable (located in the monitoring database) was empty. 

This table is populated when the AppFabric Event Collector service is started, and for whatever reason was not being populated automatically on the machines who were not logging (the table contains a list of the services that are hosted in IIS who are applicable event sources). To date, I still haven't figured out why AppFabric is unable to populate it on certain machines. 

Using another install of AppFabric, where the ASEventSourcesTable was populated automatically, I manually inserted the missing rows into the empty ASEventSourcesTable, and boom - events start arriving in the ASWcfEventTables. 

So, along with the usual places to check when you cannot see events in the AppFabric monitoring database, check to make sure the ASEventSourcesTable has been populated. So far I have only seen this occur on Window 7 machines.

Wednesday, February 29, 2012

ActionFilterAttribute and ASP.Net Web API

Similar problem to my post around IDependencyResolver,

Custom action filters for web api controllers need to be derived from  System.Web.Http.Filters.ActionFilterAttribute

.... rather than System.Web.Mvc.ActionFilterAttribute

Thursday, February 23, 2012

IDependencyResolver and ASP.Net Web API

I've started playing around with the new ASP.Net Web Api (available as part of MVC 4), and was completely stumped as to why the GetService method on IDependencyResolver was not being called when my API controller was being requested. 

Controllers that were derived from Controller, GetService was called, however any controller deriving from ApiController GetService was not being fired (resulting in the No parameterless constructor defined for this object exception being thrown). 

Little did I know, IDependencyResolver for ApiControllers is a completely different type and is 'set' on a different resolver. 

Web API: System.Web.Http.Services.IDependencyResolver

Http: System.Web.Mvc.IDependencyResolver
And for setting the resolver for ApiControllers, it should be done as GlobalConfiguration.Configuration.ServiceResolver.SetResolver()

Rather than DependencyResolver.SetResolver()

Tuesday, December 20, 2011

Adding Soap Headers at the client using OperationContextScope

Pretty much a reminder for me, because I always forget exactly how to add custom headers at the client end dynamically, i.e. that is not part of the service contract. 

You can achieve this using the OperationContextScope - http://msdn.microsoft.com/en-us/library/aa395196.aspx

What this also means that you can access the headers in the response message using OperationContext.Current.IncomingMessageHeaders

Sunday, November 13, 2011

Performance and loading testing WCF services with JMeter - Part 2

A while ago I wrote a brief post about JMeter and performance / load testing WCF services. This post will list the steps I'm normally go through to set up JMeter from scratch to test a service, it also includes the steps for parameterising the request payload using a CSV file. 

  • Add a new thread group to the test plan. The loop count when using a CSV data set means how many times to process the file.

  • Under the thread group add a CSV Data Set Config element (available under Config Element). Typically I have the CSV file in the same location as the .jmx file which allows you to just specify the file name. In the below example RequestPayloads.csv contains a payload per line, request is the variable name that will be used as a placeholder to insert the sample into the soap envelope. This will become clearer in the next step. 

  • Add a Loop Controller to the thread group (which is located under Logic Controller), and tick the Forever option.  This will ensure all entries in the CSV file will be processed (rather than having to configure the thread group to have the right amount of loops to completly process the file). Under the Loop Controller add a SOAP/XML-RPC Request element. Enter the appropriate endpoint (URL) and SOAP action (ensure that this is ticked). The request body is where it gets interesting. Here I have stripped out the entire body of the request (i.e. the elements between the SOAP Body element - <soapenv:Body>), and replaced it with ${request} - where request is the name of the variable we set in the CSV Data Set Config element. 

  • Each line in the the CSV file contains the appropriate xml to replace ${request} - so for example, the service that JMeter is testing is expecting an body element called DoStuffRequest, so each line in my CSV file contains:

<DoStuffRequest><anotherElement><name>john</name></anotherElement></DoStuffRequest>

<DoStuffRequest><anotherElement><name>sam</name></anotherElement></DoStuffRequest>

<DoStuffRequest><anotherElement><name>peter</name></anotherElement></DoStuffRequest>

  • To determine how successful our request are (and to prove that the the CSV file is being processed) we'll need to add some listeners. Add a View Results Tree element under the thread group. Start the test, you should see something similar to the below where the each individual request is logged. Select the Request tab and check that it's been formatted correctly using the CSV file etc. Select the Response data tab and check the it's the response that you're expecting. 

  • A couple of other listeners that I normally use is the Summary Report, and a Spline Visualizer. Summary report is good for latency metrics, where the Spline visualizer is good to determine the behaviour of a service over time (e.g. does the latency slowly increase?). 

  • To increase the load that the service is under, up the thread count in the Thread Group element, which will result in more threads processing the CSV data set.

Tuesday, October 4, 2011

WCF Routing Service and routing on content

If you're wanting to do some content based routing on the message payload using XPath (i.e. creating a XPath filter type), ensure you have routeOnHeadersOnly set to true (which is set on the routing behaviour <routing routeOnHeadersOnly="True">), if not a FilterInvalidBodyAccessException will be thrown, which has the following message:

A filter has attempted to access the body of a Message. Use a MessageBuffer instead if body filtering is required.

Setting routeOnHeadersOnly to false, the message will be buffered.