Invoke Lambda asynchronously form lambda in JAVA - java

Hi I am trying to call a lambda, from one lambda.
so my code snippet is like:
public String passPayloadThenReturn (){
....
....
AWSLambdaAsync asynclambda = AWSLambdaAsyncClientBuilder.defaultClient();
Payload payloadData = new Payload();
payloadData.setSupplierId(*<someId>*);
payloadData.setTransactionId(*<someOtherId>*);
payloadData.setS3(*<someS3Pic>*);
InvokeRequest lambdaCallRequest = new InvokeRequest();
lambdaCallRequest.setInvocationType("Event");
- lambdaCallRequest.withFunctionName("LambdaToCall")
.withPayload(payloadData.toString());
Future<InvokeResult> future_res = asynclambda.invokeAsync(lambdaCallRequest);
return "<some_uri >"
}
So when the code is executed I can not find the log for LambdaToCall in cloudWatch.
Not able to know whether the lambda is executed or not. If I test the lambda(LambdaToCall) it works, but not able to invoke from other lambda.
What did I do wrong?
How can I know whether the LambdaToCall is called with the payload?
Please help !!!!

Related

Java how to Uni.createFrom().future() and return that Uni from the enclosing method?

I am very new to Java and Mutiny.
As indicated below, my test function asks Redis for the value of key "foo" which is "bar". That is working and the Future onCompleted() gets "bar".
So far so good.
I have two issues with the Uni.createFrom().future() bit.
The compiler says: The method future(Future<? extends T>) in the type UniCreate is not applicable for the arguments (Future<Response>). I have tried the suggested fixes but ended up in a deeper hole. My Java skills are insufficient to fully grasp the meaning of the error.
How do I get "bar" into the Uni<String> returned from test()? I have tried all sorts of subscribing and CompletableFutures and cannot make anything work. I figure I need to return a function to generate the Uni but am at a loss about how to do that.
// The abbreviated setup
import io.vertx.redis.client.Redis;
private final Redis redisClient;
this.redisClient = Redis.createClient(vertx);
public Uni<String> test () {
// Ask Redis for the value of key "foo" => "bar"
Future<Response> futureResponse = this.redisClient.send(Request.cmd(Command.create("JSON.GET")).arg("foo"))
.compose(response -> {
// response == 'bar'
return Future.succeededFuture(response);
}).onComplete(res -> {
// res == 'bar'
});
// How to make the return of the Uni<String> wait for the completed futureResponse
// so it makes a Uni<String> from "bar" and returns it from the method?
Uni<String> respUni = Uni.createFrom().future(futureResponse);
return respUni;
}
Thanks. Any suggestions gratefully accepted! (And yes, I have spent many hours trying to work it out for myself) ;-)
Updated the post, because of errors.
UniCreate.future() takes a java.util.concurrent.Future of some type and returns Uni of the same type. That is, you'll have to pass a java.util.concurrent.Future<String> to get a Uni<String>.
The send method of the Redis client returns a io.vertx.core.Future<Response> which is not assignment compatible to java.util.concurrent.Future.
Fortunately, the API provides io.vertx.core.Future#toCompletionStage to convert a vertx Future to a JDK CompletionStage while Mutiny provides UniCreate.completionStage() to get the job done.
public Uni<String> test () {
Future<String> futureResponse = this.redisClient.send(Request.cmd(Command.create("JSON.GET")).arg("foo"))
.compose(response -> {
return Future.succeededFuture(response.toString());
});
Uni<String> respUni = Uni.createFrom().completionStage(futureResponse.toCompletionStage());
return respUni;
}

Is it possible to add an assertion message when using MockMvc?

Most of the times instead of adding comments in an ordinary JUnit assertion, we add a message to the assertion, to explain why this is assertion is where it is:
Person p1 = new Person("Bob");
Person p2 = new Person("Bob");
assertEquals(p1, p2, "Persons with the same name should be equal.");
Now, when it comes to end point testing in a Spring Boot web environment I end up with this:
// Bad request because body not posted
mockMvc.perform(post("/postregistration")).andExpect(status().isBadRequest());
// Body posted, it should return OK
mockMvc.perform(post("/postregistration").content(toJson(registrationDto))
.andExpect(status().isOk()));
Is there a way to get rid of the comments and add a message to this kind of assertion? So, when the test fails I will see the message.
You can provide a custom ResultMatcher:
mockMvc.perform(post("/postregistration")
.content(toJson(registrationDto))
.andExpect(result -> assertEquals("Body posted, it should return OK", HttpStatus.OK.value() , result.getResponse().getStatus())))
mockMvc.perform(post("/postregistration"))
.andExpect(result -> assertEquals("Bad request because body not posted", HttpStatus.BAD_REQUEST.value(), result.getResponse().getStatus()));
Explaination:
As of today the method .andExpect() accepts only one ResultMatcher. When you use .andExpect(status().isOk()) the class StatusResultMatchers will create a ResultMatcher in this way:
public class StatusResultMatchers {
//...
public ResultMatcher isOk() {
return matcher(HttpStatus.OK);
}
//...
private ResultMatcher matcher(HttpStatus status) {
return result -> assertEquals("Status", status.value(), result.getResponse().getStatus());
}
}
As you can see the message is hard-coded to "Status" and there is no other built in method to configure it. So even though providing a custom ResultMatcher is a bit verbose, at the moment might be the only feasible way using mockMvc.
I figured out that assertDoesNotThrow responds hence improves the situation (according to what I ask):
assertDoesNotThrow(() -> {
mockMvc.perform(post("/postregistration")).andExpect(status().isBadRequest());
}, "Bad Request expected since body not posted.");

