Agile

Auditing with Castle Active Record

Sometimes you need to audit everything you do in a transactional system. A lot of standards such as SOX and others state that you must audit your transactions. Doing this by hand inside of your system can (and usually is) a huge PITA. However, it is a necessary evil in some instances.

However, if you’re using Castle’s Active Record (AR) for your database access, then hopefully this post will save you some trouble.

Active Record provides us with the ability to provide interceptors which “intercept” the execution of some of the Active Record calls. I’m using the ActiveRecordMediator<T> class for all of my CRUD operations and in order to implement some sort of auditing I need to be able to intercept all of my Save, Updates and deletes. Here’s the class that does this:

 

The Interceptor

 

using System;
using System.Collections.Generic;
using Castle.ActiveRecord.Framework.Internal;
using NHibernate;
using NHibernate.Type;

namespace Felker.AR.Audit
{
    public class AuditInterceptor : EmptyInterceptor
    {
        private static AuditInterceptor instance = new AuditInterceptor();

        protected AuditInterceptor() {  }

        public static AuditInterceptor Instance
        {
            get { return instance; }
            set { instance = value; }
        }

        public override bool OnFlushDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, IType[] types)
        {
            // Object was updated. Save the current state, previous state, etc.
            return false;
        }

        public override void OnDelete(object entity, object id, object[] state, string[] propertyNames, IType[] types)
        {
            // Object was deleted.
        }

        public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, IType[] types)
        {
            // Object was created. "state" is the state of the object.
            return false;
        }
    }
}

The class above implements a default “EmptyInterceptor”. This allows you to override the methods you need in your interceptor. I have overridden the “OnSave”, “OnDelete”, and “OnFlushDirty” methods. When the interceptor is in place, when a Save, Delete or Update call is made with the ActiveRecordMediator<T> the respective overrides will get called.

It is inside of the “OnSave”, “OnDelete”, and “OnFlushDirty” that I can perform my auditing as I am provided with the object state during the save, delete or update. I have not provided any sort of mechanism in the code to actually audit the info to a database or a file as this is up to you to decide “where” it should go. This is only the boiler plate that you can use to intercept the save calls. You have all the data you need. The current entity, the current state (and previous state if it is an update) and the type information.

 

Why Works So Well

The beauty in this implementation is that I _did_not_ have to change _any_ of my pre-exising ActiveRecordMediator<T> code. I had a TON of models that used a common repository and I did not have to tough them. I just had to add the interceptor to the container (Windsor Container) at app startup and ActiveRecord picked up the interceptor and started firing it.

 

Wiring up the Interceptor with a Facility

 

using Castle.ActiveRecord.Framework;
using Castle.Core.Configuration;
using Castle.MicroKernel;
using NHibernate;

namespace Felker.Castle.Facilities
{
    /// 
    /// Allows for the system to pick up the audit facility which will be used to
    /// audit all transactions in the system.
    /// 
    public class AuditFacility : IFacility
    {
        #region IFacility Members

        public void Init(IKernel kernel, IConfiguration facilityConfig)
        {
            InterceptorFactory.Create = new InterceptorFactory.CreateInterceptor(CreateAuditInterceptor);
        }

        public void Terminate()
        {
            // Nothing to terminate
        }

        #endregion

        private IInterceptor CreateAuditInterceptor()
        {
            return AuditInterceptor.Instance;
        }
    }
}

 

The class above creates a Facility for Active Record. We wire this up in the Global.asax.cs file like so:

 

static private IWindsorContainer _container;

protected void Application_Start(object sender, EventArgs e)
{
	try
	{
		_container = new WindsorContainer(Server.MapPath("~/config/windsor.config"));
		var app = _container.Resolve();
		app.RegisterFacilities(_container);
		app.RegisterComponents(_container);
	}
}

 

In the Application.cs file we add the facility as such:

 

public void RegisterFacilities(IWindsorContainer container)
{
	container.AddFacility("audit.support", new AuditFacility());
}

The code above wires up the facility into the container which will handle all of our type registration/etc for us.

 

Conclusion

The container now contains the facility which will wire up the audit interceptor which will intercept all ActiveRecordMediator<T> calls.

We have not changed a line of code in our existing system, yet we have added the ability to audit all of our CRUD operations in a simple yet effective manner.

Finding App_Data Programmatically

While writing some code I needed to be able to access the the App_Data directory in my ASPNET MVC app. Doing this usually involves a Server.MapPath, but this wont work for my unit test.

Here’s how you can get around it:

 

var appDataPath = (string)AppDomain.CurrentDomain.GetData("DataDirectory") ?? AppDomain.CurrentDomain.SetupInformation.ApplicationBase;

 

Now I have my data directory for the test as well as during execution of the ASPNET MVC app.

During unit test execution it will be in testing directory while at runtime it will be in the ASPNET App_Data directory.

