Friday, February 26, 2010

Audit Trail System




Introduction
There are multiple reasons to have an Audit trail System in your application. Some companies have to do it because of their rigid / un-professional enviroment, such as JGC-DESCON ENGINEERING PVT. LTD. But on the other end it is very useful for debugging purpose. It shows you what was in your database at any point in time.
In this article I will explain the method I prefer for implementing an audit trail. Next, I will introduce a script to automate the implementation of the audit trail in the database.
Audit Trail With Triggers
So how to implement an audit trail? Different visions exist. The one I prefer is to use a shadow table for each table that exists in the database. Every time a record is inserted, updated or deleted in a table, the record is also inserted in the corresponding shadow table. For inserting the record in the shadow table too, I use triggers on the original table that will fire whenever something happens.
Let's make this clear with a small example.

On the left side, you see the structure of a table called Employee containing five columns. I refer to this table as the base table. On the right, you see the shadow table for this table. The shadow table contains all columns from the Employee table, plus some extra columns:
  • AuditId: This the primary key of the shadow table. It is an identity field.
  • AuditAction: This is a one letter code to indicate the kind of operation. Values are I, U or D, for insert, update and delete respectively.
  • AuditDate: The date and time when the action occurred. The default value is set to getdate(), an SQL function that returns the current date and time.
  • AuditUser: The user who performed the action. The default value is set to suser_sname(), an SQL function that returns the user name of the user currently connected.
  • AuditApp: The application that was used. The default value is set to (('App=('+rtrim(isnull(app_name(),'')))+') '). This allows you to tell which application was used to modify the data, e.g. App=(Microsoft SQL Server Management Studio Express).
To fill up the shadow table, I define triggers on the Employee table. We need three triggers: one for inserts, one for updates, and one for deletes. The code for the insert action is shown below. Those for updates and deletes are similar.

CREATE TRIGGER tr_Employee_Insert ON dbo.Employee
FOR INSERT AS
INSERT INTO Employee_shadow(ID, FNAME, LNAME, PHONE, EMAIL,AuditAction) SELECT ID, FNAME, LNAME, PHONE, EMAIL,'I' FROM employee
The columns that are filled up by the trigger are only the data columns from the base table (ID, FNAME, LNAME, PHONE, EMAIL,AuditAction) and the AuditAction column. All other columns in the shadow table (AuditId, AuditDate, AuditUser and AuditApp) are filled up by their default value definition.
So what are the strengths and weaknesses of this approach? Let's start with the strengths:
  • It completely separates the current data from the audit trail. The old values are no longer in the base table but in the shadow table. There are no soft deletes, where deleted records are flagged as being deleted instead of being actually deleted.
  • It can easily be implemented on existing databases. If originally you did not foresee audit trailing, you can add it afterwards. The only thing you need to do is add the triggers on the base tables and create the shadow table. No changes have to be made to stored procedures or applications working with your database.
  • It always triggers. E.g. if you connect to your database through Enterprise Manager and you modify the data by hand, the triggers fire and the shadow table is updated accordingly.
The method also has some drawbacks:
  • The entire record is copied to the shadow table, including the columns that were not changed. In our example, if you change the firstname of a user in the base table, the lastname is also copied to the shadow table although it did not change. Hence, the shadow table will take up more space than strictly needed.
  • A trigger cannot be used on all column data types. Text, Ntext, and Image are not supported. The reason is that they are not stored in the record itself. The record only holds a pointer to the data. In SQL 2005, the timestamp is not supported either.
  • The number of tables doubles, although I personally don't find this an objection.
  • The audit trail is on a table level instead of on an action level. If during a single save operation in your application multiple tables in your database get updated, there is no link between the different transactions that took place on the different tables. The only thing that links them together is that they occurred at (almost) the same moment and by the same user.
The Audit Trail Generator Script
If you have 50 tables in your database, adding an audit trail using the method just described means adding another 50 tables and creating 150 triggers. This is why I have created the audit trail generator. It saves time and avoids typo errors. See the link on top of this article to download the code.
The audit trail generator is written as a stored procedure. Hence, you don't need any other tools.
The stored procedure takes four arguments:
  • @TableName: The name of the table to which you want to add an audit trail, e.g. users
  • @Owner: The owner of the table. The default value is dbo
  • @AuditNameExtention: The extension you want for the shadow table name. E.g., if you set it to _shadow, the audit table for users will be calledusers_shadow. The default value is _shadow
  • @DropAuditTable: A bit to specify if the shadow table can be dropped. If 1, the existing audit table will be dropped and recreated. Of course, you lose all data in there. This is especially useful when you are still in development, but you may want to do this on a production system. The default value is 0.
The stored procedure will discover the columns in the original table by querying the system tables of SQL Server. These system tables are used by SQL Server itself to store the structure of the tables. The query to get all info about the table is shown below.

SELECT b.name, c.name as TypeName, b.length,b.isnullable, b.collation, b.xprec, b.xscale
FROM sysobjects a
inner join syscolumns b on a.id = b.id
inner join systypes c on b.xtype = c.xtype and c.name <> 'sysname'
WHERE a.id = object_id(N'Employee')
and OBJECTPROPERTY(a.id, N'IsUserTable') = 1                            ORDER BY b.colId

