Rule Archetype Pattern in SQL Modeling Services – Part 2
I realized that there was a significant oversight in my last post of this series – namely a specific hypothetical scenario that provides some context for this series. As I mentioned in my previous post, this hypothetical scenario was inspired by my post on System.Identity and the SQL Server Modeling Services Repository. The goal of this hypothetical scenario is to have a certain level of credibility while simultaneously putting Modeling Services through its paces – contrived to be sure, but not overly so.
The Scenario
Contoso is a multinational corporation with operations in both the US and Canada. Like many enterprises, Contoso has a large number of important business rules that have been embedded in Contoso’s various IT systems. In an effort to achieve BCF (i.e., Better, Cheaper, Faster) within Contoso’s IT systems, Contoso’s IT Architects have decided to migrate Contoso’s business rules out of the various IT systems and place them in a centralized, data-driven repository. For various reasons (we’ll assume that they’re architecturally valid reasons ;-), Contoso’s IT Architects have determined that purchasing a BRE solution is suboptimal for Contoso and will instead be building a custom solution. As Contoso’s IT Architects are devotees of Archetype Patterns, they’ve decided to leverage the Rule Archetype Pattern as the basis for Contoso’s business rule repository.
The following are the high-level architectural requirements for Contoso’s business rule repository:
- A single model for Contoso’s business rules will be leveraged across Contoso Corporate, Contoso USA, and Contoso Canada
- Contoso’s business rules need to be segmented by Contoso business unit (i.e., Corporate, USA, and Canada)
- Access controls to business rules must be implemented, specifically:
- Access controls based on Contoso business unit (e.g., Contoso USA business folks should only be able to see US business rules)
- Access controls based on cross-Contoso responsibilities (e.g., IT Architects should be able to see all Contoso business rules)
- Business rules must support localization. In particular, Contoso Canada’s business rules must be localized in both Canadian English and Canadian French
- Ideally, all Contoso business rules would reside in a single database to allow for analysis by Contoso’s IT department
- Ideally, the Contoso business rules repository would provide auditing features
Given the above list of architectural requirements, Contoso’s IT Architect decide to build Contoso’s business rules repository with SQL Server Modeling Services (shocking conclusion, I know ;-).
Modeling Rules
With the scenario established, it’s time to model Rules based on the refactoring of the Rule Archetype model using ‘M’ (see the previous post for a UML representation of the refactored model). First, the ‘M’ code that establishes the structure of Rules within the model:
1: module RulesModel
2: {
3: import System;
4:
5: Rules :
6: {(
7: HasFolderAndAutoId &
8: {
9: Name : Text where value.Count <= 2083; // Globalization support
10: }
11: )*};
12: }
The above code establishes that Rules support the Modeling Services Patterns for the use of Folders, Identity, and Globalization. Not a bad start for meeting the high-level requirements of the scenario, but supporting Modeling Services Folders alone does not fulfill the scenario’s requirements around access controls/security. To enable Modeling Services’ support for Security the code above needs to be refactored to adhere to the Modeling Services Pattern for Security Views:
1: module RulesModel
2: {
3: import System;
4: import Repository.Item;
5:
6: export RulesTable;
7:
8: RulesTable :
9: {(
10: HasFolderAndAutoId &
11: {
12: Name : Text where value.Count <= 2083; // Globalization support
13: }
14: )*};
15:
16: Rules () : {{ Id : Integer64; Folder : FoldersTable; Name : Text; }*}
17: {
18: RulesTable where value.Folder.Id in ReadableFoldersView().Folder
19: select
20: {
21: Id => value.Id,
22: Folder => value.Folder,
23: Name => value.Name
24: }
25: }
26: }
The above code illustrates an important characteristic of the current Modeling Services CTP – the use of convention over configuration. The can be seen specifically in the refactoring of the Rules extent to be renamed “RulesTable” and the addition of a ‘M’ computed value that produces a SQL Server view name “Rules”. As will be illustrated in subsequent posts, this use of convention is required in the Modeling Services tool chain to produce a Contoso business rules repository that fully leverages all the SQL Server Modeling Services goodness.
In fact, it’s a good idea to map the ‘M’ code above to Contoso’s requirements. As currently implemented in the code snippet above, Contoso Rules are able to:
- be segmented through the use of Modeling Services Folders
- have access controlled on a per-user basis using Modeling Services Folders
- be localized via Modeling Services
- be stored in single database using a single model
That’s not bad requirements coverage for just 26 lines of ‘M’ code.
Repeating the Patterns
One of the benefits of Modeling Services is that usage of the Modeling Services Patterns leads to a productive “plug-and-chug” development paradigm. This is illustrated in the following ‘M’ code snippets for a number of the remaining extents in the refactored Rules model. Note how each extent is very similar to the Rules extent discussed previously:
The Operator extent:
1: module RulesModel
2: {
3: import System;
4: import Repository.Item;
5:
6: export OperatorsTable;
7:
8: OperatorsTable :
9: {(
10: RuleElement &
11: {
12: Operator: Text where value.Count <= 2083; // Globalization support
13: Rule : RulesTable;
14: }
15: )*};
16:
17: Operators () : {{ Id : Integer64; Folder : FoldersTable; Name : Text; Type : Text; ElementSequence : Integer32; Operator : Text; Rule : RulesTable; }*}
18: {
19: OperatorsTable where value.Folder.Id in ReadableFoldersView().Folder
20: select
21: {
22: Id => value.Id,
23: Folder => value.Folder,
24: Name => value.Name,
25: Type => value.Type,
26: ElementSequence => value.ElementSequence,
27: Operator => value.Operator,
28: Rule => value.Rule
29: }
30: }
31: }
The RuleContext extent:
1: module RulesModel
2: {
3: import System;
4: import Repository.Item;
5:
6: export RuleContextsTable;
7:
8: RuleContextsTable :
9: {(
10: HasFolderAndAutoId &
11: {
12: Name : Text where value.Count <= 2083; // Globalization support
13: }
14: )*};
15:
16: RuleContexts () : {{ Id : Integer64; Folder : FoldersTable; Name : Text; }*}
17: {
18: RuleContextsTable where value.Folder.Id in ReadableFoldersView().Folder
19: select
20: {
21: Id => value.Id,
22: Folder => value.Folder,
23: Name => value.Name
24: }
25: }
26: }
<Author’s Note>Strictly speaking, RuleContexts within the Rule Archetype Pattern are runtime constructs. However, I thought it would be interesting to model RuleContexts as part of Contoso’s business rule repository to see how it played out. Archetype purists should feel free to eliminate RuleContexts from the model :-) </Author’s Note>
The RuleSetAssignment extent:
1: module RulesModel
2: {
3: import System;
4: import Repository.Item;
5:
6: export RuleSetAssignmentsTable;
7:
8: RuleSetAssignmentsTable :
9: {(
10: HasFolderAndAutoId &
11: {
12: RuleSet : RuleSetsTable;
13: Rule : RulesTable;
14: }
15: )*};
16:
17: RuleSetAssignments () : {{ Id : Integer64; Folder : FoldersTable; RuleSet : RuleSetsTable; Rule : RulesTable; }*}
18: {
19: RuleSetAssignmentsTable where value.Folder.Id in ReadableFoldersView().Folder
20: select
21: {
22: Id => value.Id,
23: Folder => value.Folder,
24: RuleSet => value.RuleSet,
25: Rule => value.Rule
26: }
27: }
28: }
You get the idea. Given the large amount of similarity in all of the ‘M’ code for the refactored Rule Archetype model, I won’t take up any more space going through it. For those folks that are interested, all of the ‘M’ code for the model so far is available from my SkyDrive via a link at the bottom of this post.
Next Time
With the Rule Archetype now modeled in ‘M’ it’s time to focus on getting the Modeling Services “architectural plumbing” turned on and functioning for the model.
As always, any comments/feedback are greatly appreciated.
SkyDrive Files
Comments
- Anonymous
January 04, 2010
Hi, sad to see, that the IMHO bad guidance from MSDN (http://msdn.microsoft.com/en-us/library/ee698823%28VS.85%29.aspx) makes it to the big show :-) The code is full of duplication and hard to read. This has 20 lines, many less chars and is way easier to read: module RulesModel { import System; import Repository.Item; export RulesTable; type Rule { Name : Text(2083) } RulesTable : {(HasFolderAndAutoId & Rule)}; Rules () : {(HasFolderAndAutoId & Rule)} { RulesTable where value.Folder.Id in ReadableFoldersView().Folder select value } } The duplication of "(HasFolderAndAutoId & Rule)" could be omitted by introducing another type StoredRule or so, but that might be to much. Adding HasFolderAndAutoId to the Rule-type would IMHO violate SRP (Single Responsibility Pattern).
- Lars