Java Wrapper for OFBiz Services

From Opentaps Wiki
Jump to navigationJump to search

Starting with opentaps 1.4 (after preview 2), opentaps will provide Java objects as wrappers for services defined with the ofbiz service engine, including both ofbiz and legacy opentaps services. These "service wrapper POJOs" are automatically generated along with the base entity classes using ant make-base-entities.

These service wrappers can be used instead of raw Maps to set or get the service parameters in a type-safe way. The POJOs are in package and named after the original service definition (converted to a valid java class name.) For example: createInventoryItem is CreateInventoryItemService, opentaps.runMrp is OpentapsRunMrpService.

The main benefit is that each parameter is guaranteed to exist and be of the correct type by the compiler. This makes code maintenance much easier if the service definitions are changed. In addition, an IDE such as Eclipse can help discover the service parameters via autocompletion. If a service is defined multiple time the wrapper class reflects the actual service definition as seen by the service engine.

Calling a service

For example if there is a service named example with inputs: a String partyId and a BigDecimal amount, and output partyId:

  ExampleService service = new ExampleService();
  service.setInAmount(new BigDecimal("40.0"));
  // if the service requires authentication you can either use a User instance
  service.setUser(someUser); // note that this is not setInUser since "user" is not really a defined IN parameter of the service
  // or a GenericValue userLogin instance
  // calling the service requires an Infrastructure instance
  // or it is also possible to specify that a new transaction is not necessary
  // getting the service results parameters and status
  if (service.isSuccess()) {
      String exampleOutput = service.getOutPartyId();
  } else if (service.isError()) {
      // getting the service error message
      Debug.logError(service.getErrorMessage(), MODULE);

Calling a service from inside a POJO service can be done using the runSync helper method provided by the Service class:

  ExampleService service = new ExampleService();
  service.setInAmount(new BigDecimal("40.0"));
  // this helper method will auto set the current User and Infrastructure
  // and also avoids creating a new transaction
  // on service error, a ServiceException is thrown so there is no need to test for
  // the status in most cases
  // at this point the service must have succeeded
  String exampleOutput = service.getOutPartyId();

Using the wrapper inside its service definition

The wrappers can also be used inside the service definition method to read the inputs. Following the same example as above:

  public static Map<String, Object> exampleServiceImplementation(DispatchContext dctx, Map<String, Object> context) {
      ExampleService service = ExampleService.fromInput(context);
      String partyId = service.getInPartyId();
      BigDecimal amount = service.getInAmount();
      // internal parameters are also available
      Locale locale = service.getInLocale();
      TimeZone timezone = service.getInTimeZone();
      // the user is available both as a GenericValue and a User instance
      GenericValue userLogin = service.getInUserLogin();
      User user = service.getUser(); // note that this is not getInUser since "user" is not really a defined IN parameter of the service
      String resultPartyId = "resultPartyId"; // the actual service implementation
      // then out parameter can be set in the same wrapper instance
      service.putAllOutput(ServiceUtil.returnSuccess()); // all the methods from ServiceUtil or UtilMessage normally used 
                                                         // to build the output map can be used here, for success / error or failure
      return service.outputMap();

Static fields

In addition to the accessors to get or set the inputs or outputs parameters, each wrapper defines an In and Out static enum. Following the example from above, you may also refer to the service parameters like this:

  Map<String, Object> input = UtilMisc.toMap(
     ExampleService.In.partyId.getName(), "somePartyId",
     ExampleService.In.amount.getName(), new BigDecimal("40.0"),
     ExampleService.In.userLogin.getName(), someUserLogin);
  Map<String, Object> output = dispatcher.runSync(ExampleService.NAME, input);
  String partyId = (String) mapValue.get(ExampleService.Out.partyId.getName());

Changes in 1.4 preview 3

Note that from opentaps 1.4 preview 3 and later, the java package has been changed from to