Tempo研究之FDS

 Tempo FDS是什么组件,就不多解释了,参考我的 Tempo针对BPEL4People的实现构架 这篇blog即可。

在往下说之前,有必要阐述两个FDS内部的概念:User Process 和Workflow Process。User Process其实代表是bpel engine所处理的process,而Workflow Process则代表Tempo这边所关注的people task的处理。——这两个概念刚开始时令人混淆的,至少我在一开始跟踪代码的时候是理解反了。

当Intialo BPM engine(内部apache ode bpel engine)在启动一个process的时候,如果碰到一个People Activity,则会向Tempo FDS发送一个create task的请求(UP-->WP)。当Task执行人完成task,并提交的时候,FDS向User Process发出notifyTaskCompletion请求(WP-->UP)。这中间tempo内部各个组件之间的调用关系和执行顺序,可以参考 http://www.intalio.org/confluence/display/TEMPO/Creating+and+Completing+a+Task 这上面的详细内容。

在FDS内部的实现逻辑大约是这个样子的:


FDS来回所对应的都是http请求和响应,所以消息都是由FormDispatcherServlet这个serlvet接收并处理的。

如果FDS接收的请求url是以 /fds/workflow/ib4p结尾的,则表示是WP-->UP的过程;否则是UP-->WP的过程。

建议在 Intalio\Server\var\log目录下的 server-log4j.properties(这是一个log4j的配置文件)中,增加对 org.intalio.tempo包结构的DEBUG日志信息输出,可以在 D:\Intalio\Server\var\log\geronimo.log 跟踪输出,这样可以查看来回的request/response message的xml消息格式,以及详细的处理过程。

Tempo FDS本身内部实现并不是很复杂,逻辑比较简单,主要是消息的来回转换。

一下是一个complete task处理的后台日志,方便看看具体的实现逻辑:
19:52:45,937 DEBUG [org.intalio.tempo.workflow.wds.servlets.WDSServlet] [SocketListener2-22] doGet [email protected]
19:52:45,937 DEBUG [org.intalio.tempo.workflow.wds.servlets.WDSServlet] [SocketListener2-22] Resource URI: 'PeopleActivity/PA.xform.xsd'
19:52:45,937 DEBUG [org.intalio.tempo.workflow.wds.servlets.WDSServlet] [SocketListener2-22] Participant token: ''
19:52:45,937 DEBUG [org.intalio.tempo.workflow.wds.servlets.WDSServlet] [SocketListener2-22] Retrieving the item.
19:52:45,937 DEBUG [org.intalio.tempo.workflow.wds.servlets.WDSServlet] [SocketListener2-22] Sending the data..
19:52:45,937 DEBUG [org.intalio.tempo.workflow.wds.servlets.WDSServlet] [SocketListener2-22] Item retrieved & sent OK.
19:52:46,828 DEBUG [org.intalio.tempo.workflow.auth.n3.N3AuthProvider] [SocketListener2-19] Token 'VE9LRU4mJnVzZXI9PWludGFsaW9cYWRtaW4mJmlzc3VlZD09MTE5NTY0MzM1MTczNCYmcm9sZXM9PWludGFsaW9ccHJvY2Vzc2FkbWluaXN0cmF0b3IsZXhhbXBsZXNcZW1wbG95ZWUsaW50YWxpb1xwcm9jZXNzbWFuYWdlcixleGFtcGxlc1xtYW5hZ2VyJiZmdWxsTmFtZT09QWRtaW5pbmlzdHJhdG9yJiZlbWFpbD09YWRtaW5AZXhhbXBsZS5jb20mJm5vbmNlPT0tMzU0NDYwNjI1MzA3NTkxMzMwMyYmdGltZXN0YW1wPT0xMTk1NjQzMzUxNzM0JiZkaWdlc3Q9PW92OXlVbUNyTGgvcXZQajdNdXZDZkNWMU9DTT0mJiYmVE9LRU4=' is resolved to [Lorg.intalio.tempo.security.Property;@fae917
19:52:46,828 DEBUG [org.intalio.tempo.workflow.auth.n3.N3AuthProvider] [SocketListener2-19] User intalioadmin with roles intalioprocessadministrator,examplesemployee,intalioprocessmanager,examplesmanager
19:52:46,828 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnectionFactory] [SocketListener2-19] Getting connection to TMS DB
19:52:46,828 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] About to retrieve Workflow Task with ID 1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017
19:52:46,843 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] Workflow Task 1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017 has been read from TMS DB
19:52:46,843 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] About to retrieve user owners for task 1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017
19:52:46,843 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] User Owner : intalioadmin
19:52:46,843 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] About to retrieve role owners for task 1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017
19:52:46,843 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] About to retrieve attachments for task 1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017
19:52:46,843 DEBUG [org.intalio.tempo.workflow.auth.BaseRestrictedEntity] [SocketListener2-19] isAvailableTo credentials: UserRoles{user=intalioadmin,roles=[intalioprocessadministrator, examplesemployee, intalioprocessmanager, examplesmanager]}
19:52:46,843 DEBUG [org.intalio.tempo.workflow.auth.BaseRestrictedEntity] [SocketListener2-19] isAvailableTo users: [intalioadmin]
19:52:46,843 DEBUG [org.intalio.tempo.workflow.auth.BaseRestrictedEntity] [SocketListener2-19] isAvailableTo roles: []
19:52:46,843 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] Attempt to delete Workflow Task 1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017
19:52:46,875 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] XML parsed to string :
<? xml version="1.0" encoding="UTF-8" ?> < axis2ns3:input  xmlns ="http://example.com/PA/xform"  xmlns:axis2ns3 ="http://example.com/PA/xform" >
      
