SAP MDM Enrichment Adapter - more than just enrichment

The SAP MDM Enrichment Adapter allows for the integration with third party data enrichment services that support and extend the core MDM data quality process.
I quote from the MDM Enrichment Architecture document:
"The current focus is on Enrichment services, keeping in mind that the system will be enhanced to support other data quality types and semantics, such as validation. "

So it is possible that the Enrichment Adapter can even be used for doing enhanced validations and assignments using the flexibility offered by the Java programming language.
The functionality offered till date (uptill MDM 7.1 SP03) by the MDM Validation expressions is limited particularly dealing with the lookup qualified flat fields.
In this blog, I would be focusing on a sample scenario where we can use the enrichment adapter to extract those non-qualifier values of a Lookup Qualified Flat field that satisfy a condition imposed on the qualifier values.
Sample Scenario - Products Master Data
Consider MDM Record for a Product containing the Pricing information for various Regions in which it is sold. Price Qualified Lookup Field consisting of fields:

Field Name        Type                 Is a Qualifier?
Region Name    Text                  No
Price                 Currency           Yes
MDM repository design
Requirement: To find the list of Regions for all the Product Master records having the Price above a certain threshold (say $100).

In other words, we need to retrieve the Non-Qualifier field (region name) value for only those qualified links satisfying the condition (having price > $100) imposed on their qualifier field (Price) value.
  
Solution using the Enrichment Adapter
We can achieve this by writing a custom enrichment adapter that would then allow us to perform the following:
  1. Launch a workflow for the required MDM records.
  2. Workflow step triggers the custom written enrichment adapter to process each record (syndicated as an XML).
  3. The adapter extracts only the regions with price > $100 and returns the response XML.
  4. MDM Import manager processes the response XML using the import map created and updates the MDM Records with the region names in the target lookup flat field.

Implementation
Briefly listed we would need to do the following:
  1. Create the request and response XML Schemas.
  2. Create the syndication and import maps.
  3. Create and deploy the MDM enrichment adapter.
  4. Create a MDM workflow.
  5. Edit the MDM Enrichment Controller Configuration XML.
  6. Restart the controller for configuration changes to take effect.
  7. Launch the newly created workflow for the MDM records.
1. Create the request and response XML Schemas
Here is a simple XML request that would be processed by the enrichment adapter:
               
                                121
                               
                                                Region 1
                                                101.99
                               
               

Based on the above following is the Sample Request XML Schema:
Sample Request XML schema

Similarly we have the expected response XML from the enrichment adapter:
   
        121
       
            Region 1
       
   

For the above sample xml we have the Sample Response XML Schema:
Sample response XML schema

Important
The request and response XML schemas need to be saved in the MDM repository special table XML Schemas using the Console.
               
2. Create the syndication and import maps.
The next step is the creation of Syndication and Import maps.
Here we have a sample map created in the Syndicator:
Sample Syndication Map
Note: Ensure the map is saved in the respective Remote System. Here we save the map: Request in the remote system: New Client System.
In order to create the Import Map it is important that a sample response XML file is created first. Here we use the SampleResponse.xml to create the import map.
The SampleResponse.xml file contains the list of all possible region names which have to be mapped to the lookup values of the target repository.
Mapping all the region names
Note: Ensure the map is saved in the respective Remote System. Here we save the map: Response in the remote system: New Client System.

3. Create and deploy the MDM enrichment adapter
Follow the steps to create the EJB project in the SAP NetWeaver Developer Studio as outlined in the document Setup and Use of the SAP NetWeaver Master Data Management Enrichment Controller (section Getting Started with Adapter Development).
                The business method getEnrichmentService is implemented as follows:
Implementing the getEnrichmentService() method

