Java application that monitors the file change on the server - java

I need to write a small program, that constantly checks if the JSON file on the server has been updated (by some other process) to report the change to the user of the program.
I'm interested in best/correct practice of doing it: how would I implement the idea of "listening" to the file-change?
So far, my idea is:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(getMessage, 0,1, TimeUnit.SECONDS);
where getMessage is the:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("url/get_message"))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
message = response.body();

Related

Java Spring boot - Rest Template (request with no response, no error)

I'm trying to create a GET request to retrieve commercial flights from latam. But I only get the answer through insomnia/postman...
I'm making the request through RestTemplate in Java, as shown below:
public class LatamRequest {
public void consumerAPILatam(){
RestTemplate template = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
//h.ttps://www.latamairlines.com/bff/air-offers/offers/search
UriComponents uri = UriComponentsBuilder.newInstance()
.scheme("https")
.host("www.latamairlines.com")
.path("bff/air-offers/offers/search")
.queryParam("sort","RECOMMENDED")
.queryParam("cabinType","Economy")
.queryParam("origin","GRU")
.queryParam("destination","BSB")
.queryParam("inFlightDate","null")
.queryParam("inFrom","null")
.queryParam("inOfferId","null")
.queryParam("outFlightDate","null")
.queryParam("outFrom","2022-11-15T15%3A00%3A00.000Z")
.queryParam("outOfferId","null")
.queryParam("adult","1")
.queryParam("child","0")
.queryParam("infant","0")
.queryParam("redemption","true")
.build();
headers.set("User-Agent", "test");
headers.set("Accept", "*/*");
headers.set("Content-Type", "application/json");
headers.set("X-latam-App-Session-Id", "84196897-1687-4d8c-8e63-083091ac204f");
headers.set("X-latam-Action-Name", "search-result.flightselection.offers-search");
headers.set("X-latam-Application-Name", "web-air-offers");
headers.set("X-latam-Client-Name", "web-air-offers");
headers.set("X-latam-Track-Id", "3a4ae189-e218-4606-bd9e-8b17efc93463");
headers.set("X-latam-Request-Id", "ff44ef24-e6d0-4cb0-984c-df1db18cee19");
headers.set("X-latam-Application-Country", "BR");
headers.set("X-latam-Application-Oc", "br");
headers.set("X-latam-Application-Lang", "pt");
HttpEntity<String> httpEntity = new HttpEntity<>(headers);
ResponseEntity<String> response = template.exchange(uri.toUriString(), HttpMethod.GET, httpEntity, String.class); //todo: No response, no error...
System.out.println(response);
}
}
I don't get any response or status after executing the above block. OBS: With the same parameters and headers I get status 200 in postman or insomnia.
I've tried several ways, but I can't get a response. Does anyone have any ideas for a more effective debug?
The reason that you don't get any response and no exception is because the server side gets your request and keeps holding it and doesn't respond. So you are still in a waiting mode. I ran your request from java code using different http client but used exact your params and I noticed that response never returns. I waited for over 10 minutes and I saw that the program was still running. So I modified the code and added connection timeout for 5 sec and read timeout for 30 seconds. When I ran it it I got read timeout exception after 30 seconds. So the code manages to connect to server side, but server side just doesn't respond. So you are in endless wait. So, I don't know why it works from postman. May be some headers values issues.

java 11 HttpClient async send throttle for every 100 requests

i'm trying to use the Asynchronous API of the java 11 HttpClient library to GET data from my server. But to be in line with the best practices, I want the client to throttle the request to the server to be a max of 100 requests every minute. How should this be accomplished in java 11 HttpClient library?
In python, there is the aiohttp library that allows you to specify the parameters for throttling the request.
Is there such a thing for java 11 HttpClient library as well?
HttpClient client = HttpClient.newBuilder()
.version(Version.HTTP_2)
.followRedirects(Redirect.SAME_PROTOCOL)
.proxy(ProxySelector.of(new InetSocketAddress("www-proxy.com", 8080)))
.authenticator(Authenticator.getDefault())
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://openjdk.java.net/"))
.timeout(Duration.ofMinutes(1))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofFile(Paths.get("file.json")))
.build()
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(response -> { System.out.println(response.statusCode());
return response; } )
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
link: https://openjdk.org/groups/net/httpclient/intro.html

