how to pass parameters to XQUERY in JBOSS FUSE ESB - apache-camel

XQUERY:
declare namespace ns5 = "http://sample.com/schema/Order/v1/";
declare namespace ns2 = "http://sample.com/schema/Order/v1/";
declare variable $name as xs:string external;
declare variable $details as element() external;
let $Address := $details/ns5:ContactInfo
return
<ns5:GetDetailsResponse>
<ns2:Name>$Address/ns2:name</ns2:Name>
<ns2:ID Version="1.5">Order service</ns2:ID>
<ns2:Reference>
<ns2:ID>{$name}</ns2:ID>
</ns2:Reference>
</ns5:GetDetailsResponse>
Camel Route:
<to uri="xquery:sampleXQUERY.xq"/>
Using XQUERY endpoint in camel route of FUSE ESB.
How can I pass the values to the variables $name, $details declared in this XQUERY??
I have tried using setHeader before this endpoint. But not able to pass values to XQUERY.
Please suggest solution!!

As stated in the documentation, you can pass values by setting exchange.properties or exchange.in.headers.
For example:
from("direct:myRoute")
.setProperty("someProperty", simple("some value"))
.transform().xquery("/some/xquery");

Related

Camel ProducerTemplate requestBody and return type

ProducerTemplate require a non null body parameter when the response type is specified.
In my case, the body must be null, because I use the bean component, and I have a non parameter bean, parameters being then injected in that bean and the route will continue to others beans, this time with a body.
AType response = producer.requestBody(nonNullBody, AType.class);
This won't work:
//cause ambiguous type error
AType response = producer.requestBody(null, AType.class);
//Unsupported method signature
AType response = producer.requestBody(AType.class);
Is there a turn-around beside passing a dummy body parameter ?
Also, is there a way to use a Collection as AType, without having to cast the result ? I tried to wrap it into another object, and it doesn't work.
Notes
For now, I use producer.requestBody(null), followed by a ugly cast.
Would have been cool if we could do producer.requestBody() instead.
Unfortunately, Camel does't support more than one body parameter, which also would have been very helpful eg:
requestBody(String.. args, Class<T> type)
Thanks!

how to implement iTestContext listener without adding to method argument testng(from XML) for PDFBox utility

I am automating a salesforce application using Selenium TestNG. I am implementing a utility using apache PDFBox where i paste all my screenshots into a PDF to make client happy .
My logic is i create screenshots in each method with 1.png , 2.png etc until n.png and paste them in pdf using pdfbox methods.
The problem is my number of screenshots are variable so i implemented iTestContext where i set a variable counter to maximum number pass them to my after method where i retrieve the counter , and those number of screenshots are pasted- something like this
Class Login {
#Test
mymethod(ItestContext context){
commonfunctions.savescreenshot(1.png);
commonfunctions.savescreenshot(2.png);
commonfunctions.savescreenshot(n.png);
context.setAttribute("Counter", "n");
}
#AfterMethod
myaftermethod(){
String PATH = //Path of my test method
String MethodCounter = (String)context.getAttribute("Counter");
PDFUtility.addImagetoPDF(PATH,Integer.parseInt(MethodCounter) );
}
}
The problem is i have many methods that i need to implement and i dont want ITestContext listener as argument to each method.Can i pass it in xml file and use it for all methods?
Hope i have provided all details
If you need to get hold of the current ITestContext object (which is a representation of the current <test> tag being executed), you don't need to pass it as a parameter to your #Test method.
You can get access to it from within a #Test annotated test method via something like this:
org.testng.ITestContext context =
org.testng.Reporter.getCurrentTestResult().getTestContext();
This way you dont need to pass the org.testng.ITestContext object as a parameter to your #Test method.
Can i pass it in xml file and use it for all methods?
No you cannot pass the ITestContext object via the xml file.

camel XPATH variable to XQuery element() convert problem

In Apache camel I need to extract a xml element and pass it to xquery as
element(), but i have strange error.
Any idea and suggesions are more than welcome!
Camel code:
from(SOAP_ENDPOINT_IN_URI + "&dataFormat=CXF_MESSAGE")
.setHeader("CMDRequest", XPathBuilder.xpath("//*[local-name() =
'CMDRequest']")
Xquery code:
declare variable $in.headers.CMDRequest as element() external ;
Error:
Caused by: net.sf.saxon.trans.XPathException: Required item type of value of variable $in.headers.GetDeltaCustomerRequest is element(); supplied value has item type Q{http://saxon.sf.net/java-type}com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList
It looks your xpath is returning a list of elements and not a single element. This could be fixed by by taking the first item of the array of CMDRequest's (assuming list is never empty):
.setHeader("CMDRequest", XPathBuilder.xpath("(//*[local-name()='CMDRequest'])[1]")

use uuid on the move option on Camel File route

how can I use uuid
<bean id="uuid" class="org.apache.camel.impl.SimpleUuidGenerator" />
on the move option on Camel File route ? in order to add a uuid string on the file name when moving it
The ExchangeId is a UUID, so you can simply reference the '${exchangeId}' from Simple language without having to mess with setting up the bean.
If you really want to use your own Uuid generator, reference the bean name in the parameter:
${bean:uuid.generateid}
Where 'uuid' is your bean id and generateid is the method name example here: File language

Setting multiple headers in camel route

Is it possible to set multiple exchange headers in camel route using single call to setHeader.
Something like this
<from uri="file://inputdir/?delete=true" />
<!-- need to set multiple headers at once(as a comma separated list)-->
<setHeader headerName="headername">
<constant>headerval</constant>
</setHeader>
<to uri="mock:end"/>
Or should I create a custom processor for this?
No you cant set multiple headers at once as far as I am aware. In your case a custom processor will probably be more effective.
You might want to look at the simple expression language here here is that you can OGNL notation in your camel route xml file. OGNL will allow you to specify a chain of methods in the expression.
For example suppose you have a message that contains an Employee object that has a getSalaryGrade() method you could set a header to this value by using the following syntax:
<setHeader headerName="SalaryGrade">
<simple>${body.getSalaryGrade()}</simple>
</setHeader>
You could for example create a simple class that returns a list and store the list in the header and then access the list via simple in the route. The following code is untested but should give you a idea.
public class ListCity {
public List<String> ListCities()
{
ArrayList< String> list = new ArrayList<String>();
list.add("New York");
list.add("JOhannesburg");
list.add("HoChiMinh");
return list;
}
}
Declare the list city bean in your xml. You can then set this list into a header by using something like this:
<setHeader headerName="CityList">
<simple>${listCity.ListCities()}</simple>
</setHeader>

Resources