Featured in the Spaghetti Code Podcast

I was recently interviewed on the Spaghetti Code Podcast, hosted by Microsoft’s Jeff Brand.

Jeff and I talked about Mocking and how it relates to the development process, testing process and your day to day coding.

You can download the files from the SlickThought website here or from ITunes here.

* I’m not sure if ITunes has updated yet, but it should be up there soon.

My ReSharper Templates

Recently when working with some co-workers I was flying through some menus and whipping out some code at a breakneck speed and a couple asked how I was doing it so quickly. Simple – Resharper’s live templates. I’m surprised I haven’t posted these before, but for whatever reason here they are. The NUnit templates are based off of Bellware’s NUnit snippet library, but I’ve also added some of my own as well as some common Rhino Mocks templates as well.

Without any further-ado, here they are. (Download the files at the bottom of this post).

The snippets contain the following goodies:

Live Templates

Shortcut Description
Misc Items  
nie throw new NotImplementedException();
   
Rhino Mocks Items  
mock MockRepository.GenerateMock<T>();
stub MockRepository.GenerateStub<T>();
mockery MockRepository mockery = new MockRepository();
urm using Rhino.Mocks;
   
NUnit Items  
a Assert.<Assertion>
ae Assert.AreEqual(<expected>, <actual>);
ai Assert.IsInstanceOfType(typeof(<Type>), <actual>);
aif Assert.IsFalse(<condition>);
ain Assert.IsNull(<object>);
ait Assert.IsTrue(<condition>);
ann Assert.IsNotNull(<object>);
as Assert.AreSame(<expected>, <actual>);
at Assert.That(<actual>, Is.<ConstraintAndCondition>);
eea [ExpectedException(typeof(<Type>))]
ig [Ignore(<reason>)]
sac StringAssert.Contains(<expected>,<actual>);
setup Creates a setup method for NUnit decorated with a setup attribute
sua [SetUp]
ta [Test]
tc Creates a test method in which you can define a name for the test. Decorated with the Test attribute.
td Creates a tear down method decorated with the TearDown attribute
tda [TearDown]
tfa [TestFixture]
tfp Creates the beginning of a TestFixture by adding the attribute and marking the class as public.
tfsu Creates a TestFixtureSetUp method that is decorated with the TestFixtureSetup attribute
tftd Creates a TestFixtureTearDown method that is decorated with the TestFixtureTearDown attribute
tftda [TestFixtureTearDown]
unuf using NUnit.Framework;

File Templates:

Template Description
NUnit Test Class Creates a boiler plate template that uses the default namespace of the project and the file name defaults to whatever you provide in the ReSharper file name dialog. The file name is a .cs file extension.
SparkView Essentially a blank file that is open for you to create a view from the Spark View Engine. The file extension is .spark
CssStyleSheet Similar to the SparkView template except that the extension is .css. The file is empty by default.

Download

DonnFelker_LiveTemplates.xml

DonnFelker_FileTemplates.xml

Is Premature Optimization Really Evil?

dominos
Photo Courtesy of: rosendahl

My first initial answer is … it depends. (Isn’t that the case for everything?) :)

Today I had conversation with a colleague and we were discussing how application developers don’t plan ahead.

This eventually brought up the question/topic:

“Is premature optimization pure evil?”

My colleague stated that all optimization should be done up front, while I on the other hand, disagree. In my opinion all development should be done first and then lets figure out where we might have some problems, with some exceptions (which we both agreed upon).

So, what did we agree upon?

Lets look at a classic example:

Developer Joe and his team were asked to create an order management system that could handle up to 10,000 orders a day. This doesn’t sound like that big of an issue, and Joe and his team also agreed. It shouldn’t be a big issue. A fast database, a fast web server, and a few third party controls to interact with. No problem! Heck, this is pretty straightforward they thought. In reality, the requirements were very straight forward, no hidden features, no scope creep, nothing like that. Heck, it was a dream project come true. With that said – development ensued, and two months later Joe’s team delivered the product and everyone was excited to see the product run from end to end. (By the way, this was not done TDD or with any Agile Methods – which IMO would have caught any of our upcoming issues, if the tests were written correctly. But then again “If ‘if’ was a fifth then we’d all be drunk”).

Joe’s team fired up the application for a demo and ran some orders through it and it worked great. They even ran 10 orders through the system in one minute (~14,400 Orders a day). They had gone above and beyond the call of duty (original requirement being 10,000 orders a day)! They were due for a raise! Life couldn’t be better! The system was released and the company started to use it. Orders were flowing through the system without failure and the business was happy.

Until the company decided to sell an exclusive hot item two weeks later …

Then SHTF… All of a sudden, customers were experiencing time outs,  orders were being duplicated, and the customer service line was being rung off the hook. Essentially, all hell broke loose. After looking into the system, the developers noticed that the system had only accepted 6,000 orders. What gives? This system should handle 14,400 according to their tests. *everyone is scratching their head at this point*

