Tuesday, August 20, 2013

In this post I will provide a discussion on how to apply auditing configurations to your XAF applications, I will use the build-in XAF Audit Trail module and the eXpand Logic module for extending the XAF Application Model.

Goal

Our goal is to be able to declaratively configure auditing for different scenarios. For example apply an auditing configuration to a group of objects that fit in a criterion on a predefined group of views only when these views are shown in the main window.

Background -The logic module

The logic module provides the API we will use to extend the Application Model. In eXpand there are a few modules which use this API. For example three of them live in the ModeArtifactState module. In the next image we can see the structure of two of them the ConditionalAction and the ConditionalController.

Bellow there is the third child of the ModelArtifactState module ObjectView structure. I want to draw your attention to the common attributes we see in both images. All they come from the Logic Module which has the engine to evaluate them. Moreover the Logic module allows us to define permissions and class attributes using the same common attributes.

Using the Logic module is quite easy and the benefits too many. We will go through all the steps for creating an new AuditTrail module. Make a note that we discuss a workflow that can be applied to almost any scenario.

1) The startup interface

First off we need an interface that will be the AuditTrail Rule needed from the Logic Module. Let’s go to XAF Audit Trail documentation to read what we can use to design that interface. In order to attach to the Logic Module this interface needs to derive from ILogicRule interface. Bellow we see the IAuditTrailRule interface with one property the which we can use later to configure the AuditMode from the model or by using Role permissions.

The IContextAuditTrailRule provides information about contexts such as Execution, Action, View, Frame. In the top most images of this post you see that our model already has this information. However I mentioned before that the Logic Module supports permissions and class attributes. So the IContextAuditTrailRule will be implemented by the AuditTrailAttribute, and the permission classes which they need to know about context but not about model.

The Logic module will extend the Application Model with the IModelAuditTrailRule and will give a structure similar to the one you saw in the top most images of this post. The IModelConditionalLogicRule comes from the Logic module so we only need to use here.

In addition to IModelAuditTrailRule interface we need to feed the Logic module with a list of IModelAuditTrailRules, so let’s design them.

All rules from all sources (model, attributes, permissions) ultimately are converted to LogicRule object instances. The LogicRule abstract class lives in the Logic module. So, we need to design a concrete LogicRule class for the Audit Trail module like the one bellow.

publicclassAuditTrailRule:LogicRule,IAuditTrailRule {

publicAuditTrailRule(IContextAuditTrailRule auditTrailRule)

: base(auditTrailRule) {

AuditingMode=auditTrailRule.AuditingMode;

}

publicObjectAuditingMode? AuditingMode { get; set; }

The AuditTrailRule class must also implement the common IAuditTrailRule interface as the rest of the classes. Note that we also have to initialize any Audit Trail specific properties in the constrictor.

5) The class attribute (Optional)

Below is the AuditTrailRuleAttribute which must derive from the LogicRuleAttribute. The LogicRuleAttribute comes from the Logic module so we do not need to implement anything.

The design of the permission classes is equally simple. For example the permission must derive from LogicRulePermission and implement the IContextRule interface. Here the same as step 4 there is an extra step we need to initialize the properties in the ctor as you see below.

There I used an ExecutionContext.ViewChanging as my default context. You free to use any context its appropriate for your task. The logic engine will evaluate the IAuditTrailLogicRule only when ViewChaning.

LogicRulesNodeUpdater:

If you implement the optional AuditTrailLogicRuleAttribute you need to pass its model updater at this point.

GetModelLogicCore:

There we need to return a ModelLogicWrapper class with the IModelAuditTrailRules and the rest of the context. It is possible to share rules and contexts from any model path using a different contructor overload. For example we may design the IModelLogicAuditTrail interface like below.

publicinterfaceIModelLogicAuditTrail : IModelNode {

IModelAuditTrailLogicRulesRules { get; }

IModelExecutionContextsGroupExecutionContextsGroup { get; }

}

So now the IModelLogicAuditTrail knows only about ExecutionContexts (no FrameTemplateContext, no Actions, no Views). For this configuration the appropriate ModelLogicWrapper instantiation is shown below.

The Audit Trail structure is ready! Bellow we see the model for an AuditTrailRule similar to the one of the top most images of this post.

The Logic module knows what to do with all the attributes except the AuditingMode. Next we discuss how to write logic for this attribute.

The Audit Trail Logic

To write logic for the AuditTrailRule, we have to subscribe to LogicRuleViewController RuleExecture event. The LogicRuleViewController lives of course in the Logic module and we do not need to implement it.

This method will be called for all ILogicRule interfaces, for example the new IAuditTrailRule and if you use the MasterDetail module the IMasterDetailRule. So first thing is to cast the returned Rule to IAuditTrailRule and if not it’s the right place to write our logic. In step 7 in the AuditTrailInstaller we used only ExecutionContext.ViewChaning so this method will be called only when ViewChanging and rule is IAuditTrailRule. In addition the LogicRuleInfo provides information about inverting any customization.

Audit Trail Rules in Action

In next eXpandFramework version 13.1.6.3 the Audit Trail is fully functional. More attributes are included and also an IModelMemberAuditTrail to allow creation of the collection needed to monitor auditing from the UI.

In the next image we see a rule that will force the Auditing service to use LightWeght mode for all objects.

Next is a rule applied directly to the Customer class that will audit the members included in the Customer_LastName_Age_Group in all Customer DetailViews

0
comments:

Post a Comment

Welcome to my Blog

My name is Apostolis Bekiaris and I am working for DevExpress as a technical evangelist for the frameworks team, .Net is my passion and at this blog you will find a lot of my work using DevExpress Xaf framework and many others. If you want to contact me you can use the link bellow