The concept of routing is nice in theory but in practice, I am a bit confused. I have a CXF method in my webservice
public Response someMethod(Request r) {
}
what I don't get is I need to route the Request to some further node so am I really supposed to do that in the java code or will camel generate an interface(asynch hopefully) that I can wire that node up to some transformer to a next node validator to some store and forward, etc and then finally have the store and forward reply with a Response that is somehow sent out the socket the Request came in from originally.
In the above method, I am forced to return the response back to the client in that method, right?
If I am supposed to put the code in the webservices method, is there some camel context I am supposed to call into?
Also, I want the "RAW" parameters of the SOAP method call and don't want to deal with SOAP Header and then also need to expose some REST apis as well that just accept a String.
EDIT: The proxy example from the answer below is the closest I have seen but even that one if I want to short cut and not even call the real webservice at an earlier node in the pipeline, I can't. I seem to have to call the end webservice code which is not wanted as we don't have any webservice code. We are trying to run it through existing pojos from a webservice call. If the validation node fails, we want to return a response, if it succeeds we want to forward the request on to another node where if that node fails we return a response or if it succeeds we want to forward the request on. There seems to be nothing for this??? Also, this seems like a pretty typical case to me so I am surprised or I am not getting something with all these ESB frameworks(mule, camel so far).
thanks,
Dean
Look at this official Example, it'll show how to do this
Or this Cxf proxy example if you want the RAW request
If you are in a Spring MVC webapp already - you could perhaps do this a bit easier with Spring WS and Jaxb. But that is a matter of taste. Example code here
never solved, we dropped camel as it is quite a pain compared to rolling your own.
Related
I am trying to bridge Camel REST endpoints to a backend server. Corresponding REST DSL is as follows:
from("rest:get:tt:/{id}")
.toF("%s/%s?bridgeEndpoint=true","http://192.168.1.1:80","jjjj/llll/pppp/{id}");
My expectation is that the request should be forwarded to http://192.168.1.1:80/jjjj/llll/pppp/id But what actually happens is that the request gets forwarded to http://192.168.1.1:80/jjjj/llll/pppp/%7Bid%7D/tt/id
Can any one suggest, what am I doing wrong and how I can achieve the desired behaviour? I am using Spring Boot Camel 2.3.4 which uses Camel 3.5.0 internally.
Mean while, I have found a work around that to use .to() instead of .toF(). With .to(), I achieved desired behavior. Camel route DSL is Something like
from("rest:get:tt:/{id}").to("rest:get:jjjj/llll/pppp/{id}?host=http://192.168.1.1:80")
But question still remains open that why it is not working with .toF().
Seems like you're using {id} syntax for http component uri, but I think it's only recognized by the rest component, so instead of having:
from("rest:get:tt:/{id}")
.toF("%s/%s?bridgeEndpoint=true", "http://192.168.1.1:80", "jjjj/llll/pppp/{id}");
you could try using dynamic endpoint .toD() with simple expression ${header.id}:
from("rest:get:tt:/{id}")
.toD("http://192.168.1.1:80/jjjj/llll/pppp/${header.id}?bridgeEndpoint=true");
Not exactly sure if that's what you're aiming for though
With the "traditional" web framework, one could use e.g. AbstractRequestLoggingFilter for implementing a generic logging filter. With web-reactive the filter isn't called anymore (what makes sense, since it operates on HttpServletRequest).
Can anyone point me into the right direction for implementing a request filter with web-reactive, which logs the HTTP request, including its body, before and after the request like in AbstractRequestLoggingFilter?
You can implement a WebFilter and declare it as a bean, it will be picked up automatically.
Note that the WebFilter contract is based on ServerWebExchange, which holds a ServerHttpRequest. The body is not accessible directly as byte[], but rather as a Flux<DataBuffer>; this is not meant to be buffered in memory or consumed by the filter, so logging the whole request body is more complex than in MVC scenarios. Also, you should avoid blocking operations during request processing.
Scenario:
I have a Node and Angular web app.
It needs to call an external api (a third party service) for data (more specifically this: https://api.represent.me/api/questions/).
Question:
Is it better to make this external call from the Angular frontend: GET http://thirdpartyservice.com/api/data or have the frontend calling a same domain Node endpoint: GET http://example.com/node-backend-api which then calls GET http://thirdpartyservice.com/api/data which then fetches and processes the data from the third party api before passing it back to angular?
Thoughts:
I guess two api calls is less desirable, but it is on the same domain
so would this not really be an issue?
GETing from the Node side would be more secure (especially if secret
keys were used), and also mask the fact that a third party service is
used.
CORS stuff might get in the way if calling from the frontend.
Is context key here, e.g. calling font apis from the
frontend is probably best, but fetching and needing to process data
is probably better from the backend.
What do others recommend (and do) and are there any other for or against points to add to the 'thoughts' too?
It depends on what your 3rd party API requires.
If you need some credentials to call the API it's probably better to handle the call in backend because of security concerns.
If the API delivers time sensitive data, like some auto-complete information as you type, it might be good to not do the extra roundtrip to the backend and call it from the frontend.
You might create a subdomain which points to the 3rd party server,
like 3rdparty-api.yourdomain.com, this removes a lot of cross-domain issues. But this needs cooperation of your 3rd party provider.
So, there is no clear yes or no answer but it depends on the situation and focus of your API.
Your solution looks fine, the only thing that may get in your way is if the 3rd party API you are using provides any sort of analytics. If you call it from Node you will overwrite the Agent and IP information that would be gathered if you called from UI. Other than that, I believe making the request directly from UI could reduce a little bit the load on the server, but I don't know if that matters to you.
I would say we should also take care about code duplication. In your case you are all JavaScript, but that is not true for many others. So let's say I consume api.github.com so I will not want to make some calls from frontend and some from the backend, then I think creating a controller which will handle all of this is a good choice.
Except for the cases like any analytics or tracking software, an extra round trip is ok.
As #Wolffc said, this can also prevent sending access_token to the browser which may be misused.
I currently have a camel route that exposes a cxf endpoint. When a messages comes through the endpoint I would first enrich that message with some information from another webservice and then do more processing afterwards. However, I want make the first half of this route synchronous so I can send back a response to whomever called my exposed cxf endpoint.
The route looks something like this:
from(cxf:CxfEndpoint)
.process(someProcessing)
.to(cxf:ExternalCxfEndpoint)
.to(activemq:queue:somequeue)
//return a response back to caller here
from(activemq:queue:somequeue)
... //additional processing here
...
The reason for this is because when a message comes via my exposed cxf endpoint I don't know if it's a valid message. I need to first validate it with the message enrichment. Once the message is enriched, I want let whomever sent the message know that their message is accepted but don't want them to wait for the message to make it through the whole route as that could take hours.
Does anyone know how this would work?
Thanks in advance!
I believe all you need to do is set exchangePattern to InOnly a.k.a. make it an Event Message. This should have your route not wait for a reply from ActiveMQ. Camel exchange will default to InOut when it's originating from a web service, as in your case.
A related question with an answer from a Camel dev here.
Also see this one for some details on the behavior when your broker is down.
Yes definitely , 100% possible. A simple example would be this :
From cxf endpoint
Store your request in a camel property or header
To xslt - generate xslt for cxf endpoint - Synchronous flow
Reset your original payload using set body.
Wiretap Endpoint - to any endpoint downstream or even a route , this becomes asynchronous . This won't take part in the above sync response .
Note- step 2 & 4 may not be required, it depends on your use case .
There are whole lots of things you can do, I just gave a very simple example . It doesn't need to be wiretap as well, but wiretap helps us not to write any additional custom exceptional handling.
I've been working on a REST implementation with my existing Cake install, and it's looking great except that I want to use HTTP Digest Authentication for all requests (Basic Auth won't cut it). So great, I'll generate a header in the client app (which is not cake) and send it to my cake install. Only problem is, I can't find a method for extracting that Digest from the request...
I've looked through the Cake API for something that I can use to get the Digest Header. You'd think that Request Handler would be able to grab it, but I can't find anything resembling that.
There must be another method of getting the digest that I am overlooking?
In the meantime I'm writing my own regex to parse it out of the Request... once I'm done I'll post it here so no one has to waste as much time as I did hunting for it.
Figured it out. It's already accessible via PHP as $_SERVER['PHP_AUTH_DIGEST']
So then you pass to parseDigestAuthData($_SERVER['PHP_AUTH_DIGEST']);
<bangs head against wall>