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