Archive

Archive for the ‘BPEL’ Category

Exploring ODE Part III: architecture and modules introduction

January 30, 2010 Leave a comment

In this blog entry, we will continue to explore the ODE source code. Typically, we should see the ODE’s architecture in our first part of this series, but here I put it in the third part, as at that time, I was just trying to write a blog entry about the ODE’s inner model about bpel file, didn’t thought I will write this as a series.

Anyway, lets see the ODE’s architecture diagram, which I copied it from the ODE’s architecture wiki page.

On our first part, we look at the bpel compiler module, and we look at the JACOB framework on our second part.

In this part, we will try to make an introduction to ODE’s modules:

ODE core modules
1.bpel-api: It contains the api definition for ODE, some important packages are:

  • org.apache.ode.bpel.iapi: this is for integration interfaces, like Axis2 module will implement it.
  • org.apache.ode.bpel.rapi: these interfaces are for runtime api that are implemented in the bpel-runtime module.
  • org.apache.ode.bpel.pmapi: this is for the process management.
  • org.apache.ode.bpel.evt: this is for the event.

2. bpel-runtimes: this module takes care of implementing the Bpel’s Activities, like INVOKE, REPLY, WAIT by extending the JacobRunnable Object, also it is the place that includes the internal model for compiled Bpel file, and Channel definition. You would notice that it has v1 and v2 packages, thats for ODE 1.x and ODE 2.x respectively.
3. bpel-dao: this module is the API for DAO layer, currently, it doesn’t include the DAO API for process store.
4. dao-jpa: currently it is the openjpa implementation for DAO.
5. dao-jpa-db: This is the DDL script for openjpa’s impl.
6. dao-hibernate, dao-hibernate-db: these two are the Hibernate’s impl for DAO, and its DDL scripts.
7. bpel-schemas: this is module that use xmlbeans to generate Java objects from xsd schemas, they are: deploymentDescriptor, (dd.xsd), pmapi.xsd (Process Management API), schedules.xsd, context.xsd.
8. bpel-scripts: this module is having those bpel files, it is used in bpel-compiler’s test case.
9. bpel-compiler: this module is to convert the bpel file into ODE internal model for compiled bpel file.
10. il-common: this module is the common integration layer.
11. scheduler-simple: this module is the implementation of scheduler service.
12. bpel-store: this is the module takes charge of storing process from the filesystem, the artifact includes deploy.xml, .bpel, wsdl artifacts.
13. engine: this is the ode engine that uses the runtimes, dao, scheduler services.
14. bpel-ql: bpel query language.

JACOB framework module
1. jacob-ap
2. jacob

Integration modules:
1.axis2 integration: axis2, axis2-war
2.jca integration: bpel-api-jca, bpel-connector, jca-ra, jca-server
3.jbi integration: jbi
4.extension: extensions

some leftover modules are:
1. tools: this is for the bpelc, sendsoap command line.
2. utils: utils for ODE project.
3. tasks: this is tasks for buildr tool.
4. distro: this is the module for building distro.

Categories: BPEL, ODE, Riftsaw

Exploring ODE Part II: JACOB Framework

January 27, 2010 Leave a comment

In this blog entry, we will look at the ODE’s jacob framework, which is of a library taking care of concurrency processing. ODE use this lib underlying to solve the concurrency problem, ODE has a very good wiki explains about this framework, but here I would like to highlight some concepts and introduce a simple example in the end.

Firstly, I am reusing the wiki page’s example. Say we have a following process.

1.invoke
2.receive
3.wait
4.invoke

and we have 2 parallel execution of the process, without Jacob framework the execution would be:

1. Invoke1
2. Receive1
3. Wait1
4. Invoke1
5. Invoke2
6. Receive2
7. Wait2
8. Invoke2

so the above is totally sequentially, no concurrency at all. With the jacob framework, we might see following execution order.

1. Invoke1
5. Invoke2
2. Receive1
3. Wait1
6. Receive2
7. Wait2
4. Invoke1
8. Invoke2

From a client standpoint, we’ve achieved concurrency of execution even with one thread.

Now, we will see following concepts in jacob:

1. JacobRunnable, JacobObject
In the wiki page, the JacobRunnable, JacobObject is described as a simple closure. Just like above example shows, here we abstract the action like ‘Invoke, Receive’ etc as a JacobRunnable object. Personally I also see JacobRunnable as a command pattern, which implements the run method.

2. Channel
Once we have had the JacobRunnable object, how do we connect two JacobRunnable objects? in other words, how do we invoke the wait activity after the invoke in our above example. Here is where Channel comes to play, its function is to build connections between JacobRunnable. The Channel implementation is used JDK’s dynamic proxy, you can see it from ChannelFactory.

3. ChannelListener
In the wiki page, it is referred as MLs (MethodList), but I’d prefer to call it as Listener. With introduction of Channel object, we are able to pass the Channel object into our next activity or child activity, but we need to have a listener mechanism for the parent activity so that once the child activity finished, it is able to get notified and continues the flow.

4. @ChannelType annotion
In the Jacob, we are using the ‘@ChannelType’ annotation to generate the Channel and ChannelListener interfaces in the compile time.