< username >
      
</ username >
    
</ axis2ns3:input >
19:52:46,875 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] XML parsed to string :
<? xml version="1.0" encoding="UTF-8" ?> < axis2ns4:output  xmlns ="http://example.com/PA/xform"  xmlns:axis2ns4 ="http://example.com/PA/xform"  xmlns:fe ="http://example.com/PA/xform"  participantToken ="VE9LRU4mJnVzZXI9PWludGFsaW9cYWRtaW4mJmlzc3VlZD09MTE5NTY0MzM1MTczNCYmcm9sZXM9PWludGFsaW9ccHJvY2Vzc2FkbWluaXN0cmF0b3IsZXhhbXBsZXNcZW1wbG95ZWUsaW50YWxpb1xwcm9jZXNzbWFuYWdlcixleGFtcGxlc1xtYW5hZ2VyJiZmdWxsTmFtZT09QWRtaW5pbmlzdHJhdG9yJiZlbWFpbD09YWRtaW5AZXhhbXBsZS5jb20mJm5vbmNlPT0tMzU0NDYwNjI1MzA3NTkxMzMwMyYmdGltZXN0YW1wPT0xMTk1NjQzMzUxNzM0JiZkaWdlc3Q9PW92OXlVbUNyTGgvcXZQajdNdXZDZkNWMU9DTT0mJiYmVE9LRU4="  taskId ="1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017"  user ="intalioadmin" >< username > w1 </ username ></ axis2ns4:output >
19:52:46,875 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] Workflow PA Task 1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017 is about to be registered in TMS DB
19:52:46,875 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] Workflow PA Task 1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017 registered with ID=17
19:52:46,890 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19]  and User Owner : intalioadmin
19:52:46,921 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] committed
19:52:46,921 DEBUG [org.intalio.tempo.workflow.tms.server.TMSServer] [SocketListener2-19] intalioadmin has set output and completed Workflow Task Workflow Task 1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017
19:52:46,921 DEBUG [org.intalio.tempo.workflow.tms.server.dao.JDBCTaskDAOConnection] [SocketListener2-19] Closed connection
19:52:47,421 DEBUG [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] Request URI: /ib4p
19:52:47,421 DEBUG [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] SOAPAction: "notifyTaskCompletion"
19:52:47,671 INFO  [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] Workflow Processes -> User Process
19:52:47,671 DEBUG [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] Parsing the request from the Workflow Processes.
19:52:47,687 DEBUG [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] Workflow process request:
<? xml version="1.0" ?>
< soapenv:Envelope  xmlns:soapenv ="http://schemas.xmlsoap.org/soap/envelope/" >< soapenv:Header >< addr:To  xmlns:addr ="http://www.w3.org/2005/08/addressing" > http://localhost:8080/fds/workflow/ib4p </ addr:To >< addr:Action  xmlns:addr ="http://www.w3.org/2005/08/addressing" > notifyTaskCompletion </ addr:Action >< intalio:session  xmlns:intalio ="http://www.intalio.com/type/session" > 573e4478-0f4e-4251-9d45-f870dadf4e80-2 </ intalio:session >< intalio:callback  xmlns:intalio ="http://www.intalio.com/type/session" >< addr:Address  xmlns:addr ="http://www.w3.org/2005/08/addressing" > http://localhost:8080/ode/processes/workflow/ib4p </ addr:Address >< intalio:session > 573e4478-0f4e-4251-9d45-f870dadf4e80-3 </ intalio:session ></ intalio:callback ></ soapenv:Header >< soapenv:Body >< axis2ns5:notifyTaskCompletionRequest  xmlns ="http://www.intalio.com/bpms/workflow/ib4p_20051115"  xmlns:axis2ns5 ="http://www.intalio.com/bpms/workflow/ib4p_20051115"  xmlns:b4p ="http://www.intalio.com/bpms/workflow/ib4p_20051115" >
                                                
