XSLT for merging multiple xml documents in BPEL - wso2

This is regarding xml transformation within BPEL.
In my bpel process, data is coming from two separate sources (partnerLinks).
Data from both sources is in the same xml format.
I need to combine the data from the two XML documents into one xml document and then pass it back to the ESB.
I was trying with bpel:doXslTransform()).
I am not sure how to pass the two responses from the partnerLinks to this function in a single call.
I tried concatenating the two responses into a string within a message type variable and then pass this to the bpel:doXslTransform(). Is this the right approach to merge the data?

Yes, you can do a bpel:doXslTransform here.
This involves receiving an XML document from one service, converting it to a different Schema to form a new request message, and sending the new request to another service. Such documentation conversion can be accomplished using XSLT via the bpel:doXslTransform function.
<variables>
<variable name="A" element="foo:AElement" />
<variable name="B" element="bar:BElement" />
</variables>
...
<sequence>
<invoke ... inputVariable="..." outputVariable="A" />
<assign>
<copy>
<from>
bpel:doXslTransform("urn:stylesheets:A2B.xsl", $A)
</from>
<to variable="B" />
</copy>
</assign>
<invoke ... inputVariable="B" ... />
</sequence>
Please refer http://docs.oasis-open.org/wsbpel/2.0/OS/wsbpel-v2.0-OS.html for further information.

Related

Teiid generated Swagger Json file is corrupted

I have deployed several VDBs on a teiid Master slave setup in the domain mode. for an example AirFlights-vdb.xml, Customer-vdb.xml ...etc are deployed with several procedures which are exposed as REST APIs in each VDBs.I use IP:8080/AirFlights_1/api like URL to access the swagger documentation for a particular VDB. When there are several VDBs deployed the swagger documentation get corrupted. for an example when I do IP:8080/AirFlights_1/api it lists the API resources related to Customer-vdb.xml and other deployed VDBs. Can you help me to solve this messy nature of the generated swagger file.
I use http://teiid.org/rest}auto-generate" value="true"/> property to generate War files.
example vdb whould look like this
?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<vdb name="sample" version="1">
<property name="UseConnectorMetadata" value="true" />
<property name="{http://teiid.org/rest}auto-generate" value="true"/>
<model name="PM1">
<source name="text-connector" translator-name="loopback" />
<metadata type="DDL"><![CDATA[
CREATE FOREIGN TABLE G1 (e1 string, e2 integer);
CREATE FOREIGN TABLE G2 (e1 string, e2 integer);
]]> </metadata>
</model>
<model name="View" type ="VIRTUAL">
<metadata type="DDL"><![CDATA[
SET NAMESPACE 'http://teiid.org/rest' AS REST;
CREATE VIRTUAL PROCEDURE g1Table(IN p1 integer) RETURNS TABLE (xml_out xml) OPTIONS (UPDATECOUNT 0, "REST:METHOD" 'GET', "REST:URI" 'g1/{p1}')
AS
BEGIN
SELECT XMLELEMENT(NAME "rows", XMLATTRIBUTES (g1Table.p1 as p1), XMLAGG(XMLELEMENT(NAME "row", XMLFOREST(e1, e2)))) AS xml_out FROM PM1.G1;
END
]]> </metadata>
</model>
</vdb>
That certainly looks like a bug. I was able to reproduce and captured it as https://issues.jboss.org/browse/TEIID-5173

Location data for filling the report in JasperServer

