Being a Good Host 2 – Grouping Multiple Services

Previously I gave a simple overview of hosting a single services in a form. If you’re developing a larger system and you have broken down business across several services, for reasons ranging from code management, to partitioning development tasks across teams, to reducing the compile time for a visual studio solution. You’re likely to want to keep the services separate but kick them off in groups; “Core System Services”, “Supporting Services”, “Reporting/Administration Services”, etc.

The most manual part is to merge the endpoints from all your individual config files into 1 single App.Config file that will accompany your production level deployment approach. This can also be used to package up the initial services mid-way through development when they are unlikely to change and it saves hassle running them as a group.

Watch-out-for: the contract definition in the config file; make sure it’s a fully qualified namespace for each service end point. You add individual references to your host application for each service you’re including.

<endpoint  
  address="net.tcp://localhost:8001/Patients"  
  binding="netTcpBinding"  
  bindingConfiguration="myNetTcpBinding"
  contract="Server.Patient.IPatientServiceContract" 
 />

For this example I’ve simply chosen to run it as a standard windows service, where all I need to do is implement OnStart() and OnStop() and if you think you need to OnPause() and OnContinue() or any of the other ServiceBase methods.

public partial class MultiServiceHost : ServiceBase
{
   private IList<ServiceHost> hosts = new List<ServiceHost>();
}

The OnStart() is simply a list of each of your services you’re grouping to run together.

protected override void OnStart(string[] args)
{
   try
   {
      hosts.Add(new ServiceHost(typeof(PatientService)));
      hosts.Add(new ServiceHost(typeof(MedicalProcedureService)));
      hosts.Add(new ServiceHost(typeof(OtherService)));
      //more hosts...
      StartServices();
   }
   //Catch ()...
}

A loop to kick off all the services, that’s called after they’re all added.

private void StartServices()
{
   foreach (ServiceHost h in hosts)
   {   h.Open();   }
}

Closing them all off upon shutdown of the host.

protected override void OnStop()
{
   foreach (ServiceHost host in _hosts)
   {
      if (host != null)
         host.Close();
   }
}

It’s that simple.

WPF Community Workshop

I attended a WPF Community Workshop yesterday (Sat 27/Mar/09). It was organised by The Australian Computer Society with help from some Readify guys; Mahesh Krishnan and David Burela. Our attendance fee was generously donated to the Red Cross Victorian Bushfire Appeal.

The day was targeted at people new to WPF. Which I knew going in but I still enjoy going over basic concepts, always learn a few extra little things (or at least get reminded of them). I would like to see more in depth workshops run, I’ll provide this feedback to the organisers.

As it turns out we were a test group for a set of lab activities titled “WPF Reactor”, I say this because the lab source code was out of sync with the lab instructions. Meaning it wasn’t subjected to any extensive Quality Assurance process before being burnt to little 2 disc foldout packages. With problems ranging from; lab task ordering issues (preceding labs had complete code for subsequent labs) to misleading (non-detailed or even erroneous) instructions. None the less it’s still a learning experience.

I managed to locate a download link for the lab material online (~410mb) on GainSecure.net full download here, lite download here. Those who have physical access to me, can get one of a few copies of the discs off me, not sure if it would be wise for me to upload 400mb to wordpress.

Some of the things to check out are:
– As an absolute must see of cool WPF tricks – Kevin’s WPF Bag-O-Tricks (a full VS solution of demos).
– The WPF toolkit on CodePlex.
– David Burela’s “WPF links for beginners” post – contains lots of links.
– A WPF/Silverlight tutorial site – NibblesTutorials.net.
– Expression Blend 3 Beta preview download – with a notable TFS integration amongst all the other enhancements.

To go way off topic. COBOL.

Inspired by a recent StackOverflow question about reading a file line by line in various languages. I quickly (evidently not quickly enough) dug up some 3rd year Uni labs on COBOL and tried to clean it up into a basic file reader. The post was closed up and made into a community wiki, while I was putting the comments on my COBOL application.

So I’ll be sharing it here. But first some background.

Back then we were writing labs and assignments to process large files, with the goal of doing it efficiently in particular on a machine that could not support storing the entire file contents in RAM. Having said that with the even larger volumes of data today it is still not practical to always load an entire file into memory.

