How to send data piece by piece using Flux? - spring-webflux

I play with baeldung tutorial from github.
I wanted to see how a browser retrieves data piece by piece. So I added my simple controller method:
#GetMapping("/flux")
public Flux<Employee> getFlux() {
return Flux.fromIterable(employeeRepository.employeeData.values())
.delayElements(Duration.ofMillis(2_000))
.take(3);
}
But when I look at the browser network the data is retrieved in one chunk after 6 second delay.
How to do this correctly?

This is happening because you didn't mention Media type for the response.
Try this code.
#GetMapping(value = "/test",produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public Flux getMapping() {
return Flux.interval(Duration.ofMillis(300)).map(f -> "HI");
}
Thanks,
Vimalesh

Related

How to make a MultiMock Http Callout Test for Salesforce?

If I have an Apex function that is named authorize() that just gets a username, password, and session token, and another function called getURL('id#', 'key'), that takes an id# for the record as a string and a key for the image to return as a string as parameters. getURL calls the authorize function inside it in order to get the credentials for its callout. The authorize is a post request, and the getURL is a get request.
I am trying to figure out how to test both of these callouts just so I can make sure that getURL is returning the proper JSON as a response. It doesn't even have to be the URL yet which is its intention eventually. But I just need to test it to make sure these callouts are working and that I am getting a response back for the 75% code coverage that it needs.
I made a multiRequestMock class that looks like this:
public class MultiRequestMock implements HttpCalloutMock {
Map<String, HttpCalloutMock> requests;
public MultiRequestMock(Map<String, HttpCalloutMock> requests) {
this.requests = requests;
}
public HTTPResponse respond(HTTPRequest req) {
HttpCalloutMock mock = requests.get(req.getEndpoint());
if (mock != null) {
return mock.respond(req);
} else {
throw new MyCustomException('HTTP callout not supported for test methods');
}
}
public void addRequestMock(String url, HttpCalloutMock mock) {
requests.put(url, mock);
}
}
I then began to write a calloutTest.cls file but wasn't sure how to use this mock class in order to test my original functions. Any clarity or assistance on this would be helpful Thank you.
I believe in your calloutTest class you use Test.setMock(HttpCalloutMock.class, new MultiRequestMock(mapOfRequests)); then call the getUrl and/or authorize methods and instead of the request really executing the response returned will be that which is specified in the response(HttpRequest) method you have implemented in the MultiRequestMock class. That is basically how I see it working, for more info and an example you can see this resource on testing callout classes. This will get you the code coverage you need but unfortunately cannot check you are getting the correct JSON response. For this, you may be able to use the dev console and Execute Anonymous?
You may want to look at simplifying your HttpCalloutMock Implementation and think about removing the map from the constructor as this class really only needs to return a simple response then your calloutTest class can be where you make sure the returned response is correct.
Hope this helps

Spring webflux : consume mono or flux from request

I have a resource API that handles an object (Product for example).
I use PUT to update this object in the database.
And I want to return just en empty Mono to the user.
There is my code :
public Mono<ServerResponse> updateProduct(ServerRequest request){
Mono<Product> productReceived = request.bodyToMono(Product.class);
Mono<Product> result = productReceived.flatMap(item -> {
doSomeThing(item);
System.out.println("Called or not called!!");
return Mono.just(productService.product);
}).subscribe();
return ok()
.contentType(APPLICATION_JSON)
.body(Mono.empty(), Product.class);
}
The problem is my method doSomeThing() and the println are not called.
NB: I use subscribe but doesn't work.
Thanks.
I had a similar issue when I was new to Webflux. In short, you can't call subscribe on the request body and asynchronously return a response because the subscription might not have enough time to read the body. You can see a full explanation of a similar issue here.
To make your code work, you should couple the response with your logic stream. It should be something like the following:
public Mono<ServerResponse> updateProduct(ServerRequest request){
return request
.bodyToMono(Product.class)
.flatMap(item -> {
doSomeThing(item);
System.out.println("Called or not called!!");
return Mono.just(productService.product);
})
.then(ServerResponse.ok().build());
}

Populate AtlasConversationsRecyclerView with custom HTTP response

