-
Notifications
You must be signed in to change notification settings - Fork 102
Migrate jetty-client to vertx-web-client #387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 5 commits
5584bb6
f7562b1
547e7b6
db69e2c
fe097eb
253edb0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,73 +1,54 @@ | ||||||||||||||||||||||
| package ai.labs.eddi.engine.httpclient.bootstrap; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import ai.labs.eddi.engine.httpclient.impl.JettyHttpClient; | ||||||||||||||||||||||
| import ai.labs.eddi.engine.httpclient.impl.VertxHttpClient; | ||||||||||||||||||||||
| import io.vertx.core.Vertx; | ||||||||||||||||||||||
| import io.vertx.ext.web.client.WebClient; | ||||||||||||||||||||||
| import io.vertx.ext.web.client.WebClientSession; | ||||||||||||||||||||||
| import io.vertx.ext.web.client.WebClientOptions; | ||||||||||||||||||||||
| import jakarta.enterprise.context.ApplicationScoped; | ||||||||||||||||||||||
| import jakarta.enterprise.inject.Disposes; | ||||||||||||||||||||||
| import jakarta.inject.Inject; | ||||||||||||||||||||||
| import jakarta.ws.rs.Produces; | ||||||||||||||||||||||
| import org.eclipse.jetty.client.HttpClient; | ||||||||||||||||||||||
| import org.eclipse.jetty.client.WWWAuthenticationProtocolHandler; | ||||||||||||||||||||||
| import org.eclipse.microprofile.config.inject.ConfigProperty; | ||||||||||||||||||||||
| import org.eclipse.microprofile.context.ManagedExecutor; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import java.util.Arrays; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @ApplicationScoped | ||||||||||||||||||||||
| public class HttpClientModule { | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @Inject | ||||||||||||||||||||||
| ManagedExecutor executorService; | ||||||||||||||||||||||
| Vertx vertx; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @Produces | ||||||||||||||||||||||
| @ApplicationScoped | ||||||||||||||||||||||
| public JettyHttpClient provideHttpClient(@ConfigProperty(name = "httpClient.maxConnectionsQueued") Integer maxConnectionsQueued, | ||||||||||||||||||||||
| @ConfigProperty(name = "httpClient.maxConnectionPerRoute") Integer maxConnectionPerRoute, | ||||||||||||||||||||||
| @ConfigProperty(name = "httpClient.requestBufferSize") Integer requestBufferSize, | ||||||||||||||||||||||
| @ConfigProperty(name = "httpClient.responseBufferSize") Integer responseBufferSize, | ||||||||||||||||||||||
| public VertxHttpClient provideHttpClient(@ConfigProperty(name = "httpClient.maxConnectionPerRoute") Integer maxConnectionPerRoute, | ||||||||||||||||||||||
| @ConfigProperty(name = "httpClient.maxRedirects") Integer maxRedirects, | ||||||||||||||||||||||
| @ConfigProperty(name = "httpClient.idleTimeoutInMillis") Integer idleTimeout, | ||||||||||||||||||||||
| @ConfigProperty(name = "httpClient.connectTimeoutInMillis") Integer connectTimeout, | ||||||||||||||||||||||
| @ConfigProperty(name = "httpClient.disableWWWAuthenticationValidation") | ||||||||||||||||||||||
| Boolean disableWWWAuthenticationValidation) { | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| try { | ||||||||||||||||||||||
| HttpClient httpClient = new HttpClient(); | ||||||||||||||||||||||
| httpClient.setExecutor(executorService); | ||||||||||||||||||||||
| httpClient.setMaxConnectionsPerDestination(maxConnectionsQueued); | ||||||||||||||||||||||
| httpClient.setMaxRequestsQueuedPerDestination(maxConnectionPerRoute); | ||||||||||||||||||||||
| httpClient.setRequestBufferSize(requestBufferSize); | ||||||||||||||||||||||
| httpClient.setResponseBufferSize(responseBufferSize); | ||||||||||||||||||||||
| httpClient.setMaxRedirects(maxRedirects); | ||||||||||||||||||||||
| httpClient.setIdleTimeout(idleTimeout); | ||||||||||||||||||||||
| httpClient.setConnectTimeout(connectTimeout); | ||||||||||||||||||||||
| httpClient.start(); | ||||||||||||||||||||||
| @ConfigProperty(name = "httpClient.connectTimeoutInMillis") Integer connectTimeout) { | ||||||||||||||||||||||
|
Comment on lines
22
to
25
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (disableWWWAuthenticationValidation) { | ||||||||||||||||||||||
| httpClient.getProtocolHandlers().remove(WWWAuthenticationProtocolHandler.NAME); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| WebClientOptions options = new WebClientOptions(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| registerHttpClientShutdownHook(httpClient); | ||||||||||||||||||||||
| // Mapping configuration | ||||||||||||||||||||||
| options.setMaxPoolSize(maxConnectionPerRoute); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return new JettyHttpClient(httpClient); | ||||||||||||||||||||||
| } catch (Exception e) { | ||||||||||||||||||||||
| System.out.println(Arrays.toString(e.getStackTrace())); | ||||||||||||||||||||||
| throw new RuntimeException(e.getLocalizedMessage(), e); | ||||||||||||||||||||||
| options.setMaxRedirects(maxRedirects); | ||||||||||||||||||||||
| int idleTimeoutSeconds = idleTimeout / 1000; | ||||||||||||||||||||||
| if (idleTimeout > 0 && idleTimeoutSeconds == 0) { | ||||||||||||||||||||||
|
||||||||||||||||||||||
| options.setMaxRedirects(maxRedirects); | |
| int idleTimeoutSeconds = idleTimeout / 1000; | |
| if (idleTimeout > 0 && idleTimeoutSeconds == 0) { | |
| options.setMaxRedirects(maxRedirects); | |
| // Vert.x WebClientOptions.setIdleTimeout only supports seconds granularity. | |
| // Any idleTimeout value between 1 and 999 milliseconds will be rounded up to 1 second. | |
| int idleTimeoutSeconds = idleTimeout / 1000; | |
| if (idleTimeout > 0 && idleTimeoutSeconds == 0) { | |
| // Warn users about rounding up sub-second timeouts | |
| System.out.println("Warning: httpClient.idleTimeoutInMillis (" + idleTimeout + " ms) is less than 1000 ms and will be rounded up to 1 second due to Vert.x limitation."); |
Outdated
Copilot
AI
Nov 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idle timeout conversion from milliseconds to seconds has potential issues. When idleTimeout is between 1 and 999 milliseconds, the result will be 0, which is then changed to 1 second on line 35. However, when idleTimeout is exactly 0, it bypasses the check and sets the timeout to 0 seconds. This inconsistency could cause unexpected behavior. Consider handling the conversion more consistently: if the input is > 0 but < 1000, round up to 1 second; if it's 0, keep it as 0 (which typically means no timeout).
| int idleTimeoutSeconds = idleTimeout / 1000; | |
| if (idleTimeout > 0 && idleTimeoutSeconds == 0) { | |
| idleTimeoutSeconds = 1; | |
| int idleTimeoutSeconds; | |
| if (idleTimeout == 0) { | |
| idleTimeoutSeconds = 0; // No timeout | |
| } else if (idleTimeout > 0 && idleTimeout < 1000) { | |
| idleTimeoutSeconds = 1; // Round up to 1 second | |
| } else { | |
| idleTimeoutSeconds = (int) Math.ceil(idleTimeout / 1000.0); // Round up to nearest second |
Outdated
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The timeout conversion from milliseconds to seconds using integer division can result in a timeout of 0 seconds (no timeout) for values less than 1000ms. For example, if idleTimeout is 500ms, idleTimeoutSeconds will be 0, which in Vert.x means "no timeout" rather than 500ms.
Consider using TimeUnit conversions or rounding up:
int idleTimeoutSeconds = (int) Math.ceil(idleTimeout / 1000.0);to ensure timeouts under 1 second are still applied as 1 second rather than being disabled.
| int idleTimeoutSeconds = idleTimeout / 1000; | |
| if (idleTimeout > 0 && idleTimeoutSeconds == 0) { | |
| idleTimeoutSeconds = 1; | |
| } | |
| int idleTimeoutSeconds = (int) Math.ceil(idleTimeout / 1000.0); |
Copilot
AI
Nov 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dispose method only closes the WebClientSession but doesn't close the underlying WebClient that was created on line 43. According to Vert.x documentation, both the session and the base WebClient should be closed to properly release resources. Consider also closing the base WebClient or storing a reference to it in VertxHttpClient for proper cleanup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
Vertxinstance is injected but Quarkus provides Vert.x through thequarkus-vertxextension. You need to add the Quarkus Vert.x dependency topom.xmlfor this injection to work:Without this dependency, the Vertx injection will fail at runtime.