This time I speak of wasn’t that long ago (only 2004), so we had reasonable machines hosting our Linux development environments. From what I recall the hype back then was 64 bit architectures, with the AMD Opteron having only just come out. And we’re still running x86 OS’s, shame.

The subject was focussed on understanding the processing cost of hard drive access and had us calculating latency, seek, and read times. Less of a concern with the speed of Hard Drives today (or even back then) but none the less very useful from a concept of learning fundamentals of the machines. I believe we were dealing with files that were under 1Gb, but obviously restricted from loading the entire file into memory at once. We were also required to incorporate sorting algorithms, no point in just reading and dumping a file, the trick being you couldn’t access the entire file so you had to sort in chunks. But that’s another concept.

The most annoying aspect was having to write code for a compiler that couldn’t handle a code file width greater than 80 characters. So the trick we were taught was to put in some comments at the top counting the spaces. (We would also adjust our terminal window to 80 characters wide).

      *  1         2         3         4         5         6         7
123456*89012345678901234567890123456789012345678901234567890123456789012
      *

Note in the samples COBOL reserved keywords are capitalised. The use of the full-stop was also a great headache for us. Even tho we were learning C/C++ and already well accustomed to putting semi-colons every where especially after struct/class definitions { }; The trick was actually not every line has a full stop. As a coding style you would continue on the next line for nested/associated sub-calls.

I don’t think there’s a WordPress ‘sourcecode’ tag attribute that will accept language=’COBOL’, so the highlighting won’t be perfect, even tho it’s not perfect for a lot of the WCF and C#3.0 code.

We would always start a code file off with some descriptive information. Of course indented to start at the 7th character position. The first 6 positions were used for line numbers. But it wasn’t mandatory to have line numbers in that region, at least not mandatory for our compiler.

IDENTIFICATION DIVISION.
PROGRAM-ID. myCobolFileInput.
AUTHOR. nj.

Then get right into declaring and opening file handles.

INPUT-SETUP SECTION.

FILE-CONTROL.
  SELECT file-in
    ASSIGN TO 'input.dat'.

In this example handling a file that’s 80 characters wide too, (79 data, 1 newline \n).

FD file-in.
01 line-in.
  05 data-part.
    10 current-line            PIC X(79).
  05 line-end-marker         PIC X. 

99 end-of-data  PIC XXX.

The main processing block (program loop etc).

PROCEDURE DIVISION.
100-executive-routine.
    PERFORM 200-open-files.
    PERFORM 300-read-input.
    PERFORM 400-write-output
        UNTIL end-of-data IS EQUAL TO "yes"
    PERFORM 500-close-file.

    STOP RUN.

And the rest:

200-open-files.
    OPEN INPUT  employee-details-in.
    MOVE "no" TO end-of-data.

300-read-input.
    READ employee-details-in
        AT END MOVE "yes" TO end-of-data.

400-write-output.
    DISPLAY current-line.

500-close-file.
    CLOSE file-in.

END PROGRAM myCobolFileInput.

No guarantees that’ll run as expected, as I really cannot be bothered even googling what would be required to get a compiler setup to handle this.

Interestingly the book (still on my book-shelf) that we were using for the course Mastering Cobol Programming (Palgrave Master) is available on Amazon.com.

I will get back to WCF/WPF material soon.

Talking Without Speaking, Hearing Without Listening.

In this blog I publish information and ideally have people that subscribe to it. For the blog I use the WordPress hosting site (service) you may use an RSS aggregator to subscribe (client). In a business application you can achieve this same concept easily with WCF. In this post I will run through an example of the Medical System Client application subscribing to patients of interest. When other clients update those same patients with business critical data the active clients can receive an ‘alert’ immediately at easily.

We begin with the client side setup. First we define the contract interface that contains our operational methods (excluded below, but examples include Save(), Retrieve(), etc). The key things to note on the interface is the ‘CallbackContract’ attribute, and the subscribe/unsubscribe methods. The subscription methods use a Patient Id key but this can be whatever is most suitable in your situation, for example an enum will work fine for more generalised event types.

[ServiceContract(CallbackContract = typeof(IPatientEvents))]
public interface IMyContract
{
   [OperationContract]
   void Subscribe(int patientId);
   [OperationContract]
   void UnSubscribe(int patientId);
}

