How to store back the nested response data in protobuf? - c++

I'm using GRPC to remote call the database and store the data in the response format given by the .proto file. My program is based on CPP programming:
// similar .proto file
message FinalResponse
{
repeated IntermediateResponse finals = 1;
}
message IntermediateResponse
{
string name = 1;
InitialResponse foo = 2;
}
enum InitialResponse
{
COUNTRY_UNKNOWN = 0;
COUNTRY_INDIA = 1;
}
For my case, the request message is empty(no field) so didn't displayed here. I went through the protocol buffer documentation and tried this:
// firstly called the database and stored the intermediateResponse in a vector<pair<string, string>> data
//pseudo-code below:
FinalResponse result;
for cur_data in data:
{
IntermediateResponse *interResp = result.add_finals();
interResp->set_name(cur_data.first);
interResp->set_foo(static_cast<InitialResponse>(cur_data.second));
}
When I'm executing this, there is no syntax/build error but grpc status is saying we didn't get any response back:
ERROR - (12) No message returned for unary request
I want to clarify that service was running from the server side and client is able to detect that service as well, I'm suspecting that maybe the returned data through database is not properly stored in the response message and so GRPC is deducing that we didn't get back any data. Please suggest some work around for this?

Looks like it was the server side issue probably, now with the same changes, it is able to store the response properly.
Maybe server went down for some time and returned error.

Related

Camunda- Acessing to a specific json element

I would like to obtain in a response of http-connector, only the “number” element, but I cannot obtain it.
I’m trying to have an inline Javascript with the following statement:
S(response).prop(“status”).prop(“number”).numberValue();
but it shows an error: SPIN/JACKSON-JSON-01004 Unable to find ‘status’
What it’s wrong in the statement?
Rest response to parse:
{
“status”: {
“number”: 200,
“type”: “OK”,
“description”: “Status OK”
}
}
There is no obvious issue with your expression. I would debug further to see if response indeed contanis the Json string you posted. The error shows that response exists, but the content differs.
This working example I just created may help you:
https://github.com/rob2universe/camunda-http-connector-example
If this does not help, you could share more info, e.g. the process model, server log, service you are calling...

How to specify the database in an ArangoDb AQL query?

If have multiple databases defined on a particular ArangoDB server, how do I specify the database I'd like an AQL query to run against?
Running the query through the REST endpoint that includes the db name (substituted into [DBNAME] below) ie:
/_db/[DBNAME]/_api/cursor
doesn't seem to work. The error message says 'unknown path /_db/[DBNAME]/_api/cursor'
Is this something I have to specify in the query itself?
Also: The query I'm trying to run is:
FOR col in COLLECTIONS() RETURN col.name
Fwiw, I haven't found a way to set the "current" database through the REST API. Also, I'm accessing the REST API from C++ using fuerte.
Tom Regner deserves primary credit here for prompting the enquiry that produced this answer. I am posting my findings here as an answer to help others who might run into this.
I don't know if this is a fuerte bug, shortcoming or just an api caveat that wasn't clear to me... BUT...
In order for the '/_db/[DBNAME/' prefix in an endpoint (eg full endpoint '/_db/[DBNAME/_api/cursor') to be registered and used in the header of a ::arangodb::fuerte::Request, it is NOT sufficient (as of arangodb 3.5.3 and the fuerte version available at the time of this answer) to simply call:
std::unique_ptr<fuerte::Request> request;
const char *endpoint = "/_db/[DBNAME/_api/cursor";
request = fuerte::createRequest(fuerte::RestVerb::Post,endpoint);
// and adding any arguments to the request using a VPackBuilder...
// in this case the query (omitted)
To have the database name included as part of such a request, you must additionally call the following:
request->header.parseArangoPath(endpoint);
Failure to do so seems to result in an error about an 'unknown path'.
Note 1: Simply setting the database member variable, ie
request->header.database = "[DBNAME]";
does not work.
Note 2: that operations without the leading '/_db/[DBNAME]/' prefix, seem to work fine using the 'current' database. (which at least for me, seems to be stuck at '_system' since as far as I can tell, there doesn't seem to be an endpoint to change this via the HTTP REST Api.)
The docs aren't very helpful right now, so just incase someone is looking for a more complete example, then please consider the following code.
EventLoopService eventLoopService;
// adjust the connection for your environment!
std::shared_ptr<Connection> conn = ConnectionBuilder().endpoint("http://localhost:8529")
.authenticationType(AuthenticationType::Basic)
.user(?) // enter a user with access
.password(?) // enter the password
.connect(eventLoopService);
// create the request
std::unique_ptr<Request> request = createRequest(RestVerb::Post, ContentType::VPack);
// enter the database name (ensure the user has access)
request->header.database = ?;
// API endpoint to submit AQL queries
request->header.path = "/_api/cursor";
// Create a payload to be submitted to the API endpoint
VPackBuilder builder;
builder.openObject();
// here is your query
builder.add("query", VPackValue("for col in collections() return col.name"));
builder.close();
// add the payload to the request
request->addVPack(builder.slice());
// send the request (blocking)
std::unique_ptr<Response> response = conn->sendRequest(std::move(request));
// check the response code - it should be 201
unsigned int statusCode = response->statusCode();
// slice has the response data
VPackSlice slice = response->slices().front();
std::cout << slice.get("result").toJson() << std::endl;

RESTful API, C++restSDK, JSON in C++

I am trying to use THIS RESTful API: https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md
To do this, I am using THIS C++ SDK: https://github.com/Microsoft/cpprestsdk
The Binance API returns everything as JSON, which is where I think my issue lies.
My code is here: https://pastebin.com/SeBAxvA0
I think the error is here in this function (commented as well in pastebin):
void print_test(json::value const & value){
if(!value.is_null()){
//I am doing something wrong here I'm pretty sure.
auto response = value[L"responseData"];
//"responseData" is probably not what should be here I think?
auto results = response[L"serverTime"];
wcout << results.as_integer() << endl;
}
}
Basically, I am trying to just test out this API by doing a simple GET method for the server time from the Binance API. According to the Binance documentation:
Check server time
GET /api/v1/time
Test connectivity to the Rest API and get the current server time.
Weight: 1
Parameters: NONE
Response:
{
"serverTime": 1499827319559
}
So I would like to do a GET request for that JSON, and then have my C++ program output the value of serverTime. When I try to run my code as is, I get an error saying:
error: no viable overloaded operator[] for type
'const json::value'
auto response = value[L"responseData"];
However, I am following along with an example from the C++restSDK found here:
http://mariusbancila.ro/blog/2013/08/02/cpp-rest-sdk-in-visual-studio-2013/
I think my issue has something to do with the two lines under the comment I made on line 45 in my pastebin. Presumably, I am assigning the wrong values to one or both of the variables under that line. I know this is a pretty specific help request, but does anyone know what I'm doing wrong and how to get the value of serverTime to display?
I solved this issue on my own after much digging :)
Error was in this function and it is now fixed with this code:
void print_test(json::value const & value){
if(!value.is_null()){
json::value test = value;
cout << test["serverTime"] << endl;
}
}