5. JacobVPU, ExecutionQueueImpl
As wiki page said, here are the responsibilities of JacboVPU and ExecutionQueueImpl.
1) JacobVPU is the place of Jacob processing.
2) ExecutionQueueImpl is the container for all artifacts (mostly channels and reactions) managed by JacobVPU.
3) JacobVPU is also responsible for persisting its internal state, like serialize or de-serialize the object.
4) Continuations (and hence JacobRunnables) don’t “stay” in the VPU queues. They just get popped, executed and that’s it.

Now, I will introduce an example that works with Jacob API to accomplish the above example. we are having three JacobObjects(Continuation), they are INVOKE, RECEIVE, WAIT. But for the simplicity purpose, I will just have INVOKE and RECEIVE. Also we will add a channel for their communication, I called it Demo, here is the code for Demo Channel.

@ChannelType
public interface Demo {
public void onSuccess(String successInfo);
public void onFailure(String errorString);
}

as you read from the code, we are having two methods, one for successful case, the other is for failure. use either the maven tool or buildr, you would see the generated classes for this interface, they are DemoChannel and DemoChannelListener.

Next, we will see actions.

static class INVOKE extends JacobRunnable {
private DemoChannel _channel;

public INVOKE(DemoChannel channel) {
_channel = channel;
}

@Override
public void run() {
System.out.println("INVOKE Activity");

DemoChannel demoChannel2 = newChannel(DemoChannel.class, "demo2");
instance(new RECIEVE(demoChannel2));
object(new DemoChannelListener(demoChannel2) {
public void onSuccess(String successInfo) {
System.out.println(successInfo);
_channel.onSuccess("INVOKE Done...");
}

public void onFailure(String errorString) {
System.out.println(errorString);
}
});

}
}

static class RECIEVE extends JacobRunnable {
private DemoChannel _demoChannel;

public RECIEVE(DemoChannel demoChannel) {
_demoChannel = demoChannel;
}

@Override
public void run() {
System.out.println("Receive Activity");
_demoChannel.onSuccess("RECEIVE success...");
}
}

For this example, I will add another action to start our process, it is called Process.

static class Process extends JacobRunnable {

@Override
public void run() {
DemoChannel channel = newChannel(DemoChannel.class, "demo");
instance(new INVOKE(channel));
object(new DemoChannelListener(channel) {
public void onSuccess(String successInfo) {
System.out.println(successInfo);
System.out.println("Process Done");
}

public void onFailure(String errorString) {
System.out.println(errorString);
}
});
}

}

We will talk from Process class, basically, we’ve created a DemoChannel, and then we use ‘instance(…)’ method to add the ‘activity/JacobRunnable’ into the queue, use the ‘object(….)’ to define a listener for that channel.
In the INVOKE class, we’ve created a child activity that is called RECEIVE. Which puts RECEIVE class as part of INVOKE class. I know this is a bad example, it would be much better if I use a composite activity, like While or Sequence, but you know I am just being lazy. 😉

At last, we will use following code to execute this example:

public static void main(String[] args) throws Exception {
ExecutionQueueImpl soup = new ExecutionQueueImpl(null);
JacobVPU vpu = new JacobVPU(soup, new Process());

while(vpu.execute()) {
}

}

Run this method, you would get following output.

INVOKE Activity
Receive Activity
RECEIVE success...
INVOKE Done...
Process Done

If you want to look at the code by yourself, it lies in the ode-jacob module, it extends the ode-jacob-ap module. Below are some classes that you’d look into. CommSend, CommRecv. Jacob wraps the JacobRunnable as CommSend, wraps the ChannelListener as CommRecv. And then uses the CommGroup to do the match.ExecutionQueueImpl is the container for Continuation, ExecutionObject, Channel etc. In the ExecutionQueueImpl class, you would find couple static classes, like ChannelFrame, MessageFrame… these classes are mostly used for serialized and de-serialized the object.

Categories: BPEL, ODE, Riftsaw

Exploring ODE Part I: Bpel Compiler and its internal model.

January 26, 2010 Leave a comment

In the Apache ODE, it has a bpelc, bpelc.bat script for you to compile the bpel file into ODE specific format file. We can use this tool to verify whether the bpel file’s semantic is correct or not.

So in this blog entry, we will take a closer look at the architecture of this tool, (also known as bpel-compiler module). The ode-tool module is just a wrapper for bpel-compiler module.

Firstly, lets look at the bpel object model for BPEL file, it is known as ‘bom’ (bpel object model, I guess) in the source file. It put all of bpel object model into this package, and its base class is BpelObject, this base class extends the sourceLocation which is for keeping detail info of original bpel file. some known subclasses are: IfActivity, PartnerLink, PartnerLinkType, SequenceActivity etc. These subclasses share one feature, their constructor parameter type is Element.

Second concept here is called ActivityGenerator, as name implied, it is taking care of generating the Activities, like IfActivity, InvokeActivity, SequenceActivity.

The other concept is called OBase, this class is a base class for compiled bpel object, the known subclasses are: OAssign, OInvoke, which both extend from OActivity, others are like: OPartnerlink, OProperty..