The next step is to define an events interface. This interface outlines expected methods the client must implement to be able to handle the events raised by the service. Note that the event handler has an attribute defining it as a OneWay call. This event is lab results for a patient have been entered into the system, and are of a critical nature.

public interface IPatientEvents
{
   [OperationContract(IsOneWay = true)]
   void LabResultsUpdated(int id, string text);
}

Then you simply create your client side class against the events interface. In this example the client is a WPF page class.

class PatientDetails : Page, IPatientEvents
{
     MyContractClient proxy;
	 
	 //other methods
}

The client will need to supply a context to the service so it can maintain an association on the channel. This is simply achieved through a constructor call when initialising the proxy. Also at this point we’re subscribing to the events for the given ID. This subscription can be client triggered this way. Alternatively certain actions can have the server subscribe the client server side. An example would be during a data retrieval call for a patient; the server forcing the setup up the subscription.

  InstanceContext context = new InstanceContext(this);
  
  proxy = new MyContractClient(context);

  proxy.Subscribe(id);

Now on the service we implement the same contract IMyContract we also define the signature of the delegate Action that will be raised as an event. Along with implementing the method that will attach the event handler to the appropriate client. The key thing to note here is the Current.GetCallbackChannel this is linking via the context the client supplied in the proxy initialisation.

[ServiceBehavior(InstanceContextMode
      = InstanceContextMode.PerCall)]
class PatientService : IMyContract
{
    static Action<int, string> m_EventLabs = delegate { };

    public void Subscribe(int patientId)
    {
        IPatientEvents subscriber = 
          OperationContext.Current.GetCallbackChannel<IPatientEvents>();

        m_EventLabs += subscriber.LabResultsUpdated;
    }
}

All that’s left now is to write the actual event firing code, that can be triggered after an appropriate event. In this example the firing takes place after the Patients Lab Results have been updated. Thereby allowing any other users currently viewing this patient’s details to be alerted.

public static void FireEvent(LabResult labResult)
{
    m_EventLabs(labResult.PatientId, labResult.ToString());
}

public bool SaveLabResults(LabResult lr)
{
    //save code...

    PatientService.FireEvent(labResult);
}

Back on the client we have defined a method that will be executed upon the event. Remember the service has attached the handler on the Subscribe() method.

public void LabResultsUpdated(int id, string text)
{
    this.displayAlerts.Text = text;
}

That is all that is required to have your client quickly and easily subscribe to and handle events. It’s thread-safe and efficient with the service doing all the hard work.