< b4p:taskMetaData >
                                                    
< taskId > 1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017 </ taskId >
                                                    
< processId >
    
</ processId >
                                                    
< userProcessEndpoint > http://localhost:8080/ode/processes/PeopleActivity/PA/PA/User/WFmagic_EDLpiJdCEdy9R-hEBkLEtg </ userProcessEndpoint >
                                                    
< userProcessNamespaceURI > http://example.com/PA/xform </ userProcessNamespaceURI >
                                                    
< userProcessCompleteSOAPAction > http://example.com/PA/xform/Process/notifyTaskCompletion </ userProcessCompleteSOAPAction >
                                                    
< session > 573e4478-0f4e-4251-9d45-f870dadf4e80-2 </ session >
                                                
</ b4p:taskMetaData >
                                                
< taskOutput >< axis2ns6:output  xmlns ="http://example.com/PA/xform"  xmlns:axis2ns6 ="http://example.com/PA/xform"  xmlns:fe ="http://example.com/PA/xform"  participantToken ="VE9LRU4mJnVzZXI9PWludGFsaW9cYWRtaW4mJmlzc3VlZD09MTE5NTY0MzM1MTczNCYmcm9sZXM9PWludGFsaW9ccHJvY2Vzc2FkbWluaXN0cmF0b3IsZXhhbXBsZXNcZW1wbG95ZWUsaW50YWxpb1xwcm9jZXNzbWFuYWdlcixleGFtcGxlc1xtYW5hZ2VyJiZmdWxsTmFtZT09QWRtaW5pbmlzdHJhdG9yJiZlbWFpbD09YWRtaW5AZXhhbXBsZS5jb20mJm5vbmNlPT0tMzU0NDYwNjI1MzA3NTkxMzMwMyYmdGltZXN0YW1wPT0xMTk1NjQzMzUxNzM0JiZkaWdlc3Q9PW92OXlVbUNyTGgvcXZQajdNdXZDZkNWMU9DTT0mJiYmVE9LRU4="  taskId ="1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017"  user ="intalioadmin" >< username > w1 </ username ></ axis2ns6:output ></ taskOutput >
                                                
< b4p:status >
                                                    OK
                                                
</ b4p:status >
                                            
</ axis2ns5:notifyTaskCompletionRequest ></ soapenv:Body ></ soapenv:Envelope >


19:52:47,687 DEBUG [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] Converting the request to the user process format.
19:52:47,718 DEBUG [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] Workflow process request (after conversion):
<? xml version="1.0" ?>
< soapenv:Envelope  xmlns:soapenv ="http://schemas.xmlsoap.org/soap/envelope/" >< soapenv:Header >< addr:To  xmlns:addr ="http://www.w3.org/2005/08/addressing" > http://localhost:8080/ode/processes/PeopleActivity/PA/PA/User/WFmagic_EDLpiJdCEdy9R-hEBkLEtg </ addr:To >< addr:Action  xmlns:addr ="http://www.w3.org/2005/08/addressing" > http://example.com/PA/xform/Process/notifyTaskCompletion </ addr:Action >< intalio:session  xmlns:intalio ="http://www.intalio.com/type/session" > 573e4478-0f4e-4251-9d45-f870dadf4e80-2 </ intalio:session >< session  xmlns ="http://www.intalio.com/type/session" > 573e4478-0f4e-4251-9d45-f870dadf4e80-2 </ session ></ soapenv:Header >< soapenv:Body >< userProcess:notifyTaskCompletionRequest  xmlns ="http://www.intalio.com/bpms/workflow/ib4p_20051115"  xmlns:b4p ="http://www.intalio.com/bpms/workflow/ib4p_20051115"  xmlns:userProcess ="http://example.com/PA/xform" >
                                                
