All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jd.blockchain.sdk.service.PeerBlockchainServiceFactory Maven / Gradle / Ivy

The newest version!
package com.jd.blockchain.sdk.service;

import com.jd.blockchain.consensus.ClientIncomingSettings;
import com.jd.blockchain.consensus.ConsensusProvider;
import com.jd.blockchain.consensus.ConsensusProviders;
import com.jd.blockchain.consensus.SessionCredential;
import com.jd.blockchain.consensus.client.ClientFactory;
import com.jd.blockchain.consensus.client.ConsensusClient;
import com.jd.blockchain.consensus.service.MonitorService;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.CryptoSetting;
import com.jd.blockchain.sdk.BlockchainService;
import com.jd.blockchain.sdk.BlockchainServiceFactory;
import com.jd.blockchain.sdk.LedgerAccessContext;
import com.jd.blockchain.sdk.ManagementHttpService;
import com.jd.blockchain.sdk.proxy.HttpBlockchainBrowserService;
import com.jd.blockchain.setting.GatewayAuthResponse;
import com.jd.blockchain.setting.LedgerIncomingSettings;
import com.jd.blockchain.transaction.BlockchainQueryService;
import com.jd.blockchain.transaction.TransactionService;
import com.jd.httpservice.agent.HttpServiceAgent;
import com.jd.httpservice.agent.ServiceConnection;
import com.jd.httpservice.agent.ServiceConnectionManager;
import com.jd.httpservice.agent.ServiceEndpoint;
import utils.io.ByteArray;
import utils.net.NetworkAddress;
import utils.net.SSLSecurity;

import java.io.Closeable;
import java.util.HashMap;
import java.util.Map;

public class PeerBlockchainServiceFactory implements BlockchainServiceFactory, Closeable {

    private ServiceConnectionManager httpConnectionManager;
    private PeerServiceProxy peerServiceProxy;
    // 当前连接可访问账本列表
    private HashDigest[] ledgers;
    private Map accessContextMap = new HashMap<>();
    private Map monitorServiceMap = new HashMap<>();

    /**
     * 创建共识节点的区块链服务工厂;
     *
     * @param httpConnectionManager Http请求管理器;
     * @param accessableLedgers     可用账本列表;
     */
    protected PeerBlockchainServiceFactory(ServiceConnectionManager httpConnectionManager, LedgerAccessContextImpl[] accessableLedgers) {
        this.httpConnectionManager = httpConnectionManager;
        this.peerServiceProxy = new PeerServiceProxy(accessableLedgers);
    }

    public static PeerBlockchainServiceFactory create(AsymmetricKeypair gatewayKey, NetworkAddress peerAddr, SSLSecurity manageSslSecurity, SSLSecurity consensusSslSecurity,
                                                      LedgerIncomingSettings[] ledgerSettingsArray, SessionCredentialProvider credentialProvider, ConsensusClientManager clientManager) {
        HashDigest[] ledgers = new HashDigest[ledgerSettingsArray.length];
        if (ledgerSettingsArray.length > 0) {
            ServiceConnectionManager httpConnectionManager = new ServiceConnectionManager(peerAddr.isSecure(), manageSslSecurity);
            ServiceConnection httpConnection = httpConnectionManager.create(new ServiceEndpoint(peerAddr));
            PeerBlockchainQueryService peerManageService = new PeerBlockchainQueryService(httpConnection,
                    HttpServiceAgent.createService(HttpBlockchainBrowserService.class, httpConnection, null));
            BlockchainQueryService queryService = peerManageService.getQueryService();
            LedgerAccessContextImpl[] accessAbleLedgers = new LedgerAccessContextImpl[ledgerSettingsArray.length];

            Map tempAccessCtxs = new HashMap<>();
            Map tempMonitors = new HashMap<>();
            for (int i = 0; i < ledgerSettingsArray.length; i++) {
                LedgerIncomingSettings ledgerSetting = ledgerSettingsArray[i];
                ledgers[i] = ledgerSetting.getLedgerHash();
                String providerName = ledgerSetting.getProviderName();
                ConsensusProvider provider = ConsensusProviders.getProvider(providerName);
                byte[] clientSettingBytes = ByteArray.fromBase64(ledgerSetting.getConsensusClientSettings());

                ClientIncomingSettings clientIncomingSettings = provider.getSettingsFactory()
                        .getIncomingSettingsEncoder().decode(clientSettingBytes);

                SessionCredential sessionCredential = clientIncomingSettings.getCredential();
                ConsensusClient consensusClient = clientManager.getConsensusClient(ledgerSetting.getLedgerHash(),
                        sessionCredential, () -> {
                            ClientFactory clientFactory = provider.getClientFactory();
                            return clientFactory.setupClient(
                                    clientFactory.buildClientSettings(clientIncomingSettings, consensusSslSecurity),
                                    ledgerSetting.getLedgerHash().toBase58()
                                    );
                        });

                MonitorService monitorService = null;

                TransactionService autoSigningTxProcService = enableGatewayAutoSigning(gatewayKey,
                        ledgerSetting.getCryptoSetting(), consensusClient);
                if (autoSigningTxProcService instanceof NodeSigningAppender) {
                    monitorService = new PeerMonitorHandler((((NodeSigningAppender) autoSigningTxProcService)));
                }

                LedgerAccessContextImpl accCtx = new LedgerAccessContextImpl(sessionCredential);
                accCtx.ledgerHash = ledgerSetting.getLedgerHash();
                accCtx.cryptoSetting = ledgerSetting.getCryptoSetting();
                accCtx.queryService = queryService;
                accCtx.txProcService = autoSigningTxProcService;
                accCtx.consensusClient = consensusClient;
                accessAbleLedgers[i] = accCtx;
                tempAccessCtxs.put(accCtx.ledgerHash, accCtx);

                if (monitorService != null) {
                    tempMonitors.put(accCtx.ledgerHash, monitorService);
                }

                // 保存会话凭证;如果出错不影响后续执行;
                updateSessionCredential(ledgerSetting.getLedgerHash(), sessionCredential, credentialProvider);
            }

            PeerBlockchainServiceFactory factory = new PeerBlockchainServiceFactory(httpConnectionManager, accessAbleLedgers);
            factory.accessContextMap.putAll(tempAccessCtxs);
            factory.monitorServiceMap.putAll(tempMonitors);
            factory.ledgers = ledgers;
            return factory;
        } else {
            throw new IllegalStateException("No ledger accessible!");
        }
    }

