Enterprise Service Bus in a nutshell
An ESB can be described as a set of components that provide the busisness tier with core integration services. The key advantage of an ESB is that it allows different applications to communicate with each other by acting as transit system for carrying data between applications within your intranet or over the internet.
ESB core components
Data routing
Data transformation
Protocol transformation
Service naming mapping
Message processing
Transaction management
Coordination of implementation services ("services orchestration")
Coordination of business processes ("processes choreography")
Security management
During the ESB lab we will learn the benefits of using ESB, how applications that operate using different data types and transport technologies can be easily integrated. We will cover a wide view all the aspects of the ESB using Mule. The student will learn how to create and integrate service components using ESB in simple scenarios.
Installation and Configuration
Mule ESB is a lighweight Enterprise Service Bus and integration framework that allows us to easily and quickly integrate applications and enable them to exchange data. It can handle services and applications using different transport and messaging technologies. A complete list of technologies that are known to work with Mule are listed in: http://www.mulesoft.org/display/MULE2INTRO/Compatible+Technologies
For installing Mule, we can use maven, ant or Mule IDE for Eclipse. For these lessons we will use the Mule IDE for Eclipse.
Follow the steps in the Mule webpage: http://www.mulesoft.org/display/MULE2INTRO/Installing+Mule
Installing Mule Server on Windows
1) Download Mule Standalone Server => http://project-icebar.net/bpm/
2) Set up your JAVA_HOME and MULE_HOME environment variables, and then update your PATH to point to the JDK and MULE binaries:
Example:
JAVA_HOME = C:\Program Files\Java\jdk1.6.0_15
Path += C:\Mule\mule-sandalone-2.2.1\bin
MULE_HOME = C:\Mule\mule-standalone-2.2.1
3) Test the server
With the command line, navigate to the examples folder which is in your Mule folder. Go to the hello folder and type the following:
> hello.bat
OR
> mule -config conf\hello-config.xml
The first time you run mule will prompt for an agreement, press continue and accept the terms for get the example running.
4) Install Mule IDE
Follow instructions in: http://www.mulesoft.org/display/MULEIDE/Mule+IDE+2.0+Installation+Guide
Using Windows Remote Desktop
Ask for an user account
1) Create your workspace folder inside your User Folder
2) Copy the example from N:\example to your user folder
3) Launch Eclipse and set up Mule IDE
4) Import the example that is in your user folder as a Java Project
Lesson 1 - Hello World
Summary
In this lesson the student will learn to build a hello world ESB Mule application. We will walk through the example in order to understand the basics of the Mule framework, how service components are built and how they communicate with each others. Finally, the student will develop and integrate a service component to the application.
In this lesson we will cover the following aspects:
Installation of the ESB Mule framework and plugins for eclipse.
Creation of a Mule application
Overview of the XML configuration (schema,namespace,global connectors, model, services)
Inbound Routers
Components
Outbound Routers
Transformers
Hello World Example
In this example we will create an application in Mule ESB using Mule IDE with Eclipse. The Mule IDE let us quickly create a new project, which can be based on existing examples. In this case we will use the Hello World example that is a simple approach yet cover a lot of aspect in order to get familiar with Mule.
1) Creating and running the Hello World Example
Creating the Application
In Eclipse Workbench, choose File > New > Project, expand the Mule folder and select Mule Project, and then click Next.
Enter the name HelloApp, ensuring that there is no space in the project name.
Click Add sample project content and select the Hello example.
Click Next, and then click the Libraries tab and verify that the Java 5 or later library is installed and available on the build path.
Click Finish to have the Mule IDE generate your project.
Running the application
In the Package Explorer, expand the conf directory, and right-click the hello-config.xml configuration file.
Choose Run As > Mule Server.
Package and Deploy the JAR and Configuration File
In Eclipse, right-click the project and choose Export.
Expand the Java folder, select JAR file, and then click Next.
Make sure Export generated class files and resources is selected and the other options are deselected.
Specify a location and name for the JAR file, and then click Finish. Eclipse creates the JAR file.
Copy the JAR file to the lib\user directory under your Mule home directory.
Copy the configuration file to the conf directory under your Mule home directo
To run the application using the jar, use the following command at the command prompt:
mule [-config <your-config.xml>]
2) Walking through the Hello World Example
The example consist of two service components:
Greeter: recieves the name of the person from STDIO, append the word "hello" to the data and send it to the ChitChat service component.
ChitChat: recieves the payload and append "How are you?" to the data and it deliver the data to STDIO.
Creating a mule application consist basically on creating a configuration file that points to the java classes that implement any custom logic on the message that come through. Lets open the configuration file of the example (hello-config.xml) and walk through the configuration.
The configuration file consist of:
XML declaration
<?xml version="1.0" encoding="UTF-8"?>
Namespaces declaration
Each Mule transport or module has its own xml schema and namespace.
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:jms="http://www.mulesource.org/schema/mule/jms/2.2"
xmlns:file="http://www.mulesource.org/schema/mule/file/2.2"
xsi:schemaLocation="
http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
http://www.mulesource.org/schema/mule/jms/2.2 http://www.mulesource.org/schema/mule/jms/2.2/mule-jms.xsd
http://www.mulesource.org/schema/mule/file/2.2 http://www.mulesource.org/schema/mule/file/2.2/mule-file.xsd">
Global Connectors
There are different ways to configure a transport. The best practice is to use the <connector> element in order to define global connector configuration. The connector element must be prefixed by the namespace of its transport. In the example is configured the STDIO connector:
<stdio:connector name="SystemStreamConnector" promptMessageCode="3" resourceBundle="messages.hello-example-messages" messageDelayTime="1000"/>
Configure the Model and the Services
Services components are contained within models. Therefore, we first define the model element <model> follow by the services.
<model name="helloSample">
<service name="Greeter">
..
</service>
<service name="ChitChat">
..
</service>
</model>
Inbound
The inbound element is used to configure inbound endpoints and inbound routers. Endpoints are used to receive incoming messages, and inbound routers determine how these messages are routed. Inbound endpoints and routers are configured separately within the <inbound> element. In the ChitChat service is defined an inbound-endpoint which indicates which transport uses (vm), the path/address to receive messages from (path="chitchatter"), and the current transformer to apply before past the payload to the component. We can define different inbound-endpoint for each service component with different transport such as jms, http, axis, bpm, among others. See available transport for more info.
<inbound>
<vm:inbound-endpoint path="chitchatter" transformer-refs="NameStringToChatString"/>
</inbound>
For more information, see Inbound Routers, and Configuring Endpoints
Transformers
Each service component can expect as input different data types, in that case we need to transform the payload to the corresponding expected data type for the component. To achieve this Mule has defined the notion of transformers, which can be referenced before the message reach to the component (inbound-endpoint) or after being processed. Mule provides a set of standards transformer (http://www.mulesoft.org/display/MULE2USER/Using+Transformers#UsingTransformers-ref) out of the box, but in this example we will see custom implementation of transformers in order to learn how to implement our own transformers. Custom transformer must be declared outside the model element:
<custom-transformer name="NameStringToChatString" class="org.mule.example.hello.NameStringToChatString"/>
<custom-transformer name="NameStringToChatString" class="org.mule.example.hello.NameStringToChatString"/>
Component
The <component> element configures the service component that will be invoked after the inbound message is processed by the inbound routers. If no component is configured, the service acts as a bridge and simply passes messages through to the outbound router. The component contain the business logic for working with the messages passed through Mule ESB. This service component can be any type of object, including POJO, script, Spring bean, web service, or REST call. In the ChitChat service the component is a simple Java Object which implements the business logic. When no entry point is defined, Mule uses an entry point resolver to dynamically choose the method to invoke based on the payload type of the message.
<component class="org.mule.example.hello.ChitChatter"/>
For more information, see Developing Service Components
Outbound
The <outbound> element configures outbound routers and their endpoints. Because outbound routers are used to determine which endpoints to use for dispatching messages after the component has finished processing them, outbound endpoints are configured on the outbound routers, not directly on the <outbound> element. Outbound routers allow the developer to define multiple routing constraints for any given message. In our example the <pass-through-router> is used, which simply sends or dispatches the message via the one endpoint it has configured, which is the system out endpoint, before deliver the message it apply a custom transformer to the payload.
More info: Outbound Routers
Wiring the Components
Now, let see how the first service component Greeter interact with the ChitChat component. The Greeter service component accepts the input the user types at the prompt, calls the Greeter class, and forwards the message to an internal queue called vm://chitchatter on which the ChitChat service component is listening. A transformation is performed before the message payload is delivered to the Greeter component and after the component has finished processing it.
<service name="Greeter">
<inbound>
<stdio:inbound-endpoint system="IN" transformer-ref="StdinToNameString"/>
</inbound>
<component class="org.mule.example.hello.Greeter"/>
<outbound>
<filtering-router>
<vm:outbound-endpoint path="chitchatter"/>
<payload-type-filter expectedType="org.mule.example.hello.NameString"/>
</filtering-router>
<vm:outbound-endpoint path="userErrorHandler"/>
<payload-type-filter expectedType="java.lang.Exception"/>
</filtering-router>
</outbound>
</service>
Greeter service component description
<service name="ChitChat">
<inbound>
<vm:inbound-endpoint path="chitchatter" transformer-refs="NameStringToChatString"/>
</inbound>
<component class="org.mule.example.hello.ChitChatter"/>
<outbound>
<pass-through-router>
<stdio:outbound-endpoint system="OUT" transformer-refs="ChatStringToString" />
</pass-through-router>
</outbound>
</service>
ChitChat service component description
3) Exercise
Now, we are going to add a new service component called "ChitPresenter" to the model. The new service component will be listening the channel that the Greeter component uses to send its message. The new component will add a presentation phrase like "My name is Diego" to the message payload, and send it to another channel where the ChitChat component is listening to.
For Homework
Change the expected data type of the service component you have already developed (if you have not already done) and build your own transformers. Also, add more inbound-endpoint to the Greeter component using different transport protocol such as http, axis, etc.
Lesson 2 - Stock Quote
Summary
In this section we will learn how to define service components using external services, invoking them using SOAP and REST. We will introduce the message filters by specifying conditions that the message should met to be routed to a service. In this lab we will create a new project based on the stock quote example and we will extend it based on the described scenario.
The lesson will cover the following aspect:
Custom filter implementation
External service invocation (REST and Soap)
Chaining routers, synchronous request.
1) The Stock Quote Scenario
The Stock Quote example consists of a service component that receives a company symbol as input and invokes an external service using REST and SOAP to get the stock quote of the company and return it to the user.
Now, lets suppose that we have the following new scenario:
The value provided by the component is not updated, in the sense that the value change very often and the data is only refreshed every 10 minutes. Therefore, we may get an outdated value from that service. Now, let suppose we want to add a new service for the GOLD customers who pay for a real time data. To achieve this we will develop a new service component that will return an updated stock quote value (fake service). Then, we will use the power of filters to dispatch the message to the corresponding channel by checking in the message payload if the user is gold.
We will start by creating a new application based on the stock quote example and learn how to define a component using external services.
Creating the application
Follow the same instruction described in lesson 1 for creating a new project and select the Stock Quotes Example instead.
Open the stdio-config.xml:
<service name="Console I/O">
<inbound>
<stdio:inbound-endpoint system="IN" synchronous="true"/>
</inbound>
<outbound>
<chaining-router>
<vm:outbound-endpoint path="stockquote"/>
<stdio:outbound-endpoint system="OUT"/>
</chaining-router>
</outbound>
</service>
The synchronous attribute in the inbound-endpoint element makes the component to recieve the message and the component processes before sending it out on another endpoint. HTTP/S, SSL, TCP, and Servlet endpoint are synchronous by default and do not require to set it.
The chaining-router element is a fast and lightweight configuration for sending message to an endpoint and then sending the result to the next endpoint. In the example the result of the service component that is listening on vm://stockquote will be the input for the next component which is the system out.
Configuring a service component using a REST service.
The following component uses an external REST service as the component of the service. It recieves the payload message containing the company symbol and invoke a REST service. The responseTransformer-refs="ToString XmlDecoder Xslt XmlToObject" indicates that after procesing the request, the resultant payload should pass through the following transformers:
XmlDecoder: decodes a String or byte[] containing xml entities
XSLT: transform the resultant xml into our desired format.
XmlToObject: map the xml to a java object.
<service name="HTTPPostSample">
<inbound>
<vm:inbound-endpoint path="stockquote"
responseTransformer-refs="XmlDecoder Xslt XmlToObject" synchronous="true"/>
</inbound>
<http:rest-service-component
serviceUrl="http://www.webservicex.net/stockquote.asmx/GetQuote"
httpMethod="POST">
<http:payloadParameterName value="symbol"/>
</http:rest-service-component>
</service>
Similar configuration is used to invoke with SOAP using axis, which is detailed in stockquote-soap-config.xml
2) Filters
The filters are used in order to specify conditions that a message must met to be routed to a service. Mule provides standard filters that we can use such as payload, or we can develop our own filter. Here is a brief summary of the filters implemented by Mule:
Payload Type Filter: check the class type
Expression Filter: it evaluates the payload using a range of expressions (JXPath, OGNL).
RegEx: for regular expression pattern.
Wildcar: it applies a wildcar pattern to the message payload.
Exception Type Filter: to match with an exception type
Message Property Filter: based on the property of the message.
Logic Filters: AND, OR, NOT logic filters.
More information about filters in Using Filters
There are some modules that provide their own filters such as the XML Module. To develop our own filter we need to implement the Filter Interface. An example of a configuration that we can use for the described scenario can looks like:
<outbound>
<filtering-router>
<vm:outbound-endpoint path="stockquotegold" transformer-refs="StockQuoteRequestToSymbolString"/>
<custom-filter class="org.mule.example.stockquote.FilterGoldUser"/>
</filtering-router>
<chaining-router>
<vm:outbound-endpoint path="stockquote" transformer-refs="StockQuoteRequestToSymbolString"/>
<stdio:outbound-endpoint system="OUT"/>
</chaining-router>
</outbound>
Here, we develop all the logic of our filter in the class org.mule.example.stockquote.FilterGoldUser, the class simple check if the user is gold returning true or false. If the filter return true, the message will go through channel vm://stockquotegold, otherwise will check the next router and dispatch to the vm://stockquote channel.
3) Exercise
Base on the described scenario, the exercise for this leason consist of extending the stock quote example by adding the stock quote service for gold customers (fake service). This new service returns the same object type (StockQuote.class) as the implemented service in the example when a stock quote is requested.
The student should create a filter that will check if the message comes from a gold customer. If the message mets the condition, it will be routed to the stock quote service for gold customers, otherwise it will be routed to the standard "free" service.
The application should be modified in order to receive as input the name of the person (for gold customer identification) and a company symbol.
Hints
Firts, create the new component which uses the same input format as the one in the example. Then, define a new object type for the input data (such as StockQuoteRequest) which contains the name of the person and the symbol. Finally, create the filter and transform the data before send the message.
Lesson 3 - Sales Broker (Pub/Sub)
Summary
In this lesson the student will learn how to implement a Mule ESB app using publish/subscribe messaging. In this lesson we will integrate an external JMS broker that is running in the cloud to our ESB application. The student will create the publisher and the subscribers thought the ESB application, and finally he will simulate a scenario by publishing message and adding dynamically subscribers to topics.
Scenario
Many companies notify to their costumers about promotion/discount of their products via pub/sub mechanism. Each company creates a topic on which they send the promotions of their products. The customers that are interested in recieving the promotions subscribe to that topic. The problem is that we are having many companies and the final user must know about them, even more he has to subscribe to each of them. Now, because we know about this problem and we want to make life easier, we are planning to provide to the end user a easier way to get the bargains. We will create an intermediate service (broker) that will subscribe to the topics of the companies/stores. Then, we will create our "Deals" topic in which we will send all the promotions to the end user in order that they can just subscribe to our service and receive all the promotions. We also want to clean a the data and send only the promotions that are really interesting. Therefore we will apply a filter to the message in order to check the percentage of discount, and if they are above a threshold we send to our topic.
Installing JMS Provider
Mule can work with a lot of JMS providers. In this lesson we learn also how we can easily integrate an external JMS provider (ActiveMQ) into our ESB project.
For this lesson we can either:
1) Use an active broker that i set up in the cloud (see if the proxy allows)
BrokerURL: tcp://ec2-184-73-34-161.compute-1.amazonaws.com:61616
2) Install ActiveMQ locally.
Go to http://activemq.apache.org/download.html and get the latest release of ActiveMQ.
Follow the instructions to quickly setup the jms broker provider.
Lets start..
Create a new Project
For this lesson we will create a new esb project from the scratch. Please follows the steps:
In Eclipse:
1) File->New Project->Mule->Mule Project
2) Create the configuration file inside the conf folder: RightClick->NewFile->mule-config.xml
Add the schema location for the modules and transport (mule/spring/jms/stdio/tcp)
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.mulesource.org/schema/mule/jms/2.2" xmlns:stdio="http://www.mulesource.org/schema/mule/stdio/2.2"
xmlns:spring="http://www.springframework.org/schema/beans" xmlns:ftp="http://www.mulesource.org/schema/mule/ftp/2.2"
xmlns:tcp="http://www.mulesource.org/schema/mule/tcp/2.2"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.mulesource.org/schema/mule/jms/2.2 http://www.mulesource.org/schema/mule/jms/2.2/mule-jms.xsd
http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
http://www.mulesource.org/schema/mule/stdio/2.2 http://www.mulesource.org/schema/mule/stdio/2.2/mule-stdio.xsd
http://www.mulesource.org/schema/mule/tcp/2.2 http://www.mulesource.org/schema/mule/tcp/2.2/mule-tcp.xsd">
<!-- Define here the configurations -->
</mule>
Now, set up the JMS provider (ActiveMQ) adding the following configuration to the file
<!-- Configure an ActiveMQ Connection Factory. -->
<spring:bean
id="jmsFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
<spring:property
name="brokerURL"
value="tcp://localhost:61616" />
</spring:bean>
<!-- the JMS connector we'll use -->
<jms:activemq-connector
name="mqConnector"
connectionFactory-ref="jmsFactory"
eagerConsumer="false"
username=""
password=""
specification="1.1"
maxRedelivery="4">
<spring:property
name="numberOfConcurrentTransactedReceivers"
value="10" />
<spring:property
name="maxDispatchersActive"
value="50" />
<spring:property
name="serviceOverrides">
<spring:map>
<spring:entry
key="message.receiver"
value="org.mule.transport.jms.MultiConsumerJmsMessageReceiver" />
</spring:map>
</spring:property>
</jms:activemq-connector>
Now lets proceed to create the service component that will subscribe to the company's topics. In the inbound router we set up the topics that our service component is subscribe to, using jms as transport protocol. In the outbound router we define our topic on which we will deliver the message after filtering the content. In this way, we put all the subscriptions in the inbound router and the publishing in the outbound.
Example:
For the inbounds
<jms:inbound-endpoint topic="store1" />
<jms:inbound-endpoint topic="store2" />
...
For the outbound
<jms:outbound-endpoint topic="TopDeals"/>
If you are using the cloud broker, please append a personal identifier to the topic in order to diferenciate your topic from other students (if you prefer to not share). Example: topic="mynameMyTopic"
Filter
Create a filter for the promotions base on some criteria. One possible criteria is to assume that the message will have the percentage of disccount, we parse the information y define a threshold that the message should met before send to our "deal" topic. For example. just send promotions that have at least 20% off.
Test your application:
Using ActiveMQ Administrator
You can use the administration web of the ActiveMQ to see your topics and the the current status.
If you are running locally, go to: http://localhost:8161/admin/topics.jsp and you should get something similar to this page. You can use the operations to send messages to any of the topics.
Using Java
You can also test it using java. Find on http://project-icebar.net/bpm/pub-sub/ two java files i have prepared, you can use the Consumer class for subscribing to a topic, and the producer class to publish in a topic. Put the java files into your Mule project in order to have the correct references for the javax.jms implementation.
Exercise
Finally, use the java files and simulate the scenario. You can create some topics and start publishing data (randomly). The service component will consume the messages, filter and publish the messages to our new topic. You can also create other service components in your Mule application.
Questions? you can reach me at: mussiATdisi.unitn.it