//declared, visible, and open coupling

declared, visible, and open coupling

Recently, I blogged that two coupled services should have declared, visible, and open coupling.  I was promptly asked how.

First off, when you have two services, why would they be coupled?  Isn’t the POINT that your services are decoupled?  Sure.  That’s the point.  But the business doesn’t always work that way.  Sometimes, your services are coupled because the business is coupled.

Here’s an example. 

Let’s say that our company (Contoso) has a couple of co-op marketing programs.  This kind of program is fairly common these days.  You make an arrangement with a business partner.  They include a reference to your product in their advertising, and you provide some money to pay for the ad.  A good example that most folks will recognize: Intel has a co-op marketing program.  Any ad that specifically mentions that a machine has an Intel chip in it, and displays the Intel logo, earns a reimbursement from Intel for the costs of producing and running the ad.  As a result, we all seen (and heard) the “Intel Inside” brand quite frequently.  The program works. 

Now, let’s look at this from a business side.  I’m going to pick on two  closely related use cases.  Signing up to be a partner of any kind, and signing up to be a member of the co-op partner programs.

Contoso has lots of relationships with partners.  We have partners in the supply chain, in manufacturing, as well as in distribution and retail.  Each of our partners needs to be uniquely identified, so we have a system where we record the basic information about a partner: legal entity name, DUNS number,  Government Tax Id, Street Address, and other information needed to correctly identify this company.  Attached to this record, we may have information about contacts, directors/owners, and people that we recognize as contract signatories.

Seperately, we will have a system that records the information specific to the co-op programs.  It will contain the list of programs, eligibility rules, claim constraints, claim history, and measures of visibility and effectiveness of the co-op programs.  The partner identified in this system has to also exist in the core partner system, but not the other way around.  In other words, in order to be eligible, you have to be a partner in some way, but not all partners are eligible.  The supplier of cardboard boxes should not be able to claim co-op marketing funds for our product, for example.

So, what kind of service is “create co-op partner”?  First off, it is a composite service.  It needs to orchestrate between two lower-level services.  For the sake of argument, I’ll call the lower level services “partner-master” and “add-to-co-op-master”.

If I send data to a service that creates a co-op partner, and I don’t know the id in the partner master system, then I need to look the partner up, and if they are not found, create them in the partner master system, then take their partner id and add them to the co-op system.  I may not want to do any of that if they are not eligible to join the co-op system. 

Adding data to the co-op system itself is done in the ‘add-to-co-op-master’ service.  This service simply requires the existence of a ‘partner master’ id.  Of course, to be defensive, it will need to check to see if that id is valid or have some other way to trust the caller. 

And here’s where we get to the notion of a declared coupling.  The ‘create co-op partner’ service needs to have a way to declare, even if it is just in text, that it is responsible for checking the ‘partner-master’ service, looking for duplicates and creating the partner if necessary.  There needs to be data that shows the coupling of this composite service.  In the best of all possible worlds, This data would be available in the contract header information (although I don’t know of any standard way to do that).

In addition, there needs to be a way for the ‘add-to-co-op-master’ service to trust the partner id that comes in on a call, without actually calling the ‘partner-master’ service.  Perhaps it will only accept calls that have an ID if the call comes from a known composite service or from a known IP address?  Perhaps digital signatures are required?  Trust has to be established.

It is important that the fine-grained ‘add-to-co-op-master’ service NOT directly call the ‘partner-master’ service.  This would be unnecessary coupling.  

So, recap, the rules to making this coupling open and visible:

— In the header of any composite service, declare the child services that will be called, with sufficient reference data for the system that is asking for data to drill down and find out about the called service.

—  If a service has data reference requirements, it can limit the list of eligible callers to a known collaborator (like a known composite service).  It should not call other fine-grained services to validate inbound data.

— The only services that can call other services are composites, and composites can only call other services in a rules-defined order.  They should not perform their own data storage or data validation operations, relying only on underlying services to provide these capabilities.

