Skip to content

Commit 102b419

Browse files
committed
fix: honor timeout set for REST API calls
1 parent 1c11818 commit 102b419

File tree

6 files changed

+78
-34
lines changed

6 files changed

+78
-34
lines changed

‎deploy/docker/frontend/nginx-http.conf

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ http {
3535
listen 3000 default_server;
3636
root /lowcoder/client;
3737

38+
proxy_connect_timeout 125;
39+
proxy_send_timeout 125;
40+
proxy_read_timeout 125;
3841

3942
location / {
4043
try_files $uri /index.html;

‎deploy/docker/frontend/nginx-https.conf

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ http {
3838
include /etc/nginx/ssl-certificate.conf;
3939
include /etc/nginx/ssl-params.conf;
4040

41+
proxy_connect_timeout 125;
42+
proxy_send_timeout 125;
43+
proxy_read_timeout 125;
44+
4145
location / {
4246
try_files $uri /index.html;
4347

‎server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/query/service/QueryExecutionService.java

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public Mono<QueryExecutionResult> executeQuery(Datasource datasource, Map<String
4444
String timeoutStr, QueryVisitorContext queryVisitorContext) {
4545

4646
int timeoutMs = QueryTimeoutUtils.parseQueryTimeoutMs(timeoutStr, requestParams);
47+
queryConfig.putIfAbsent("timeoutMs", timeoutMs);
4748

4849
return Mono.defer(() -> {
4950
if (datasourceMetaInfoService.isJsDatasourcePlugin(datasource.getType())) {

‎server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/RestApiExecutor.java

+62-33
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,48 @@
1919

2020
package org.lowcoder.plugin.restapi;
2121

22-
import com.fasterxml.jackson.core.JsonProcessingException;
23-
import com.fasterxml.jackson.databind.JsonNode;
24-
import com.fasterxml.jackson.databind.node.ObjectNode;
25-
import com.google.common.collect.ImmutableMap;
26-
import lombok.Builder;
27-
import lombok.Getter;
22+
import static com.google.common.base.MoreObjects.firstNonNull;
23+
import static org.apache.commons.collections4.MapUtils.emptyIfNull;
24+
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
25+
import static org.lowcoder.plugin.restapi.RestApiError.REST_API_EXECUTION_ERROR;
26+
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isBinary;
27+
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isJson;
28+
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isJsonContentType;
29+
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isPicture;
30+
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.isValidContentType;
31+
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.parseContentType;
32+
import static org.lowcoder.sdk.exception.PluginCommonError.JSON_PARSE_ERROR;
33+
import static org.lowcoder.sdk.exception.PluginCommonError.QUERY_ARGUMENT_ERROR;
34+
import static org.lowcoder.sdk.exception.PluginCommonError.QUERY_EXECUTION_ERROR;
35+
import static org.lowcoder.sdk.plugin.restapi.DataUtils.convertToMultiformFileValue;
36+
import static org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType.DIGEST_AUTH;
37+
import static org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType.OAUTH2_INHERIT_FROM_LOGIN;
38+
import static org.lowcoder.sdk.util.ExceptionUtils.propagateError;
39+
import static org.lowcoder.sdk.util.JsonUtils.readTree;
40+
import static org.lowcoder.sdk.util.JsonUtils.toJsonThrows;
41+
import static org.lowcoder.sdk.util.MustacheHelper.renderMustacheJson;
42+
import static org.lowcoder.sdk.util.MustacheHelper.renderMustacheString;
43+
import static org.lowcoder.sdk.util.StreamUtils.collectList;
44+
45+
import java.io.IOException;
46+
import java.net.URI;
47+
import java.net.URISyntaxException;
48+
import java.nio.charset.StandardCharsets;
49+
import java.text.ParseException;
50+
import java.time.Duration;
51+
import java.util.ArrayList;
52+
import java.util.Base64;
53+
import java.util.HashMap;
54+
import java.util.HashSet;
55+
import java.util.List;
56+
import java.util.Map;
57+
import java.util.Set;
58+
import java.util.function.Consumer;
59+
import java.util.stream.Collectors;
60+
import java.util.stream.Stream;
61+
62+
import javax.annotation.Nullable;
63+
2864
import org.apache.commons.collections4.CollectionUtils;
2965
import org.apache.commons.lang3.ObjectUtils;
3066
import org.apache.commons.lang3.StringUtils;
@@ -51,41 +87,29 @@
5187
import org.lowcoder.sdk.query.QueryVisitorContext;
5288
import org.lowcoder.sdk.webclient.WebClientBuildHelper;
5389
import org.pf4j.Extension;
54-
import org.springframework.http.*;
90+
import org.springframework.http.HttpCookie;
91+
import org.springframework.http.HttpHeaders;
92+
import org.springframework.http.HttpMethod;
93+
import org.springframework.http.HttpStatus;
94+
import org.springframework.http.MediaType;
95+
import org.springframework.http.ResponseEntity;
5596
import org.springframework.http.client.reactive.ClientHttpRequest;
97+
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
5698
import org.springframework.util.MultiValueMap;
5799
import org.springframework.web.reactive.function.BodyInserter;
58100
import org.springframework.web.reactive.function.BodyInserters;
59101
import org.springframework.web.reactive.function.client.ExchangeStrategies;
60102
import org.springframework.web.reactive.function.client.WebClient;
61-
import reactor.core.publisher.Mono;
62103

63-
import javax.annotation.Nullable;
64-
import java.io.IOException;
65-
import java.net.URI;
66-
import java.net.URISyntaxException;
67-
import java.nio.charset.StandardCharsets;
68-
import java.text.ParseException;
69-
import java.util.*;
70-
import java.util.function.Consumer;
71-
import java.util.stream.Collectors;
72-
import java.util.stream.Stream;
104+
import com.fasterxml.jackson.core.JsonProcessingException;
105+
import com.fasterxml.jackson.databind.JsonNode;
106+
import com.fasterxml.jackson.databind.node.ObjectNode;
107+
import com.google.common.collect.ImmutableMap;
73108

74-
import static com.google.common.base.MoreObjects.firstNonNull;
75-
import static org.apache.commons.collections4.MapUtils.emptyIfNull;
76-
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
77-
import static org.lowcoder.plugin.restapi.RestApiError.REST_API_EXECUTION_ERROR;
78-
import static org.lowcoder.plugin.restapi.helpers.ContentTypeHelper.*;
79-
import static org.lowcoder.sdk.exception.PluginCommonError.*;
80-
import static org.lowcoder.sdk.plugin.restapi.DataUtils.convertToMultiformFileValue;
81-
import static org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType.DIGEST_AUTH;
82-
import static org.lowcoder.sdk.plugin.restapi.auth.RestApiAuthType.OAUTH2_INHERIT_FROM_LOGIN;
83-
import static org.lowcoder.sdk.util.ExceptionUtils.propagateError;
84-
import static org.lowcoder.sdk.util.JsonUtils.readTree;
85-
import static org.lowcoder.sdk.util.JsonUtils.toJsonThrows;
86-
import static org.lowcoder.sdk.util.MustacheHelper.renderMustacheJson;
87-
import static org.lowcoder.sdk.util.MustacheHelper.renderMustacheString;
88-
import static org.lowcoder.sdk.util.StreamUtils.collectList;
109+
import lombok.Builder;
110+
import lombok.Getter;
111+
import reactor.core.publisher.Mono;
112+
import reactor.netty.http.client.HttpClient;
89113

90114
@Extension
91115
public class RestApiExecutor implements QueryExecutor<RestApiDatasourceConfig, Object, RestApiQueryExecutionContext> {
@@ -176,6 +200,7 @@ public RestApiQueryExecutionContext buildQueryExecutionContext(RestApiDatasource
176200
.authConfig(datasourceConfig.getAuthConfig())
177201
.sslConfig(datasourceConfig.getSslConfig())
178202
.authTokenMono(queryVisitorContext.getAuthTokenMono())
203+
.timeoutMs(queryConfig.getTimeoutMs())
179204
.build();
180205
}
181206

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

263+
HttpClient httpClient = HttpClient.create()
264+
.responseTimeout(Duration.ofMillis(context.getTimeoutMs()));
265+
238266
webClientBuilder.defaultCookies(injectCookies(context));
239267
WebClient client = webClientBuilder
240268
.exchangeStrategies(exchangeStrategies)
269+
.clientConnector(new ReactorClientHttpConnector(httpClient))
241270
.build();
242271

243272
BodyInserter<?, ? super ClientHttpRequest> bodyInserter = buildBodyInserter(

‎server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/model/RestApiQueryConfig.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,19 @@ public class RestApiQueryConfig {
3030
private final List<Property> params;
3131
private final List<Property> headers;
3232
private final List<Property> bodyFormData;
33+
private final long timeoutMs;
3334

3435
@JsonCreator
3536
private RestApiQueryConfig(HttpMethod httpMethod, boolean disableEncodingParams, String body, String path,
36-
List<Property> params, List<Property> headers, List<Property> bodyFormData) {
37+
List<Property> params, List<Property> headers, List<Property> bodyFormData, long timeoutMs) {
3738
this.httpMethod = httpMethod;
3839
this.disableEncodingParams = disableEncodingParams;
3940
this.body = body;
4041
this.path = path;
4142
this.params = params;
4243
this.headers = headers;
4344
this.bodyFormData = bodyFormData;
45+
this.timeoutMs = timeoutMs;
4446
}
4547

4648
public static RestApiQueryConfig from(Map<String, Object> queryConfigs) {

‎server/api-service/lowcoder-plugins/restApiPlugin/src/main/java/org/lowcoder/plugin/restapi/model/RestApiQueryExecutionContext.java

+5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class RestApiQueryExecutionContext extends QueryExecutionContext {
4343
@Getter
4444
private Mono<List<Property>> authTokenMono;
4545
private SslConfig sslConfig;
46+
private long timeoutMs;
4647

4748
public URI getUri() {
4849
return uri;
@@ -96,4 +97,8 @@ public AuthConfig getAuthConfig() {
9697
public SslConfig getSslConfig() {
9798
return sslConfig;
9899
}
100+
101+
public long getTimeoutMs() {
102+
return timeoutMs;
103+
}
99104
}

0 commit comments

Comments
 (0)