I have used a user defined function named getResponse() that accepts the request content parameter and returns the appropriate response as a string. This is encapsulated as an Enrichment Content and returned as an EnrichmentAdapterResponse parameter by the adapter.
//Method that generates the response as String from the request content passed//Response string consists of the region names having price greater than $100
private String getResonse(EnrichmentContent reqContent)
      throws EnrichmentAdapterException {
      String responseStr = "";
      try {
      //Extract the Document object from request EnrichmentContent object
            Document doc = reqContent.getContentDocument();

            //Get the root node from the document object
            Node root = doc.getFirstChild();

            //Ensure the root node name is SampleRequest
            if (!root.getNodeName().equals("SampleRequest")) {
                  throw new EnrichmentAdapterException(
                        "Unexpected XML root: <" + root.getNodeName() + ">");
            }

            
//Get the child nodes             NodeList rootChildNodes = root.getChildNodes();

            //Loop through all the nodes
            for (int i = 0; i < rootChildNodes.getLength(); i++) {
                  Element recordEle = (Element) rootChildNodes.item(i);
                        
                  //Validate XML structure by checking the node name
                  if (!recordEle.getNodeName().equals("Record")) {
                        throw new EnrichmentAdapterException(
                              "Unexpected XML element: <"
                                    + recordEle.getNodeName()
                                    + ">");
                  }

            //Get the list of Elements having the tag name value as Name
            NodeList nameList = recordEle.getElementsByTagName("Name");
                        
            //Check to ensure Name tag is not repeated
            if (nameList.getLength() > 1) {
            throw new EnrichmentAdapterException("Duplicate  Elements!");
                        }
                        
            //Extract the tag value of the  element
            Element nameEle = (Element) nameList.item(0);
            String nameValue = nameEle.getFirstChild().getNodeValue();

            //Call the method that extracts the list of Regions having price above $100
            ArrayList regionList = getPricingRegions(recordEle);

            String regionName = "";
                        
            //Create the response string with the  tag
            responseStr += "" + "" + nameValue + "";

            //Loop through the regions ArrayList
            for (int j = 0; j < regionList.size(); j++) {

                  regionName = (String) regionList.get(j);
                  //Append the response string with  tag value      
                  responseStr += ""
                                    + ""
                                    + regionName
                                    + ""
                                    + "";
            }
            //Ending the  tag element
            responseStr += "";

      }
            } catch (EnrichmentAdapterException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            }
            //Encapsulate the response with the root tag
            responseStr = "" + responseStr + "";

            return responseStr;
}
The getResponse() method in turn calls the getPricingRegions() method which does the actual work of selecting only those Region names having the Price greater than $100.

//Method returning an ArrayList of the regions having Price above $100
      private ArrayList getPricingRegions(Element recordEle) {
            String regionName = "";
            
            //Initialize the ArrayList containing the region names
            ArrayList regionList = new ArrayList();
            
            //Get the list of all the Pricing tag elements
            NodeList qualifiedElements = recordEle.getElementsByTagName("Pricing");
 
            //Loop through all Nodes in the list
            for (int i = 0; i < qualifiedElements.getLength(); i++) {
                  Element qualEle = (Element) qualifiedElements.item(i);
                  
                  //Extract the value of the  tag
                  regionName = qualEle.getFirstChild().getFirstChild().getNodeValue();
                  
                  //Get the list of the child nodes of the  tag element
                  NodeList childNodesList = qualEle.getChildNodes();
                  
                  //Loop through the child nodes and retrieve the  child node
                  for (int j = 0; j < childNodesList.getLength(); j++) {
                        if (childNodesList.item(j).getNodeType() == Node.ELEMENT_NODE
                              && childNodesList.item(j).getNodeName().equals("Price")) {
                              
                              //Get the  tag value as string
                              String priceValue =
                                    childNodesList.item(j).getFirstChild().getNodeValue();
                                    
                              //Parse the string to get the value as a double
                              double price = Double.parseDouble(priceValue);
                              
                              //Check if the price value is greater than 100
                              if (price > (double) 100.00) {
                                    //Add the region name to the ArrayList
                                    regionList.add(regionName);
                              }
                        }
                  }
 
            }
 
            return regionList;
      }
 
Now that the enrichment adapter coding is complete we build and deploy the generated adapter EAR to the NetWeaver WebAS.
4. Create a MDM workflow
We create a simple workflow for triggering the Enrichment Adapter from the Data Manager as follows:
 MDM Workflow for triggering the enrichment adapter
Note: The Request step is assigned to the user EnrichUser who can only perform the process of launching and triggering the enrichment adapter.
5. Edit the MDM Enrichment Controller Configuration XML
Following is the configuration made for triggering the enrichment adapter from the workflow of the Demo repository.
MDM EC Configuration for launching enrichment adapter 
6. Restart the controller for configuration changes to take effect
Using either the SAP MDM Enrichment Controller page or the Visual Admin restart the Enrichment Controller for the configurations made in step 5 to take effect.
 Restarting the EC using SAP MDM EC page
7. Launch the newly created workflow for the MDM records
Firstly we need to login to the Data Manager as the user: EnrichUser.
Now we can select the MDM records from the Data Manager and launch the workflow that does the job of extracting those Region names from the Lookup Qualified Flat field that have the qualifier Price > $100.
Here we have a record having the following qualified links:
                Link        Region (Non-Qualifier)  Price (Qualifier)
                1              Region 3                               $ 99.99
                2              Region 4                               $ 100.05
                3              Region 5                               $ 100.99
 
 Launching the workflow to trigger the enrichment adapter 
After the workflow is completed we get back the region names populated in the Lookup Flat multivalued field (Price Regions above $100):
 Enriched MDM Record containing the updated region names
The method explained here is just another way that the SAP MDM Enrichment Adapter can be used to extract those Non qualifier values of a Lookup Qualified Flat field that satisfy a condition imposed on the qualifier values. 
If the scenario requires only validations to be performed on the qualifier values for every qualified link then you can follow the procedure described in the SAP Notes: 1340831 and 1423359.

SAP Developer Network Latest Updates