Skip to content

Commit

Permalink
[FAB-1878]: Add fetch config CLI command
Browse files Browse the repository at this point in the history
Adding an ability to fetch configuration block, usefull
for complex setups such as many orgs having many peers.

The syntax is following:

peer channel fetch -c chainID

Change-Id: I20ef7091be0c76e42d8fb1a4913e8f3f8e7d5748
Signed-off-by: Artem Barger <bartem@il.ibm.com>
  • Loading branch information
C0rWin committed Jan 27, 2017
1 parent 62eac5b commit 12e85d8
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 5 deletions.
5 changes: 3 additions & 2 deletions peer/channel/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func Cmd(cf *ChannelCmdFactory) *cobra.Command {
AddFlags(channelCmd)
channelCmd.AddCommand(joinCmd(cf))
channelCmd.AddCommand(createCmd(cf))
channelCmd.AddCommand(fetchCmd(cf))

return channelCmd
}
Expand Down Expand Up @@ -80,7 +81,7 @@ type ChannelCmdFactory struct {
}

// InitCmdFactory init the ChannelCmdFactor with default clients
func InitCmdFactory(forJoin bool) (*ChannelCmdFactory, error) {
func InitCmdFactory(isOrdererRequired bool) (*ChannelCmdFactory, error) {
var err error

cmdFact := &ChannelCmdFactory{}
Expand All @@ -96,7 +97,7 @@ func InitCmdFactory(forJoin bool) (*ChannelCmdFactory, error) {
}

//for join, we need the endorser as well
if forJoin {
if isOrdererRequired {
cmdFact.EndorserClient, err = common.GetEndorserClient()
if err != nil {
return nil, fmt.Errorf("Error getting endorser client %s: %s", channelFuncName, err)
Expand Down
5 changes: 2 additions & 3 deletions peer/channel/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,13 @@ import (
"io/ioutil"
"time"

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/common/configtx"
configtxtest "github.com/hyperledger/fabric/common/configtx/test"
mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
"github.com/hyperledger/fabric/orderer/common/bootstrap/provisional"
cb "github.com/hyperledger/fabric/protos/common"
"github.com/hyperledger/fabric/protos/utils"

"github.com/golang/protobuf/proto"
mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
"github.com/spf13/cobra"
)

Expand Down
67 changes: 67 additions & 0 deletions peer/channel/fetchconfig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
Copyright IBM Corp. 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package channel

import (
"io/ioutil"

"github.com/golang/protobuf/proto"
cb "github.com/hyperledger/fabric/protos/common"
"github.com/spf13/cobra"
)

func fetchCmd(cf *ChannelCmdFactory) *cobra.Command {
createCmd := &cobra.Command{
Use: "fetch",
Short: "Fetch configuration block.",
Long: `Fetch configuration block.`,
RunE: func(cmd *cobra.Command, args []string) error {
return fetch(cmd, args, cf)
},
}

return createCmd
}

func fetch(cmd *cobra.Command, args []string, cf *ChannelCmdFactory) error {
var err error
if cf == nil {
cf, err = InitCmdFactory(false)
if err != nil {
return err
}
}

defer cf.BroadcastClient.Close()

var block *cb.Block
if block, err = cf.DeliverClient.getBlock(); err != nil {
return err
}

b, err := proto.Marshal(block)
if err != nil {
return err
}

file := chainID + ".block"
if err = ioutil.WriteFile(file, b, 0644); err != nil {
return err
}

return nil
}
76 changes: 76 additions & 0 deletions peer/channel/fetchconfig_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright IBM Corp. 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package channel

import (
"os"
"testing"

"github.com/hyperledger/fabric/peer/common"
)

func TestFetchChain(t *testing.T) {
InitMSP()

mockchain := "mockchain"

signer, err := common.GetDefaultSigner()
if err != nil {
t.Fatalf("Get default signer error: %v", err)
}

mockBroadcastClient := common.GetMockBroadcastClient(nil)

mockCF := &ChannelCmdFactory{
BroadcastClient: mockBroadcastClient,
Signer: signer,
DeliverClient: &mockDeliverClient{},
}

cmd := createCmd(mockCF)

AddFlags(cmd)

args := []string{"-c", mockchain}
cmd.SetArgs(args)

if err := cmd.Execute(); err != nil {
t.Fail()
t.Errorf("expected join command to succeed")
}

os.Remove(mockchain + ".block")

cmd = fetchCmd(mockCF)
defer os.Remove(mockchain + ".block")

AddFlags(cmd)

args = []string{"-c", mockchain}
cmd.SetArgs(args)

if err := cmd.Execute(); err != nil {
t.Fail()
t.Errorf("expected join command to succeed")
}

if _, err := os.Stat(mockchain + ".block"); os.IsNotExist(err) {
// path/to/whatever does not exist
t.Fail()
t.Error("expected configuration block to be fetched")
}
}

0 comments on commit 12e85d8

Please sign in to comment.