Thursday, 29 March 2012

Actions and Funcs

For a long time now, I have been wanting to better understand Action<T>, Func<T1, T2>, and Predicate<T> in C#.  I have always understood that they are generic delegates, but I never could get where they are most appropriate to be used when designing a library or framework for other developers to use.  I did see examples in libraries like linq, AutoMapper, and RhinoMocks where I thought the usage of Actions or Funcs as extension points made a lot of sense.

So, with this in mind, I'm planning to devote a couple of posts about an exploration into Action<T>, Func<T1, T2>, and Predicate<T>.  Hopefully, by recording this journey I'll take more from it and even perhaps help a few other developers to better embrace these tools.

In this post, I just want to do a quick introduction to what Action<T>, Func<T1, T2>, and Predicate<T> are.  As I mentioned, these classes seem to be just another way to express a delegate in C#.  So why are they needed?  There seem to be many answers to that question.  First off, they allow for lambda expressions in C#, they are much more terse than anonymous delegates, and in my opinion they express a function pointer in a more direct way than a traditional delegate.  Plus, they are fun and make code more expressive.

Action<T>, Func<T1, T2>, Predicate<T> and delegates for that matter are just function pointers.  They allow functions to be passed around in code as data.

The place where most people have seen this the most is with C# events.  An event needs a delegate type in order to know what type of function it can register.  Then when you register that OnLoad event for example, the compiler will only allow a callback method to register against the event that conforms to the correct signature.

In the above example, we are defining a delegate with the common .NET event signature void (object sender, EventArgs e). This comes in handy when we want to wire up a callback function that will listen out for when the event fires.  Underneath, the complier is going to make a new collection of OnLoadHandler delegate types and add (+=) or remove (-=) callbacks from the collection.  Then when the event is fired, the collection will iterate and call all the registered functions.

So, events is one place that many developers are familiar with delegates.  Since Action<T> is a void returning generic delegate, can we use it instead.  Yes, and here is the code:

As you can see, we have eliminated the need for a delegate to be defined in the Page class.  And what is better, we got rid of that Page.OnLoadHandler scoping issue when we registered the event.  The Action<T> can be registered against the event and all the functions stay roughly the same.  This is pretty cool, however, with EventHandler<T> out there not that useful.  This is more of an example to get warmed up for more to come.

Alright, got it
It's easy to see what is going on here.  Action<T> allows us a better way to express a delegate.  So now it's time to define these guys.

Actions are delegates that always return void.  Each generic type defined (and in the same order) become the type of the parameter in the function.

Func<T1, T2>
Funcs are the most expressive generic delegate form.  They take at least two generic type arguments because the last one is always the return type of the delegate signature.  So, in this case T2 is the type that you want to return.

Predicates are Funcs that always return a boolean value.  All of Predicate's generic type arguments define the parameters in its delegate signature.

In the next post, I'll dig a bit deeper into some more typical usages for API design.  See ya then!

Saturday, 17 March 2012

First node.js unit test with nodeunit

Well, my little practice app has a few features now.  In fact, it is already getting a bit out of hand.  If I'm going to add more to it, I need to treat the project with a little more respect.  So, carrying on from my last node.js post about a simple module, I'm going to add a unit test.  Then, I begin the journey of placing most of my controller logic in modules (carefully) and unit testing everything.  Then, I can start to develop with much more confidence.

There seems to be a few unit testing frameworks out there for node.js.  So far I've checked out Expresso and nodeunit as well has having a glance at vows for a more BDD approach.  For this project, I'm choosing nodeunit because it seems like it will do the job and I like the syntax a little more than Expresso.

Nodeunit Install
Like most every package, nodeunit installs very smoothly with npm.

npm install nodeunit -g

In my environment (ubuntu), nodeunit needed to be globally installed (-g) in order for the nodeunit command to be available on the command line.

First Test
The first test I'm going to write is going to make sure that my format method in the dateFormatter.js module is working as expected.  So I first created a directory for tests (mkdir tests), then I added a new file named dateFormatterTest.js into the new directory.  Here is the code for the test module:

I've got my /tests directory on the same level as my /modules directory so I just go up a directory to require the module I want to test.

First Test Run
So, I'm ready for my first test run.  nodeunit will run all the tests in a directory so I can just type nodeunit /tests in the root directory to run the test.  And here is the result:

Looks good.  Now I'm ready to start breaking this thing up and adding more tests.

