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  }