Scalability is Relative

Scalability in this case, is relative. While looking at the stats, Joe’s team realized that those 6000 orders came in in about 1.5 hours. This was the first 1.5 hours that this product was available. At the end of the day the company eventually sold under 10,000 units, so why did this issue happen?

Lets take a look at some stats:

  Orders Per Minute Time Between Orders (seconds)
Original Spec (10,000 Per day) ~7 8.64
Current State (6000 in 90 Minutes) ~67 0.9

Orders Per Minute Equation: Orders / Minutes          Minutes: (HoursInDay * MinutesInHour)

Orders Per Second Equation: Seconds / Orders       Seconds: (HoursInDay * MinutesInHour * SecondsInMinute)

 

Do we see the problem here?

Again, scalability is relative. In this case, analysis and optimization was not done ahead of the time to anticipate the flood of orders at a peak period. The spec was straight forward:  The system is to be designed to handle an order rate of 10,000 orders a day. The system was designed exactly to the spec, and in this case, the system was designed incorrectly.

Now, I have a confession… 6 years ago, I was Joe. Yes, I made this very mistake. I was a hero for a couple of weeks, then SHTF. :) Live and learn. Live and learn.

When We Agreed

My colleague and I both agreed that in certain instances premature optimization should be done, such as this case. The developers should optimize the order process to handle issues at peak times. Perhaps implementing a order service, based on MQ, or implementing a service bus for this type of high-availability process would be the best. In this case, we agree. All of this analysis and optimization should be done up front because this type of thing WILL be a problem at any peak utilization times. We both agree that neglecting to analyze the problem domain can and will lead to performance problems down the road. Plain and simple.

When We Disagreed

My colleague and I still disagree on the statement of “all code should be optimized up front”. In my opinion this is a BDUF approach that I tend to shy away from. I don’t necessary mean that no design should happen up front, but I do think it should be limited. In an agile environment things tend to change, and we need to be able to adapt quickly. Wasting months in front of a whiteboard, with of reams of documentation, and endless meetings only slows the process down if something has to change down the road. Re-updating project baselines, and adjusting documentation and so forth is a huge hassle. I would like to state that there is a place for this type of development though. Some companies do require BDUF approaches because of huge regulatory compliance issues, so sometimes there is not much you can do about it. However process driven approaches such as ITIL and Agile can work together if done properly. With that said, I tend to shy away from BDUF approaches because of a simple example that is also exemplified by Jeff Atwood in a previous post of his (and I agree with him and the many other experts in the field). Jeff adds a third rule to M.A. Jacksons Optimization Rules that I like agree with the most:

And I would add a third: don’t optimize work that doesn’t have to be done.  – Jeff Atwood

This can be demonstrated as a sort routine. Lets say you have a menu that will be populated via user selections and the maximum number of values you can have in the menu is 100. You can either implement IComparable and utilize the List<T>.Sort() method to sort the class (which utilizes the Quicksort Algorithm) which would be SUPER easy but may not be the “Fastest” method of sorting, or you could write an extension method to create your own sort routine to sort the 100 items. At this point we’re splitting hairs. A millisecond, or even 10 milliseconds, wont matter at this point in UI response. We’re only sorting a menu that will never grow beyond 100 items. At this point, pre-mature optimization is evil. There is NO need to rewrite something that that does the job well enough. Can we do it better? Yes! Is there a need to? NO. We wont get any value out of it. The time spend on development is wasted compared to the benefit to the application.

On the other hand, if the menu had no upper bound limit, then we would want to implement the best sort routine we could because some routines are exponentially faster than others. In this case we would want to optimize early because the possibility of a bottleneck can and might occur in certain situations.

It all boils down to: “It Depends”

At the end of the day, the true answer to “Is Premature optimization evil?” is “It Depends”.

It depends on the problem. It depends on the architecture and design. It depends on analysis of the domain. It depends on the factors which “could” come into play.

Finally, what it really boils down to is: It depends on MONEY. We can optimize all day and gobs of the companies money in development/optimization costs. This is why deep analysis into the problems need to take place. As architects we need to define the business process that could impact our architecture design and implementation and development of code. At some point we need the business to interject into this analysis and optimization party to say “Listen, I’m willing to deal with X, but I’m not willing to deal with Y”. At that point, our jobs as Architects is to define how much X costs compared to how much Y costs. Only then will the business truly know what should be done juxtaposed with what should not be done.

To sum it up in my own personal opinion, premature optimization can be evil. We, as architects and developers need to think about the problem at hand before we write a line of code. As I stated above, there is no need for a full 90 page document on the process, but at least whiteboard with your colleagues. Are you a solo developer and need someone to bounce ideas off of? Join your local user group, join some groups online, visit the MSDN architecture forum and ask questions.