diff --git a/pkg/fab/channel/transactor.go b/pkg/fab/channel/transactor.go index 3b7fa9d265..93da6b0bdb 100644 --- a/pkg/fab/channel/transactor.go +++ b/pkg/fab/channel/transactor.go @@ -16,6 +16,7 @@ import ( reqContext "context" + "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/status" contextImpl "github.com/hyperledger/fabric-sdk-go/pkg/context" "github.com/hyperledger/fabric-sdk-go/pkg/core/config/endpoint" "github.com/hyperledger/fabric-sdk-go/pkg/fab/txn" @@ -54,18 +55,31 @@ func NewTransactor(reqCtx reqContext.Context, cfg fab.ChannelCfg) (*Transactor, } func orderersFromChannelCfg(ctx context.Client, cfg fab.ChannelCfg) ([]fab.Orderer, error) { - orderers := []fab.Orderer{} + + //below call to get orderers from endpoint config 'channels..orderers' is not recommended. + //To override any orderer configuration items, entity matchers should be used. + orderers, err := orderersFromChannel(ctx, cfg.ID()) + if err != nil { + return nil, err + } + if len(orderers) > 0 { + logger.Warn("Getting orderers from endpoint config channels.orderer is deprecated, use entity matchers to override orderer configuration") + logger.Warn("visit https://github.com/hyperledger/fabric-sdk-go/blob/master/test/fixtures/config/overrides/local_entity_matchers.yaml for samples") + return orderers, nil + } + ordererDict, err := orderersByTarget(ctx) if err != nil { return nil, err } - // Add orderer if specified in config + // Add orderer if specified in channel config for _, target := range cfg.Orderers() { // Figure out orderer configuration oCfg, ok := ordererDict[target] + //try entity matcher if !ok { logger.Debugf("Failed to get channel Cfg orderer [%s] from ordererDict, now trying orderer Matchers in Entity Matchers", target) // Try to find a match from entityMatchers config @@ -77,6 +91,7 @@ func orderersFromChannelCfg(ctx context.Client, cfg fab.ChannelCfg) ([]fab.Order } } + //create orderer using channel config block orderer address if !ok { logger.Debugf("Unable to find matching ordererConfig from entity Matchers for channel Cfg Orderer [%s]", target) oCfg = fab.OrdererConfig{ @@ -95,6 +110,39 @@ func orderersFromChannelCfg(ctx context.Client, cfg fab.ChannelCfg) ([]fab.Order return orderers, nil } +//deprecated +//orderersFromChannel returns list of fab.Orderer by channel id +//will return empty list when orderers are not found in endpoint config +func orderersFromChannel(ctx context.Client, channelID string) ([]fab.Orderer, error) { + + chNetworkConfig, err := ctx.EndpointConfig().ChannelConfig(channelID) + if err != nil { + return nil, errors.WithMessage(err, "failed to get channel network config") + } + + orderers := []fab.Orderer{} + for _, chOrderer := range chNetworkConfig.Orderers { + + ordererConfig, err := ctx.EndpointConfig().OrdererConfig(chOrderer) + if err != nil { + s, ok := status.FromError(err) + if !ok || s.Code != status.NoMatchingOrdererEntity.ToInt32() { + return nil, errors.Wrapf(err, "unable to get orderer config from [%s]", chOrderer) + } + //continue if given channel orderer not found in endpoint config + continue + } + + orderer, err := ctx.InfraProvider().CreateOrdererFromConfig(ordererConfig) + if err != nil { + return nil, errors.WithMessage(err, "failed to create orderer from config") + } + + orderers = append(orderers, orderer) + } + return orderers, nil +} + func orderersByTarget(ctx context.Client) (map[string]fab.OrdererConfig, error) { ordererDict := map[string]fab.OrdererConfig{} orderersConfig, err := ctx.EndpointConfig().OrderersConfig() diff --git a/pkg/fab/channel/transactor_test.go b/pkg/fab/channel/transactor_test.go index c145e0ddbc..eaf2f22ed5 100644 --- a/pkg/fab/channel/transactor_test.go +++ b/pkg/fab/channel/transactor_test.go @@ -11,8 +11,13 @@ import ( "time" + "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/hyperledger/fabric-sdk-go/pkg/context" + "github.com/hyperledger/fabric-sdk-go/pkg/core/config" + "github.com/hyperledger/fabric-sdk-go/pkg/core/config/lookup" + mocksConfig "github.com/hyperledger/fabric-sdk-go/pkg/core/mocks" + fabImpl "github.com/hyperledger/fabric-sdk-go/pkg/fab" "github.com/hyperledger/fabric-sdk-go/pkg/fab/mocks" "github.com/hyperledger/fabric-sdk-go/pkg/fab/txn" mspmocks "github.com/hyperledger/fabric-sdk-go/pkg/msp/test/mockmsp" @@ -136,3 +141,47 @@ func TestOrderersFromChannelCfgBadTLS(t *testing.T) { assert.Nil(t, err) assert.NotEmpty(t, o) } + +// TestOrderersURLOverride tests orderer URL override from endpoint channels config +func TestOrderersURLOverride(t *testing.T) { + sampleOrdererURL := "orderer.example.com.sample.url:100090" + + //Create endpoint config + configBackends, err := config.FromFile("../../core/config/testdata/config_test.yaml")() + if err != nil { + t.Fatal("failed to get config backends") + } + + //Override orderer URL in endpoint config + //Create an empty network config + networkConfig := fab.NetworkConfig{} + err = lookup.New(configBackends...).UnmarshalKey("orderers", &networkConfig.Orderers) + if err != nil { + t.Fatal("failed to unmarshal orderer") + } + + orderer := networkConfig.Orderers["orderer.example.com"] + orderer.URL = sampleOrdererURL + networkConfig.Orderers["orderer.example.com"] = orderer + + backendMap := make(map[string]interface{}) + backendMap["orderers"] = networkConfig.Orderers + backends := append([]core.ConfigBackend{}, &mocksConfig.MockConfigBackend{KeyValueMap: backendMap}) + backends = append(backends, configBackends...) + endpointCfg, err := fabImpl.ConfigFromBackend(backends...) + if err != nil { + t.Fatal("failed to get endpoint config") + } + + user := mspmocks.NewMockSigningIdentity("test", "test") + ctx := mocks.NewMockContext(user) + ctx.SetEndpointConfig(endpointCfg) + chConfig := mocks.NewMockChannelCfg("mychannel") + chConfig.MockOrderers = []string{"example.com"} + + o, err := orderersFromChannelCfg(ctx, chConfig) + assert.Nil(t, err) + assert.NotEmpty(t, o) + assert.Equal(t, 1, len(o), "expected one orderer from response orderers list") + assert.Equal(t, sampleOrdererURL, o[0].URL(), "orderer URL override from endpointconfig channels is not working as expected") +} diff --git a/pkg/fab/mocks/mockfabricprovider.go b/pkg/fab/mocks/mockfabricprovider.go index fbccaee8df..71b0519c6d 100644 --- a/pkg/fab/mocks/mockfabricprovider.go +++ b/pkg/fab/mocks/mockfabricprovider.go @@ -69,6 +69,10 @@ func (f *MockInfraProvider) CreateOrdererFromConfig(cfg *fab.OrdererConfig) (fab return f.customOrderer, nil } + if cfg.URL != "" { + return &MockOrderer{OrdererURL: cfg.URL}, nil + } + return &MockOrderer{}, nil }