From ca2879743d3721623031f57fc761972292f6a62b Mon Sep 17 00:00:00 2001 From: Hamza Mahmood Date: Thu, 7 Aug 2025 15:38:11 +0500 Subject: [PATCH 1/6] feat(http-client-configration): add proxy support --- .../client/CoreHttpClientConfiguration.java | 42 ++++- .../http/client/CoreProxyConfiguration.java | 151 ++++++++++++++++++ 2 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java diff --git a/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java b/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java index 02f022dd..d988e403 100644 --- a/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java +++ b/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java @@ -1,5 +1,6 @@ package io.apimatic.core.configurations.http.client; +import io.apimatic.coreinterfaces.http.proxy.ProxyConfiguration; import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -122,6 +123,12 @@ public final class CoreHttpClientConfiguration implements ClientConfiguration { */ private final boolean skipSslCertVerification; + /** + * The proxy configuration used to route network requests through a proxy server. + * Contains details such as address, port, and optional authentication credentials. + */ + private final ProxyConfiguration proxyConfiguration; + /** * @param timeout * @param numberOfRetries @@ -140,7 +147,7 @@ private CoreHttpClientConfiguration(final long timeout, final int numberOfRetrie final boolean skipSslCertVerification, final Set httpStatusCodesToRetry, final Set httpMethodsToRetry, final long maximumRetryWaitTime, final boolean shouldRetryOnTimeout, final okhttp3.OkHttpClient httpClientInstance, - final boolean overrideHttpClientConfigurations) { + final boolean overrideHttpClientConfigurations, final ProxyConfiguration proxyConfiguration) { this.timeout = timeout; this.numberOfRetries = numberOfRetries; this.backOffFactor = backOffFactor; @@ -152,6 +159,7 @@ private CoreHttpClientConfiguration(final long timeout, final int numberOfRetrie this.httpClientInstance = httpClientInstance; this.overrideHttpClientConfigurations = overrideHttpClientConfigurations; this.skipSslCertVerification = skipSslCertVerification; + this.proxyConfiguration = proxyConfiguration; } /** @@ -243,6 +251,14 @@ public boolean skipSslCertVerification() { return skipSslCertVerification; } + /** + * Returns the proxy configuration used to route requests through a proxy server. + * This includes the proxy address, port, and any authentication credentials. + * + * @return the {@link ProxyConfiguration}, or {@code null} if no proxy is configured + */ + public ProxyConfiguration getProxyConfiguration() { return proxyConfiguration; } + /** * Converts this HttpClientConfiguration into string format. * @return String representation of this class. @@ -255,7 +271,8 @@ public String toString() { + ", httpMethodsToRetry=" + httpMethodsToRetry + ", maximumRetryWaitTime=" + maximumRetryWaitTime + ", shouldRetryOnTimeout=" + shouldRetryOnTimeout + ", httpClientInstance=" + httpClientInstance - + ", overrideHttpClientConfigurations=" + overrideHttpClientConfigurations + "]"; + + ", overrideHttpClientConfigurations=" + overrideHttpClientConfigurations + + ", proxy=" + proxyConfiguration + "]"; } /** @@ -269,7 +286,8 @@ public Builder newBuilder() { .httpStatusCodesToRetry(httpStatusCodesToRetry) .httpMethodsToRetry(httpMethodsToRetry).maximumRetryWaitTime(maximumRetryWaitTime) .shouldRetryOnTimeout(shouldRetryOnTimeout) - .httpClientInstance(httpClientInstance, overrideHttpClientConfigurations); + .httpClientInstance(httpClientInstance, overrideHttpClientConfigurations) + .proxyConfiguration(proxyConfiguration); } /** @@ -322,6 +340,11 @@ public static class Builder { * Skip Ssl certification. */ private boolean skipSslCertVerification; + /** + * The proxy configuration used to route network requests through a proxy server. + * Contains details such as address, port, and optional authentication credentials. + */ + private ProxyConfiguration proxyConfiguration; /** * Default Constructor to initiate builder with default properties. @@ -463,6 +486,17 @@ public Builder skipSslCertVerification(boolean skipSslCertVerification) { return this; } + /** + * Sets the proxy configuration to be used for routing requests through a proxy server. + * + * @param proxyConfiguration the {@link ProxyConfiguration} instance to use + * @return the builder instance + */ + public Builder proxyConfiguration(ProxyConfiguration proxyConfiguration) { + this.proxyConfiguration = proxyConfiguration; + return this; + } + /** * Builds a new HttpClientConfiguration object using the set fields. * @return {@link CoreHttpClientConfiguration}. @@ -471,7 +505,7 @@ public CoreHttpClientConfiguration build() { return new CoreHttpClientConfiguration(timeout, numberOfRetries, backOffFactor, retryInterval, skipSslCertVerification, httpStatusCodesToRetry, httpMethodsToRetry, maximumRetryWaitTime, shouldRetryOnTimeout, - httpClientInstance, overrideHttpClientConfigurations); + httpClientInstance, overrideHttpClientConfigurations, proxyConfiguration); } } } diff --git a/src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java b/src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java new file mode 100644 index 00000000..ef9e4f40 --- /dev/null +++ b/src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java @@ -0,0 +1,151 @@ +package io.apimatic.core.configurations.http.client; + +import io.apimatic.coreinterfaces.http.proxy.ProxyConfiguration; + +/** + * Represents a proxy configuration with address, port, and optional authentication credentials. + * This class is an implementation of the {@link ProxyConfiguration} interface. + */ +public class CoreProxyConfiguration implements ProxyConfiguration { + + /** + * The proxy server address (e.g., IP or domain name). + */ + private final String address; + + /** + * The port on which the proxy server is listening. + */ + private final int port; + + /** + * The username for proxy authentication, if required. + */ + private final String username; + + /** + * The password for proxy authentication, if required. + */ + private final String password; + + /** + * Creates a new instance of {@code CoreProxyConfiguration} with the specified address, + * port, and optional authentication credentials. + * + * @param address The proxy server address. + * @param port The proxy server port. + * @param username The username for proxy authentication (can be {@code null}). + * @param password The password for proxy authentication (can be {@code null}). + */ + private CoreProxyConfiguration(String address, int port, String username, String password) { + this.address = address; + this.port = port; + this.username = username; + this.password = password; + } + + @Override + public String getAddress() { + return address; + } + + @Override + public int getPort() { + return port; + } + + @Override + public String getUsername() { + return username; + } + + @Override + public String getPassword() { + return password; + } + + /** + * Creates a new builder initialized with the current configuration's values. + * @return a new {@link Builder} instance + */ + public Builder newBuilder() { + return new Builder() + .address(this.address) + .port(this.port) + .username(this.username) + .password(this.password); + } + + /** + * Returns a string representation of this proxy configuration. + * @return string representation of this object + */ + @Override + public String toString() { + return "CoreProxyConfiguration [" + + "address=" + address + + ", port=" + port + + ", username=" + (username != null ? username : "null") + + ", password=" + (password != null ? password : "null") + + "]"; + } + + /** + * Builder class for constructing {@link CoreProxyConfiguration} instances. + */ + public static class Builder { + + private String address; + private int port; + private String username; + private String password; + + /** + * Sets the proxy server address. + * @param address the address to set + * @return the builder instance + */ + public Builder address(String address) { + this.address = address; + return this; + } + + /** + * Sets the proxy server port. + * @param port the port to set + * @return the builder instance + */ + public Builder port(int port) { + this.port = port; + return this; + } + + /** + * Sets the proxy username for authentication. + * @param username the username to set + * @return the builder instance + */ + public Builder username(String username) { + this.username = username; + return this; + } + + /** + * Sets the proxy password for authentication. + * @param password the password to set + * @return the builder instance + */ + public Builder password(String password) { + this.password = password; + return this; + } + + /** + * Builds a new {@link CoreProxyConfiguration} instance using the set fields. + * @return the built {@link CoreProxyConfiguration} + */ + public CoreProxyConfiguration build() { + return new CoreProxyConfiguration(address, port, username, password); + } + } +} \ No newline at end of file From 25c4abb275568a6bd6173b3d5eb609beb6ca2c07 Mon Sep 17 00:00:00 2001 From: Hamza Mahmood Date: Thu, 7 Aug 2025 16:25:20 +0500 Subject: [PATCH 2/6] Update README.md --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0ed35098..d861f5bc 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Core lib's Maven group ID is `io.apimatic`, and its artifact ID is `core`. | [`Or`](./src/main/java/io/apimatic/core/authentication/multiple/Or.java) | A class to hold the algorithm for `Or` combination of auth schemes | | [`Single`](./src/main/java/io/apimatic/core/authentication/multiple/Single.java) | A class to hold the logic for single auth scheme, it is used as leaf node for auth combination or it could be used directly to apply one auth only to the http request | | [`CoreHttpClientConfiguration`](./src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java) | To hold HTTP Client Configuration | +| [`CoreProxyConfiguration`](./src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java) | To hold the Proxy configuration for the underlying HTTP client instance. | | [`EndpointConfiguration`](./src/main/java/io/apimatic/core/configurations/http/request/EndpointConfiguration.java) | The configuration for an endpoint | | [`AsyncExecutor`](./src/main/java/io/apimatic/core/request/async/AsyncExecutor.java) | Executor service for asynchronous HTTP endpoint call | | [`OptionalNullable`](./src/main/java/io/apimatic/core/types/OptionalNullable.java) | Class to encapsulate fields which are Optional as well as Nullable | @@ -56,12 +57,12 @@ Core lib's Maven group ID is `io.apimatic`, and its artifact ID is `core`. | [`CoreApiException`](./src/main/java/io/apimatic/core/types/CoreApiException.java) | This is the base class for all exceptions that represent an error response from the server | | [`MultipartFileWrapper`](./src/main/java/io/apimatic/core/types/http/request/MultipartFileWrapper.java) | To wrap file and headers to be sent as part of a multipart request | | [`MultipartWrapper`](./src/main/java/io/apimatic/core/types/http/request/MultipartWrapper.java) | To wrap byteArray and headers to be sent as part of a multipart request | -| [`PaginatedData`](./src/main/java/io/apimatic/core/types/pagination/PaginatedData.java) | To provide pagination functionality for both synchronous and asynchronous pagination types | -| [`PageWrapper`](./src/main/java/io/apimatic/core/types/pagination/PageWrapper.java) | To wrap a single page along with its items and meta-data in the paginated data | -| [`CursorPagination`](./src/main/java/io/apimatic/core/types/pagination/CursorPagination.java) | Provides cursor based pagination strategy | -| [`LinkPagination`](./src/main/java/io/apimatic/core/types/pagination/LinkPagination.java) | Provides link based pagination strategy | -| [`OffsetPagination`](./src/main/java/io/apimatic/core/types/pagination/OffsetPagination.java) | Provides offset based pagination strategy | -| [`PagePagination`](./src/main/java/io/apimatic/core/types/pagination/PagePagination.java) | Provides page based pagination strategy | +| [`PaginatedData`](./src/main/java/io/apimatic/core/types/pagination/PaginatedData.java) | To provide pagination functionality for both synchronous and asynchronous pagination types | +| [`PageWrapper`](./src/main/java/io/apimatic/core/types/pagination/PageWrapper.java) | To wrap a single page along with its items and meta-data in the paginated data | +| [`CursorPagination`](./src/main/java/io/apimatic/core/types/pagination/CursorPagination.java) | Provides cursor based pagination strategy | +| [`LinkPagination`](./src/main/java/io/apimatic/core/types/pagination/LinkPagination.java) | Provides link based pagination strategy | +| [`OffsetPagination`](./src/main/java/io/apimatic/core/types/pagination/OffsetPagination.java) | Provides offset based pagination strategy | +| [`PagePagination`](./src/main/java/io/apimatic/core/types/pagination/PagePagination.java) | Provides page based pagination strategy | | [`CoreHelper`](./src/main/java/io/apimatic/core/utilities/CoreHelper.java) | This is a Helper class with commonly used utilities for the SDK | | [`DateHelper`](./src/main/java/io/apimatic/core/utilities/DateHelper.java) | This is a utility class for LocalDate operations | | [`LocalDateTimeHelper`](./src/main/java/io/apimatic/core/utilities/LocalDateTimeHelper.java) | This is a utility class for LocalDateTime operations | @@ -72,7 +73,7 @@ Core lib's Maven group ID is `io.apimatic`, and its artifact ID is `core`. | [`CoreJsonObject`](./src/main/java/io/apimatic/core/utilities/CoreJsonObject.java) | Wrapper class for JSON object | | [`CoreJsonValue`](./src/main/java/io/apimatic/core/utilities/CoreJsonValue.java) | Wrapper class for JSON value | | [`TestHelper`](./src/main/java/io/apimatic/core/utilities/TestHelper.java) | Contains utility methods for comparing objects, arrays and files | -| [`AdditionalProperties`](./src/main/java/io/apimatic/core/types/AdditionalProperties.java) | A generic class for managing additional properties in a model. | +| [`AdditionalProperties`](./src/main/java/io/apimatic/core/types/AdditionalProperties.java) | A generic class for managing additional properties in a model. | | [`ConversionHelper`](./src/main/java/io/apimatic/core/utilities/ConversionHelper.java) | A Helper class for the coversion of type (provided as function) for all structures (array, map, array of map, n-dimensional arrays etc) supported in the SDK. | ## Interfaces From 9ebdfc1a32ee5860fadf64252603c32d6fbc83cc Mon Sep 17 00:00:00 2001 From: Hamza Mahmood Date: Fri, 8 Aug 2025 17:09:12 +0500 Subject: [PATCH 3/6] fix: npe on client new builder - rename proxy to proxySetting - add required parameters address & port in builder ctor --- .../http/client/CoreProxyConfiguration.java | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java b/src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java index ef9e4f40..83adc7e6 100644 --- a/src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java +++ b/src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java @@ -69,9 +69,7 @@ public String getPassword() { * @return a new {@link Builder} instance */ public Builder newBuilder() { - return new Builder() - .address(this.address) - .port(this.port) + return new Builder(this.address, this.port) .username(this.username) .password(this.password); } @@ -95,29 +93,14 @@ public String toString() { */ public static class Builder { - private String address; - private int port; + private final String address; + private final int port; private String username; private String password; - /** - * Sets the proxy server address. - * @param address the address to set - * @return the builder instance - */ - public Builder address(String address) { + public Builder(String address, int port) { this.address = address; - return this; - } - - /** - * Sets the proxy server port. - * @param port the port to set - * @return the builder instance - */ - public Builder port(int port) { this.port = port; - return this; } /** From e6fa057720149f9fdf958c5a41c2d25fcc691ef6 Mon Sep 17 00:00:00 2001 From: Hamza Mahmood Date: Mon, 11 Aug 2025 18:46:28 +0500 Subject: [PATCH 4/6] fix: lint errors --- .../client/CoreHttpClientConfiguration.java | 7 ++--- .../http/client/CoreProxyConfiguration.java | 27 ++++++++++++------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java b/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java index d988e403..1179b3ea 100644 --- a/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java +++ b/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java @@ -141,13 +141,15 @@ public final class CoreHttpClientConfiguration implements ClientConfiguration { * @param shouldRetryOnTimeout * @param httpClientInstance * @param overrideHttpClientConfigurations + * @param proxyConfiguration */ private CoreHttpClientConfiguration(final long timeout, final int numberOfRetries, final int backOffFactor, final long retryInterval, final boolean skipSslCertVerification, final Set httpStatusCodesToRetry, final Set httpMethodsToRetry, final long maximumRetryWaitTime, final boolean shouldRetryOnTimeout, final okhttp3.OkHttpClient httpClientInstance, - final boolean overrideHttpClientConfigurations, final ProxyConfiguration proxyConfiguration) { + final boolean overrideHttpClientConfigurations, + final ProxyConfiguration proxyConfiguration) { this.timeout = timeout; this.numberOfRetries = numberOfRetries; this.backOffFactor = backOffFactor; @@ -254,8 +256,7 @@ public boolean skipSslCertVerification() { /** * Returns the proxy configuration used to route requests through a proxy server. * This includes the proxy address, port, and any authentication credentials. - * - * @return the {@link ProxyConfiguration}, or {@code null} if no proxy is configured + * @return the {@link ProxyConfiguration} */ public ProxyConfiguration getProxyConfiguration() { return proxyConfiguration; } diff --git a/src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java b/src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java index 83adc7e6..e1c719d9 100644 --- a/src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java +++ b/src/main/java/io/apimatic/core/configurations/http/client/CoreProxyConfiguration.java @@ -6,7 +6,7 @@ * Represents a proxy configuration with address, port, and optional authentication credentials. * This class is an implementation of the {@link ProxyConfiguration} interface. */ -public class CoreProxyConfiguration implements ProxyConfiguration { +public final class CoreProxyConfiguration implements ProxyConfiguration { /** * The proxy server address (e.g., IP or domain name). @@ -37,7 +37,8 @@ public class CoreProxyConfiguration implements ProxyConfiguration { * @param username The username for proxy authentication (can be {@code null}). * @param password The password for proxy authentication (can be {@code null}). */ - private CoreProxyConfiguration(String address, int port, String username, String password) { + private CoreProxyConfiguration(final String address, final int port, + final String username, final String password) { this.address = address; this.port = port; this.username = username; @@ -80,12 +81,12 @@ public Builder newBuilder() { */ @Override public String toString() { - return "CoreProxyConfiguration [" + - "address=" + address + - ", port=" + port + - ", username=" + (username != null ? username : "null") + - ", password=" + (password != null ? password : "null") + - "]"; + return "CoreProxyConfiguration [" + + "address=" + address + + ", port=" + port + + ", username=" + username + + ", password=" + password + + "]"; } /** @@ -98,7 +99,13 @@ public static class Builder { private String username; private String password; - public Builder(String address, int port) { + /** + * Creates a new {@code Builder} instance with the specified proxy server details. + * + * @param address the hostname or IP address of the proxy server + * @param port the port number of the proxy server + */ + public Builder(final String address, final int port) { this.address = address; this.port = port; } @@ -131,4 +138,4 @@ public CoreProxyConfiguration build() { return new CoreProxyConfiguration(address, port, username, password); } } -} \ No newline at end of file +} From 3baade1499d01fe22d55d00d6a388250a182d2e3 Mon Sep 17 00:00:00 2001 From: Hamza Mahmood Date: Tue, 12 Aug 2025 11:58:04 +0500 Subject: [PATCH 5/6] Update CoreHttpClientConfiguration.java --- .../http/client/CoreHttpClientConfiguration.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java b/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java index 1179b3ea..c6d47684 100644 --- a/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java +++ b/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java @@ -258,7 +258,9 @@ public boolean skipSslCertVerification() { * This includes the proxy address, port, and any authentication credentials. * @return the {@link ProxyConfiguration} */ - public ProxyConfiguration getProxyConfiguration() { return proxyConfiguration; } + public ProxyConfiguration getProxyConfiguration() { + return proxyConfiguration; + } /** * Converts this HttpClientConfiguration into string format. From 16ef119ebeb16baee1f08d6d2458ef822a9076a0 Mon Sep 17 00:00:00 2001 From: Hamza Mahmood Date: Tue, 12 Aug 2025 14:29:52 +0500 Subject: [PATCH 6/6] fix: CoreHttpClientConfiguration toString() proxyConfiguration name --- .../configurations/http/client/CoreHttpClientConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java b/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java index c6d47684..7577c041 100644 --- a/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java +++ b/src/main/java/io/apimatic/core/configurations/http/client/CoreHttpClientConfiguration.java @@ -275,7 +275,7 @@ public String toString() { + maximumRetryWaitTime + ", shouldRetryOnTimeout=" + shouldRetryOnTimeout + ", httpClientInstance=" + httpClientInstance + ", overrideHttpClientConfigurations=" + overrideHttpClientConfigurations - + ", proxy=" + proxyConfiguration + "]"; + + ", proxyConfiguration=" + proxyConfiguration + "]"; } /**