Monday, September 20, 2010

Agnostic / Non agnostic

Recently I had a conversation with a customer who did not understand the difference between agnostic and non agnostic.

An example from PCI compliance pov could elaborate which I would like to share.

In service orientation one of the guiding principles is to separate agnostic and non-agnostic service logic. This can be done by separating agnostic service logic into one service and any non-agnostic parts into (an) other service(s).

The definition of agnostic/non agnostic did not help him onto the right track so we used PCI compliance to allow for an appropriate example.

To check the definition of agnostic/non-agnostic, check it at SOAGlossary.com

Summarized, agnostic logic is supposed to be more reusable than non-agnostic logic. Separating agnostic logic from non-agnostic logic is done to increase the reuse potential of a service.

In PCI compliance, one of the scenarios is where customer management representatives view customer details. The business rules dictate that unless explicitly necessary, a card number should not be readable. In this example, the method of making a card number not readable is by masking parts of the number when displayed.

Several places for masking can be identified:
1. In the service which retrieves the customer details including payment data (as the customer had requested)
2. In the front end(s) which use this service to display the payment details are changed where necessary
3. Somewhere else?

Regarding 1) 
Introduces the issue that when the service mask the payment details all the time, the service can never be used in other scenario’s ie. when requirements for viewing unmasked details or when the service is used on other service compositions and unmasked data is necessary. Since the service is agnostic, it does not know the reason as to why the details are retrieved.

Regarding 2) 
Introduces the issue that during the initial implementation one might catch all the scenarios, but as new screens and applications (front ends) are built, no guarantees exist that these comply with the PCI requirements. Furthermore, if the amount of front ends or screens is large, the effort to incorporate the masking logic may be considerable, resulting in an expensive implementation.

Regarding 3) 
This is where the agnostic/non-agnostic can be explained more easily and this is what the remainder of this post will elaborate on.

Agnostic logic should not be aware of the reason why it’s used. This means it would lack functional or process context. If the knowledge like reason or process context must not be in the service which retrieves the customer’s details we can move that knowledge and corresponding logic into a separate service which is non-agnostic. In fact, the task service type as defined by Thomas Erl et al is intended to do exactly this: encapsulate non-agnostic logic.

So we’ve ended up with a customer details service which is agnostic and will retrieve unmasked credit card number data. This can be considered an entity services as per Thomas Erl et al definition.
And we’ve ended up with one or more task service(s) which should be able to distinguish from the agnostic service in the sense that it knows whether or not to mask credit card details.

As indicated the customer details service is agnostic and will not perform the masking logic. If we use the contract centralization pattern and the logic centralization pattern, we have created an official end point pattern. This means we can force users in the service inventory to not use the agnostic service directly but force them to use the non-agnostic task services.

A task service can then deal with the non-agnostic context. A task service is built in a certain context, ie. it retrieves the customer details for sales process purposes. A sales process should typically not be interested in the credit card number. The non-agnostic service, intended for the sales process would always mask the card data.

In the context of a billing process, another task service could expose the unmasked number so that particular service support the actual act of making payment with the card number.

The end result is that:
- the reusable agnostic entity service is not publicly exposed
- one or more non-agnostic task services are publicly exposed, managing the masking logic depending on the context it's called in.

Note that the two task services could be replaced by one task service that could perform masking of card holder data, based upon additional parameters, ie. a reason code, which represents the context in which the service is called. The task service would then decide, based upon the reason code, whether or not to mask any data.

Hope this one helps a bit - I know it's a bit over-simplified but this should paint the picture.