< userProcess:taskMetaData >
                                                    
< userProcess:taskId > 1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017 </ userProcess:taskId >
                                                    
< userProcess:processId >
    
</ userProcess:processId >
                                                    
< userProcess:userProcessEndpoint > http://localhost:8080/ode/processes/PeopleActivity/PA/PA/User/WFmagic_EDLpiJdCEdy9R-hEBkLEtg </ userProcess:userProcessEndpoint >
                                                    
< userProcess:userProcessNamespaceURI > http://example.com/PA/xform </ userProcess:userProcessNamespaceURI >
                                                    
< userProcess:userProcessCompleteSOAPAction > http://example.com/PA/xform/Process/notifyTaskCompletion </ userProcess:userProcessCompleteSOAPAction >
                                                    
< userProcess:session > 573e4478-0f4e-4251-9d45-f870dadf4e80-2 </ userProcess:session >
                                                
</ userProcess:taskMetaData >
                                                
< userProcess:taskOutput >< axis2ns6:output  xmlns ="http://example.com/PA/xform"  xmlns:axis2ns6 ="http://example.com/PA/xform"  xmlns:fe ="http://example.com/PA/xform"  participantToken ="VE9LRU4mJnVzZXI9PWludGFsaW9cYWRtaW4mJmlzc3VlZD09MTE5NTY0MzM1MTczNCYmcm9sZXM9PWludGFsaW9ccHJvY2Vzc2FkbWluaXN0cmF0b3IsZXhhbXBsZXNcZW1wbG95ZWUsaW50YWxpb1xwcm9jZXNzbWFuYWdlcixleGFtcGxlc1xtYW5hZ2VyJiZmdWxsTmFtZT09QWRtaW5pbmlzdHJhdG9yJiZlbWFpbD09YWRtaW5AZXhhbXBsZS5jb20mJm5vbmNlPT0tMzU0NDYwNjI1MzA3NTkxMzMwMyYmdGltZXN0YW1wPT0xMTk1NjQzMzUxNzM0JiZkaWdlc3Q9PW92OXlVbUNyTGgvcXZQajdNdXZDZkNWMU9DTT0mJiYmVE9LRU4="  taskId ="1228262541d53628:-5bad7914:11661f87cf4:-7fab192.168.67.2403670017"  user ="intalioadmin" >< username > w1 </ username ></ axis2ns6:output ></ userProcess:taskOutput >
                                                
< userProcess:status >
                                                    OK
                                                
</ userProcess:status >
                                            
</ userProcess:notifyTaskCompletionRequest ></ soapenv:Body ></ soapenv:Envelope >


19:52:47,718 DEBUG [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] Completion SOAP Action: 'http://example.com/PA/xform/Process/notifyTaskCompletion'
19:52:47,718 DEBUG [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] Sending the request to the user process and getting the response
19:52:48,921 DEBUG [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] User process response:
<? xml version="1.0" ?>
< soapenv:Envelope  xmlns:soapenv ="http://schemas.xmlsoap.org/soap/envelope/" >< soapenv:Body >< axis2ns7:response  xmlns ="http://example.com/PA/xform"  xmlns:axis2ns7 ="http://example.com/PA/xform"  xmlns:xform ="http://example.com/PA/xform" >
  
< xform:isChainedAfter >
  
</ xform:isChainedAfter >
  
< xform:taskMetaData >
    
< xform:taskId >
    
</ xform:taskId >
    
< xform:taskState >
    
</ xform:taskState >
    
< xform:taskType >
    
</ xform:taskType >
    
< xform:description >
    
</ xform:description >
    
< xform:processId >
    
</ xform:processId >
    
< xform:creationDate >
    
</ xform:creationDate >
    
< xform:userOwner >
    
</ xform:userOwner >
    
< xform:roleOwner >
    
</ xform:roleOwner >
    
< xform:claimAction >
      
< xform:user >
      
</ xform:user >
      
< xform:role >
      
</ xform:role >
    