It’s not dissimilar to the notions of ‘good practice’ that evolved out of object-oriented programming when it started to get off the ground.  Things like naming rules and style considerations, all of which were designed to make code easier to read and use.  The same goes for service coupling.  If we follow these basic rules, we can minimize coupling and keep it contained in an open and controlled location.

—  Addendum

In response to a question about application-level authentication, I am updating this post to include a link to an MSDN article that discusses this aspect in rich detail.  I highly recommend this ‘Patterns and Practices’ article.

http://msdn.microsoft.com/library/en-us/dnnetsec/html/SecNetch10.asp

By |2006-10-23T00:50:00+00:00October 23rd, 2006|Enterprise Architecture|5 Comments

About the Author:

President of Vanguard EA, an Enterprise Architecture consulting firm in Seattle focused on the Pacific coast of the US. Nick has over 30 years of professional experience in management, systems, and technology. He is the co-author of the influential paper "Perspectives on Enterprise Architecture" with Dr. Brian Cameron that effectively defined modern Enterprise Architecture practices, and he is frequent speaker at public gatherings on Enterprise Architecture and related topics. He coauthored a book on Visual Storytelling with Martin Sykes and Mark West titled "Stories That Move Mountains".

5 Comments

  1. Donald Evans October 24, 2006 at 2:20 pm - Reply

    <i>Perhaps it will only accept calls that have an ID if the call comes from a known composite service or from a known IP address?  Perhaps digital signatures are required?</i>

    I have a tangential question, on the topic of trust, that is prodded by recent projects and my questioning of the tradeoffs I have made in the design and implementation to balance deadlines, functionality, security, and expectations of imminent reuse:

    Is there a defined standard — ideally, a framework and API, or perhaps a documented design pattern — for establishing trust at the level of calling a method on a public interface, or at the level of obtaining a reference to a public interface?

    You’ve suggested an IP address lookup as well as digital signatures to establish trust. The .NET framework seems to require a (partial) public key to be registered with a .NET-specific security policy before interface calls are permitted. I’ve used cryptographic hashing to authenticate credentials sent into the public interface before I trust the caller.

    Why the proliferation of approaches, particularly if the ultimate design goal is to reuse mature services that are already best implemented? For example: your suggestion of using digital signatures — via the certificate APIs in the cryptography framework — seems like the best implementation.

  2. NickMalik October 24, 2006 at 6:47 pm - Reply

    Good question.  Why many mechanisms?  I think because there are assumptions in each mechanism about the environment in which the mechanism would be the most appropriate.  

    By ‘environment,’ I include both the technical infrastructure used to manage authorization as well as the business climate and culture with respect to the control (and potentially the financing) of shared services.

    An old saw that gets bantered around is "software reflects the organization that builds it."  I think the same applies to the standards used by our services infrastructure.  There are different approaches and different standards because there are different organizations.

    Is there one right answer?  Darned if I know.

    Digital signatures are particularly appealing to me.

    As far as "is there a defined standard," to be fair, I don’t know how to answer that.  There are some standards about providing credentials.  However, the WS standards all assume that the service itself will step through some additional work to decide of the credentials of the user match the called function.  That work isn’t "out of the box" as far as I know.

  3. Udi Dahan -The Software Simplist October 26, 2006 at 6:54 pm - Reply

    Always a pleasure, Nick Malik’s Inside Architecture blog hits another one out of the park. <a href="http://blogs.msdn.com/nickmalik/archive/2006/10/22/declared-visible-and-open-coupling.aspx">Declare, Visible, and Open Coupling</a> gives me exactly the kind of meaty examples I like to sink my teeth into. The fact that I disagree with Nick’s solution makes this even more interesting, since I usually do a lot of head-nodding when I read his stuff.

    <a href="http://udidahan.weblogs.us/archives/037010.html">Continued here</a>

  4. Inside Architecture October 27, 2006 at 6:09 am - Reply

    Udi Dahan posted an interesting reply to a recent posting of mine . In my post, I go into detail to present

  5. Sam Gentile September 25, 2007 at 3:06 am - Reply

    I am still reeling from seeing the Red Hot Chili Peppers with Mars Volta 2 nights ago in Philly at the

Leave A Comment

1 × 1 =