    /**
     * 连接到指定的共识节点
     *
     * @param gatewayKey           提供对网关接入认证的共识节点身份信息; 
* @param peerAddr 提供对网关接入认证的节点的认证地址列表;
* @param manageSslSecurity 提供对网关接入认证的节点的管理服务TLS证书相关信息;
* @param consensusSslSecurity 提供对网关接入认证的节点的公式服务TLS证书相关信息;
* @param credentialProvider 共识客户端在接入认证过程中使用的凭证的来源 * @param clientManager 账本对应的共识客户端管理 * @return 区块链服务工厂实例 */ public static PeerBlockchainServiceFactory connect(AsymmetricKeypair gatewayKey, NetworkAddress peerAddr, SSLSecurity manageSslSecurity, SSLSecurity consensusSslSecurity, SessionCredentialProvider credentialProvider, ConsensusClientManager clientManager) { // 认证,返回账本列表及配置相关信息 PeerAuthenticator authenticator = new PeerAuthenticator(peerAddr, manageSslSecurity, gatewayKey, credentialProvider); GatewayAuthResponse gatewayAuthResponse = authenticator.request(); return create(gatewayKey, peerAddr, manageSslSecurity, consensusSslSecurity, gatewayAuthResponse.getLedgers(), credentialProvider, clientManager); } /** * 连接到指定的共识节点 * * @param gatewayKey 提供对网关接入认证的共识节点身份信息;
* @param peerAddr 提供对网关接入认证的节点的认证地址列表;
* @param credentialProvider 共识客户端在接入认证过程中使用的凭证的来源 * @param clientManager 账本对应的共识客户端管理 * @return 区块链服务工厂实例 */ public static PeerBlockchainServiceFactory connect(AsymmetricKeypair gatewayKey, NetworkAddress peerAddr, SessionCredentialProvider credentialProvider, ConsensusClientManager clientManager) { return connect(gatewayKey, peerAddr, new SSLSecurity(), new SSLSecurity(), credentialProvider, clientManager); } private static void updateSessionCredential(HashDigest ledgerHash, SessionCredential sessionCredential, SessionCredentialProvider credentialProvider) { try { // 保存会话凭证; credentialProvider.setCredential(ledgerHash.toBase58(), sessionCredential); } catch (Exception e) { // 如果出错不影响后续执行; } } private static ManagementHttpService getManageService(NetworkAddress peer) { ServiceEndpoint peerServer = new ServiceEndpoint(peer.getHost(), peer.getPort(), false); ManagementHttpService manageService = HttpServiceAgent.createService(ManagementHttpService.class, peerServer); return manageService; } /** * 启用网关自动签名; * * @param nodeKeyPair * @param cryptoSetting * @return */ private static TransactionService enableGatewayAutoSigning(AsymmetricKeypair nodeKeyPair, CryptoSetting cryptoSetting, ConsensusClient consensusClient) { NodeSigningAppender signingAppender = new NodeSigningAppender(cryptoSetting.getHashAlgorithm(), nodeKeyPair, consensusClient); return signingAppender.init(); } public HashDigest[] getLedgerHashs() { return ledgers; } @Override public BlockchainService getBlockchainService() { return peerServiceProxy; } /** * 返回交易服务; * *
*

* 返回的交易服务聚合了该节点绑定的多个账本的交易服务,并根据交易请求中指定的目标账本选择相应的交易服务进行转发; * * @return */ public TransactionService getTransactionService() { return peerServiceProxy; } @Override public void close() { try { httpConnectionManager.close(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public Map getMonitorServiceMap() { return monitorServiceMap; } private static class LedgerAccessContextImpl implements LedgerAccessContext { private final SessionCredential credential; private HashDigest ledgerHash; private CryptoSetting cryptoSetting; private TransactionService txProcService; private BlockchainQueryService queryService; private ConsensusClient consensusClient; public LedgerAccessContextImpl(SessionCredential credential) { this.credential = credential; } /** * 经过认证的客户端凭证; * * @return */ public SessionCredential getCredential() { return credential; } @Override public HashDigest getLedgerHash() { return ledgerHash; } @Override public CryptoSetting getCryptoSetting() { return cryptoSetting; } @Override public TransactionService getTransactionService() { return txProcService; } @Override public BlockchainQueryService getQueryService() { return queryService; } } private static final class PeerBlockchainQueryService { ServiceConnection httpConnection; BlockchainQueryService queryService; public PeerBlockchainQueryService(ServiceConnection httpConnection, BlockchainQueryService queryService) { this.httpConnection = httpConnection; this.queryService = queryService; } public ServiceConnection getHttpConnection() { return httpConnection; } @SuppressWarnings("unused") public void setHttpConnection(ServiceConnection httpConnection) { this.httpConnection = httpConnection; } public BlockchainQueryService getQueryService() { return queryService; } @SuppressWarnings("unused") public void setQueryService(BlockchainQueryService queryService) { this.queryService = queryService; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy