A typical business scenario is that client is sending an order id and that can contain multiple product id.Using BPEL how can we accomplish this?
This is an easy task provided you have some basic knowledge of XSD.
We will try to design a BPEL process and see how we change our XSd to create a order which can take multiple product id.
Open your Jdeveloper and create a new BPEL process
Let the default name and settings be there and just say finish.
It will create a default BPEL process.Now try to analyst the files that are created by jdeveloper automatically for this Project
You will find that it has created a .bpel ,.wsdl and a xsd file for us.
Here we will just check the xsd file because that is our concern.
Try to open the xsd file and go to source tab you will get something like this
<schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://xmlns.oracle.com/BPELProcess1"
xmlns="http://www.w3.org/2001/XMLSchema">
<element name="BPELProcess1ProcessRequest">
<complexType>
<sequence>
<element name="input" type="string"/>
</sequence>
</complexType>
</element>
<element name="BPELProcess1ProcessResponse">
<complexType>
<sequence>
<element name="result" type="string"/>
</sequence>
</complexType>
</element>
</schema>
Now i want you guys to just have a luk in my earlier post
Tuesday, February 2, 2010
XML SChema
So in this Xsd we are defining two element BPELProcess1ProcessRequest and BPELProcess1ProcessResponse of type string which mean it will take an output string as input and return to us an output string.
Now we will see how to make changes in this xsd file to fulfill our requirement.
It is important to know that the XML schema is build with elements and attributes.These building bloc comes from the namespace http://www.w3.org/2001/XMLSchema which is declared as a reserved namespace that contains elements and attributes defined in w3c schema structure specification.You can not add element or attributes to this namespace.
Using these building blocks we create our own elements and attributes and we put them in some namespace which is nothing but the target namespace or in other words the namespace where the newly created elements and attributes will reside.
So i believe you already have read the document which i have recommended.
so now we will go ahead and design our xml document.
This target name space is just an identifier and you can name it any thing what you want so i can also say
targetNamespace="http://arpit.com"
Ok so as per our requirement i will change my xsd as below
<schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://arpit.com"
xmlns="http://www.w3.org/2001/XMLSchema">
<element name="BPELProcess1Request" type="ProductType"/>
<element name="BPELProcess1Response" type="ProductType"/>
<complexType name="ProductType">
<sequence>
<element name="listElement" type="listElementType" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="listElementType">
<sequence maxOccurs="unbounded">
<element name="itemID" type="string"/>
<element name="itemValue" type="string"/>
</sequence>
</complexType>
</schema>
Here i have defined both input and output message as of type ProductType.
Now if you see i have again defined ProductType as list of element which contain two values itemID and itemValue.I have set maxOccurs="unbounded" which means they can occur any number of time.This is simple xml concept which you can just have by going through xml docs.
My intention here is to make you aware of namespace concept.
Now we have designed our XSD but it is not correct.
It is because the namespace http://www.w3.org/2001/XMLSchema doesn't know about the type productType and listElementType.These we have defined by our own.So we need to modify our code so that it can understand that the their are some user defined type.For that purpose we will add one namespace to our xsd Since our xsd document is now represented by targetnamespace we will add a namespace
xmlns:arpit="http://arpit.com"
Here arpit is a namespace prefix.The idea is that whatever variable we have defined by our own we will prefix it with arpit so that parser could understand that they are user defined and belong to "http://arpit.com" namespace.
So i will change the document accordingly and it will be
So now the correct schema should look like
<schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://arpit.com"
xmlns:arpit="http://arpit.com"
xmlns="http://www.w3.org/2001/XMLSchema">
<element name="BPELProcess1ProcessRequest" type="arpit:productType"/>
<element name="BPELProcess1ProcessResponse" type="arpit:productType"/>
<complexType name="productType">
<sequence>
<element name="listElement" type="arpit:listElementType" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="listElementType">
<sequence maxOccurs="unbounded">
<element name="itemID" type="string"/>
<element name="itemValue" type="string"/>
</sequence>
</complexType>
</schema>
Again one thing here to understand is that for all the other types there is default prefix because we have not used any prefix for http://www.w3.org/2001/XMLSchema
If you are using a jdeveloper you can see the structure of the document.
But again when i tried to compile my project i got following error
Error:
[Error ORABPEL-10902]: compilation failed
[Description]: in "bpel.xml", XML parsing failed because "undefined part element.
In WSDL at "file:/D:/testcase/Java/BPELProcess1/bpel/BPELProcess1.wsdl", message part element "{http://xmlns.oracle.com/BPELProcess1}BPELProcess1ProcessRequest" is not defined in any of the schemas.
Please make sure the spelling of the element QName is correct and the WSDL import is complete.
".
[Potential fix]: n/a.
This occured because i made changes in my xsd file only but all the other files that has been created by jdeveloper still have the reference for the variable
BPELProcess1ProcessRequest and BPELProcess1ProcessResponse
So simply to avoid this issue we can change our xsd and make it as
<schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://xmlns.oracle.com/BPELProcess1"
xmlns:arpit="http://xmlns.oracle.com/BPELProcess1"
xmlns="http://www.w3.org/2001/XMLSchema">
<element name="BPELProcess1ProcessRequest" type="arpit:productType"/>
<element name="BPELProcess1ProcessResponse" type="arpit:productType"/>
<complexType name="productType">
<sequence>
<element name="listElement" type="arpit:listElementType" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="listElementType">
<sequence maxOccurs="unbounded">
<element name="itemID" type="string"/>
<element name="itemValue" type="string"/>
</sequence>
</complexType>
</schema>
Ot if you don't want to change your xsd you need to change your WSDL file which still has the reference for that old message type.So just go to the WSDL and make change in the wsdl message as
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<message name="BPELProcess1RequestMessage">
<part name="payload" element="client:BPELProcess1Request"/>
</message>
<message name="BPELProcess1ResponseMessage">
<part name="payload" element="client:BPELProcess1Response"/>
</message>
Now you have completed the input and output file just drag and drop an assign activity and map input to output variable just to make some sense to the project.
Now deploy your project to the server and go to BPEL console to check the process.
Now you can see you will get a plus sign which you can click to get more than one input.In my case i am taking two input
SO i went to check the result and i got following error in my assign activity
XPath query string returns multiple nodes.
According to BPEL4WS spec 1.1 section 14.3, The assign activity part and query /client:BPELProcess1ProcessRequest/client:listElement/client:itemID should not return multipe nodes.
Please check the BPEL source at line number "70" and verify the part and xpath query /client:BPELProcess1ProcessRequest/client:listElement/client:itemID.
Possible reasons behind this problems are: some xml elements has maxOccurs > 1 or the xml data is invalid according to XML Schema.
To verify whether XML data received by a process is valid, user can turn on validateXML switch at the domain administration page.
Well this error is because we have not defined any rule in our assign activity to assign each input variable to each output variable.This can be verified if you will try to invoke your process with a single input and you can find the output but for multiple input we have to process it in a different way.
So what we can do is that we can either use a loop and then we can use assign activity within that loop to copy each input to output or we can either use flowN activity or you can have some of your own logic.
Well you cam also use a transform activity and use for -each to assign each input variable to corresponding output variable.Discussing all in a same post will make it too complex so we will cover it sometimes later.