public CompletableFuture asyncRequest()

in server/src/main/java/org/eclipse/jifa/server/service/impl/WorkerServiceImpl.java [305:362]


    public <Response> CompletableFuture<Response> asyncRequest(WorkerEntity worker, HttpRequestToWorker<Response> request) {
        UriBuilder uriBuilder = new DefaultUriBuilderFactory().builder()
                                                              .scheme("http")
                                                              .host(worker.getHostAddress())
                                                              .port(worker.getPort())
                                                              .path(HTTP_API_PREFIX + "/" + request.uri());

        HttpMethod method = request.method();
        if (method == HttpMethod.GET && request.query() != null) {
            uriBuilder.queryParams(request.query());
        }

        WebClient.RequestBodySpec spec = webClient.method(method)
                                                  .uri(uriBuilder.build())
                                                  .accept(MediaType.APPLICATION_JSON);

        String jwtToken = userService.getCurrentUserJwtTokenOrNull();

        if (jwtToken != null) {
            spec.header(HttpHeaders.AUTHORIZATION, "Bearer " + jwtToken);
        }

        if (request.body() != null) {
            Object body = request.body();
            String bodyJson;
            if (body instanceof JsonConvertible convertible) {
                bodyJson = convertible.toJson();
            } else {
                bodyJson = GSON.toJson(body);
            }
            byte[] bytes = bodyJson.getBytes(Constant.CHARSET);
            spec.contentType(MediaType.APPLICATION_JSON)
                .body((BodyInserter<byte[], ClientHttpRequest>) (message, context) -> {
                    DataBuffer buffer = message.bufferFactory().wrap(bytes);
                    message.getHeaders().setContentLength(bytes.length);
                    return message.writeWith(Mono.just(buffer));
                });
        }

        Class<Response> responseClass = request.responseType();
        return spec.exchangeToMono(response -> {
            if (!response.statusCode().is2xxSuccessful()) {
                return response.createError();
            }

            if (responseClass == Void.class) {
                return Mono.empty();
            }

            if (responseClass == byte[].class) {
                return (Mono<Response>) response.bodyToMono(byte[].class)
                                                .defaultIfEmpty(Constant.EMPTY_BYTE_ARRAY);
            }

            return response.bodyToMono(String.class)
                           .map(s -> GSON.fromJson(s, responseClass));
        }).toFuture();
    }