github.com/anjalikarhana/fabric@v2.1.1+incompatible/internal/peer/lifecycle/chaincode/queryinstalled.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package chaincode
     8  
     9  import (
    10  	"context"
    11  	"fmt"
    12  	"io"
    13  	"os"
    14  	"strings"
    15  
    16  	"github.com/golang/protobuf/proto"
    17  	cb "github.com/hyperledger/fabric-protos-go/common"
    18  	pb "github.com/hyperledger/fabric-protos-go/peer"
    19  	lb "github.com/hyperledger/fabric-protos-go/peer/lifecycle"
    20  	"github.com/hyperledger/fabric/bccsp"
    21  	"github.com/hyperledger/fabric/protoutil"
    22  	"github.com/pkg/errors"
    23  	"github.com/spf13/cobra"
    24  	"github.com/spf13/viper"
    25  )
    26  
    27  // InstalledQuerier holds the dependencies needed to query
    28  // the installed chaincodes
    29  type InstalledQuerier struct {
    30  	Command        *cobra.Command
    31  	Input          *InstalledQueryInput
    32  	EndorserClient EndorserClient
    33  	Signer         Signer
    34  	Writer         io.Writer
    35  }
    36  
    37  type InstalledQueryInput struct {
    38  	OutputFormat string
    39  }
    40  
    41  // QueryInstalledCmd returns the cobra command for listing
    42  // the installed chaincodes
    43  func QueryInstalledCmd(i *InstalledQuerier, cryptoProvider bccsp.BCCSP) *cobra.Command {
    44  	chaincodeQueryInstalledCmd := &cobra.Command{
    45  		Use:   "queryinstalled",
    46  		Short: "Query the installed chaincodes on a peer.",
    47  		Long:  "Query the installed chaincodes on a peer.",
    48  		RunE: func(cmd *cobra.Command, args []string) error {
    49  			if i == nil {
    50  				ccInput := &ClientConnectionsInput{
    51  					CommandName:           cmd.Name(),
    52  					EndorserRequired:      true,
    53  					ChannelID:             channelID,
    54  					PeerAddresses:         peerAddresses,
    55  					TLSRootCertFiles:      tlsRootCertFiles,
    56  					ConnectionProfilePath: connectionProfilePath,
    57  					TLSEnabled:            viper.GetBool("peer.tls.enabled"),
    58  				}
    59  
    60  				cc, err := NewClientConnections(ccInput, cryptoProvider)
    61  				if err != nil {
    62  					return err
    63  				}
    64  
    65  				iqInput := &InstalledQueryInput{
    66  					OutputFormat: output,
    67  				}
    68  
    69  				// queryinstalled only supports one peer connection,
    70  				// which is why we only wire in the first endorser
    71  				// client
    72  				i = &InstalledQuerier{
    73  					Command:        cmd,
    74  					EndorserClient: cc.EndorserClients[0],
    75  					Input:          iqInput,
    76  					Signer:         cc.Signer,
    77  					Writer:         os.Stdout,
    78  				}
    79  			}
    80  			return i.Query()
    81  		},
    82  	}
    83  
    84  	flagList := []string{
    85  		"peerAddresses",
    86  		"tlsRootCertFiles",
    87  		"connectionProfile",
    88  		"output",
    89  	}
    90  	attachFlags(chaincodeQueryInstalledCmd, flagList)
    91  
    92  	return chaincodeQueryInstalledCmd
    93  }
    94  
    95  // Query returns the chaincodes installed on a peer
    96  func (i *InstalledQuerier) Query() error {
    97  	if i.Command != nil {
    98  		// Parsing of the command line is done so silence cmd usage
    99  		i.Command.SilenceUsage = true
   100  	}
   101  
   102  	proposal, err := i.createProposal()
   103  	if err != nil {
   104  		return errors.WithMessage(err, "failed to create proposal")
   105  	}
   106  
   107  	signedProposal, err := signProposal(proposal, i.Signer)
   108  	if err != nil {
   109  		return errors.WithMessage(err, "failed to create signed proposal")
   110  	}
   111  
   112  	proposalResponse, err := i.EndorserClient.ProcessProposal(context.Background(), signedProposal)
   113  	if err != nil {
   114  		return errors.WithMessage(err, "failed to endorse proposal")
   115  	}
   116  
   117  	if proposalResponse == nil {
   118  		return errors.New("received nil proposal response")
   119  	}
   120  
   121  	if proposalResponse.Response == nil {
   122  		return errors.New("received proposal response with nil response")
   123  	}
   124  
   125  	if proposalResponse.Response.Status != int32(cb.Status_SUCCESS) {
   126  		return errors.Errorf("query failed with status: %d - %s", proposalResponse.Response.Status, proposalResponse.Response.Message)
   127  	}
   128  
   129  	if strings.ToLower(i.Input.OutputFormat) == "json" {
   130  		return printResponseAsJSON(proposalResponse, &lb.QueryInstalledChaincodesResult{}, i.Writer)
   131  	}
   132  	return i.printResponse(proposalResponse)
   133  }
   134  
   135  // printResponse prints the information included in the response
   136  // from the server.
   137  func (i *InstalledQuerier) printResponse(proposalResponse *pb.ProposalResponse) error {
   138  	qicr := &lb.QueryInstalledChaincodesResult{}
   139  	err := proto.Unmarshal(proposalResponse.Response.Payload, qicr)
   140  	if err != nil {
   141  		return errors.Wrap(err, "failed to unmarshal proposal response's response payload")
   142  	}
   143  	fmt.Fprintln(i.Writer, "Installed chaincodes on peer:")
   144  	for _, chaincode := range qicr.InstalledChaincodes {
   145  		fmt.Fprintf(i.Writer, "Package ID: %s, Label: %s\n", chaincode.PackageId, chaincode.Label)
   146  	}
   147  	return nil
   148  }
   149  
   150  func (i *InstalledQuerier) createProposal() (*pb.Proposal, error) {
   151  	args := &lb.QueryInstalledChaincodesArgs{}
   152  
   153  	argsBytes, err := proto.Marshal(args)
   154  	if err != nil {
   155  		return nil, errors.Wrap(err, "failed to marshal args")
   156  	}
   157  
   158  	ccInput := &pb.ChaincodeInput{
   159  		Args: [][]byte{[]byte("QueryInstalledChaincodes"), argsBytes},
   160  	}
   161  
   162  	cis := &pb.ChaincodeInvocationSpec{
   163  		ChaincodeSpec: &pb.ChaincodeSpec{
   164  			ChaincodeId: &pb.ChaincodeID{Name: lifecycleName},
   165  			Input:       ccInput,
   166  		},
   167  	}
   168  
   169  	signerSerialized, err := i.Signer.Serialize()
   170  	if err != nil {
   171  		return nil, errors.WithMessage(err, "failed to serialize identity")
   172  	}
   173  
   174  	proposal, _, err := protoutil.CreateProposalFromCIS(cb.HeaderType_ENDORSER_TRANSACTION, "", cis, signerSerialized)
   175  	if err != nil {
   176  		return nil, errors.WithMessage(err, "failed to create ChaincodeInvocationSpec proposal")
   177  	}
   178  
   179  	return proposal, nil
   180  }