Skip to content

Commit

Permalink
fix: honor timeout set for REST API calls
Browse files Browse the repository at this point in the history
  • Loading branch information
ludomikula committed Aug 20, 2023
1 parent 1c11818 commit 102b419
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 34 deletions.
3 changes: 3 additions & 0 deletions deploy/docker/frontend/nginx-http.conf
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ http {
listen 3000 default_server;
root /lowcoder/client;

proxy_connect_timeout 125;
proxy_send_timeout 125;
proxy_read_timeout 125;

location / {
try_files $uri /index.html;
Expand Down
4 changes: 4 additions & 0 deletions deploy/docker/frontend/nginx-https.conf
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ http {
include /etc/nginx/ssl-certificate.conf;
include /etc/nginx/ssl-params.conf;

proxy_connect_timeout 125;
proxy_send_timeout 125;
proxy_read_timeout 125;

location / {
try_files $uri /index.html;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public Mono<QueryExecutionResult> executeQuery(Datasource datasource, Map<String
String timeoutStr, QueryVisitorContext queryVisitorContext) {

int timeoutMs = QueryTimeoutUtils.parseQueryTimeoutMs(timeoutStr, requestParams);
queryConfig.putIfAbsent("timeoutMs", timeoutMs);

return Mono.defer(() -> {
if (datasourceMetaInfoService.isJsDatasourcePlugin(datasource.getType())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,48 @@

package org.lowcoder.plugin.restapi;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableMap;
import lombok.Builder;
import lombok.Getter;
import static com.google.common.base.MoreObjects.firstNonNull;
import static org.apache.commons.collections4.MapUtils.emptyIfNull;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
import static org.lowcoder.plugin.restapi.RestApiError.REST_API_EXECUTION_ERROR;
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isBinary;
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isJson;
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isJsonContentType;
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isPicture;
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isValidContentType;
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.parseContentType;
import static org.lowcoder.sdk.exception.PluginCommonError.JSON_PARSE_ERROR;
import static org.lowcoder.sdk.exception.PluginCommonError.QUERY_ARGUMENT_ERROR;
import static org.lowcoder.sdk.exception.PluginCommonError.QUERY_EXECUTION_ERROR;
import static org.lowcoder.sdk.plugin.restapi.DataUtils.convertToMultiformFileValue;
import static org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType.DIGEST_AUTH;
import static org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType.OAUTH2_INHERIT_FROM_LOGIN;
import static org.lowcoder.sdk.util.ExceptionUtils.propagateError;
import static org.lowcoder.sdk.util.JsonUtils.readTree;
import static org.lowcoder.sdk.util.JsonUtils.toJsonThrows;
import static org.lowcoder.sdk.util.MustacheHelper.renderMustacheJson;
import static org.lowcoder.sdk.util.MustacheHelper.renderMustacheString;
import static org.lowcoder.sdk.util.StreamUtils.collectList;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Nullable;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -51,41 +87,29 @@
import org.lowcoder.sdk.query.QueryVisitorContext;
import org.lowcoder.sdk.webclient.WebClientBuildHelper;
import org.pf4j.Extension;
import org.springframework.http.*;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.reactive.ClientHttpRequest;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserter;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import javax.annotation.Nullable;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableMap;

import static com.google.common.base.MoreObjects.firstNonNull;
import static org.apache.commons.collections4.MapUtils.emptyIfNull;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
import static org.lowcoder.plugin.restapi.RestApiError.REST_API_EXECUTION_ERROR;
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.*;
import static org.lowcoder.sdk.exception.PluginCommonError.*;
import static org.lowcoder.sdk.plugin.restapi.DataUtils.convertToMultiformFileValue;
import static org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType.DIGEST_AUTH;
import static org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType.OAUTH2_INHERIT_FROM_LOGIN;
import static org.lowcoder.sdk.util.ExceptionUtils.propagateError;
import static org.lowcoder.sdk.util.JsonUtils.readTree;
import static org.lowcoder.sdk.util.JsonUtils.toJsonThrows;
import static org.lowcoder.sdk.util.MustacheHelper.renderMustacheJson;
import static org.lowcoder.sdk.util.MustacheHelper.renderMustacheString;
import static org.lowcoder.sdk.util.StreamUtils.collectList;
import lombok.Builder;
import lombok.Getter;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;

@Extension
public class RestApiExecutor implements QueryExecutor<RestApiDatasourceConfig, Object, RestApiQueryExecutionContext> {
Expand Down Expand Up @@ -176,6 +200,7 @@ public RestApiQueryExecutionContext buildQueryExecutionContext(RestApiDatasource
.authConfig(datasourceConfig.getAuthConfig())
.sslConfig(datasourceConfig.getSslConfig())
.authTokenMono(queryVisitorContext.getAuthTokenMono())
.timeoutMs(queryConfig.getTimeoutMs())
.build();
}

Expand Down Expand Up @@ -235,9 +260,13 @@ public Mono<QueryExecutionResult> executeQuery(Object webClientFilter, RestApiQu
webClientBuilder.filter(new BufferingFilter());
}

HttpClient httpClient = HttpClient.create()
.responseTimeout(Duration.ofMillis(context.getTimeoutMs()));

webClientBuilder.defaultCookies(injectCookies(context));
WebClient client = webClientBuilder
.exchangeStrategies(exchangeStrategies)
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();

BodyInserter<?, ? super ClientHttpRequest> bodyInserter = buildBodyInserter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,19 @@ public class RestApiQueryConfig {
private final List<Property> params;
private final List<Property> headers;
private final List<Property> bodyFormData;
private final long timeoutMs;

@JsonCreator
private RestApiQueryConfig(HttpMethod httpMethod, boolean disableEncodingParams, String body, String path,
List<Property> params, List<Property> headers, List<Property> bodyFormData) {
List<Property> params, List<Property> headers, List<Property> bodyFormData, long timeoutMs) {
this.httpMethod = httpMethod;
this.disableEncodingParams = disableEncodingParams;
this.body = body;
this.path = path;
this.params = params;
this.headers = headers;
this.bodyFormData = bodyFormData;
this.timeoutMs = timeoutMs;
}

public static RestApiQueryConfig from(Map<String, Object> queryConfigs) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class RestApiQueryExecutionContext extends QueryExecutionContext {
@Getter
private Mono<List<Property>> authTokenMono;
private SslConfig sslConfig;
private long timeoutMs;

public URI getUri() {
return uri;
Expand Down Expand Up @@ -96,4 +97,8 @@ public AuthConfig getAuthConfig() {
public SslConfig getSslConfig() {
return sslConfig;
}

public long getTimeoutMs() {
return timeoutMs;
}
}

0 comments on commit 102b419

Please sign in to comment.