Openbravo Architecture

Module: Integrating JBoss Seam and Openbravo

donderdag 5 november 2009

The Openbravo Seam module integrates Seam with Openbravo, making it possible to develop Seam applications on top of Openbravo. The OB Seam module is a special module in that it provides custom implementations of specific Openbravo core (DAL) classes. This is a good example of the extendability provided by Openbravo modularity!

The OB Seam module implements two specific Seam/Openbravo integration points:

  • Session/Transaction handling
  • User context as a Seam component.
Session/Transaction handling: Openbravo uses a so-called open-session-in-view pattern (one Hibernate session per HTTP request), while Seam mainly uses an EntityManager (is equivalent to a Hibernate session) per conversation. The OB Seam module makes it possible to use these two concepts next to eachother. Openbravo Seam automatically detects that a Hibernate session is opened as part of a Seam conversation or independently from a Seam conversation. In the latter case the session-in-view pattern is automatically applied, in the first case Seam takes care of transaction handling.

The user context as a Seam component: the module makes the OBContext object available through the OBUserContext component. The module contains an example of a Seam authenticator which authenticates a user/password against the Openbravo user database, the authenticator adds the Openbravo role in the Seam identity object.

The OB Seam module is shipped with a small example app (developed with RichFaces/JSF) which allows a user to login with his/her Openbravo account and then view the content of all tables available for the current role of the user. The user can switch role to view the content of other tables. The table view is a paging grid with a detail view.

After installing the module (read the install tips here) and starting Openbravo you can reach the example app through this url:
Make sure that the browser has enough horizontal space (the grid/detail are layed out horizontally) then login using your Openbravo login/pwd (for example: Openbravo/openbravo).

To help you getting started, there is a short developers manual available here.

The module is available through the central repository. I invite you to try it out, it should be easy to extend the example app. As always feel free to share your experience with us!

Update April 2010

To facilitate the download size, the original Seam module has been split in several modules:

  • Base Seam: the original Seam module now provides the main backend integration with Openbravo but no jsf/user interface parts.

  • Seam Richfaces: provides the JSF and Richfaces parts of Seam.

  • Seam Test: provides the Seam test environment.

Module: Openbravo JSON REST Webservice!

maandag 26 oktober 2009

As some of you may know we are currently prototyping a new user interface library. As part of the development for the new user interface we have developed a JSON REST webservice module.

This module is a very good example on how you can extend the Openbravo webservice functionality using Openbravo modularity. It shows how easy it is to extend Openbravo not only when coding your functionality but also when configuring your services (extending web.xml and other configuration files).

JSON is a light-weight data-exchange format used extensively for client-service communication in web based applications. The JSON REST module is similar to the standard Openbravo XML REST webservice in that it makes Openbravo information available through a webservice supporting CRUD operations.

The module can be downloaded from the forge here or can be installed from the central repository. After installing the module and restarting Openbravo you can try out the webservice directly. For example enter the following url in the address-bar of the browser:


This call will retrieve the Country business object with id 100 as a JSON string. You can save the returned content and open it in a text editor. The JSON will look like this:

{"_identifier":"United States","entityName":"Country","$ref":"Country\/100","id":"100","client":{"_identifier":"System","entityName":"ADClient","$ref":"ADClient\/0","id":"0","active":true},"organization":{"_identifier":"*","entityName":"Organization","$ref":"Organization\/0","id":"0","active":true},"active":true,"creationDate":"2009-10-26T19:20:06","createdBy":{"_identifier":"System","entityName":"ADUser","$ref":"ADUser\/0","id":"0","active":true},"updated":"2009-10-26T19:20:06","updatedBy":{"_identifier":"System","entityName":"ADUser","$ref":"ADUser\/0","id":"0","active":true},"name":"United States","description":"United States of America","iSOCountryCode":"US","hasRegions":true,"regionName":"State","phoneNoFormat":"Y","addressPrintFormat":"@C@, @R@ @P@","additionalPostalCode":false,"default":true,"language":{"_identifier":"English (USA)","entityName":"ADLanguage","$ref":"ADLanguage\/192","id":"192","active":true},"currency":{"_identifier":"USD","entityName":"Currency","$ref":"Currency\/100","id":"100","active":true}}