So in the bpel-compiler module, the work procedure is convert the bpel file into BOM, and then using AcitivityGenerator to convert them into OBase (ODE inner Object model).

If you want to look at the source code, you can start with BpelC class, the method for it is called compile(File file), in this method, you would find it uses the BpelObjectFactory to convert the xml file into BOM, and then get the correct BpelCompiler implementation to convert the BOM object to compiled object representation. (objects extends OBase class).

In the bpel-compiler module’s test part, we are using the bpel files that are put in the bpel-scripts module, to do the unit test. If you want to learn about the bpel’s activity, this is also a good resource.

Categories: BPEL, ODE, Riftsaw

PartnerLink,PartnerLinkType详解

September 28, 2009 Leave a comment

记得我在看BPEL的时候,总是对PartnerLink和PartnerLinkType概念比较混淆,特别是里面的partnerRole, myRole属性的疑惑,后通过查阅资料,觉得理解得差不多,特分享自己的学习笔记.

BPEL的出现,最主要是想提供一个业务流程(process)的语法,从另外一个方面,也就是想对已有的服务(这里限定于发布成web service的服务)进行一系列的编制(orchestration),然后变成一个新的服务(默认也是发布成web service). 这从一方面来说,也算是重复利用了已有的服务.

BPEL Process主要包括了Activity的概念,里面有包括最基本的Receive,Invoke, Reply等primitive Activity,也包括了strcture activity,比如sequence, flow, case等. 那既然我们定义了这些activity,又是怎么跟外部的已有服务进行联系上呢. 那么就是通过我们所要讲的PartnerLink, PartnerLinkType来关联.

我们先来看下PartnerLinkType. 我比较赞同把PartnerLinkType比喻成通道{Note: 来自于reference[2]的文章}. 可以这么想, BPEL Process是一个web service,这个服务是通过什么方法来与其他已经存在的另外一些web service(s)进行关联呢?PartnerLinkType就是定义这样的一个通道.

先看下PartnerLinkType的例子.


<plnk:partnerLinkType name="AuctionHouse_SellerLT">
<plnk:role name="AuctionHouse" portType="tns:sellerPT" />
<plnk:role name="Seller" portType="tns:sellerAnswerPT" />
</plnk:partnerLinkType>

注意这里定义的role可以有1个或者2个,在这个例子当中,我们看到的是2个,代表着需要两个portType(类似Java的Interface)来完成这个通道.这种情况一般是属于异步(Asynchronous)的情况. 我们也可以看做是2个的叫做双向,1个的叫做单向. 1个的一般直接是同步(Synchronous)的,可以直接获取到结果的,不用向异步那样需要一个回调方法(callback).

介绍完PartnerLinkType,可以把PartnerLink想做是PartnerLinkType的实例化.但有点不同的是,在上面我们讲到PartnerLinkType是有单向和双向的,在双向的情况下,那到底是哪个方向呢?比方说,到底是从A ->B 还是从 B -> A呢? PartnerLink的定义就会明确规定了这个方向,比如说:


<partnerLink name=”seller”
partnerLinkType=”AuctionHouse_SellerLT”
myRole=”AuctionHouse” partnerRole=”Seller”
</partnerLink>

注意到这里的myRole和partnerRole的属性,这两个属性指明了PartnerLinkType的方向. 这里, MyRole是指BPEL Process, partnerRole是指外部的we service. 那么,这个例子当中就是,这个通道是从bpel process流向exernal web service.也就是有个请求发送到bpel process,然后bpel process通过这个通道,调用到外面的web service,然后外部的web service再传递结果给bpel process.

这里,我们还得看下单向的情况(也就是在定义PartnerLinkType时,只有一个role的). 比方下面的这个例子.


<plnk:partnerLinkType name="loanPartnerLT">
<plnk:role name="loanService" portType="tns:loanServicePT" />
</plnk:partnerLinkType>
<plnk:partnerLinkType name="loanApprovalLT">
<plnk:role name="approver" portType="tns:loanApprovalPT" />
</plnk:partnerLinkType>

再看PartnerLink的定义.


<partnerLink name="customer"
partnerLinkType="lns:loanPartnerLT"
myRole="loanService" />

<partnerLink name="approver"
partnerLinkType="lns:loanApprovalLT"
partnerRole="approver" />

在这里,第一个customer的partnerLink定义,说明这个管道是从bpel process这个方向开的,也就是说Request的message应该是发到 Bpel Process. 相反的,第二个approver是属于partnerRole,也就是说这个Request Message应该是BPEL Process发给 partner (也就是外部真正提供服务的web service).

可以推知,凡是partnerLink中定义了myrole的地方,都是外界要调用bpel process的地方,必然对应receive操作.

注意,因为这个PartnerLinkType是WSDL的一个扩展点,所以很多时候,对于这个PartnerLinkType就直接定义在WSDL文件里,而不放在.bpel文件中.

[Reference]
0. WSBPEL 2.0 specification
1. PartnerLinks and PartnerLinkTypes
2. BPEL中的PartnerLink和PartnerLinkType

Categories: BPEL, Chinese