HttpTimeout gracefully close connection

I am using java Apache HttpClient to request a resource (B) with a timeout of 10s. If timeout exceeds Broken pipe is seen at the other application server.
Because of which Nginx at application B is not caching the response. How to gracefully close the connection so that the other app server (B) does not encounter broken pipe exception.
If you're using new enough HttpClient can't you do something like this (I just found a snippet someone else had written ... but see below where I've added ###)
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8081/test/resource"))
.header("Accept", "application/json")
.POST(HttpRequest.BodyPublishers.ofString("ping!"))
.build();
CompletableFuture<HttpResponse<String>> completableFuture =
client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
completableFuture
.completeOnTimeout(DEFAULT_RESPONSE, 1, TimeUnit.SECONDS) // ### ADD THIS the HttpClientRequest actually continues but the future has timed out so the user of the client progresses ??
.thenApplyAsync(HttpResponse::headers)
.thenAcceptAsync(System.out::println);
HttpResponse<String> response = completableFuture.join();

Add Proxy to HttpRequest in java

I'm trying to understand how can I implement the use of a proxy for each request built like the following using Java API:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.version(HttpClient.Version.HTTP_2)
.uri(URI.createh("https://myurl"))
.timeout(Duration.ofMinutes(2))
.setHeader("User-Agent","Just an user agent")
.GET()
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
I'm seeing from the doc (https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html#Asynchronous%20Example)
that is possible with Synchronous requests. My code is within a method and it will run with threads parallelly. So how is it possible to set a proxy with Asynchronous Requests? If it is not possible, what's the difference between them?
Solved, it's a bit unclear the doc about that but at the end, I was able to set the proxy when building the client:
HttpClient client = HttpClient.newBuilder().
proxy(ProxySelector.of(new InetSocketAddress("proxy",port))))
.build();
//The request code is identical to what I wrote above.
The method is newBuilder anyway and not Builder.

Okhttp big file upload fails

I am experiencing an issue with Okhttp + Node.js Formidable serverside big file upload.
Currently the upload works for < 100Mb files but fails for bigger files.
For bigger files, the onprogress event serverside is fired until 99% progress, regardless of the file size, then it stops, reports request abort, and the onfile event is not fired.
Already tried timeouts workarounds, even defined a custom SocketFactory to manually set the socket keepalive and sotimeout.
So, Im stuck here. Any help would be appreciated.
CustomSocketFactory MySocketFactory = new CustomSocketFactory();
OkHttpClient client = new OkHttpClient.Builder()
.socketFactory(MySocketFactory)
.readTimeout(largenumber, TimeUnit.SECONDS)
.writeTimeout(largenumber, TimeUnit.SECONDS)
.connectTimeout(largenumber, TimeUnit.SECONDS)
.build();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("nombre_file", file_pais.getName())
.addFormDataPart("nombre_pais", pais.getName())
.addFormDataPart("file", file_pais.getName(),
RequestBody.create(MediaType.parse("application/octet-stream"),
new File(filepath)
.build();
Request request = new Request.Builder()
.url(server_url)
.post(requestBody)
.build();
Call call = client.newCall(request);
Response response = call.execute();
response.body().close();
Its way too easy using snoopy api: one line of code if you exclude identifiers definition :)
URI uri = ...;
Path fileToUpload = ...;
Snoopy.builder()
.config(SnoopyConfig.defaults())
.build()
.post(uri)
.followRedirects(true)
.failIfNotSuccessfulResponse(true)
.body(fileToUpload)
.consumeAsString();
https://bitbucket.org/abuwandi/snoopy
Tested on large files and it worked like a charm

Categories

Resources