The image below shows the results if we launch this query for our Employee table.

The remainder of the stored procedure loops over the result of this query using a cursor, and dynamically builds up the SQL statements in a string to create the shadow table and to add the triggers to the original table. These statements are then executed with the EXEC command. I will not go into the details of it, since it is straight forward.

Using the Script
The script is a stored procedure, so using it means calling the stored procedure. In its simplest form, you only need to set the @TableName parameter because for all other parameters, default values have been specified. The following statement can be launched from a query window.
EXECUTE GenerateAudittrail 'Users'
The following example shows what it looks like if all parameter values are specified.                     
EXECUTE GenerateAudittrail 'Users', 'dbo','_shadow', 0                                        
The script is very handy to quickly create a shadow table for a given database table. However, it was not designed to modify a shadow table to reflect changes to the corresponding base table. In this case, it can only drop the shadow table, losing all records in it, and recreate it. Set the @DropAuditTable to 1 to force dropping and recreating the shadow table.

Sunday, February 7, 2010

Biztalk Server 2006 compatibility with Visual Studio 2008 (VS2008)

This is for all you guys who are trying to figure out whether Biztalk 2006 works with VS2008.

I had this requirement in my project that we all migrate to .NET 3.5 environment / VS2008. Everything looked fine untill we realized that Biztalk 2006 is not supported by VS2008. I did a lot of reaseach in blogs and talking to Microsoft Support. The anwer is found was that "Biztalk Server 2006 will not work with VS2008". In fact Biztalk is not compatible with any of the 2008 technologies including SQL Server 2008.

I spoke to MS Tech. Support and they confirmed that there is no compatibility. It is expected that future versions of Biztalk (R3) will possibly support VS2008. They have no idea when it would be release, but the hint is that the CTP version might hit by the end of the year.

I also tried out practically on my machine. I installed VS2008 on existing Biztalk setup, but VS2008 doesn't recognize ".BTPROJ". I even tried to install VS2008 first and then Biztalk, still the same issue.

