Developing Web
Applications Part 2 – Externalizing Business Logic |
||
Step 11. Creating Remote Greeting Service
Step 13. Run Application in Hosted Mode
Step 15. Moving Business Logic to OpenRules
In the Part 1 we have created a working GWT application that enters customer data and generates a simple greeting. While the application uses only simple greeting rules hardcoded directly in the GWT composite Hello.java, the whole setup works. Now we are ready to add real functionality. First we will create a remote greeting service in Java with still simple greeting rules. Secondary, we will externalize these rules into OpenRules-based Excel tables allowing them to be executed on the server side using OpenRulesEngine. Then we will make our business logic (greeting rules) much more complex without changing Java code. The final application will use OpenRules in both host and web modes.
Step 11 – Creating Remote Greeting Service ►top
Let's copy our Part 1 Eclipse project HelloGWT to a new Eclipse project HelloGWTOpenRules that will gradually support an OpenRules-based remote greeting service. GWT Designer provides a wizard for creating remote services. Select the client package com.openrules.gwt.client and select the Designer toolbar button and select GWT > GWT Remote Service from the pull-down menu:
and type GreetingService as a name of the new remote service:
The GWT Designer will add two new classes to the package com.openrules.gwt.client:
GreetingService.java - an initial RemoteService interface
GreetingServiceAsync.java - facilitates communication with the server.
and one new class to the package com.openrules.gwt.server:
GreetingServiceImpl.java - implements the actual service logic.
The GWT Designer also added the remote path description
<servlet path="/GreetingService" class="com.openrules.gwt.server.GreetingServiceImpl"/>
to the module XML file src\com\openrules\gwt\HelloGWT.gwt.xml.
The GWT Designer will keep all these files synchronized, e.g. adding a method to the remote service interface class will automatically add the appropriate method to the matching *Async and *Impl classes.
We want to pass to our remote greeting service a customer and receive back a greeting for this customer at this particular time of day. Thus, we will add only one method "getGreeting" to the automatically created interface GreetingService.java:
src/com/openrules/gwt/client/GreetingService.java |
package com.openrules.gwt.client; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.rpc.RemoteService; import com.google.gwt.user.client.rpc.ServiceDefTarget; public interface GreetingService extends RemoteService {
} |
When we save the changes in the file GreetingService.java, this method will be automatically added to the files GreetingServiceAsync.java and GreetingServiceImpl.java. Before we start adding an actual greeting rules implementation in the file GreetingServiceImpl.java we have to take care of the important GWT convention that states: Java objects passed between client and server must be marked as serializable via the GWT IsSerializable interface. Thus, we have to add the clause "implements IsSerializable" to our class Customer.java:
HelloGWTOpenRules/src/com/openrules/gwt/client/Customer.java |
package com.openrules.gwt.client; import com.google.gwt.user.client.rpc.IsSerializable;public class Customer implements IsSerializable { String name; String maritalStatus; String gender; int age; ..... } |
Step 12 – Moving Business Logic from GUI to Remote Service ►top
In Part 1 we placed greeting rules into the file Hello.java that implements the GWT user interface. Now we will move greeting rules from the client-based Hello.java to our server-based greeting service implementation GreetingServiceImpl.java:
HelloGWTOpenRules/src/com/openrules/gwt/server/GreetingServiceImpl.java |
package com.openrules.gwt.server; import com.openrules.gwt.client.Customer; import com.openrules.gwt.client.GreetingService; import com.google.gwt.user.server.rpc.RemoteServiceServlet; public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService { public String getGreeting(Customer customer) { /* * Greeting generation rules */ String salutation = "?"; if (customer.getGender().equals("Male")) salutation = "Mr."; else { if (customer.getMaritalStatus().equals("Single")) salutation = "Ms."; else salutation = "Mrs."; } return "Hello " + salutation + customer.getName() + "!"; } } |
And we have to modify the user interface Hello.java so when the user clicks on the Generate Greeting button the interface will invoke our remote service to produce the proper greeting. To do that we will add the call of the remote service instead of rules into the listener for our Generate Greeting button:
HelloGWTOpenRules/src/com/openrules/gwt/client/Hello.java |
... generateGreetingButton.addClickListener(new ClickListener() { public void onClick(final Widget sender) { customer.setName(textBoxName.getText()); customer.setAge(Integer.parseInt(textBoxAge.getText())); String gender = (maleRadioButton.isChecked()) ? "Male" : "Female"; customer.setGender(gender); int selectedIndex = listBoxMaritalStatus.getSelectedIndex(); String maritalStatus = listBoxMaritalStatus.getItemText(selectedIndex); customer.setMaritalStatus(maritalStatus); /* * execute remote GreetingService */ AsyncCallback callback = new AsyncCallback() { public void onSuccess(Object result) { textBoxGeneratedGreeting.setText((String) result); } public void onFailure(Throwable ex) { } };
GreetingService.Util.getInstance().getGreeting(customer,
callback); |
Now we are ready to run the application in hosted mode.
Step 13 – Run Remote Service in Hosted Mode ►top
In the Eclipse Package explorer,
right-click the HelloGWT.java and select
Run As > GWT Application.
This will create a launch configuration and run the application locally.
Click on the Generate Greeting
button.
While now we use a remote service the results are identical to those in the Part 1.
Step 14 – Deploy and Run Remote Service in Web Mode ►top
Right click on HelloGWT.java and select Google Web Toolkit > Deploy module. Specify the server deployment options as follows:
Click OK to complete the deployment of our remote service on Tomcat as HelloGWTOpenRules.war.
Now you may start/restart
your Tomcat server. To run the
application deployed on the Tomcat, slightly modify the file run.html
using the new path HelloGWTOpenRules:
HelloGWTOpenRules/run.html |
<h2> Deployed GWT-OpenRules Application </h2> <h3> http://localhost:8080/HelloGWTOpenRules/HelloGWT.html</h3> <a href="http://localhost:8080/HelloGWTOpenRules/HelloGWT.html"> Run</a> |
Double-click on the run.html to launch your application in the web mode. The results will be again identical to the web mode results from the Part 1.
Step 15 – Moving Business Logic to OpenRules ►top
The greeting rules above deal only with customer's gender and marital status and produced only salutation like "Mr." or "Mrs.". We want to create a more sophisticated greeting service that could generate a personalized greeting for any Customer based on time of the day and customer's attributes, and most importantly it should be extracted form the code to be managed by business analysts (not programmers). To achieve this we will externalize business logic from Java to OpenRules business rules.
We will start with the greeting rules themselves. OpenRules provides similar greeting rules with many standard examples for different environments - see for example the basic project HelloJava. For simplicity, we will place all rules inside one Excel file HelloCustomer.xls. We will place this file inside HelloGWTOpenRules/src/com/openrules/gwt/public (while any other folder could be selected).
We will create the following tables inside this
file:
Rules void defineGreeting(int hour, Response response) | ||
C1 | C2 | A1 |
min <= hour | hour <= max | response.map.put("greeting", greeting); |
int min | int max | String greeting |
Hour From | Hour To | Set Greeting |
0 | 11 | Good Morning |
12 | 17 | Good Afternoon |
18 | 22 | Good Evening |
23 | 24 | Good Night |
Rules void defineSalutation(Customer customer, Response response) | |||
C1 | C2 | C3 | A1 |
customer.gender.equals(gender) | customer.maritalStatus.equals(status) | customer.age < age | response.map.put("salutation",salutation); |
String gender | String status | int age | String salutation |
Gender | Marital Status | Age Less Than | Set Salutation |
Male | Mr. | ||
Female | Married | Mrs. | |
Female | Single | Ms. | |
Male | <5 | Little |
We will use the method "helloCustomer" as the main method that will be called from the OpenRulesEngine:
Method String helloCustomer(Customer customer, Response response) |
int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); defineGreeting(hour, response); defineSalutation(customer,response); String result = response.map.get("greeting") + ", " + response.map.get("salutation") + " " + customer.name + "!"; return result; |
This method that will find out the current time, execute rules "defineGreeting" and "defineSalutation", and will return a ready-to-go greeting.
To make sure that our rules inside this Excel
file "understand" our Java classes Customer and Response from the
package "hello", we should add the following Environment table:
Environment | |
import.java | com.openrules.gwt.client.Customer |
com.openrules.gwt.server.Response |
Our rules use two parameters "customer" and "response". The second parameter of
the type Response is used to demonstrate how to pass back more information from
OpenRules. Here is the code for the class Response needed only on the server
side:
HelloGWTOpenRules/src/com/openrules/gwt/server/Response.java |
package com.openrules.gwt.server; import java.util.HashMap; public class Response extends HashMap { } |
Now we will make our project to be dependent on OpenRules. In Eclipse we will open the properties of the project HelloGWTOpenRules and add "openrules.config" to the Java build path.
To complete the integration, we have to replace old rules inside GreetingServiceImpl.java to an execution of a preliminary created OpenRulesEngine:
HelloGWTOpenRules/src/com/openrules/gwt/server/GreetingServiceImpl.java |
package com.openrules.gwt.server; import com.openrules.gwt.client.Customer; import com.openrules.gwt.client.GreetingService; import com.google.gwt.user.server.rpc.RemoteServiceServlet; public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService { OpenRulesEngine ruleEngine = null; static String filename = "file:./webapps/HelloGWTOpenRules/HelloCustomer.xls"; // for WEB MODE//static String filename = "file:./src/com/openrules/gwt/public/HelloCustomer.xls"; // for HOST MODE public String getGreeting(Customer customer) { |
The OpenRulesEngine will be created upon the first execution of the remote method getGreeting. The OpenRulesEngine has to know the location of the main Excel file "HelloCustomer.xls" that is different for different execution modes:
Web mode: file:./webapps/HelloGWTOpenRules/HelloCustomer.xls
Host mode: file:./src/com/openrules/gwt/public/HelloCustomer.xls
In the code above we use the web mode (the host mode is commented out).
To deploy our modified service at the Tomcat follow the same steps as at the Step 14 above. Right click on HelloGWT.java and select Google Web Toolkit > Deploy module. Double-click on the run.html to launch your application in the web mode with OpenRulesEngine executing the Excel-based business rules:
To run in the host mode switch the execution mode do the following:
change comments for the filename in the GreetingServiceImpl.java
save
right-click to HelloGWT and Run As GWT Application.
Thus, our OpenRules-based remote service works with our GWT greeting application. Much more complex applications with GWT-based GUI and OpenRules-based server could be developed in a similar way.
Summary ►top
We created a remote service for the GWT application from the Part 1
We define more sophisticated greeting rules in Excel using OpenRules decision tables.
We deployed and executed the GWT Greeting Application in both web and host modes with OpenRules taking care about business logic.
Copyright © 2008, OpenRules, Inc.