Abstract
Client X has an ERP system with a master module and several
instances of its client installed across the Globe. The business requires all
the client instances to be in sync with the master with exceptions. The way to
achieve that was to keep the metadata of the instances, stored in the system
databases of the client and master in sync. One way of doing that was to
restrict the users from making changes to the client or run synchronization
scripts at regular intervals to sync the master and clients.
Introduction
The objective of the project was to ensure that all client
databases are using a group standard set of data in key tables. It also allows
client databases to set certain local persisted fields whist blocking changes
to other fields. The way to achieve that was to develop Triggers on the local
tables to enforce the business rules. And
in cases where it does not stop
local users with DBA access from being able to disable the triggers and update
the synchronized data, develop stored procedures run every night to overwrite
and persist the group data standards.
So the solution designed was:
The target implementations were:
Client Synchronization Triggers
o
SQL Triggers on the database to enforce the
business logic by allowing or preventing changes to the synchronized data
Master Audit Triggers
o
SQL Triggers on the database will track any
changes made to the synchronized tables
Synchronization Scripts
o
SQL scripts contain the business logic and
will copy the necessary values from the tables in the GBLDEVALLSynchronisation
schema to the Production tables.
Problem
Definition
One such requirement for us was to check whether the setting
options applied in clients where in sync with the master. Each of the setting
options were applied through check boxes.
When we check the metadata tables we found out all the
setting options were defined as a screen within a column value in a table with
each setting option represented by a bit.
Now the users were allowed to make changes to certain
settings, while prevented from changing others.
So our job was to search for bits at particular positions
within the string and preventing the user to change those bits from 1 to 0 or
vice-versa. If in case someone with
administrator privilege disables the trigger and change the restricted values,
then run scripts at night to search for those bits and compare their values
between master and clients, and in case difference reverting back the client’s
value.
High Level
Solution
For us there were
two deliverables:
- Triggers-To restrict the users from making changes.
- Synchronization script-In case someone makes the change, identifies the change and revert it.
Since
it was a bitwise operation the operators available to us were
- &(bitwise AND)
- |(bitwise OR)
- ^(bitwise exclusive OR)
The
challenges we faced were
- Searching for bits at particular positions.
- Turning on or off a bit if a mismatch is found.
Solution
Details
Let
us try to explain the solution we implemented for the trigger. Let’s take an
example for the bit position – 256.The meaning of this requirement is value at
the bit position 256 should be same for the client and master, whereas the
value for the other bit positions may be different. In other words the client is
not allowed to change value at the 256 bit position while they can change the
value at other bit positions.
Let’s
consider the master has hexadecimal value – 421, binary value – (110100101).
And the
client tries to change it to hex value of 165, binary value – (010100101).
So
the result should be, it should throw an error.Beacuse the value at the 256 bit
position is different. Though the values at the other positions are different
it should not matter.
So
the solution we came up with is applying & (Bitwise AND) the values with
bit position we are searching for and comparing the values.
[
Example
of how & (Bitwise AND) works.
(A & B)
0000 0000 1010 1010
0000 0000 0100 1011
-------------------
0000 0000 0000 1010
]
For
Master - 421 & 256 = 256.
i.e.
110100101 & 100000000 = 100000000.
For
Client – 165 & 256 = 0
i.e.
010100101 & 100000000 = 000000000
Since
the values are different it throws an error.
Let’s
take another example –
The
master has hexadecimal value – 420, binary value – (110100100).
And
the client tries to change it to hex value of 421, binary value – (110100101).
So
the result should be, it should not throw an error.Beacuse the value at the 256
bit position is same. Though the values at the other positions are different it
should not matter.
For
Master - 420 & 256 = 256.
i.e.
110100100 & 100000000 = 100000000.
For
Client – 421 & 256 = 256
i.e.
110100101 & 100000000 = 100000000
Since
the values are same it does not throw an error.
Now
let’s try to explain what we did for the stored procedure. The purpose of the
stored procedure is to turn on or off the value if a standard value has been
changed by the client which he is not allowed to do.
Let’s
consider the same example of the value being changed at 256th
position.
Note
there are two parts to it.In case the client has changed the value at 256th
position to 1 we need to revert it back to 0 and in case the client has changed
it to 0 we need to revert it back to 1.
The
challenge was to achieve the toggle function.
Part
1 -
Now
let’s consider a value of 111001010 which in hexadecimal is 458.
[
Example
of how Bitwise Exclusive OR works
(A ^ B)
0000 0000 1010 1010
0000 0000 0100 1011
-------------------
0000 0000 1110 0001
]
The
function we came up with to achieve the toggle function is:
(The
number ^ the position) & 67108863.
So
for our example:
(458
^ 256) & 67108863
Or
(111001010 ^ 100000000) & 11111111111111111111111111
=
011001010.
Part
2 -
Now
let’s consider a value of 1011000110 which in hexadecimal is 710.
So
the underlined value at the 256th position is 0 and it needs to be
toggled to 1.
[
Example
of how Bitwise Exclusive OR works
(A ^ B)
0000 0000 1010 1010
0000 0000 0100 1011
-------------------
0000 0000 1110 0001
]
As
mentioned before the function for toggling is:
(The
number ^ the position) & 67108863.
So
for our example:
(710
^ 256) & 67108863
Or (1011000110
^ 100000000) & 11111111111111111111111111
= 1111000110.
Hence
we achieved our toggling function.
We
took 67108863 as the value since for us the highest position required for
toggling is 33554432 and our value is next higher to it.So we made sure we
covered our requirement.
Solution Benefits
With our deliverable s we achieved the objective of ensuring that all client databases are in sync with the master and are using a group standard set of data in key tables. It blocked changes to protected fields while allowing clients to change certain local persisted fields.
While along with it, it took care of the following key considerations:
· The process does not cause heavy network traffic and is as optimized as possible
· The process is able to handle different versions of Viewpoint
· The process is able to enforce the business logic (i.e. prohibit local changes from being made to synchronized fields that are NOT persisted)
· The process is updateable to handle changing business logic
· The process only updates ViewPoint tables during a specified time window
· The process is fully auditable
· The process facilitates a full DTAP lifecycle
While along with it, it took care of the following key considerations:
· The process does not cause heavy network traffic and is as optimized as possible
· The process is able to handle different versions of Viewpoint
· The process is able to enforce the business logic (i.e. prohibit local changes from being made to synchronized fields that are NOT persisted)
· The process is updateable to handle changing business logic
· The process only updates ViewPoint tables during a specified time window
· The process is fully auditable
· The process facilitates a full DTAP lifecycle
Solution
extend-ability
As
next set of steps we would include the auditing functionality and it would be
fully automated. The design and functionality details are mentioned below:
Master Audit Triggers
Overview
The master audit triggers will be used to audit any changes
made to the synchronized tables in the Group ViewPoint Master database.
Auditing strategy
Let’s consider the following example.
A table SUPPLIER_MSTR exists as:
Supplier_Key
|
Supplier_Code
|
Supplier_Name
|
Supplier_State
|
123
|
ABC
|
Acme
Supply Co
|
Manchester
|
A corresponding table SUPPLIER_MSTR_AUDIT for it exists as:
Supplier_Key
|
Supplier_Code
|
Supplier_Name
|
Supplier_State
|
User
|
Event_Type
|
Event_DateTime
|
123
|
ABC
|
Acme
Supply Co
|
Manchester
|
Alan.Donald
|
Insert
|
23-2-2012
10:15 AM
|
It tells us John created this record on 23rd Feb
2012 as 10:15 AM.
Now this morning I changed it to –
Supplier_Key
|
Supplier_Code
|
Supplier_Name
|
Supplier_State
|
123
|
ABC
|
Acme
Supply Co
|
London
|
SUPPLIER_MSTR will show no history and will show the current
scenario.
So SUPPLIER_MSTR_AUDIT table will be now –
Supplier_Key
|
Supplier_Code
|
Supplier_Name
|
Supplier_State
|
User
|
Event_Type
|
Event_DateTime
|
123
|
ABC
|
Acme
Supply Co
|
Manchester
|
Alan.Donald
|
Insert
|
23-2-2012
10:15 AM
|
123
|
ABC
|
Acme
Supply Co
|
London
|
Anirban.Dutta
|
Update
|
21-6-2013
12:46 PM
|
Another record added.
SUPPLIER_MSTR:
Supplier_Key
|
Supplier_Code
|
Supplier_Name
|
Supplier_State
|
123
|
ABC
|
Acme
Supply Co
|
London
|
124
|
XYZ
|
Worlds
Greatest Retailer
|
Leeds
|
SUPPLIER_MSTR_AUDIT:
Supplier_Key
|
Supplier_Code
|
Supplier_Name
|
Supplier_State
|
User
|
Event_Type
|
Event_DateTime
|
123
|
ABC
|
Acme
Supply Co
|
Manchester
|
Alan.Donald
|
Insert
|
23-2-2012
10:15 AM
|
123
|
ABC
|
Acme
Supply Co
|
London
|
Anirban.Dutta
|
Update
|
21-6-2013
12:46 PM
|
But David came and deleted the first record.
SUPPLIER_MSTR:
Supplier_Key
|
Supplier_Code
|
Supplier_Name
|
Supplier_State
|
124
|
XYZ
|
Worlds
Greatest Retailer
|
Leeds
|
SUPPLIER_MSTR_AUDIT:
Supplier_Key
|
Supplier_Code
|
Supplier_Name
|
Supplier_State
|
User
|
Event_Type
|
Event_DateTime
|
123
|
ABC
|
Acme
Supply Co
|
Manchester
|
Alan.Donald
|
Insert
|
23-2-2012
10:15 AM
|
123
|
ABC
|
Acme
Supply Co
|
London
|
Anirban.Dutta
|
Update
|
21-6-2013
12:46 PM
|
124
|
XYZ
|
Worlds
Greatest Retailer
|
Leeds
|
Anirban.Dutta
|
Insert
|
21-6-2013
12:50 PM
|
123
|
ABC
|
Acme
Supply Co
|
London
|
Arron.Lennon
|
Delete
|
21-6-2013
12:53 PM
|
Audit table structures
Each table will have its own
audit table.
The AUDIT tables will replicate
the actual table along with few extra columns.
The extra columns being.
User nvarchar(100)
Event_Type nvarchar(50) only
(‘Insert,’Update’,’Delete’ should be allowed).
Event_DateTime DateTime.
Stored Procedure run status logging
We are planning to capture the
run status of a SP with the following table structure.
SchemaName nvarchar(100),
StoredProcedure nvarchar(128),
UserName nvarchar(100),
StartTime datetime,
EndTime datetime,
EventStatus nvarchar(500),
ReasonForFailure nvarchar(max)
The granularity of the information capture will
be object level.
For example:
If we assume a four Stored Procedures to be
loading four tables:
COAAccount
COAHeader
DMIxFields
EntityTypes
Then the corresponding entries in
the table would be :
SchemaName
|
StoredProcedure
|
UserName
|
StartTime
|
EndTime
|
EventStatus
|
ReasonForFailure
|
GBLDEVALLSECCO
|
USP_SynchroniseCoaAccount
|
Anirban.Dutta
|
1:15:0010 PM
|
1:15:0017 PM
|
Success
|
|
GBLDEVALLSECCO
|
USP_SynchroniseCoaHeader
|
Anirban.Dutta
|
1:15:0018 PM
|
1:15:0025 PM
|
Success
|
|
GBLDEVALLSECCO
|
USP_SynchroniseDmixfields
|
Anirban.Dutta
|
1:15:0019 PM
|
1:15:0022 PM
|
Success
|
|
GBLDEVALLSECCO
|
USP_SynchroniseEntityTypes
|
Anirban.Dutta
|
1:15:0023 PM
|
1:15:0026 PM
|
Success
|
Deliverables
1.
Stored Procedure code.
2.
Trigger code.
Conclusion
The above solution was provided by using/extending VP MDT to
copy the synchronized tables from Group ViewPoint Master to each client
database during the VP change window, then using stored procedures run every
night to overwrite and persist the group data standards.
Triggers were added to the Group ViewPoint Master for audit
purposes as well as being required on the local tables to enforce the business
rules.