Today Microsoft hosted the Architecture Day. This is an interesting event where architects from different companies come together to talk about different topics (similar to the Regional Architect Forum). In this opportunity I proposed to do a presentation about Identity related to some work we did with a customer on Microsoft “Geneva”. So together with Sebastian Renzi (who was the PM in that project) we did a one hour presentation covering the basis of claim based identity and a demo of the work we did in this customer.

The presentation started by telling a story about a typical company that created its first application. This app used Windows Authentication so life was easy :). However business grew over time and they ended up with multiple applications, each one with its own identity repository, different authentication methods, support users accessing from intranet, internet, extranet, cloud, and so on and so forth. I grab this diagram from Stuart Kwan presentation from the Genevea Product Team (so thanks Stuart for the cool representation).

image

Then we went through the problems from different perspectives: the department who is in charge of security, the end user and the architect. (I wish I had the time to translate it to English but you can imagine…)

image image
image  

If you think about these problems, many of them can be solved if you follow this principle:

Externalize from the application logic the following responsibilities:

  • the process of authentication
  • the retrieval of attributes that will be used later for authorization

This is exactly what claim based identity is about. We setup an analogy between how an event registration works under the same principles of credentials, STS, claims and resources (kudos to Eugenio Pace who originally did this analogy in his PDC presentation).

image

Now, if I have to start a company I certainly would create my STS and applications and will use claim based identity. However, in the real world we know that the landscape is much more complex and there are existing applications with identity silos running everyday. Any disruptive change will be a huge mess for everyone. So this is the roadmap we established together with this customer (which is one of the biggest insurance company here in Argentina):

image

We decided to tackle authentication first and try to remove the identity silos in an organic fashion. Since they had many applications (some of them using SQL Server, some others AD, some others a custom mechanism) we wanted to rely on users to do the migration as opposed to a huge migration from IT. This also allowed IT to debug the user database. The following figure shows how the consolidation of identity would happen through time. It will work as fast as users will do its first login and create the mapping with the new repository. This works well when you have lots of apps using a database as the user repository.

image

Note: this is not based on real data, it tries to give you an idea of how it works over time (credits to Johnny Halife).

We did a demo on how this works and people were interested in this approach because it is not disruptive.

I posted the presentation in Spanish and you can download it from here

Some useful resources

Identity Development Training Kit: http://snipurl.com/identitytk
“Geneva” Download: http://snipurl.com/genevadownload
Channel9 Identity: http://channel9.msdn.com/identity/
Blog Vittorio Bertocci: http://snipurl.com/vibro

Problem
 
UAB does not resume
broken downloads (due to connection failure or user cancelling the
download).
 
Solution
 
These are the two
changes to do in the BitsDownloader class
 
1. On the
OnJobError method we need to NOT cancel the BITS job if the state is
ERROR:
 
if( state !=
BG_JOB_STATE.BG_JOB_STATE_ACKNOWLEDGED &&
     state !=
BG_JOB_STATE.BG_JOB_STATE_CANCELLED &&
     state !=
BG_JOB_STATE.BG_JOB_STATE_TRANSFERRING &&      // don’t interrupt
downloads in progress
     state != BG_JOB_STATE.BG_JOB_STATE_TRANSFERRED
&&      // don’t cancel a finished download
     state !=
BG_JOB_STATE.BG_JOB_STATE_TRANSIENT_ERROR &&   // don’t cancel when
connection problems
     state != BG_JOB_STATE.BG_JOB_STATE_ERROR )
{            // don’t cancel when connection problems
    
pJob.Cancel();
 }
 
2. On the
CheckForResumeAndProceed method check to see if the job is in ERROR or
TRANSIENT_ERROR state and resume it. Why add this here? Because this method
checks if there is a pending job. If there is a pending job and its state is
ERROR, that means that the pending job failed due to a network failuire, or user
aborted the application. If we call Resume BITS try to connect again.
It will try to connect for 5 secs (NoProgressTimeout constant). If it couldn’t
do it, the job will stay in ERROR state. If not, it will transfer from the last
byte transferred.
The code in bold
letter need to be added
 
