What Spring WebFlux does behind the scene after exit from endpoint method which returns Mono?
Asked Answered
E

1

-1

Let consider following codebase:

@GetMapping("/test")
public Mono<org.springframework.security.oauth2.jwt.Jwt> test {
    Mono<org.springframework.security.oauth2.jwt.Jwt> mono =
            ReactiveSecurityContextHolder.getContext()
                    .map(securityContext ->(org.springframework.security.oauth2.jwt.Jwt) securityContext.getAuthentication().getPrincipal());
    org.springframework.security.oauth2.jwt.Jwt jwtFromMono = firstMono
            .toFuture()
            .get();
    System.out.println("jwt value is " + jwtFromMono);
    return mono ;
}

As a result we see following console output:

jwt value is null

And following http response :

{
  "tokenValue": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlVzJhNVlVRXRoTFBYeTBVUWlXQTZudWtOQ2UtU0x2aU9IVlZ5RnJyVW9FIn0.eyJleHAiOjE2NzM2MzkwOTQsImlhdCI6MTY3MzYzODc5NCwianRpIjoiYTJjZTFmYWUtZWU1NS00MDc4LWE0NDctYzdkNDU3MWRhNWYwIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLTM3My05OWJhYy5kYnAuaW5uby50ZWNoL3JlYWxtcy90ZWNocGxhdCIsInN1YiI6Ijk5ZGZmZDliLWQ5OWEtNGM5Zi1hZWNhLTgxMThlMTYyOTU3MCIsInR5cCI6IkJlYXJlciIsImF6cCI6InBsYXQtZWNtLWNhbGxlci1jbGllbnQiLCJzZXNzaW9uX3N0YXRlIjoiNTQ4YzlhMTctZTdjYi00NzkxLTg5ZWUtMWU3OTU3ODQ2YWI3Iiwic2NvcGUiOiIiLCJzaWQiOiI1NDhjOWExNy1lN2NiLTQ3OTEtODllZS0xZTc5NTc4NDZhYjciLCJyb2xlcyI6WyJFQ01fVVNFUiJdfQ.Nfm-kqOp57bIuou8Qu0Gd4p06eUnbcKwEhxMGWGGqQN1Xh_czT2pNhqDQClsFVeyloIZeuKLCXvCJcK0-BrLqKwIWeQWX8lmmDEgdjwvPm9Uaypq2K1ur8OyzYTAocXRkL6_tcyP64th2m6xL5pVGeoqavdcDBR2e15_P8gHZaAzi8M6ke5V_uTNA6DNJrLAwMmHHjieWimBdFtxb5QFDtmfHWgyChYRQIvJVO74EKdXLv_XT_9hjByG2uQ5x4tEEtqZeWALlAMMzvcgHcA8llg5rHtvyGUl9Yv4d2oLoyHy22zvMO3BfxjpA4W19ps6vLHFLoUK9alcStuZlwSvPA",
  "issuedAt": "2023-01-13T19:39:54Z",
  "expiresAt": "2023-01-13T19:44:54Z"
  ...

Result is very representative:

  1. When we call .toFuture().get() manually we receive null

  2. When we return Mono from endpoint method - the result contains data from security context (Jwt token which is not null)

So Spring does some work behind the scene. What is the work ? Is there way to call it manually from my endpoint method ?

Emigrate answered 15/1, 2023 at 9:38 Comment(0)
A
0

I'd recommend making the logging statement a part of your publisher, such that it logs when the mono is subscribed to, rather than attempting to invoke the publisher early. That is:

 @GetMapping("/test")
 public Mono<org.springframework.security.oauth2.jwt.Jwt> test() {
            return ReactiveSecurityContextHolder.getContext()
                    .map(securityContext -> (org.springframework.security.oauth2.jwt.Jwt) securityContext.getAuthentication().getPrincipal())
                    .doOnNext(jwt -> System.out.println("jwt value is " + jwt));
}

I can't actually answer what happens behind the scenes when the response is returned, but at some point after the return statement, the mono will be subscribed to. The steps in the reactive pipeline will usually only be evaluated once the mono is subscribed to, which could explain the null value in your logging statement.

Afton answered 24/1, 2023 at 12:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.