package bdchain.api; import bdchain.api.grpc.*; import bdchain.api.grpc.TransactionLedgerGrpc.TransactionLedgerBlockingStub; import bdchain.api.grpc.TransactionLedgerGrpc.TransactionLedgerFutureStub; import com.google.common.util.concurrent.ListenableFuture; import com.google.protobuf.ByteString; import com.google.protobuf.Empty; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.StatusRuntimeException; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; // import bdchain.api.grpc.TransactionLedgerGrpc.TransactionLedgerStub; /** * 事务账本客户端 * *

如有更灵活的需求可直接使用{@link bdchain.api.grpc.TransactionLedgerGrpc}类。 * * @see 事务账本API * @author nex */ public class TransactionLedgerClient { private static final Logger logger = Logger.getLogger(TransactionLedgerClient.class.getName()); private final ManagedChannel channel; private final TransactionLedgerFutureStub futureStub; private final TransactionLedgerBlockingStub blockingStub; // private final TransactionLedgerStub asyncStub; /** 构造客户端来访问{@code host:port}的事务账本服务。 */ public TransactionLedgerClient(String host, int port) { this(ManagedChannelBuilder.forAddress(host, port).usePlaintext()); } /** 用已有的{@link io.grpc.Channel}对象构造客户端来访问事务账本服务。 */ public TransactionLedgerClient(ManagedChannelBuilder channelBuilder) { channel = channelBuilder.build(); futureStub = TransactionLedgerGrpc.newFutureStub(channel); blockingStub = TransactionLedgerGrpc.newBlockingStub(channel); // asyncStub = TransactionLedgerGrpc.newStub(channel); } /** 关闭客户端的网络连接。 */ public void shutdown() throws InterruptedException { channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); } /** * 创建账本 * (非阻塞) */ public ListenableFuture createLedger(String name) { info("*** createLedger: name={0}", name); CreateLedgerRequest request = CreateLedgerRequest.newBuilder().setName(name).build(); try { return futureStub.createLedger(request); } catch (StatusRuntimeException e) { warning("RPC failed: {0}", e.getStatus()); return null; } } /** * 创建账本 * (阻塞) */ public CreateLedgerResponse createLedgerSync(String name) { info("*** createLedgerSync: name={0}", name); CreateLedgerRequest request = CreateLedgerRequest.newBuilder().setName(name).build(); try { return blockingStub.createLedger(request); } catch (StatusRuntimeException e) { warning("RPC failed: {0}", e.getStatus()); return null; } } /** * 返回账本列表 * (非阻塞) */ public ListenableFuture getLedgers() { info("*** getLedgers"); try { return futureStub.getLedgers(Empty.getDefaultInstance()); } catch (StatusRuntimeException e) { warning("RPC failed: {0}", e.getStatus()); return null; } } /** * 返回账本列表 * (阻塞) */ public GetLedgersResponse getLedgersSync() { info("*** getLedgersSync"); try { return blockingStub.getLedgers(Empty.getDefaultInstance()); } catch (StatusRuntimeException e) { warning("RPC failed: {0}", e.getStatus()); return null; } } /** * 发送新事务 * (非阻塞) */ public ListenableFuture sendTransaction( String ledger, TransactionType type, String from, String to, byte[] data) { info( "*** sendTransaction: ledger={0} type={1} from={2} to={3} data={4}", ledger, type, from, to, data); SendTransactionRequest request = SendTransactionRequest.newBuilder() .setLedger(ledger) .setTransaction( SendTransactionRequest.Transaction.newBuilder() .setType(type) .setFrom(ByteString.copyFrom(Utils.hexStringToByteArray(from))) .setTo(ByteString.copyFrom(Utils.hexStringToByteArray(from))) .setData(ByteString.copyFrom(data))) .build(); try { return futureStub.sendTransaction(request); } catch (StatusRuntimeException e) { warning("RPC failed: {0}", e.getStatus()); return null; } } /** * 发送新事务 * (阻塞) */ public SendTransactionResponse sendTransactionSync( String ledger, TransactionType type, String from, String to, byte[] data) { info( "*** sendTransactionSync: ledger={0} type={1} from={2} to={3} data={4}", ledger, type, from, to, data); SendTransactionRequest request = SendTransactionRequest.newBuilder() .setLedger(ledger) .setTransaction( SendTransactionRequest.Transaction.newBuilder() .setType(type) .setFrom(ByteString.copyFrom(Utils.hexStringToByteArray(from))) .setTo(ByteString.copyFrom(Utils.hexStringToByteArray(from))) .setData(ByteString.copyFrom(data))) .build(); try { return blockingStub.sendTransaction(request); } catch (StatusRuntimeException e) { warning("RPC failed: {0}", e.getStatus()); return null; } } private void info(String msg, Object... params) { logger.log(Level.INFO, msg, params); } private void warning(String msg, Object... params) { logger.log(Level.WARNING, msg, params); } }