用Java调用.net的Web service
Web service可以提高interoperability,可以实现跨平台的应用……听起来不错。但真的做一下,还是有很多小陷阱。
下面是最近做的小例子,用Java Axis2作为客户端调用.net写的web服务。支持自定义的数据结构(这个不是那么简单……)。
准备:
1、下载axis2 ,注意,不要google “axis”,那个是旧版的,一定要google“axis2”,目前的最新版本是1.41。
2、Visual studio 2008,C#。 这个不用说什么了。
服务端:
在visual studio里写个hello world服务很简单,函数前加个[WebMethod]就可以。但是, 如果用到自定义的类,比如下面定义的person类作为GetUserInfoByPerson服务的参数:
namespace WebService1
{
public class Person
{
public string IdentityNumber
{
get { return m_IdentityNumber; }
set { m_IdentityNumber = value; }
}
private string m_IdentityNumber;
}
}
这时要注意,直接按Ctrl+F5后生成的wsdl不包括Person的定义。
正确的做法是加一行
[SoapRpcMethod(Action = "http://tempurl.org/GetUserInfoByPerson", RequestNamespace = "http://tempurl.org", Use=SoapBindingUse.Literal)]
代码如下:
[WebService(Namespace = "http://tempurl.org/")]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
[SoapRpcMethod(Action = "http://tempurl.org/GetUserInfoByPerson", RequestNamespace = "http://tempurl.org", Use=SoapBindingUse.Literal)]
// 不加这一句,wsdl中就不生成Person类型
public Person GetUserInfoByPerson(Person q)
{
Person p = new Person();
p.IdentityNumber = q.IdentityNumber+"123";
}
}
现在Ctrl+F5运行这个服务,假设地址是http://localhost:56765/Service1.asmx,那就可以在http://localhost:56765/Service1.asmx?WSDL里看到,Person的定义已经出现了。
客户端:
axis2有一个不错的quickstart教程。axis2目录下面samples\faulthandling这个例子值得参考,里面有详细的readme.txt和build.xml。
1、用axis2自带的wsdl2java工具生成代码框架:
%AXIS2_HOME%\bin\wsdl2java.bat -uri http://localhost:56765/Service1.asmx?WSDL -u -o <target dir>
这样会在target dir下生成一个目录,里面有现成的Person.java等代码。
2、写调用代码
在Eclipse里建好项目,加入axis2\lib目录下所有的jar包,把刚才生成的目录也拷进去。
然后可以写代码了:
package example;
import org.tempurl.*;
public final class MyClient {
public static void main(String[] args) {
try {
Service1Stub service1Stub = new Service1Stub("http://localhost:8080/Service1.asmx");
service1Stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);
Service1 service1 = service1Stub;
GetUserInfoByPerson req = new GetUserInfoByPerson();
Person personReq = new Person();
personReq.setIdentityNumber("123");
req.setQ(personReq);
GetUserInfoByPersonResponse response = service1.GetUserInfoByPerson(req);
PersonE personResponse = response.getGetUserInfoByPersonResult();
System.out.println("ID = " + personResponse.getIdentityNumber());
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意这一句!service1Stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);
不做这个设置,一开始我怎么都调用失败,Axis2报告说HTTP send recv出错(记不清楚错误信息了)。用tcpmon查看调用服务时的tcp传输,发现.net的web server根本不接受axis2的soap包。(btw,tcpmon是个不错的工具啊。)
google了很久发现原因是,axis2在做http传输时采用了“chunked”模式,而.net的web server不支持。
“axis中使用的是HTTP/1.0协议,而.NET和axis2使用的是HTTP/1.1协议,后两者的区别在于.NET未使用ns1的命名空间前缀打包SOAP请求,且axis2使用了Content-Encoding: chunked头。 所以必须在axis2中设置一下。”
总结:
web服务调用还是很麻烦的。除了上面列举的问题,还可能有soap协议版本1.1和1.2不兼容之类的细节问题。在调试这类问题时,tcpmon是必备工具。
刚才讨论了如何用java调.net服务。如果反过来,不知是否会简单一点。
最后,其实我一年前就写过axis2 1.3的代码……可是昨天,除了知道这件事可以用axis2做,所有的细节都忘光了。还是花半个小时记下来比较安全。
WS-CDL跟BPEL相比有什么价值?
问题:既然有BPEL标准,为什么又出了个WS-CDL? BPEL不够用的么?WS-CDL自身有什么优势?WS-CDL解决了bpel解决不了的问题么?
CDL描述问题的角度跟BPEL不同。与BPEL相比,BPEL强调的是以“我”为中心,描述我跟别人的交互;而CDL是从一个“导演”的层次来描述“他跟她交互,她再跟他交互”,导演要考虑各方如何协调演戏,但BPEL只考虑自己。总之,CDL从需求层面上描述不同 participant之间的交互过程,描述的是business protocol,或者说商业合同。
注意这里的一个前提是要存在多个不同的participant,这意味着我们描述的对象是跨组织的business process,此时CDL才能派得上用场。想象一个含有buyer、seller、bank、shipper等多方的场景,你可以写四个bpel流程,并把它们的并行作为这整个场景的描述,也可以写一个CDL流程作为这整个场景的描述。
既然用4个流程或1个流程都可以描述,那么CDL的好处是什么呢?在引入CDL之前,标准的开发流程是各方先定义自己的BPEL程序,然后把它们放在一起并行执行;这种bottom-up的方法可能会产生死锁等并行程序开发中固有的一些难题。
引入CDL后的开发模型是top-down的,先定义全局的CDL交互模型,然后用一个“编译器”从CDL自动或半自动地生成各方的BPEL描述;这样自动产生的BPEL代码一定不会死锁,一定跟全局模型一致(如果你的CDL到BPEL的“编译器”够强的话)。
必须客观承认的是,CDL还远远达不到工业应用的程度,目前的支持者只有Oracle,Adobe等“非主流”公司,上面所说的“编译器”还没有一个完美的实现。它还是比较新的一个东西,有很多地方人们还不清楚(但是正因为它不清楚,所以学术研究对它反而比较感兴趣)。而且,CDL是对需求的描述——在实际开发中,“需求”未必有人花太多功夫描述——这就是说,就算不引入CDL,还是照样可以开发;它不像BPEL是实现语言,必须采用。但这不代表CDL就没有用;打个比方,尽管严格进行需求分析的人不多,我们能说需求分析没有用么?
BPEL4People, HumanTask和BPEL2.0之间的关系
作为对BPEL的扩展,BPEL4People本来打算做一份规范,但是做到后面做成了两份,即BPEL4People和HumanTask,这两个规范要一起使用。下面我们用一个简单的例子说明它们之间的关系。
WS-BPEL2里定义了"extensionActivity",支持对标准BPEL进行扩展。BPEL4People则定义了一种特殊的extensionActivity,叫做peopleActivity,如下所示:
<sequence>
<extensionActivity>
<b4p:peopleActivity name="electEmployeeOfTheMonth"
inputVariable="candidates"
outputVariable="vote"
isSkipable="yes">
<htd:task name="votingTask">
...
</htd:task>
<b4p:scheduledActions>...</b4p:scheduledActions>
</b4p:peopleActivity>
</extensionActivity>
<assign>
<copy>
<from>$vote</from>
<to>$electionResult/votes[i]</to>
</copy>
</assign>
</sequence>
这个sequence先执行了一个peopleActivity,然后做了个赋值。注意peopleActivity是放在extensionActivity里面的,好让BPEL2.0引擎知道它是一个扩充活动。
BPEL4People仅仅定义了peopleActivity的接口,比如输入/输出变量,跟<invoke>的功能差不多,当然还定义了一些API函数用于取得一个peopleActivity的参数,比如可以通过getActualOwner得知,已经执行完毕的某个peopleActivity究竟是由哪个人做的。
而一个peopleActivity的主要细节,是通过WS-HumanTask来定义的,见上面例子中的<htd:task>部分。换句话说,BPEL4People规范的作用仅仅是连接WS-BPEL2.0和WS-HumanTask。下面是该HumanTask的具体内容:
<htd:task name="votingTask">
<htd:interface operation="vote" portType="el:votingPT"/>
<htd:peopleAssignments>
<htd:potentialOwners>
<htd:from>$voters/users/user[i]</htd:from>
</htd:potentialOwners>
</htd:peopleAssignments>
<htd:presentationElements/>
</htd:task>
这里只定义了该任务的potentialOwner,即哪些人有权限执行该任务;在<htd:task>里还可以定义很多细节,比如过多久之后会超时,超时后要执行什么动作(Escalation),等等。
可以说凡是跟“人”有关的东西,都定义在WS-HumanTask中。每个business process中可能需要定义一些角色,和一些人;这些"角色"和"人"也是由WS-HumanTask定义的,此外还预定义了几种角色,比如Administrator, Task initiator等。
总结一下,WS-HumanTask专注于“人”,与BPEL规范没有一点关系,甚至连名字都不一样——在BPEL中叫做Activity的东西到了这儿就变成了Task;而BPEL4People就是BPEL 2.0和HumanTask之间的桥梁。
要学习这两个规范,我建议先看WS-BPEL4People规范中的Appendix - D,这里给了个完整的例子。看过例子再读规范,就清楚得多了。
相关链接:BPEL4People规范阅读笔记
BPEL4People规范阅读笔记
下面是我前几天读WS-HumanTask和WS-BPEL4People规范时作的笔记,因为有太多术语,所以就直接用英文写了。不保证笔记的完全正确性,只是用于日后参考。
关于bpel4people的更多资料,请参考http://del.icio.us/tags/bpel4people上搜集的各个页面。
RBAC related basic concepts (Sec. 3, WS-HumanTask):
- organization
entity (a person or a group of persons. Must be linked to outer RBAC/LDAP user
database)
- logical group (roles of the process, i.e. "voters", "approvers".
Must be linked to outer RBAC/LDAP user database)
- generic roles (task
initiator, stakeholder, potential owner, excluded owner, admin, notification
receipient)
-
- process initiator/stakeholder/admin are defined in BPEL4People
spec. - person assignments (use an expression (literal, logical group, etc.)
to assign some people to some generic role) - e.g. we can assign logical
group "voters" as the potential owner of task "vote", or assign the "previous
approver" as the excluded owner of task "approve_2") - In other words, we
can define the potential owners of a task dynamically; thus we can do SoD and
BoD.)
- process initiator/stakeholder/admin are defined in BPEL4People
From a task's view: (Sec. 4, WS-HumanTask)
* A
task includes (page 23-36):
- service signature (input/output parameter,
operation name, etc) - people assignments, indicating who can do the task,
and who cannot, etc.- When a task is executed, it will have an "actual
owner".
- When a task is executed, it will have an "actual
- deadline requirements
- two kinds of deadline:
start/complete - can define multiple deadlines on different times with
different behaviors - If timeout, then calculate each escalation's condition,
and execute the corresponding behavior (behavior can only be either notification or reassign) - e.g. 1
hours after start -> notify manager, 2 days after start -> notify
director, 1 day after complete -> reassign task owner
- two kinds of deadline:
- delegation requirement
(to whom can we delegate the task? nobody/anybody/...) - attachment requirement, priority,
comment, represetation info., etc.
* A task's lifeline (page
37-38):
- created (by business process)
- ready (created, but no one
claims it yet) - researved (some potential owner claims it) [Note: delegate,
revoke(release) can be done in this state] - inprogress (some one starts it)
[Note: revoke, stop, delegate can be done in this state] - completed
- failed
(divide by zero, or the performer thinks it is a bad task) - obsolete (owner
skips it, e.g. the receiver discards a notification, or gives up the right to vote) - terminated (outer
scope terminates, or timeout) - a task can also be suspended and resumed
(I'm not clear about this yet)
* Notification (Sec. 5, WS-HumanTask)
- is a one-way, asynchronous human task
- can only assign "receipients" to a
notification, rather than "potential owners"
From a user's
view (page 42-54):
* Normal User
- claim, start, release, complete,
fail, delegate ... a task- use "remove" for notifications
- query
tasks (similar to a SQL select. can specify many parameters, e.g.
"Task.Priority=1 AND maxTasks=10")
* Administrator
- activate (set
status to Ready) - nominate (set potential owner to a specific person, and
set task status to - set role (change people assignment
dynamically)
From business process's view:
(WS-BPEL4People)
* A process includes:
- some logical group definition
(roles in the process, i.e. "voters", "approvers". Must be linked to outer
RBAC/LDAP user database) - person assignments of process generic roles
(process initiator, process admin, etc.) - human task definitions
- process definition, where each "human task" is wrapped in a "people activity",
whose syntax follows the spec of BPEL.- task definitions can be given
inside a people activity, at the beginning of the process, or elsewhere. (see
"constellations" on page 16) - a globally defined task's people assignment
or priority can be overidden in local people activity. - people activity's
state diagram is at page 27. (running, completed, obsolete, failed, terminated,
closed)
- task definitions can be given
First Impressions
* The idea
- Task owners can be
specified in a fine-grained way in the task definition, and can change
dynamically. - Many states for a task, many possible operations for a user
(which states/operations are important, which are not?) - Fine-grained
deadline support- to read: what if several escalation conditions have
overlap?
- to read: what if several escalation conditions have
- Two spec instead of one
- aims at the separation of
TaskEngine, TaskList, BPEngine, so that we can combine different products
together (see the official podcast)
- aims at the separation of
- Question: how to link logical group to actual
users? Can this link be changed dynamically by process admin?
* The spec
text
- Quite long, but quite easy to read (compared with the BPEL spec)
- Read the examples for a quick start!!! (The final sections of the specifications)
- Still some small errors in the spec
- e.g. page 54 has a typo
"assigment". - In the task state transition figure, the word "revoke" is used.
However it is called "release" in the text.
- e.g. page 54 has a typo
BPEL4People v1.0规范发布了
前两天我在我看BPEL4People这篇blog里,提到一些对BPEL4People的批评,包括它的规范拖了又拖不知道什么时候推出。经过了white paper发布后漫长的等待,BPEL4People终于发布了1.0版的正式规范,可以从IBM developer works下载:WS-BPEL Extension for People
制定者包括Active Endpoints, Adobe, BEA, IBM, Oracle, SAP AG。显然,微软是自己玩他的Windows workflow foundation去了。
开始读这份52页的规范吧~估计过几天就会看到一些评论了。
我看BPEL4People
近来比较关注BPEL4People。这是IBM和SAP提出的一个white paper,目标是给BPEL加上human workflow的功能。一共不到20页,很短很好读。
我觉得BPEL human workflow还是很必要的。在工作流的角度来看,BPEL太像一个编程语言,只是做了service composition,却没有考虑task list等问题;毕竟,多数工作流是要牵涉到人的,比如任何一个公文流转的流程。事实上大多数BPEL厂商都自行扩展了human workflow的支持。引述Bruce Silver的一段话:
The world of BPMS is divided into BPEL-lovers and BPEL-haters, and the thing that BPEL-haters seem to hate most is that even the not-yet-final 2.0 version of the OASIS standard "excludes" human tasks. How can you have a "business process" execution language that cannot accommodate human-performed activities? "Out of scope"?! Are you kidding?
不过,这份white paper迄今还没有变成一份规范;而且有些人批评说它多余,比如这篇Do We Need This Animal Called 'BPEL4People'?,这标题起的几乎有点刻薄了。Bruce Silver在他的文章中也表示BPEL4People有点“overly ambitious”,因为其中提出的5个interaction patterns的构想不太容易实现。
不管怎样,扩展BPEL使之支持human workflow的基本想法还是很好的,这一点Bruce Silver也同意。只是从具体的技术细节来看,BPEL4People可能还有一些不尽人意之处。上个月OASIS的BPEL Webinar上有人提问“BPEL4People什么时候出规范?“回答是”快了“。
6月1日的更新:
仿佛是回应我这篇blog一样
,ActiveBPEL昨天推出了ActiveBPEL for People,支持BPEL4People的大部分功能:
Key capabilities of ActiveBPEL for People include:
-- Extensions to ActiveBPEL Designer, the SOA community's leading BPELauthoring environment, that support the design, testing and deploymentof human-centric BPEL processes
-- New human interaction operations that are wrapped in Web services andinvoked as BPEL activities
-- Task Editor and Task Inbox controls that can be directly embedded intoSOA applications or used as templates for creating custom userinterfaces
-- An ActiveBPEL Task Services subsystem that creates and manages thecomplete lifecycle of human tasks
-- Alarm, escalation and notification services that allow human-centric
applications to be easily integrated with enterprise monitoring and
management infrastructures
-- An identity services infrastructure that integrates with popular enterprise directories to support roles and rights configurations - such as owners, users and administrators - of human tasks
-- Supports common workflow patterns:
-- Four eyes
-- Nomination
关于BPEL形式化的重要文章
最近经常有些朋友问我有关BPEL形式化、Web服务形式化等等的问题。推荐两篇文章如下:
- Models and Verification of BPEL
很好的survey,如题目所说,做BPEL模型和验证的人必看。(也提到了我们组的工作^_^) - Formal frameworks for workflow modelling
也是一个survey,但其出发点是workflow,视角似乎更广一点。重点比较了petri网、进程代数和逻辑演算三种方法。 - 此外,在学术界研究BPEL常遇到的问题是找不到例子。ActiveBPEL提供了不少例子,可以参考。
客观的说,国际上做BPEL形式化的人还是很多的……所以现在再做的话就要有一定的创新才行了。
最后闲扯一下~昨天看到一句话:”一流的科学家挖坑,二流的科学家灌水“。说的好。
WS-BPEL 2.0 Webinar总结
OASIS最近给出了两个关于WS-BPEL 2.0的视频讲座,可免费下载http://www.oasis-open.org/events/webinars/,很值得一看。最有趣的是最后有一段Q&A时间,提到了好几个人们对BPEL特别关注的问题。几点笔记如下,边听边记的,所以写的比较随意。
- event handling可以用于实现基于async的并行。想像有几个event同时发生,同时得到处理。
- correlation set用于实现LRT。区分多个instance,多个receive。
- assign用于做transform,可以用xsl来做,bpel不关心其变换细节。
- foreach可以通过设置一个参数使其所有的子scope并行的执行
- variable property作为一个alias,可用于分离process logic和数据的实际格式信息,主要用于correlation id
- isolated scope:用于对共享变量加锁(不是很懂)
- bpel2.0增加了rethrow, validate, terminationHandler,"join" correlation 等东西
- compensateAll v.s. compensateScope
提问中提到的问题:
- bpel4people: vague answer... near future会有新的update,目前还是只有那个white paper
- bpel vs. cdl: they are othogonal!!! different aspect(很高兴听到做bpel的人也承认cdl的价值了)
- bpel and bpmn: vague answer... omg and oasis are two different organizations。目前omg还是只有bpmn到bpel1.1的转换,不支持2.0
据说q&a部分的文本也会放在oasis网站上?迄今还未发现。
以下是对bpel基本知识的复习:(最近不怎么看bpel,有些细节还真的都忘了,这个视频是个很好的复习串讲)
- wsdl message和xml schema的关系:一个message分为多个part,每个part的类型是一个xml schema.
- portType里说明本process用到的各个wsdl operation,没有给出任何的role信息,也没说明哪些是本process提供的operation。
- partnerLinkType包含两个portType,并给这两个portType增加了各自相应的role信息,说明“谁”来提供这些operation。
- partnerLink里标明了partnerLinkType中的role是“my”还是“partner”,说明本process站在哪一边。
- receive说明了本process提供的operation是什么。(其实这么理解也不太合适,因为一个process未必就是rpc形式的,比如auctionService可能需要分别从buyer和seller处receive消息,然后再进行处理,最后分别通知buyer和seller)
- reply里写的operation必需与某个receive对应。(因为可能有多个receive)此时可以理解为RPC响应。
如果你对BPEL感兴趣,请参考我的BPEL和CDL专栏里的更多文章。
到底该怎么对business process建模?
不管是叫workflow还是叫business process,工作流/商业流程的建模一直是个重要问题。不幸的是,这一问题一直也没有个统一的答案——在学术界,“Petri网派”和“进程代数派”(主要是Pi演算)之间的口水战似乎从未停止过。
最早是有人写了一篇文章workflow is just a pi-calculus。然后,van der Aalst先生对此作了有力的批驳,除了Why workflow is not just a pi calculus,还有一篇文章Pi calculus versus Petri nets: Let us eat “humble pie” rather than further inflate the “Pi hype”包括了对Pi Calculus局限的分析,提出了不少“challenges”,其中的关键就是pi calculus不能支持所有的patterns。
最近又看到一篇文章:Why do we actually need the Pi-Calculus for Business Process Management,其中还引用了"eat humble pie"一文,可以看作“进程代数派”对“petri网派”的反击。文章指出petri网的缺点在于
1)static structure,不支持动态变化的结构(应该是指mobility)
2)不支持高级composition construct,比如递归。
虽然存在一些对petri网的扩展以解决这些问题,但这些扩展都会导致复杂度过高。
而pi演算就没有这些问题,而且支持mobility。作者认为mobility非常有价值,并举了一个例子来说明之。
此外,作者还提出了web service时代导致workflow模型的几点新变化:
1)从基于状态的系统转为基于message的系统
2)从central engine到分布式服务
3)从closed到open的环境(指的是mobility)
我个人是倾向于process algebra的。