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 }