Kotlin - Is it possible to return a variable from a higher order function?

I have a Kotlin function from a separate library that takes a function as a parameter and gets the variable I need from the callback:
object Session {
fun get(callback: (accessToken: String?) -> Unit): Boolean {
SomeOtherClass(callback).get()
return true
}
}
Then to call it from another class I make the call (in java):
public String getToken() {
Session.INSTANCE.get((accessToken) -> {
// I want the method getToken() to be able to 'return accessToken;'
// but this call back returns Unit and the get method itself returns Boolean
});
}
Is there a way to return the variable accessToken from getToken() directly, or at least the equivalent value? Session.get is async so creating a "global" variable returns null because the value hasn't been assigned yet. This is one thing I have tried:
public String getToken() {
String temp;
Session.INSTANCE.get((accessToken) -> {
temp = accessToken;
});
return temp;
}
Relatively new to functional programming so any help is appreciated!
If the call to get the access token is async then you can't just grab right away. This is because the code inside the get call is running on another thread while your code keeps going. It would look like this:
public String getToken() {
String temp; // 1. you make a variable
Session.INSTANCE.get((accessToken) -> { // 2. get call starts processing
temp = accessToken;
});
return temp; // 3. now you return your uninitialized variable
}
and then after your function ends the token callback happens, but its to late, you already returned nothing. If you run it in a debugger with a break point on each line and keep running you will see the order that the code is executed and it may make more sense.
Your best bet is to just handle what you need in the callback rather than returning it in getToken()...
Not sure if you wanted an answer in kotlin or java but your code may look something like this in kotlin:
Session.get { token ->
onToken(token)
}
where onToken handles whatever code you needed the token for
fun onToken(token: String) {
// do whatever code you would've executed after getToken() here
}
Hope I explained that alright.
You can't return a callback's eventual result from the method that calls it without blocking the thread that made the call. The reason callbacks exist is so you won't block the thread that's making the call. On Android, your app will crash with an Application Not Responding message if you block the main thread for a few seconds.
If you use Kotlin, you can wrap library callbacks using suspendCancellableCoroutine to make them coroutine-compatible. Coroutine suspend functions do allow you to return delayed results.

How to get String from Mono<String> in reactive java

I have a method which accepts Mono as a param.
All I want is to get the actual String from it. Googled but didn't find answer except calling block() over Mono object but it will make a blocking call so want to avoid using block(). Please suggest other way if possible.
The reason why I need this String is because inside this method I need to call another method say print() with the actual String value.
I understand this is easy but I am new to reactive programming.
Code:
public String getValue(Mono<String> monoString) {
// How to get actual String from param monoString
// and call print(String) method
}
public void print(String str) {
System.out.println(str);
}
Getting a String from a Mono<String> without a blocking call isn't easy, it's impossible. By definition. If the String isn't available yet (which Mono<String> allows), you can't get it except by waiting until it comes in and that's exactly what blocking is.
Instead of "getting a String" you subscribe to the Mono and the Subscriber you pass will get the String when it becomes available (maybe immediately). E.g.
myMono.subscribe(
value -> System.out.println(value),
error -> error.printStackTrace(),
() -> System.out.println("completed without a value")
)
will print the value or error produced by myMono (type of value is String, type of error is Throwable). At https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html you can see other variants of subscribe too.
According to the doc you can do:
String getValue(Mono<String> mono) {
return mono.block();
}
be aware of the blocking call
Finally what worked for me is calling flatMap method like below:
public void getValue(Mono<String> monoString)
{
monoString.flatMap(this::print);
}
What worked for me was the following:
monoString.subscribe(this::print);
Simplest answer is:
String returnVal = mono.block();
This should work
String str = monoString.toProcessor().block();
Better
monoUser.map(User::getId)

SIngle RxJava how to extract object

I can think of two ways to get the value from Single
Single<HotelResult> observableHotelResult =
apiObservables.getHotelInfoObservable(requestBody);
final HotelResult[] hotelResults = new HotelResult[1];
singleHotelResult
.subscribe(hotelResult -> {
hotelResults[0] = hotelResult;
});
Or
final HotelResult hotelResult = singleHotelResult
.toBlocking()
.value();
It's written in the documentation that we should avoid using .toBlocking method.
So is there any better way to get value
Even it is not recommended to block it (you should subscribe), in RxJava v2 the method for blocking is blockingGet(), it returns the object immediately.
When we use toBlocking then we get result immediately. When we use subscribe then result is obtained asynchronously.
Single<HotelResult> observableHotelResult =
apiObservables.getHotelInfoObservable(requestBody);
final HotelResult[] hotelResults = new HotelResult[1];
singleHotelResult.subscribe(hotelResult -> {
hotelResults[0] = hotelResult;
});
// hotelResults[0] may be not initialized here yet
// println not show result yet (if operation for getting hotel info is long)
System.out.println(hotelResults[0]);
For blocking case:
final HotelResult hotelResult = singleHotelResult.toBlocking().value();
// hotelResult has value here but program workflow will stuck here until API is being called.
toBlocking helps in the cases when you are using Observables in "normal" code where you need to have the result in place.
subscribe helps you for example in Android application when you can set some actions in subscribe like show result on the page, make button disabled etc.

Categories