Headers h = t.getResponseHeaders(); // t - is HttpExchange
String val = h.getFirst("???"); // what to put here?
System.out.println("result: " + val);
I've tried to use a value like "cookie", but it returned null, how can I retrieve the browser cookie id? to implement manually a session?
Related
I'm trying to create from an async client a method to retrieve items from a CosmosDB but I'm afraid I'm full of questions and little to no documentation from Microsoft side
I've created a function that will read from a cosmosDB a list of items, page by page, which continuation will depend on a continuityToken. The methos looks like this. Please, be aware there could be some minor mistakes non related to the core functionality which is reading page by page:
#FunctionName("Feed")
public HttpResponseMessage getFeed(
#HttpTrigger(
name = "get",
methods = { HttpMethod.GET },
authLevel = AuthorizationLevel.ANONYMOUS,
route = "Feed"
) final HttpRequestMessage<Optional<String>> request,
#CosmosDBInput(
name = "Feed",
databaseName = Constants.DATABASE_NAME,
collectionName = Constants.LOG_COLLECTION_NAME,
sqlQuery = "SELECT * FROM c", // This won't be used actually as we use our own query
connectionStringSetting = Constants.CONNECTION_STRING_KEY
) final LogEntry[] logEntryArray,
final ExecutionContext context
) {
context
.getLogger()
.info("Query with paging and continuation token");
String query = "SELECT * FROM c"
int pageSize = 10; //No of docs per page
int currentPageNumber = 1;
int documentNumber = 0;
String continuationToken = null;
double requestCharge = 0.0;
// First iteration (continuationToken = null): Receive a batch of query response pages
// Subsequent iterations (continuationToken != null): Receive subsequent batch of query response pages, with continuationToken indicating where the previous iteration left off
do {
context
.getLogger()
.info("Receiving a set of query response pages.");
context
.getLogger()
.info("Continuation Token: " + continuationToken + "\n");
CosmosQueryRequestOptions queryOptions = new CosmosQueryRequestOptions();
Flux<FeedResponse<LogEntry>> feedResponseIterator =
container.queryItems(query, queryOptions, LogEntry.class).byPage(continuationToken,pageSize);
try {
feedResponseIterator.flatMap(fluxResponse -> {
context
.getLogger()
.info("Got a page of query result with " +
fluxResponse.getResults().size() + " items(s)"
+ " and request charge of " + fluxResponse.getRequestCharge());
context
.getLogger()
.info("Item Ids " + fluxResponse
.getResults()
.stream()
.map(LogEntry::getDate)
.collect(Collectors.toList()));
return Flux.empty();
}).blockLast();
} catch (Exception e) {
}
} while (continuationToken != null);
context
.getLogger()
.info(String.format("Total request charge: %f\n", requestCharge));
return request
.createResponseBuilder(HttpStatus.OK)
.header("Content-Type", "application/json")
.body("ALL READ")
.build();
}
For simplicity the read items are merely logged.
First question: We are using an async document client that returns a Flux. Will the client keep track of the token? It is a stateless client in principle. I understand that the sync client could take easily care of this case, but wouldn't the async client reset its memory of tokens after the first page and token has been generated?
Second: Is the while loop even appropriated? My assumption is a big no, as we need to send back the token in a header and the frontend UI will need to send the token to the Azure Function in a header or other similar fashion. The token should be extracted from the context then
Third: Is the flatMap and blockList way to read the flux appropriate? I was trying to play with the subscribe method but again I don't see how it could work for an async client.
Thanks a lot,
Alex.
UPDATE:
I have observed that Flux only uses the items per page value to set the number of items to be retrieved per batch, but after retrieval of one page it doesn't stop and keeps retrieving pages! I don't know how to stop it. I have tried substituting the Flux.empty() per Mono.empty() and setting a LIMIT clause in the sql query. The first option does the same and the second freezes the query and never returns apparently. How can I return one page an only one page along with the continuation token to do the following query once the user clicks on the next page button?
I need to populate a database with the fields of the HTTP requests based on if the sender IP is valid or not.
For example if someone make a GET request on my IP with that:
/test/demo.php?name1=value1&name2=value2
How can I receive it so I can handle it and perform actions like:
Get the ip of the sender (And validate it - just confronting it with a list -)
Recognize the type of the Request
Extrapolate the fields (value1 and value2) and save them in variables
I'm using java.net.http package
You can't perform that using package java.net.http because you need to create an http server not an http client. To achieve that, you need HttpServer which is found in package com.sun.net.httpserver.
The first thing is to create a new instance of HttpServer :
final int port = 3000;//You can change with your port number you need
final HttpServer httpServer = HttpServer.create(new InetSocketAddress(port), 0);
System.out.println("Listening port : " + port);
Then, configure an http context. The first parameter accepts the route you defines and the second parameter accepts the http handler in which you can extract all your data that you need to store in your database.
httpServer.createContext("/test/demo.php", buildHttpHandler());//buildHttpHandler is to create
What contains the function buildHttpHandler()? :
Each time where route /test/demo.php is called, the content of arrow function is called. Here, we attempt only to create a simple page html and serves it to the http client. But before responding http client, we need to extract all data you need (ip, request type and parameters).
return httpExchange -> {
final String html = "<!DOCTYPE html>\n" +
"<html>\n" +
" <head>\n" +
" <title>Page</title>\n" +
" <meta charset='utf-8'/>\n" +
" </head>\n" +
" <body>Ok</body>\n" +
"</html>";
//Function to create
extractData(httpExchange);
httpExchange.getResponseHeaders().set("Content-Type", "text/html; charset=utf-8");
httpExchange.sendResponseHeaders(200, html.length());
final OutputStream outputStream = httpExchange.getResponseBody();
outputStream.write(html.getBytes(StandardCharsets.UTF_8));
outputStream.close();
};
What contains extractData() function?
In this function we will extract the data you need.
final String ip = getClientIp(httpExchange);
System.out.println("IP : " + ip);
final String requestType = httpExchange.getRequestMethod();
System.out.println("Request type : " + requestType);
final Map<String, String> parameters = extractParameters(httpExchange);
displayParameters(parameters);
Extracting ip client is more complicated because sometime client uses proxy that's why we create a dedicated function getClientIp() to extract the ip.
In this function, we attempt to extract firstly proxy ip. If not found, we extract standard ip from remote :
final String ip = getProxyIp(httpExchange);
return ip == null ? httpExchange.getRemoteAddress().getAddress().getHostAddress() : ip;
To extract proxy ip, we create another function getProxyIp(). It attempts to extract the ip provided from x-forwarded-for request header.
final List<String> ips = httpExchange.getRequestHeaders().get("x-forwarded-for");
return ips == null ? null : ips.get(ips.size() - 1);
I don't know what do you mean with extrapolating fields but you can store all data in a Map variable. The key will be the name of parameter and the value will be the value of parameter. But this is complicated also because we need to parse the string value from name1=value1&name2=value2. So, we create a new function extractParameters(). It contains :
final String query = httpExchange.getRequestURI().getQuery();
final Map<String, String> parameters = new HashMap<>();
if (query != null) {
final String[] firstParts = query.split("&");
for (final String firstPart : firstParts) {
final String[] secondParts = firstPart.split("=");
final String name = secondParts[0];
final String value = secondParts.length > 1 ? secondParts[1] : null;
parameters.put(name, value);
}
}
return parameters;
You notice maybe what is displayParameters() content. It just attempts to display, parameters retrieved from extractParameters().
for (final Map.Entry<String, String> parameter : parameters.entrySet()) {
System.out.println("Parameter key : " + parameter.getKey());
System.out.println("Parameter value : " + parameter.getValue());
}
And finally don't forget to start the http server :
httpServer.start();
You can check for a full code here https://gist.github.com/razafinarivohanania/24fe0986ea5868097404f2a758131823
When you test it, you can get something like :
IP : 127.0.0.1
Request type : GET
Parameter key : name2
Parameter value : value2
Parameter key : name1
Parameter value : value1
I'm USING GATLING AND trying to use in java's library "Base64" in scala for sending encode uder:password in header ("authorization") request, with dynamic values:
I'm trying to do as follow :
val register = {
exec(request.asJSON
.check(status.is(200))
.check(jsonPath("$..user").saveAs("user"))
.check(jsonPath("$..password").saveAs("password"))
).pause(1)
}
val myvalue: HttpRequestBuilder = Utils.createPostFormParamsRequest(
"myvalue",
login,
Map("value"-> ("Basic " + Base64.getEncoder.encodeToString((("${user}").getBytes() + ":" + ("${password}").getBytes()).getBytes("utf-8")))),
Map())
I'd tried also Base64.getEncoder.encodeToString(("${uesr}" + ":" + "${password}").getBytes("utf-8"))))
But it seems like the Base64 take the String "${user}" and not the actual value, so the encryption does not work properly.
I'd tried to :
val helper = {
exec { session =>
val user : String= (session("user").as[String])
val password : String= (session("password").as[String])
val temp = "Basic " + Base64.getEncoder.encodeToString((user + ":" + password).getBytes("utf-8"))
val temp2: HttpRequestBuilder = Utils.createPostFormParamsRequest(
"bla",
login,
Map("value"-> temp),
Map())
val assert = {
exec(helper.asJSON
.check(status.is(200))
.check(header("answer").saveAs("answer"))
).pause(1)
}
session
}
And here the encryption works properly, but the "exec" do not.
There is a way to save the values in run time without part of the exec?
I don't know Gatling that well, but I think this should work. It's not the prettiest but without seeing the full code and how it's used it's a bit difficult to come up with something that looks good:
var token: String = null
val registerAssert = exec(...)
def finalToken = {
Utils.createPostFormParamsRequest(
"Final token",
Constants.LOGIN,
Map("Authorization"-> token),
Map())
}
def saveToken(s: Session) = {
token = "Basic " + Base64.getEncoder.encodeToString((s("uuid").as[String].getBytes() + ":" + s("secret").as[String].getBytes()).getBytes("utf-8")
s
}
// now you're actually executing the above
scenario(...)
.exec(registerAssert)
.exec(saveToken(_))
.exec(finalToken) // I'm assuming finalToken is executable
The intention of this is to first save the token value in a class variable, and then only construct the finalToken request (which uses that token) afterwards. Hence the def, and when it's called the token value will have been set.
I am creating some nodes within a transaction in neo4j using the rest api. After all nodes have been created (typically between 3 and 5 in one transaction), I have to create some relationships between them. To do this I need, of course the location of the nodes, and this is the source of my problem. I can't figure out how to get this location.
According to documentation, I should be able to get the location of a node from the response-object, after creating the node, like so:
nodeLocation = response.getLocation();
But in a transaction, this of course returns the url of the transaction:
http://localhost:7474/db/data/transaction/108
Then I thought, if I query for the just created node, maybe in that response I can find the location. Again, according to documentation, the node location should be presented in the json-structure extensions in the field self.
"self" : "http://localhost:7474/db/data/node/357",
But my response to the query does not seem to contain an extension structure.
This is the query I'm using:
{"statements": [ {"statement": "MATCH (p:POST {sn_id: 'TW', id: '536982477664190465'} ) RETURN p"} ] }
I send it to the open transaction, and I get this back:
GET to http://localhost:7474/db/data/transaction/108 returned status code 200, returned data: {"commit":"http://localhost:7474/db/data/transaction/108/commit","results":[{"columns":["p"],"data":[]}],"transaction":{"expires":"Mon, 24 Nov 2014 20:40:34 +0000"},"errors":[]}
Just for completeness, this is the code for my query:
String payload = "{\"statements\": "
+ "[ "
+ "{\"statement\": "
+ "\"MATCH (p:POST {sn_id: 'TW', id: '536982477664190465'} ) RETURN p\""
+ "} "
+ "] "
+ "}";
logger.trace("sending cypher {} to endpoint {}", payload, endpointLoc);
WebResource resource = Client.create().resource( endpointLoc );
ClientResponse response = resource
.accept( MediaType.APPLICATION_JSON )
.type( MediaType.APPLICATION_JSON )
.entity( payload )
.get(ClientResponse.class);
//.post( ClientResponse.class );
String responseEntity = response.getEntity(String.class).toString();
int responseStatus = response.getStatus();
logger.trace("GET to {} returned status code {}, returned data: {}",
endpointLoc, responseStatus,
responseEntity);
JSONParser reponseParser = new JSONParser();
Object responseObj = reponseParser.parse(responseEntity);
JSONObject jsonResponseObj = responseObj instanceof JSONObject ?(JSONObject) responseObj : null;
if(jsonResponseObj == null)
throw new ParseException(0, "returned json object is null");
String result = (String) jsonResponseObj.get("results").toString();
logger.trace("result is {} ", result);
String error = (String) jsonResponseObj.get("errors").toString();
Am I missing something? Do I need to use a special call?
Can someone help me with this? Thanks in advance,
Christian
What do you need the node-URL for?
That's the old RESTful representation. You can either get it by using the old HTTP endpoint /db/data/cypher or better by specifying the (very verbose) resultDataContents type REST
You can also specify other types like "row" and "graph" in parallel.
{"statements": [
{"statement": "MATCH (p:POST {sn_id: 'TW', id: '536982477664190465'} ) RETURN p",
"resultDataContents":["REST"]}
] }
I am becoming almost mad with the GWT Cookies,
in one of my application I set the cookie in an RPC success, but I am trying to retrieve it in another place of my application, it returns null.
I know that when setting a variable in an rpc sucess,if we try to access it elsewhere it result null, so how can i set a cookie an rpc so that it does not returns null??
Edit:-
I am doing something like this:
I do in Main.java
RPC.getUserDetails(new AsyncCallback <String>())
{
public void onSuccess(String result)
{
Cookies.set("UserDetails",result);
}
}
Now in another file.java, when i do Cookies.get("UserDetails"), I get null
I had the same problem and after setting expiration time I was able to retrieve it:
Date now = new Date();
long week = now.getTime();
week = week + (1000 * 60 * 60 * 24 * 7);
Cookies.setCookie("UserDetails", result, week);
Also make sure that you are setting none secure cookie and are retrieving none secure cookie. Make sure by checking the browser if the cookie file exists. And check the content of the file. If you have problems after this post the content of the cookie file here.
I tried it also this way:
Date expires = new Date(System.currentTimeMillis() + (1000 * 3600 * 24));
String categoriesCookieJson = asJson(allCategories);
System.out.println("inserting cat cookie lenth : " + categoriesCookieJson.toCharArray().length + " : " + categoriesCookieJson);
Cookies.setCookie(VU_ME_CATEGORIES_CACHE, categoriesCookieJson, expires);
String categoriesJsonCookieCache = Cookies.getCookie(VU_ME_CATEGORIES_CACHE);
System.out.println("cookie in chache " + categoriesJsonCookieCache);
it returns null and there's no cookie file entry (looking in ff firebug)
inserting cat cookie lenth : 8303 : {"categories":[{"id":"71","name":"Immoblier","children":[{"id":"76","parentKey":"71","name":"Terrain....
cookie in chache null
Ok!!! so it seams it's related to the size of my cookie content:
inserting cat cookie length : 8303
I will have to split the data