github.com/lzy4123/fabric@v2.1.1+incompatible/internal/peer/common/peerclient.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package common 8 9 import ( 10 "context" 11 "crypto/tls" 12 "io/ioutil" 13 "time" 14 15 pb "github.com/hyperledger/fabric-protos-go/peer" 16 "github.com/hyperledger/fabric/core/config" 17 "github.com/hyperledger/fabric/internal/pkg/comm" 18 "github.com/pkg/errors" 19 "github.com/spf13/viper" 20 ) 21 22 // PeerClient represents a client for communicating with a peer 23 type PeerClient struct { 24 CommonClient 25 } 26 27 // NewPeerClientFromEnv creates an instance of a PeerClient from the global 28 // Viper instance 29 func NewPeerClientFromEnv() (*PeerClient, error) { 30 address, override, clientConfig, err := configFromEnv("peer") 31 if err != nil { 32 return nil, errors.WithMessage(err, "failed to load config for PeerClient") 33 } 34 return newPeerClientForClientConfig(address, override, clientConfig) 35 } 36 37 // NewPeerClientForAddress creates an instance of a PeerClient using the 38 // provided peer address and, if TLS is enabled, the TLS root cert file 39 func NewPeerClientForAddress(address, tlsRootCertFile string) (*PeerClient, error) { 40 if address == "" { 41 return nil, errors.New("peer address must be set") 42 } 43 44 override := viper.GetString("peer.tls.serverhostoverride") 45 clientConfig := comm.ClientConfig{} 46 clientConfig.Timeout = viper.GetDuration("peer.client.connTimeout") 47 if clientConfig.Timeout == time.Duration(0) { 48 clientConfig.Timeout = defaultConnTimeout 49 } 50 51 secOpts := comm.SecureOptions{ 52 UseTLS: viper.GetBool("peer.tls.enabled"), 53 RequireClientCert: viper.GetBool("peer.tls.clientAuthRequired"), 54 } 55 56 if secOpts.RequireClientCert { 57 keyPEM, err := ioutil.ReadFile(config.GetPath("peer.tls.clientKey.file")) 58 if err != nil { 59 return nil, errors.WithMessage(err, "unable to load peer.tls.clientKey.file") 60 } 61 secOpts.Key = keyPEM 62 certPEM, err := ioutil.ReadFile(config.GetPath("peer.tls.clientCert.file")) 63 if err != nil { 64 return nil, errors.WithMessage(err, "unable to load peer.tls.clientCert.file") 65 } 66 secOpts.Certificate = certPEM 67 } 68 clientConfig.SecOpts = secOpts 69 70 if clientConfig.SecOpts.UseTLS { 71 if tlsRootCertFile == "" { 72 return nil, errors.New("tls root cert file must be set") 73 } 74 caPEM, res := ioutil.ReadFile(tlsRootCertFile) 75 if res != nil { 76 return nil, errors.WithMessagef(res, "unable to load TLS root cert file from %s", tlsRootCertFile) 77 } 78 clientConfig.SecOpts.ServerRootCAs = [][]byte{caPEM} 79 } 80 return newPeerClientForClientConfig(address, override, clientConfig) 81 } 82 83 func newPeerClientForClientConfig(address, override string, clientConfig comm.ClientConfig) (*PeerClient, error) { 84 // set the default keepalive options to match the server 85 clientConfig.KaOpts = comm.DefaultKeepaliveOptions 86 gClient, err := comm.NewGRPCClient(clientConfig) 87 if err != nil { 88 return nil, errors.WithMessage(err, "failed to create PeerClient from config") 89 } 90 pClient := &PeerClient{ 91 CommonClient: CommonClient{ 92 GRPCClient: gClient, 93 Address: address, 94 sn: override}} 95 return pClient, nil 96 } 97 98 // Endorser returns a client for the Endorser service 99 func (pc *PeerClient) Endorser() (pb.EndorserClient, error) { 100 conn, err := pc.CommonClient.NewConnection(pc.Address, comm.ServerNameOverride(pc.sn)) 101 if err != nil { 102 return nil, errors.WithMessagef(err, "endorser client failed to connect to %s", pc.Address) 103 } 104 return pb.NewEndorserClient(conn), nil 105 } 106 107 // Deliver returns a client for the Deliver service 108 func (pc *PeerClient) Deliver() (pb.Deliver_DeliverClient, error) { 109 conn, err := pc.CommonClient.NewConnection(pc.Address, comm.ServerNameOverride(pc.sn)) 110 if err != nil { 111 return nil, errors.WithMessagef(err, "deliver client failed to connect to %s", pc.Address) 112 } 113 return pb.NewDeliverClient(conn).Deliver(context.TODO()) 114 } 115 116 // PeerDeliver returns a client for the Deliver service for peer-specific use 117 // cases (i.e. DeliverFiltered) 118 func (pc *PeerClient) PeerDeliver() (pb.DeliverClient, error) { 119 conn, err := pc.CommonClient.NewConnection(pc.Address, comm.ServerNameOverride(pc.sn)) 120 if err != nil { 121 return nil, errors.WithMessagef(err, "deliver client failed to connect to %s", pc.Address) 122 } 123 return pb.NewDeliverClient(conn), nil 124 } 125 126 // Certificate returns the TLS client certificate (if available) 127 func (pc *PeerClient) Certificate() tls.Certificate { 128 return pc.CommonClient.Certificate() 129 } 130 131 // GetEndorserClient returns a new endorser client. If the both the address and 132 // tlsRootCertFile are not provided, the target values for the client are taken 133 // from the configuration settings for "peer.address" and 134 // "peer.tls.rootcert.file" 135 func GetEndorserClient(address, tlsRootCertFile string) (pb.EndorserClient, error) { 136 var peerClient *PeerClient 137 var err error 138 if address != "" { 139 peerClient, err = NewPeerClientForAddress(address, tlsRootCertFile) 140 } else { 141 peerClient, err = NewPeerClientFromEnv() 142 } 143 if err != nil { 144 return nil, err 145 } 146 return peerClient.Endorser() 147 } 148 149 // GetCertificate returns the client's TLS certificate 150 func GetCertificate() (tls.Certificate, error) { 151 peerClient, err := NewPeerClientFromEnv() 152 if err != nil { 153 return tls.Certificate{}, err 154 } 155 return peerClient.Certificate(), nil 156 } 157 158 // GetDeliverClient returns a new deliver client. If both the address and 159 // tlsRootCertFile are not provided, the target values for the client are taken 160 // from the configuration settings for "peer.address" and 161 // "peer.tls.rootcert.file" 162 func GetDeliverClient(address, tlsRootCertFile string) (pb.Deliver_DeliverClient, error) { 163 var peerClient *PeerClient 164 var err error 165 if address != "" { 166 peerClient, err = NewPeerClientForAddress(address, tlsRootCertFile) 167 } else { 168 peerClient, err = NewPeerClientFromEnv() 169 } 170 if err != nil { 171 return nil, err 172 } 173 return peerClient.Deliver() 174 } 175 176 // GetPeerDeliverClient returns a new deliver client. If both the address and 177 // tlsRootCertFile are not provided, the target values for the client are taken 178 // from the configuration settings for "peer.address" and 179 // "peer.tls.rootcert.file" 180 func GetPeerDeliverClient(address, tlsRootCertFile string) (pb.DeliverClient, error) { 181 var peerClient *PeerClient 182 var err error 183 if address != "" { 184 peerClient, err = NewPeerClientForAddress(address, tlsRootCertFile) 185 } else { 186 peerClient, err = NewPeerClientFromEnv() 187 } 188 if err != nil { 189 return nil, err 190 } 191 return peerClient.PeerDeliver() 192 }