Executing the Rules

Procedure

Creating the Web Module

  1. In the SAP NetWeaver Developer Studio, choose Start of the navigation pathFile Next navigation step New Next navigation step ProjectEnd of the navigation path.

  2. In the wizard that appears, expand the Development Infrastructure node and choose Development Component . Choose Next .

  3. In the screen that appears, expand the J2EE node and choose Web Module . Choose Next .

  4. In the screen that appears, choose the software component where you want to create the DCs. For example expand the 'Local Development' node and choose MyComponents [demo.sap.com] . Choose Next .

  5. In the screen that appears, enter rates in the Name field. Choose Finish .

The Java EE perspective opens and in the Project Explorer view, you should see the rates node.

Adding Dependency to the Web Module
  1. Choose Start of the navigation pathWindow Next navigation step Open Perspective Next navigation step OtherEnd of the navigation path.

  2. In the dialog box that appears, choose Development Infrastructure . Choose OK .

  3. In the Component Browser view, expand the MyComponents[demo.sap.com] node and choose the rates node.

  4. In the Component Properties view, choose the Dependencies tab.

  5. Choose the Add button and in the wizard that appears, expand the BRMS-FACADE[sap.com] node and select the tc/brms/facade checkbox. Choose Next .

  6. In the screen that appears, select the Design Time , Deploy Time , Run Time checkboxes. Choose Finish .

Creating EngineInvoker.java

