OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

wsbpel message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: Issue - 2 - A subfunction proposal


Here is a very rough, rough draft of a possible solution to Issue 2.

This rough draft introduces three new elements into BPEL - subfunction,
return and function.

The subfunction XML element is used to define a subfunction. It takes
parameters as arguments and those parameters can be variables, partnerLinks
or correlationSets. subfunctions can return values but only variables, not
partnerLinks or correlationSets. If a subfunction returns a value then the
return activity is used to specify the value to return. Other than
specifying the input parameters and optional return value a subfunction's
body looks more or less identical to a scope activity's body.

A subfunction can be defined in the global scope, inside of a scope activity
or in another file and imported into the global scope. The normal BPEL
naming rules apply so you can only call a sub-function you can 'see'.

To call a subfunction you would use the function activity. All parameters
are passed by reference so any changes to those parameters in the
subfunction are reflected back in the host. Returned values however are
always passed by value. Subfunctions that return values can only be called
inside of expressions. This requires changing expressions to allow elements
as arguments but we already have that problem in Issue 13.

If a subfunction throws a fault that isn't caught by the subfunction's fault
handler then the fault is propagated into the host.

If the host starts compensation then the compensation handler on the
subfunction is called through the function activity in the same way one
calls a compensation handler on a scope.

In the example given below a one-way message is received which contains a
math problem. The process calls the IsAddOne subfunction which looks at the
type of math problem that has been received and determines if it is a
request to add one to a value in the input message. If it is then the
process calls the AddOne subfunction which will calculate the desired result
and send it back to the student using a one-way message. If the request is
not to add one then the process will use a one-way to return an error to the
student. In either case the process ends when the logger is sent a copy of
the message that was sent to the student. Notice that even if the AddOne
subfunction was called the final invoke to the logger still sees the value
sent to the student because the mathProblem variable was passed by reference
to the AddOne subfunction.

<process>
   <partnersLinks>
      <partnerLink name="mathStudent" partnerLinkType="a:mathStudent"/>
      <partnerLink name="loggingService"
partnerLinkType="b:loggingService"/>
   </partnerLinks>

   <variables>
      <variable name="mathProblem" messageType="a:mathProblem"/>
   </variables>

   <subfunction name="IsAddOne">
      <parameters>
         <parameter name="problemType" type="xsd:string"/>
      <parameters>
      <returnValue type="xsd:boolean"/>
      <return expression="getVariableData('problemType') ==
'AddOneProblem'"/>
   </subfunction>

   <subfunction name="AddOne">
      <parameters>
         <parameter name="MathMessage" messageType="a:mathProblem"/>
         <parameter name="Student" partnerLinkType="a:mathStudent"/>
      </parameters>
      <sequence>
         <assign>
            <copy>
               <from
expression="getVariableData('MathMessage','partOne','/TheNumber') + 1"/>
               <to variable="MathMessage" part="partOne"
query="/TheNumber"/>
            </copy>
         <assign>
         <invoke partnerLink="Student" portType="a:AsynchResponse"
                 operation="mathProblemSolution"
inputVariable="MathMessage"/>
      </sequence>
   </subfunction>

   <sequence>

      <receive partnerLink="mathStudent" portType="a:MathProblem"
               operation="a:AsynchProblemRequest" variable="mathProblem"/>

      <switch>
         <case>
            <condition>
               <function functionName="IsAddOne">
                  <parameter variable="mathProblem" property="problemType"/>
               </function>
            </condition>
            <function functionName="AddOne">
               <parameter variable="mathProblem"/>
               <parameter partnerLink="mathStudent"/>
            </function>
         </case>
         <otherwise>
            <sequence>
               <assign>
                  <copy>
                     <from>
                        <requestFailedCannotHandleProblemType/>
                     </from>
                     <to variable="mathProblem" part="partTwo"/>
                  </copy>
               </assign>
               <invoke partnerLink="mathStudent" portType="a:AsynchResponse"
                       operation="mathProblemSolution"
inputVariable="mathProblem"/>
            </sequence>
         </otherwise>
      </switch>

      <invoke partnerLink="loggingService" portType="b:loggingService"
              operation="logProblemSolution" inputVariable="mathProblem"/>

   </sequence>

</process>



[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]