github.com/yimialmonte/fabric@v2.1.1+incompatible/discovery/cmd/peers.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package discovery
     8  
     9  import (
    10  	"encoding/json"
    11  	"fmt"
    12  	"io"
    13  
    14  	"github.com/golang/protobuf/proto"
    15  	"github.com/hyperledger/fabric-protos-go/msp"
    16  	"github.com/hyperledger/fabric/cmd/common"
    17  	discovery "github.com/hyperledger/fabric/discovery/client"
    18  	"github.com/pkg/errors"
    19  )
    20  
    21  // NewPeerCmd creates a new PeerCmd with the given Stub and ResponseParser
    22  func NewPeerCmd(stub Stub, parser ResponseParser) *PeerCmd {
    23  	return &PeerCmd{
    24  		stub:   stub,
    25  		parser: parser,
    26  	}
    27  }
    28  
    29  // PeerCmd executes channelPeer listing command
    30  type PeerCmd struct {
    31  	stub    Stub
    32  	server  *string
    33  	channel *string
    34  	parser  ResponseParser
    35  }
    36  
    37  // SetServer sets the server of the PeerCmd
    38  func (pc *PeerCmd) SetServer(server *string) {
    39  	pc.server = server
    40  }
    41  
    42  // SetChannel sets the channel of the PeerCmd
    43  func (pc *PeerCmd) SetChannel(channel *string) {
    44  	pc.channel = channel
    45  }
    46  
    47  // Execute executes the command
    48  func (pc *PeerCmd) Execute(conf common.Config) error {
    49  	channel := ""
    50  
    51  	if pc.channel != nil {
    52  		channel = *pc.channel
    53  	}
    54  
    55  	if pc.server == nil || *pc.server == "" {
    56  		return errors.New("no server specified")
    57  	}
    58  
    59  	server := *pc.server
    60  
    61  	req := discovery.NewRequest()
    62  	if channel != "" {
    63  		req = req.OfChannel(channel)
    64  		req = req.AddPeersQuery()
    65  	} else {
    66  		req = req.AddLocalPeersQuery()
    67  	}
    68  	res, err := pc.stub.Send(server, conf, req)
    69  	if err != nil {
    70  		return err
    71  	}
    72  	return pc.parser.ParseResponse(channel, res)
    73  }
    74  
    75  // PeerResponseParser parses a channelPeer response
    76  type PeerResponseParser struct {
    77  	io.Writer
    78  }
    79  
    80  // ParseResponse parses the given response about the given channel
    81  func (parser *PeerResponseParser) ParseResponse(channel string, res ServiceResponse) error {
    82  	var listPeers peerLister
    83  	if channel == "" {
    84  		listPeers = res.ForLocal()
    85  	} else {
    86  		listPeers = &simpleChannelResponse{res.ForChannel(channel)}
    87  	}
    88  	peers, err := listPeers.Peers()
    89  	if err != nil {
    90  		return err
    91  	}
    92  
    93  	channelState := channel != ""
    94  	b, _ := json.MarshalIndent(assemblePeers(peers, channelState), "", "\t")
    95  	fmt.Fprintln(parser.Writer, string(b))
    96  	return nil
    97  }
    98  
    99  func assemblePeers(peers []*discovery.Peer, withChannelState bool) interface{} {
   100  	if withChannelState {
   101  		var peerSlices []channelPeer
   102  		for _, p := range peers {
   103  			peerSlices = append(peerSlices, rawPeerToChannelPeer(p))
   104  		}
   105  		return peerSlices
   106  	}
   107  	var peerSlices []localPeer
   108  	for _, p := range peers {
   109  		peerSlices = append(peerSlices, rawPeerToLocalPeer(p))
   110  	}
   111  	return peerSlices
   112  }
   113  
   114  type channelPeer struct {
   115  	MSPID        string
   116  	LedgerHeight uint64
   117  	Endpoint     string
   118  	Identity     string
   119  	Chaincodes   []string
   120  }
   121  
   122  type localPeer struct {
   123  	MSPID    string
   124  	Endpoint string
   125  	Identity string
   126  }
   127  
   128  type peerLister interface {
   129  	Peers() ([]*discovery.Peer, error)
   130  }
   131  
   132  type simpleChannelResponse struct {
   133  	discovery.ChannelResponse
   134  }
   135  
   136  func (scr *simpleChannelResponse) Peers() ([]*discovery.Peer, error) {
   137  	return scr.ChannelResponse.Peers()
   138  }
   139  
   140  func rawPeerToChannelPeer(p *discovery.Peer) channelPeer {
   141  	var ledgerHeight uint64
   142  	var ccs []string
   143  	if p.StateInfoMessage != nil && p.StateInfoMessage.GetStateInfo() != nil && p.StateInfoMessage.GetStateInfo().Properties != nil {
   144  		properties := p.StateInfoMessage.GetStateInfo().Properties
   145  		ledgerHeight = properties.LedgerHeight
   146  		for _, cc := range properties.Chaincodes {
   147  			if cc == nil {
   148  				continue
   149  			}
   150  			ccs = append(ccs, cc.Name)
   151  		}
   152  	}
   153  	var endpoint string
   154  	if p.AliveMessage != nil && p.AliveMessage.GetAliveMsg() != nil && p.AliveMessage.GetAliveMsg().Membership != nil {
   155  		endpoint = p.AliveMessage.GetAliveMsg().Membership.Endpoint
   156  	}
   157  	sID := &msp.SerializedIdentity{}
   158  	proto.Unmarshal(p.Identity, sID)
   159  	return channelPeer{
   160  		MSPID:        p.MSPID,
   161  		Endpoint:     endpoint,
   162  		LedgerHeight: ledgerHeight,
   163  		Identity:     string(sID.IdBytes),
   164  		Chaincodes:   ccs,
   165  	}
   166  }
   167  
   168  func rawPeerToLocalPeer(p *discovery.Peer) localPeer {
   169  	var endpoint string
   170  	if p.AliveMessage != nil && p.AliveMessage.GetAliveMsg() != nil && p.AliveMessage.GetAliveMsg().Membership != nil {
   171  		endpoint = p.AliveMessage.GetAliveMsg().Membership.Endpoint
   172  	}
   173  	sID := &msp.SerializedIdentity{}
   174  	proto.Unmarshal(p.Identity, sID)
   175  	return localPeer{
   176  		MSPID:    p.MSPID,
   177  		Endpoint: endpoint,
   178  		Identity: string(sID.IdBytes),
   179  	}
   180  }