github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/peer/channel/channel.go (about)

     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  	"fmt"
    21  	"strings"
    22  
    23  	"github.com/hyperledger/fabric/common/flogging"
    24  	"github.com/hyperledger/fabric/msp"
    25  	"github.com/hyperledger/fabric/peer/common"
    26  	ab "github.com/hyperledger/fabric/protos/orderer"
    27  	pb "github.com/hyperledger/fabric/protos/peer"
    28  	"github.com/spf13/cobra"
    29  	"github.com/spf13/pflag"
    30  	"golang.org/x/net/context"
    31  	"google.golang.org/grpc"
    32  	"google.golang.org/grpc/credentials"
    33  )
    34  
    35  const (
    36  	channelFuncName = "channel"
    37  	shortDes        = "Operate a channel: create|fetch|join|list|update."
    38  	longDes         = "Operate a channel: create|fetch|join|list|update."
    39  )
    40  
    41  var logger = flogging.MustGetLogger("channelCmd")
    42  
    43  type OrdererRequirement bool
    44  type EndorserRequirement bool
    45  
    46  const (
    47  	EndorserRequired    EndorserRequirement = true
    48  	EndorserNotRequired EndorserRequirement = false
    49  	OrdererRequired     OrdererRequirement  = true
    50  	OrdererNotRequired  OrdererRequirement  = false
    51  )
    52  
    53  var (
    54  	// join related variables.
    55  	genesisBlockPath string
    56  
    57  	// create related variables
    58  	chainID                    string
    59  	channelTxFile              string
    60  	orderingEndpoint           string
    61  	tls                        bool
    62  	caFile                     string
    63  	ordererTLSHostnameOverride string
    64  	timeout                    int
    65  )
    66  
    67  // Cmd returns the cobra command for Node
    68  func Cmd(cf *ChannelCmdFactory) *cobra.Command {
    69  	AddFlags(channelCmd)
    70  
    71  	channelCmd.AddCommand(createCmd(cf))
    72  	channelCmd.AddCommand(fetchCmd(cf))
    73  	channelCmd.AddCommand(joinCmd(cf))
    74  	channelCmd.AddCommand(listCmd(cf))
    75  	channelCmd.AddCommand(updateCmd(cf))
    76  
    77  	return channelCmd
    78  }
    79  
    80  // AddFlags adds flags for create and join
    81  func AddFlags(cmd *cobra.Command) {
    82  	flags := cmd.PersistentFlags()
    83  
    84  	flags.StringVarP(&orderingEndpoint, "orderer", "o", "", "Ordering service endpoint")
    85  	flags.BoolVarP(&tls, "tls", "", false, "Use TLS when communicating with the orderer endpoint")
    86  	flags.StringVarP(&caFile, "cafile", "", "", "Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint")
    87  	flags.StringVarP(&ordererTLSHostnameOverride, "ordererTLSHostnameOverride", "", "", "The hostname override to use when validating the TLS connection to the orderer.")
    88  }
    89  
    90  var flags *pflag.FlagSet
    91  
    92  func init() {
    93  	resetFlags()
    94  }
    95  
    96  // Explicitly define a method to facilitate tests
    97  func resetFlags() {
    98  	flags = &pflag.FlagSet{}
    99  
   100  	flags.StringVarP(&genesisBlockPath, "blockpath", "b", common.UndefinedParamValue, "Path to file containing genesis block")
   101  	flags.StringVarP(&chainID, "channelID", "c", common.UndefinedParamValue, "In case of a newChain command, the channel ID to create.")
   102  	flags.StringVarP(&channelTxFile, "file", "f", "", "Configuration transaction file generated by a tool such as configtxgen for submitting to orderer")
   103  	flags.IntVarP(&timeout, "timeout", "t", 5, "Channel creation timeout")
   104  }
   105  
   106  func attachFlags(cmd *cobra.Command, names []string) {
   107  	cmdFlags := cmd.Flags()
   108  	for _, name := range names {
   109  		if flag := flags.Lookup(name); flag != nil {
   110  			cmdFlags.AddFlag(flag)
   111  		} else {
   112  			logger.Fatalf("Could not find flag '%s' to attach to commond '%s'", name, cmd.Name())
   113  		}
   114  	}
   115  }
   116  
   117  var channelCmd = &cobra.Command{
   118  	Use:   channelFuncName,
   119  	Short: fmt.Sprint(shortDes),
   120  	Long:  fmt.Sprint(longDes),
   121  }
   122  
   123  type BroadcastClientFactory func() (common.BroadcastClient, error)
   124  
   125  // ChannelCmdFactory holds the clients used by ChannelCmdFactory
   126  type ChannelCmdFactory struct {
   127  	EndorserClient   pb.EndorserClient
   128  	Signer           msp.SigningIdentity
   129  	BroadcastClient  common.BroadcastClient
   130  	DeliverClient    deliverClientIntf
   131  	BroadcastFactory BroadcastClientFactory
   132  }
   133  
   134  // InitCmdFactory init the ChannelCmdFactory with clients to endorser and orderer according to params
   135  func InitCmdFactory(isEndorserRequired EndorserRequirement, isOrdererRequired OrdererRequirement) (*ChannelCmdFactory, error) {
   136  	var err error
   137  
   138  	cmdFact := &ChannelCmdFactory{}
   139  
   140  	cmdFact.Signer, err = common.GetDefaultSignerFnc()
   141  	if err != nil {
   142  		return nil, fmt.Errorf("Error getting default signer: %s", err)
   143  	}
   144  
   145  	cmdFact.BroadcastFactory = func() (common.BroadcastClient, error) {
   146  		return common.GetBroadcastClientFnc(orderingEndpoint, tls, caFile)
   147  	}
   148  
   149  	//for join and list, we need the endorser as well
   150  	if isEndorserRequired {
   151  		cmdFact.EndorserClient, err = common.GetEndorserClientFnc()
   152  		if err != nil {
   153  			return nil, fmt.Errorf("Error getting endorser client %s: %s", channelFuncName, err)
   154  		}
   155  	}
   156  
   157  	//for create and fetch, we need the orderer as well
   158  	if isOrdererRequired {
   159  		if len(strings.Split(orderingEndpoint, ":")) != 2 {
   160  			return nil, fmt.Errorf("Ordering service endpoint %s is not valid or missing", orderingEndpoint)
   161  		}
   162  
   163  		var opts []grpc.DialOption
   164  		// check for TLS
   165  		if tls {
   166  			if caFile != "" {
   167  				creds, err := credentials.NewClientTLSFromFile(caFile, ordererTLSHostnameOverride)
   168  				if err != nil {
   169  					return nil, fmt.Errorf("Error connecting to %s due to %s", orderingEndpoint, err)
   170  				}
   171  				opts = append(opts, grpc.WithTransportCredentials(creds))
   172  			}
   173  		} else {
   174  			opts = append(opts, grpc.WithInsecure())
   175  		}
   176  		conn, err := grpc.Dial(orderingEndpoint, opts...)
   177  		if err != nil {
   178  			return nil, err
   179  		}
   180  
   181  		client, err := ab.NewAtomicBroadcastClient(conn).Deliver(context.TODO())
   182  		if err != nil {
   183  			return nil, fmt.Errorf("Error connecting due to  %s", err)
   184  		}
   185  
   186  		cmdFact.DeliverClient = newDeliverClient(conn, client, chainID)
   187  	}
   188  	logger.Infof("Endorser and orderer connections initialized")
   189  	return cmdFact, nil
   190  }