One Star

[resolved] REST service proxy route

Hello!
Using Talend ESB, I want to proxy my REST service that is deployed, for example, on: http://hostnameA:8080/web_app to http://hostnameB:8085/web_app. That means, when I want to invoke the service (http://hostnameA:8080/web_app), I need to invoke them on: http://hostnameB:8085/web_app. It is just a simple proxy route.
I tried to do this using TOS and Talend ESB Studio, but without result. I tried something similar with Axis web services and works fine. My configuration for this case was:
Part of camel-config.xml file



address="http://proxy_hostname:8090/application/service/TokenService"
endpointName="sSmiley Frustratedervice"
serviceName="s:TokenService"
wsdlURL="etc/TokenService.wsdl"
xmlns:s="http://tempo.intalio.org/security/tokenService/"/>


serviceName="serviceNS:TokenService"
endpointName="serviceNSSmiley Frustratedervice" address="http://hostname:8080/axis2/services/TokenService">

....









Can someone help me?
Thanks in advance!

27 REPLIES
One Star

Re: [resolved] REST service proxy route

Can anyboby, please help me?
Employee

Re: [resolved] REST service proxy route

Hi,
Can you give us a little bit more details on what is not working actually ?
Thanks,
Bahaaldine
One Star

Re: [resolved] REST service proxy route

Hi,
I have a REST service deployed on http://hostname:8080/alfresco/service/service_name/process/{instanceId}/doctypes/{doctype} with,as you can see, 2 parameters. I want to publish this service on Talend ESB and proxy them on different hostname and (or) port.
I've tried with a job that call this service using the tREST component, exported them as an OSGi bundle for ESB and deployed on ESB. When I invoke them with "job:start job_name" command it works fine. Shows the expected response (link in string format). I think this is not a right solution to proxy a REST service.
How can I invoke this job remotely from another application? Is there any other better solutions to proxy a REST service using Talend ESB? Can I use the Route Builder within Talend ESB Studio to create a simple proxy route? If yes, how? Is there any example?
Thanks
Employee

Re: [resolved] REST service proxy route

Hi
You can probably just use simpler Camel HTTP or Jetty components for a simple proxying.
I'm not sure if you can use CXF components in the from: mode when WSDL2 is used to describe a RESTful endpoint.
Alternatively please also consider using to:cxfrs:uri, instead of just to:uri, though to:uri should work, the problem seems to be on the from: end
Employee

Re: [resolved] REST service proxy route

Hi,
I think you can do it directly on the RouteBuilder :
- Create a cMessagingEndpoint, set the URI as follow :
"cxf://http://KarafHostName:KarafPort/webserviceEndpoint?wsdlURL=file:///pathToMyWSDL/file.wsdl&dataFormat=MESSAGE"
This messaging endpoint is the proxy service entry point.
- Create a cMessagingEndpoint, set the URI to your REST Web service :
"cxf://http://RESTHostName:RestPortt/RestWebserviceEndpoint?dataFormat=MESSAGE"

Connect the two cMessagingEndpoint and run.

Bahaaldine
Employee

Re: [resolved] REST service proxy route

@ bahaaldine: if using TESB 4.2.0, maybe a patch about CXF is needed to make the Route work. And in the next release of TESB, Route with CXF will run without any workaround.
One Star

Re: [resolved] REST service proxy route

Hi bahaaldine,
should I implement a service and write a WSDL for my REST service which I will expose on ESB or? I don't understand.
I tried with this configuration:
First cMessagingEndpoint:
"cxf://http://localhost:18081/applicationName/service/serviceName/process?dataFormat=MESSAGE"
Second cMessagingEndpoint:
"cxf://http://mashina:8080/applicationName/service/serviceName/process?dataFormat=MESSAGE"
The error I get is: "Failed to create route cMessagingEndpoint_1: Route[[From[cxf://http://localhost:18081/alfresco/service/ab... because of Failed to resolve endpoint: cxf://http://localhost:18081/alfresco/service/abitecm/process?dataFormat=MESSAGE due to: No component found with scheme: cxf" (Error within Talend Route Builder when I press Run)
Then I have tried without "cxf" prefix in uri. No errors.
When I invoke the endpoint: http://localhost:18081/applicationName/service/serviceName/process/{parameter1}/doctypes/{parameter2}
nothing happens (Firefox REST client)
KarafHostName: localhost
KarafPort: 18081
I deployed the route on Talend ESB and invoked again the endpoint. The error I get then is:
"


Error 404 Not Found


HTTP ERROR: 404

Problem accessing /applicationName/service/serviceName/process/28/doctypes/doctypeName. Reason:

    Not Found



Powered by Jetty://"
I do not know if I have well explained what I need?!
One Star

Re: [resolved] REST service proxy route

