Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Commit 768e22a

Browse files
committed
FABJ-420 Switch to CompletableFutures
Change-Id: Ia8dd4080e9f7ca255a6ff3fd3a2d295755db8aac Signed-off-by: rickr <cr22rc@gmail.com>
1 parent 8bdcbe9 commit 768e22a

File tree

5 files changed

+84
-41
lines changed

5 files changed

+84
-41
lines changed

pom.xml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@
2828
<tag>fabric-sdk-java-1.0</tag>
2929
</scm>
3030
<properties>
31-
<grpc.version>1.18.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
32-
<protobuf.version>3.6.1</protobuf.version>
33-
<bouncycastle.version>1.60</bouncycastle.version>
34-
<httpclient.version>4.5.6</httpclient.version>
31+
<grpc.version>1.19.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
32+
<protobuf.version>3.7.0</protobuf.version>
33+
<bouncycastle.version>1.61</bouncycastle.version>
34+
<httpclient.version>4.5.7</httpclient.version>
3535
<javadoc.version>3.0.1</javadoc.version>
3636
<skipITs>true</skipITs>
3737
<alpn-boot-version>8.1.7.v20160121</alpn-boot-version>
@@ -178,6 +178,17 @@
178178
<scope>test</scope>
179179
</dependency>
180180

181+
<dependency>
182+
<groupId>com.spotify</groupId>
183+
<artifactId>futures-extra</artifactId>
184+
<version>4.1.3</version>
185+
</dependency>
186+
<dependency>
187+
<groupId>com.google.api</groupId>
188+
<artifactId>api-common</artifactId>
189+
<version>1.7.0</version>
190+
<scope>provided</scope><!-- so only used for compilation to work, not needed at runtime -->
191+
</dependency>
181192

182193
<!-- https://mvnrepository.com/artifact/org.glassfish/javax.json -->
183194
<dependency>
@@ -205,7 +216,7 @@
205216
<dependency>
206217
<groupId>org.yaml</groupId>
207218
<artifactId>snakeyaml</artifactId>
208-
<version>1.23</version>
219+
<version>1.24</version>
209220
</dependency>
210221

211222
<!-- https://mvnrepository.com/artifact/org.miracl.milagro.amcl/milagro-crypto-java -->

src/main/java/org/hyperledger/fabric/sdk/EndorserClient.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414

1515
package org.hyperledger.fabric.sdk;
1616

17+
import java.util.concurrent.CompletableFuture;
18+
import java.util.concurrent.CompletionException;
1719
import java.util.concurrent.TimeUnit;
1820

19-
import com.google.common.util.concurrent.ListenableFuture;
21+
import com.spotify.futures.CompletableFuturesExtra;
2022
import io.grpc.ManagedChannel;
2123
import io.grpc.ManagedChannelBuilder;
2224
import org.apache.commons.logging.Log;
@@ -110,18 +112,35 @@ synchronized void shutdown(boolean force) {
110112
}
111113
}
112114