How to get CookieManager from JMeter SampleResult

I have a backend listener that posts JMeter results to an external server. It works for most parts. However, I'd like to get cookie info for failed requests. Backend listener only gets SampleResult and I don't see an API to access cookie info from SampleResult. Does anyone have an idea?
View Result Tree listener is able to print out request cookies, so there must be a way. However, it's not obvious what's the class name for that particular listener. If anyone can point me to that source code, it'll be a starting point.
With current JMeter implementation it is not possible unless your create your own AbstractBackendListenerClient implementation which will be cookies-aware.
Also depending on how do you parse result you can substitute a "not interesting" SampleResult field (for example Response Message) with cookie values for failed requests. It can be done using i.e. JSR223 PostProcessor and the following Groovy code
if (!prev.isSuccessful()) {
def manager = sampler.getCookieManager()
def cookies = new StringBuilder()
for (int i = 0; i < manager.getCookieCount(); i++) {
cookies.append(manager.get(i).getName()).append('=').append(manager.get(i).getValue())
}
prev.setResponseMessage(cookies.toString())
}
Hard to help without seeing some code, but one general direction could be this: you can check if your SampleResult is of type HTTPSampleResult, and if yes, get its cookies, using getCookies() method. Whole process could be wrapped as the following function:
public String getCookiesForHttpResult(SampleResult sampleResult) {
if (sampleResult instanceof HTTPSampleResult) {
HTTPSampleResult httpSampleResult = (HTTPSampleResult) sampleResult;
return httpSampleResult.getCookies();
}
// not HTTP result
return null;
}
Something like that is done in JMeter's RequestViewHTTP.java
Getting CookieManager in backend listener can be problematic, since it's mutable: by the time backend listener reads from CookieManager, list of cookies may be different from the time of request execution.

Using cpp-netlib 0.8 as a HTTP Proxy - Helpless

I am trying to use cpp-netlib in a project of mine. I simply need to create a HTTP proxy into which I can plug in some functionality later. For now, I just need to listen to requests, send request to a new site, and forward the answer of the new request to the first request.
This is the code I have so far:
std::string ip = source(request);
http::client client;
std::ostringstream url;
url << "www.example.com/image.jpg";
http::client::request clientRequest(url.str());
http::client::response clientResponse = client.get(clientRequest);
response = server::response::stock_reply(server::response::ok);
response.headers = clientResponse.headers(); //This is not possible - not correct type or something
response.content = clientResponse.body();
Results in error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::multimap<_Kty,_Ty>' (or there is no acceptable conversion)
A request to the test image I am using yields 19.4kb data in the response. If I do the same request through the above code (without header copying) I get an answer with about 4kb data, which the browser tries to show as text (default header). It does seem like an image though, even in text.
Anyone out there that is familiar with cpp-netlib-0.8? is response.content = clientResponse.body(); the correct way? How can I add the correct headers?
It's altogether too much template weirdness in cpp-netlib for me to understand it right now!
Thanks...
Instead of using:
response.content = clientResponse.body();
the correct way is:
std::string body_content = body(clientResponse);
also, you are using response as variable, while your variable is actually clientResponse
For more examples read cpp-netlib v0.8 documentation