I am working on an Android app, using Layer Atlas for the conversations section. Right now I am trying to populate the conversations list (AtlasConversationsRecyclerView) with my own query:
private AtlasConversationsRecyclerView mConversationsList;
.
.
.
HTTPRequestManager.fetchConversations(
new HTTPRequestManager.VolleyCallback() {
#Override
public void onSuccess(String response) {
JSONArray jsonArray = Base.toJSONResponse(response);
JSONArray sortedJsonArray = Base.sortJSONArray(jsonArray, Base.CREATE_TIMESTAMP);
// mConversationsAdapter.setData(sortedJsonArray);
}
}, Base.mChannelId);
What I normally do to populate an ordinary RecyclerView is write an adapter for it, specifically a setData() method that solves the query-view integration (mConversationsAdapter.setData(..)). This time, I have the query response, but I don't understand how to use it to populate the AtlasConversationsRecyclerView, which has its own adapter.
The code that comes next:
// Atlas methods
mConversationsList.init(getLayerClient(), getPicasso())
.setInitialHistoricMessagesToFetch(20)
.setOnConversationClickListener(new AtlasConversationsAdapter.OnConversationClickListener() {...}
This is what I found on the reference files, but I am missing the query-adapter integration part.
Could you please give me some advice?
Thank you,
Michelle

Mapping response objects(C#)

I am consuming an API mehod and it returns response as of type Product and below is the response class structure.
Public class Product
{
public int Id;
public string Name;
public IList<Product> MasterProduct { get; set; }
}
The API result include the product attributes along with IList. Since this API cannot be consumed directly though our windows client we have a wrapper web API which consume this API, for this in the local API we have defined similar Product class. The issue I am facing is when trying to map the attibues of external API with local. Below is what I am trying to do.
response = Response.Result.Select(x => new Product
{
Id=x.Id,
Name=x.Name
MasterProduct = x.MasterProduct.Cast<MasterProduct>().ToList()//tried below
}).ToList();
but it fails with error as - Unable to cast object of type 'Api.Models.Product' to type 'App.DataContracts.Product'
The Masterproduct consist of hierarchal data .I am wondering if the approach I am taking is right or it has to be done through some method. Any suggestion or help would be appreciated.
Upon searching the web I came across some code where serpare method is being called to parse using Microsoft.Its.Data, but this was for single object where as in my case I have a List(Hierarchical).
Appreciate if someone can point to some linke/sampel to achive the same.
Trying serialization/deserialization would do. Below is the code
Perhaps trying serialization/deserialization would do.
if (response.Result != null)
{
var serializedResponse = JsonConvert.SerializeObject(Response.Result, Formatting.Indented);
response = JsonConvert.DeserializeObject<List<Product>>(serializedResponse);
}).ToList();
return response;

Captcha in oracle adf project

I'm trying to use captcha as it's shown in this example:
http://www.oracle.com/technetwork/developer-tools/jdev/captcha-099103.html
And it works fine in .jspx page or in .jsff page fragment, but I have to place captcha onto the first page of taskflow, and there... it's not updated! /* I mean the button "can't read image" doesn't work */ I have no idea why. Can anybody help?
Actually, I figured out how to do it by myself:
we need captcha image binding in our bean and the resetting method:
private RichImage captchaImage;
public void setCaptchaImage(RichImage captchaImage) {
this.captchaImage = captchaImage;
}
public RichImage getCaptchaImage() {
return captchaImage;
}
public void resetCaptcha(ActionEvent actionEvent) {
captchaImage.setSource("/captchaservlet?rand=" +
String.valueOf(Math.random()));
AdfFacesContext.getCurrentInstance().addPartialTarget(captchaImage.getParent());
}
All, I didn't know how to do was adding parameter to "/captchaservlet"
And now it works fine :)
But the next problem appears: when returning to this page with captcha from the second one in task flow I need to refresh captcha image. Is there any method that is executed on page return or something?
Aaaaaaaaaaaand I found even more elegant solution: one should just set the source of the captcha image to this method using the expression builder:
public String getCaptchaSource() {
return "/captchaservlet?rand=" + String.valueOf(Math.random());
}
The button "Refresh", of course, should be set as a partial trigger for the image, as in the example.
And that's it :)