I have developed a template design in JasperSoft Studio and upload jrxml file to JasperServer. I want to send data (JSON or XML) to filling report template from my python application and take back report in some popular formats like PDF, XLS using REST API. I do not want to store the data on the server. How can I do this? Or data must be stored on the server and there is no alternative way of their transmission by WEB-Service?
The data does not necessarily have to reside on the server.
You could design your template in such way that you can pass the data via input control parameters as #tobi6 suggested.
Then you could use either the reports service or the reportExecutions service to get the desired output.
In your case, the data could be the actual data(XML or JSON) or the source of the data(a URL to the data file).
Here are some basic samples for working with XML data(for JSON is quite similar):
With actual data as parameter
The JasperReports template:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.1.1.final using JasperReports Library version 6.1.1 -->
<!-- 2016-05-25T14:18:00 -->
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="XmlDSReport_with_data" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="85d7b9ad-6feb-43dc-84cc-5175bf629546">
<parameter name="xmlString" class="java.lang.String">
<defaultValueExpression><![CDATA["<?xml version=\"1.0\" encoding=\"UTF-8\"?><a><b><val>val1</val></b><b><val>val2</val></b></a>"]]></defaultValueExpression>
</parameter>
<parameter name="XML_INPUT_STREAM" class="java.io.InputStream">
<defaultValueExpression><![CDATA[new java.io.ByteArrayInputStream($P{xmlString}.getBytes("UTF-8"))]]></defaultValueExpression>
</parameter>
<queryString language="xPath">
<![CDATA[/a/b]]>
</queryString>
<field name="value" class="java.lang.String">
<fieldDescription><![CDATA[val]]></fieldDescription>
</field>
<columnHeader>
<band height="31" splitType="Stretch">
<staticText>
<reportElement x="150" y="0" width="100" height="30" uuid="b33a123d-8987-4da4-b21b-1f9ccc50e92d"/>
<text><![CDATA[value]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="30" splitType="Stretch">
<textField>
<reportElement x="150" y="0" width="100" height="30" uuid="14c51219-5ce2-47ce-abb9-71bc11a6f28c"/>
<textFieldExpression><![CDATA[$F{value}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
After you deploy the report and create the input control for the xmlString parameter you can test it. Let's say you want to pass this XML instead of leaving the default in place:
<?xml version="1.0" encoding="UTF-8"?>
<a>
<b><val>new_val1</val></b>
<b><val>new_val2</val></b>
</a>
To test the reports service you run something similar to this in a terminal(I URL-encoded the XML string) and check the result:
curl -u user:password \
http://localhost:8080/jasperserver/rest_v2/reports/reports/XmlDSReport_with_data.pdf?xmlString=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%20%20%20%20%3Ca%3E%0A%20%20%20%20%20%20%3Cb%3E%3Cval%3Enew_val1%3C%2Fval%3E%3C%2Fb%3E%0A%20%20%20%20%20%20%3Cb%3E%3Cval%3Enew_val2%3C%2Fval%3E%3C%2Fb%3E%0A%20%20%20%20%3C%2Fa%3E > report.pdf
To test the reportExecutions service, the main steps are:
1.Create an XML file with the request(name it reportExecutionRequest.xml)
<reportExecutionRequest>
<reportUnitUri>/reports/XmlDSReport_with_data</reportUnitUri>
<outputFormat>pdf</outputFormat>
<freshData>true</freshData>
<saveDataSnapshot>false</saveDataSnapshot>
<interactive>true</interactive>
<allowInlineScripts>true</allowInlineScripts>
<async>false</async>
<parameters>
<reportParameter name="xmlString">
<value><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<a><b><val>new_val1</val></b><b><val>new_val2</val></b></a>]]></value>
</reportParameter>
</parameters>
</reportExecutionRequest>
2.Make the request(you need to save the session cookie to retrieve the output):
curl -u user:password \
-H "Content-Type: application/xml" \
-d #reportExecutionRequest.xml \
-c cookies.txt \
http://localhost:8080/jasperserver/rest_v2/reportExecutions
3.Get the output with the requestID and exportID from the result of the previous request:
curl -b cookies.txt \
http://localhost:8080/jasperserver/rest_v2/reportExecutions/cc57b351-cfb6-429e-8c92-d0aebebbed66/exports/b71d6353-1eec-4304-8713-5d0f3105680e/outputResource > report.pdf
With data as source URL
It is the same report template, but with the two parameters replaced with:
<parameter name="xmlSource" class="java.lang.String">
<defaultValueExpression><![CDATA["http://serverwithdata/xmlData.xml"]]></defaultValueExpression>
</parameter>
<parameter name="net.sf.jasperreports.xml.source" class="java.lang.String">
<defaultValueExpression><![CDATA[$P{xmlSource}]]></defaultValueExpression>
</parameter>
Note: I created two parameters here just because I wanted to keep a shorter name for the parameter when passing it through the reports service. I also created an input control just for the xmlSource parameter.
The tests in this case are similar.
EDIT: To use JSON instead of XML, the original JasperReports template needs to be adjusted in this way:
For data as parameter, just change the xmlString parameter, the XML_INPUT_STREAM parameter and the queryString to this:
<parameter name="jsonString" class="java.lang.String">
<defaultValueExpression><![CDATA["{\"a\": [ {\"b\": { \"val\": \"val1\"}}, {\"b\": { \"val\": \"val2\" }}]}"]]></defaultValueExpression>
</parameter>
<parameter name="JSON_INPUT_STREAM" class="java.io.InputStream">
<defaultValueExpression><![CDATA[new java.io.ByteArrayInputStream($P{jsonString}.getBytes("UTF-8"))]]></defaultValueExpression>
</parameter>
<queryString language="json">
<![CDATA[a.b]]>
</queryString>
For data as source URL, change the xmlString parameter, the XML_INPUT_STREAM parameter and the queryString to this:
<parameter name="jsonSource" class="java.lang.String">
<defaultValueExpression><![CDATA["http://serverwithdata/jsonData.json"]]></defaultValueExpression>
</parameter>
<parameter name="net.sf.jasperreports.json.source" class="java.lang.String">
<defaultValueExpression><![CDATA[$P{jsonSource}]]></defaultValueExpression>
</parameter>
<queryString language="json">
<![CDATA[a.b]]>
</queryString>
The cURL tests for the REST services are basically the same with the main difference that you will be passing JSON instead of XML and use the JSON specific parameters jsonString or jsonSource.
The API is separated in three domains:
Administration services
Repository services
Report services
To generate reports, they first have to be deployed to the server via the repository service. If later on the report needs to be generated, it is called via the report services. Here, it is also possible to start synchronous or asynchronous report generation.
Therefore the report needs to be in the repository.
EDIT
Since you also need to deliver parameters, referring to this example it would work like this:
Add a report parameter
Add a input control for a report parameter
Call the API with your input parameter: http://<host>:<port>/jasperserver[-pro]/rest_v2/reports/reports/samples/EmployeeAccounts.html?EmployeeID=sarah_id
Do as needed for other parameters

How to manipulate xml data in Oracle SOA suite?

<Employees manager="101" xmlns:ns1="http://www.example.org" xmlns="http://www.example.org">
<ns1:person ssn="101">
<ns1:firstName>Lakshminarayana</ns1:firstName>
<ns1:lastName>medikoda</ns1:lastName>
</ns1:person>
<ns1:person ssn="102">
<ns1:firstName>narasimha</ns1:firstName>
<ns1:lastName>mannepalli</ns1:lastName>
</ns1:person>
<ns1:person ssn="103">
<ns1:firstName>venu</ns1:firstName>
<ns1:lastName>ponakala</ns1:lastName>
</ns1:person>
</Employees>
I want to append new records and remove some records from this file in oracle soa
You should not be using XSLT to make this adjustment, you should be using the BPELX functions in an Assign activity.
To append a new record into the list you should be doing the following
bpelx:append
The bpelx:append extension in an assign activity enables a BPEL process to append the contents of one variable, expression, or XML fragment to another variable's contents.
<bpel:assign>
<bpelx:append>
<bpelx:from ... />
<bpelx:to ... />
</bpelx:append>
</bpel:assign>
The following example will show you how to implement this in your example.
<bpel:assign>
<bpelx:append>
<from variable="variableFrom"
query="variableFromQuery" />
<to variable="variableTo"
query="/ns1:Employees/ns1:person" />
</bpelx:append>
</bpel:assign>
To remove this from the queue you should
The bpelx:remove extension in an assign activity enables a BPEL process to remove a variable.
<bpel:assign>
<bpelx:remove>
<bpelx:target variable="variableName" part="Employee" query="query to match node you want to remove" />
</bpelx:remove>
</bpel:assign>

JAX WS xsd:any type is an XMLSchema element

Handling xsd:any type is an XMLSchema element JAX WS
<types>
<schema targetNamespace="http://www.iona.com/artix/wsdl"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<complexType name="unmappedType">
<sequence>
<xsd:any namespace="##other"
processContents="skip"/>
</sequence>
</complexType>
<element name="request" type="tns:requestType"/>
</schema>
</types>
The xml is there as a STring how to have it as a document object, and then transfer its contents into a SOAPElement instance
Need guidance for the implementation and client code.
Convertng the XML String into the Element. and also reading it back once the response is received .
I see that someone has downvoted your question... If you don't mind, I would first point out the issues your question seems to have: the snippet most likely comes from an WSDL, but the schema is rather invalid. The first thing you should do is to make it right. Maybe something like this:
<?xml version="1.0" encoding="utf-8"?>
<!--W3C Schema generated by QTAssistant/W3C Schema Refactoring Module (http://www.paschidev.com)-->
<schema targetNamespace="http://www.iona.com/artix/wsdl" xmlns:tns="http://www.iona.com/artix/wsdl" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<complexType name="unmappedType">
<sequence>
<any namespace="##other" processContents="skip"/>
</sequence>
</complexType>
<element name="request" type="tns:unmappedType"/>
</schema>
Once you've done it, I suggest making up an XML that looks the way you want; make sure you validate that. Post it along with your question...
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<request xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://www.iona.com/artix/wsdl">
<any_element xmlns="otherNS">anyType</any_element>
</request>
I would then use a tool that's free and easy to use when it comes to JAXB (I recommend NetBeans, it has a straightforward interface). Then write a small Java console app that uses your code; debug through, and see what you get when you unmarshall the XML. Maybe read a little bit the documentation, and then eventually post to ask for help with a more specific question.
The xsd:any and JAXB is pretty well documented: try this about JAXB...

copy complexType to message in BPEL

I am using Apache ODE to write some simple BPEL's to connect 2 web services.
One of the WSDL files of my two services contains this complex type:
<types>
<t:schema targetNamespace="http://ws.panos.com/" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<t:complexType name="myObject">
<t:sequence>
<t:element minOccurs="0" name="str" type="t:string" />
</t:sequence>
</t:complexType>
</t:schema>
How do I make a copy from a service return message (which is just a xsd:string) to the input of a message (inside "str" of type "myObject"?
I have tried to do this, but doesnt seem to work:
<assign name="assign_2">
<copy>
<from variable="wsA_output" part="return"/>
<to variable="wsC_input" part="arg0" query="/arg0/str"/>
</copy>
I always get a null string transfered. Help much appreciated.
The to-spec <to variable="..." part="..." query="..."/> is not valid in BPEL 1.1 nor BPEL 2.0. The correct equivalent expression is: <to>$wsC_input.arg0/arg0/str</to> or <to variable="wsC_input" part="arg0"><query>/arg0/str</query></to>. Please make also sure that you initialize the variable before assigning values to nested structures.
Just found the mistake. You are right, we need to query in order to find the field like this:
<assign name="assign_2">
<copy>
<from variable="wsA_output" part="return"/>
<to>$wsC_input.message/arg0/str</to>
</copy>
</assign>
Also, we need to initialize the variable like this:
<assign name="assign_init">
<copy>
<from>
<literal><arg0><str xmlns="">nothing</str></arg0></literal>
</from>
<to variable="wsC_input" part="arg0"></to>
</copy>
</assign>
The xmlns="" is needed when the default namespace in your bpel is different that the namespace in the receiving web service.
I am just writing these down for future reference :)
Again, thanks for you your answer.
Some links that could also help other people:
http://ode.apache.org/faq.html
http://jee-bpel-soa.blogspot.com/2009/08/manipulating-ws-bpel-variables-and.html