View source | Discuss this page | Page history | Printable version   

ERP 2.50:Developers Guide/Examples/SOAP WebService

ERP 2.50:Developers Guide

Index


Contents

Introduction

The way to interact from an external application with Openbravo ERP is through WebServices. Openbravo provides a set of services that allows you to perform actions such as: Query Business Partner information, upload orders, etc. This methods are exposed as SOAP WebServices.

SOAP is a lightweight protocol for exchanging structured information in a decentralized, distributed environment. It is an XML based protocol that consists of three parts: an envelope that defines a framework for describing what is in a message and how to process it, a set of encoding rules for expressing instances of application-defined datatypes, and a convention for representing remote procedure calls and responses [1]

Objective

The objective of this document is explain the Openbravo implementation of the current SOAP WebServices

Implementation

Openbravo ERP uses Apache Axis as framework to build the SOAP Webservices. The implementation is simple: You have an Interface that defines which are the available methods, a Class that implements the Interface and available methods. A set of Classes (POJOs) used to transport information and a WSDD [2] file that describes the webservice.

Java

POJOS

Under the org.openbravo.erpCommon.ws.externalSales package you'll find several Java classes (see the list below). This classes are simple POJOs, used to transport information.

Product Example
 
/*
 *************************************************************************
 * The contents of this file are subject to the Openbravo  Public  License
 * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
 * Version 1.1  with a permitted attribution clause; you may not  use this
 * file except in compliance with the License. You  may  obtain  a copy of
 * the License at http://www.openbravo.com/legal/license.html 
 * Software distributed under the License  is  distributed  on  an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific  language  governing  rights  and  limitations
 * under the License. 
 * The Original Code is Openbravo ERP. 
 * The Initial Developer of the Original Code is Openbravo SLU 
 * All portions are Copyright (C) 2001-2009 Openbravo SLU 
 * All Rights Reserved. 
 * Contributor(s):  ______________________________________.
 ************************************************************************
 */
 
package org.openbravo.erpCommon.ws.externalSales;
 
import java.io.Serializable;
import java.math.BigDecimal;
 
public class Product implements Serializable {
  private static final long serialVersionUID = 1L;
  private String id;
  private String name;
  private String number;
  private String description;
  private BigDecimal listPrice;
  private BigDecimal purchasePrice;
  private Tax tax;
  private String imageUrl;
  private String ean;
  private Category category;
 
  public String getId() {
    return id;
  }
 
  public void setId(String id) {
    this.id = id;
  }
 
 // Getters & Setters for each one of the class members
 
}

Service Interface

 
/*
 *************************************************************************
 * The contents of this file are subject to the Openbravo  Public  License
 * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
 * Version 1.1  with a permitted attribution clause; you may not  use this
 * file except in compliance with the License. You  may  obtain  a copy of
 * the License at http://www.openbravo.com/legal/license.html 
 * Software distributed under the License  is  distributed  on  an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific  language  governing  rights  and  limitations
 * under the License. 
 * The Original Code is Openbravo ERP. 
 * The Initial Developer of the Original Code is Openbravo SLU 
 * All portions are Copyright (C) 2001-2006 Openbravo SLU 
 * All Rights Reserved. 
 * Contributor(s):  ______________________________________.
 ************************************************************************
 */
 
package org.openbravo.erpCommon.ws.externalSales;
 
public interface ExternalSales {
 
  public Product[] getProductsCatalog(String entityId, String organizationId, String salesChannel,
      String username, String password);
 
  public ProductPlus[] getProductsPlusCatalog(String entityId, String organizationId,
      String salesChannel, String username, String password);
 
  public boolean uploadOrders(String entityId, String organizationId, String salesChannel,
      Order[] newOrders, String username, String password);
 
  public Order[] getOrders(String entityId, String organizationId, OrderIdentifier[] orderIds,
      String username, String password);
}

This Interface defines which are the available methods to be exposed by Apache Axis.