</ xform:claimAction >
    
< xform:revokeAction >
      
< xform:user >
      
</ xform:user >
      
< xform:role >
      
</ xform:role >
    
</ xform:revokeAction >
    
< xform:saveAction >
      
< xform:user >
      
</ xform:user >
      
< xform:role >
      
</ xform:role >
    
</ xform:saveAction >
    
< xform:completeAction >
      
< xform:user >
      
</ xform:user >
      
< xform:role >
      
</ xform:role >
    
</ xform:completeAction >
    
< xform:formUrl >
    
</ xform:formUrl >
    
< xform:failureCode >
    
</ xform:failureCode >
    
< xform:failureReason >
    
</ xform:failureReason >
    
< xform:userProcessCompleteSOAPAction >
    
</ xform:userProcessCompleteSOAPAction >
    
< xform:isChainedBefore >
    
</ xform:isChainedBefore >
    
< xform:previousTaskId >
    
</ xform:previousTaskId >
    
< xform:userProcessEndpoint >
    
</ xform:userProcessEndpoint >
    
< xform:userProcessNamespaceURI >
    
</ xform:userProcessNamespaceURI >
  
</ xform:taskMetaData >
  
< xform:status > OK </ xform:status >
  
< xform:errorCode >
  
</ xform:errorCode >
  
< xform:errorReason >
  
</ xform:errorReason >
</ axis2ns7:response ></ soapenv:Body ></ soapenv:Envelope >


19:52:48,921 DEBUG [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] Converting the response to the Workflow Processes format.
19:52:48,921 DEBUG [org.intalio.tempo.workflow.fds.core.UserProcessMessageConvertor] [SocketListener2-19] Converted SOAP Action: null
19:52:48,921 DEBUG [org.intalio.tempo.workflow.fds.core.UserProcessMessageConvertor] [SocketListener2-19] Did not find addr:To in SOAP header
19:52:48,921 DEBUG [org.intalio.tempo.workflow.fds.core.UserProcessMessageConvertor] [SocketListener2-19] Did not find intalio:callback/addr:Address in SOAP header
19:52:48,937 DEBUG [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] Sending the converted response back to the Workflow Processes.
19:52:48,937 DEBUG [org.intalio.tempo.workflow.fds.FormDispatcherServlet] [SocketListener2-19] User process response (after conversion)
<? xml version="1.0" ?>
< soapenv:Envelope  xmlns:soapenv ="http://schemas.xmlsoap.org/soap/envelope/" >< soapenv:Body >< ib4p:response  xmlns ="http://example.com/PA/xform"  xmlns:ib4p ="http://www.intalio.com/bpms/workflow/ib4p_20051115"  xmlns:xform ="http://example.com/PA/xform" >
  
< ib4p:isChainedAfter >
  
</ ib4p:isChainedAfter >
  
< ib4p:taskMetaData >
    
< ib4p:taskId >
    
</ ib4p:taskId >
    
< ib4p:taskState >
    
</ ib4p:taskState >
    
< ib4p:taskType >
    
</ ib4p:taskType >
    
< ib4p:description >
    
</ ib4p:description >
    
< ib4p:processId >
    
</ ib4p:processId >
    
< ib4p:creationDate >
    
</ ib4p:creationDate >
    
< ib4p:userOwner >
    
</ ib4p:userOwner >
    
< ib4p:roleOwner >
    
</ ib4p:roleOwner >
    
< ib4p:claimAction >
      
< ib4p:user >
      
</ ib4p:user >
      
< ib4p:role >
      
</ ib4p:role >
    
</ ib4p:claimAction >
    
< ib4p:revokeAction >
      
< ib4p:user >
      
</ ib4p:user >
      
< ib4p:role >
      
</ ib4p:role >
    
</ ib4p:revokeAction >
    
< ib4p:saveAction >
      
< ib4p:user >
      
</ ib4p:user >
      
< ib4p:role >
      
</ ib4p:role >
    
</ ib4p:saveAction >
    
< ib4p:completeAction >
      
< ib4p:user >
      
</ ib4p:user >
      
< ib4p:role >
      
</ ib4p:role >
    
</ ib4p:completeAction >
    
< ib4p:formUrl >
    
</ ib4p:formUrl >
    
< ib4p:failureCode >
    
</ ib4p:failureCode >
    
< ib4p:failureReason >