Each of the properties of the Country object is present for example. client, id, iSOCountryCode etc. Openbravo JSON REST adds some special properties: _identifier and $ref which can be useful on the client. Each foreign key reference is also represented in a special way. for example the Country refers to the English (USA) language, the reference to that language is represented like this in the JSON string:

"language":{"_identifier":"English (USA)","entityName":"ADLanguage","$ref":"ADLanguage\/192","id":"192","active":true}

the 'language' is the property of the Country then within brackets the information of the language object itself is present. Adding this information in the returned JSON string has as advantage that it is not needed to do extra requests from client to server to display all the details of the Country object (including referenced objects).

The JSON REST service also supports query and paging parameters, some examples:

See the JSON REST Developers Manual for more details on the querying capabilities and on the format of the returned information. The JSON REST module uses the same authentication and authorization functionality as the XML REST webservice functionality and the data-access-layer.

The JSON REST service also supports insert, update and removal of information. To insert a new Country you have to post a message like shown below to the Openbravo application and use the POST HTTP method. To try this directly in your browser you can make use of a Firefox plugin like poster.

{data: {"entityName":"Country","active":true,"name":"Test","description":"Test Country","iSOCountryCode":"ZZ","hasRegions":true,"regionName":"State","phoneNoFormat":"Y","addressPrintFormat":"@C@, @R@ @P@","additionalPostalCode":false,"language":{"id":"192"},"currency":{"id":"100"}}}

You see the result below. The system replies with a response JSON object which contains all the data of the inserted Country. The important one to take note of is the id.

We will be using the id in the next step to update the name of the Country to a better one (if you try this your self, the id will be for sure different!).

{data: {"entityName":"Country","id":"FF80818124923C2C0124923D39A80002","name":"My Great Test Country"}}

The response will return the complete JSON object with a status code (0 for success).

Then to clean up, let's delete the newly created country. Use this url (replacing the id part with your id) and do a DELETE HTTP method request:


A response with status 0 is returned with the deleted object as the data entry. This clean up action concludes this short tutorial. I hope you found it interesting.

As always we welcome feedback. We will be using this module as part of our new Openbravo user interface development and extend it further based on new requirements.

Selecting a new User Interface Framework/Library (comparing dojo, extjs and smartclient)

woensdag 16 september 2009

Openbravo is planning to re-design and re-implement the current user interface using both new user interface design paradigms as well as using new technology in a different architecture. The user experience re-design is being done by Rob Goris with some great results and a lot of response from the community.

On the more technical side we are currently in the process of selecting a new user interface framework/library. As many people have noted it is a difficult task to select a user interface framework. There are many good frameworks out there and also many people with strong opinions on what framework is the best. In the end of-course the main deciding factor is if a framework fits to the specific requirements of a web-based ERP.

Next to the obvious selection criteria (open-source, mature, large community, cross-browser, etc.) there are also Openbravo specific selection criteria which play a role in the process:

  • a framework should support our target architecture
  • a framework must work in a model-driven architecture with runtime re-generation of the user interface (in our new approach the user interface should be re-generated without restarting the application)
  • a framework should preferably be targeted for data-oriented web ui's (powerfull grids/forms/tabs play a vital role in these types of user interfaces).
We have decided to do this selection process in three steps:
  1. define a long list of user interface libraries
  2. select a shorter list based on specific selection criteria
  3. get the list down to a small number libraries and do a more detailed comparison and analysis
For the long list we considered a total of 22 different frameworks (see the complete list here). In the first cycle we cut down the long list to four, using these selection criteria. Based on further analysis and also some community feedback we decided on our final short list: dojo, extjs and smartclient.

At the moment we are in the last stage of the selection process and are doing a more thorough analysis of both dojo, extjs and smartclient. The process and conclusions can be found here (this page is under construction). The detailed analysis is being done by building targeted prototypes and studying available information such as the documentation, sample code, forum posts, tutorials and other information sources.

As always we are interested in your feedback. Feel free to check out this page and to give your own opinion and experience in this forum post!

Openbravo 2.50: The Developers Guide