113-
public ListenableFuture<FabricProposalResponse.ProposalResponse> sendProposalAsync(FabricProposal.SignedProposal proposal) throws PeerException {
115+
public CompletableFuture<FabricProposalResponse.ProposalResponse> sendProposalAsync(FabricProposal.SignedProposal proposal) {
114116
if (shutdown) {
115-
throw new PeerException("Shutdown " + toString());
117+
CompletableFuture<FabricProposalResponse.ProposalResponse> ret = new CompletableFuture<>();
118+
ret.completeExceptionally(new PeerException("Shutdown " + toString()));
119+
return ret;
116120
}
117-
return futureStub.processProposal(proposal);
121+
122+
CompletableFuture<FabricProposalResponse.ProposalResponse> future = CompletableFuturesExtra.toCompletableFuture(futureStub.processProposal(proposal));
123+
124+
return future.exceptionally(throwable -> {
125+
throw new CompletionException(format("%s %s", toString, throwable.getMessage()), throwable);
126+
});
127+
128+
// return CompletableFuturesExtra.toCompletableFuture(futureStub.processProposal(proposal));
129+
// return futureStub.processProposal(proposal);
118130
}
119131

120-
public ListenableFuture<Protocol.Response> sendDiscoveryRequestAsync(Protocol.SignedRequest signedRequest) throws PeerException {
132+
public CompletableFuture<Protocol.Response> sendDiscoveryRequestAsync(Protocol.SignedRequest signedRequest) {
121133
if (shutdown) {
122-
throw new PeerException("Shutdown " + toString());
134+
CompletableFuture<Protocol.Response> ret = new CompletableFuture<>();
135+
ret.completeExceptionally(new PeerException("Shutdown " + toString()));
136+
return ret;
123137
}
124-
return discoveryFutureStub.discover(signedRequest);
138+
139+
CompletableFuture<Protocol.Response> future = CompletableFuturesExtra.toCompletableFuture(discoveryFutureStub.discover(signedRequest));
140+
return future.exceptionally(throwable -> {
141+
throw new CompletionException(format("%s %s", toString, throwable.getMessage()), throwable);
142+
});
143+
125144
}
126145

127146
boolean isChannelActive() {

src/main/java/org/hyperledger/fabric/sdk/Peer.java

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020
import java.util.EnumSet;
2121
import java.util.Objects;
2222
import java.util.Properties;
23+
import java.util.concurrent.CompletableFuture;
24+
import java.util.concurrent.CompletionException;
2325
import java.util.concurrent.ExecutorService;
2426
import java.util.concurrent.atomic.AtomicLong;
2527

26-
import com.google.common.util.concurrent.ListenableFuture;
2728
import io.netty.util.internal.StringUtil;
2829
import org.apache.commons.logging.Log;
2930
import org.apache.commons.logging.LogFactory;
@@ -220,22 +221,29 @@ public int hashCode() {
220221
return Objects.hash(name, url);
221222
}
222223

223-
ListenableFuture<FabricProposalResponse.ProposalResponse> sendProposalAsync(FabricProposal.SignedProposal proposal)
224-
throws PeerException, InvalidArgumentException {
225-
checkSendProposal(proposal);
224+
CompletableFuture<FabricProposalResponse.ProposalResponse> sendProposalAsync(FabricProposal.SignedProposal proposal) {
225+
try {
226+
checkSendProposal(proposal);
227+
} catch (Exception e) {
228+
CompletableFuture<FabricProposalResponse.ProposalResponse> future = new CompletableFuture<>();
229+
future.completeExceptionally(e);
230+
return future;
231+
}
226232

227233
if (IS_DEBUG_LEVEL) {
228234
logger.debug(format("peer.sendProposalAsync %s", toString()));
229235
}
230236

231237
EndorserClient localEndorserClient = getEndorserClient();
232238

233-
try {
234-
return localEndorserClient.sendProposalAsync(proposal);
235-
} catch (Throwable t) {
239+
return localEndorserClient.sendProposalAsync(proposal).exceptionally(throwable -> {
236240
removeEndorserClient(true);
237-
throw t;
238-
}
241+
if (throwable instanceof CompletionException) {
242+
throw (CompletionException) throwable;
243+
}
244+
throw new CompletionException(throwable);
245+
});
246+
239247
}
240248

241249
private synchronized EndorserClient getEndorserClient() {
@@ -274,19 +282,18 @@ private synchronized void removeEndorserClient(boolean force) {
274282
}
275283
}
276284

277-
ListenableFuture<Protocol.Response> sendDiscoveryRequestAsync(Protocol.SignedRequest discoveryRequest)
278-
throws PeerException, InvalidArgumentException {
279-
285+
CompletableFuture<Protocol.Response> sendDiscoveryRequestAsync(Protocol.SignedRequest discoveryRequest) {
280286
logger.debug(format("peer.sendDiscoveryRequstAsync %s", toString()));
281287

282288
EndorserClient localEndorserClient = getEndorserClient();
283289

284-
try {
285-
return localEndorserClient.sendDiscoveryRequestAsync(discoveryRequest);
286-
} catch (Throwable t) {
290+
return localEndorserClient.sendDiscoveryRequestAsync(discoveryRequest).exceptionally(throwable -> {
287291
removeEndorserClient(true);
288-
throw t;
289-
}
292+
if (throwable instanceof CompletionException) {
293+
throw (CompletionException) throwable;
294+
}
295+
throw new CompletionException(throwable);
296+
});
290297
}
291298

292299
synchronized byte[] getClientTLSCertificateDigest() {
@@ -630,6 +637,7 @@ public enum PeerRole {
630637
public String getPropertyName() {
631638
return propertyName;
632639
}
640+
633641
}
634642

635643
String getEndpoint() {

src/test/java/org/hyperledger/fabric/sdk/ChannelTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
import java.util.Properties;
3131
import java.util.concurrent.CompletableFuture;
3232

33-
import com.google.common.util.concurrent.ListenableFuture;
34-
import com.google.common.util.concurrent.SettableFuture;
3533
import com.google.protobuf.ByteString;
3634
import io.grpc.Status;
3735
import io.grpc.StatusRuntimeException;
@@ -791,8 +789,9 @@ public void testQueryInstalledChaincodesERROR() throws Exception {
791789
final Channel channel = createRunningChannel(null);
792790
Peer peer = channel.getPeers().iterator().next();
793791

794-
final SettableFuture<FabricProposalResponse.ProposalResponse> settableFuture = SettableFuture.create();
795-
settableFuture.setException(new Error("Error bad bad bad"));
792+
final CompletableFuture<FabricProposalResponse.ProposalResponse> settableFuture = new CompletableFuture<>();
793+
// settableFuture.setException(new Error("Error bad bad bad"));
794+
settableFuture.completeExceptionally(new Error("Error bad bad bad"));
796795
setField(peer, "endorserClent", new MockEndorserClient(settableFuture));
797796

798797
hfclient.queryChannels(peer);
@@ -808,8 +807,9 @@ public void testQueryInstalledChaincodesStatusRuntimeException() throws Exceptio
808807
final Channel channel = createRunningChannel(null);
809808
Peer peer = channel.getPeers().iterator().next();
810809

811-
final SettableFuture<FabricProposalResponse.ProposalResponse> settableFuture = SettableFuture.create();
812-
settableFuture.setException(new StatusRuntimeException(Status.ABORTED));
810+
final CompletableFuture<FabricProposalResponse.ProposalResponse> settableFuture = new CompletableFuture<>();
811+
settableFuture.completeExceptionally(new StatusRuntimeException(Status.ABORTED));
812+
813813
setField(peer, "endorserClent", new MockEndorserClient(settableFuture));
814814

815815
hfclient.queryChannels(peer);
@@ -1016,7 +1016,7 @@ public void testProposalBuilderWithMetaInfEmpty() throws Exception {
10161016

10171017
class MockEndorserClient extends EndorserClient {
10181018
final Throwable throwThis;
1019-
private final ListenableFuture<FabricProposalResponse.ProposalResponse> returnedFuture;
1019+
private final CompletableFuture<FabricProposalResponse.ProposalResponse> returnedFuture;
10201020

10211021
MockEndorserClient(Throwable throwThis) {
10221022
super("blahchannlname", "blahpeerName", "blahURL", new Endpoint("grpc://loclhost:99", null).getChannelBuilder());
@@ -1027,14 +1027,14 @@ class MockEndorserClient extends EndorserClient {
10271027
this.returnedFuture = null;
10281028
}
10291029

1030-
MockEndorserClient(ListenableFuture<FabricProposalResponse.ProposalResponse> returnedFuture) {
1030+
MockEndorserClient(CompletableFuture<FabricProposalResponse.ProposalResponse> returnedFuture) {
10311031
super("blahchannlname", "blahpeerName", "blahURL", new Endpoint("grpc://loclhost:99", null).getChannelBuilder());
10321032
this.throwThis = null;
10331033
this.returnedFuture = returnedFuture;
10341034
}
10351035

10361036
@Override
1037-
public ListenableFuture<FabricProposalResponse.ProposalResponse> sendProposalAsync(FabricProposal.SignedProposal proposal) throws PeerException {
1037+
public CompletableFuture<FabricProposalResponse.ProposalResponse> sendProposalAsync(FabricProposal.SignedProposal proposal) {
10381038
if (throwThis != null) {
10391039
getUnsafe().throwException(throwThis);
10401040
}

src/test/java/org/hyperledger/fabric/sdk/PeerTest.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
package org.hyperledger.fabric.sdk;
1616

17+
import java.util.concurrent.ExecutionException;
18+
import java.util.concurrent.Future;
19+
20+
import org.hyperledger.fabric.protos.peer.FabricProposalResponse;
1721
import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
1822
import org.hyperledger.fabric.sdk.exception.PeerException;
1923
import org.junit.Assert;
@@ -66,9 +70,10 @@ public void testSetEmptyName() throws InvalidArgumentException {
6670
Assert.fail("expected set empty name to throw exception.");
6771
}
6872

69-
@Test (expected = PeerException.class)
70-
public void testSendAsyncNullProposal() throws PeerException, InvalidArgumentException {
71-
peer.sendProposalAsync(null);
73+
@Test (expected = Exception.class)
74+
public void testSendAsyncNullProposal() throws PeerException, InvalidArgumentException, ExecutionException, InterruptedException {
75+
Future<FabricProposalResponse.ProposalResponse> future = peer.sendProposalAsync(null);
76+
future.get();
7277
}
7378

7479
@Test (expected = InvalidArgumentException.class)

0 commit comments

Comments
 (0)