Apache Camel route, pull a value from a BSON document to put in an http connection string - apache-camel

I'm pulling a document from a MongoDB and want to take the value of startTime and add it as a connection parameter to an http url string.
The document looks like this:
Document{{_id=6110593a2d79803d4ebf2b83, startTime=1585009140000}}
I'm using projection to get only the field I need. I can log the value using jsonpath. But how to I get the value in a way I can cleanly add it to the http url?
from("timer:PingTimer?fixedRate=true&period=15000")
.setHeader(MongoDbConstants.SORT_BY).constant(Sorts.descending("startTime"))
.setHeader(MongoDbConstants.FIELDS_PROJECTION).constant(Projections.include("startTime"))
.setBody().constant("{}")
.to("mongodb:mongo?database={{spring.data.mongodb.database}}&collection=one_min&operation=findOneByQuery")
.log("Body ${body}")
.toD("https://this.that/api/markets/USD?resolution=60&start_time="
//How do I get the value of startTime in here?
)
.setBody().jsonpath("$.startTime") // This gets the value
;
[Edit]
Is this advisable?
.setHeader("test").jsonpath("$.startTime")
.toD("https://this.that/api/markets/USD?resolution=60&start_time=" + "${headers.test}")

Related

Add a value in http request in Gatling

I am using http request in Gatling as
.get(“http://Gatling.com/messages/“).
I need to add a param in the URL which will be picked from the variable ${Correlation}
So my URL should look like this
.get(“http://gatling.com/message/${CorrelationID}) I need to pass in from in my URL
How can I do that?
For fill variable use feed. There is official documentation Feeders
At first let's define feed variable:
val idFeeder = Iterator.continually(Map("CorrelationID" -> "some value"))
And add to scenario with request:
scenarion(...)
.feed(idFeeder)
.exec(....)

How to Pass POJO over JMS Queue in Apache Camel

I am relatively new to Jboss Fuse & Apache Camel. I poll a directory for specific XML files (using file filter) and extract info from XML content and save it in POJO, which then needs to be sent over JMS Queue (databaseQueue) along with the XML file to a route where I need to extract the params from POJO and insert in Database. But I am unable to pass the POJO over JMS queue to be able to retrieve in another route. I can't set the POJO in body as the original payload will be lost. Please help. Below is the sample route.
<route id="fileRoute">
<from uri="file:{{PFlowIn_AEROW}}?delay={{PFlowScanDelay}}&filter=#fileFilter&delete=true"/>
<process ref="saveFlowParamsInPOJO"/>
<recipientList>
<simple>activemq:queue:databaseQueue, activemq:queue:messageArchiveQueue, activemq:queue:XmlValidationQueue</simple>
</recipientList>
</route>
As far as I know you can only set one Object in message body, however you have two options.
Maybe you can deal with an object that contains the XML and your POJO.
Another option is to try to add the POJO to the message headers. Try to add it in your Processor step and the retrieve it from the other side.
exchange.getIn().setHeader("myPOJO", POJOvalue);
Edit:
As #BeenaRautela indicates, the second option proposed is not valid because headers only accepts non-object data type.
Another options are:
Send the POJO in the message body and try to send the XML as String in a header.
Store the POJO params in a Map and set it in a header.
Convert your POJO into data-interchange format (e.g. json) and save into header
Convert POJO to json string
Save json string into message header
Convert json string to POJO or map
You could import json library which are available in apache camel json component and then perform marshal/unmarshal.
If you wish to convert your POJO within your bean, you may also try Jackson ObjectMapper class to do conversion.
// Convert from POJO to json String
ObjectMapper objectMapper = new ObjectMapper();
String pojoAsString = objectMapper.writeValueAsString(yourPojo);
// Convert from json String to POJO
YourPojo yourPojo = objectMapper.readValue(pojoAsString , YourPojo.class);
// convert from json String to map
Map<String, Object> map = objectMapper.readValue(pojoAsString , new TypeReference<Map<String,Object>>(){});
Source of above ObjectMapper examples

How do you append a url as a query param value

My website has a search form where someone can search a URL beginning with http:// like this:
https://www.google.com
which should then be encoded and appended as a query parameter value like this:
localhost:4000/api/https%3A%2F%2Fwww.google.com
When I run it (above) locally, it works, but when deployed (below):
https://api.mysite.com/search/api/https%3A%2F%2Fwww.google.com%2F
=> returns 404.
If I type this in:
http://localhost:4000/api/https://www.google.com
I get this error:
Phoenix.Router.NoRouteError at GET /api/v1/https://www.google.com
no route found for GET /api/v1/https:/www.google.com (ExternalPing.Router)
I'm not sure if these are related. What is the correct way to append a url as a query parameter value?
I have already tried encoding with URI.encode and URI.encode_www_form but they didn't resolve this
Now you haven't posted your server code, so I am just going to assume here.
I think the problem is that you didn't encode the second string, since it contains / in the url you have problems.
The url is:
http://localhost:4000/api/https://www.google.com
The server will interpret it wrong. So you are asking for a route called:
/api/https:/
With a parameter called /www.google.com
You need to encode the query string.
But again this is guessing since I have no idea how your server looks.
I just tried calling an endpoint at my iis server with a unencoded url as a parameter, and this is what it gave me back:
<Error>
<Message>The request is invalid.</Message>
</Error>

Get error when I try to pass date value in URL to web api method

I create this date variable in client side:
this.latestDate = new Date(2001, 1, 1,1,1,1,1);
Here how it looks in client watch:
self.latestDate: Thu Feb 01 2001 01:01:01 GMT+0200 (Jerusalem Standard Time)
here is angularjs service that I use to asyncroniusly call my web api method:
$http.get(serviceUrl + "?date=" + self.latestDate);
And here is the web api method that I call from cilent:
[HttpGet]
public HttpResponseMessage GetByDate(DateTime date){}
But each time I call for web api method above, I get this error on cilent:
<Error>
<Message>The request is invalid.</Message>
<MessageDetail>
The parameters dictionary contains a null entry for parameter 'date' of non-nullable type 'System.DateTime' for method 'System.Net.Http.HttpResponseMessage GetByDate(System.DateTime)' in 'SensorObservation.Web.SensorsDataController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
</MessageDetail>
</Error>
Any idea why I get the error above?
First, doing this is a really bad idea:
$http.get(serviceUrl + "?date=" + self.latestDate);
A URL is a structured text format; it has formatting rules that must be followed. When you dump unstructured text into a structured format by using simple string concatenation, you are likely to be breaking some of those rules. I would recommend using the jQuery param function for this.
Second, you are serializing the date to a string using the default format, which is the one you see in the client watch. This may or may not work on the server. A better bet is to serialize using a well known format such as ISO 8601. I would recommend using the JavaScript date toISOString function for this.
Applying these changes, your API call code would look something like this:
var query = jQuery.param({ date: self.latestDate.toISOString() });
$http.get(serviceUrl + "?" + query);
Update
I ran a quick test since I was in my WebAPI code already, and you can create and use an endpoint with a DateTime parameter as long as the URL is formatted correctly.
My test endpoint looks like this:
[HttpGet]
[Route("test/datetest")]
public HttpResponseMessage DateTest(DateTime d)
{
HttpResponseMessage response = new HttpResponseMessage();
response.Content = new StringContent(d.ToString(), Encoding.UTF8, "text/plain");
return response;
}
It echoes the date back as expected.

How to pass a list value to a webapp2 backend via $.post?

In my coffeescript frontend I attempt to pass a list of value to the backend
data = {
id: [2, 3, 4]
}
$.post url, data
In the handler in a Google app engine (python) backend, I read the value like so:
id_value = self.request.get('id')
LOG.info("%s", id_value)
It always print out '2' only.
How can I get the backend to obtain the list [2,3,4]?
$.post by default sends data in url-encoded format, which handles nested structures in its own way.
You might need to encode the data in JSON before sending and then decode it on the server side - an example is here.
The request object provides a get() method that returns values for arguments parsed from the query and from POST data.
If the argument appears more than once in a request, by default get()
returns the first occurrence. To get all occurrences of an argument
that might appear more than once as a list (possibly empty), give
get() the argument allow_multiple=True.
Hence you should use something like the below snippet. You can find more details here.
id_value = self.request.get('id', allow_multiple=True)
If you need to access variables url encoded in the body of a request (generally a POST form submitted using the application/x-www-form-urlencoded media type), you should use something like this.
id_value = self.request.POST.getall('id')

Resources