donderdag 27 augustus 2009

Openbravo 2.50 has been released a few months ago, so some of you may have already noticed that as part of this release we created a completely new developers guide. This blog is to help spread the word even further that the developers guide is a great resource of information available for those of you who are customizing or developing on Openbravo 2.50.

The developers guide consists of different sections providing valuable information for starting developers, medium experienced as well as Openbravo expert developers. Here is an overview of these sections.

The introduction is relevant when starting development with Openbravo (see the Development Environment and Development Concepts sections) and for developers wanting to know more about the changes from 2.40 to 2.50 (see what's new and howto upgrade).

The how-to sections describe Openbravo development topics using a focused development goal. There are how-tos on modularity, extending the datamodel, adding windows and webservices, the data access layer and more.

The fundamentals and concepts chapter gives a detailed description of all relevant Openbravo ERP development concepts. The content ranges from common development topics (such as the project structure, build tasks) to modularity and the application dictionary. Each of the main layers of the application is discussed: database, middle-tier and web-tier with webservices.

The reference section consists of a detailed description of the data model from different points of view: the database model, the entity model, the hibernate mapping and the REST XML Schema. In addition javadoc and other reference-like topics are discussed in this section.

The examples section contains examples of existing code in the Openbravo ERP application. The purpose of this chapter is to give directions for the reader to study current Openbravo code and use that as the basis for own custom code

A very useful section is the tips and tricks section. The tips and tricks are based on experience and user questions and solutions in the forums.

I hope that the developers guide is useful for you as a developer. Feel free to give feedback on the guide, especially if certain parts can be improved or if you miss certain information.

Happy reading!

Openbravo 2.50: Using the Model in your Application Code

dinsdag 28 april 2009

As you may know Openbravo follows a Model-Driven-Development (MDD) approach. The main theme of MDD is generating an application from a model. An aspect which is often ignored by traditional MDD methods is the availability of the model at runtime. Openbravo specifically pays attention to the runtime model and makes it available through an easy-to-use api.

The main advantage of a runtime-model is that it is possible to develop very generic application functionality at model-level. Writing code at model-level is far more efficient than writing specific code for each table. Another advantage of model-level code is that it is often robust for model changes.

Here are some examples of generic application functionality which can make use of the runtime model:

  • security
  • import and export logic
  • archiving
  • tracking/tracing of changes
Some main concepts of the Openbravo runtime model:
  • The runtime model consists of a set of Entities.
  • An Entity is a domain concept like an Order or a Product. Currently in Openbravo an Entity is the same as a table (each table has an Entity representing it and vice versa).
  • An Entity has a list of Properties, for example an id, a name, a description. Some properties are primitives (string, number, etc.), some are single references (from an Order to a Currency), some are many references (from an Order to all its OrderLines).
To make use of the runtime model it is good to understand the Openbravo business object class model.

As you can see, each business object (order, product, etc.) inherits from the BaseOBObject class. The BaseOBObject class offers a number of important methods:
  • getEntity(): to get access to the domain concept (=table) represented by this java class
  • get(String propName): get the value of a certain property
  • set(String propName, Object value): set the value of a certain property
  • getIdentifier(): returns a readable name for the business object
So while the specific subclass has specific set and get methods for each property, the main super class has generic set and get methods to set/get the value of all properties of a business object.

In a runtime model-driven-development approach the code uses the runtime model and accesses objects as a generic BaseOBObject. In Openbravo 2.50 access to the runtime model is provided by the ModelProvider class.

I will illustrate the use of the ModelProvider class and the Openbravo runtime model in general with some example code. This sample code exports all data in an Openbravo instance in just a few lines of code, the code executes the following steps:
  1. get all Entities from the ModelProvider
  2. for each Entity get all records/instances from the databases
  3. for each instance iterate over its properties and read the property value
  4. create a string representation of that property value
// as we read all entities, be an administrator to prevent
// security exceptions

// iterate over all entities
for (Entity entity : ModelProvider.getInstance().getModel()) {

// query for all objects of the entity and iterate over them
final List businessObjects = OBDal.getInstance().createCriteria(
for (BaseOBObject businessObject : businessObjects) {

final StringBuilder line = new StringBuilder();

// place the entity name so for each line it is known what type is exported there

// and iterate over all the properties of the entity
for (Property property : entity.getProperties()) {
// ignore these type of properties, as the children are exported separately
if (property.isOneToMany()) {


// get the current value
final Object value = businessObject.get(property.getName());
// handle null
if (value == null) {
// export primitives in the same way as xml primitives
if (property.isPrimitive()) {
} else {
// export the id of a referenced business object
line.append(((BaseOBObject) value).getId());
writer.append(line + "\n");
The data is appended to the writer object (which can be a FileWriter), with the BigBazaar Openbravo sample data this results in a file of about 13mb. The XMLTypeConverter is an Openbravo class which correctly converts primitive types such as a Date, a number, etc. to a String.

You can copy the above code directly in a test case and run it (set the writer and SEPARATOR variables). For how-to create a test case in Openbravo see this how-to.

An additional nice feature of the Openbravo runtime model is that all tables added by modules are automatically made part of the runtime model. So for Openbravo in the runtime model, there is no difference between an Openbravo core Entity/table or a custom module table/Entity.

The runtime model is used extensively by the Data Access Layer and REST web services.

Well I hope that this blog gives some inspiration to try out coding at model level and to make use of the Openbravo runtime model. Thanks for reading, and feel free to ask any (detailed) questions on the Openbravo deverlopers forum!

Openbravo 2.50: REST Webservices

maandag 2 maart 2009

In this post I will talk about new very exciting functionality in Openbravo 2.50: full REST web services support for all tables in the Openbravo datamodel (including the tables added by modules).

I will first start with a general overview and then some examples of web service calls which you can try directly in your browser. The post is concluded with a short description on how to add your own REST-like web services and a number of interesting links on REST.

Openbravo REST provides a CRUD-like interface so that external applications can retrieve, update, create and delete business objects through standard HTTP requests.

Some benefits of using a REST approach:

  • favors identifying and addressing resources which fits to the data-centric nature of the provided apis (a resource corresponds to a business object)
  • has actions (POST, PUT, DELETE, GET) which correspond to standard CRUD actions
  • allows linking to specific business objects or to sets of business objects. This is a very powerfull feature of a REST approach and it allows for easy navigation between business objects.
  • is simple to develop and use, and very lightweight from an architectural point of view
The Openbravo REST webservice operates on Business Objects in Openbravo. Before continuing let's first explain what a Business Object is (in Openbravo). A business object can be a simple entity (==table) such as a currency which just has basic primitive fields. On the other hand it can also be a structure of entities, for example an order header with its order line.

Openbravo REST web services provide the following functionality:
  • retrieve a single business object or a list of business objects using a standard HTTP GET request
  • querying, filtering, paging and sorting of lists of business objects, again through standard HTTP requests
  • update of an existing business object or multiple business objects through XML and a HTTP POST or PUT operation
  • creation of new business objects through a POST/PUT operation
  • export and import of data: xml files which contain a mix of different types of business objects and a mix of new and existing business object
  • delete operation using either a url pointing to a specific business object which needs to be removed or a XML document which contains business objects (as full xml or as partial xml) which need to be removed.
This functionality can be used for standard integration scenario's, but it can also be used to develop another UI on top of Openbravo using an alternative UI-technology (e.g. Flex).

The Openbravo REST web services use the same access/authorizations as the standard Openbravo application. Before calling a web service the caller must log in. The login functionality is provided by the Openbravo REST framework. All REST actions are then executed in the context of a client/organization and current role of the user.

Now let's go to some examples. When you have Openbravo running then you can try these out directly in your browser by entering the urls in your browser's address bar. Note that the examples assume that Openbravo runs locally on port 8080, it maybe necessary to replace the localhost:8080 part with your own server name/port. The examples assume that the web service user has access to the Country and Currency tables.
  • Query for all Countries:
  • Get a specific Country (in this case Spain):

Note that the xml returned contains both the Country and its children (Regions), i.e. a business object structure.
  • An ordered example, query for all countries and return them ordered by ibanCode and regionName:
  • The same example with paging, returns 10 Countries starting from the 19th:
  • Do some filtering, only return countries which have a Currency with id 102 and a iBANLength of minimum 23:
http://localhost:8080/openbravo/ws/dal/Country?where=currency='102' and iBANLength>=23

(the where parameter can contain a Hibernate Query Language where clause)

After trying some examples, the next question is which web services are provided by Openbravo, i.e. what url's are valid, what are the entity names and XML property names, what is valid xml? To answer this question Openbravo REST has a special web service which can be called. This web service generates a XML Schema of the available business objects and their elements (including the tables added by custom/external modules). You can try it yourselve on your local running Openbravo instance:

These first examples only retrieved data. The REST web services also have update/create/delete functions. To support web service testing, Firefox has a nice add-on: Poster. This add-on allows you to POST/PUT XML to a URL. For these examples I again assume that you have Openbravo running locally. I will be creating a new currency, updating its precision and then deleting the currency.

Here is an example of xml which can be used to create a new Currency:

<?xml version="1.0" encoding="UTF-8"?>
<ob:Openbravo xmlns:ob="">
<description>Openbravo Dollars</description>

You can easily create this xml by retrieving a Currency through a url (for example, the euro) and then removing the XML parts related to id, client/organization and audit info.

Click on the Poster icon (right-bottom in Firefox) and set the options as displayed in the image below.

Note that the xml (displayed above) is entered in the Content field, the Action is set to POST and the User Auth. fields contain the login and password. The user must have permissions to create a Currency. The standard Openbravo demo user has these capabilities.

Then click on the first GO button, you should be seeing the following result:

This xml gives a success message but more importantly it also gives the id back of the newly created object. This allows software, making REST calls, to use this id in further processing. In our case we can use this id to check if the currency was indeed created (note replace the id in the url with the id you received back):

Now as a next step let's update a field of the new Currency, in this case the precision is changed. The image below shows how this is done. The xml only has the field which needs to be updated and the id of the Currency is present as an xml attribute (to try-this-at-home, replace the id value with the one created in your case).

And to clean up let's delete the new currency. This is done with a DELETE action, the url of the action needs to point to the business object which needs to be deleted (in this case the Currency created above).

The above actions can be performed for all of the 425+ tables in Openbravo. More importantly REST webservices automatically work out-of-the-box also for new tables added by modules.

The delete action concludes the quick overview of the capabilities of Openbravo REST Webservices. The overview hopefully showed how easy it is to use REST webservices. Software talking to REST webservices need basic xml processing capabilities but that's the only real prerequisite.

The Openbravo REST framework can be extended with new Webservices. See here for more information. Openbravo REST takes care of security and exception handling. Web services can be added (installed/uninstalled) as part of a module.

For more information:
  • REST Webservice Technical Design
  • REST test cases can be found in the openbravo development project in the src-test folder and then in the org.openbravo.test.webservice package
Here are some other interesting (non-Openbravo) links:

Some links related to REST versus SOAP, there is a fair amount of articles on the web on this topic:

Openbravo 2.50: Data Access Layer in the overall Openbravo Architecture

donderdag 8 januari 2009

This post discusses the architecture of the new Data Access Layer and its place in the rest of the current and future envisioned architecture.

The image below illustrates the different layers of the Openbravo architecture. Part of the architecture is delivered in 2.50 other parts will be delivered in future releases.

The Data Access Layer (DAL) uses the application dictionary as the basis for its operations. The application dictionary defines the tables, columns and data types in Openbravo (for example Business Partner, Sales Order, etc.). The Data Access Layer uses the application dictionary for two purposes:

  • to generate Java business objects at development time
  • at runtime to generate a Hibernate mapping to persist the business objects
To perform these two steps the DAL reads the application dictionary from the database and builds an in-memory representation. This is called the runtime model. Having the model in-memory makes it possible to use the model in an efficient way for different kinds of tasks (security checking, validation, etc.)

So at development time Java business objects are generated for each table in the system. The columns of the table corresponds to properties (getters/setters) in the generated Java class. The foreign key columns are present as references to other generated business objects. The business object generation is done as part of the standard Openbravo build steps. The generated classes can be found in the src-gen folder in the openbravo development project.

At runtime the DAL is responsible for generating the mapping for Hibernate and configuring Hibernate.
The DAL provides an API to store, query and remove business objects from the database. This DAL service layer takes care of validation and security checks. In a future Openbravo release this API will be used to develop the business logic layer. The business logic layer will replace the current stored procedures and triggers. The business service layer will provide an API to the outside world to run business logic within Openbravo.

Two other interesting components are also present: UI and Web Services. Integrating the DAL into the UI will be done in a future release. In 2.50 we provide a REST webservice layer which provides CRUD operations on all Openbravo business objects. I will discuss the REST Webservice support in the next post.

At runtime the DAL takes care of transaction handling and providing a context in which all DAL operations run. The transaction handling is done using the open-session-in-view pattern whereby the developer in general does not need to take care of transaction handling explicitly (but he/she can ofcourse when required). The Openbravo context object makes it easy for a developer to retrieve the current user object and other context information.

The following parts of the new architecture are delivered as part of 2.50:
  • Runtime Model
  • Generation of Business Object and Hibernate Mapping
  • REST Webservices
  • Transaction Handling and User Context
The other components will be delivered as part of subsequent releases.

For more information here are two wiki documents which give some more details:
This hopefully gives a feel for the overall current and future architecture of Openbravo. In the next blog post I will discuss the new REST Webservice functionality in Openbravo 2.50.

Openbravo 2.50: New Architectural Developments: Data Access Layer and REST Webservices

maandag 5 januari 2009

The Openbravo 2.50 release contains a number of new architectural developments which can be of great interest for Openbravo developers and system integrators.

The first main development is the Data Access Layer which provides the application developer with an object-oriented view on the Openbravo database. The Data Access Layer is also used to support new XML conversion functionality which allows the application developer to convert business objects from and to XML. The XML conversion logic again forms the basis for export and import of Client data and new REST webservices functionality provided in Openbravo 2.50.

I will cover these new developments in a series of posts which will be published the coming weeks.

In this first post for Openbravo, let me also introduce myself. I am responsible for some of the new architecture developments at Openbravo, both design and development. My background is both in ERP system as well as technical Java coding. Next to Openbravo I am involved in open source development as a committer of the Eclipse Modeling Framework project. I am looking forward to work further on extending the Openbravo architecture and hope for extensive feedback from the community on the new developments in the Openbravo 2.50 release.

The starting point for the blog series will be the new Data Access Layer (DAL). The DAL provides an object-oriented layer over the Openbravo database. It is based on Hibernate using model-driven code generation techniques. The Data Access Layer provides the application developer with the following functionality:

  • type safe querying and retrieval of business objects from the database.
  • a convenient API to update or create new data in the database.
  • a type safe interface to update information of a business object, increased productivity by making the properties of a business object directly visible through getters and setters (in the development environment).
  • transaction and context handling.
  • security and validation checking.
  • automatically maps new entries in the application dictionary to database tables and columns.
  • generates Java class business objects (and their associations) on the basis of the Application Dictionary model.

With the DAL the application developer does not need to type in tedious/type-unsafe sql queries. He/she can make use of the code completion and compile time checking functionality of his/her development environment. The Data Access Layer can also be easily integrated in test driven development approach as it operates independent from servlet containers such as Tomcat.

The Data Access Layer uses an in-memory representation of the application dictionary (the runtime model). This runtime model is used to convert business objects from and to XML. The XML conversion functionality is very usefull for integration scenarios. It is the basis for new functions such as the export and import of Client data and Webservice functionality. The XML Conversion functionality will be discussed in a separate technical post.

The 2.50 release also provides completely new REST webservice functionality. The REST webservice offers a common APO to query, retrieve and update all Openbravo business objects (persisted in the database). The REST webservice can be reached using simple (REST) URI's making it easy to use, test and try out. The Openbravo REST framework is easy to extend and allows you to add your own (REST) webservices. I will spend a separate post on REST Webservices and how to create your own WebService.

This post was just an introduction to give you a feel for what is coming in 2.50. The next posts will dive into more details, starting with an architecture description followed by the standard Hello World DAL example!