Friday, 9 March 2012

Who logged on? Get the source IP of a windows session

I've been looking after a few servers in a virtual host that is stretched for resource.  I started to notice that merely by the fact of many people logging on to the servers (and forgetting to log off) resources were being taken up and slowing down the entire virtual infrastructure.  Each login would spin up a few more services on the server and slowly deprive the rest of resource.

qwinsta and rwinsta to the rescue!
Two tools that are built into windows and often overlooked are qwinsta and rwinsta.  qwinsta will query the server for all the sessions (active or disconnected) that are registered on the server.  rwinsta will allow you to reset a session (again active or disconnected) by the session's id.  These tools have been invaluable for me to see if there are any sessions on the servers and be able to clean off the disconnected sessions left open.

qwinsta /server:<server name>

And then you can use rwinsta using the ID to kill the session:

rwinsta /server:<server name> 1

Administrator, who are you?
This left me with another problem.  As you can see somebody logged on as the local Administrator account and then left the session open.  How can I get the source IP address for this disconnected session so that I can track down who done it?  Enter CAD_UtilPack.

The CAD_UtilPack (free version) is a rich tool set for doing all sorts of admin tasks.  Inside there is a tool called ENVTSCIP.  This tool can easily be configured on a server to log the IP of someone requesting a new TS session, perfect.

*Disclaimer: I don't think I have to say it, but what comes next is not supported and not even tested that well.  But I did get everything to work on my Windows Server 2008 R2 box.

Ok, well now we have the tools.  I'm going to log all the connections and qwinsta info to the file C:\temp\logons.txt, then I'll be able to look up a logon and correlation the qwinsta ID.

To do this, I need to:

  1. Create a script to run at windows logon
  2. Edit the registry to include my script
  3. Drop the logon script and the ENVTSCIP in  %SystemRoot% \System32\ directory
  4. Sit back and wait

So, this is my registry script (tslogon.reg):

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]
"Userinit"="C:\\Windows\\system32\\userinit.exe, C:\\Windows\\system32\\tslogon.cmd,"

The userinit.exe was already in the registry so I'm just appending the tslogon.cmd to what exists already.

Here is the script that runs at logon (tslogon.cmd):

%SystemRoot%\System32\envtscip.exe >> c:\temp\logons.txt
echo %DATE% %TIME% >> c:\temp\logons.txt
echo. >> c:\temp\logons.txt
qwinsta >> c:\temp\logons.txt
echo. >> c:\temp\logons.txt
echo. >> c:\temp\logons.txt

This script is going to run ENVTSCIP from the %SystemRoot%\System32\ directory, log the date and time, and finally log out the current qwinsta result.

Finally, I create a logons.txt file in the C:\temp\ directory and give write permissions to everyone (yes not the best idea, but this is only a first stab).

I see you...
This is now what I get logged when the local Administrator logs on:

09/03/2012 17:42:08.99 

 SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE 
 services                                    0  Disc                        
>rdp-tcp#0         Administrator             1  Active  rdpwd               
 console                                     3  Conn                        
 rdp-tcp                                 65536  Listen  

You can see that ENVTSCIP gives us the WTSClientAddress, and qwinsta gave us the session ID when the session was initiated.  From there I can do an nslookup on the IP and get the machine name of the user that made the session.

Yes! However, there is some set up here.  I scripted the install and it was pretty easy to roll out, but I'm still not convinced this is the right solution.  Anyone know of a better way?

Thursday, 1 March 2012

WCF: Tracing the Raw SOAP XML

Recently, I needed to get a look at the actual SOAP message that was being sent between an app and a web service. Back in the .asmx days, I remember having to through a proxy between the app and the service, but WCF now allows for much better message inspection. This is done through the SvcTraceViewer.exe tool that ships with the Windows SDK.

The SvcTraceViewer, if configured correctly, can give you both the activities take place during a service call and the message body itself.  Using the config in the here, you only get the activities.  Here is the configuration if you want both the activities and the message body:

The initializeData attribute on the sharedListener node will define the log file that you want to create with the trace information.  Then you are ready to run your trace.  For my set up, after I run, I see an Accounts.svclog file appear in the root directory of the application.  This file can then be opened by the SvcTraceViewer.exe and analysed:

If you see the 'Received a message over a channel' and 'Received a reply over request channel' then your config is correct.  Now its time to figure out if the message coming back is correct!