@@ -17,22 +17,61 @@ import (
17
17
"github.com/hyperledger/fabric/protoutil"
18
18
"github.com/pkg/errors"
19
19
"github.com/spf13/cobra"
20
+ "github.com/spf13/viper"
20
21
)
21
22
22
- var (
23
- chaincodeQueryCommittedCmd * cobra.Command
24
- )
23
+ // CommittedQuerier holds the dependencies needed to query
24
+ // the committed chaincode definitions
25
+ type CommittedQuerier struct {
26
+ Command * cobra.Command
27
+ Input * CommittedQueryInput
28
+ EndorserClient EndorserClient
29
+ Signer Signer
30
+ }
25
31
26
- // queryCommittedCmd returns the cobra command for
32
+ type CommittedQueryInput struct {
33
+ ChannelID string
34
+ Name string
35
+ }
36
+
37
+ // QueryCommittedCmd returns the cobra command for
27
38
// querying a committed chaincode definition given
28
39
// the chaincode name
29
- func queryCommittedCmd ( cf * CmdFactory ) * cobra.Command {
30
- chaincodeQueryCommittedCmd = & cobra.Command {
40
+ func QueryCommittedCmd ( c * CommittedQuerier ) * cobra.Command {
41
+ chaincodeQueryCommittedCmd : = & cobra.Command {
31
42
Use : "querycommitted" ,
32
- Short : "Query a committed chaincode definition by name on a peer." ,
33
- Long : "Query a committed chaincode definition by name on a peer." ,
43
+ Short : "Query a committed chaincode definition by channel and name on a peer." ,
44
+ Long : "Query a committed chaincode definition by channel and name on a peer." ,
34
45
RunE : func (cmd * cobra.Command , args []string ) error {
35
- return queryCommitted (cmd , cf )
46
+ if c == nil {
47
+ ccInput := & ClientConnectionsInput {
48
+ CommandName : cmd .Name (),
49
+ EndorserRequired : true ,
50
+ ChannelID : channelID ,
51
+ PeerAddresses : peerAddresses ,
52
+ TLSRootCertFiles : tlsRootCertFiles ,
53
+ ConnectionProfilePath : connectionProfilePath ,
54
+ TLSEnabled : viper .GetBool ("peer.tls.enabled" ),
55
+ }
56
+
57
+ cc , err := NewClientConnections (ccInput )
58
+ if err != nil {
59
+ return err
60
+ }
61
+
62
+ cqInput := & CommittedQueryInput {
63
+ ChannelID : channelID ,
64
+ Name : chaincodeName ,
65
+ }
66
+
67
+ c = & CommittedQuerier {
68
+ Command : cmd ,
69
+ EndorserClient : cc .EndorserClients [0 ],
70
+ Input : cqInput ,
71
+ Signer : cc .Signer ,
72
+ }
73
+ }
74
+ return c .Query ()
36
75
},
37
76
}
38
77
@@ -48,72 +87,84 @@ func queryCommittedCmd(cf *CmdFactory) *cobra.Command {
48
87
return chaincodeQueryCommittedCmd
49
88
}
50
89
51
- func queryCommitted (cmd * cobra.Command , cf * CmdFactory ) error {
52
- // Parsing of the command line is done so silence cmd usage
53
- cmd .SilenceUsage = true
54
-
55
- var err error
56
- if cf == nil {
57
- cf , err = InitCmdFactory (cmd .Name (), true , false )
58
- if err != nil {
59
- return err
60
- }
90
+ // Query returns the committed chaincode definition
91
+ // for a given channel and chaincode name
92
+ func (c * CommittedQuerier ) Query () error {
93
+ if c .Command != nil {
94
+ // Parsing of the command line is done so silence cmd usage
95
+ c .Command .SilenceUsage = true
61
96
}
62
97
63
- creator , err := cf . Signer . Serialize ()
98
+ err := c . validateInput ()
64
99
if err != nil {
65
- return fmt . Errorf ( "Error serializing identity: %s" , err )
100
+ return err
66
101
}
67
102
68
- proposal , err := createQueryCommittedChaincodeDefinitionProposal ( channelID , chaincodeName , creator )
103
+ proposal , err := c . createProposal ( )
69
104
if err != nil {
70
- return errors .WithMessage (err , "error creating proposal" )
105
+ return errors .WithMessage (err , "failed to create proposal" )
71
106
}
72
107
73
- signedProposal , err := protoutil . GetSignedProposal (proposal , cf .Signer )
108
+ signedProposal , err := signProposal (proposal , c .Signer )
74
109
if err != nil {
75
- return errors .WithMessage (err , "error creating signed proposal" )
110
+ return errors .WithMessage (err , "failed to create signed proposal" )
76
111
}
77
112
78
- // QueryCommittedChaincodeDefinition is currently only supported for one peer
79
- proposalResponse , err := cf .EndorserClients [0 ].ProcessProposal (context .Background (), signedProposal )
113
+ proposalResponse , err := c .EndorserClient .ProcessProposal (context .Background (), signedProposal )
80
114
if err != nil {
81
- return errors .WithMessage (err , "error endorsing proposal" )
115
+ return errors .WithMessage (err , "failed to endorse proposal" )
116
+ }
117
+
118
+ if proposalResponse == nil {
119
+ return errors .New ("received nil proposal response" )
82
120
}
83
121
84
122
if proposalResponse .Response == nil {
85
- return errors .Errorf ( " proposal response had nil response" )
123
+ return errors .New ( "received proposal response with nil response" )
86
124
}
87
125
88
126
if proposalResponse .Response .Status != int32 (cb .Status_SUCCESS ) {
89
- return errors .Errorf ("bad response : %d - %s" , proposalResponse .Response .Status , proposalResponse .Response .Message )
127
+ return errors .Errorf ("query failed with status : %d - %s" , proposalResponse .Response .Status , proposalResponse .Response .Message )
90
128
}
91
129
92
- return printQueryCommittedResponse (proposalResponse )
130
+ return c . printResponse (proposalResponse )
93
131
}
94
132
95
133
// printResponse prints the information included in the response
96
134
// from the server.
97
- func printQueryCommittedResponse (proposalResponse * pb.ProposalResponse ) error {
135
+ func ( c * CommittedQuerier ) printResponse (proposalResponse * pb.ProposalResponse ) error {
98
136
qdcr := & lb.QueryChaincodeDefinitionResult {}
99
137
err := proto .Unmarshal (proposalResponse .Response .Payload , qdcr )
100
138
if err != nil {
101
- return err
139
+ return errors . Wrap ( err , "failed to unmarshal proposal response's response payload" )
102
140
}
103
141
fmt .Printf ("Committed chaincode definition for chaincode '%s' on channel '%s':\n " , chaincodeName , channelID )
104
142
fmt .Printf ("Version: %s, Sequence: %d, Endorsement Plugin: %s, Validation Plugin: %s\n " , qdcr .Version , qdcr .Sequence , qdcr .EndorsementPlugin , qdcr .ValidationPlugin )
143
+
105
144
return nil
106
145
107
146
}
108
147
109
- func createQueryCommittedChaincodeDefinitionProposal (channelID , chaincodeName string , creatorBytes []byte ) (* pb.Proposal , error ) {
148
+ func (c * CommittedQuerier ) validateInput () error {
149
+ if c .Input .ChannelID == "" {
150
+ return errors .New ("channel name must be specified" )
151
+ }
152
+
153
+ if c .Input .Name == "" {
154
+ return errors .New ("chaincode name must be specified" )
155
+ }
156
+
157
+ return nil
158
+ }
159
+
160
+ func (c * CommittedQuerier ) createProposal () (* pb.Proposal , error ) {
110
161
args := & lb.QueryChaincodeDefinitionArgs {
111
- Name : chaincodeName ,
162
+ Name : c . Input . Name ,
112
163
}
113
164
114
165
argsBytes , err := proto .Marshal (args )
115
166
if err != nil {
116
- return nil , err
167
+ return nil , errors . Wrap ( err , "failed to marshal args" )
117
168
}
118
169
ccInput := & pb.ChaincodeInput {Args : [][]byte {[]byte ("QueryChaincodeDefinition" ), argsBytes }}
119
170
@@ -124,9 +175,14 @@ func createQueryCommittedChaincodeDefinitionProposal(channelID, chaincodeName st
124
175
},
125
176
}
126
177
127
- proposal , _ , err := protoutil .CreateProposalFromCIS (cb .HeaderType_ENDORSER_TRANSACTION , channelID , cis , creatorBytes )
178
+ signerSerialized , err := c .Signer .Serialize ()
179
+ if err != nil {
180
+ return nil , errors .WithMessage (err , "failed to serialize identity" )
181
+ }
182
+
183
+ proposal , _ , err := protoutil .CreateProposalFromCIS (cb .HeaderType_ENDORSER_TRANSACTION , c .Input .ChannelID , cis , signerSerialized )
128
184
if err != nil {
129
- return nil , errors .WithMessage (err , "error creating proposal for ChaincodeInvocationSpec" )
185
+ return nil , errors .WithMessage (err , "failed to create ChaincodeInvocationSpec proposal " )
130
186
}
131
187
132
188
return proposal , nil
0 commit comments