Camel: POST-request routing by URL-pattern - apache-camel

I'm trying to catch some POST-request, log a message (and maybe a body or params in future); then pass them further to booHost, so the client will get the result of the call:
from("restlet:http://localhost:8090/api/endpointFoo?restletMethod=post")
.log("oh, it's a message!")
.routeId("someAPI")
.to("http://booHost:8090/api/endpointFoo?bridgeEndpoint=true&restletMethod=post");
That works just GREAT.
But:
What I need is the URL-pattern that will work that way. I'm trying:
from("restlet:http://localhost:8090/api/{endpoint}?restletMethod=post")
.log("oh, it's a message!")
.routeId("someAPI")
.to("http://booHost:8090/api/{endpoint}?bridgeEndpoint=true&restletMethod=post");
The "from" shots when I make the post. The message is logged.
But "to" seems not to treat {endpoint} as a param - it treats it like a constant; so the result of that call fails.
I don't need hardcoded endpoints because booHost API should be extended in future without Camel changes.
In other words, I need all calls to http://localhost:8090/api/* to be catched and resent to http://booHost:8090/api/* on the same endpoint.
Maybe I should use another component? Or How can I make it this way?
Thanks.

Thanks to #vikingsteve I've started to read about recipientList.
I've modified my code according to this FAQ question
The final version looks like this:
from("restlet:http://localhost:8090/api/{endpoint}?restletMethod=post")
.log(LoggingLevel.INFO, "POST-request to /${headers.endpoint} was sent")
.routeId("someAPI")
.recipientList(simple("http://booHost:8090/api/${headers.endpoint}?bridgeEndpoint=true&restletMethod=post"));
It works as suggested.

Related

Apache Camel - Mybatis select with parameters and useIterator

I'm trying to use Apache Camel (version 2.20.0) with mybatis component.
More specifically, I have to export a large set or record from database to file.
I'd like to prevent memory issues so I want to use the option consumer.useIterator. My route is:
from("mybatis:selectItemsByDate?statementType=SelectList&consumer.useIterator=true")
.split()
.body()
.process(doSomething)
to(file:my-path-file);
but my query has in input a parameter (the starting date to get data). How should I set this parameter?
In many example on internet I saw the parameter in the body or in the header of the Exchange message but I think is possibile only if the mybatis endpoint is in a "to" method. But the option "consumer.useIterator" is working only when the enpdoint is in a "from" method.
Please help me to understand how I can set the input for my query or if this is not supported yet (in this case if you can give some hint how to implement would be great)
thank you.
Then you need to start your route from something else, like a timer or direct endpoint, and then call the mybatis endpoint in a to, where you have set that information in the message body/header you use in the mybatis query so its dynamic.
Also you should set the splitter to be in streaming mode so it walks the iterator it gets from mybatis on-demand.

Intercepting Camel Endpoint Dynamically

I am trying to intercept an endpoint where the value of the URI matches some information in the exchange header.
Let say I have a field in the header called DatabaseName. I want to enforce that a specific route is only writing to the database specified in the header.
Can I do something like this?
interceptSendToEndpoint("mock:${in.header.DatabaseName}")
I tried that but it does not seem to work. What are my options?
I was also thinking of doing something like:
interceptSendToEndpoint("mock:*").when(...)?
But in this case, I am not sure if I can reference the URI of the intercepted node in the when expression.
Thanks
You can intercept using a wildcard and combine that with when to do what you want, see details at: http://camel.apache.org/intercept
The is a header on the Message with the key Exchange.INTERCEPTED_ENDPOINT (CamelInterceptedEndpoint) that has the endpoint uri that was intercepted. You can use that in the when to match the predicate. Something a like:
interceptSendToEndpoint("mock:*")
.when(simple("${header.CamelInterceptedEndpoint} == ${in.header.DatabaseName}"))
...
Use the recipientList instruction for this: http://camel.apache.org/how-do-i-use-dynamic-uri-in-to.html

How to rewrite function used POST metod to use also GET method in LoadRunner?

For POST method I have this piece of code in LR (it is working):
web_custom_request(transname,
URL,
"Method=POST",
"TargetFrame=",
"Mode=HTML",
"Resource=0",
"Referer=",
EncodingType,
lr_eval_string(request),
LAST);
This piece of code is placed in a separated .c file and called from user_init using a long sequence of related functions working with XML, arrays, strings data.
URL for POST requests has structure in user_init like this:
URL=https://{HOST}/aaa/bbb/page.asp
Also user_init contains this piece of code:
web_custom_request("Login_page",
"URL=http://{HOST}/api/04_00/Pr_NAME.asp",
"Method=POST",
"RecContentType=text/xml",
"Body="
"<?xml version=\"1.0\"?>"
"<Request xmlns=\"http://api.rr.com/Pr_NAME\">\r\n"
" <MethodRequest>\r\n"
" <AuthenticateUserRequest appID=\"value_appID\" password=\"value_password\">\r\n"
" <User>\r\n"
" <LoginName>value_LoginName</LoginName>\r\n"
" </User>\r\n"
" </AuthenticateUserRequest>\r\n"
" </MethodRequest>\r\n"
"</Request>\r\n",
LAST);
I need something additional to this code, that will allow to send both POST and GET requests to web-service. Now it sends only POST requests.
There are some questions:
1) How should I change this function to get the possibility to send both types of requests, POST and GET? What strings should I add to this function?
2) How should I change the URL for GET requests?
I think, it should be something like this:
URL=https://{HOST}/aaa/bbb/page.asp?param1=value1&param2=value2...&paramN=valueN
But what parameters should I add as param1, param2, ..., paramN?
How to define, how many and what parameters I need put in this URL construction?
Should I write this structure:
URL=http://{HOST}/api/04_00/Pr_NAME.asp?appID=value_appID&password=value_password&LoginName=value_LoginName
or shouldn't I add LoginName=value_LoginName in this structure?
3) How can I combine both 2 methods POST and GET in 1 function, to have the possibility to send both types of requests, POST and GET, from LR?
Please, could you help me? I'm a novice in data transferring in LR using POST and GET methods and functions.
Here are some answers (not entirely related to LR).
1) POST and GET are HTTP verbs that tell the server what you expect it to do with your request. There is no rules on what the server should do but instead conventions. The conventions are:
GET - Tells the server: Please give me data related to the parameters I provide in the querystring.
POST - Tells the server: Here is some data in the body of this request, please do something with it (usually but not always create a record of something).
There is no sense of sending both types of verbs in the same request.
In any case to set the verb use the "method" parameter (in your example it says "Method = POST" so you can change it to "Method = GET".
2)GET request sometimes needs parameters. As a convention you don't send those parameters in the Body but in a structure called querystring which comes after the URL separated by "?". The querystring is a list of parameter name and its value. Please google "querystring" for more information. The parameters you should use are the ones expected by the server. You have to ask the server creator about which parameters to send.
3) As I mentioned above, this doesn't make sense.
Hope this helps.
Since you likely have recorded this conversation, the natural question to ask why you would want to alter the request method in your application code to something else other than what is deployed? This is a break in your test between deployed and test and would need to be noted with your test results.
Requests' method should either POST or GET or other types of methods. There should NOT be both. I understand that you are doing self-study, but it is protocol violation.

How can I test /_ah/bounce?

I have implemented a bounce handler by copying the code from the documentation, but now I would like to test that this code works before I push it out to production. Is there an easy way to do this?
I wound up using a Chrome extension called POSTMan to formulate a POST request with all of the required parameters, as shown in the docstring of the BounceNotification class:
post_vars: a dict-like object containing bounce information.
This is typically the self.request.POST variable of a RequestHandler
object. The following keys are expected in the dict:
original-from
original-to
original-subject
original-text
notification-from
notification-to
notification-subject
notification-text
raw-message
When I sent all of the required POST params, I indeed saw my bounce handler get the request and log the appropriate information.

cakephp url append invalid parameter But still work. Should be 404 page not found

I find a problem when i develop application via cakephp.
for example: my url is http://localhost/controller/view/id this is working fine.
BUT, when i append more invalid parameter, it still works,
like http://localhost/controller/view/id/adfasd/adfasdf/asdfasdf/asdfasdf
It should show up 404 page not found.
Shall i need to use $this->passedArgs to check pass parameter manually in controller then throw exception? Or is there any configuration?
How can i deal with this case
Thank you
You should first look here Cakephp, Routing-Named params to find out how to properly use them.
As you should add which one to use, you should also add a regex to your id in the route.
Also when sending the data to an action you should throw the exception there like it is explained here: cakephp deal with passing wrong parameter in url

Resources