if (
jobState == BG_JOB_STATE.BG_JOB_STATE_TRANSFERRED )
{
      
OnJobTransferred( task, copyJob );
       return true;
}
if (
jobState == BG_JOB_STATE.BG_JOB_STATE_ERROR || jobState ==
BG_JOB_STATE.BG_JOB_STATE_TRANSIENT_ERROR ) {
      
copyJob.Resume();
}
 
Observations
  • This new code was
    tested in this scenarios: stopping the website; disabling the network card and
    aborting the application in the middle of the job, and it worked on all the
    scenarios. The job was resumed from the last byte transfered
  •  It’s important to
    attach to the PendingUpdatesDetected event of the
    ApplicationUpdaterManager. On the handler of this event call
    ResumePendingUpdates. This is important because this method
    deserializes the tasks that holds the BITS Job ID previously
    aborted.
  • It is not recommended
    to debug the WaitForDownload method due to concurrency and sync issues.
    Instead, tracing is recommended. A simple tracing could be implemented to
    troubleshoot, just by using the Logger.LogInformation method that will
    write to the Event Viewer.

I’ve been experimenting with EntLib Logging App Block. I wanted to do the async logging via MSMQ.

Async logging is one of the requirements of Enterprise Applications that does not want to waste cpu cycles logging on the Event Viewer or raising a WMI event or whatever logging strategy they use. Instead, a better approach is write the log message to a MSMQ and then have a service polling that queue that will do whatever with this log.

This way we could have our logging in a separate machine and the applications just write to a queue (which in turns much more fast compared to other things). Indeed we could write to a queue on the same machine. Here we could be more performant because the logging runs in a separate process (with a Windows Service, a Console app or whatever that polls the queue and get the log message).

Enterprise Library takes care of all this for us and we could have async logging setup in a matter of minutes.

I will show here what I did to get it running.

Client Application

First, we need to create the Logging Application Block for our application. Right Click on App -> New -> Logging and Instrumentation Application Block.

ent1

Then we need to remove some stuff that the client application won’t use. The logging will be done by a separate service, no by the client application inprocess. We won’t need the Distributor Settings and we don’t need the InProcess distribution strategy. So right click on Distributor Settings -> Remove. And Right click on InProcess -> Remove.

ent2

Now, we need to add the MSMQ distribution strategy. Right click on Distribution Strategies -> New -> MSMQ. The MSMQ distribution strategy has a queue associated where the LogEntries will be throw. Click on MSMQ and modify the QueuePath to some message queue you want (remember to create the queue before using it!)

ent3

Click on Client Settings and choose MSMQ on the DistributionStrategy property.

ent4

MSMQ Distributor Service

EntLib provides a Windows Service (MsmqDistributor) that will poll the message queue within a configured interval and do the real logging. This service is not installed by default, nor via InstallServices batch. So we need to install it by ourselves.

Open a vs.net 2003 command prompt and do a

cd [EntLibInstallDir]\bin\

Then run the installutil

installutil MsmqDistributor.exe

ent5

Now we need to configure the Logging block in the service. Think now that the service config file is like your client application. Remember that the async logging has two process running: the client application itself (winforms, web, whatever) and the service distributor (the service that will do the real logging).

You will need to copy two files required by the MsmqDistributor config otherwise there will be a validation error (it seems like the PAG guys forgot to include them in the bin directory). So copy these two files

[EntLibInstallDir]\src\Logging\MSMQDistributor\loggingConfiguration.config to [EntLibInstallDir]\bin
[EntLibInstallDir]\src\Logging\MSMQDistributor\loggingDistributorConfiguration.config to [EntLibInstallDir]\bin

Now, open the [EntLibInstallDir]\bin\MsmqDistributor.exe.config with the EntLib console (you can use the same console that you were using for the client app, but if you are using separate machines obviously not :)

ent6

(it seems they forgot to change a path there [C:\Depots\Microsoft\ELF2\QuickStarts\Logging\CS\LoggingQuickStart\App.config] ;)
Let’s configure the last thing! Right click on the Distributor Settings of the MsmqDistributor config file -> New -> MSMQ Distributor Service. This is the configuration that will tells the Windows Service which is the queue path where the logentries are being saved.
You should set the QueuePath in the property grid to the same queue configured in the client app (if you want it to work of course ;)

ent7

Finally, you can configure whatever you want regards Formatters, Sinks and Categories here. Remember to do it on the service and not the client!

Save All, start the service, start your application and enjoy Distributed Async Logging!