Working with Business Processes and Enterprise Service Bus
In this assignment we will learn about the SOA architectural style of
enterprise service bus (ESB). An ESB provides endpoints to which
heterogeneous services can be plugged in readily. The burden of
interoperability is on the ESB. We will also learn to use a business
process manager to orchestrate the execution of the services on the bus.
Interestingly, a business process itself can be plugged to an ESB as a
service. This (look for "Basic ESB Patterns") is a good introduction to the concepts of ESB. Do not worry about the IBM specific details.
The final goal of this assignment is to develop and deploy a travel
agent business process that interacts with an air ticket reservation
service, hotel reservaion service, and payment service for making travel arrangements.
We intend to de-emphasize the specifics of the travel (city, dates,
passengers etc.). Instead, the emphasis is on the concepts of ESB.
Specifically, the travel agent process is started by receiving a travel
request though a JMS gateway. The arrival of the request triggers the
start of a business process. The process then interacts with the air
reservation and the hotel reservation services. These services are internal to
the bus. Further, the process should be capable of handling faults
(failed reservations) returned by the air and hotel services. If only
one of the reservation succeeds, then it must be rolled back via
compensation (simply by sending appropriate messages to the air or hotel
service for cancellation). Once both, air and hotel, reservations succeed
the process moves on to accept payment. If the payment fails the
entire process is aborted by sending cancellation to both air and hotel.
The picture below shows the overall ESB configuration for this
assignment. You will develop the light blue boxes (some start code may
be provided for some of the components).
Notes / Updates:
Updates will be posted here.
The environment
CSC_750/450_P2
An image (CSC_750/450_P2) containing the
preinstalled environment is available for you on VCL. If you want to
get your hands dirty for your own sake and install the environment for
yourself here are some tips. Note: The VCL image is the reference environment, please ensure that your projects work on it.
- You should be in the "Java EE" perspective in eclipse
which has a server's tab on the bottom section of the UI. To start the
ESB server that you created simply right click on the server and select
start. The console tab should pop-up and show the output from the
server. (screenshot (not exact))
- After the server is started go to http://localhost:8080/jbpm-console/ and login as manager. There should not be any process in the process manager yet.
- To add your process open the processdefinition.xml file in
Eclipse. At the bottom of the editor click on the deployment tab. Click
test connection to make sure everything is working and then click
"Deploy Process Archive" to install the process on the server. (screenshot)
- Go back to the console in step 2 and refresh. The process that you just uploaded should now appear in the UI.
- To deploy your services to the ESB simply right click on your project name go to Run As --> Run on Server (screenshot)
- Then select the server (the same one you started in step 1) from the list. (screenshot)
- To test the ESB services and business process you need to
execute the SendJMSMessage.java class by right clicking on the class
name and going to Run As --> Java Application. (screenshot)
- The program in the previous step sends a JMS message to the
server, which triggers the business process. The process in turn calls
various services on the ESB who print their results to the ESB console.
If you see their output on the console tab then you know you have
completed the steps properly.
Modifying the Project
ESB
You are responsible for adding 3 additional services to the ESB. The
services can either be implemented in java or groovy but must have the
following interfaces
- Payment Service
- Name: PaymentService
- Input Message Components
- makePayment (Integer) -- Payment amount
- paySucceed (boolean)
- Output Message Components
- paySucceeded (boolean)
- AirService
- Name: AirService
- Input Message Components
- bookAirTickets (Integer) -- Number of air tickets to book
- cancelAirTickets (boolean)
- airBookingSucceed (boolean)
- airlines (String)
- customerName (String)
- Output Message Components
- airTicketsBooked (boolean)
- airTicketsRefunded (boolean)
- airBookingRefNum (String) -- A reference number generated by Air Service
- Hotel Service
- Name: HotelService
- Input Message Components
- reserveHotel (Integer) -- Number of hotel rooms to book
- cancelHotelReservation (boolean)
- hotelReservationSucceed (boolean)
- customerName (String)
- Output Message Components
- hotelReserved (boolean)
- hotelReservationRefunded (boolean)
- hotelReservationRef (String) -- A reference number generated by Hotel Service
The services are always to print the booking or reservation reference string to
the console when they are invoked. The following logic is then invoked
according to the values of the input message components.
-
if bookAirTickets > 0 AND airBookingSucceed == true then print "$airlines AIR BOOKING SUCCEEDED FOR $bookAirTickets; CUSTOMER: $customerName; BOOKING REF # $airBookingRefNum;" AND set airTicketsBooked = true.
-
if reserveHotel > 0 AND hotelReservationSucceed == true then print "HOTEL BOOKING SUCCEEDED FOR $reserveHotel; CUSTOMER: $customerName; RESERVATION REF # $hotelReservationRef" AND set hotelReserved = true.
-
if bookAirTickets > 0 AND airBookingSucceed == false then print "$airlines AIR BOOKING FAILED FOR $bookAirTickets; BOOKING REF # $airBookingRefNum;" AND set airTicketsBooked = false.
-
if reserveHotel > 0 AND hotelReservationSucceed == false then print "HOTEL BOOKING FAILED FOR $reserveHotel; RESERVATION REF # $hotelReservationRef" AND set hotelReserved = false.
-
if cancelAirTickets == true then print "$airlines AIR BOOKING CANCELLED FOR $bookAirTickets; BOOKING REF # airBookingRefNum" AND set airTicketsRefunded = true.
-
if cancelHotelReservation == true then print "HOTEL RESERVATION CANCELLED FOR $reserveHotel; RESERVATION REF # hotelReservationRef" AND set hotelReservationRefunded = true.
-
if makePayment > 0 AND paySucceed == true then print "PAYMENT PROCESSED FOR AMOUNT $makePayment" AND set paySucceeded = true.
-
if makePayment > 0 AND paySucceed == false then print "PAYMENT FAILED" AND set paySucceeded, airTicketsBooked = false, hotelReserved = false.
Furthermore, the following assumptions can be made in regard to the implementation of the service logic found above.
-
bookAirTickets and cancelAirTickets will never be set to true at the same time.
-
reserveHotel and cancelHotelReservation will never be set to true at the same time.
- the boolean values should be stored as case-sensitive strings, which are "true" and "false".
- if a boolean value isn't explicitly referenced in the above
if/then statements then it should either be set to false or omitted from
the input/output.
Business Process
The business process you have been provided only extracts the variables
from the XML and prints them to the console. You are responsible for
expanding that process to concurrently execute the air and hotel booking
services (fork operation) and combining their results (join operation).
After receiving their results you must cancel the air booking if the
hotel failed and vice versa (decision operation). If both succeed,
you proceed to payment. If payment fails, you cancel air and hotel.
The easiest way to modify the process is by using the visual editor within eclipse in conjunction with the jBPM console (http://localhost:8080/jbpm-console/). In addition to modifying the process you must rename the process to "[unity_id]_TravelProcess".
Deliverables
Submit your entire eclipse project as a zip file named as
[unity_id]_p2_esb.zip. You can create the zip file by either using the
export wizard (general archive) feature within eclipse or by using the
zip command on the project folder in your OS's filesystem viewer. Thoroughly document your processdefenition.xml explaining the purpose of every node, join, fork and decision. Make sure processimage.jpg represents the final version of your processdefenition.xml.
You also need to submit a README.txt file containing your name, unity id, section number, and any special
instructions for your submission.. The README can also contain a
description of the functional sections of the program as well as any
errors that have prevented you from submitting a completed project. The
more detailed a description of the work you have put in (not stack
traces) will increase the number of points you can be awarded.
Please note that the VCL image is the reference environment for
grading, so before submitting your project ensure that it works on the
VCL image correctly.
Testing and Grading
We will test your projects in the following way. First we will import
your project into eclipse and deploy your business process to our
server. Then we will send in a series of travel requests from our JMS
Client which will test your services and process. Examples of the tests
are...
- We will check that when payment, air and hotel services are asked to
succeed, all services are successfull and no compensation happens.
Here is the test Case1:
Input:
bookAirTickets=3, reserveHotel=3, airlines=American Airlines, customerName=John, cancelAirTickets=false, cancelHotelReservation=false, airBookingSucceed=true, hotelReservationSucceed=true,
makePayment=300, paySucceed=true
Expected Output:
American Airlines AIR BOOKING SUCCEEDED FOR 3; CUSTOMER: John; BOOKING REF # X;
HOTEL RESERVATION SUCCEEDED FOR 3; CUSTOMER: John; RESERVATION REF # Y;
PAYMENT SUCCEEDED for 300
- We will check that when only one of air and hotel is asked to
succeed, that one service successfully books while the other fails.
Then, the successful service should be compensated (cancelled) to ensure
the desired "all or none" behavior.
Input (listing only for the case when air fails; what changes from case 1):
airBookingSucceed=false
Expected Output:
American Airlines AIR BOOKING FAILED for 3; BOOKING REF # null;
HOTEL RESERVATION CANCELLED for 3; RESERVATION REF # X;
PAYMENT CANCELLED FOR 300
- We will check that when both air and hotel are asked to fail, that both services fail and no compensation happens.
Input (listing only what changes from case 1):
hotelReservationSucceed=false, airBookingSucceed=false
Expected Output:
American Airlines AIR BOOKING FAILED for 3; BOOKING REF # null;
HOTEL RESERVATION FAILED for 3; RESERVATION REF # null;
PAYMENT CANCELLED FOR 300
- We will check that when payment fails, that both air and hotel services are compensated (canceled).
Input (listing only what changes from case 1):
paySucceed=false
Expected Output:
AIR BOOKING CANCELLED for 3; BOOKING REF # X;
HOTEL RESERVATION CANCELLED for 3; RESERVATION REF # Y
PAYMENT FAILED FOR 300
- You will need to create and deploy queues for each service that you add.
- Figure out what jboss-esb.xml and jbm-queue-service.xml do?
You will find extensive details here.
specifically here
- To figure out what processdefinition.xml does:
You will find extensive details here.
- JBoss jPDL Documentation can be found here. jPDL is the language the business process spec is written in.
- Post your general questions regarding P2 here.
We will not provide
support for the following steps. However, you can ask on the message
board and perhaps other students who have encountered a similar
situation could help.
JBoss ESB Server
Download the JBoss ESB Server 4.8 (download link)
zip file to your machine and then unzip the contents into the directory
of your choosing. Remember where you installed it because you will need
to provide the location at a later step.
Eclipse (Galileo)
To make the development process easier we will be using some Eclipse
plugins provided by JBoss. To install the plugins use the Eclipse
update manager (found under the help menu) and add the following remote
site and install "JBoss All Tools"
- http://download.jboss.org/jbosstools/updates/stable/galileo/
After installing the plugins and restarting the next step is
to create the ESB project. To to so follow the instructions below...
- Go to the add project wizard and select the ESB Project Type (screenshot)
- Enter
the project name of [unity_id]_soc_project2, select the JBoss ESB
version , and finally click the new button next to the Target Runtime (screenshot)
- In
the new server runtime wizard select JBoss 4.2 Runtime from the JBoss
folder also make sure to select the "Create a new local server" option
before clicking next (screenshot)
- On
the next screen of the wizard set the server name to "JBoss ESB 4.8",
browse to the folder where you installed the server, then select the
1.5 JVM if it is available on your system, and finally click the next
button (screenshot)
- In the create server screen set the name of the server to "JBoss ESB 4.8 Server" and click finish (screenshot)
- You
should now be back to your original create project screen but now the
Target Runtime is filled in, double check the values and click finish (screenshot)
- The final step is to copy the following files into the specified directories
back