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 }