diff --git a/build.gradle b/build.gradle index c9c0740..58b71f0 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ javadoc { options { encoding 'UTF-8' charSet 'UTF-8' - title "BDChain Java SDK API" + title "BDLedger Java SDK API" } } diff --git a/settings.gradle b/settings.gradle index 9eeb23c..6af04a4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ -rootProject.name = 'BDLedger Java SDK' +rootProject.name = 'bdledger-java-sdk' diff --git a/src/main/java/bdledger/api/Client.java b/src/main/java/bdledger/api/Client.java new file mode 100644 index 0000000..764d193 --- /dev/null +++ b/src/main/java/bdledger/api/Client.java @@ -0,0 +1,418 @@ +package bdledger.api; + +import bdledger.api.grpc.common.Block; +import bdledger.api.grpc.common.Transaction; +import bdledger.api.grpc.node .ClientVersionResponse; +import bdledger.api.grpc.common.TransactionType; +import bdledger.api.grpc.ledger.*; +import bdledger.api.grpc.node.NodeGrpc; +import bdledger.api.grpc.query.*; +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; + +/** + * 事务账本客户端 + * + *

如有更灵活的需求可直接使用{@link bdledger.api.grpc.ledger.TransactionLedgerGrpc}类。 + * + * @see 事务账本API + * @author nex + */ +public class Client { + + private static final Logger logger = Logger.getLogger(Client.class.getName()); + + private final ManagedChannel channel; + private final NodeGrpc.NodeFutureStub nodeFutureStub; + private final NodeGrpc.NodeBlockingStub nodeBlockingStub; + private final TransactionLedgerGrpc.TransactionLedgerFutureStub ledgerFutureStub; + private final TransactionLedgerGrpc.TransactionLedgerBlockingStub ledgerBlockingStub; + private final QueryGrpc.QueryFutureStub queryFutureStub; + private final QueryGrpc.QueryBlockingStub queryBlockingStub; + + /** 构造客户端来访问{@code host:port}的事务账本服务。 */ + public Client(String host, int port) { + this(ManagedChannelBuilder.forAddress(host, port).usePlaintext()); + } + + /** 用已有的{@link io.grpc.Channel}对象构造客户端来访问事务账本服务。 */ + public Client(ManagedChannelBuilder channelBuilder) { + channel = channelBuilder.build(); + nodeFutureStub = NodeGrpc.newFutureStub(channel); + nodeBlockingStub = NodeGrpc.newBlockingStub(channel); + ledgerFutureStub = TransactionLedgerGrpc.newFutureStub(channel); + ledgerBlockingStub = TransactionLedgerGrpc.newBlockingStub(channel); + queryFutureStub = QueryGrpc.newFutureStub(channel); + queryBlockingStub = QueryGrpc.newBlockingStub(channel); + } + + /** 关闭客户端的网络连接。 */ + public void shutdown() throws InterruptedException { + channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + + /** + * 查询节点客户端版本 + * (非阻塞) + */ + public ListenableFuture clientVersion() { + + info("*** clientVersion"); + + try { + return nodeFutureStub.clientVersion(Empty.getDefaultInstance()); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + /** + * 查询节点客户端版本 + * (阻塞) + */ + public ClientVersionResponse clientVersionSync() { + + info("*** clientVersionSync"); + + try { + return nodeBlockingStub.clientVersion(Empty.getDefaultInstance()); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + /** + * 创建账本 + * (非阻塞) + */ + public ListenableFuture createLedger(String name) { + + info("*** createLedger: name={0}", name); + + try { + return ledgerFutureStub.createLedger(createLedgerRequest(name)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + /** + * 创建账本 + * (阻塞) + */ + public CreateLedgerResponse createLedgerSync(String name) { + + info("*** createLedgerSync: name={0}", name); + + try { + return ledgerBlockingStub.createLedger(createLedgerRequest(name)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + private CreateLedgerRequest createLedgerRequest(String name) { + return CreateLedgerRequest.newBuilder().setName(name).build(); + } + + /** + * 返回账本列表 + * (非阻塞) + */ + public ListenableFuture getLedgers() { + + info("*** getLedgers"); + + try { + return ledgerFutureStub.getLedgers(Empty.getDefaultInstance()); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + /** + * 返回账本列表 + * (阻塞) + */ + public GetLedgersResponse getLedgersSync() { + + info("*** getLedgersSync"); + + try { + return ledgerBlockingStub.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); + + try { + return ledgerFutureStub.sendTransaction(SendTransactionRequest(ledger, type, from, to, data)); + } 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); + + try { + return ledgerBlockingStub.sendTransaction(SendTransactionRequest(ledger, type, from, to, data)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + private SendTransactionRequest SendTransactionRequest( + String ledger, TransactionType type, String from, String to, byte[] data) { + + SendTransactionRequest.Transaction.Builder txBuilder = + SendTransactionRequest.Transaction.newBuilder().setType(type); + if (from != null) { + txBuilder.setFrom(ByteString.copyFrom(Utils.hexStringToByteArray(from))); + } + if (to != null) { + txBuilder.setTo(ByteString.copyFrom(Utils.hexStringToByteArray(to))); + } + if (data != null) { + txBuilder.setData(ByteString.copyFrom(data)); + } + + return SendTransactionRequest.newBuilder().setLedger(ledger).setTransaction(txBuilder).build(); + } + + /** + * 返回最新区块的区块号 + * (非阻塞) + */ + public ListenableFuture blockNumber(String ledger) { + + info("*** blockNumber: ledger={0}", ledger); + + try { + return queryFutureStub.countBlocks(blocksRequest(ledger)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + /** + * 返回最新区块的区块号 + * (阻塞) + */ + public CountBlocksResponse blockNumberSync(String ledger) { + + info("*** blockNumberSync: ledger={0}", ledger); + + try { + return queryBlockingStub.countBlocks(blocksRequest(ledger)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + private BlocksRequest blocksRequest(String ledger) { + return BlocksRequest.newBuilder().setLedger(ledger).build(); + } + + /** + * 返回哈希所指定区块的信息 + * (非阻塞) + */ + public ListenableFuture getBlockByHash( + String ledger, String hash, boolean fullTransaction) { + + info( + "*** getBlockByHash: ledger={0} hash={1} fullTransaction={2}", + ledger, hash, fullTransaction); + + try { + return queryFutureStub.getBlockByHash(getBlockByHashRequest(ledger, hash, fullTransaction)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + /** + * 返回哈希所指定区块的信息 + * (阻塞) + */ + public GetBlockByHashResponse getBlockByHashSync(String ledger, String hash, boolean fullTransaction) { + + info( + "*** getBlockByHashSync: ledger={0} hash={1} fullTransaction={2}", + ledger, hash, fullTransaction); + + try { + return queryBlockingStub.getBlockByHash(getBlockByHashRequest(ledger, hash, fullTransaction)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + private GetBlockByHashRequest getBlockByHashRequest( + String ledger, String hash, boolean fullTransaction) { + + GetBlockByHashRequest.Builder reqBuilder = + GetBlockByHashRequest.newBuilder().setLedger(ledger).setFullTransaction(fullTransaction); + if (hash != null) { + reqBuilder.setHash(ByteString.copyFrom(Utils.hexStringToByteArray(hash))); + } + + return reqBuilder.build(); + } + + /** + * 返回哈希所指定事务的信息 + * (非阻塞) + */ + public ListenableFuture getTransactionByHash(String ledger, String hash) { + + info("*** getTransactionByHash: ledger={0} hash={1}", ledger, hash); + + try { + return queryFutureStub.getTransactionByHash(getTransactionByHashRequest(ledger, hash)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + /** + * 返回哈希所指定事务的信息 + * (阻塞) + */ + public GetTransactionByHashResponse getTransactionByHashSync(String ledger, String hash) { + + info("*** getTransactionByHashSync: ledger={0} hash={1}", ledger, hash); + + try { + return queryBlockingStub.getTransactionByHash(getTransactionByHashRequest(ledger, hash)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + private GetTransactionByHashRequest getTransactionByHashRequest(String ledger, String hash) { + + GetTransactionByHashRequest.Builder reqBuilder = + GetTransactionByHashRequest.newBuilder().setLedger(ledger); + if (hash != null) { + reqBuilder.setHash(ByteString.copyFrom(Utils.hexStringToByteArray(hash))); + } + + return reqBuilder.build(); + } + + /** + * 返回区块的哈希与事务的index所指定事务的信息 + * (非阻塞) + */ + public ListenableFuture getTransactionByBlockHashAndIndex( + String ledger, String block_hash, int index) { + + info( + "*** getTransactionByBlockHashAndIndex: ledger={0} block_hash={1} index={2}", + ledger, block_hash, index); + + try { + return queryFutureStub.getTransactionByBlockHashAndIndex( + getTransactionByBlockHashAndIndexRequest(ledger, block_hash, index)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + /** + * 返回区块的哈希与事务的index所指定事务的信息 + * (阻塞) + */ + public GetTransactionByBlockHashAndIndexResponse getTransactionByBlockHashAndIndexSync( + String ledger, String block_hash, int index) { + + info( + "*** getTransactionByBlockHashAndIndexSync: ledger={0} block_hash={1} index={2}", + ledger, block_hash, index); + + try { + return queryBlockingStub.getTransactionByBlockHashAndIndex( + getTransactionByBlockHashAndIndexRequest(ledger, block_hash, index)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + private GetTransactionByBlockHashAndIndexRequest getTransactionByBlockHashAndIndexRequest( + String ledger, String block_hash, int index) { + + GetTransactionByBlockHashAndIndexRequest.Builder reqBuilder = + GetTransactionByBlockHashAndIndexRequest.newBuilder().setLedger(ledger).setIndex(index); + + if (block_hash != null) { + reqBuilder.setBlockHash(ByteString.copyFrom(Utils.hexStringToByteArray(block_hash))); + } + + return reqBuilder.build(); + } + + 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); + } +} diff --git a/src/main/java/bdledger/api/TransactionLedgerClient.java b/src/main/java/bdledger/api/TransactionLedgerClient.java deleted file mode 100644 index c9bf12f..0000000 --- a/src/main/java/bdledger/api/TransactionLedgerClient.java +++ /dev/null @@ -1,224 +0,0 @@ -package bdledger.api; - -import bdchain.api.grpc.common.ClientVersionResponse; -import bdchain.api.grpc.common.TransactionType; -import bdchain.api.grpc.txledger.*; -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.txledger.TransactionLedgerGrpc.TransactionLedgerStub; - -/** - * 事务账本客户端 - * - *

如有更灵活的需求可直接使用{@link bdchain.api.grpc.txledger.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 clientVersion() { - - info("*** clientVersion"); - - try { - return futureStub.clientVersion(Empty.getDefaultInstance()); - } catch (StatusRuntimeException e) { - warning("RPC failed: {0}", e.getStatus()); - return null; - } - } - - /** - * 查询节点客户端版本 - * (阻塞) - */ - public ClientVersionResponse clientVersionSync() { - - info("*** clientVersionSync"); - - try { - return blockingStub.clientVersion(Empty.getDefaultInstance()); - } catch (StatusRuntimeException e) { - warning("RPC failed: {0}", e.getStatus()); - return null; - } - } - - /** - * 创建账本 - * (非阻塞) - */ - public ListenableFuture createLedger(String name) { - - info("*** createLedger: name={0}", name); - - try { - return futureStub.createLedger(createLedgerRequest(name)); - } catch (StatusRuntimeException e) { - warning("RPC failed: {0}", e.getStatus()); - return null; - } - } - - /** - * 创建账本 - * (阻塞) - */ - public CreateLedgerResponse createLedgerSync(String name) { - - info("*** createLedgerSync: name={0}", name); - - try { - return blockingStub.createLedger(createLedgerRequest(name)); - } catch (StatusRuntimeException e) { - warning("RPC failed: {0}", e.getStatus()); - return null; - } - } - - private CreateLedgerRequest createLedgerRequest(String name) { - return CreateLedgerRequest.newBuilder().setName(name).build(); - } - - /** - * 返回账本列表 - * (非阻塞) - */ - 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); - - try { - return futureStub.sendTransaction(SendTransactionRequest(ledger, type, from, to, data)); - } 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); - - try { - return blockingStub.sendTransaction(SendTransactionRequest(ledger, type, from, to, data)); - } catch (StatusRuntimeException e) { - warning("RPC failed: {0}", e.getStatus()); - return null; - } - } - - private SendTransactionRequest SendTransactionRequest( - String ledger, TransactionType type, String from, String to, byte[] data) { - - SendTransactionRequest.Transaction.Builder txBuilder = - SendTransactionRequest.Transaction.newBuilder().setType(type); - if (from != null) { - txBuilder.setFrom(ByteString.copyFrom(Utils.hexStringToByteArray(from))); - } - if (to != null) { - txBuilder.setTo(ByteString.copyFrom(Utils.hexStringToByteArray(to))); - } - if (data != null) { - txBuilder.setData(ByteString.copyFrom(data)); - } - - SendTransactionRequest request = - SendTransactionRequest.newBuilder().setLedger(ledger).setTransaction(txBuilder).build(); - - return request; - } - - 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); - } -}