Coding a rule engine behavior extension

Now that the rule engine extension project is created and the dependencies are in place, you can write the code for the behavior extension.

About this task

This procedure uses the example of a simple addPerson validation behavior extension. If your behavior extension has a different goal, then the code will have to be customized as needed.

Procedure

  1. Open the <behavior extension name>.java file (such as PersonAddValidation.java).
  2. Replace the content of the Java file with the following code, adding the imports below the package name:
    import java.io.StringReader;
    import java.io.StringWriter;
    import java.util.ArrayList;
    import java.util.Hashtable;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.stream.StreamResult;
    import javax.xml.transform.stream.StreamSource;
    
    import com.dwl.base.extensionFramework.ExtensionParameters;
    import com.dwl.base.logging.DWLLoggerManager;
    import com.dwl.base.logging.IDWLLogger;
    import com.dwl.base.rules.RuleEngineException;
    import com.ibm.mdm.rule.engine.JRulesXUEngine;
    import com.dwl.base.externalrule.ExternalRuleFact;
    import com.dwl.tcrm.coreParty.component.TCRMPersonBObj;
    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     *
     * This is a Java rule that extends the behavior of WCC. @see
     * com.dwl.base.extensionFramework.ClientJavaExtensionSet
     * 
     * @generated
     */
    public class PersonAddValidation extends JRulesXUEngine {
    	private static final String stylesheet = "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:out='http://www.ibm.com/mdm/schema'><xsl:output omit-xml-declaration='yes' indent='no'/><xsl:template match='node()|@*'><xsl:copy><xsl:apply-templates select='node()|@*'/></xsl:copy></xsl:template><xsl:template match='*'><xsl:element name='out:{name()}'><xsl:copy-of select='namespace::*'/><xsl:apply-templates select='node()|@*'/></xsl:element></xsl:template></xsl:stylesheet>";
    	Hashtable spec;
    	List<Object> ruleInput = null;
    	boolean isExternalRuleFact = false;
    	private final static IDWLLogger logger = DWLLoggerManager.getLogger(PersonAddValidation.class);
    	private TransformerFactory transformerFactory = TransformerFactory.newInstance();
    	/**
         * <!-- begin-user-doc -->
         * <!-- end-user-doc -->
         *
         * The execute method will be called in case of extension activation.
         *
         * @generated
         */
    
        public PersonAddValidation (Hashtable spec) throws RuleEngineException {
    		super(spec);
    		this.spec=spec;
    		ruleInput = new ArrayList<Object>();
    				
    	}
        
    	@Override
    	public void populateODMInputParameters(List<Object> factObject,	Map<String, Object> ruleInputParameters) {
    		
    		String xmlParty=null;
    		TCRMPersonBObj tcrmPerson=null;
    		System.out.println("Inside PersonAddValidation::populateODMInputParameters ");
    		System.out.println("factObject.size()="+factObject.size());	
    		for(Object obj:factObject)
    		{
    			System.out.println(" obj :"+obj.getClass().getCanonicalName());
    			if(obj  instanceof  TCRMPersonBObj)
    			{
    			  tcrmPerson= (TCRMPersonBObj) obj;	
    			 
    			  try {
    					xmlParty = tcrmPerson.toXML("TCRM", "MDMDomains.xsd",0,null,false);
    					//add the 'http://www.ibm.com/mdm/schema' namespace to the raw xml
    				    javax.xml.transform.Source xmlSource = new StreamSource(new StringReader(xmlParty));
    					StreamSource xslSource = new StreamSource(new StringReader(stylesheet));
    				    Transformer transformer = transformerFactory.newTransformer(xslSource);
    				    StringWriter xmlOutput = new StringWriter();
    				    StreamResult result = new StreamResult(xmlOutput);
    				    transformer.transform(xmlSource, result);
    				    xmlParty = xmlOutput.toString();
    				
    				} catch (Exception e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			} 
    			 
    		}
    		
    		
    					
    		System.out.println("Setting Value PersonPojo="+tcrmPerson.getDisplayName() +"in ODM");	
    		ruleInputParameters.put("person",xmlParty );
    	}
    
    	@Override
    	public void populateODMOutputParameters(List<Object> factObject, Map<String, Object> ruleOutputParameters) {
    		// logs the rule output in fine mode for debugging
    		if (logger.isFineEnabled())
    			logRuleOutputsInFineMode(ruleOutputParameters);
    		
    		// If the ilog rule is of external rule type, then the rule output will be set back to the ExternalRuleFact object
    		if (isExternalRuleFact) {
    			((ExternalRuleFact)factObject.get(0)).setOutput(ruleOutputParameters);
    		}
    	}
    	
    	/**
    	 * Method just logs the rule output in fine mode for debugging.
    	 * 
    	 * @param outputParameters
    	 */
    	private void logRuleOutputsInFineMode(Map<String,Object> outputParameters) {
    		if (outputParameters!=null && outputParameters.size()>0) {
    			Iterator itr = outputParameters.keySet().iterator();
    			while (itr.hasNext()) {
    				Object key = itr.next();
    				logger.fine("[PersonAddValidation] Rule Result <.>: "+key+"="+outputParameters.get(key));
    			}
    		}
    	}
    	
      
    }

    This class extends the JRulesXUEngine, which is the default rule engine implementation in InfoSphere® MDM. You must override the following methods:

    @Override
    public void populateODMInputParameters(List<Object> factObject,	Map<String, Object> ruleInputParameters)
    

    Write your implementation to pass InfoSphere MDM objects to ODM:

    @Override
    public void populateODMOutputParameters(List<Object> factObject, Map<String, Object> ruleOutputParameters) 
    

    Write your implementation to get output from ODM. Override the default constructor with the following implementation:

    public PersonAddValidation (Hashtable spec) throws RuleEngineException {
    		super(spec);
    		this.spec=spec;
    		ruleInput = new ArrayList<Object>();
    				
    	}
  3. Modify the blue-print.xml file.
    1. Locate blueprint-generated.xml.
      Locate blueprint-generated.xml
    2. Replace the following contents in blueprint-generated.xml to be picked up as a rule engine project.
      <?xml version="1.0" encoding="UTF-8"?>
      <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
      	<service id="ODM.RuleEngine.IMPL" interface="com.dwl.base.rules.RuleEngineLocator" >
      		<service-properties>
      			<entry key="RuleEngine" value="com.ibm.odm.behaviour.PersonAddValidation"/>
      		</service-properties>
      		<bean class="com.dwl.base.rules.RuleEngineLocatorImpl">
      		 <property name="bpBundle" ref="blueprintBundle"/>
      		</bean>
      	</service>
      </blueprint>
      Note: Ensure the RuleEngine key has the correct behavior extension class name.
      <entry key="RuleEngine" value="com.ibm.odm.behaviour.PersonAddValidation"/>
  4. Right-click on the CBA project, such as PersonAddValidation.cba, and select META-INF\COMPOSITEBUNDLE.MF.
  5. Change the value of CompositeBundle-ExportService: to com.dwl.base.rules.RuleEngineLocator with a space in between, as shown below:
    CompositeBundle-ExportService: com.dwl.base.rules.RuleEngineLocator
    Note: This step is important so that the RuleEngineService locator will invoke this extension project.
    Composite bundle export service

What to do next

Now that you have coded the rule engine extension, you can deploy the extension.