Created
November 19, 2021 02:55
-
-
Save Toparvion/90ebbdef9d31185a785670d9c2a86762 to your computer and use it in GitHub Desktop.
A simple WebFilter (from Spring WebFlux framework) for correct handling of 'rid' URL query parameter as a similarly-named MDC entry (even in threads spawned by Reactor's Schedulers)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pro.toparvion.sample.gateway.gatewaydemo; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.slf4j.MDC; | |
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; | |
import org.springframework.stereotype.Component; | |
import org.springframework.web.server.ServerWebExchange; | |
import org.springframework.web.server.WebFilter; | |
import org.springframework.web.server.WebFilterChain; | |
import reactor.core.publisher.Mono; | |
import reactor.core.scheduler.Schedulers; | |
import javax.annotation.PostConstruct; | |
import javax.annotation.PreDestroy; | |
import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.REACTIVE; | |
@Component | |
@ConditionalOnWebApplication(type = REACTIVE) | |
public class ReactiveMdcFilter implements WebFilter { | |
private static final Logger log = LoggerFactory.getLogger(ReactiveMdcFilter.class); | |
private static final String RID = "rid"; | |
@Override | |
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { | |
String rid = exchange.getRequest().getQueryParams().getFirst(RID); | |
return chain.filter(exchange) | |
.doOnSubscribe(subscription -> { | |
MDC.put(RID, rid); | |
log.trace("rid={} has been set in filter", rid); | |
}) | |
.doFinally(whatever -> { | |
MDC.remove(RID); | |
log.trace("rid={} has been removed in filter", rid); | |
}); | |
} | |
@PostConstruct | |
void setupReactorThreadsDecorator() { | |
Schedulers.onScheduleHook("mdc", runnable -> { | |
String rid = MDC.get(RID); | |
return () -> { | |
MDC.put(RID, rid); | |
log.trace("'rid' mark has been assigned to the thread"); | |
try { | |
runnable.run(); | |
} finally { | |
MDC.remove(RID); | |
log.trace("'rid' mark removed from the thread"); | |
} | |
}; | |
}); | |
log.info("Reactive MDC hook has been set"); | |
} | |
@PreDestroy | |
void shutdownThreadsDecorator() { | |
Schedulers.resetOnScheduleHook("mdc"); | |
log.info("Reactive MDC hook has been removed"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment