github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/internal/pkg/gateway/endpoint.go (about) 1 /* 2 Copyright 2021 IBM All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package gateway 8 9 import ( 10 "context" 11 "fmt" 12 "time" 13 14 "github.com/hechain20/hechain/gossip/common" 15 "github.com/hechain20/hechain/internal/pkg/comm" 16 ab "github.com/hyperledger/fabric-protos-go/orderer" 17 "github.com/hyperledger/fabric-protos-go/peer" 18 "google.golang.org/grpc" 19 "google.golang.org/grpc/connectivity" 20 ) 21 22 type endorser struct { 23 client peer.EndorserClient 24 closeConnection func() error 25 *endpointConfig 26 } 27 28 type orderer struct { 29 client ab.AtomicBroadcastClient 30 closeConnection func() error 31 *endpointConfig 32 } 33 34 type endpointConfig struct { 35 pkiid common.PKIidType 36 address string 37 mspid string 38 tlsRootCerts [][]byte 39 } 40 41 type ( 42 endorserConnector func(*grpc.ClientConn) peer.EndorserClient 43 ordererConnector func(*grpc.ClientConn) ab.AtomicBroadcastClient 44 ) 45 46 //go:generate counterfeiter -o mocks/dialer.go --fake-name Dialer . dialer 47 type dialer func(ctx context.Context, target string, opts ...grpc.DialOption) (*grpc.ClientConn, error) 48 49 type endpointFactory struct { 50 timeout time.Duration 51 connectEndorser endorserConnector 52 connectOrderer ordererConnector 53 dialer dialer 54 clientCert []byte 55 clientKey []byte 56 } 57 58 func (ef *endpointFactory) newEndorser(pkiid common.PKIidType, address, mspid string, tlsRootCerts [][]byte) (*endorser, error) { 59 conn, err := ef.newConnection(address, tlsRootCerts) 60 if err != nil { 61 return nil, err 62 } 63 connectEndorser := ef.connectEndorser 64 if connectEndorser == nil { 65 connectEndorser = peer.NewEndorserClient 66 } 67 close := func() error { 68 if conn != nil && conn.GetState() != connectivity.Shutdown { 69 logger.Infow("Closing connection to remote endorser", "address", address, "mspid", mspid) 70 return conn.Close() 71 } 72 return nil 73 } 74 return &endorser{ 75 client: connectEndorser(conn), 76 closeConnection: close, 77 endpointConfig: &endpointConfig{pkiid: pkiid, address: address, mspid: mspid, tlsRootCerts: tlsRootCerts}, 78 }, nil 79 } 80 81 func (ef *endpointFactory) newOrderer(address, mspid string, tlsRootCerts [][]byte) (*orderer, error) { 82 conn, err := ef.newConnection(address, tlsRootCerts) 83 if err != nil { 84 return nil, err 85 } 86 connectOrderer := ef.connectOrderer 87 if connectOrderer == nil { 88 connectOrderer = ab.NewAtomicBroadcastClient 89 } 90 return &orderer{ 91 client: connectOrderer(conn), 92 closeConnection: conn.Close, 93 endpointConfig: &endpointConfig{address: address, mspid: mspid, tlsRootCerts: tlsRootCerts}, 94 }, nil 95 } 96 97 func (ef *endpointFactory) newConnection(address string, tlsRootCerts [][]byte) (*grpc.ClientConn, error) { 98 config := comm.ClientConfig{ 99 SecOpts: comm.SecureOptions{ 100 UseTLS: len(tlsRootCerts) > 0, 101 ServerRootCAs: tlsRootCerts, 102 RequireClientCert: true, 103 Certificate: ef.clientCert, 104 Key: ef.clientKey, 105 }, 106 DialTimeout: ef.timeout, 107 } 108 dialOpts, err := config.DialOptions() 109 if err != nil { 110 return nil, err 111 } 112 113 ctx, cancel := context.WithTimeout(context.Background(), ef.timeout) 114 defer cancel() 115 116 dialer := ef.dialer 117 if dialer == nil { 118 dialer = grpc.DialContext 119 } 120 conn, err := dialer(ctx, address, dialOpts...) 121 if err != nil { 122 return nil, fmt.Errorf("failed to create new connection: %w", err) 123 } 124 return conn, nil 125 }