Skip to main content
Announcements
See what Drew Clarke has to say about the Qlik Talend Cloud launch! READ THE BLOG
cancel
Showing results for 
Search instead for 
Did you mean: 
Anonymous
Not applicable

[resolved] Reference header element in cHTTP in a Route

Hello,
I have a route with a cSetHeader which sets something in the header exchange.
I've validated that there is something there with the following Java code

exchange.getIn().getHeader("test");
System.out.println("header: " + list.item(0).getTextContent());

Now I try to use this header as a parameter in my external HTTP call (see cHTTP screenshot), but the variable is not replaced by its value. Instead I get this
GET /hlEndpoint/getStatus?orderNum=%24%7Bheader.newOrderId%7D HTTP/1.1
Any ideas? I can change this HTTP call to a POST if it makes it easier.
Regards,
Enrique
0683p000009MBHf.png 0683p000009MBkW.png
Labels (3)
1 Solution

Accepted Solutions
Anonymous
Not applicable
Author

Hi Enrique,
That should indeed work. If you'd like to accomplish this without using cProcessor, you could use a single cSetHeader component and include two entries. In the first, you can use some XPath to pull your order number out of the XML and place it in the first header (e.g. 'my_order_number'). Then in the second entry, you can use the Camel Simple language to build your HTTP query. In this case it would be "orderNumber=${header.my_order_number}".
I've included an example where I've done this with the entire HTTP URL, but it should easily apply to just the query portion like you're doing.

http://camel.apache.org/simple.html
Best Regards,
Ben
0683p000009MBkb.jpg

View solution in original post

7 Replies
Anonymous
Not applicable
Author

Hello,
I succeed solving the problem, so I give the solution if it's helpful for somebody:
Before the cHTTP, put a Processor and put in Java

com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList list = (com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList) exchange.getIn().getHeader("orderNumber");
String orderNumber = list.item(0).getTextContent();
exchange.getIn().setHeader(org.apache.camel.Exchange.HTTP_QUERY, "orderNumber=" + orderNumber);

After, there is no need to put this as param in cHTTP component
Best regards,
Enrique
Anonymous
Not applicable
Author

Hi Enrique,
That should indeed work. If you'd like to accomplish this without using cProcessor, you could use a single cSetHeader component and include two entries. In the first, you can use some XPath to pull your order number out of the XML and place it in the first header (e.g. 'my_order_number'). Then in the second entry, you can use the Camel Simple language to build your HTTP query. In this case it would be "orderNumber=${header.my_order_number}".
I've included an example where I've done this with the entire HTTP URL, but it should easily apply to just the query portion like you're doing.

http://camel.apache.org/simple.html
Best Regards,
Ben
0683p000009MBkb.jpg
Anonymous
Not applicable
Author

Hi Ben,
Thank you for your response. So far, I'm happy with the Processor, even if no so elegant as a SetHeader component, but at least I have the URL of the endpoint separated in the cHTTP, and I can externalise it in the context easily.
EDIT: I realise that your solution (2 setHeader) was the first option I tested, and it never worked. I believe this is an error that has been solved in more recent versions of Talend (or Camel component?). I am using the version 5.1.2 which is starting to be a bit out of date.
I take the opportunity, to ask you about another problem, still related with cHTTP. I want to manage if I have an error in this HTTP call, because I want to send a special reply to the requester of the route.
I put the param "throwExceptionOnFailure=false" found on the Jetty Camel component, but my requester receives this response:

java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:80)
at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:122)
at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)

I would like to be able to analyse the response, and if it's connection refused, error 4XX or 5XX, handle it and send special response
Also, I try with a cTry and catch branch, but the route does not compile (see 2nd attached screenshot on my first post of the topic). Here is the code who does not compile
								.to(uriMap.get("to Intermediate")).id(
"cMessagingEndpoint_14").when().xpath(
"/OrderStatus/Status='FINAL'")
.to(uriMap.get("to Final")).id(
"cMessagingEndpoint_11").doCatch(
java.lang.Throwable.class).process(
new org.apache.camel.Processor() {

The error displayed is
The method doCatch(Class<Throwable>) is undefined for the type ChoiceDefinition

Any ideas/suggestions? The version of Talend I'm using is 5.1.2.r90681 Professional Edition
Best regards,
Enrique
Anonymous
Not applicable
Author

Hi Enrique,
In your 'catch' path, did you specify the exception to catch? You may want to try java.lang.Exception instead to see if that clears it up.
Another thing it could be is that your try/catch could be interacting with your ChoiceDefinition. Sometimes it helps to use cDirect components after a cMessageRouter if you have to use some of these other conditional components further down the line. So the modification would look something like this:
1) Drop a cDirect in and point your cMessageRouter 'when' to it.
2) Drop another cDirect and connect it to the orphaned route segment. Configure the new cDirect with a sensible name.
3) Configure the first cDirect to point to the second.
Hope that helps
Ben
Anonymous
Not applicable
Author

I just remembered you're using 5.1.2, which I don't think has cDirect.
So in place of all the cDirect components, you would use the cMessagingEndpoint. The URI to link two point together would simply be "direct:MyDirectEndpointName" on both ends.
http://camel.apache.org/direct.html
Anonymous
Not applicable
Author

Hi Ben,
Thank you for your response. I got that cDirect was equivalent to cMessagingEndpoint with "direct:xxxx".
As you can see in the screenshot I put, the exception I defined is "java.lang.Throwable.class". I did another try/catch block in other part of the route, and it worked without problem.
I tried with your suggestion, and I have to say that it worked! Indeed it seems that the Route compiler does not take into account what is after my cDirect, and the try branch finishes with it.
Now I have the desired behavior 0683p000009MACn.png. Thank you for your help
Enrique
krishna_g
Contributor II
Contributor II

Hey 
I have a header as endpoint url value of a service.I need to call the header value as a url in chttp component.
Can any one tell me how to set the header value in the chttp component URL