Skip to content

Commit

Permalink
[FAB-8811] Rename WithOrdererID to WithOrdererURL
Browse files Browse the repository at this point in the history
This change renames WithOrdererID to WithOrdererURL in
resmgmt client. An additional option WithOrderer is also
added to specify the orderer object itself.

Change-Id: Id561d432691d3ff093d0f35074c5326f7e949b3c
Signed-off-by: Troy Ronda <troy@troyronda.com>
  • Loading branch information
troyronda committed Mar 12, 2018
1 parent 81a872e commit 7bb665c
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 61 deletions.
41 changes: 33 additions & 8 deletions pkg/client/resmgmt/opts.go
Expand Up @@ -9,45 +9,70 @@ package resmgmt
import (
"time"

"github.com/hyperledger/fabric-sdk-go/pkg/common/context"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
"github.com/pkg/errors"
)

//WithTargets encapsulates fab.Peer targets to resmgmtclient RequestOption
func WithTargets(targets ...fab.Peer) RequestOption {
return func(opts *Opts) error {
return func(ctx context.Client, opts *requestOptions) error {
opts.Targets = targets
return nil
}
}

//WithTarget encapsulates fab.Peer target to RequestOption
func WithTarget(target fab.Peer) RequestOption {
return func(opts *Opts) error {
return func(ctx context.Client, opts *requestOptions) error {
opts.Targets = []fab.Peer{target}
return nil
}
}

//WithTargetFilter encapsulates resmgmtclient TargetFilter targets to resmgmtclient RequestOption
func WithTargetFilter(targetFilter TargetFilter) RequestOption {
return func(opts *Opts) error {
return func(ctx context.Client, opts *requestOptions) error {
opts.TargetFilter = targetFilter
return nil
}
}

//WithTimeout encapsulates time.Duration to resmgmtclient RequestOption
func WithTimeout(timeout time.Duration) RequestOption {
return func(opts *Opts) error {
return func(ctx context.Client, opts *requestOptions) error {
opts.Timeout = timeout
return nil
}
}

//WithOrdererID encapsulates OrdererID to RequestOption
func WithOrdererID(ordererID string) RequestOption {
return func(opts *Opts) error {
opts.OrdererID = ordererID
//WithOrdererURL allows an orderer to be specified for the request.
//The orderer will be looked-up based on the url argument.
//A default orderer implementation will be used.
func WithOrdererURL(ordererID string) RequestOption {
return func(ctx context.Client, opts *requestOptions) error {

ordererCfg, err := ctx.Config().OrdererConfig(ordererID)
if err != nil {
return errors.WithMessage(err, "orderer not found")
}
if ordererCfg == nil {
return errors.New("orderer not found")
}

orderer, err := ctx.InfraProvider().CreateOrdererFromConfig(ordererCfg)
if err != nil {
return errors.WithMessage(err, "creating orderer from config failed")
}

return WithOrderer(orderer)(ctx, opts)
}
}

//WithOrderer allows an orderer to be specified for the request.
func WithOrderer(orderer fab.Orderer) RequestOption {
return func(ctx context.Client, opts *requestOptions) error {
opts.Orderer = orderer
return nil
}
}
69 changes: 30 additions & 39 deletions pkg/client/resmgmt/resmgmt.go
Expand Up @@ -23,7 +23,6 @@ import (
contextImpl "github.com/hyperledger/fabric-sdk-go/pkg/context"
"github.com/hyperledger/fabric-sdk-go/pkg/errors/multi"
"github.com/hyperledger/fabric-sdk-go/pkg/errors/status"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/orderer"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/peer"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/resource"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/resource/api"
Expand Down Expand Up @@ -75,11 +74,11 @@ type UpgradeCCRequest struct {
}

//Opts contains options for operations performed by ResourceMgmtClient
type Opts struct {
type requestOptions struct {
Targets []fab.Peer // target peers
TargetFilter TargetFilter // target filter
Timeout time.Duration //timeout options for instantiate and upgrade CC
OrdererID string // use specific orderer
Timeout time.Duration // timeout options for instantiate and upgrade CC
Orderer fab.Orderer // use specific orderer
}

//SaveChannelRequest used to save channel request
Expand All @@ -93,7 +92,7 @@ type SaveChannelRequest struct {
}

//RequestOption func for each Opts argument
type RequestOption func(opts *Opts) error
type RequestOption func(ctx context.Client, opts *requestOptions) error

var logger = logging.NewLogger("fabsdk/client")

Expand Down Expand Up @@ -183,14 +182,9 @@ func (rc *Client) JoinChannel(channelID string, options ...RequestOption) error
return errors.New("No targets available")
}

ordererCfg, err := rc.ordererConfig(&opts, channelID)
orderer, err := rc.requestOrderer(&opts, channelID)
if err != nil {
return errors.WithMessage(err, "failed to find orderer config")
}

orderer, err := rc.ctx.InfraProvider().CreateOrdererFromConfig(ordererCfg)
if err != nil {
return errors.WithMessage(err, "failed to create orderers from config")
return errors.WithMessage(err, "failed to find orderer for request")
}

genesisBlock, err := resource.GenesisBlockFromOrderer(rc.ctx, channelID, orderer)
Expand Down Expand Up @@ -632,14 +626,9 @@ func (rc *Client) SaveChannel(req SaveChannelRequest, options ...RequestOption)
configSignatures = append(configSignatures, configSignature)
}

ordererCfg, err := rc.ordererConfig(&opts, req.ChannelID)
orderer, err := rc.requestOrderer(&opts, req.ChannelID)
if err != nil {
return errors.WithMessage(err, "failed to find orderer config")
}

orderer, err := orderer.New(rc.ctx.Config(), orderer.FromOrdererConfig(ordererCfg))
if err != nil {
return errors.WithMessage(err, "failed to create new orderer from config")
return errors.WithMessage(err, "failed to find orderer for request")
}

request := api.CreateChannelRequest{
Expand Down Expand Up @@ -667,14 +656,9 @@ func (rc *Client) QueryConfigFromOrderer(channelID string, options ...RequestOpt
return nil, err
}

ordererCfg, err := rc.ordererConfig(&opts, channelID)
orderer, err := rc.requestOrderer(&opts, channelID)
if err != nil {
return nil, errors.WithMessage(err, "failed to find orderer config")
}

orderer, err := orderer.New(rc.ctx.Config(), orderer.FromOrdererConfig(ordererCfg))
if err != nil {
return nil, errors.WithMessage(err, "failed to resolve orderer")
return nil, errors.WithMessage(err, "failed to find orderer for request")
}

channelConfig, err := chconfig.New(rc.ctx, channelID, chconfig.WithOrderer(orderer))
Expand All @@ -686,18 +670,25 @@ func (rc *Client) QueryConfigFromOrderer(channelID string, options ...RequestOpt

}

func (rc *Client) ordererConfig(opts *Opts, channelID string) (*core.OrdererConfig, error) {
if opts.OrdererID != "" {
ordererCfg, err := rc.ctx.Config().OrdererConfig(opts.OrdererID)
if err != nil {
return nil, errors.WithMessage(err, "orderer not found")
}
if ordererCfg == nil {
return nil, errors.New("orderer not found")
}
return ordererCfg, nil
func (rc *Client) requestOrderer(opts *requestOptions, channelID string) (fab.Orderer, error) {
if opts.Orderer != nil {
return opts.Orderer, nil
}

ordererCfg, err := rc.ordererConfig(channelID)
if err != nil {
return nil, errors.WithMessage(err, "orderer not found")
}

orderer, err := rc.ctx.InfraProvider().CreateOrdererFromConfig(ordererCfg)
if err != nil {
return nil, errors.WithMessage(err, "failed to create orderer from config")
}
return orderer, nil

}

func (rc *Client) ordererConfig(channelID string) (*core.OrdererConfig, error) {
orderers, err := rc.ctx.Config().ChannelOrderers(channelID)

// TODO: Not sure that we should fallback to global orderers section.
Expand All @@ -719,10 +710,10 @@ func (rc *Client) ordererConfig(opts *Opts, channelID string) (*core.OrdererConf
}

// prepareRequestOpts prepares request options
func (rc *Client) prepareRequestOpts(options ...RequestOption) (Opts, error) {
opts := Opts{}
func (rc *Client) prepareRequestOpts(options ...RequestOption) (requestOptions, error) {
opts := requestOptions{}
for _, option := range options {
err := option(&opts)
err := option(rc.ctx, &opts)
if err != nil {
return opts, errors.WithMessage(err, "Failed to read opts")
}
Expand Down
21 changes: 9 additions & 12 deletions pkg/client/resmgmt/resmgmt_test.go
Expand Up @@ -87,9 +87,7 @@ func TestJoinChannelSuccess(t *testing.T) {
rc := setupResMgmtClient(ctx, nil, t)

// Setup target peers
var peers []fab.Peer
peer1, _ := peer.New(fcmocks.NewMockConfig(), peer.WithURL("grpc://"+addr))
peers = append(peers, peer1)

// Test valid join channel request (success)
err := rc.JoinChannel("mychannel", WithTargets(peer1))
Expand Down Expand Up @@ -283,8 +281,7 @@ func TestOrdererConfigFail(t *testing.T) {
ctx.SetConfig(noOrdererConfig)
rc := setupResMgmtClient(ctx, nil, t)

opts := Opts{}
orderer, err := rc.ordererConfig(&opts, "mychannel")
orderer, err := rc.ordererConfig("mychannel")
assert.Nil(t, orderer)
assert.NotNil(t, err, "should fail since no orderer has been configured")
}
Expand Down Expand Up @@ -1371,7 +1368,7 @@ func TestSaveChannelSuccess(t *testing.T) {
}

// Test valid Save Channel request (success)
err = cc.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig}, WithOrdererID("example.com"))
err = cc.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig}, WithOrdererURL("example.com"))
if err != nil {
t.Fatal(err)
}
Expand All @@ -1398,7 +1395,7 @@ func TestSaveChannelFailure(t *testing.T) {
}

// Test create channel failure
err = cc.SaveChannel(SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig})
err = cc.SaveChannel(SaveChannelRequest{ChannelID: "Invalid", ChannelConfig: channelConfig})
if err == nil {
t.Fatal("Should have failed with create channel error")
}
Expand Down Expand Up @@ -1431,14 +1428,14 @@ func TestSaveChannelWithOpts(t *testing.T) {
req := SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig}

// Test empty option (default order is random orderer from config)
opts := WithOrdererID("")
opts := WithOrdererURL("")
err := cc.SaveChannel(req, opts)
if err != nil {
t.Fatal(err)
}

// Test valid orderer ID
opts = WithOrdererID("orderer.example.com")
opts = WithOrdererURL("orderer.example.com")
err = cc.SaveChannel(req, opts)
if err != nil {
t.Fatal(err)
Expand All @@ -1451,7 +1448,7 @@ func TestSaveChannelWithOpts(t *testing.T) {

cc = setupResMgmtClient(ctx, nil, t)

opts = WithOrdererID("Invalid")
opts = WithOrdererURL("Invalid")
err = cc.SaveChannel(req, opts)
if err == nil {
t.Fatal("Should have failed for invalid orderer ID")
Expand All @@ -1461,7 +1458,7 @@ func TestSaveChannelWithOpts(t *testing.T) {
func TestJoinChannelWithInvalidOpts(t *testing.T) {

cc := setupDefaultResMgmtClient(t)
opts := WithOrdererID("Invalid")
opts := WithOrdererURL("Invalid")
err := cc.JoinChannel("mychannel", opts)
if err == nil {
t.Fatal("Should have failed for invalid orderer ID")
Expand Down Expand Up @@ -1491,15 +1488,15 @@ func TestSaveChannelWithMultipleSigningIdenities(t *testing.T) {

// empty list of signing identities (defaults to context user)
req := SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig, SigningIdentities: []msp.Identity{}}
err := cc.SaveChannel(req, WithOrdererID(""))
err := cc.SaveChannel(req, WithOrdererURL(""))
if err != nil {
t.Fatalf("Failed to save channel with default signing identity: %s", err)
}

// multiple signing identities
secondCtx := fcmocks.NewMockContext(fcmocks.NewMockUser("second"))
req = SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig, SigningIdentities: []msp.Identity{cc.ctx, secondCtx}}
err = cc.SaveChannel(req, WithOrdererID(""))
err = cc.SaveChannel(req, WithOrdererURL(""))
if err != nil {
t.Fatalf("Failed to save channel with multiple signing identities: %s", err)
}
Expand Down
7 changes: 7 additions & 0 deletions pkg/fab/mocks/mockconfig.go
Expand Up @@ -188,6 +188,9 @@ func (c *MockConfig) SetCustomRandomOrdererCfg(customRandomOrdererCfg *config.Or

// OrdererConfig not implemented
func (c *MockConfig) OrdererConfig(name string) (*config.OrdererConfig, error) {
if name == "Invalid" {
return nil, errors.New("no orderer")
}
if c.customOrdererCfg != nil {
return c.customOrdererCfg, nil
}
Expand Down Expand Up @@ -245,6 +248,10 @@ func (c *MockConfig) ChannelPeers(name string) ([]config.ChannelPeer, error) {

// ChannelOrderers returns a list of channel orderers
func (c *MockConfig) ChannelOrderers(name string) ([]config.OrdererConfig, error) {
if name == "Invalid" {
return nil, errors.New("no orderer")
}

oConfig, err := c.OrdererConfig("")

return []config.OrdererConfig{*oConfig}, err
Expand Down
4 changes: 2 additions & 2 deletions test/integration/sdk/resmgmt_queries_test.go
Expand Up @@ -139,15 +139,15 @@ func testQueryConfigFromOrderer(t *testing.T, channelID string, client *resmgmt.
t.Fatalf("Expected orderer %s, got %s", expected, channelCfg.Orderers())
}

channelCfg, err = client.QueryConfigFromOrderer(channelID, resmgmt.WithOrdererID("orderer.example.com"))
channelCfg, err = client.QueryConfigFromOrderer(channelID, resmgmt.WithOrdererURL("orderer.example.com"))
if err != nil {
t.Fatalf("QueryConfig return error: %v", err)
}
if !contains(channelCfg.Orderers(), expected) {
t.Fatalf("Expected orderer %s, got %s", expected, channelCfg.Orderers())
}

channelCfg, err = client.QueryConfigFromOrderer(channelID, resmgmt.WithOrdererID("non-existent"))
channelCfg, err = client.QueryConfigFromOrderer(channelID, resmgmt.WithOrdererURL("non-existent"))
if err == nil {
t.Fatalf("QueryConfig should have failed for invalid orderer")
}
Expand Down

0 comments on commit 7bb665c

Please sign in to comment.