Using reactor context to get back results from downstram chain

443 views Asked by At

I got this bean:

@Bean("reactiveNeo4jDatabaseNameProvider")
public ReactiveDatabaseSelectionProvider reactiveDatabaseSelectionProvider() {

    log.info("Database selection step");

    return () -> getRealmFromContext()
            .flatMap(realmId -> {
                Flux<String> stringFlux = translateRealmToDbName(realmId);
                Mono<DatabaseSelection> next = stringFlux.map(DatabaseSelection::byName).next();
                        return next;
                    }
            )
            .switchIfEmpty(Mono.just(DatabaseSelection.undecided()));
}

whose task is selecting the database name at runtime reading some data enclosed in the Reactor context, filled by the webfilter filter function:

public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {

    ....


    return webFilterChain.filter(serverWebExchange)
            .subscriberContext(e -> e.put("realmId", "some string"));

Everything works as expected: I'm able to read from the context in the db selector bean but I need to communicate the choice back to the webfilter which should add a specific header in the final response. I was thinking something like this

serverWebExchange.getResponse().beforeCommit(() -> {
    Mono.subscriberContext().doOnNext(ctx, {
       // fetch the selected db value here and add the header
    });
});

Problem is, how can I add something new in the context and get it picked up by the function above?

EDIT: getRealmFromContext() function subscribes to the context and map it to get the realm value.

Best,

FB

1

There are 1 answers

0
FrankBr On

Well, after digging, I did not work it out as I expected to want; I just turned around the problem

Mono.zip(Mono.just(serverWebExchange.getResponse()), selectionDbService.translateRealmToDbName(realmId))
        .subscribe(objects -> objects.getT1().beforeCommit(() -> {
            serverWebExchange.getResponse().getHeaders().add(COMPANY_HEADER_NAME_RESPONSE, objects.getT2());
            return Mono.empty();
        }) );

To avoid calling the service twice, I used a caching system.