Hi,
I want to have this functionality for the REST service using Talend ESB:
http://www.mulesoft.org/web-service-proxy
One Star

Re: [resolved] REST service proxy route

Hi,
can anyone help me to solve this problem? I have a deadline next Monday.
I have tried various solutions like:
http://camel.apache.org/cxfrs.html
http://camel.apache.org/http.html
but without result :-(
One Star

Re: [resolved] REST service proxy route

Hi,
I have a another question..
If I have a job deployed on Talend ESB and the job calls a REST service using tREST or tHttpRequest component with 2 parameters (http://mashina:8080/applicationName/service/serviceName/process/{parameter1}/doctypes/{parameter2} - REST service endpoint), how can I invoke this job remotely from another application and read (or store) the response?
The KarafHostName is: localhost and KarafPort is: 18081
Thanks in advance!
One Star

Re: [resolved] REST service proxy route

Hi ipercinlic, i'm also new to talend esb, camel, ... but i think you can solve this error "The error I get is: "Failed to create route cMessagingEndpoint_1: Route[[From[cxf://http://localhost:18081/alfresco/service/ab... because of Failed to resolve endpoint: cxf://http://localhost:18081/alfresco/service/abitecm/process?dataFormat=MESSAGE due to: No component found with scheme: cxf" (Error within Talend Route Builder when I press Run)" if you set the Camel component dependency to 'cxf' of the cMessagingEndpoint_1 component (Look under "Advenced settings" of the component cMessagingEndpoint_1). What i don't understand is that CXF has a special prefix for REST CXF Web Services (CXFRS, http://camel.apache.org/components.html) and how to import that prefix. May be you can import the prefix CXFRS when you import the corresponding .jar (Look under "Advenced settings" of the component cMessagingEndpoint_1 + "Use a custom component").
If i then try to run the example directly in the studio i get some "NoClassDefFoundError" errors. I believe that some camel / spring jars are missing in the studio runtime environment. But you can export the route and try to "import" these route in the talend esb (karaf). Unfortunately is in my example no proxy ws under the url http://KarafHostName:KarafPort/webserviceEndpoint reachable but may be you find a solution for this problem or it helps you to go further.
Good Luck!!!
One Star

Re: [resolved] REST service proxy route

Hi frankEichholz, I tried your suggestion. When I run the route in the Talend ESB console, I get the error: "karaf@tesb> Failed to create Producer for endpoint: Endpoint. Reason: org.apache.camel.RuntimeCamelException: java.lang.NullPointerException".
I have a simple requirement - just want to expose my REST service on Talend ESB and I can't believe that there is no (simple) way to do it?! Or?
Talend Team?
Can anybody answer my question how can I run (call) a talend Job deployed on Talend ESB (as OSGi bundle for ESB) from another application?
Thanks in advance!
One Star

Re: [resolved] REST service proxy route

Hi ipercinlic, me again.
I believe that you have to set some more cxf options.
bahaaldine mentioned that you have to set the wsdlURL option too.
"cxf://http://KarafHostName:KarafPort/webserviceEndpoint?wsdlURL=file:///pathToMyWSDL/file.wsdl&dataFormat=MESSAGE"
In my example (that currently does not work) i set the following options. I think it mainly depends on your wsdl.
"cxf://http://localhost:8080/webservices/TransportOrderService?wsdlURL=file:///C:/Temp/talend/TransportOrderService.wsdl&dataFormat=MESSAGE&portName={http://salt-solutions.de/logbase/transportorder/}TransportOrderServiceSoap"
Did you tried the "CXFRS" prefix and imported the corresponding jar (http://camel.apache.org/cxfrs.html)?
Sorry that i can not help you more but as i said i'm new to the technology.
Employee

Re: [resolved] REST service proxy route

hi,
For the Proxy Web server, can you try the following in ESB Studio
Create the HTTP listener for http://hostnameA:8080/web_app
1. Create a MessageEndpoint to listen for your HTTP requests (ProxyService)
2. In the Component panel, "Basic Settings" set the URL to "jetty:http://hostnameA:8080/web_app"
3. In the "Advanced Settings" click the + to add a dependency. Select 'jetty'
Forward request to http://hostnameB:8085/web_app (InternalService)
1. Create a MessageEndpoint
2. In the Component panel, under "Basic Settings" set the URL to http://hostnameB:8085/web_app
Create Proxy Service (Proxify)
You need to connect the inbound message and proxy the request to the service on hostnameB, _and_ connect the response messages on the outbound
1. Add a cProcessor
2. In Basic Settings of the Component add the following
//Print Request headers
System.out.println("> " + exchange.getIn().getHeaders());
//Create response message
exchange.getOut();

The first part is just for logging the request, so you can see something happening. The second line though is what connects the responses.

Certainly this works for me.
Hope this helps,
Ciaran
One Star

Re: [resolved] REST service proxy route

Hi cdynes,
I tried your proposed solution, but when I invoke the REST service deployed on hostnameB I didn't get the response.
The expected response of my REST service is an url (in string format).
I tried with this configuration:
First cMessageEndpoint (HTTP listener) url: (Proxy service) "jetty:http://mashina:8085/alfresco/service/service_name/process/28/doctypes/banka.odobravanjeKredita.gotovinski.kreditniZahtjev"
Second cMessageEndpoint url: (Real web service)
"http://mashina:8080/alfresco/service/service_name/process/28/doctypes/banka.odobravanjeKredita.gotovinski.kreditniZahtjev?throwExceptionOnFailure=false"
The response that I get is: "Message: "
Look for the screenshots.
I checked the servers access logger and the request that commes to my service is fine:
"GET /alfresco/service/service_name/process/28/doctypes/banka.odobravanjeKredita.gotovinski.kreditniZahtjev HTTP/1.1" 200 119
I am using Jboss as an application server.
Employee

Re: [resolved] REST service proxy route

One Star

Re: [resolved] REST service proxy route

Hi cdynes, when I use the cSetHeader component to set the "Authorization" header (because my internal service needs an authentication), the proxy route works fine. In my test route, the cSetHeader component is configured with these parameters:
Header: "Authorization"
Language: Constant
Expression: "Basic value for username and password (fixed)"
How should I configure the cSetHeader component or the entire route to use the authorization parameters which are coming with a request?
I use the Firefox REST Client to test my route.
Thanks a lot for your help!
Employee

Re: [resolved] REST service proxy route

Hi,
Good to hear!
Not sure I understand the setHeader() question. Is it that you need to add a new header for the internal REST service?

Ciaran
http://camel.apache.org/http.html
One Star

Re: [resolved] REST service proxy route

Hi,
Because my REST Internal service needs the authentication, when I invoke the Proxy service I need also to send the authentication parameters (username, password). Using the Firefox REST client plugin, I've set the header "Authorization" and the corresponding value for username and password (Authorization=Basic someValue). When I want to invoke the service, I always get the dialog to enter the username and password although I have the "Authorization" header set.
But, when I use the cSetHeader component with these parameters:
Header: "Authorization"
Language: Constant
Expression: "Basic value for username and password (fixed)"
the service works fine.
I don't want to use fixed authentication parameters but parameters which I will send when I invoke the Proxy service. The question is - how can I proxy my authentication parameters to my REST internal service?
One Star

Re: [resolved] REST service proxy route

Hi,
I found the solution to proxy authentication parameters from my Proxy service to REST internal service.
I added the following line to the cProcessor component:
exchange.getOut().setHeader("Authorization",exchange.getIn().getHeader("Authorization"));
It isn't necessary to use the cSetHeader component.
I have another question:
As you have seen, my REST internal service has this endpoint:
http://mashina:8080/alfresco/service/abitecm/process/28/doctypes/banka.odobravanjeKredita.gotovinski.kreditniZahtjev
"28" is a parameter and the "banka.odobravanjeKredita.gotovinski.kreditniZahtjev" is also a parameter
This endpoint was just for testing. The real endpoint is:
http://mashina:8080/alfresco/service/abitecm/process/PARAMETER1/doctypes/PARAMETER2
My requirement is: I want to be able to invoke the REST Internal service using the Proxy service by sending the parameters PARAMETER1 and PARAMETER2.
How should I configure my endpoints in the Proxy service and REST Internal service to meet my requirement? Do I need to re-configure my cProccesor component (Proxy)?
Thanks in advance!
Employee

Re: [resolved] REST service proxy route

Hi,
When you say parameters to you mean HTTP header, or perhaps using a query string?
You can get access to query or set your own custom HTTP headers:
System.out.println("uri: " + exchange.getIn().getHeader(org.apache.camel.Exchange.HTTP_URI));
System.out.println("params: " + exchange.getIn().getHeader(org.apache.camel.Exchange.HTTP_QUERY));
System.out.println("Param1="+ exchange.getIn().getHeader("X-Param1")); <---- you can add a header quite easily using the REST Client from Firefox.

Setting your own headers is quite simply. Using the query string you need to parse the string and then access the values.
Note: just a general note, if security is an issue, you should never expose any of the internal proxies URL, even if it's only part of the full URL. Rather, better off provide a mapping with the ProxyService, thereby the external client never understands any part of the internal REST service.
Thanks
One Star

Re: [resolved] REST service proxy route

Hi,
No, I don't want to use a HTTP header as a parameter.
My REST service has two parameters - "28" and "banka.odobravanjeKredita.gotovinski.kreditniZahtjev": http://mashina:8080/alfresco/service/abitecm/process/28/doctypes/banka.odobravanjeKredita.gotovinski.kreditniZahtjev
The response of this service is a link to a document for process number 228" and doctype "banka.odobravanjeKredita.gotovinski.kreditniZahtjev".
A response can also be another document link, for another process, eg. 256 and other doctype, eg. banka.odobravanjeKredita.gotovinski.IsplatnaLista.
The request is the same, but with other parameters:
http://mashina:8080/alfresco/service/abitecm/process/256/doctypes/banka.odobravanjeKredita.gotovinski.IsplatnaLista
How should I configure the endpoints in Proxy service (cMessageEndpoint_1) and Internal Service (cMessageEndpoint_2) to be able to call the Internal service with other parameters using the same route?
Thanks
Employee

Re: [resolved] REST service proxy route

Hi,
Try the following - connect a http message_endpoint to a cProcessor to another http Message_endpoint.
1. configure your jetty listener to allow all matching URIs (see http://camel.apache.org/how-do-i-let-jetty-match-wildcards.html)
"jetty:http://localhost:9000?matchOnUriPrefix=true"

2. In the cProcessor you need to grab the inbound URI and set the URI for the request to the Internal service
//grab inbound URI
String inbound=(String)exchange.getIn().getHeader(org.apache.camel.Exchange.HTTP_URI);
// setup URI for internal service
exchange.getOut().setHeader(org.apache.camel.Exchange.HTTP_URI, constant("http://localhost:8888"+inbound));

3. connect your cProcessor to a message endpoint (http://localhost/doesnotmatter") <--- the component only needs to be a "http://something"

Basically this should create a new URL based on the inbound URI for the resource + the Internal host/port, in my case localhost:8888
Cheers
One Star

Re: [resolved] REST service proxy route

Hi cydnes,
the route is finally completed and works fine. :-)) I've tested the route with various hostname configurations and REST service parameters - all routes are working fine and I get the expected result -> link to my document.
For those who want the same functionality, my final configuration is:
1. Proxy Service endpoint (cMessageEndpoint_1):
"jetty:http://hostnameA:8085/alfresco/service/abitecm/process?matchOnUriPrefix=true"
2. Proxify (cProcessor):
//If I do not remove the header, you will get the error "host parameter is null"
exchange.getIn().removeHeaders("CamelHttpPath");
//grab inbound URI
String inbound=(String)exchange.getIn().getHeader("CamelHttpUri");
// setup URI for internal service
exchange.getOut().setHeader("CamelHttpUri", constant("http://hostnameB:8080"+inbound));
//setup Authorization
exchange.getOut().setHeader("Authorization",exchange.getIn().getHeader("Authorization"));
//Create response message
exchange.getOut();
3. REST Internal Service (cMessageEndpoint_2:
"http://hostnameB:8080"
That's it!
Thanks a lot for your help!
Best Regards
Employee

Re: [resolved] REST service proxy route

Great! Nice to see it working.
One suggestion is to use the Context mechanism to allow for configuration of the hosts and ports for the Proxy endpoint and also the internal web server.
In the Proxy Service URL, set it to
"jetty:http://"+context.host + ":"+ context.port +"?matchOnUriPrefix=true"

In the cProcessor, use the context variables ->>
String inbound=(String)exchange.getIn().getHeader(org.apache.camel.Exchange.HTTP_URI);
System.out.println("> " + "http://"+context.internal_host+":"+context.internal_port+inbound);
// set URI for internal service
exchange.getOut().setHeader(org.apache.camel.Exchange.HTTP_URI, constant("http://"+context.internal_host+":"+context.internal_port+inbound));

Lastly create the 4 context values with default values in the properties panel
host=0.0.0.0
port=80
internal_host=myhost
internal_port=8000
One Star

Re: [resolved] REST service proxy route

Hi cydnes,
Thanks for your suggestions!
One Star

Re: [resolved] REST service proxy route

Hi,
can you tell how do we put certificate in this configuration?
So our endpoint is now: https://hostnameB:8443 and we have problem with certificate.
Where and how to set certificate so that service also work on https?
Thanks and regards,
Jurica
Here is an error:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1731)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:637)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:89)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828)
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.flushRequestOutputStream(MultiThreadedHttpConnectionManager.java:1565)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at org.apache.camel.component.http.HttpProducer.executeMethod(HttpProducer.java:195)
at org.apache.camel.component.http.HttpProducer.process(HttpProducer.java:100)
at org.apache.camel.impl.converter.AsyncProcessorTypeConverter$ProcessorToAsyncProcessorBridge.process(AsyncProcessorTypeConverter.java:50)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:77)
at org.apache.camel.processor.SendProcessor$2.doInAsyncProducer(SendProcessor.java:104)
at org.apache.camel.impl.ProducerCache.doInAsyncProducer(ProducerCache.java:272)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:98)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:77)
at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:98)