From 1b231dbc383e6e2b8e64b403ddfa97a1052b4174 Mon Sep 17 00:00:00 2001 From: Troy Ronda Date: Tue, 13 Mar 2018 15:58:41 -0400 Subject: [PATCH] [FAB-8847] Use Reader in SaveChannel This change replaces the filename in SaveChannel with an io.Reader for greater flexability. Change-Id: Icdd76ff0cea9e42ed958e31bb540bc99e00abd42 Signed-off-by: Troy Ronda --- pkg/client/resmgmt/opts.go | 2 +- pkg/client/resmgmt/resmgmt.go | 17 +++--- pkg/client/resmgmt/resmgmt_test.go | 62 +++++++++++++++++---- test/integration/base_test_setup.go | 20 ++++--- test/integration/e2e/end_to_end.go | 9 ++- test/integration/fab/channel_ledger_test.go | 10 +++- test/integration/fab/main_test.go | 6 +- test/integration/msp/user_data_mgmt_test.go | 4 +- test/integration/orgs/multiple_orgs_test.go | 9 ++- test/integration/sdk/channel_config_test.go | 8 +-- test/integration/sdk/main_test.go | 6 +- 11 files changed, 109 insertions(+), 44 deletions(-) diff --git a/pkg/client/resmgmt/opts.go b/pkg/client/resmgmt/opts.go index 35201fd82b..dbff1ff969 100644 --- a/pkg/client/resmgmt/opts.go +++ b/pkg/client/resmgmt/opts.go @@ -15,7 +15,7 @@ import ( "github.com/pkg/errors" ) -// WithTargetURLs allows overriding of the target peers for the request. +// WithTargets allows overriding of the target peers for the request. func WithTargets(targets ...fab.Peer) RequestOption { return func(ctx context.Client, opts *requestOptions) error { opts.Targets = targets diff --git a/pkg/client/resmgmt/resmgmt.go b/pkg/client/resmgmt/resmgmt.go index 7fe1c59902..436d4e0570 100644 --- a/pkg/client/resmgmt/resmgmt.go +++ b/pkg/client/resmgmt/resmgmt.go @@ -8,6 +8,7 @@ SPDX-License-Identifier: Apache-2.0 package resmgmt import ( + "io" "io/ioutil" "math/rand" "time" @@ -83,12 +84,10 @@ type requestOptions struct { //SaveChannelRequest used to save channel request type SaveChannelRequest struct { - // Channel Name (ID) - ChannelID string - // Path to channel configuration file - ChannelConfig string - // Users that sign channel configuration - SigningIdentities []msp.Identity + ChannelID string + ChannelConfig io.Reader // ChannelConfig data source + SigningIdentities []msp.Identity // Users that sign channel configuration + // TODO: support pre-signed signature blocks } //RequestOption func for each Opts argument @@ -597,11 +596,11 @@ func (rc *Client) SaveChannel(req SaveChannelRequest, options ...RequestOption) return err } - if req.ChannelID == "" || req.ChannelConfig == "" { + if req.ChannelID == "" || req.ChannelConfig == nil { return errors.New("must provide channel ID and channel config") } - logger.Debugf("***** Saving channel: %s *****\n", req.ChannelID) + logger.Debugf("saving channel: %s", req.ChannelID) // Signing user has to belong to one of configured channel organisations // In case that order org is one of channel orgs we can use context user @@ -619,7 +618,7 @@ func (rc *Client) SaveChannel(req SaveChannelRequest, options ...RequestOption) return errors.New("must provide signing user") } - configTx, err := ioutil.ReadFile(req.ChannelConfig) + configTx, err := ioutil.ReadAll(req.ChannelConfig) if err != nil { return errors.WithMessage(err, "reading channel config file failed") } diff --git a/pkg/client/resmgmt/resmgmt_test.go b/pkg/client/resmgmt/resmgmt_test.go index 6b632bf44f..593a0f8c46 100644 --- a/pkg/client/resmgmt/resmgmt_test.go +++ b/pkg/client/resmgmt/resmgmt_test.go @@ -10,6 +10,7 @@ import ( "fmt" "net" "net/http" + "os" "strings" "testing" "time" @@ -1343,32 +1344,44 @@ func TestSaveChannelSuccess(t *testing.T) { t.Fatalf("Should have failed for empty channel request") } + r, err := os.Open(channelConfig) + assert.Nil(t, err, "opening channel config file failed") + defer r.Close() + // Test empty channel name - err = cc.SaveChannel(SaveChannelRequest{ChannelID: "", ChannelConfig: channelConfig}) + err = cc.SaveChannel(SaveChannelRequest{ChannelID: "", ChannelConfig: r}) if err == nil { t.Fatalf("Should have failed for empty channel id") } // Test empty channel config - err = cc.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: ""}) + err = cc.SaveChannel(SaveChannelRequest{ChannelID: "mychannel"}) if err == nil { t.Fatalf("Should have failed for empty channel config") } // Test extract configuration error - err = cc.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: "./testdata/extractcherr.tx"}) + r1, err := os.Open("./testdata/extractcherr.tx") + assert.Nil(t, err, "opening channel config file failed") + defer r1.Close() + + err = cc.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: r1}) if err == nil { t.Fatalf("Should have failed to extract configuration") } // Test sign channel error - err = cc.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: "./testdata/signcherr.tx"}) + r2, err := os.Open("./testdata/signcherr.tx") + assert.Nil(t, err, "opening channel config file failed") + defer r2.Close() + + err = cc.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: r2}) if err == nil { t.Fatalf("Should have failed to sign configuration") } // Test valid Save Channel request (success) - err = cc.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig}, WithOrdererURL("example.com")) + err = cc.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: r}, WithOrdererURL("example.com")) if err != nil { t.Fatal(err) } @@ -1395,7 +1408,11 @@ func TestSaveChannelFailure(t *testing.T) { } // Test create channel failure - err = cc.SaveChannel(SaveChannelRequest{ChannelID: "Invalid", ChannelConfig: channelConfig}) + r, err := os.Open(channelConfig) + assert.Nil(t, err, "opening channel config file failed") + defer r.Close() + + err = cc.SaveChannel(SaveChannelRequest{ChannelID: "Invalid", ChannelConfig: r}) if err == nil { t.Fatal("Should have failed with create channel error") } @@ -1425,16 +1442,26 @@ func TestSaveChannelWithOpts(t *testing.T) { cc := setupResMgmtClient(ctx, nil, t) // Valid request (same for all options) - req := SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig} + r1, err := os.Open(channelConfig) + assert.Nil(t, err, "opening channel config file failed") + defer r1.Close() + + req := SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: r1} // Test empty option (default order is random orderer from config) opts := WithOrdererURL("") - err := cc.SaveChannel(req, opts) + err = cc.SaveChannel(req, opts) if err != nil { t.Fatal(err) } // Test valid orderer ID + r2, err := os.Open(channelConfig) + assert.Nil(t, err, "opening channel config file failed") + defer r2.Close() + + req = SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: r2} + opts = WithOrdererURL("orderer.example.com") err = cc.SaveChannel(req, opts) if err != nil { @@ -1442,6 +1469,11 @@ func TestSaveChannelWithOpts(t *testing.T) { } // Test invalid orderer ID + r3, err := os.Open(channelConfig) + assert.Nil(t, err, "opening channel config file failed") + defer r3.Close() + + req = SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: r3} mockConfig = &fcmocks.MockConfig{} ctx.SetConfig(mockConfig) @@ -1487,15 +1519,23 @@ func TestSaveChannelWithMultipleSigningIdenities(t *testing.T) { cc := setupResMgmtClient(ctx, nil, t) // empty list of signing identities (defaults to context user) - req := SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig, SigningIdentities: []msp.Identity{}} - err := cc.SaveChannel(req, WithOrdererURL("")) + r1, err := os.Open(channelConfig) + assert.Nil(t, err, "opening channel config file failed") + defer r1.Close() + + req := SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: r1, SigningIdentities: []msp.Identity{}} + err = cc.SaveChannel(req, WithOrdererURL("")) if err != nil { t.Fatalf("Failed to save channel with default signing identity: %s", err) } // multiple signing identities + r2, err := os.Open(channelConfig) + assert.Nil(t, err, "opening channel config file failed") + defer r2.Close() + secondCtx := fcmocks.NewMockContext(fcmocks.NewMockUser("second")) - req = SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig, SigningIdentities: []msp.Identity{cc.ctx, secondCtx}} + req = SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: r2, SigningIdentities: []msp.Identity{cc.ctx, secondCtx}} err = cc.SaveChannel(req, WithOrdererURL("")) if err != nil { t.Fatalf("Failed to save channel with multiple signing identities: %s", err) diff --git a/test/integration/base_test_setup.go b/test/integration/base_test_setup.go index 2f3ba07044..e41600db5a 100644 --- a/test/integration/base_test_setup.go +++ b/test/integration/base_test_setup.go @@ -22,12 +22,12 @@ import ( // BaseSetupImpl implementation of BaseTestSetup type BaseSetupImpl struct { - Identity msp.Identity - Targets []string - ConfigFile string - OrgID string - ChannelID string - ChannelConfig string + Identity msp.Identity + Targets []string + ConfigFile string + OrgID string + ChannelID string + ChannelConfigFile string } // Initial B values for ExampleCC @@ -80,8 +80,14 @@ func (setup *BaseSetupImpl) Initialize(sdk *fabsdk.FabricSDK) error { } setup.Targets = targets + r, err := os.Open(setup.ChannelConfigFile) + if err != nil { + return errors.Wrapf(err, "opening channel config file failed") + } + defer r.Close() + // Create channel for tests - req := resmgmt.SaveChannelRequest{ChannelID: setup.ChannelID, ChannelConfig: setup.ChannelConfig, SigningIdentities: []msp.Identity{adminIdentity}} + req := resmgmt.SaveChannelRequest{ChannelID: setup.ChannelID, ChannelConfig: r, SigningIdentities: []msp.Identity{adminIdentity}} if err = InitializeChannel(sdk, setup.OrgID, req, targets); err != nil { return errors.WithMessage(err, "failed to initialize channel") } diff --git a/test/integration/e2e/end_to_end.go b/test/integration/e2e/end_to_end.go index 2e53cd37d6..5d1743a70e 100644 --- a/test/integration/e2e/end_to_end.go +++ b/test/integration/e2e/end_to_end.go @@ -7,6 +7,7 @@ SPDX-License-Identifier: Apache-2.0 package e2e import ( + "os" "path" "strconv" "testing" @@ -67,8 +68,14 @@ func Run(t *testing.T, configOpt core.ConfigProvider, sdkOpts ...fabsdk.Option) t.Fatal(err) } + ccReader, err := os.Open(path.Join("../../../", metadata.ChannelConfigPath, "mychannel.tx")) + if err != nil { + t.Fatal(err) + } + defer ccReader.Close() + req := resmgmt.SaveChannelRequest{ChannelID: channelID, - ChannelConfig: path.Join("../../../", metadata.ChannelConfigPath, "mychannel.tx"), + ChannelConfig: ccReader, SigningIdentities: []msp.Identity{adminIdentity}} if err = resMgmtClient.SaveChannel(req); err != nil { t.Fatal(err) diff --git a/test/integration/fab/channel_ledger_test.go b/test/integration/fab/channel_ledger_test.go index 5fdbc31031..b4d4bf6549 100644 --- a/test/integration/fab/channel_ledger_test.go +++ b/test/integration/fab/channel_ledger_test.go @@ -7,6 +7,7 @@ SPDX-License-Identifier: Apache-2.0 package fab import ( + "os" "path" "strconv" "testing" @@ -50,8 +51,13 @@ func initializeLedgerTests(t *testing.T) (*fabsdk.FabricSDK, []string) { t.Fatalf("creating peers failed: %v", err) } - channelConfig := path.Join("../../../", metadata.ChannelConfigPath, channelConfigFile) - req := resmgmt.SaveChannelRequest{ChannelID: channelID, ChannelConfig: channelConfig, SigningIdentities: []msp.Identity{adminIdentity}} + ccReader, err := os.Open(path.Join("../../../", metadata.ChannelConfigPath, channelConfigFile)) + if err != nil { + t.Fatal(err) + } + defer ccReader.Close() + + req := resmgmt.SaveChannelRequest{ChannelID: channelID, ChannelConfig: ccReader, SigningIdentities: []msp.Identity{adminIdentity}} err = integration.InitializeChannel(sdk, orgName, req, targets) if err != nil { t.Fatalf("failed to ensure channel has been initialized: %s", err) diff --git a/test/integration/fab/main_test.go b/test/integration/fab/main_test.go index 5f953d4df6..69b9383973 100644 --- a/test/integration/fab/main_test.go +++ b/test/integration/fab/main_test.go @@ -36,9 +36,9 @@ func setup() { testSetup := integration.BaseSetupImpl{ ConfigFile: "../" + integration.ConfigTestFile, - ChannelID: "mychannel", - OrgID: org1Name, - ChannelConfig: path.Join("../../", metadata.ChannelConfigPath, "mychannel.tx"), + ChannelID: "mychannel", + OrgID: org1Name, + ChannelConfigFile: path.Join("../../../", metadata.ChannelConfigPath, "mychannel.tx"), } sdk, err := fabsdk.New(config.FromFile(testSetup.ConfigFile)) diff --git a/test/integration/msp/user_data_mgmt_test.go b/test/integration/msp/user_data_mgmt_test.go index f05976d8fe..40025cc6e6 100644 --- a/test/integration/msp/user_data_mgmt_test.go +++ b/test/integration/msp/user_data_mgmt_test.go @@ -27,7 +27,7 @@ import ( // TestWithCustomStores demonstrates the usage of custom key and cert stores // to manage user private keys and certificates. func TestWithCustomStores(t *testing.T) { - config, err := configImpl.FromFile(sdkConfigFile)() + config, err := configImpl.FromFile("../" + integration.ConfigTestFile)() if err != nil { t.Fatalf("Unexpected error from config: %v", err) } @@ -45,7 +45,7 @@ func TestWithCustomStores(t *testing.T) { // // NOTE: BCCSP SW implementation currently doesn't allow - // writting private keys out. The file store used internally + // writing private keys out. The file store used internally // by BCCSP has access to provate parts that are not available // outside of BCCSP at the moment. Fot this reason, our // example custom kay store will just hold the keys in memory. diff --git a/test/integration/orgs/multiple_orgs_test.go b/test/integration/orgs/multiple_orgs_test.go index 8b329a7a98..618a794d8e 100644 --- a/test/integration/orgs/multiple_orgs_test.go +++ b/test/integration/orgs/multiple_orgs_test.go @@ -8,6 +8,7 @@ package orgs import ( "math" + "os" "path" "strconv" "strings" @@ -96,8 +97,14 @@ func testWithOrg1(t *testing.T, sdk *fabsdk.FabricSDK) int { } // Create channel (or update if it already exists) + ccReader, err := os.Open(path.Join("../../../", metadata.ChannelConfigPath, "orgchannel.tx")) + if err != nil { + t.Fatal(err) + } + defer ccReader.Close() + req := resmgmt.SaveChannelRequest{ChannelID: "orgchannel", - ChannelConfig: path.Join("../../../", metadata.ChannelConfigPath, "orgchannel.tx"), + ChannelConfig: ccReader, SigningIdentities: []msp.Identity{org1AdminUser, org2AdminUser}} if err = chMgmtClient.SaveChannel(req); err != nil { t.Fatal(err) diff --git a/test/integration/sdk/channel_config_test.go b/test/integration/sdk/channel_config_test.go index 52a6825860..9b1416e7ec 100644 --- a/test/integration/sdk/channel_config_test.go +++ b/test/integration/sdk/channel_config_test.go @@ -89,10 +89,10 @@ func TestChannelConfig(t *testing.T) { func TestChannelConfigWithOrderer(t *testing.T) { testSetup := integration.BaseSetupImpl{ - ConfigFile: "../" + integration.ConfigTestFile, - ChannelID: "mychannel", - OrgID: org1Name, - ChannelConfig: path.Join("../../../", metadata.ChannelConfigPath, "mychannel.tx"), + ConfigFile: "../" + integration.ConfigTestFile, + ChannelID: "mychannel", + OrgID: org1Name, + ChannelConfigFile: path.Join("../../../", metadata.ChannelConfigPath, "mychannel.tx"), } confProvider := config.FromFile(testSetup.ConfigFile) diff --git a/test/integration/sdk/main_test.go b/test/integration/sdk/main_test.go index b0855f967c..66671a73cd 100644 --- a/test/integration/sdk/main_test.go +++ b/test/integration/sdk/main_test.go @@ -32,9 +32,9 @@ func setup() { testSetup := integration.BaseSetupImpl{ ConfigFile: "../" + integration.ConfigTestFile, - ChannelID: "mychannel", - OrgID: org1Name, - ChannelConfig: path.Join("../../", metadata.ChannelConfigPath, "mychannel.tx"), + ChannelID: "mychannel", + OrgID: org1Name, + ChannelConfigFile: path.Join("../../../", metadata.ChannelConfigPath, "mychannel.tx"), } sdk, err := fabsdk.New(config.FromFile(testSetup.ConfigFile))