Service Implementation

 
/*
 *************************************************************************
 * The contents of this file are subject to the Openbravo  Public  License
 * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
 * Version 1.1  with a permitted attribution clause; you may not  use this
 * file except in compliance with the License. You  may  obtain  a copy of
 * the License at http://www.openbravo.com/legal/license.html
 * Software distributed under the License  is  distributed  on  an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific  language  governing  rights  and  limitations
 * under the License.
 * The Original Code is Openbravo ERP.
 * The Initial Developer of the Original Code is Openbravo SLU
 * All portions are Copyright (C) 2001-2009 Openbravo SLU
 * All Rights Reserved.
 * Contributor(s):  ______________________________________.
 ************************************************************************
 */
 
package org.openbravo.erpCommon.ws.externalSales;
 
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Vector;
 
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
 
import org.apache.axis.MessageContext;
import org.apache.axis.transport.http.HTTPConstants;
import org.apache.log4j.Logger;
import org.openbravo.base.ConnectionProviderContextListener;
import org.openbravo.database.ConnectionProvider;
import org.openbravo.erpCommon.utility.SequenceIdData;
 
public class ExternalSalesImpl implements ExternalSales {
  protected static ConnectionProvider pool;
  // protected static String javaDateFormat;
  static Logger log4j = Logger.getLogger(ExternalSales.class);
 
  // date formats are hard coded because it is required by
  // synchronization of POS.
  private final String dateFormatStr = "yyyy-MM-dd HH:mm:ss";
  private final String dateTimeFormatStr = "YYYY-MM-DD HH24:MI:SS";
 
  /** Creates a new instance of ExternalSalesImpl */
  public ExternalSalesImpl() {
    if (log4j.isDebugEnabled())
      log4j.debug("ExternalSales");
    initPool();
  }
 
  private boolean access(String username, String password) {
    try {
      return !ExternalSalesOrderData.access(pool, username, password).equals("0");
    } catch (Exception e) {
      return false;
    }
 
  }
 
  public Product[] getProductsCatalog(String ClientID, String organizationId, String salesChannel,
      String username, String password) {
 
    if (!access(username, password)) {
      if (log4j.isDebugEnabled()) {
        log4j.debug("Access denied for user: " + username + " - password: " + password);
      }
      return null;
    }
 
    if (log4j.isDebugEnabled()) {
      log4j.debug("getProductsCatalog" + " ClientID " + ClientID + " organizationId "
          + organizationId + " salesChannel " + salesChannel);
    }
 
    try {
 
      // Select
      ExternalSalesProductData[] data = ExternalSalesProductData.select(pool, ClientID,
          salesChannel, organizationId);
 
      if (data != null && data.length > 0) {
        int i = 0;
        if (log4j.isDebugEnabled()) {
          log4j.debug("data.length " + data.length);
        }
        Product[] products = new Product[data.length];
 
        while (i < data.length) {
          if (log4j.isDebugEnabled()) {
            log4j.debug("getProductsCatalog data[i].id " + data[i].id + " data[i].name "
                + data[i].name);
          }
          products[i] = new Product();
          products[i].setId(data[i].id);
          products[i].setName(data[i].name);
          products[i].setNumber(data[i].number1);
          products[i].setDescription(data[i].description);
          products[i].setListPrice(new BigDecimal(data[i].listPrice));
          products[i].setPurchasePrice(new BigDecimal(data[i].purchasePrice));
          Tax tax = new org.openbravo.erpCommon.ws.externalSales.Tax();
          tax.setId(data[i].taxId);
          tax.setName(data[i].taxName);
          tax.setPercentage(new BigDecimal(data[i].percentage));
          products[i].setTax(tax);
          products[i].setImageUrl(data[i].imageUrl);
          products[i].setEan(data[i].ean);
          Category category = new org.openbravo.erpCommon.ws.externalSales.Category();
          category.setId(data[i].mProductCategoryId);
          category.setName(data[i].mProductCategoryName);
          category.setDescription(data[i].mProductCategoryDescription);
          products[i].setCategory(category);
          i++;
        }
        return products;
      } else if (data != null && data.length == 0) { // In case that don't
        // return data,
        // return an empty
        // array
        if (log4j.isDebugEnabled()) {
          log4j.debug("data.length " + data.length);
        }
        return new Product[0];
      }
    } catch (Exception e) {
      log4j.error("Error : getProductsCatalog");
      e.printStackTrace();
    }
 
    destroyPool();
    return null;
  }
 
 
  //-----------------------------------------//
  //- Implementation of the rest of methods -//
  //-----------------------------------------//
 
 
  private void initPool() {
    if (log4j.isDebugEnabled())
      log4j.debug("init");
    try {
      HttpServlet srv = (HttpServlet) MessageContext.getCurrentContext().getProperty(
          HTTPConstants.MC_HTTP_SERVLET);
      ServletContext context = srv.getServletContext();
      pool = ConnectionProviderContextListener.getPool(context);
    } catch (Exception e) {
      log4j.error("Error : initPool");
      e.printStackTrace();
    }
  }
 
