Showing posts with label ESB. Show all posts
Showing posts with label ESB. Show all posts

Monday, September 28, 2015

WSO2 API Manager vs WSO2 ESB: Should the API Manager replace the ESB?

In the `good old days’ the aim of the Enterprise Service Bus (ESB) was to integrate applications inside the organisation. Many years later, the need for integration still continues to grow, and the integration scenarios tend to exponentially diversify. These days it’s absolutely critical to be able to connect with partners and customers outside the organisation in much more flexible and agile ways. This is where API Managers (or API Gateways as offered by some vendors) are predominantly used. Does this mean that the ESB is old-fashioned and should be replaced by an API Manager? 

There used to be only one way to integrate applications: exchanging files. Then application transaction calls were added followed by asynchronous exchanges using queuing. Now, mobile, Internet of Things, and machine-to-machine (M2M) technologies introduce multiple additional scenarios using APIs and streaming integration styles. Nevertheless, even with these new scenarios, older technologies remain in use. So, when all these integration scenarios are combined, it becomes hard for developers to decide which should be used over the other or when to use both with respect to Integration Solutions (ESB) and API Managers.

So, back to the question: Should ESBs be replaced by API Managers? In most cases, it will not be an either/or situation; ESBs and API Gateway Services can coexist and complement each other. However, depending on the integration requirement and cost implications (using both technologies is expensive), one might have to be chosen over the other. Let’s take a look at some examples of real-world integration requirements and see how they should be addressed by using either the ESB or the API Manager or both. 


Scenario 1 - A loosely coupled integration solution

In an organization, there are numerous heterogeneous systems (as a result of a merger between several companies), from database applications to legacy ERP systems to cloud applications like Salesforce. There are also some SOAP web services and some recently developed REST APIs. The need is to seamlessly connect them through a centralized integration layer so that tight coupling between the applications can be avoided.  The solution should be on-premise and provide application connectors, message queueing, transformation, service orchestration and monitoring. Ability to add security and other policies to enable security, throttling etc. are useful features. What can this organization use?


Solution: ESB 

An ESB can be defined as:
- An architectural construct that provides fundamental services to complex architectures
- An entity that acts as a hub connecting many diverse systems
- A central driver that facilitates Enterprise Application Integration (EAI)


Some of these basic services of an ESB:
- Message passing, routing and filtering
- Message transformation
- Protocol conversion
- QoS enforcement (security, reliable delivery etc)
- Logging, auditing and monitoring


The WSO2 ESB can be used to integrate a large number of heterogeneous systems in an enterprise setting. It is currently used in hundreds of production deployments all around the world to connect various applications, implemented using various technologies (both open source and proprietary) running on various platforms (Windows, Linux, .NET, J2EE, LAMP, cloud). In other words, it is used as a centralized driver that facilitates EAI. The configuration model of the WSO2 ESB is so agile and powerful that practically any EAI pattern can be implemented on top of them. It has a very flexible enterprise messaging model. This is achieved through its ability to support for any wire level protocol or any message format that can be easily implemented on top of this model and can be deployed as a separate pluggable module. 

. Figure 1 - WSO2 ESB as a centralized integration layer

Figure 1 shows how the ESB can act as a centralized integration layer which contains all integration logic to connect to heterogeneous applications and systems. It can be integrated with other WSO2 middleware products such as the WSO2 Identity Server to implement security scenarios; it can publish events to the WSO2 Data Analytics Server (DAS) to perform batch, real-time, predictive and interactive analytics. 

Scenario 2 - A centrally-owned but locally-managed integration solution

An IT services provider has a closed group of clients, who have identical business interests. The clients want to be able to make use of some common integration services as well as a few others that are specific to each client to be able to communicate over domain specific standards and protocols. In order to perform information retrieval and write their own applications, they want these services to be provided by the said IT services provider. For example, a national data registry or database needs to be accessed over a custom protocol by different municipalities in a country to write their apps. Both the clients and the service provider prefer a cloud service as opposed to an on-premise solution at each site due to ease of management and to have a single point of control - for example if there are global changes or updates, they can be easily applied at a single place. (Check  [5] for a real case study on a connected government system). What can the IT services provider use?

Solution: A multi-tenanted ESB in private/public cloud

WSO2 middleware products inherently support multi-tenancy. In this example, each client’s integration needs can be configured in separate tenants in the ESB. The service provider will have to create an adapter(s) for the ESB to integrate with the data registries and create integration services for each client. 

Scenario 3 - Basic API management

An organization already has ready-to-use REST APIs and SOAP services; they don’t want to change anything (no transformations required); they want to become API providers. Some APIs will be only for internal use to enable business agility and customer engagement. Some others will be B2B APIs to optimize value chain relationships and processes. And the rest will be public APIs for access by thousands of developers across the open Web.  It is important to make it easy for API users — developers, whether internal or external to the API provider’s organization, who write applications that leverage an API — to access and understand how to use the API; to be able to secure and throttle the access of and API, and know who is using an API, typically by having them register for an API key; and ensure that API users have the support necessary to solve any problems they may have, whether that support comes from the API provider or from other API users (e.g., through community discussion forums). What does this organization need?


Solution: API Manager
,
An API manager provides developer portal frameworks with pre-built capabilities for the above mentioned requirements and more. It can enforce agreements on API usage and security. An API key is often only the first element of an API provider’s control over API use. API management products enforce usage parameters as agreed to between an API provider and API users in a variety of ways: the use of a secure sockets layer (SSL) or digital signatures for added security; the use of OAuth to allow the API provider’s customers to authorize access to their data; or quotas and rate limits for how many API calls an API user can make. 


Figure 2 - WSO2 API management platform




The WSO2 API Manager is a complete solution for designing and publishing APIs, creating and managing a developer community, and for scalably routing API traffic. It leverages proven, production-ready integration, security, and governance components from the WSO2 Enterprise Service Bus, WSO2 Identity Server, and WSO2 Governance Registry. In addition, it leverages the WSO2 Data Analytics Server for Big Data analytics, giving you instant insight into APIs behavior.

Scenario 4 - API management with simple mediation

An organization has several REST and SOAP APIs already and needs the same capabilities as mentioned in the 3rd scenario. However, the APIs are not ready-to-use and there are ‘minor’ transformations required. For example, a mobile application can only send and receive JSON messages but the backend APIs/services process only XML. Should the organization use the ESB instead of the API Manager or should it use both?

Solution: API Manager

Apart from routing, enforcing security and throttling, the WSO2 API Manager's gateway includes in-built minor payload and protocol transformation capabilities. In fact, the API Manager's Gateway is a basic stripped-down version of the WSO2 ESB and is not intended to be used as a fully-fledged ESB. For minor transformations, dependance on the ESB can be reduced or avoided altogether. For this scenario the API Manager would suffice. 

Scenario 5 - API management with complex integrations

There is a mix of APIs, services and applications (including home-grown applications). In addition to the ready-made APIs and services, a service/API layer must be introduced to access the applications. Some applications communicate over proprietary protocols while some others support standard protocols. Service chaining/orchestration may also need to take place. All services must be exposed centrally to external and internal parties. Management and monitoring of all these APIs are absolutely necessary. Obviously this is far more complex than the previous scenario; so should both the API Manager and ESB be used in this case?

Solution: API Facade Pattern (The combination of the API Manager and the ESB)

API facade is an interface between API consumers (application developers) and the backend systems of the organization. API facade would hide the complexity of the backend services from the application developers and provide a unified layer that developers can use for their applications. 

Because of the heterogeneous nature and the complexity of the backend services, they cannot be exposed directly as APIs to application developers. These backend services require a certain level of mediation; this highlights the need to have a separate mediation layer behind the facade layer. Coupling these two layers increase the complexity in the facade layer, create architectural and scalability limitations, and would require a significant level of mediation logic to be outside the firewall if the APIs are to be exposed to external developers. The solution to this problem is the use of the API Facade pattern.

Figure 3 - API facade pattern 


Implementation of the API facade pattern can be done by using the WSO2 API Manager to build a facade layer and the WSO2 ESB to build the mediation layer (add in products like the WSO2 Data Analytics Server for analytics) and connect to the existing services/applications. 


Other Frequently Implemented Patterns with the API Manager

WSO2’s open source platform provides many opportunities to extend API management. Aside from being the only fully open source solution, the unique feature for WSO2 is the ability to extend API management features . 

Scenario 6 - External key manager
An organization already has an OAuth2 authorization server which issues and validates OAuth2 tokens and want to use that instead of the in-built Key Manager of the WSO2 API Manager. Can this be done?

Absolutely! With the revamped architecture of the API Manager (having started from version 1.9.0), all integration points with the key manager are made to be extensible, thereby enabling the plugging of an external OAuth2 authorization server. See [7] for more information. 


Scenario 7 - External API gateway
What if an organization already has an existing API gateway or ESB component (non-WSO2), which handles token generation and validation on its own or in combination with a Key Manager, and what they are looking for are API store and publisher portals, and their API management capabilities (such as versioning, lifecycle management, notifications etc.). Can they still use the WSO2 API Manager?

This pattern can be implemented using WSO2 Governance Registry 5.0.0 [8].  The Governance Registry can provide store and publisher interfaces. It can be used to write executors to push API definitions to the external gateway (in the required format) once an API’s lifecycle state changes from ‘created’ to ‘published’ state in the publisher (and removed/disabled when the state changes to ‘deleted’). 

Resources - 


Wednesday, May 14, 2014

Entity Aggregation with WSO2 ESB and WSO2 Data Services Server – Part II

This post is the second part of the Entity Aggregation with WSO2 ESB and WSO2 Data Services Server series. Part I can be found here.




I am going to implement a prototype of the above scenario with the following assumptions:
The ERP system exposes the Customer Data through a MySQL database.
The CRM Service will expose the Customer Data through a SOAP service.

Requirement:

The requirement is to implement the Aggregation Service which will aggregate the customer information from the ERP and CRM systems and expose a unified view of the Customer through a RESTful API.

Implementation:

The following WSO2 products and the respective versions were used for the implementation:

For the implementation of this scenario I have done the following:

Mocking the ERP System:

Customer data of the ERP system exists in a MySQL database which will be exposed by the Data Services Server.  Create the database and the Customer table as provided in the following SQL statements. 

create database ERP_DB;
use ERP_DB;
CREATE TABLE `Customer` (
  `ERPCustID` varchar(90) NOT NULL PRIMARY KEY,
  `LName` varchar(200) DEFAULT NULL,
  `FName` varchar(200) DEFAULT NULL,
  `OrgID` varchar(200) DEFAULT NULL
);

insert into Customer values ("001", "Green", "Rachel","1010");
insert into Customer values ("002", "Buffet", "Phoebe","1020");
insert into Customer values ("003", "Geller", "Monica","1030");
insert into Customer values ("004", "Geller", "Ross","1040");
insert into Customer values ("005", "Bing", "Chandler","1050");
insert into Customer values ("006", "Tribbiani", "Joey","1060");

Once the Customer table is created a select * statement should show a populated table as given below:



Mocking the CRM System:

The CRM service as mentioned earlier will be a SOAP service named CRMCustomerService hosted in the WSO2 Application Service with two operations – getAllCRMCustomers and getCustomerByOrgId. A response from the getAllCRMCustomers would look like this:

<ns:getAllCRMCustomersResponse xmlns:ns="http://crm.wso2.org" xmlns:ax21="http://crm.wso2.org/xsd">
   <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:Customer">
      <ax21:CRMCustID>2001</ax21:CRMCustID>
      <ax21:LName>Geller</ax21:LName>
      <ax21:address>45, Broadway Avenue, NYC</ax21:address>
      <ax21:fname>Ross</ax21:fname>
      <ax21:orgID>1040</ax21:orgID>
      <ax21:tel>43124562</ax21:tel>
   </ns:return>
   <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:Customer">
      <ax21:CRMCustID>2002</ax21:CRMCustID>
      <ax21:LName>Bing</ax21:LName>
      <ax21:address>55, Fifth Avenue, NYC</ax21:address>
      <ax21:fname>Chandler</ax21:fname>
      <ax21:orgID>1050</ax21:orgID>
      <ax21:tel>91234829</ax21:tel>
   </ns:return>
   <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:Customer">
      <ax21:CRMCustID>2003</ax21:CRMCustID>
      <ax21:LName>Tribbiani</ax21:LName>
      <ax21:address>98, Park Avenue, NYC</ax21:address>
      <ax21:fname>Joey</ax21:fname>
      <ax21:orgID>1060</ax21:orgID>
      <ax21:tel>12304883</ax21:tel>
   </ns:return>
   <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:Customer">
      <ax21:CRMCustID>2004</ax21:CRMCustID>
      <ax21:LName>Green</ax21:LName>
      <ax21:address>999, Park Avenue, NYC</ax21:address>
      <ax21:fname>Rachel</ax21:fname>
      <ax21:orgID>1010</ax21:orgID>
      <ax21:tel>12304883</ax21:tel>
   </ns:return>
   <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:Customer">
      <ax21:CRMCustID>2005</ax21:CRMCustID>
      <ax21:LName>Buffet</ax21:LName>
      <ax21:address>123, Park Avenue, NYC</ax21:address>
      <ax21:fname>Phoebe</ax21:fname>
      <ax21:orgID>1020</ax21:orgID>
      <ax21:tel>9786756</ax21:tel>
   </ns:return>
   <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:Customer">
      <ax21:CRMCustID>2006</ax21:CRMCustID>
      <ax21:LName>Geller</ax21:LName>
      <ax21:address>98, Broadway Avenue, NYC</ax21:address>
      <ax21:fname>Monica</ax21:fname>
      <ax21:orgID>1030</ax21:orgID>
      <ax21:tel>14652638</ax21:tel>
   </ns:return>
</ns:getAllCRMCustomersResponse>

While a response from getCustomerByOrgID would look like this:

<ns:getCustomerByOrgIDResponse xmlns:ns="http://crm.wso2.org">
   <ns:return xmlns:ax21="http://crm.wso2.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:Customer">
      <ax21:CRMCustID>2004</ax21:CRMCustID>
      <ax21:LName>Green</ax21:LName>
      <ax21:address>999, Park Avenue, NYC</ax21:address>
      <ax21:fname>Rachel</ax21:fname>
      <ax21:orgID>1010</ax21:orgID>
      <ax21:tel>12304883</ax21:tel>
   </ns:return>
</ns:getCustomerByOrgIDResponse>

The CRMCustomerService was implemented using the following Java classes which were used to create an Axis2 Web Service using WSO2 Developer Studio.  Here is how you can create an Axis2 Service from the WSO2 Developer Studio.

 CRMCustomerService.java
package org.wso2.crm;

public class CRMCustomerService{
 
 Customer[] customers;
  
 public CRMCustomerService() {
  super();
  customers = new Customer[6];
  customers[0] = new Customer("2001", "Geller", "Ross", "45, Broadway Avenue, NYC", "43124562", "1040");
  customers[1] = new Customer("2002", "Bing", "Chandler", "55, Fifth Avenue, NYC", "91234829", "1050");
  customers[2] = new Customer("2003", "Tribbiani", "Joey", "98, Park Avenue, NYC", "12304883", "1060");
  customers[3] = new Customer("2004", "Green", "Rachel", "999, Park Avenue, NYC", "12304883", "1010");
  customers[4] = new Customer("2005", "Buffet", "Phoebe", "123, Park Avenue, NYC", "9786756", "1020");
  customers[5] = new Customer("2006", "Geller", "Monica", "98, Broadway Avenue, NYC", "14652638", "1030");
 }

 public Customer[] getAllCRMCustomers() {
  return customers;

 }
 
 public Customer getCustomerByOrgID(String OrgID) {
  
  for(int i=0; iif
(customers[i] != null && customers[i].getOrgID() != null && customers[i].getOrgID().equals(OrgID)){ return customers[i]; } } return null; } }
Customer.java
package org.wso2.crm;

public class Customer {
 
 private String CRMCustID;
 private String LName;
 private String Fname;
 private String Address;
 private String Tel;
 private String OrgID;
 
 
 public Customer(String cRMCustID, String lName, String fname,
   String address, String tel, String orgID) {
  super();
  CRMCustID = cRMCustID;
  LName = lName;
  Fname = fname;
  Address = address;
  Tel = tel;
  OrgID = orgID;
 }
 
 public String getCRMCustID() {
  return CRMCustID;
 }
 public void setCRMCustID(String cRMCustID) {
  CRMCustID = cRMCustID;
 }
 public String getLName() {
  return LName;
 }
 public void setLName(String lName) {
  LName = lName;
 }
 public String getFname() {
  return Fname;
 }
 public void setFname(String fname) {
  Fname = fname;
 }
 public String getAddress() {
  return Address;
 }
 public void setAddress(String address) {
  Address = address;
 }
 public String getTel() {
  return Tel;
 }
 public void setTel(String tel) {
  Tel = tel;
 }
 public String getOrgID() {
  return OrgID;
 }
 public void setOrgID(String orgID) {
  OrgID = orgID;
 }

To host the CRMCustomerService, download the service from here and host it in the WSO2 Application Server. When running the Application Server, run it with port offset 1. More information on setting port offset here.

Implementing the Entity Aggregation Solution

I have used the WSO2 ESB and the Data Services Server to implement the Entity Aggregation Solution.

Configuring WSO2 Data Services Server


First, the data from the ERP service needs to be exposed through a data service (SOAP service) hosted in the Data Services Server. Create a new data service named ERPCustomerDataService in the Data Services Server with the following configuration.  The Data Services Server should run with port offset 2. Since we are using a MySQL database make sure to place the MySQL JDBC driver (mysql-connector-java-5.XX-bin.jar)in HOME/repository/components/dropins folder of the Data Services Server.

<data name="ERPCustomerDataService">
   <config id="mysql">
      <property name="driverClassName">com.mysql.jdbc.Driver</property>
      <property name="url">jdbc:mysql://localhost:3306/ERP_DB</property>
      <property name="username">root</property>
      <property name="password">root</property>
   </config>
   <query id="getAllCustomersQuery" useConfig="mysql">
      <sql>SELECT * FROM Customer;</sql>
      <result element="Customers" rowName="Customer">
         <element column="ERPCustID" name="ERPCustID" xsdType="string"/>
         <element column="LName" name="LName" xsdType="string"/>
         <element column="FName" name="FName" xsdType="string"/>
         <element column="OrgID" name="OrgID" xsdType="string"/>
      </result>
   </query>
   <query id="getCustomerByOrgIDQuery" useConfig="mysql">
      <sql>SELECT * FROM Customer WHERE OrgID LIKE ? ;</sql>
      <param name="OrgID" ordinal="1" sqlType="STRING"/>
      <result element="Customers" rowName="Customer">
         <element column="ERPCustID" name="ERPCustID" xsdType="string"/>
         <element column="LName" name="LName" xsdType="string"/>
         <element column="FName" name="FName" xsdType="string"/>
         <element column="OrgID" name="OrgID" xsdType="string"/>
      </result>
   </query>
   <operation name="getAllCustomersOperation">
      <call-query href="getAllCustomersQuery"/>
   </operation>
   <operation name="getCustomerByOrgIDOperation">
      <call-query href="getCustomerByOrgIDQuery">
         <with-param name="OrgID" query-param="OrgID"/>
      </call-query>
   </operation>
</data>

The above data service has two operations: getAllCustomers and getCustomerByOrgIDOperation.  Sample responses from the above services are as shown below. 

getAllCustomers:
<Customers xmlns="http://ws.wso2.org/dataservice">
   <Customer>
      <ERPCustID>001</ERPCustID>
      <LName>Green</LName>
      <FName>Rachel</FName>
      <OrgID>1010</OrgID>
   </Customer>
   <Customer>
      <ERPCustID>002</ERPCustID>
      <LName>Buffet</LName>
      <FName>Phoebe</FName>
      <OrgID>1020</OrgID>
   </Customer>
   <Customer>
      <ERPCustID>003</ERPCustID>
      <LName>Geller</LName>
      <FName>Monica</FName>
      <OrgID>1030</OrgID>
   </Customer>
   <Customer>
      <ERPCustID>004</ERPCustID>
      <LName>Geller</LName>
      <FName>Ross</FName>
      <OrgID>1040</OrgID>
   </Customer>
   <Customer>
      <ERPCustID>005</ERPCustID>
      <LName>Bing</LName>
      <FName>Chandler</FName>
      <OrgID>1050</OrgID>
   </Customer>
   <Customer>
      <ERPCustID>006</ERPCustID>
      <LName>Tribbiani</LName>
      <FName>Joey</FName>
      <OrgID>1060</OrgID>
   </Customer>
</Customers>

getCustomerByOrgIDOperation:
<Customers xmlns="http://ws.wso2.org/dataservice">
   <Customer>
      <ERPCustID>001</ERPCustID>
      <LName>Green</LName>
      <FName>Rachel</FName>
      <OrgID>1010</OrgID>
   </Customer>
</Customers>


Configuring WSO2 ESB

The ESB needs to be configured to expose a REST API which on invocation should call the respective data service and obtain the ERP customer data and then the web service hosted in the WSO2 Application server to retrieve the CRM customer data. Thereafter, it must aggregate the fields according to the new data model and send the aggregated response. 

The ESB should be started with port offset 0. This is the default port offset so nothing needs to be changed in the configuration files. 


Create a new API named CustomerAPI in the ESB with the following configuration:


<api xmlns="http://ws.apache.org/ns/synapse" name="CustomerAPI" context="/customer">
   <resource methods="GET" uri-template="/{OrgID}">
      <inSequence>
         <payloadFactory media-type="xml">
            <format>
               <p:getCustomerByOrgIDOperation xmlns:p="http://ws.wso2.org/dataservice">
                  <a:OrgID xmlns:a="http://ws.wso2.org/dataservice">$1</a:OrgID>
               </p:getCustomerByOrgIDOperation>
            </format>
            <args>
               <arg evaluator="xml" expression="get-property('uri.var.OrgID')"></arg>
            </args>
         </payloadFactory>
         <log level="full"></log>
         <call>
            <endpoint>
               <address uri="http://localhost:9765/services/ERPCustomerDataService/getCustomerByOrgIDOperation" format="soap12"></address>
            </endpoint>
         </call>
         <property xmlns:ns1="http://ws.wso2.org/dataservice" name="ERPCustID" expression="//ns1:ERPCustID"></property>
         <payloadFactory media-type="xml">
            <format>
               <p:getCustomerByOrgID xmlns:p="http://crm.wso2.org">
                  <b:OrgID xmlns:b="http://crm.wso2.org">$1</b:OrgID>
               </p:getCustomerByOrgID>
            </format>
            <args>
               <arg evaluator="xml" expression="get-property('uri.var.OrgID')"></arg>
            </args>
         </payloadFactory>
         <call>
            <endpoint>
               <address uri="http://localhost:9764/services/CRMCustomerService/getCustomerByOrgID" format="soap12"></address>
            </endpoint>
         </call>
         <property xmlns:ns2="http://crm.wso2.org/xsd" xmlns:ns1="http://crm.wso2.org" name="LName" expression="//ns1:return/ns2:LName"></property>
         <property xmlns:ns2="http://crm.wso2.org/xsd" xmlns:ns1="http://crm.wso2.org" name="address" expression="//ns1:return/ns2:address"></property>
         <property xmlns:ns2="http://crm.wso2.org/xsd" xmlns:ns1="http://crm.wso2.org" name="fname" expression="//ns1:return/ns2:fname"></property>
         <property xmlns:ns2="http://crm.wso2.org/xsd" xmlns:ns1="http://crm.wso2.org" name="orgID" expression="//ns1:return/ns2:orgID"></property>
         <property xmlns:ns2="http://crm.wso2.org/xsd" xmlns:ns1="http://crm.wso2.org" name="tel" expression="//ns1:return/ns2:tel"></property>
         <log>
            <property name="TEL" expression="$ctx:tel"></property>
         </log>
         <payloadFactory media-type="xml">
            <format>
               <result>
                  <erp_cust_id>$1</erp_cust_id>
                  <last_name>$2</last_name>
                  <first_name>$3</first_name>
                  <address>$4</address>
                  <organization>$5</organization>
                  <tel>$6</tel>
               </result>
            </format>
            <args>
               <arg evaluator="xml" expression="$ctx:ERPCustID"></arg>
               <arg evaluator="xml" expression="$ctx:LName"></arg>
               <arg evaluator="xml" expression="$ctx:fname"></arg>
               <arg evaluator="xml" expression="$ctx:address"></arg>
               <arg evaluator="xml" expression="$ctx:orgID"></arg>
               <arg evaluator="xml" expression="$ctx:tel"></arg>
            </args>
         </payloadFactory>
         <property name="messageType" value="application/xml" scope="axis2"></property>
         <respond></respond>
      </inSequence>
   </resource>
</api>

The API does the following:

1) The API is defined by a context - /customer and the URI template /{OrgID} is used to invoke the single GET resource that is defined in the API. So how it works is, you need to invoke the API with a URL like this: http://10.100.1.79:8280/customer/1010 

2) An in sequence is defined. In the in sequence the transformation mediator Payloadfactory is used to construct a message (convert the payload to one that matches with the request format of the data service) to the data service with the given OrgID (1010 in this case).  getCustomerByOrgIDOperation will be invoked from the data service with the given OrgID. 

3) Next the message is logged. 

4) Now the message needs to be sent to the data service. This is done with a Call mediator. The Call mediator invokes the service in a synchronous manner and mediation will be paused from that point. When the response is received, the mediation flow resumes from the next mediator in the sequence.

5) Once the response is received from the data service for the customer with OrgID = 1010, a Property mediator is used to store the ERPCustID from the response since this is the only field required from the ERP system and the rest should be taken from the CRM service. 

6) Another Payloadfactory mediator is added to create the payload for the CRM service in the Application Server.  The OrgID is passed to invoke the getCustomerByOrgID operation in the CRM service. 

7) A Call mediator is included at this step to send the request to the getCustomerByOrgID operation in the CRM service. 

8) Next there are five Property mediators to extract LName, FName,Address, Telephone and OrgID from the response. 

9) A property is logged to check if a value has been assigned to the property. This was mainly used for debugging purposes. 

10) Next the payload needs to be constructed that provides a holistic view of the customer and be sent back to the consumer. The payload is constructed with the Payloadfactory mediator and that payload is sent to the consumer using the Respond mediator, which is used to stop further processing of a message and send the message back to the client.

Testing the API

Do a search for a customer on your browser– e.g.
http://10.100.1.79:8280/customer/1010 and you will receive the following response from the API.


<result xmlns="http://ws.apache.org/ns/synapse">
<erp_cust_id>001</erp_cust_id>
<last_name>Green</last_name>
<first_name>Rachel</first_name>
<address>999, Park Avenue, NYC</address>
<organization>1010</organization>
<tel>12304883</tel>
</result>