Skip to content

Commit 2c67e17

Browse files
cavazosjoejcavazos
authored andcommitted
#496: Update JDK version to 11. Remove okhttp dependency and replace usages with JDK 11 HttpClient. Import Apache CXF for server-side-event (SSE) handling.
1 parent 6104e7c commit 2c67e17

File tree

62 files changed

+1248
-723
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1248
-723
lines changed

build.gradle.kts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ group = "network.lightsail"
1414
version = "1.0.0"
1515

1616
java {
17-
sourceCompatibility = JavaVersion.VERSION_1_8
18-
targetCompatibility = JavaVersion.VERSION_1_8
17+
sourceCompatibility = JavaVersion.VERSION_11
18+
targetCompatibility = JavaVersion.VERSION_11
1919
}
2020

2121
spotless {
@@ -33,12 +33,15 @@ repositories {
3333
dependencies {
3434
val okhttpVersion = "4.12.0"
3535

36-
implementation("com.squareup.okhttp3:okhttp:${okhttpVersion}")
37-
implementation("com.squareup.okhttp3:okhttp-sse:${okhttpVersion}")
3836
implementation("com.moandjiezana.toml:toml4j:0.7.2")
3937
implementation("com.google.code.gson:gson:2.11.0")
4038
implementation("org.bouncycastle:bcprov-jdk18on:1.79")
4139
implementation("commons-codec:commons-codec:1.17.1")
40+
implementation("org.jetbrains:annotations:26.0.2")
41+
42+
// Dependencies for SSE.
43+
implementation("org.apache.cxf:cxf-rt-rs-sse:4.1.0")
44+
implementation("org.apache.cxf:cxf-rt-rs-client:4.1.0")
4245

4346
testImplementation("org.mockito:mockito-core:5.14.2")
4447
testImplementation("com.squareup.okhttp3:mockwebserver:${okhttpVersion}")

src/main/java/org/stellar/sdk/Server.java

Lines changed: 102 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,37 @@
44
import java.io.Closeable;
55
import java.io.IOException;
66
import java.net.SocketTimeoutException;
7+
import java.net.URI;
8+
import java.net.URISyntaxException;
9+
import java.time.temporal.ChronoUnit;
710
import java.util.HashSet;
11+
import java.util.Map;
812
import java.util.Set;
9-
import java.util.concurrent.TimeUnit;
1013
import lombok.Getter;
1114
import lombok.Setter;
12-
import okhttp3.*;
13-
import okhttp3.Response;
14-
import org.stellar.sdk.exception.AccountRequiresMemoException;
15-
import org.stellar.sdk.exception.BadRequestException;
16-
import org.stellar.sdk.exception.ConnectionErrorException;
17-
import org.stellar.sdk.exception.RequestTimeoutException;
18-
import org.stellar.sdk.exception.TooManyRequestsException;
19-
import org.stellar.sdk.operations.AccountMergeOperation;
20-
import org.stellar.sdk.operations.Operation;
21-
import org.stellar.sdk.operations.PathPaymentStrictReceiveOperation;
22-
import org.stellar.sdk.operations.PathPaymentStrictSendOperation;
23-
import org.stellar.sdk.operations.PaymentOperation;
15+
import org.stellar.sdk.exception.*;
16+
import org.stellar.sdk.http.IHttpClient;
17+
import org.stellar.sdk.http.Jdk11HttpClient;
18+
import org.stellar.sdk.http.PostRequest;
19+
import org.stellar.sdk.http.StringResponse;
20+
import org.stellar.sdk.http.sse.ISseClient;
21+
import org.stellar.sdk.operations.*;
2422
import org.stellar.sdk.requests.*;
25-
import org.stellar.sdk.responses.*;
23+
import org.stellar.sdk.responses.AccountResponse;
24+
import org.stellar.sdk.responses.FeeStatsResponse;
25+
import org.stellar.sdk.responses.SubmitTransactionAsyncResponse;
26+
import org.stellar.sdk.responses.TransactionResponse;
2627
import org.stellar.sdk.xdr.CryptoKeyType;
2728

2829
/** Main class used to connect to Horizon server. */
2930
public class Server implements Closeable {
30-
private final HttpUrl serverURI;
31-
@Getter @Setter private OkHttpClient httpClient;
31+
private final URI serverURI;
32+
@Getter @Setter private IHttpClient httpClient;
3233

3334
/** submitHttpClient is used only for submitting transactions. The read timeout is longer. */
34-
@Getter @Setter private OkHttpClient submitHttpClient;
35+
@Getter @Setter private IHttpClient submitHttpClient;
36+
37+
@Getter @Setter private ISseClient sseClient;
3538

3639
/**
3740
* HORIZON_SUBMIT_TIMEOUT is a time in seconds after Horizon sends a timeout response after
@@ -54,31 +57,43 @@ public class Server implements Closeable {
5457
* @param uri The URI of the Horizon server.
5558
*/
5659
public Server(String uri) {
57-
this(
58-
uri,
59-
new OkHttpClient.Builder()
60-
.addInterceptor(new ClientIdentificationInterceptor())
61-
.connectTimeout(10, TimeUnit.SECONDS)
62-
.readTimeout(30, TimeUnit.SECONDS)
63-
.retryOnConnectionFailure(true)
64-
.build(),
65-
new OkHttpClient.Builder()
66-
.addInterceptor(new ClientIdentificationInterceptor())
67-
.connectTimeout(10, TimeUnit.SECONDS)
68-
.readTimeout(HORIZON_SUBMIT_TIMEOUT + 5, TimeUnit.SECONDS)
69-
.retryOnConnectionFailure(true)
70-
.build());
60+
this(uri, normalHttpClient(), submitHttpClient());
61+
}
62+
63+
private static IHttpClient normalHttpClient() {
64+
return new Jdk11HttpClient.Builder()
65+
.withDefaultHeader("X-Client-Name", "java-stellar-sdk")
66+
.withDefaultHeader("X-Client-Version", Util.getSdkVersion())
67+
.withConnectTimeout(10, ChronoUnit.SECONDS)
68+
.withReadTimeout(30, ChronoUnit.SECONDS)
69+
.withRetryOnConnectionFailure(true)
70+
.build();
71+
}
72+
73+
private static IHttpClient submitHttpClient() {
74+
return new Jdk11HttpClient.Builder()
75+
.withDefaultHeader("X-Client-Name", "java-stellar-sdk")
76+
.withDefaultHeader("X-Client-Version", Util.getSdkVersion())
77+
.withConnectTimeout(10, ChronoUnit.SECONDS)
78+
.withReadTimeout(HORIZON_SUBMIT_TIMEOUT + 5, ChronoUnit.SECONDS)
79+
.withRetryOnConnectionFailure(true)
80+
.build();
7181
}
7282

7383
/**
7484
* Constructs a new Server object with custom HTTP clients.
7585
*
7686
* @param serverURI The URI of the Horizon server.
77-
* @param httpClient The OkHttpClient to use for general requests.
78-
* @param submitHttpClient The OkHttpClient to use for submitting transactions.
87+
* @param httpClient The IHttpClient to use for general requests.
88+
* @param submitHttpClient The IHttpClient to use for submitting transactions.
7989
*/
80-
public Server(String serverURI, OkHttpClient httpClient, OkHttpClient submitHttpClient) {
81-
this.serverURI = HttpUrl.parse(serverURI);
90+
public Server(String serverURI, IHttpClient httpClient, IHttpClient submitHttpClient) {
91+
try {
92+
this.serverURI = new URI(serverURI);
93+
} catch (URISyntaxException e) {
94+
throw new RuntimeException("Invalid URI: " + serverURI);
95+
}
96+
8297
this.httpClient = httpClient;
8398
this.submitHttpClient = submitHttpClient;
8499
}
@@ -114,77 +129,77 @@ public TransactionBuilderAccount loadAccount(String address) {
114129
* @return {@link RootRequestBuilder} instance.
115130
*/
116131
public RootRequestBuilder root() {
117-
return new RootRequestBuilder(httpClient, serverURI);
132+
return new RootRequestBuilder(httpClient, sseClient, serverURI);
118133
}
119134

120135
/**
121136
* @return {@link AccountsRequestBuilder} instance.
122137
*/
123138
public AccountsRequestBuilder accounts() {
124-
return new AccountsRequestBuilder(httpClient, serverURI);
139+
return new AccountsRequestBuilder(httpClient, sseClient, serverURI);
125140
}
126141

127142
/**
128143
* @return {@link AssetsRequestBuilder} instance.
129144
*/
130145
public AssetsRequestBuilder assets() {
131-
return new AssetsRequestBuilder(httpClient, serverURI);
146+
return new AssetsRequestBuilder(httpClient, sseClient, serverURI);
132147
}
133148

134149
/**
135150
* @return {@link ClaimableBalancesRequestBuilder} instance.
136151
*/
137152
public ClaimableBalancesRequestBuilder claimableBalances() {
138-
return new ClaimableBalancesRequestBuilder(httpClient, serverURI);
153+
return new ClaimableBalancesRequestBuilder(httpClient, sseClient, serverURI);
139154
}
140155

141156
/**
142157
* @return {@link EffectsRequestBuilder} instance.
143158
*/
144159
public EffectsRequestBuilder effects() {
145-
return new EffectsRequestBuilder(httpClient, serverURI);
160+
return new EffectsRequestBuilder(httpClient, sseClient, serverURI);
146161
}
147162

148163
/**
149164
* @return {@link LedgersRequestBuilder} instance.
150165
*/
151166
public LedgersRequestBuilder ledgers() {
152-
return new LedgersRequestBuilder(httpClient, serverURI);
167+
return new LedgersRequestBuilder(httpClient, sseClient, serverURI);
153168
}
154169

155170
/**
156171
* @return {@link OffersRequestBuilder} instance.
157172
*/
158173
public OffersRequestBuilder offers() {
159-
return new OffersRequestBuilder(httpClient, serverURI);
174+
return new OffersRequestBuilder(httpClient, sseClient, serverURI);
160175
}
161176

162177
/**
163178
* @return {@link OperationsRequestBuilder} instance.
164179
*/
165180
public OperationsRequestBuilder operations() {
166-
return new OperationsRequestBuilder(httpClient, serverURI);
181+
return new OperationsRequestBuilder(httpClient, sseClient, serverURI);
167182
}
168183

169184
/**
170185
* @return {@link FeeStatsResponse} instance.
171186
*/
172187
public FeeStatsRequestBuilder feeStats() {
173-
return new FeeStatsRequestBuilder(httpClient, serverURI);
188+
return new FeeStatsRequestBuilder(httpClient, sseClient, serverURI);
174189
}
175190

176191
/**
177192
* @return {@link OrderBookRequestBuilder} instance.
178193
*/
179194
public OrderBookRequestBuilder orderBook() {
180-
return new OrderBookRequestBuilder(httpClient, serverURI);
195+
return new OrderBookRequestBuilder(httpClient, sseClient, serverURI);
181196
}
182197

183198
/**
184199
* @return {@link TradesRequestBuilder} instance.
185200
*/
186201
public TradesRequestBuilder trades() {
187-
return new TradesRequestBuilder(httpClient, serverURI);
202+
return new TradesRequestBuilder(httpClient, sseClient, serverURI);
188203
}
189204

190205
/**
@@ -198,42 +213,50 @@ public TradeAggregationsRequestBuilder tradeAggregations(
198213
long resolution,
199214
long offset) {
200215
return new TradeAggregationsRequestBuilder(
201-
httpClient, serverURI, baseAsset, counterAsset, startTime, endTime, resolution, offset);
216+
httpClient,
217+
sseClient,
218+
serverURI,
219+
baseAsset,
220+
counterAsset,
221+
startTime,
222+
endTime,
223+
resolution,
224+
offset);
202225
}
203226

204227
/**
205228
* @return {@link StrictReceivePathsRequestBuilder} instance.
206229
*/
207230
public StrictReceivePathsRequestBuilder strictReceivePaths() {
208-
return new StrictReceivePathsRequestBuilder(httpClient, serverURI);
231+
return new StrictReceivePathsRequestBuilder(httpClient, sseClient, serverURI);
209232
}
210233

211234
/**
212235
* @return {@link StrictSendPathsRequestBuilder} instance.
213236
*/
214237
public StrictSendPathsRequestBuilder strictSendPaths() {
215-
return new StrictSendPathsRequestBuilder(httpClient, serverURI);
238+
return new StrictSendPathsRequestBuilder(httpClient, sseClient, serverURI);
216239
}
217240

218241
/**
219242
* @return {@link PaymentsRequestBuilder} instance.
220243
*/
221244
public PaymentsRequestBuilder payments() {
222-
return new PaymentsRequestBuilder(httpClient, serverURI);
245+
return new PaymentsRequestBuilder(httpClient, sseClient, serverURI);
223246
}
224247

225248
/**
226249
* @return {@link TransactionsRequestBuilder} instance.
227250
*/
228251
public TransactionsRequestBuilder transactions() {
229-
return new TransactionsRequestBuilder(httpClient, serverURI);
252+
return new TransactionsRequestBuilder(httpClient, sseClient, serverURI);
230253
}
231254

232255
/**
233256
* @return {@link LiquidityPoolsRequestBuilder} instance.
234257
*/
235258
public LiquidityPoolsRequestBuilder liquidityPools() {
236-
return new LiquidityPoolsRequestBuilder(httpClient, serverURI);
259+
return new LiquidityPoolsRequestBuilder(httpClient, sseClient, serverURI);
237260
}
238261

239262
/**
@@ -259,20 +282,22 @@ public LiquidityPoolsRequestBuilder liquidityPools() {
259282
* due to cancellation or connectivity problems, etc.
260283
*/
261284
public TransactionResponse submitTransactionXdr(String transactionXdr) {
262-
HttpUrl transactionsURI = serverURI.newBuilder().addPathSegment("transactions").build();
263-
RequestBody requestBody = new FormBody.Builder().add("tx", transactionXdr).build();
264-
Request submitTransactionRequest =
265-
new Request.Builder().url(transactionsURI).post(requestBody).build();
285+
final var transactionsURI = new UriBuilder(serverURI).addPathSegment("transactions").build();
286+
final var form = Map.of("tx", transactionXdr);
287+
final var post = PostRequest.formBody(transactionsURI, form);
266288
TypeToken<TransactionResponse> type = new TypeToken<TransactionResponse>() {};
267-
268289
ResponseHandler<TransactionResponse> responseHandler = new ResponseHandler<>(type);
269-
Response response;
290+
StringResponse response;
270291
try {
271-
response = this.submitHttpClient.newCall(submitTransactionRequest).execute();
292+
response = this.submitHttpClient.post(post);
272293
} catch (SocketTimeoutException e) {
273294
throw new RequestTimeoutException(e);
274295
} catch (IOException e) {
275-
throw new ConnectionErrorException(e);
296+
if (e.getMessage().contains("request timed out")) {
297+
throw new RequestTimeoutException(e);
298+
} else {
299+
throw new ConnectionErrorException(e);
300+
}
276301
}
277302
return responseHandler.handleResponse(response);
278303
}
@@ -431,17 +456,17 @@ public TransactionResponse submitTransaction(FeeBumpTransaction transaction) {
431456
* a Transaction Asynchronously</a>
432457
*/
433458
public SubmitTransactionAsyncResponse submitTransactionXdrAsync(String transactionXdr) {
434-
HttpUrl transactionsURI = serverURI.newBuilder().addPathSegment("transactions_async").build();
435-
RequestBody requestBody = new FormBody.Builder().add("tx", transactionXdr).build();
436-
Request submitTransactionRequest =
437-
new Request.Builder().url(transactionsURI).post(requestBody).build();
459+
final var transactionsURI =
460+
new UriBuilder(serverURI).addPathSegment("transactions_async").build();
461+
final var form = Map.of("tx", transactionXdr);
462+
final var post = PostRequest.formBody(transactionsURI, form);
438463
TypeToken<SubmitTransactionAsyncResponse> type =
439464
new TypeToken<SubmitTransactionAsyncResponse>() {};
440465

441466
ResponseHandler<SubmitTransactionAsyncResponse> responseHandler = new ResponseHandler<>(type);
442-
Response response;
467+
StringResponse response;
443468
try {
444-
response = this.submitHttpClient.newCall(submitTransactionRequest).execute();
469+
response = this.submitHttpClient.post(post);
445470
} catch (SocketTimeoutException e) {
446471
throw new RequestTimeoutException(e);
447472
} catch (IOException e) {
@@ -653,9 +678,16 @@ private void checkMemoRequired(Transaction transaction) {
653678

654679
@Override
655680
public void close() {
656-
// workaround for https://github.com/square/okhttp/issues/3372
657-
// sometimes, the connection pool keeps running and this can prevent a clean shut down.
658-
this.httpClient.connectionPool().evictAll();
659-
this.submitHttpClient.connectionPool().evictAll();
681+
try {
682+
this.httpClient.close();
683+
} catch (Exception e) {
684+
e.printStackTrace();
685+
}
686+
687+
try {
688+
this.submitHttpClient.close();
689+
} catch (Exception e) {
690+
e.printStackTrace();
691+
}
660692
}
661693
}

0 commit comments

Comments
 (0)