blabla...
bexee runs in a servlet container e.g. Apache Tomcat and thus ships ready to use in a web application archive (war) file. The war is divided into a number of components according to function that make up the entire application.
The accompanying illustration gives a rough overview of the main components that belong to bexee:
We will start from the inside out, explaining what the different components do and thus begin with the Engine Core component.
The Engine Core comprises all the business logic and knowledge about how to process a given BPEL document.
Most importantly this includes the BPELProcessFactory
for
creating a BPEL process given a BPEL document, the
ProcessController
for processing a BPEL process, the
Dispatcher
for looking up deployed BPEL processes and
executing instances as well as a number of other components.
As the name implies this is the core of the bexee engine, but of course there is a number of other supporting components that are needed, for making bexee a complete application.
As explained in the previous section, the provider has the key role for connecting bexee with Axis.
The Management component includes classes for deploying new BPEL processes to bexee and registering them as Web Services in Axis. Probably there will also be some classes that can be used to administrate the engine.
It is important to note that management components are deployed as Web Services into Axis. This allows for an open interface available to a number of various clients; e.g. web application front-ends, Ant tasks, etc.
As explained in the previous section we are using Apache Axis for processing SOAP messages. The Management and Engine Core components are deployed into Axis as Web Services.
The WebApp component includes Servlets, JSP's, HTML pages etc. offering more convenient access for querying or managing the engine. Note that the engine is always accessed through its Web Service interfaces. More detailed information on this component can be found in the bexee WebApp section further down in this document.
The Axis framework is a Java-based, open source implementation of the SOAP specification from the Apache Group. Essentially Axis is a SOAP engine, i.e. a framework for constructing SOAP processors such as clients, servers, gateways, etc.
Axis provides a flexible messaging framework that includes handlers, chain, serializers, and deserializers. The latter provide encoding support for a wide variety of XML Schema data types.
In the following sections we will describe how we extended, used and integrated Axis in bexee. It is assumed that the reader has a basic understanding of the Axis architecture and how Axis works. More information on the Axis project can be found on the Apache Axis web site [?].
Every BPEL process has to expose itself as a Web Service in order to be
triggered by clients who want to execute the process. We thus need to
process incoming Web Service request, i.e. SOAP messages, somehow
transfer the request to the bexee engine
(BPELProcessor
) for processing and after the process has
finished executing, send a meaningful SOAP message containing the
process result back to the client.
For processing SOAP messages we are using Apache Axis.
A provider is a special handler which handles incoming requests. Axis
provides a number of different providers. A JavaProvider
for example handles a request by invoking a method on a given Java class
and then returns the result back to the response flow. Usually this is
the default behavior for Web Services deployed in Axis.
Which provider shall be used for a given Web Service can be specified upon deploying the new service. The provider model is extensible, which means that you can plug in your own custom providers. Below you find a typical wsdd file used for deploying services into Axis. The service will be accessible under the name bexeeService and incoming requests will be handled by a custom provider.
Note that in the Axis vocabulary, providers are sometimes also called pivot handlers.
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="bexeeService" provider="java:BexeeProvider" /> </deployment>
As the above deployment descriptor shows, we use a special provider
called BexeeProvider
which we plug into the Axis engine.
Strictly speaking it is not the provider itself that is plugged into
Axis but rather a custom factory which will then create the provider of
the given type.
Below you find an excerpt of the factory and provider class together with the methods they implement:
public class BexeeWSDDProvider extends WSDDProvider { public Handler newProviderInstance(WSDDService service, EngineConfiguration registry) throws Exception { return new BexeeProvider(); } public String getName() { return "BexeeProvider"; } }
public class BexeeProvider extends BasicProvider { public void initServiceDesc(SOAPService service, MessageContext msgContext) throws AxisFault { // init the service } public void invoke(MessageContext ctx) throws AxisFault { // process message and invoke target service } public void generateWSDL(MessageContext msgContext) throws AxisFault { // generate the web service description } }
This means that we are using our own custom provider for connection Axis
and bexee: The provider takes the incoming SOAP message,
performs a number of checks (e.g. verifies whether the requested
operation can actually be performed by our process controller), puts all
the necessary information into a new BexeeMessage
and
dispatches it to the bexee engine.
Note that the BexeeMessage
contains no SOAP specific data,
just XML together with other information such as the operation name etc.
This allows for a decoupling of the bexee engine and thus
keeping it relatively independent from the SOAP protocol and Axis.
As soon as the provider receives the result back from the dispatcher, it will create a new SOAP response and hand it back to the Axis response flow, from where it will eventually be sent back to the client that invoked the service.
The following picture shows the connection between Axis and
bexee. If you've read the Axis architecture guide you may
notice that we simply replaced the provider on the left side of the
picture with our own BexeeProvider
.
For an explanation of what happens after a new BexeeMessage
arrives at the Dispatcher please refer to section TODO: link in the
architecture guide.
EngineConfigurationFactory is an interface used to construct concrete EngineConfigurationFactory instances.
public interface EngineConfigurationFactory { public EngineConfiguration getClientEngineConfig(); public EngineConfiguration getServerEngineConfig(); }
Each EngineConfigurationFactory implementation must also (directly) implement the following static method:
public static EngineConfigurationFactory newFactory(Object param);
Which engine configuration is to be used can be specified with either a
system property or using Apache Commons Discovery [?]. We used the
latter approach, which means that a file called
org.apache.axis.EngineConfigurationFactory must be created in the META-
INF/services directory in bexee.jar
. Inside this file the
fully qualified name of the class implementing the
EngineConfigurationFactory must be indicated.
Plugging our own BexeeEngineConfigurationFactory
into Axis
allows us to specify how the Axis server will be configured when it is
created.
We use this technique to make the bexee Manager Web Service available as soon as a new Axis server is created. For more information on this please refer to Deployment section further down in this document.
The BexeeEngineConfigurationFactory
extends the
EngineConfigurationFactoryServlet
in package
org.apache.axis.configuration
and basically doesn't do
anything else but making sure that the right server configuration file
is read in, when a new factory is created. The server configuration file
is stored as a wsdd file and includes - among other things - the
following service deployment information for deploying the Manager
Service.
<service name="Manager" style="message"> <parameter name="allowedMethods" value="*"/> <parameter name="className" value="bexee.admin.Manager"/> </service>
Probably the most important component is the AxisServlet
which was shamelessly copied from the Axis web application and handles
all Web Service traffic for bexee.
The routing of an incoming http request containing a SOAP message is
handled by the AxisServlet
, which runs inside the bexee web
application. It is the main entry point for every incoming Web Service
request. The URL pattern that will invoke the AxisServlet
is configured to /bexee/services/*
.
The AxisServlet
's duty is to take on incoming http
requests, process them and deliver them to the Axis engine, which will
finally invoke the target service or the provider to be precise.
The AxisServlet
is also responsible for creating a new
AxisServer
in case one has not been created already. To do
this, the AxisServlet
uses an
EngineConfiguratinoFactory
as described above and then uses
this information to create a new AxisServer with the help of a an
AxisServerFactory
.
The AxisServer
is only created once by the
AxisServlet
during the life time of the web application.
This is done upon the first request to the AxisServlet
and
the AxisServer
is then put in to the web application
context from where it will be retrieved for every subsequent request.