Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import com.fasterxml.jackson.core.type.TypeReference;
import java.io.Closeable;
import java.io.IOException;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
Expand All @@ -32,16 +31,7 @@ public abstract class ApiClient implements Closeable {
public AuthInterceptor authInterceptor;

/** Constructs a new instance of the {@link ApiClient}. */
protected ApiClient(
String appId,
String apiKey,
String clientName,
@Nullable ClientOptions options,
List<Host> defaultHosts,
Duration connectTimeout,
Duration readTimeout,
Duration writeTimeout
) {
protected ApiClient(String appId, String apiKey, String clientName, @Nullable ClientOptions options, List<Host> defaultHosts) {
if (appId == null || appId.isEmpty()) {
throw new AlgoliaRuntimeException("`appId` is missing.");
}
Expand All @@ -52,20 +42,11 @@ protected ApiClient(
executor = clientOptions.getExecutor();
requester = clientOptions.getCustomRequester() != null
? clientOptions.getCustomRequester()
: defaultRequester(appId, apiKey, clientName, clientOptions, defaultHosts, connectTimeout, readTimeout, writeTimeout);
: defaultRequester(appId, apiKey, clientName, clientOptions, defaultHosts);
}

/** Creates a default {@link Requester} for executing API requests. */
private Requester defaultRequester(
String appId,
String apiKey,
String clientName,
ClientOptions options,
List<Host> defaultHosts,
Duration connectTimeout,
Duration readTimeout,
Duration writeTimeout
) {
private Requester defaultRequester(String appId, String apiKey, String clientName, ClientOptions options, List<Host> defaultHosts) {
AlgoliaAgent algoliaAgent = new AlgoliaAgent(BuildConfig.VERSION)
.addSegment(new AlgoliaAgent.Segment(clientName, BuildConfig.VERSION))
.addSegments(options.getAlgoliaAgentSegments());
Expand All @@ -78,10 +59,7 @@ private Requester defaultRequester(
HttpRequester.Builder builder = new HttpRequester.Builder(serializer)
.addInterceptor(authInterceptor)
.addInterceptor(new UserAgentInterceptor(algoliaAgent))
.addInterceptor(new RetryStrategy(statefulHosts))
.setConnectTimeout(connectTimeout)
.setReadTimeout(readTimeout)
.setWriteTimeout(writeTimeout);
.addInterceptor(new RetryStrategy(statefulHosts));
if (options.getRequesterConfig() != null) {
options.getRequesterConfig().accept(builder);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
ModelPruner.removeOrphanModelFiles(this, operations, models);
Helpers.removeHelpers(operations);
Timeouts.propagate(operations);
GenericPropagator.propagateGenericsToOperations(operations, models);
return operations;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,24 @@ public void run(Map<String, CodegenModel> models, Map<String, CodegenOperation>
stepOut.put("isCreateClient", true); // TODO: remove once kotlin is converted

boolean hasCustomHosts = step.parameters != null && step.parameters.containsKey("customHosts");
if (hasCustomHosts) testOut.put("useEchoRequester", false);
stepOut.put("hasCustomHosts", hasCustomHosts);
if (hasCustomHosts) {
testOut.put("useEchoRequester", false);
stepOut.put("customHosts", step.parameters.get("customHosts"));
}

boolean hasCustomWriteTimeout = step.parameters != null && step.parameters.containsKey("writeTimeout");
stepOut.put("hasCustomWriteTimeout", hasCustomWriteTimeout);
if (hasCustomWriteTimeout) {
stepOut.put("writeTimeout", step.parameters.get("writeTimeout"));
}

stepOut.put("hasCustomClientCreate", hasCustomWriteTimeout || hasCustomHosts);

boolean hasTransformationRegion = step.parameters != null && step.parameters.containsKey("transformationRegion");
if (hasTransformationRegion) testOut.put("useEchoRequester", false);
stepOut.put("hasTransformationRegion", hasTransformationRegion);
if (hasTransformationRegion) {
testOut.put("useEchoRequester", false);
stepOut.put("transformationRegion", step.parameters.get("transformationRegion"));
}

Expand Down
49 changes: 37 additions & 12 deletions generators/src/main/java/com/algolia/codegen/utils/Timeouts.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.*;
import io.swagger.v3.oas.models.OpenAPI;
import java.util.*;
import org.openapitools.codegen.model.OperationsMap;

class TimeoutsValues {

Expand All @@ -20,9 +21,11 @@ class TimeoutsBundle {

public class Timeouts {

private static TimeoutsBundle defaults;

/** Inject timeouts in miliseconds into the given bundle, under the x-timeouts property * */
public static void enrichBundle(OpenAPI spec, Map<String, Object> bundle) throws ConfigException {
TimeoutsBundle defaults = new TimeoutsBundle();
defaults = new TimeoutsBundle();
// the default below are what the search API expect, which was previously used for any client
defaults.browser.connect = 1000;
defaults.browser.read = 2000;
Expand All @@ -33,18 +36,40 @@ public static void enrichBundle(OpenAPI spec, Map<String, Object> bundle) throws
defaults.server.write = 30000;

TimeoutsBundle specTimeouts = new ObjectMapper().convertValue(spec.getExtensions().get("x-timeouts"), TimeoutsBundle.class);
if (specTimeouts == null) {
specTimeouts = new TimeoutsBundle();
specTimeouts.browser = defaults.browser;
specTimeouts.server = defaults.server;
}
if (specTimeouts.browser == null) {
specTimeouts.browser = defaults.browser;
}
if (specTimeouts.server == null) {
specTimeouts.server = defaults.server;
if (specTimeouts != null) {
if (specTimeouts.browser != null) {
defaults.browser = specTimeouts.browser;
}
if (specTimeouts.server == null) {
defaults.server = specTimeouts.server;
}
}

bundle.put("x-timeouts", specTimeouts);
bundle.put("x-timeouts", defaults);
}

public static void propagate(OperationsMap operations) throws ConfigException {
operations
.getOperations()
.getOperation()
.forEach(entry -> {
if (!entry.vendorExtensions.containsKey("x-timeouts")) {
Map<String, Object> vendor = new HashMap<>();

Map<String, Object> browser = new HashMap<>();
browser.put("connect", defaults.browser.connect);
browser.put("read", defaults.browser.read);
browser.put("write", defaults.browser.write);
vendor.put("browser", browser);

Map<String, Object> server = new HashMap<>();
server.put("connect", defaults.server.connect);
server.put("read", defaults.server.read);
server.put("write", defaults.server.write);
vendor.put("server", server);

entry.vendorExtensions.put("x-timeouts", vendor);
}
});
}
}
9 changes: 7 additions & 2 deletions templates/csharp/tests/client/createClient.mustache
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{{#hasCustomHosts}}
{{#hasCustomClientCreate}}
{{clientPrefix}}Config _config = new {{clientPrefix}}Config("{{parametersWithDataTypeMap.appId.value}}","{{parametersWithDataTypeMap.apiKey.value}}"{{#hasRegionalHost}}{{#parametersWithDataTypeMap.region}},"{{parametersWithDataTypeMap.region.value}}"{{/parametersWithDataTypeMap.region}}{{/hasRegionalHost}}) {
{{#hasCustomHosts}}
CustomHosts = new List<StatefulHost>
{
{{#customHosts}}new () {
Expand All @@ -11,8 +12,12 @@
Accept = CallType.Read | CallType.Write,
}{{^-last}},{{/-last}}{{/customHosts}}
}{{#gzipEncoding}},Compression = CompressionType.Gzip{{/gzipEncoding}}
{{/hasCustomHosts}}
{{#hasCustomWriteTimeout}}
WriteTimeout = {{writeTimeout}}
{{/hasCustomWriteTimeout}}
};
{{^autoCreateClient}}var client = {{/autoCreateClient}}new {{client}}(_config);
{{/hasCustomHosts}}
{{/hasCustomClientCreate}}
{{#useEchoRequester}}
{{^autoCreateClient}}var client = {{/autoCreateClient}}new {{client}}(new {{clientPrefix}}Config("{{parametersWithDataTypeMap.appId.value}}","{{parametersWithDataTypeMap.apiKey.value}}"{{#hasRegionalHost}}{{#parametersWithDataTypeMap.region}},"{{parametersWithDataTypeMap.region.value}}"{{/parametersWithDataTypeMap.region}}{{/hasRegionalHost}}), _echo);{{/useEchoRequester}}
3 changes: 3 additions & 0 deletions templates/go/tests/client/createClient.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ cfg = {{clientPrefix}}.{{clientName}}Configuration{
{{#hasCustomHosts}}
Hosts: []transport.StatefulHost{ {{#customHosts}}transport.NewStatefulHost("http", tests.GetLocalhost() + ":{{port}}", call.IsReadWrite),{{/customHosts}} },
{{/hasCustomHosts}}
{{#hasCustomWriteTimeout}}
WriteTimeout: {{writeTimeout}},
{{/hasCustomWriteTimeout}}
{{#gzipEncoding}}
Compression: compression.GZIP,
{{/gzipEncoding}}
Expand Down
6 changes: 3 additions & 3 deletions templates/java/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public class {{classname}} extends ApiClient {
}

public {{classname}}(String appId, String apiKey, String region, ClientOptions options) {
super(appId, apiKey, "{{{baseName}}}", options, getDefaultHosts(region), Duration.ofMillis({{{x-timeouts.server.connect}}}L), Duration.ofMillis({{{x-timeouts.server.read}}}L), Duration.ofMillis({{{x-timeouts.server.write}}}L));
super(appId, apiKey, "{{{baseName}}}", options, getDefaultHosts(region));
}

{{/hasRegionalHost}}
Expand All @@ -95,7 +95,7 @@ public class {{classname}} extends ApiClient {
}

public {{classname}}(String appId, String apiKey, ClientOptions options) {
super(appId, apiKey, "{{{baseName}}}", options, getDefaultHosts({{#hostWithAppID}}appId{{/hostWithAppID}}), Duration.ofMillis({{{x-timeouts.server.connect}}}L), Duration.ofMillis({{{x-timeouts.server.read}}}L), Duration.ofMillis({{{x-timeouts.server.write}}}L));
super(appId, apiKey, "{{{baseName}}}", options, getDefaultHosts({{#hostWithAppID}}appId{{/hostWithAppID}}));
}
{{/hasRegionalHost}}

Expand Down Expand Up @@ -218,7 +218,7 @@ public class {{classname}} extends ApiClient {
{{#headerParams}}.addHeader("{{baseName}}", {{paramName}}){{/headerParams}}
{{#vendorExtensions}}{{#queryParams}}{{^x-is-custom-request}}.addQueryParameter("{{baseName}}", {{paramName}}){{/x-is-custom-request}}{{#x-is-custom-request}}.addQueryParameters(parameters){{/x-is-custom-request}}{{/queryParams}}{{/vendorExtensions}}
.build();
return executeAsync(request, {{#vendorExtensions.x-timeouts}}new RequestOptions().setReadTimeout(Duration.ofMillis({{{read}}}L)).setWriteTimeout(Duration.ofMillis({{{write}}}L)).setConnectTimeout(Duration.ofMillis({{{connect}}}L)).mergeRight({{/vendorExtensions.x-timeouts}}requestOptions{{#vendorExtensions.x-timeouts}}){{/vendorExtensions.x-timeouts}}, {{#vendorExtensions}}{{#x-is-generic}}{{{returnType}}}.class, innerType{{/x-is-generic}}{{/vendorExtensions}}{{^vendorExtensions.x-is-generic}}{{^returnType}}null{{/returnType}}{{#returnType}}new TypeReference<{{{.}}}>(){}{{/returnType}}{{/vendorExtensions.x-is-generic}});
return executeAsync(request, new RequestOptions(){{#vendorExtensions.x-timeouts.server}}.setReadTimeout(clientOptions.getReadTimeout() != null ? clientOptions.getReadTimeout() : Duration.ofMillis({{{read}}}L)).setWriteTimeout(clientOptions.getWriteTimeout() != null ? clientOptions.getWriteTimeout() : Duration.ofMillis({{{write}}}L)).setConnectTimeout(clientOptions.getConnectTimeout() != null ? clientOptions.getConnectTimeout() : Duration.ofMillis({{{connect}}}L)){{/vendorExtensions.x-timeouts.server}}.mergeRight(requestOptions), {{#vendorExtensions}}{{#x-is-generic}}{{{returnType}}}.class, innerType{{/x-is-generic}}{{/vendorExtensions}}{{^vendorExtensions.x-is-generic}}{{^returnType}}null{{/returnType}}{{#returnType}}new TypeReference<{{{.}}}>(){}{{/returnType}}{{/vendorExtensions.x-is-generic}});
}

{{! This case only sets `requestOptions` as optional }}
Expand Down
10 changes: 7 additions & 3 deletions templates/java/tests/client/client.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,15 @@ class {{client}}ClientTests {
}

{{client}} createClient() {
return new {{client}}("appId", "apiKey", {{#hasRegionalHost}}"{{defaultRegion}}", {{/hasRegionalHost}}withEchoRequester());
return new {{client}}("appId", "apiKey", {{#hasRegionalHost}}"{{defaultRegion}}", {{/hasRegionalHost}}withEchoRequester(null));
}

private ClientOptions withEchoRequester() {
return ClientOptions.builder().setRequesterConfig(requester -> requester.addInterceptor(echo)).build();
private ClientOptions withEchoRequester(Integer writeTimeout) {
if (writeTimeout == null) {
return ClientOptions.builder().setRequesterConfig(requester -> requester.addInterceptor(echo)).build();
}

return ClientOptions.builder().setRequesterConfig(requester -> requester.addInterceptor(echo)).setWriteTimeout(Duration.ofMillis(writeTimeout)).build();
}

private ClientOptions withCustomHosts(List<Host> hosts, boolean gzipEncoding) {
Expand Down
2 changes: 1 addition & 1 deletion templates/java/tests/client/createClient.mustache
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
{{^autoCreateClient}}{{client}} client = {{/autoCreateClient}}new {{client}}("{{parametersWithDataTypeMap.appId.value}}","{{parametersWithDataTypeMap.apiKey.value}}"{{#hasRegionalHost}}{{#parametersWithDataTypeMap.region}},"{{parametersWithDataTypeMap.region.value}}"{{/parametersWithDataTypeMap.region}}{{/hasRegionalHost}}{{#useEchoRequester}},withEchoRequester(){{/useEchoRequester}}{{#hasCustomHosts}},withCustomHosts(Arrays.asList({{#customHosts}}new Host("true".equals(System.getenv("CI")) ? "localhost" : "host.docker.internal", EnumSet.of(CallType.READ, CallType.WRITE), "http", {{port}}){{^-last}},{{/-last}}{{/customHosts}}), {{gzipEncoding}}){{/hasCustomHosts}});
{{^autoCreateClient}}{{client}} client = {{/autoCreateClient}}new {{client}}("{{parametersWithDataTypeMap.appId.value}}","{{parametersWithDataTypeMap.apiKey.value}}"{{#hasRegionalHost}}{{#parametersWithDataTypeMap.region}},"{{parametersWithDataTypeMap.region.value}}"{{/parametersWithDataTypeMap.region}}{{/hasRegionalHost}}{{#useEchoRequester}},withEchoRequester({{#hasCustomWriteTimeout}}{{writeTimeout}}{{/hasCustomWriteTimeout}}{{^hasCustomWriteTimeout}}null{{/hasCustomWriteTimeout}}){{/useEchoRequester}}{{#hasCustomHosts}},withCustomHosts(Arrays.asList({{#customHosts}}new Host("true".equals(System.getenv("CI")) ? "localhost" : "host.docker.internal", EnumSet.of(CallType.READ, CallType.WRITE), "http", {{port}}){{^-last}},{{/-last}}{{/customHosts}}), {{gzipEncoding}}){{/hasCustomHosts}});
{{#hasTransformationRegion}}client.setTransformationRegion("{{{transformationRegion}}}");{{/hasTransformationRegion}}
8 changes: 7 additions & 1 deletion templates/javascript/tests/client/createClient.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
{{/customHosts}}
],
{{/hasCustomHosts}}
{{#hasCustomWriteTimeout}}
writeTimeout: {{writeTimeout}},
{{/hasCustomWriteTimeout}}
{{#hasTransformationRegion}}
transformation: { region : "{{{transformationRegion}}}" },
{{/hasTransformationRegion}}
Expand All @@ -41,7 +44,10 @@
},
{{/customHosts}}
]
{{/hasCustomHosts}}
{{/hasCustomHosts}}
{{#hasCustomWriteTimeout}}
writeTimeout: {{writeTimeout}},
{{/hasCustomWriteTimeout}}
},
{{#hasRegionalHost}}
// @ts-ignore
Expand Down
2 changes: 1 addition & 1 deletion templates/kotlin/tests/client/createClient.mustache
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{^autoCreateClient}}val client = {{/autoCreateClient}}{{client}}(appId = "{{parametersWithDataTypeMap.appId.value}}", apiKey = "{{parametersWithDataTypeMap.apiKey.value}}",{{#hasRegionalHost}}{{#parametersWithDataTypeMap.region}}"{{parametersWithDataTypeMap.region.value}}",{{/parametersWithDataTypeMap.region}}{{/hasRegionalHost}}{{#hasCustomHosts}}options = ClientOptions(hosts = listOf({{#customHosts}}Host(url = if (System.getenv("CI") == "true") "localhost" else "host.docker.internal", protocol = "http", port = {{port}}){{^-last}},{{/-last}}{{/customHosts}}){{#gzipEncoding}}, compressionType = CompressionType.GZIP{{/gzipEncoding}}){{/hasCustomHosts}})
{{^autoCreateClient}}val client = {{/autoCreateClient}}{{client}}(appId = "{{parametersWithDataTypeMap.appId.value}}", apiKey = "{{parametersWithDataTypeMap.apiKey.value}}",{{#hasRegionalHost}}{{#parametersWithDataTypeMap.region}}"{{parametersWithDataTypeMap.region.value}}",{{/parametersWithDataTypeMap.region}}{{/hasRegionalHost}}{{#hasCustomClientCreate}}options = ClientOptions({{#hasCustomHosts}}hosts = listOf({{#customHosts}}Host(url = if (System.getenv("CI") == "true") "localhost" else "host.docker.internal", protocol = "http", port = {{port}}){{^-last}},{{/-last}}{{/customHosts}}){{/hasCustomHosts}}{{#hasCustomWriteTimeout}} writeTimeout = {{writeTimeout}}{{/hasCustomWriteTimeout}}{{#gzipEncoding}}, compressionType = CompressionType.GZIP{{/gzipEncoding}}){{/hasCustomClientCreate}})
6 changes: 3 additions & 3 deletions templates/php/tests/client/createClient.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ $client = $this->createClient(
{{#parametersWithDataTypeMap.apiKey}}"{{parametersWithDataTypeMap.apiKey.value}}"{{/parametersWithDataTypeMap.apiKey}}{{^parametersWithDataTypeMap.apiKey}}null{{/parametersWithDataTypeMap.apiKey}}{{#hasRegionalHost}},
{{#parametersWithDataTypeMap.region}}"{{parametersWithDataTypeMap.region.value}}"{{/parametersWithDataTypeMap.region}}{{^parametersWithDataTypeMap.region}}null{{/parametersWithDataTypeMap.region}}{{/hasRegionalHost}}
);
{{^isError}}$this->assertIsObject($client);{{/isError}}{{/useEchoRequester}}{{^hasTransformationRegion}}{{#hasCustomHosts}}
$client = {{client}}::createWithConfig({{clientPrefix}}Config::create("{{parametersWithDataTypeMap.appId.value}}","{{parametersWithDataTypeMap.apiKey.value}}"{{#hasRegionalHost}}{{#parametersWithDataTypeMap.region}},"{{parametersWithDataTypeMap.region.value}}"{{/parametersWithDataTypeMap.region}}{{/hasRegionalHost}})->setFullHosts([{{#customHosts}}"http://" . (getenv("CI") == "true" ? "localhost" : "host.docker.internal") . ":{{port}}"{{^-last}},{{/-last}}{{/customHosts}}]));
{{/hasCustomHosts}}{{/hasTransformationRegion}}
{{^isError}}$this->assertIsObject($client);{{/isError}}{{/useEchoRequester}}{{^hasTransformationRegion}}{{#hasCustomClientCreate}}
$client = {{client}}::createWithConfig({{clientPrefix}}Config::create("{{parametersWithDataTypeMap.appId.value}}","{{parametersWithDataTypeMap.apiKey.value}}"{{#hasRegionalHost}}{{#parametersWithDataTypeMap.region}},"{{parametersWithDataTypeMap.region.value}}"{{/parametersWithDataTypeMap.region}}{{/hasRegionalHost}}){{#hasCustomHosts}}->setFullHosts([{{#customHosts}}"http://" . (getenv("CI") == "true" ? "localhost" : "host.docker.internal") . ":{{port}}"{{^-last}},{{/-last}}{{/customHosts}}]){{/hasCustomHosts}}{{#hasCustomWriteTimeout}}->setWriteTimeout({{writeTimeout}}){{/hasCustomWriteTimeout}});
{{/hasCustomClientCreate}}{{/hasTransformationRegion}}
{{#hasTransformationRegion}}
$client = {{client}}::createWithConfig({{clientPrefix}}Config::create("{{parametersWithDataTypeMap.appId.value}}","{{parametersWithDataTypeMap.apiKey.value}}")->setFullHosts([{{#customHosts}}"http://" . (getenv("CI") == "true" ? "localhost" : "host.docker.internal") . ":{{port}}"{{^-last}},{{/-last}}{{/customHosts}}])->setTransformationRegion("{{{transformationRegion}}}"));
{{/hasTransformationRegion}}
3 changes: 3 additions & 0 deletions templates/python/tests/client/createClient.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ _config = {{#lambda.pascalcase}}{{clientPrefix}}Config{{/lambda.pascalcase}}("{{
{{#hasCustomHosts}}
{{#isError}} {{/isError}}_config.hosts = HostsCollection([{{#customHosts}}Host(url='localhost' if environ.get('CI') == 'true' else 'host.docker.internal', scheme='http', port={{port}}){{^-last}},{{/-last}}{{/customHosts}}])
{{/hasCustomHosts}}
{{#hasCustomWriteTimeout}}
{{#isError}} {{/isError}}_config.write_timeout = {{writeTimeout}}
{{/hasCustomWriteTimeout}}
{{#hasTransformationRegion}}
{{#isError}} {{/isError}}_config.set_transformation_region("{{{transformationRegion}}}")
{{/hasTransformationRegion}}
Expand Down
Loading
Loading