Make sure that you are in the Java EE perspective.

  1. Expand the web module: rates node and in the context menu of the Java Resources: Source node, choose Start of the navigation pathNew Next navigation step OtherEnd of the navigation path

  2. In the wizard that appears, expand the Java node and choose Package . Choose Next .

  3. In the screen that appears, enter com.sap.helper in the Name field.

  4. Choose Finish .

  5. In the context menu of com.sap.helper , choose Start of the navigation pathNew Next navigation step OtherEnd of the navigation path

  6. In the wizard that appears, choose Class . Choose Next .

  7. In the screen that appears, enter EngineInvoker in the Name field.

    You should see the EngineInvoker.java window.

  8. Delete all existing lines and copy the following lines into the window:

    
    package com.sap.helper;
    import com.sap.brms.qrules.ejb.RuleEngineHome;
    import com.sap.brms.qrules.engine.RuleEngine;
    import com.sap.brms.qrules.xml.XMLObject;
    import com.sap.brms.qrules.xml.XMLObjectFactory;
    import java.io.BufferedReader;
    import java.io.PrintWriter;
    import java.io.StringReader;
    import java.io.StringWriter;
    import java.util.*;
    import javax.naming.InitialContext;
    import javax.rmi.PortableRemoteObject;
    public class EngineInvoker
    {
        private static String jndiName = "com.sap.brms.RuleEngine";
        private static String payloadSeparator;
        private static String ret_payloadSeparator;
        private static final String PROPS_FILE = "engine.properties";
        public EngineInvoker()
        {
        }
        public static RuleEngine getRuleEngine()
            throws Exception
        {        
            InitialContext context = new InitialContext();
            Object obj = context.lookup(jndiName);       
            RuleEngineHome home = (RuleEngineHome)PortableRemoteObject.narrow(obj, RuleEngineHome.class);
            return (RuleEngine)home.create();
        }
        public static String invokeRuleset(String projectName, String rsName, String inputXML, RuleEngine ruleEngine)
        {
            String output = null;
            if(projectName == null || rsName == null || inputXML == null)
            {
                output = "Project Name or Ruleset Name or Payload should not be NULL";
            }
            try
            {
                if(ruleEngine == null)
                {
                    ruleEngine = getRuleEngine();
                }
                List xmlObjList = processPayload(inputXML);
                List opXMLObjects = ruleEngine.invokeRuleset(projectName, rsName, xmlObjList);
                output = processReturnPayload(opXMLObjects);
            }
            catch(Exception e)
            {            
                output = e.getMessage();            
            }
            return output;
        }
        private static String processReturnPayload(List opXMLObjects)
        {
            StringBuffer op = new StringBuffer();
            int size = opXMLObjects.size();
            for(int i = 0; i < size; i++)
            {
                XMLObject obj = (XMLObject)opXMLObjects.get(i);
                String opS = obj.getXmlString();
                op.append(opS);
                if(size != 1 && i != size - 1)
                {
                    op.append(ret_payloadSeparator);
                    op.append(System.getProperty("line.separator"));
                }
            }
            return op.toString();
        }
        private static List processPayload(String inputXML)
            throws Exception
        {
            List inputList = new ArrayList();
            StringReader strReader = new StringReader(inputXML);
            BufferedReader in = new BufferedReader(strReader);
            String line = null;
            StringBuffer sb = new StringBuffer();
            XMLObject xmlObj = null;
            while((line = in.readLine()) != null) 
            {
                String trimmedLine = line.trim();
                if(trimmedLine.startsWith(payloadSeparator))
                {
                    xmlObj = XMLObjectFactory.createXMLObject(sb.toString());
                    inputList.add(xmlObj);
                    sb.setLength(0);
                    ret_payloadSeparator = trimmedLine;
                } else
                {
                    sb.append(line);
                }
            }
            if(sb.length() != 0)
            {
                xmlObj = XMLObjectFactory.createXMLObject(sb.toString());
                inputList.add(xmlObj);
            }
            return inputList;
        }
        public static void main(String args[])
        {
            try
            {
                processPayload(null);
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
        static 
        {
            payloadSeparator = "#";
            ret_payloadSeparator = payloadSeparator;
        }
    }
                      

Creating the XMLHelper.java

  1. In the context menu of com.sap.helper , choose Start of the navigation pathNew Next navigation step OtherEnd of the navigation path

  2. In the wizard that appears, choose Class . Choose Next .

  3. In the screen that appears, enter XMLHelper in the Name field. Choose Finish .

    You should see the XMLHelper.java window.

  4. Delete all existing lines and copy the following lines into the window:

    package com.sap.helper;
    import java.io.ByteArrayInputStream;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import org.w3c.dom.Document;
    public class XMLHelper {
    public static String ConstructXML(String connProvider, String destCountry, String originCountry, String typeOfLine){
                                    String xmlString =  "<?xml version='1.0' encoding='UTF-8'?>" + 
    
    "<CallCharges>" +
    "<Charges>" +             
    "<ConnectionProvider>" + connProvider +"</ConnectionProvider>"+
    "<ConnectionRate>0.0</ConnectionRate>"+
    "<DestinationCountry>" + destCountry + "</DestinationCountry>" +
    "<OriginCountry>" + originCountry + "</OriginCountry>" + 
    "<TypeOfLine>" + typeOfLine + "</TypeOfLine>"+ 
    "</Charges>"+
    "</CallCharges>";  
    
     return xmlString;
            }
    
            public static String GetConnectionrate(String output)throws Exception
            {
                    try {                   
                            DocumentBuilderFactory factory = DocumentBuilderFactory
                                            .newInstance();
                            // Use the factory to create a builder
                            DocumentBuilder builder = factory.newDocumentBuilder();
                            ByteArrayInputStream stream = new ByteArrayInputStream(output
                                            .getBytes());
                            Document doc = builder.parse(stream);
                            // Get a list of all elements in the document.
                            // Get the value of the 3rd attribute which is the connection charge.
                            String attValue = doc.getElementsByTagName("*").item(3)
                                            .getTextContent();
                            return attValue;
                    } catch (Exception e) {
                            String error = "Unable to get connection rate. Failed Parsing"+"\n"+output+"\n";
                            error += e.getMessage();
                            throw new Exception(error,e);           
                    }
            }
            
    }
                      

Creating the CallCharges.jsp

  1. Expand the web module: rates node and in the context menu of the Web Content node, choose Start of the navigation pathNew Next navigation step OtherEnd of the navigation path

  2. In the dialog box that appears, expand the Web node and choose JSP . Choose Next

  3. In the screen that appears, enter CallCharges in the File name field.

  4. Choose Finish .

    You should see the CallCharges.jsp window with the following lines:

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    <head>
    <body>
    </body>
    </html>
                      
  5. Replace <title>Insert title here </title> with <title>Call Charge Calculator </title> .

  6. Copy the following lines after <body>

    
    
    <form name="ui" method="POST" action="invoker.jsp">
    <h3>BRMS Invocation Client</h3>
    <%
     String connProvider = (String) request.getAttribute("CONN_PROVIDER");
     String destCountry = (String) request.getAttribute("DEST_COUNTRY");
     String originCountry = (String) request.getAttribute("ORIGIN_COUNTRY");
     String typeOfLine = (String) request.getAttribute("TYPE_OF_LINE");
     String callCharge = (String) request.getAttribute("CALL_CHARGE");
     
     if(connProvider == null){
             connProvider = "";
     }
     if(destCountry == null){
             destCountry = "";
     }
     if(originCountry == null){
             originCountry = "";
     }
     if(typeOfLine == null){
             typeOfLine = "";
     }
     if(callCharge == null)
     {
             callCharge = "";
     }
    %>
    <table cellpadding="0" cellspacing="0" border="0">
    
    <tr>
    <td>Connection Provider: </td>
    <td><input type="text" name="CONN_PROVIDER"
                            value="<%=connProvider %>"></input></td> 
    </tr>
    <tr>
    <td>Destination Country:</td>  
    <td><input name="DEST_COUNTRY" type="text"
                            value="<%=destCountry %>"></input></td> 
    </tr>
    <tr>
    <td>Origin Country:</td>  
    <td><input name="ORIGIN_COUNTRY" type="text"
                            value="<%=originCountry %>"></input></td>  </tr>
    <tr>
    <td>Type Of Line:</td>
    <td><input name="TYPE_OF_LINE" type="text"
                            value="<%=typeOfLine %>"></input></td>      
                         </tr>
    <tr>
    <td> </td>
    <td> </td>
    </tr>
    <tr>
    <td> </td>
    <td><input name="INVOKE" type="submit" value="Submit"/></td> 
    </tr>
    </table>
    <br/>
    <strong>Call Charges:</strong><br/>
    <textarea id="CallCharge" name="CALL_CHARGE"
            style="width: 503px; height: 50px;"><%=callCharge %></textarea>
    </form>
                      
  7. Save the changes.

Creating the index.jsp

  1. Expand the web module: Rates node and in the context menu of the Web Content node, choose Start of the navigation pathNew Next navigation step OtherEnd of the navigation path

  2. In the dialog box that appears, expand the Web node and choose JSP . Choose Next

  3. In the screen that appears, enter index in the File name field. Choose Next .

  4. Choose Finish .

    You should see the index.jsp window with the following lines:

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert the title here</title>
    <head>
    <body>
    </body>
    </html>
                      
  5. Replace <title>Insert title here </title> with <title>Call Charge Calculator </title> .

  6. Copy the following line after <body> :

    <jsp:forward page="CallCharges.jsp"/>
                      
  7. Save the changes.

Creating the invoker.jsp

  1. Expand the web module: rates node and in the context menu of the Web Content node, choose Start of the navigation pathNew Next navigation step OtherEnd of the navigation path

  2. In the dialog box that appears, expand the Web node and choose JSP . Choose Next

  3. In the screen that appears, enter invoker in the File name field. Choose Next .

  4. Choose Finish .

    You should see the invoker.jsp window with the following lines:

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert the title here</title>
    <head>
    <body>
    </body>
    </html>
                      
  5. Replace <title>Insert title here </title> with <title>Call Charge Calculator </title> .

  6. Copy the following lines before <html>

    
    <%@page import="com.sap.helper.*"%>
    <%@page import="javax.xml.parsers.*" %>
    <%@page import="org.w3c.dom.*"%>
    <%@page import="java.io.ByteArrayInputStream"%>
                      
  7. Copy the following line after <body> :

    
    <%
    String connProvider = (String) request.getParameter("CONN_PROVIDER");
            String destCountry = (String) request.getParameter("DEST_COUNTRY");
            String originCountry = (String) request.getParameter("ORIGIN_COUNTRY");
            String typeOfLine = (String) request.getParameter("TYPE_OF_LINE");
                    // create a xml string by making use of the values inputted by the user.
            String xmlString =  XMLHelper.ConstructXML(connProvider,destCountry,originCountry,typeOfLine);
            System.out.println(connProvider + "@@ "+ destCountry+" @@"+originCountry + " @@" + typeOfLine);
            // set project name and ruleset name.
        String projectName = "demo.sap.com~ratecalculation";
        //String rulesetName = "CalculateRates";
        String rulesetName = "ratecalcrules";
            //invoking the rule engine
        String output = EngineInvoker.invokeRuleset(projectName, rulesetName, xmlString, null);
        // Create a factory
        //DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        // Use the factory to create a builder
        //DocumentBuilder builder = factory.newDocumentBuilder();  
        //ByteArrayInputStream stream = new ByteArrayInputStream(output.getBytes());   
        //Document doc = builder.parse(stream);
        // Get a list of all elements in the document.
        // Get the value of the 3rd attribute which is the connection charge.
        String attValue = XMLHelper.GetConnectionrate(output);
            System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "+ output);
        request.setAttribute("CONN_PROVIDER", connProvider);
        request.setAttribute("DEST_COUNTRY", destCountry);
        request.setAttribute("ORIGIN_COUNTRY", originCountry);
        request.setAttribute("TYPE_OF_LINE", typeOfLine);
        request.setAttribute("CALL_CHARGE", attValue);      
    %>
    <jsp:forward page="CallCharges.jsp"/>
                      
  8. Save the changes.

Creating the Enterprise Application

Make sure that you are in the Java EE perspective.

  1. In the SAP NetWeaver Developer Studio, choose Start of the navigation pathFile Next navigation step New Next navigation step ProjectEnd of the navigation path.

  2. In the wizard that appears, expand the Development Infrastructure node and choose Development Component . Choose Next .

  3. In the screen that appears, expand the J2EE node and choose Enterprise Application . Choose Next .

  4. In the screen that appears, choose the software component where you want to create the DCs. For example expand the 'Local Development' node and choose MyComponents [demo.sap.com] . Choose Next .

  5. In the screen that appears, enter ratesear in the Name field. Choose Next .

  6. Choose Next .

  7. In the New EAR Project screen select the LocalDevelopment~LocalDevelopment~ rates ~demo.sap.com checkbox. Choose Finish.

In the Project Explorer view, you should see the ratesear node.

Adding Dependency to the Enterprise Application

Make sure that you are in the Development Infrastructure perspective.

  1. In the Component Browser view, expand the MyComponents[demo.sap.com] node and choose the ratesear node.

  2. In the Component Properties view, choose the Dependencies tab.

  3. Choose the Add button and in the wizard that appears, expand the BRMS-FACADE[sap.com] node and select the tc/brms/facade checkbox. Choose Next .

  4. In the screen that appears, select the Design Time , Deploy Time , Run Time checkboxes. Choose Finish .

Creating application.xml

Make sure that you are in the Java EE perspective.

  1. In the Project Explorer view, in the context menu of the enterprise application: ratesear node and choose Java EE Tools

  2. In the menu that appears, choose Generate Deployment Descriptor Tub .

    You should see the application.xml window with the following lines:

    
    <?xml version = "1.0" encoding = "ASCII"?>
    <application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns="http://java.sun.com/xml/ns/javaee" 
     xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" version="5">
    <display-name>LocalDevelopment~LocalDevelopment~ratesear~demo.sap.com</display-name>
    <module>
         <web>
            <web-uri>demo.sap.com~rates.war</web-uri>
            <context-root>LocalDevelopment~LocalDevelopment~rates~demo.sap.com</context-root>
         </web>
    </module>
    </application>
                      

    Replace <context-root>LocalDevelopment~LocalDevelopment~buyer~demo.sap.com</context-root> with <context-root>CallCharges</context-root> .

Building and Deploying

Make sure you are in the Development Infrastructure perspective.

  1. In the Component Browser view, expand the Local Development , MyComponents[demo.sap.com] nodes and in the context menu of the rates and ratesear nodes, choose Start of the navigation pathBuild.End of the navigation path.

  2. In the dialog box that appears, choose OK .

  3. In the context menu of the ratesear node, choose Start of the navigation pathDeployEnd of the navigation path.

  4. In the dialog box that appears, choose OK .

  5. Open the Infrastructure Console , to check if the build and deploy actions have happened successfully.

Running the Web Module

  1. Open the browser and enter the Application Server Address followed by the port number and the application name: CallCharges .

  2. Enter relevant data in all available fields and choose Submit .

    The rules gest executed and you should the see the call charges based on the data you entered.

    Here is the snapshot of the web module: