Ofbiz Soap Rmi Tutorial
Ofbiz Soap Rmi Tutorial
Ofbiz Soap Rmi Tutorial
Table of contents
1 2 3 4 5 6 7 8 9
About this document.................................................................................................... 2 Introduction.................................................................................................................. 2 Defining the data model............................................................................................... 2 Populating the database tables with Seed Data............................................................ 6 Creating Business Logic...............................................................................................7 Creating the Web Application.................................................................................... 11 Accessing the services of OFBiz via RMI................................................................. 11 Accessing the services of OFBiz via SOAP...............................................................13 Testing the service of OFBiz that wraps a remote Web Service................................15
A Sample OFBiz application implementing remote access via RMI and SOAP
2. Introduction
This tutorial describes how to build a complete application using OFBiz and how to access this application directly via RMI and SOAP over HTTP. It is entirely based on Hello3 tutorial from Open Source Strategies Inc. you may found at this url http://www.opensourcestrategies.com/ofbiz/hello_world3.php, it reproduces some parts of it, modifies some other ones or extends them when necessary. Before starting you should have downloaded: The extended hello3 application (deploy it under <ofbiz_base>/hot-deploy after having unzipped it) The script bshcontainer.bsh (deploy under <ofbiz_base>) The test client RMI (deploy where you want) The test client SOAP (deploy where you want) The new OFBiz class SOAPClientEngine modified in order to make the invocation of a remote Web Service working (you should replace the old one and compile OFBiz) It could be necessary to adjust the scripts used to compile in order to set the proper classpaths.
Warning:
You are supposed to know at least the basics of OFBiz before reading this tutorial. Some of them could be found as well on the Open Source Strategies web site. In addition some information about Web Services and RMI could be useful.
Page 2/15
A Sample OFBiz application implementing remote access via RMI and SOAP
lookup all the hobbies of a person (or, alternatively, all the people who share a hobby.) The data model thus calls for person, hobby, and person-hobby linkage. With a relational database, you would define two tables, one for a person and one for a hobby, and link them together with a third table. The third table would allow you to associate as many hobbies as you would want with a person, and vice versa. You would define foreign-keys to constrain the third table so only actual persons and hobbies are present. The following picture shows the ER diagram for such tables.
ER diagram Note that you do not need to create those tables in your database manually, OFBiz will take care of that automatically, this will be clarified later. OFBiz works similarly. You would define two entities, which we will call HelloPerson and HelloHobby, and a linking entity, HelloPersonHobby, and establish a relationship between them. The relationship serve as foreign-key constraints but also allow you to go from one entity to another without having to remember yourself what their respective keys are (or change your code when keys change.) To define data models, go to the entitydef/ directory inside your application (hello3/ in this case) and locate the files entitymodel.xml and entitygroup.xml inside your entitydef/ directory. Let's have a look at entitymodel.xml first:
Page 3/15
A Sample OFBiz application implementing remote access via RMI and SOAP
snippet from entitymodel.xml Just a few words about the entity definition. HelloPerson and HelloHobby each has a primary key, and HelloPersonHobby has two primary key fields, which it uses to link HelloPerson and HelloHobby. It is considered good practice to give your relations a foreign key name to make debugging easier and avoid accidental collision of foreign key names OFBiz generates for you. There is an implicit rule linking database objects (such as table names and column names) with entity definition (entity names and field names). In particular:
entity element entity name rule similar to Java class names: all words starting with capital letters including the first one. The corresponding database table name is lowercase and uses the separator "_" example the entity name "HelloPerson" is mapped to a database table with name "hello_person".
Page 4/15
A Sample OFBiz application implementing remote access via RMI and SOAP
(underscore). entity fields similar to Java methods: all words starting with capital letters except for the first one. The corresponding database field name is lowercase and uses the separator "_" (underscore). the field name "helloPersonId" is mapped to a database field with name "hello_person_id".
The data type is defined by the attribute "type" in the tag "field". This data type is abstract and should be translated into a real data type that is database specific. This translation is done in particular in the files fieldtype<database_name>.xml contained in the directory <ofbiz_base>/framework/entity/fieldtype. Now the file entitygroup.xml
snippet from entitigroup.xml The main issue with this file id the "group" attribute. It is important in order to identify the database to be used. Have a look at the file entityengine.xml you may find under <ofbiz_base>/framework/entity/config, you will see that each dispatcher (OFBiz object used to access a data source) has a corresponding group-name attribute that should match the one defined in entitygroup.xml. This group-name points to a real data source configured in the same file entityengine.xml. Once the data source is identified per each entity by using this mechanism, it is also possible to select the right data types through the entity definition and the translation rules for the fieldtypes. (described above). Now start OFBiz. You will see the following lines in your console.log (Linux) or roll past you on your console (Windows), telling you that your entities were loaded:
.... 2391 [ UtilXml.java:263:DEBUG] XML Read 0.0s: D:/ofbiz_work/hot-deploy/hello3/entitydef/entitymodel.xml .... 2719 [ UtilXml.java:263:DEBUG] XML Read 0.0s: D:/ofbiz_work/hot-deploy/hello3/entitydef/entitygroup.xml ....
When you go into Web Tools application, you will see the entities:
Page 5/15
A Sample OFBiz application implementing remote access via RMI and SOAP
entities in Web Tools The tables have been automatically created on your database by OFBiz, including the foreign keys.
snippet from HobbiesData.xml seed file The content of the file is auto-explaining. Now you are ready to load your seed data. Go to the Web Tools application's "Main" screen, and you will see links for "XML Import". Click on "XML Import" and on the next screen, it will prompt you for the name of your file, relative to your ofbiz/ directory. I usually don't click on any of the optional check boxes and just "Import". If you are
Page 6/15
A Sample OFBiz application implementing remote access via RMI and SOAP
successful, the same screen will come back and tell you at the bottom how many values were added.
Note:
More details about this phase on the tutorial by Open Source Strategies.
Page 7/15
A Sample OFBiz application implementing remote access via RMI and SOAP
content of services.xml Three services are defined here, here are some explanations: createHelloPerson: this service is implemented through a Java class (engine="java"), the class and the method to call are defined via the attributes location="org.ofbiz.hello3.Hello3Services" and invoke="createHelloPerson". The service can be also accessed externally, via RMI or SOAP for instance, since export="true". The service has one output parameter called "helloPersonId" of type String that is mandatory. The automatic mapping of all the input parameters to the fields of the entity "HelloPerson" has been adopted, all output parameters are optional. searchHelloPerson: this service is implemented through a Java class (engine="java"), the class and the method to call are defined via the attributes location="org.ofbiz.hello3.Hello3Services" and invoke="searchHelloPerson". The service can be also accessed externally since export="true". The service has one input parameter called "helloPersonId" of type String that is optional. The service has three output parameters called "helloPersonIdOut", "firstName" and "lastName", two of them are optional. Note that the automatic mapping of all the output parameters has been disabled since I've had some problems when accessing externally via SOAP wrapper. BabelFishService: this service is implemented through a SOAP engine (engine="soap"), it wraps the remote Web Service BabelFish (invoke="BabelFish") available over the Internet and reachable at the endpoint location="http://services.xmethods.net:80/perl/soaplite.cgi". You can get the WSDL at this url "http://www.xmethods.net/sd/2001/BabelFishService.wsdl". In this way you can access this service as you can do with all other OFBiz services, all the implementation details about the SOAP connection and remote invocation are done by OFBiz automatically. More details on ithis service in a dedicated section of this document : "Testing the service of OFBiz that wraps a remote Web Service".
Note:
There is also another service developed via minilang (createHelloPersonHobby) that is not documented here, see the tutorial by Open Source Strategies to get details on it.
You would also need to reference the service resource in your ofbiz-component.xml as well. In addition, you must create <classpath> directives in ofbiz-component.xml to tell it where to load up the apps. Have a look at the config file. Now to create the services. A Java service goes inside a src/ directory in your application and is written in a standard fashion: A public class with public static methods which take two parameters, a DispatchContext for getting objects like delegators, dispatchers, locale, and security, and a Map called context which are your input parameters and returns a map of results:
Page 8/15
A Sample OFBiz application implementing remote access via RMI and SOAP
implementation of the service createHelloPerson The service creates a new record in the entity HelloPerson, the primary key is auto-generate via a sequence, all other fields are directly taken from the input parameters. Take your time to learn how to interact with entities, load input parameters from the context and return output values. The next picture shows the implementation of the service searchHelloPerson:
Page 9/15
A Sample OFBiz application implementing remote access via RMI and SOAP
implementation of the service searchHelloPerson The service queries the entity HelloPerson trying to get a record where the primary key field is equal to the input parameter "helloPersonId". If that is successful, then it returns also the firstName and lastName, otherwise only the helloPersonIdOut is returned. Java services will also need to be compiled, with knowledge of the proper classpaths for other OFBiz apps. This involves using ant and a build.xml build script, which you can usually copy over from another application. Simply launch ant from the directory hello3 to compile the application. Finally, to test it, re-start OFBiz to load all the new definitions in ofbiz-component.xml and services.xml. Then, open a beanshell window (that is connect via telnet to the port 9990 on you host) and test our service:
Page 10/15
A Sample OFBiz application implementing remote access via RMI and SOAP
trying to test our services Here, beanshell calls the service dispatcher to run the service, and they were successful, so the right values are created. Note that you need to start the script bshcontainer.bsh to have a dispatcher, a delegator and the utility UtilMisc. In the example above, the services are invoked through the method runSync of the dispatcher object.
Page 11/15
A Sample OFBiz application implementing remote access via RMI and SOAP
disabling SSL in rmi dispatcher The modification is necessary since the certificate server side is expired (at least in my OFBiz distribution) and I do not want to generate a new one, it is only a test application. Now everything is ready and we just have to write a test client java class.
Page 12/15
A Sample OFBiz application implementing remote access via RMI and SOAP
code snippet of the test client class The code is very simple, after having received the remote handler for the rmi dispatcher, it is just needed to invoke the runSync method on it, exactly as it was done during the tests via bsh shell.
Note:
It seems that there is a problem with the RMI dispatcher if you are running OFBiz within eclipse development environment. In case of a trouble simply do not use it.
Page 13/15
A Sample OFBiz application implementing remote access via RMI and SOAP
code snippet of the test client class Some comments... The port I am using (18080) is not the default one (8080), this is due to the fact that I trace the TCP traffic via the TCP monitor bundled with axis. Naming the parameters is normally not needed with axis, the input parameters are automatically named arg0, arg1, arg2 and so on. But these default names are not known by the service implemented in OFBiz, therefore the service invocation isn't successful since the validation phase could not be passed. The method addParameter is used to name the parameters (it just necessary to name all input parameters) according to the service definition. In case there are more than one output parameters, the first one is got as returned value from the call.invoke(..) and the other ones via the call.getOutputParameters() method. This is quite strange for me but it is exactly how axis 1.4 works and it seems not to be a bug. It is possible to retrieve the output parameters either by name or by position. The code snippet shown above displays only the first method, the code of the extended hello3 application uses both methods.
Page 14/15
A Sample OFBiz application implementing remote access via RMI and SOAP
Then you should modify the class org.ofbiz.service.engine.SOAPClientEngine in order to avoid to use the method call.setOperation (well, at least this is what i've done to make it working, even if maybe it is not the best way to proceed). The modified class SOAPClientEngine is in the files attached to this document.
make a telnet connection to your host on the port 9990 and invoke the service:
BeanShell 1.3a1 - by Pat Niemeyer ([email protected]) bsh % source("bshcontainer.bsh"); bsh % result = dispatcher.runSync("BabelFishService",UtilMisc.toMap("translationmode", "en_fr","sourcedate","I am")); bsh % print(result); [return=je suis ] bsh %
Page 15/15