From 4f46edde663d40fb9d58fbe997e464de59be62ab Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Fri, 13 Sep 2024 12:30:16 -0400 Subject: [PATCH 1/5] make XrplClient timeouts configurable --- .../org/xrpl/xrpl4j/client/JsonRpcClient.java | 9 +++++++ .../org/xrpl/xrpl4j/client/XrplClient.java | 27 +++++++++++++++++++ .../xrpl/xrpl4j/client/XrplClientTest.java | 15 +++++++++++ 3 files changed, 51 insertions(+) diff --git a/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/JsonRpcClient.java b/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/JsonRpcClient.java index 75a25ddd5..c6ae03d0a 100644 --- a/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/JsonRpcClient.java +++ b/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/JsonRpcClient.java @@ -27,6 +27,7 @@ import com.google.common.annotations.Beta; import feign.Feign; import feign.Headers; +import feign.Request.Options; import feign.RequestLine; import feign.jackson.JacksonDecoder; import feign.jackson.JacksonEncoder; @@ -78,11 +79,19 @@ public interface JsonRpcClient { static JsonRpcClient construct(final HttpUrl rippledUrl) { Objects.requireNonNull(rippledUrl); + return construct(rippledUrl, new Options()); + } + + static JsonRpcClient construct(HttpUrl rippledUrl, Options options) { + Objects.requireNonNull(rippledUrl); + Objects.requireNonNull(options); + return Feign.builder() .encoder(new JacksonEncoder(objectMapper)) // rate limiting will return a 503 status that can be retried .errorDecoder(new RetryStatusDecoder(RETRY_INTERVAL, SERVICE_UNAVAILABLE_STATUS)) .decode404() + .options(options) .decoder(new OptionalDecoder(new JacksonDecoder(objectMapper))) .target(JsonRpcClient.class, rippledUrl.toString()); } diff --git a/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java b/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java index bf744ea25..a4e384c40 100644 --- a/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java +++ b/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java @@ -28,6 +28,8 @@ import com.google.common.collect.Range; import com.google.common.primitives.UnsignedInteger; import com.google.common.primitives.UnsignedLong; +import feign.Request; +import feign.Request.Options; import okhttp3.HttpUrl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -101,6 +103,7 @@ import java.util.Objects; import java.util.Optional; +import java.util.concurrent.TimeUnit; /** *

A client which wraps a rippled network client and is responsible for higher order functionality such as signing @@ -127,6 +130,30 @@ public XrplClient(final HttpUrl rippledUrl) { this(JsonRpcClient.construct(rippledUrl)); } + /** + * Public constructor that allows for configuration of connect and read timeouts. + * + * @param rippledUrl The {@link HttpUrl} of the node to connect to. + * @param connectTimeout A {@code long} indicating the client's connect timeout. + * @param connectTimeoutUnit The {@link TimeUnit} that {@code connectTimeout} is denominated in. + * @param readTimeout A {@code long} indicating the client's read timeout. + * @param readTimeoutUnit The {@link TimeUnit} that {@code readTimeout} is denominated in. + */ + public XrplClient( + HttpUrl rippledUrl, + long connectTimeout, + TimeUnit connectTimeoutUnit, + long readTimeout, + TimeUnit readTimeoutUnit + ) { + this( + JsonRpcClient.construct( + rippledUrl, + new Options(connectTimeout, connectTimeoutUnit, readTimeout, readTimeoutUnit, true) + ) + ); + } + /** * Required-args constructor (exists for testing purposes only). * diff --git a/xrpl4j-client/src/test/java/org/xrpl/xrpl4j/client/XrplClientTest.java b/xrpl4j-client/src/test/java/org/xrpl/xrpl4j/client/XrplClientTest.java index 32c4e05be..bd49b068b 100644 --- a/xrpl4j-client/src/test/java/org/xrpl/xrpl4j/client/XrplClientTest.java +++ b/xrpl4j-client/src/test/java/org/xrpl/xrpl4j/client/XrplClientTest.java @@ -125,6 +125,7 @@ import java.time.ZonedDateTime; import java.util.Optional; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; /** @@ -599,6 +600,20 @@ public void getXrplClientTest() { assertThat(new XrplClient(rippledUrl) instanceof JsonRpcClient).isFalse(); } + @Test + void createXrplClientWithTimeouts() { + HttpUrl rippledUrl = HttpUrl.parse("https://s.altnet.rippletest.net:51234"); + XrplClient client = new XrplClient( + rippledUrl, + 1, + TimeUnit.SECONDS, + 2, + TimeUnit.MINUTES + ); + + assertThat(client).isInstanceOf(XrplClient.class); + } + @Test public void submitSingleSignedTransaction() { BcSignatureService bcSignatureService = new BcSignatureService(); From 912138ae2451ad52ce42282b0e8ac6597c3f23b3 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Fri, 13 Sep 2024 12:35:26 -0400 Subject: [PATCH 2/5] javadoc --- .../java/org/xrpl/xrpl4j/client/JsonRpcClient.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/JsonRpcClient.java b/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/JsonRpcClient.java index c6ae03d0a..0c8a3ad4e 100644 --- a/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/JsonRpcClient.java +++ b/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/JsonRpcClient.java @@ -72,7 +72,7 @@ public interface JsonRpcClient { /** * Constructs a new client for the given url. * - * @param rippledUrl url for the faucet server. + * @param rippledUrl The {@link HttpUrl} of the node to connect to. * * @return A {@link JsonRpcClient} that can make request to {@code rippledUrl} */ @@ -82,6 +82,14 @@ static JsonRpcClient construct(final HttpUrl rippledUrl) { return construct(rippledUrl, new Options()); } + /** + * Constructs a new client for the given url with the given client options. + * + * @param rippledUrl The {@link HttpUrl} of the node to connect to. + * @param options An {@link Options}. + * + * @return A {@link JsonRpcClient}. + */ static JsonRpcClient construct(HttpUrl rippledUrl, Options options) { Objects.requireNonNull(rippledUrl); Objects.requireNonNull(options); From 17208324a5fe399c902eae71f78d7d65b32a1609 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Mon, 16 Sep 2024 09:02:08 -0400 Subject: [PATCH 3/5] add Duration overload --- .../org/xrpl/xrpl4j/client/XrplClient.java | 21 +++++++++++++++++++ .../xrpl/xrpl4j/client/XrplClientTest.java | 13 ++++++++++++ 2 files changed, 34 insertions(+) diff --git a/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java b/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java index a4e384c40..8f733274c 100644 --- a/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java +++ b/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java @@ -101,6 +101,7 @@ import org.xrpl.xrpl4j.model.transactions.Transaction; import org.xrpl.xrpl4j.model.transactions.TransactionMetadata; +import java.time.Duration; import java.util.Objects; import java.util.Optional; import java.util.concurrent.TimeUnit; @@ -154,6 +155,26 @@ public XrplClient( ); } + /** + * Public constructor that allows for configuration of connect and read timeouts. + * + * @param rippledUrl The {@link HttpUrl} of the node to connect to. + * @param connectTimeout A {@link Duration} indicating the client's connect timeout. + * @param readTimeout A {@link Duration} indicating the client's read timeout. + */ + public XrplClient( + HttpUrl rippledUrl, + Duration connectTimeout, + Duration readTimeout + ) { + this( + JsonRpcClient.construct( + rippledUrl, + new Options(connectTimeout.toNanos(), TimeUnit.NANOSECONDS, readTimeout.toNanos(), TimeUnit.NANOSECONDS, true) + ) + ); + } + /** * Required-args constructor (exists for testing purposes only). * diff --git a/xrpl4j-client/src/test/java/org/xrpl/xrpl4j/client/XrplClientTest.java b/xrpl4j-client/src/test/java/org/xrpl/xrpl4j/client/XrplClientTest.java index bd49b068b..3dc744e47 100644 --- a/xrpl4j-client/src/test/java/org/xrpl/xrpl4j/client/XrplClientTest.java +++ b/xrpl4j-client/src/test/java/org/xrpl/xrpl4j/client/XrplClientTest.java @@ -122,6 +122,7 @@ import org.xrpl.xrpl4j.model.transactions.XrpCurrencyAmount; import java.math.BigDecimal; +import java.time.Duration; import java.time.ZonedDateTime; import java.util.Optional; import java.util.Set; @@ -614,6 +615,18 @@ void createXrplClientWithTimeouts() { assertThat(client).isInstanceOf(XrplClient.class); } + @Test + void createXrplClientWithDurationTimeouts() { + HttpUrl rippledUrl = HttpUrl.parse("https://s.altnet.rippletest.net:51234"); + XrplClient client = new XrplClient( + rippledUrl, + Duration.ofSeconds(1), + Duration.ofMinutes(2) + ); + + assertThat(client).isInstanceOf(XrplClient.class); + } + @Test public void submitSingleSignedTransaction() { BcSignatureService bcSignatureService = new BcSignatureService(); From d213a6456c9026adbdb66b38e73ab3636910063a Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Mon, 16 Sep 2024 13:12:20 -0400 Subject: [PATCH 4/5] use millis instead of nanos --- .../org/xrpl/xrpl4j/client/XrplClient.java | 31 ++++--------------- .../xrpl/xrpl4j/client/XrplClientTest.java | 14 --------- 2 files changed, 6 insertions(+), 39 deletions(-) diff --git a/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java b/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java index 8f733274c..7a43b423b 100644 --- a/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java +++ b/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java @@ -133,30 +133,10 @@ public XrplClient(final HttpUrl rippledUrl) { /** * Public constructor that allows for configuration of connect and read timeouts. - * - * @param rippledUrl The {@link HttpUrl} of the node to connect to. - * @param connectTimeout A {@code long} indicating the client's connect timeout. - * @param connectTimeoutUnit The {@link TimeUnit} that {@code connectTimeout} is denominated in. - * @param readTimeout A {@code long} indicating the client's read timeout. - * @param readTimeoutUnit The {@link TimeUnit} that {@code readTimeout} is denominated in. - */ - public XrplClient( - HttpUrl rippledUrl, - long connectTimeout, - TimeUnit connectTimeoutUnit, - long readTimeout, - TimeUnit readTimeoutUnit - ) { - this( - JsonRpcClient.construct( - rippledUrl, - new Options(connectTimeout, connectTimeoutUnit, readTimeout, readTimeoutUnit, true) - ) - ); - } - - /** - * Public constructor that allows for configuration of connect and read timeouts. + *

+ * Note that any {@link Duration} passed in that is less than one millisecond will result in the actual timeout being + * zero milliseconds. It is therefore advised to never set {@code connectTimeout} or {@code readTimeout} to a + * {@link Duration} less than one millisecond. * * @param rippledUrl The {@link HttpUrl} of the node to connect to. * @param connectTimeout A {@link Duration} indicating the client's connect timeout. @@ -170,7 +150,8 @@ public XrplClient( this( JsonRpcClient.construct( rippledUrl, - new Options(connectTimeout.toNanos(), TimeUnit.NANOSECONDS, readTimeout.toNanos(), TimeUnit.NANOSECONDS, true) + new Options(connectTimeout.toMillis(), TimeUnit.MILLISECONDS, readTimeout.toMillis(), TimeUnit.MILLISECONDS, + true) ) ); } diff --git a/xrpl4j-client/src/test/java/org/xrpl/xrpl4j/client/XrplClientTest.java b/xrpl4j-client/src/test/java/org/xrpl/xrpl4j/client/XrplClientTest.java index 3dc744e47..2aa720346 100644 --- a/xrpl4j-client/src/test/java/org/xrpl/xrpl4j/client/XrplClientTest.java +++ b/xrpl4j-client/src/test/java/org/xrpl/xrpl4j/client/XrplClientTest.java @@ -601,20 +601,6 @@ public void getXrplClientTest() { assertThat(new XrplClient(rippledUrl) instanceof JsonRpcClient).isFalse(); } - @Test - void createXrplClientWithTimeouts() { - HttpUrl rippledUrl = HttpUrl.parse("https://s.altnet.rippletest.net:51234"); - XrplClient client = new XrplClient( - rippledUrl, - 1, - TimeUnit.SECONDS, - 2, - TimeUnit.MINUTES - ); - - assertThat(client).isInstanceOf(XrplClient.class); - } - @Test void createXrplClientWithDurationTimeouts() { HttpUrl rippledUrl = HttpUrl.parse("https://s.altnet.rippletest.net:51234"); From 01c18453f0c3c6f8ff9708626d4222d69eb6299f Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Mon, 16 Sep 2024 14:08:01 -0400 Subject: [PATCH 5/5] fix javadoc --- .../src/main/java/org/xrpl/xrpl4j/client/XrplClient.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java b/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java index 7a43b423b..26ef8179a 100644 --- a/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java +++ b/xrpl4j-client/src/main/java/org/xrpl/xrpl4j/client/XrplClient.java @@ -133,9 +133,9 @@ public XrplClient(final HttpUrl rippledUrl) { /** * Public constructor that allows for configuration of connect and read timeouts. - *

- * Note that any {@link Duration} passed in that is less than one millisecond will result in the actual timeout being - * zero milliseconds. It is therefore advised to never set {@code connectTimeout} or {@code readTimeout} to a + * + *

Note that any {@link Duration} passed in that is less than one millisecond will result in the actual timeout + * being zero milliseconds. It is therefore advised to never set {@code connectTimeout} or {@code readTimeout} to a * {@link Duration} less than one millisecond. * * @param rippledUrl The {@link HttpUrl} of the node to connect to.