Skip to content

Commit a2b550d

Browse files
committed
[FAB-2861]: Add list channels command to peer cli
In order to be able to retrieve list of channels peer joined to this commit add new peer cli command to issue get channels cscc proposal. E.g.: peer channel list will result with list of channels peer is part of. Change-Id: I0383c7233ebd630b8d401147878be29cb484580b Signed-off-by: Artem Barger <[email protected]>
1 parent 3181e78 commit a2b550d

File tree

3 files changed

+163
-0
lines changed

3 files changed

+163
-0
lines changed

peer/channel/channel.go

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func Cmd(cf *ChannelCmdFactory) *cobra.Command {
5454
channelCmd.AddCommand(joinCmd(cf))
5555
channelCmd.AddCommand(createCmd(cf))
5656
channelCmd.AddCommand(fetchCmd(cf))
57+
channelCmd.AddCommand(listCmd(cf))
5758

5859
return channelCmd
5960
}

peer/channel/list.go

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
Copyright IBM Corp. 2017 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package channel
18+
19+
import (
20+
"errors"
21+
"fmt"
22+
23+
"github.com/golang/protobuf/proto"
24+
"github.com/hyperledger/fabric/core/scc/cscc"
25+
common2 "github.com/hyperledger/fabric/protos/common"
26+
pb "github.com/hyperledger/fabric/protos/peer"
27+
"github.com/hyperledger/fabric/protos/utils"
28+
"github.com/spf13/cobra"
29+
"golang.org/x/net/context"
30+
)
31+
32+
type endorserClient struct {
33+
cf *ChannelCmdFactory
34+
}
35+
36+
func (cc *endorserClient) getChannels() ([]*pb.ChannelInfo, error) {
37+
var err error
38+
39+
invocation := &pb.ChaincodeInvocationSpec{
40+
ChaincodeSpec: &pb.ChaincodeSpec{
41+
Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]),
42+
ChaincodeId: &pb.ChaincodeID{Name: "cscc"},
43+
Input: &pb.ChaincodeInput{Args: [][]byte{[]byte(cscc.GetChannels)}},
44+
},
45+
}
46+
47+
var prop *pb.Proposal
48+
c, _ := cc.cf.Signer.Serialize()
49+
prop, _, err = utils.CreateProposalFromCIS(common2.HeaderType_ENDORSER_TRANSACTION, "", invocation, c)
50+
if err != nil {
51+
return nil, errors.New(fmt.Sprintf("Cannot create proposal, due to %s", err))
52+
}
53+
54+
var signedProp *pb.SignedProposal
55+
signedProp, err = utils.GetSignedProposal(prop, cc.cf.Signer)
56+
if err != nil {
57+
return nil, errors.New(fmt.Sprintf("Cannot create signed proposal, due to %s", err))
58+
}
59+
60+
proposalResp, err := cc.cf.EndorserClient.ProcessProposal(context.Background(), signedProp)
61+
if err != nil {
62+
return nil, errors.New(fmt.Sprintf("Failed sending proposal, got %s", err))
63+
}
64+
65+
if proposalResp.Response == nil || proposalResp.Response.Status != 200 {
66+
return nil, errors.New(fmt.Sprint("Received bad response, status", proposalResp.Response.Status))
67+
}
68+
69+
var channelQueryResponse pb.ChannelQueryResponse
70+
err = proto.Unmarshal(proposalResp.Response.Payload, &channelQueryResponse)
71+
if err != nil {
72+
return nil, errors.New(fmt.Sprintf("Cannot read channels list response, %s", err))
73+
}
74+
75+
return channelQueryResponse.Channels, nil
76+
}
77+
78+
func listCmd(cf *ChannelCmdFactory) *cobra.Command {
79+
// Set the flags on the channel start command.
80+
81+
return &cobra.Command{
82+
Use: "list",
83+
Short: "List of channels peer has been joined to.",
84+
Long: "List of channels peer has been joined to.",
85+
RunE: func(cmd *cobra.Command, args []string) error {
86+
return list(cf)
87+
},
88+
}
89+
}
90+
91+
func list(cf *ChannelCmdFactory) error {
92+
var err error
93+
if cf == nil {
94+
cf, err = InitCmdFactory(true)
95+
if err != nil {
96+
return err
97+
}
98+
}
99+
100+
client := &endorserClient{cf}
101+
102+
if channels, err := client.getChannels(); err != nil {
103+
return err
104+
} else {
105+
fmt.Println("Channels peers has joined to:")
106+
for _, channel := range channels {
107+
fmt.Println("\t", channel.ChannelId)
108+
}
109+
}
110+
111+
return nil
112+
}

peer/channel/list_test.go

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package channel
2+
3+
import (
4+
"testing"
5+
6+
"github.com/golang/protobuf/proto"
7+
"github.com/hyperledger/fabric/peer/common"
8+
pb "github.com/hyperledger/fabric/protos/peer"
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestListChannels(t *testing.T) {
13+
InitMSP()
14+
15+
mockChannelResponse := &pb.ChannelQueryResponse{
16+
Channels: []*pb.ChannelInfo{{
17+
ChannelId: "TEST_LIST_CHANNELS",
18+
}},
19+
}
20+
21+
mockPayload, err := proto.Marshal(mockChannelResponse)
22+
23+
assert.NoError(t, err)
24+
25+
mockResponse := &pb.ProposalResponse{
26+
Response: &pb.Response{
27+
Status: 200,
28+
Payload: mockPayload,
29+
},
30+
Endorsement: &pb.Endorsement{},
31+
}
32+
33+
signer, err := common.GetDefaultSigner()
34+
assert.NoError(t, err)
35+
36+
mockCF := &ChannelCmdFactory{
37+
EndorserClient: common.GetMockEndorserClient(mockResponse, nil),
38+
BroadcastFactory: mockBroadcastClientFactory,
39+
Signer: signer,
40+
}
41+
42+
cmd := listCmd(mockCF)
43+
44+
AddFlags(cmd)
45+
46+
if err := cmd.Execute(); err != nil {
47+
t.Fail()
48+
t.Error(err)
49+
}
50+
}

0 commit comments

Comments
 (0)