Its really so bad on Microsoft that Biztalk being such a advanced technology will not be a part of .NET Framework 3.5 environment for so long :(.

Here is the response I got from Microsoft.

--------------------------------------------------------------------------------------
Thank you for contacting Microsoft Sales Information today.

Per our discussion, I've attached links/information that you requested below.

From my research I have found that BizTalk Server 06 and Visual Studios 08 actually are not compatible. The .NET framework used by Visual Studios 08 to create applications is not compatible with the requirements of BizTalk Server 06; Microsoft may be releasing a Service Pack for BizTalk Server or a new BizTalk Server which will address this compatibility issue.
This blog on this Microsoft web site will outline more in-depth what I have just stated here.

http://blogs.msdn.com/stevemar/archive/2008/04/23/biztalk-server-platform-updates.aspx

Thursday, January 21, 2010

Writting My Own WebServer



Still Working on it.... will post all the data shortly ........

Monday, January 11, 2010

Interface Vs Abstract Class

Feature
Interface
Abstract class
Multiple inheritance
A class may inherit several interfaces.
A class may inherit only one abstract class.
Default implementation
An interface cannot provide any code, just the signature.
An abstract class can provide complete, default code and/or just the details that have to be overridden.
Access Modfiers
An interface cannot have access modifiers for the subs, functions, properties etc everything is assumed as public
An abstract class can contain access modifiers for the subs, functions, properties
Core VS Peripheral
Interfaces are used to define the peripheral abilities of a class. In other words both Human and Vehicle can inherit from a IMovable interface.
An abstract class defines the core identity of a class and there it is used for objects of the same type.
Homogeneity
If various implementations only share method signatures then it is better to use Interfaces.
If various implementations are of the same kind and use common behaviour or status then abstract class is better to use.
Speed
Requires more time to find the actual method in the corresponding classes.
Fast
Adding functionality (Versioning)
If we add a new method to an Interface then we have to track down all the implementations of the interface and define implementation for the new method.
If we add a new method to an abstract class then we have the option of providing default implementation and therefore all the existing code might work properly.
Fields and Constants
No fields can be defined in interfaces
An abstract class can have fields and constrants defined

Wednesday, November 4, 2009

BizTalk Architecture

Introduction


I have heard they ask "How would you explain Excel (any product) to your grandmother?" in many companies; a question popularized by Microsoft, I believe. First, I am not so sure my grandma would understand any technology product so easily. Also, I am not sure if this is a good question to ask a software developer; maybe, to someone from sales, yes! On the record, I must say that my grandmother is an incredibly smart lady. So the question really boils down to "How you would make an IT common man understand what a product is all about?" This is what I am trying to endeavor in this article.
Sometime back, I had to explain to a group of non-IT folks about BizTalk Server. You know the people who wouldn't understand all these geeky terms like SOA, XML, SOAP, or Orchestrations (pardon me, she says she knows about SOAP!). I thought I'd share my experience here in this article for the benefit of the CodeProject community. This article is aimed at you if you have heard about this wonderful thing called BizTalk Server, and want to understand what it is clearly before diving into the marketing material which seems to be the same for every product - the "panacea" of all your problems.

Drawing a Parallel

BizTalk Server is Microsoft's enterprise application integration solution, with built-in support for XML and SOAP. It offers integration with Visual Studio .NET, and provides speed, reliability, and flexibility for standards-based enterprise application integration. An analogy they say is "Similarity in some respects between things that are otherwise dissimilar". So for me, to explain BizTalk, I would start off with an analogy. In the section below, I am comparing BizTalk Server to a Customs facility.

The Customs Facility




What we have in the figure above is a Customs facility. We have an Import Terminal through which a large number of packages come in by different modes of transport: planes, ships, buses, trucks, barges. These packages then go through a standard inspection process, with several stages including identifying the package, unpacking the contents, and then identifying the shipper. The packages then go to a central store. From there, customs inspection of the packages takes place. The process could be different for different types of packages, and there is a "Customs Inspection Rules and Regulations Manual" which details the inspection process, and which in practice, gets updated from time to time. After a package passes the inspection process, it is sent back to the central store, from where it is packaged and sent to the correct destination.

The BizTalk Server Architecture





The figure above is the architecture of a BizTalk Server messaging subsystem. As you will notice, this figure is same as the previous figure except for the labeling. Here, instead of packages moving, we have XML messages that are moving. The files come in through Receive Ports and are passed to the "Message Box" through a "Receive Pipeline". They are then picked up by "BizTalk Orchestrations" and are processed. Custom rules maybe loaded and executed at this point. They are then send out using a Receive Pipeline through a "Send Port" to the destination.

Receive Ports

The Receive Ports are how messages come into BizTalk. Messages can come into BizTalk by any means of transport like HTTP, SOAP, SQL, file, EDI; just like the way packages arrive via planes, ships, buses, or trucks. How they are transported does not change how they are processed later. This is a very powerful feature because it gives you the ability to change the transport type and the source of the data even after your application is deployed, without changing your application implementation. For instance, let us say some sales related data is coming in from a shared "FILE" folder in Europe connected via WAN today, tomorrow you can configure it as an FTP pickup from a remote server from India, or probably accept it as an HTTP request over the web posted from a browser.

Adaptors

Adaptors are the BizTalk way of handling additional transport. Just like you can have a private plane fly your package in, you can write your own adaptor for a custom transport, like say POP3. So there is always scope for buying or writing your own custom adaptor to integrate with all the other available transports. For instance, you can have a DB2 adaptor or a SAP adaptor.

Receive Pipeline

The Receive Pipeline contains different mechanisms like "Decoding" (if encoded), "Disassembling" (if there are multiple parts), and "Party Resolution". This is similar to the unpacking and identifying the sender, in our example. Just like we have an express lane for certain packages, there is a "Pass Through" pipeline facility in BizTalk which is essential a smooth transfer to the Message Box. Just like you can have special handling instructions for certain packages, you can write custom pipeline components using the framework.

Message Box and Subscriptions

The BizTalk Message Box lies in the heart of the BizTalk messaging subsystem; this is like our central store. This message box is, in fact, realized as a SQL Store; so this way, BizTalk ensures reliability for your messages in terms of guaranteed delivery. Even if a node in BizTalk fails, the message will be picked up by another node in the farm. BizTalk also ensures that it does not delete the file from a pickup folder location while using file/any transport, unless it is persisted completely in SQL. Well, this also means you need to have a fault tolerant SQL Server architecture. Just like we will be noting down a few important details while we unpack the packages, in the pipeline, certain properties are promoted into the context, like transport information: the most important of these being the incoming XMLSchema#RootNode. The BizTalk Publish-Subscribe mechanism identifies which Orchestrations subscribe to that particular message, based on this promoted information, and routes it accordingly.

Orchestrations

Orchestrations are processes that are defined in the Business Process Execution Language (BPEL). This could be something like, say: if quantity is greater than threshold, apply discount, else standard discount. At this stage, you can also change the format of the message using Transformation Maps, or you can call some other web service to do an operation like credit card verification. This is like our example in which we have the customs inspection process and checking with the bank if the excise payment is cleared.

Business Rules Engine

Business Rules Engine is used by BizTalk to load the current policies which are a collection of Rules from the Orchestration. These rules are kept separately as these could change from time to time. In our example above, this would be something like, during Olympics there could be certain relaxations in guidelines or certain promotions in effect. These change from time to time, and they are kept separate. This is the idea behind the Rule Store in BizTalk.

Send Pipeline

The "Send Pipelines" are just the opposite of the "Receive Pipelines" and they do operations like "Encoding" the message, or "Assembling" or "Signing" the message. This is like packing and sealing a package before we send it. Just like we have different types of packaging like bubble wrapping and cushion mailers, there could be different pipeline components at this stage.

Send Ports

Send Ports also handle transport like receive ports, but their direction is the reverse. Here, the message direction is from the Message Box to the destination. Send Ports can subscribe to a message directly from the Message Box, without passing through the orchestration. This is like having a package coming in from a certain shipper which has a prior clearance attached with it. This is called Content Based Routing (CBR).