Spring WebClient: Call Rest Service which has paginated response - spring

I want to hit a service which has a paginated response using Web Client. ie. I hit a service, check if it returns hasMoreElements as TRUE, then call the service again with updated request parameters like START_ROW, END_ROW, PAGE_NUMBER. What is the best approach to achieve this? Currently am just looping through the results and hitting the service again. But their should be a better approach to this. PFB my pseudocode. Any libraries I can use?
boolean hasMoreElements=true;
while(!hasMoreElements==false)
{
response=webClient.post().header(HEADERS).bodyValue(REQUEST).block();
Get the NEW START ROW, END ROW, AND PAGE NUMBER and SET in the REQUEST
Get the hasMoreElements value
}

Use JPARepository with paging for this.
You can return a list of objects and check if its length is less then the limit passed, if yes then you can stop fetching.
You could also return a Page or a Slice instead which gives you a little bit more information about the current and next fetch cycle

Related

Is there anyway to hold response until we get full response from server in Jmeter?

The services I'm trying to test, will work on long pooling method.
They won't give results in first response.
When I run my API script I am not getting full response in first time.
How can I wait in this case for the remaining portion of response to be received?
I want to use values from this response into next call..
In the above screen my response should wait when complete:True
As far as I understand your requirement you need to repeat the Gethotels request until complete attribute becomes true.
In order to accomplish this:
Add a JSON Extractor as a child of the Gethotels request and set it up as follows:
Put your Gethotels request under the While Controller and use the following __jexl3() function as the condition:
${__jexl3("${complete}" != "true",)}
That's it, While Controller loop the Gethotels request until complete becomes true

Elasticsearch Java API: Wait until document findable in search results?

I have written a REST API (javax.ws.rs) that uses the high-level Elasticsearch API. This is with ES 7.2.
The client needs to index a record, then execute a search that includes that record and there is some delay after the index operation before the document will actually appear in searches.
Is there any way to block the index operation until the newly index record appears in search results?
Failing that, is there any way to get an asynchronous notification that the document is now searchable?
To give an idea of my use case, here is the code from the client side:
const cr = await this.client.dNodeCreate(fixedNode).toPromise();
const fr = await this.client.dNodeGetById(cr._id).toPromise();
await this.client.dNodeCreate(replyRoot).toPromise();
The first line causes a Index request to ES, and returns the status object. That object includes the ID of the new document.
The second line fetches the record by ID. This always works.
The third line fails. The document it attempts to index is dependent on the first document, which the REST middleware attempts to look up by a search (not by the ID). This is the equivalent of an SQL relation enforced by the REST layer.
I can always make the code work by introducing a delay (say 1500ms) before the third call but this is really a non-robust solution. It might always work in development mode (all the servers are on my laptop and no other users) but there is no way to predict how long the delay needs to be in actual production.
UPDATE: Solved.
The marked answer below seems to do the trick. For reference, the needed call in the Java API looks like this:
IndexRequest req = new IndexRequest(DNode.INDEX);
req.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
The 'refresh' parameter is what you are looking for. From the Elasticsearch documentation:
Refresh (Index API): ) If true, Elasticsearch refreshes the affected shards to make this operation visible to search, if wait_for then wait for a refresh to make this operation visible to search, if false do nothing with refreshes. Valid values: true, false, wait_for. Default: false
So your index request should look something like this:
PUT /<index>/_doc/<_id>?refresh=wait_for
I do not believe there is a built-in way to get an asynchronous notification that the document is now searchable. That being said, if you already have access to the document ID it might make more sense to use that in the code instead of a search.

Why is returning a Springboot ResponseEntitty so slow?

So I am building this springboot REST consumer within an API. The API request is dependend on a different API.
The user can make a Request to my API and my API makes a request to another service to log the user in.
While building this I came to the conclusion that returning a ResponseEntity is much slower than just returning the result in the body of the request.
This my fast code, response time less than a seccond:
#PostMapping("/adminLogin")
fun adminLogin(#RequestBody credentials: Credentials): AuthResponse {
return RestTemplate().getForEntity(
"$authenticatorURL/adminLogin?userName=${credentials.username}&passWord=${credentials.password}",
AuthResponse::class.java).body
}
When doing this it takes lots of seconds to respond:
#PostMapping("/adminLogin")
fun adminLogin(#RequestBody credentials: Credentials): ResponseEntity<AuthResponse> {
return RestTemplate().getForEntity(
"$authenticatorURL/adminLogin?userName=${credentials.username}&passWord=${credentials.password}",
AuthResponse::class.java)
}
Can someone explain to me what the difference is why one approach is faster than the other.
I had the same issue yesterday. The problem was as follows: imagine the API I use is sending a json like this:
{"id": "12"}
what I do is take that into a ResponseEntity, and IdDTO stores the id field as an integer. When I returned this ResponseEntity as a response to my request, it returns this:
{"id": 12}// notice the absence of string quotes around 12
The problem is as follows: the API that I used sends the Content-Length header to be equal to 12, but after my DTO conversion it becomes 10.
Spring does not recalculate the content length and the client is reading the 10 characters you sent, then waiting for other 2. It never receives anything and Spring closes the connection after 1 minute(that is the default timeout for a connection).
If you create a new response entity and put your data into it, Spring will calculate the new content length and it will be as fast as the first case you mentioned.

How to conditional cache results using OSB?

Good morning,
I'm implementing an OSB-Coherence Integration and I would like to cache results only if a condition is returned.
Example:
I have a OSB Business Service interface that return stateCode = 0 in the sucess case, otherwise it will return an error code. I wish to cache only the sucess case.
There are a few tricks you can do to switch the result cache on or off based on the request by inserting custom values of <tp:cache-token> into $outbound/ctx:transport/ctx:request.
However, doing conditional caching based on the result requires a different approach.
What I would do would be to create a cache wrapper proxy.
Let's say your proxy flow is currently
MyProxy-http.proxy -> MyBusinessService-http-cached.biz
You instead insert a bizref to a second proxy, like so:
MyProxy-http.proxy -> MyBusinessService-sb-cached.biz -> MyBusinessService-wrapper-sb.proxy -> MyBusinessService-http.biz
The new bizref has the cache, so you remove results caching from the old bizref.
(So far you haven't changed anything, so the next bit is the step that does the conditional caching)
You modify MyBusinessService-wrapper-sb.proxy to read the $body of the response. If it detects from the response that it shouldn't be cached, you return failure.
This failure will suppress result caching via the bizref.
If it's important to you, you can reconstitute the original message in MyProxy-http.proxy via a fault handler, and return it as an uncached 'success' message.

Invoking a spring action repeatedly without user interaction

I Have a requirement like below :
Get invoked a particular action repeatedly without user interaction.For example, I have a message status page which displayed JMS message status.Message status can be changed by a number of application components.What I wanted is, my status UI has to pick latest message status.I need the action which displays status UI to be called repeatedly in an interval of 5 seconds or so, so that UI will get displayed with latest status.
How can I achieve this in spring.Is it something,Polling an action?
Any help highly appreciated
The easiest thing to do is to ask the server every few seconds using JavaScript and AJAX (pseudo-code using jquery):
function askServerForStatus() {
$.getJSON('/your-app/jms-status', function(response) {
$('#status').text(response.status);
}
}
setInterval(askServerForStatus, 5000); //every 5 seconds
Very simple example, it asks Spring MVC controllers mapped to /jms-status and expects the following JSON response:
{"status": "Processing..."}
Consider using setTimeout().
More general, reliable and robust approach is to use websockets, servlet-3.0 asynchronous support or comet. Also have a look at atmosphere.

Resources