• Tidak ada hasil yang ditemukan

The variables in the business process hold and maintain the data. We used variables in <invoke>,

<receive>, and <reply> to specify the input and output messages for invocation of operations on partner web services. In this section, we get familiar with how to copy data between variables.

To copy data between variables, expressions, and partner link endpoint references BPEL provides the <assign> activity. Within it, we can perform one or more <copy> commands. For each <copy>

we have to specify the source (<from>) and the destination (<to>). The syntax of an assignment is presented below:

<assign>

<copy>

<from ... />

<to ... />

</copy>

<copy>

<from ... />

<to ... />

</copy>

...

</assign>

There are several choices for the <from> and <to> clauses. To copy values from one variable to the other we have to specify the variable attribute in the <from> and <to> elements. This is shown in the following example, where we have copied a value from the InsuranceAResponse

variable to the InsuranceSelectionResponse variable:

<assign>

<copy>

<from variable="InsuranceAResponse" />

<to variable="InsuranceSelectionResponse" />

</copy>

</assign>

This copy can be performed only if both variables are of same type, as in our example

ins:InsuranceResponseMessage, or if the source type is a subtype of the destination type.

Variables can be of three types:

• WSDL message types

• XML Schema elements

• XML Schema primitive types

If a variable holds a WSDL message, which is common, we can further refine the copy by specifying the part of the message we would like to copy. WSDL messages consist of parts (more on WSDL can be found at http://www.w3.org/TR/wsdl). Presented below is a simple message (defined in the WSDL document) that consists of two parts, the insuredPersonData part and the

insuranceDetails part. Both parts are specified with the corresponding XML Schema complex types (not shown here):

<message name="InsuranceRequestMessage">

<part name="insuredPersonData" type="ins:InsuredPersonDataType" />

<part name="insuranceDetails" type="ins:InsuranceDetailsType" />

</message>

Now suppose that we get a variable of type ins:InsuredPersonDataType from invoking another web service, which has the following message declaration in its WSDL and uses the same namespace:

...

<message name="InsuredPersonDataRequestMessage">

<part name="insuredPersonData" type="ins:InsuredPersonDataType" />

</message>

...

Our BPEL process would declare two variables, InsuranceRequest and InsuredPersonRequest, with the declaration shown below:

<variables>

<variable name="InsuranceRequest"

messageType="ins:InsuranceRequestMessage"/>

<variable name="InsuredPersonRequest"

messageType="ins:InsuredPersonDataRequestMessage"/>

</variables>

Now we could perform a copy from the InsuredPersonRequest variable to the

insuredPersonData part of the InsuranceRequest variable using the following assignment:

<assign>

<copy>

Chapter 3 <from variable="InsuredPersonRequest" part="insuredPersonData" />

<to variable="InsuranceRequest" part="insuredPersonData" />

</copy>

</assign>

We could also perform a copy in the opposite direction. In addition to specifying the part, we can also specify the exact path to the element we require. To specify the path we have to write a query, using the selected query language specified within the <process> tag.

The default query language is XPath 1.0.

In our previous example, suppose the ins:InsuredPersonDataType is defined as follows:

<xs:complexType name="InsuredPersonDataType">

<xs:sequence>

<xs:element name="FirstName" type="xs:string" />

<xs:element name="LastName" type="xs:string" />

<xs:element name="Address" type="xs:string" />

<xs:element name="Age" type="xs:int" />

</xs:sequence>

</xs:complexType>

We could perform a copy from the LastName variable to the InsuranceRequest variable, to the message part insuredPersonData, to the last name:

<assign>

<copy>

<from variable="LastName" />

<to variable="InsuranceRequest"

part="insuredPersonData"

query="/insuredPersonData/ins:LastName" />

</copy>

</assign>

The location path must select exactly one node. In the query attribute, we specify an absolute location path, where the root '/' means the root of the document fragment representing the entire part of the message.

In our examples, we have used the message part name insuredPersonData as the name of the first step (top-level element). This is because we have used RPC-style web services, which use

messages defined as XML types. For example, the InsuranceRequest variable is of type

InsuranceRequestMessage. This message has been defined with two parts, each defined by an XML type, as shown on the code excerpt below:

<message name="InsuranceRequestMessage">

<part name="insuredPersonData" type="ins:InsuredPersonDataType" />

<part name="insuranceDetails" type="ins:InsuranceDetailsType" />

</message>

If we had used document-style web services, which use messages defined as XML elements, we would have to use a slightly different XPath query expression. Instead of the part name we would use the element name for the first step in the query expression.

We can also use the <assign> activity to copy expressions to variables. Expressions are written in the selected expression language; the default is XPath 1.0. We specify the expression

attribute in the <from> element. The following example shows how to copy a constant string to the LastName variable:

<assign>

<copy>

<from expression="string('Juric')" />

<to variable="LastName"/>

</copy>

</assign>

We are not restricted to such simple expressions. We can use any valid XPath 1.0 expressions (or the expressions of the selected expression language). For more information, refer to the XPath 1.0 specification: http://www.w3.org/TR/xpath.

Another possibility is to copy a constant XML complex element to the InsuredPersonRequest

variable. In this case, we can specify the source XML directly:

<assign>

<copy>

<from>

<insuredPersonData xmlns="http://packtpub.com/bpel/insurance/">

<FirstName>Matjaz B.</FirstName>

<LastName>Juric</LastName>

<Address>Ptuj</Address>

<Age>30</Age>

</insuredPersonData>

</from>

<to variable="InsuredPersonRequest" part="insuredPersonData" />

</copy>

</assign>