  private void destroyPool() {
    if (log4j.isDebugEnabled())
      log4j.debug("destroy");
  }
 
}
getProductsCatalog
 
  public Product[] getProductsCatalog(String ClientID, String organizationId, String salesChannel,
      String username, String password) {

The methods receives a Client, Organization, Sales Channel, Username and Password.

Bulbgraph.png   The password should be sent encrypted, but is transported as plain text. A SSL should be used to secure your service
 
     if (!access(username, password)) {

If the combination username/password is not valid, or has no access to the service the process is finished.

 
      // Select
      ExternalSalesProductData[] data = ExternalSalesProductData.select(pool, ClientID,
          salesChannel, organizationId);

Using SQLC generated class (ExternalSalesProductData) we get all the products for this combination. Client, Sales Channel an Organization. Note that the pool parameter is a member of the class already initialized in the constructor.

 
      if (data != null && data.length > 0) {
        int i = 0;
        // Part of the code removed
        Product[] products = new Product[data.length];
 
        while (i < data.length) {
          // Part of the code removed
          products[i] = new Product();

If data is not empty, we iterate trough the array (data) creating a new Product object and setting all the values for each member of Product.

 
        return products;

We return the products array.

 
      } else if (data != null && data.length == 0) {
        // Part of the code removed
        return new Product[0];

If data is empty, a blank product is returned.

WSDD

Bulbgraph.png   deploy.wsdd and undeploy.wsdd files for webservices defined within modules should be in each module's src folder.
 
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<!--
 *************************************************************************
 * The contents of this file are subject to the Openbravo  Public  License
 * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
 * Version 1.1  with a permitted attribution clause; you may not  use this
 * file except in compliance with the License. You  may  obtain  a copy of
 * the License at http://www.openbravo.com/legal/license.html 
 * Software distributed under the License  is  distributed  on  an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific  language  governing  rights  and  limitations
 * under the License. 
 * The Original Code is Openbravo ERP. 
 * The Initial Developer of the Original Code is Openbravo SLU 
 * All portions are Copyright (C) 2001-2008 Openbravo SLU 
 * All Rights Reserved. 
 * Contributor(s):  ______________________________________.
 ************************************************************************
-->
    <service name="ExternalSales" provider="java:RPC">
        <parameter name="className" value="org.openbravo.erpCommon.ws.externalSales.ExternalSalesImpl"/>
        <parameter name="allowedMethods" value="*"/>
        <beanMapping qname="myNS:Product"  xmlns:myNS="/services/ExternalSales" languageSpecificType="java:org.openbravo.erpCommon.ws.externalSales.Product"/>
        <beanMapping qname="myNS:ProductPlus"  xmlns:myNS="/services/ExternalSales" languageSpecificType="java:org.openbravo.erpCommon.ws.externalSales.ProductPlus"/>
        <beanMapping qname="myNS:Tax"  xmlns:myNS="/services/ExternalSales" languageSpecificType="java:org.openbravo.erpCommon.ws.externalSales.Tax"/>
        <beanMapping qname="myNS:Category"  xmlns:myNS="/services/ExternalSales" languageSpecificType="java:org.openbravo.erpCommon.ws.externalSales.Category"/>
        <beanMapping qname="myNS:BPartner"  xmlns:myNS="/services/ExternalSales" languageSpecificType="java:org.openbravo.erpCommon.ws.externalSales.BPartner"/>
        <beanMapping qname="myNS:Order"  xmlns:myNS="/services/ExternalSales" languageSpecificType="java:org.openbravo.erpCommon.ws.externalSales.Order"/>
        <beanMapping qname="myNS:OrderLine"  xmlns:myNS="/services/ExternalSales" languageSpecificType="java:org.openbravo.erpCommon.ws.externalSales.OrderLine"/>
        <beanMapping qname="myNS:OrderIdentifier"  xmlns:myNS="/services/ExternalSales" languageSpecificType="java:org.openbravo.erpCommon.ws.externalSales.OrderIdentifier"/>
        <beanMapping qname="myNS:Payment"  xmlns:myNS="/services/ExternalSales" languageSpecificType="java:org.openbravo.erpCommon.ws.externalSales.Payment"/>
    </service>
    <service name="WebService" provider="java:RPC">
        <parameter name="className" value="org.openbravo.erpCommon.ws.services.WebServiceImpl"/>
        <parameter name="allowedMethods" value="*"/>
        <beanMapping qname="myNS:BusinessPartner"  xmlns:myNS="/services/WebService" languageSpecificType="java:org.openbravo.erpCommon.ws.services.BusinessPartner"/>
        <beanMapping qname="myNS:Contact"  xmlns:myNS="/services/WebService" languageSpecificType="java:org.openbravo.erpCommon.ws.services.Contact"/>
        <beanMapping qname="myNS:Customer"  xmlns:myNS="/services/WebService" languageSpecificType="java:org.openbravo.erpCommon.ws.services.Customer"/>
        <beanMapping qname="myNS:Location"  xmlns:myNS="/services/WebService" languageSpecificType="java:org.openbravo.erpCommon.ws.services.Location"/>
    </service>
</deployment>

External Sales definition

 
 <service name="ExternalSales" provider="java:RPC">

Defines the name of the service. The service will be accessed through this name e.g. http://localhost:8880/openbravo/services/ExternalSales

 
 <parameter name="className" value="org.openbravo.erpCommon.ws.externalSales.ExternalSalesImpl"/>

Defines the class that implements the service

 
 <parameter name="allowedMethods" value="*"/>

Defines which methods of the class are allowed

 
 <beanMapping qname="myNS:Product"  xmlns:myNS="/services/ExternalSales" languageSpecificType="java:org.openbravo.erpCommon.ws.externalSales.Product"/>

For each POJO, we have an beanMapping with the name, and the java class. More information on Apache Axis documentation.

Final Result

Deploying the WebService

$ ant installWebService
Buildfile: build.xml

init:

installWebService:

init:

installWebService:
     [java] Processing file ./deploy.wsdd
     [java] <Admin>Done processing</Admin>

BUILD SUCCESSFUL
Total time: 3 seconds

WSDL

Example-soap1.png

Notes

  1. http://ws.apache.org/axis/
  2. http://www.omii.ac.uk/docs/2.3.0/reference/apache_axis/wsdd/wsdd.htm



ERP 2.50:Developers Guide/Examples/Process | ERP 2.50:Developers Guide/Examples/Window and Tab 

Retrieved from "http://wiki.openbravo.com/wiki/ERP_2.50:Developers_Guide/Examples/SOAP_WebService"

This page has been accessed 15,300 times. This page was last modified on 14 June 2011, at 11:04. Content is available under Creative Commons Attribution-ShareAlike 2.5 Spain License.