github.com/kaituanwang/hyperledger@v2.0.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/comm" 17 "github.com/hyperledger/fabric/core/config" 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 gClient, err := comm.NewGRPCClient(clientConfig) 85 if err != nil { 86 return nil, errors.WithMessage(err, "failed to create PeerClient from config") 87 } 88 pClient := &PeerClient{ 89 CommonClient: CommonClient{ 90 GRPCClient: gClient, 91 Address: address, 92 sn: override}} 93 return pClient, nil 94 } 95 96 // Endorser returns a client for the Endorser service 97 func (pc *PeerClient) Endorser() (pb.EndorserClient, error) { 98 conn, err := pc.CommonClient.NewConnection(pc.Address, comm.ServerNameOverride(pc.sn)) 99 if err != nil { 100 return nil, errors.WithMessagef(err, "endorser client failed to connect to %s", pc.Address) 101 } 102 return pb.NewEndorserClient(conn), nil 103 } 104 105 // Deliver returns a client for the Deliver service 106 func (pc *PeerClient) Deliver() (pb.Deliver_DeliverClient, error) { 107 conn, err := pc.CommonClient.NewConnection(pc.Address, comm.ServerNameOverride(pc.sn)) 108 if err != nil { 109 return nil, errors.WithMessagef(err, "deliver client failed to connect to %s", pc.Address) 110 } 111 return pb.NewDeliverClient(conn).Deliver(context.TODO()) 112 } 113 114 // PeerDeliver returns a client for the Deliver service for peer-specific use 115 // cases (i.e. DeliverFiltered) 116 func (pc *PeerClient) PeerDeliver() (pb.DeliverClient, error) { 117 conn, err := pc.CommonClient.NewConnection(pc.Address, comm.ServerNameOverride(pc.sn)) 118 if err != nil { 119 return nil, errors.WithMessagef(err, "deliver client failed to connect to %s", pc.Address) 120 } 121 return pb.NewDeliverClient(conn), nil 122 } 123 124 // Certificate returns the TLS client certificate (if available) 125 func (pc *PeerClient) Certificate() tls.Certificate { 126 return pc.CommonClient.Certificate() 127 } 128 129 // GetEndorserClient returns a new endorser client. If the both the address and 130 // tlsRootCertFile are not provided, the target values for the client are taken 131 // from the configuration settings for "peer.address" and 132 // "peer.tls.rootcert.file" 133 func GetEndorserClient(address, tlsRootCertFile string) (pb.EndorserClient, error) { 134 var peerClient *PeerClient 135 var err error 136 if address != "" { 137 peerClient, err = NewPeerClientForAddress(address, tlsRootCertFile) 138 } else { 139 peerClient, err = NewPeerClientFromEnv() 140 } 141 if err != nil { 142 return nil, err 143 } 144 return peerClient.Endorser() 145 } 146 147 // GetCertificate returns the client's TLS certificate 148 func GetCertificate() (tls.Certificate, error) { 149 peerClient, err := NewPeerClientFromEnv() 150 if err != nil { 151 return tls.Certificate{}, err 152 } 153 return peerClient.Certificate(), nil 154 } 155 156 // GetDeliverClient returns a new deliver client. If both the address and 157 // tlsRootCertFile are not provided, the target values for the client are taken 158 // from the configuration settings for "peer.address" and 159 // "peer.tls.rootcert.file" 160 func GetDeliverClient(address, tlsRootCertFile string) (pb.Deliver_DeliverClient, error) { 161 var peerClient *PeerClient 162 var err error 163 if address != "" { 164 peerClient, err = NewPeerClientForAddress(address, tlsRootCertFile) 165 } else { 166 peerClient, err = NewPeerClientFromEnv() 167 } 168 if err != nil { 169 return nil, err 170 } 171 return peerClient.Deliver() 172 } 173 174 // GetPeerDeliverClient returns a new deliver client. If both the address and 175 // tlsRootCertFile are not provided, the target values for the client are taken 176 // from the configuration settings for "peer.address" and 177 // "peer.tls.rootcert.file" 178 func GetPeerDeliverClient(address, tlsRootCertFile string) (pb.DeliverClient, error) { 179 var peerClient *PeerClient 180 var err error 181 if address != "" { 182 peerClient, err = NewPeerClientForAddress(address, tlsRootCertFile) 183 } else { 184 peerClient, err = NewPeerClientFromEnv() 185 } 186 if err != nil { 187 return nil, err 188 } 189 return peerClient.PeerDeliver() 190 }