I will expand on [ServiceContract(CallbackContract … ] and [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] in future posts, and I’ll try to remember to update this post with direct links.

Just for some reference sake here are the objects used above that were not defined in the code blocks:

[DataContract]
public class Patient
{    [DataMember]
    public int PatientId { get; set; }
    //more members
}
[DataContract]
public class LabResult
{    [DataMember]
    public int LabResultId { get; set; }
    //more members
}
//displayAlerts is just a page <TextBlock> object

This MessageHeader will self destruct in 5 seconds

Let’s get our hands dirty with an example you can follow along with. With the basic concepts covered we can whip up something to send some data back and forth. We will start with a simple winform to run our service. Another winform (acting as the client application) to connect to it so our service can do some intended job.

In this post I’m also going to introduce a refined and well developed library of enhancements for WCF. It is created by the very talented Juval Lowy you can find his work at IDesign.net. This library is called ServiceModelEx it is available as a free download, and it is very, very useful. I hope to demonstrate its usefulness in this and future posts. ServiceModelEx is designed to help simplify some of the more complex aspects of WCF along with adding extension to existing features. It makes some aspects of WCF more robust, such as adding TypeSafe alternatives and often adding an overlooked sub-feature (e.g. NetNamedPipeContextBinding I’ll discuss this in a future post).

Once you have ServiceModelEx downloaded and included in your Visual Studio project all you need to do is add a reference to it:

//WCF Service Model:
using System.ServiceModel;
//iDesign Service Model Extensions:
using ServiceModelEx;

In this post I’m introducing a theme for the demos; they will follow the ideas of a medical system. With concepts such as Patient, TreatmentSchedule, MedicalProcedure, Doctor, and other types of system Users (Nurses, LabTechnicians, etc).

On with it.
We are setting up a simple call to a service to create/update/delete a new patient.

To begin we will need to setup some data constructs (they are simplified to keep the code sections short, i.e. no extensive code to setup private members and public properties). A class MsgHeader will act as a common object sent ‘out-of-band’ on all calls to the service. The ‘out-of-band’ concept is used for the purpose of keeping data contracts free of plumbing-related operations. This example uses the header to supply something specific about the user, and the type of operation we are performing (enum OperationTypes). Another example of advanced control data you can pass via headers is a ‘message priority’ value.

[DataContract]
public class MsgHeader
{
    [DataMember]
    public int userRoleId;
    [DataMember]
    public int operationType;
}

A snippet of the data contract, and other setup data:

[DataContract]
public class Patient
{
   [DataMember]
   public int PatientId;
   //more members...
}

public enum OperationTypes { 
   Update = 0, Insert = 1, Delete = 2 }
public enum UserRoles { 
   Reception = 1, Nurse = 2, Doctor = 3 }

The Service is set up with a simple save/retrieve interface:

[ServiceContract]
interface IPatientContract
{
   [OperationContract]
   void SavePatient(Patient p);
   [OperationContract]
   Patient RetrievePatient(int patientId);
}

Via the Client proxy constructor we pass in our populated MsgHeader object. Then call any required methods on the proxy, in this case the save.

//class instance of patient details
public Patient CurrentPatient;

public void Save()
{
   MsgHeader header = new MsgHeader();
   //Set the properties accordingly ...

   //Setup and Call Proxy
   MedicalSystem proxy = new MedicalSystem(header);

   proxy.SavePatient(this.CurrentPatient);

   proxy.Close();
}

Finally on the service implementation to access the MsgHeader you simply use HeaderContext.Current.

class MedicalSystem : IPatientContract
{
   public void SavePatient(Patient p)
   {
      switch (HeaderContext.Current.dataOperation)
      {
         case (int)DataOperations.Delete:
            DeletePatient(p.id);
            break;
         case (int)DataOperations.Insert:
            CreateNewPatient(p);
            break;
         // ...
      }
   }
   // ...
}

There we have it – ‘out-of-band’ passing of data to your service to keep system entities free of the clutter of control data.

Putting all the basics together

Before we get stuck into a full scale example, I’ve prepared a simple checklist of tasks required to get a basic service up and running.

Refer to this checklist to get your first WCF solutions up and running quickly.

Service & (Host)

  1. Service Contract IMyServiceContract
  2. Implementation of that Contract
  3. Service Proxy Implementing ServiceContract & ClientBase<IMyServiceContract>
  4. Endpoints via App.Config
  5. Form/Console to kick off Host

Client

  1. Proxy implementing IMyServiceContract
  2. Endpoints to match those specified in service via App.config

If you haven’t done things right one of the very early exceptions you might receive is an InvalidOperationException and it will name the Contract that you haven’t implemented correctly. This is likely to be caused by a flaw in your app.config (server side).

A Common Exception from a Simple Misconfiguration

A Common Exception from a Simple Misconfiguration

Other exceptions to look out for are those when you attempt to call the service and either endpoints are misconfigured or implementations aren’t complete.

Being a Good Host

Hosting a WCF application is quite simple. There are 3 available hosting options IIS (Internet Information Services), WAS (Windows Activation Service) under Vista/Server 2008 and an ordinary (windows form/console) application.

The quickest to getting your project up and running is a windows form (or console) app. This way you can begin development quickly.

//program.cs
static class Program
{
   [STAThread]
   static void Main()
   {
      Application.Run(new FormWcfHost());
   }
}

Then for the windows form:

public partial class FormWcfHost : Form
{
   private ServiceHost<MyService> serviceManager 
      = new ServiceHost<MyService>();

   public FormWcfHost()
   {
      serviceManager.Open();
   }
		
   private void FormWcfHost_FormClosed(object sender, 
       FormClosedEventArgs e)
   {
      serviceManager.Close();
   }
}

It’s that simple.

The production level hosting decissions are just slightly more involved. Basically if you have an installation of Windows 2008 Server available then it’s ideal to make use of WAS to host it. Otherwise the choice can be argued between IIS6 hosting or just running it as a standard windows service on a Windows 2003 depolyment.

The advantages that WAS offers are; application pooling, isolation, identity management. So is the more scalable choice.