@SuppressWarnings("unchecked") private static <T> Supplier<Mono<T>> skipBodyAsMono(ReactiveHttpInputMessage message) { return message instanceof ClientHttpResponse ? () -> consumeAndCancel(message).then(Mono.empty()) : Mono::empty; }
@Override public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) { WebHandler webHandler = (WebHandler) handler; Mono<Void> mono = webHandler.handle(exchange); return mono.then(Mono.empty()); }
/** * Prepare the model to use for rendering. * <p>The default implementation creates a combined output Map that includes * model as well as static attributes with the former taking precedence. */ protected Mono<Map<String, Object>> getModelAttributes(@Nullable Map<String, ?> model, ServerWebExchange exchange) { int size = (model != null ? model.size() : 0); Map<String, Object> attributes = new LinkedHashMap<>(size); if (model != null) { attributes.putAll(model); } return resolveAsyncAttributes(attributes).then(Mono.just(attributes)); }
@Override public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) { WebSocketHandler webSocketHandler = (WebSocketHandler) handler; return getWebSocketService().handleRequest(exchange, webSocketHandler).then(Mono.empty()); }
@Override public Mono<ServerResponse> build(Publisher<Void> voidPublisher) { Assert.notNull(voidPublisher, "Publisher must not be null"); return build((exchange, handlerStrategies) -> Mono.from(voidPublisher).then(exchange.getResponse().setComplete())); }
@PostMapping("/mono") public Mono<Void> createWithMono(@RequestBody Mono<Person> mono) { return mono.doOnNext(persons::add).then(); }
@ModelAttribute public Mono<Void> voidMonoMethodBean(Model model) { return Mono.just("Void Mono Method Bean") .doOnNext(name -> model.addAttribute("voidMonoMethodBean", new TestBean(name))) .then(); }
/** * Bind query params, form data, and or multipart form data to the binder target. * @param exchange the current exchange. * @return a {@code Mono<Void>} when binding is complete */ public Mono<Void> bind(ServerWebExchange exchange) { return getValuesToBind(exchange) .doOnNext(values -> doBind(new MutablePropertyValues(values))) .then(); }
@Override public ListenableFuture<Void> connect(final TcpConnectionHandler<P> handler) { Assert.notNull(handler, "TcpConnectionHandler is required"); if (this.stopping) { return handleShuttingDownConnectFailure(handler); } Mono<Void> connectMono = this.tcpClient .handle(new ReactorNettyHandler(handler)) .connect() .doOnError(handler::afterConnectFailure) .then(); return new MonoToListenableFutureAdapter<>(connectMono); }
private Mono<Void> executeInternal(URI url, HttpHeaders headers, WebSocketHandler handler) { MonoProcessor<Void> completionMono = MonoProcessor.create(); return Mono.fromCallable( () -> { if (logger.isDebugEnabled()) { logger.debug("Connecting to " + url); } Object jettyHandler = createHandler(url, handler, completionMono); ClientUpgradeRequest request = new ClientUpgradeRequest(); request.setSubProtocols(handler.getSubProtocols()); UpgradeListener upgradeListener = new DefaultUpgradeListener(headers); return this.jettyClient.connect(jettyHandler, url, request, upgradeListener); }) .then(completionMono); }
private Mono<Void> executeInternal(URI url, HttpHeaders requestHeaders, WebSocketHandler handler) { MonoProcessor<Void> completionMono = MonoProcessor.create(); return Mono.fromCallable( () -> { if (logger.isDebugEnabled()) { logger.debug("Connecting to " + url); } List<String> protocols = handler.getSubProtocols(); DefaultConfigurator configurator = new DefaultConfigurator(requestHeaders); Endpoint endpoint = createEndpoint(url, handler, completionMono, configurator); ClientEndpointConfig config = createEndpointConfig(configurator, protocols); return this.webSocketContainer.connectToServer(endpoint, config, url); }) .subscribeOn(Schedulers.elastic()) // connectToServer is blocking .then(completionMono); }
@Test public void onStatusWithMonoErrorAndBodyConsumed() { RuntimeException ex = new RuntimeException("response error"); testOnStatus(ex, response -> response.bodyToMono(Void.class).then(Mono.error(ex))); }
/** * Apply {@link Flux#reduce(Object, BiFunction) reduce} on the body, count * the number of bytes produced, release data buffers without writing, and * set the {@literal Content-Length} header. */ @Override public final Mono<Void> writeWith(Publisher<? extends DataBuffer> body) { return Flux.from(body) .reduce(0, (current, buffer) -> { int next = current + buffer.readableByteCount(); DataBufferUtils.release(buffer); return next; }) .doOnNext(count -> getHeaders().setContentLength(count)) .then(); }
@Override public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) { HandlerMethod handlerMethod = (HandlerMethod) handler; Assert.state(this.methodResolver != null && this.modelInitializer != null, "Not initialized"); InitBinderBindingContext bindingContext = new InitBinderBindingContext( getWebBindingInitializer(), this.methodResolver.getInitBinderMethods(handlerMethod)); InvocableHandlerMethod invocableMethod = this.methodResolver.getRequestMappingMethod(handlerMethod); Function<Throwable, Mono<HandlerResult>> exceptionHandler = ex -> handleException(ex, handlerMethod, bindingContext, exchange); return this.modelInitializer .initModel(handlerMethod, bindingContext, exchange) .then(Mono.defer(() -> invocableMethod.invoke(exchange, bindingContext))) .doOnNext(result -> result.setExceptionHandler(exceptionHandler)) .doOnNext(result -> bindingContext.saveModel()) .onErrorResume(exceptionHandler); }
@Test public void captureAndClaim() { ClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, "/test"); ClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK); ClientHttpConnector connector = (method, uri, fn) -> fn.apply(request).then(Mono.just(response)); ClientRequest clientRequest = ClientRequest.create(HttpMethod.GET, URI.create("/test")) .header(WebTestClient.WEBTESTCLIENT_REQUEST_ID, "1").build(); WiretapConnector wiretapConnector = new WiretapConnector(connector); ExchangeFunction function = ExchangeFunctions.create(wiretapConnector); function.exchange(clientRequest).block(ofMillis(0)); WiretapConnector.Info actual = wiretapConnector.claimRequest("1"); ExchangeResult result = actual.createExchangeResult(Duration.ZERO, null); assertEquals(HttpMethod.GET, result.getMethod()); assertEquals("/test", result.getUrl().toString()); }
@Override public Mono<Void> handle(ServerWebExchange exchange) { if (exchange.getRequest().getQueryParams().containsKey("expire")) { return exchange.getSession().doOnNext(session -> { // Don't do anything, leave it expired... }).then(); } else if (exchange.getRequest().getQueryParams().containsKey("changeId")) { return exchange.getSession().flatMap(session -> session.changeSessionId().doOnSuccess(aVoid -> updateSessionAttribute(session))); } else if (exchange.getRequest().getQueryParams().containsKey("invalidate")) { return exchange.getSession().doOnNext(WebSession::invalidate).then(); } else { return exchange.getSession().doOnSuccess(this::updateSessionAttribute).then(); } }
@Override public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) { if (this.forwardedHeaderTransformer != null) { request = this.forwardedHeaderTransformer.apply(request); } ServerWebExchange exchange = createExchange(request, response); LogFormatUtils.traceDebug(logger, traceOn -> exchange.getLogPrefix() + formatRequest(exchange.getRequest()) + (traceOn ? ", headers=" + formatHeaders(exchange.getRequest().getHeaders()) : "")); return getDelegate().handle(exchange) .doOnSuccess(aVoid -> logResponse(exchange)) .onErrorResume(ex -> handleUnresolvedError(exchange, ex)) .then(Mono.defer(response::setComplete)); }
@Override public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) { Mono<Integer> requestSizeMono = request.getBody(). reduce(0, (integer, dataBuffer) -> integer + dataBuffer.readableByteCount()). doOnSuccessOrError((size, throwable) -> { assertNull(throwable); assertEquals(REQUEST_SIZE, (long) size); }); response.getHeaders().setContentLength(RESPONSE_SIZE); return requestSizeMono.then(response.writeWith(multipleChunks())); }
@Test // SPR-16231 public void responseCommitted() { Throwable ex = new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Oops"); this.exchange.getResponse().setStatusCode(HttpStatus.CREATED); Mono<Void> mono = this.exchange.getResponse().setComplete() .then(Mono.defer(() -> this.handler.handle(this.exchange, ex))); StepVerifier.create(mono).consumeErrorWith(actual -> assertSame(ex, actual)).verify(); }
private Mono<Void> assertGetFormParts(ServerWebExchange exchange) { return exchange .getMultipartData() .doOnNext(parts -> { assertEquals(2, parts.size()); assertTrue(parts.containsKey("fooPart")); assertFooPart(parts.getFirst("fooPart")); assertTrue(parts.containsKey("barPart")); assertBarPart(parts.getFirst("barPart")); }) .then(); }