Skip to content

Commit

Permalink
[FAB-8716] Simplify SDK options
Browse files Browse the repository at this point in the history
Change-Id: I1a9006cc559de62ddcd6065787178cbba29564ed
Signed-off-by: Troy Ronda <troy@troyronda.com>
  • Loading branch information
troyronda committed Mar 8, 2018
1 parent 7f5d553 commit 61c4f1a
Show file tree
Hide file tree
Showing 20 changed files with 70 additions and 180 deletions.
58 changes: 3 additions & 55 deletions pkg/fabsdk/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ type ClientContext struct {
provider clientProvider
}

// ContextOption configures the client context created by the SDK.
type ContextOption func(opts *contextOptions) error

type contextOptions struct {
orgID string
config core.Config
Expand All @@ -41,7 +38,6 @@ type clientOptions struct {
type clientProvider func() (*clientContext, error)

type clientContext struct {
opts *contextOptions
identity contextApi.Identity
providers providers
}
Expand All @@ -50,14 +46,6 @@ type providers interface {
contextApi.Providers
}

// WithOrg uses the configuration and users from the named organization.
func WithOrg(name string) ContextOption {
return func(opts *contextOptions) error {
opts.orgID = name
return nil
}
}

// WithTargetFilter allows for filtering target peers.
func WithTargetFilter(targetFilter fab.TargetFilter) ClientOption {
return func(opts *clientOptions) error {
Expand All @@ -66,35 +54,21 @@ func WithTargetFilter(targetFilter fab.TargetFilter) ClientOption {
}
}

// withConfig allows for overriding the configuration of the client.
// TODO: This should be removed once the depreacted functions are removed.
func withConfig(config core.Config) ContextOption {
return func(opts *contextOptions) error {
opts.config = config
return nil
}
}

// NewClient allows creation of transactions using the supplied identity as the credential.
//Deprecated: use sdk.Context() or sdk.ChannelContext() instead
func (sdk *FabricSDK) NewClient(identityOpt IdentityOption, opts ...ContextOption) *ClientContext {
func (sdk *FabricSDK) NewClient(opts ...ContextOption) *ClientContext {
// delay execution of the following logic to avoid error return from this function.
// this is done to allow a cleaner API - i.e., client, err := sdk.NewClient(args).<Desired Interface>(extra args)
provider := func() (*clientContext, error) {
o, err := newContextOptions(sdk.provider.Config(), opts)
if err != nil {
return nil, errors.WithMessage(err, "unable to retrieve configuration from SDK")
}

identity, err := sdk.newIdentity(identityOpt, WithOrgName(o.orgID))
identity, err := sdk.newIdentity(opts...)
if err != nil {
return nil, errors.WithMessage(err, "unable to create client context")
}

cc := clientContext{
opts: o,
identity: identity,
providers: &context.Client{Providers: &sdk.provider, Identity: identity},
providers: &context.Client{Providers: sdk.provider, Identity: identity},
}
return &cc, nil
}
Expand All @@ -104,32 +78,6 @@ func (sdk *FabricSDK) NewClient(identityOpt IdentityOption, opts ...ContextOptio
return &client
}

func newContextOptions(config core.Config, options []ContextOption) (*contextOptions, error) {
// Read default org name from configuration
client, err := config.Client()
if err != nil {
return nil, errors.WithMessage(err, "unable to retrieve client from network config")
}

opts := contextOptions{
orgID: client.Organization,
config: config,
}

for _, option := range options {
err := option(&opts)
if err != nil {
return nil, errors.WithMessage(err, "error in option passed to client")
}
}

if opts.orgID == "" {
return nil, errors.New("must provide default organisation name in configuration")
}

return &opts, nil
}

func newClientOptions(options []ClientOption) (*clientOptions, error) {
opts := clientOptions{}

Expand Down
24 changes: 3 additions & 21 deletions pkg/fabsdk/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestFromConfigGoodClientOpt(t *testing.T) {
}

func goodClientOpt() ContextOption {
return func(opts *contextOptions) error {
return func(opts *identityOptions) error {
return nil
}
}
Expand All @@ -73,7 +73,7 @@ func TestNewBadClientOpt(t *testing.T) {
}

func badClientOpt() ContextOption {
return func(opts *contextOptions) error {
return func(opts *identityOptions) error {
return errors.New("Bad Opt")
}
}
Expand Down Expand Up @@ -124,24 +124,6 @@ func TestWithFilter(t *testing.T) {
}
}

func TestWithConfig(t *testing.T) {
c, err := configImpl.FromFile(clientConfigFile)()
if err != nil {
t.Fatalf("Unexpected error from config: %v", err)
}
opt := withConfig(c)

opts := contextOptions{}
err = opt(&opts)
if err != nil {
t.Fatalf("Expected no error from option, but got %v", err)
}

if opts.config != c {
t.Fatalf("Expected config to be set in opts")
}
}

func TestNoIdentity(t *testing.T) {
sdk, err := New(configImpl.FromFile(clientConfigFile))
if err != nil {
Expand All @@ -155,7 +137,7 @@ func TestNoIdentity(t *testing.T) {
}
}

func noopIdentityOpt() IdentityOption {
func noopIdentityOpt() ContextOption {
return func(o *identityOptions) error {
return nil
}
Expand Down
58 changes: 16 additions & 42 deletions pkg/fabsdk/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,71 +16,45 @@ import (
type identityOptions struct {
identity contextApi.Identity
orgName string
user string
userName string
}

// IdentityOption provides parameters for creating a session (primarily from a fabric identity/user)
type IdentityOption func(s *identityOptions) error
// ContextOption provides parameters for creating a session (primarily from a fabric identity/user)
type ContextOption func(s *identityOptions) error

// WithUser uses the named user to load the identity
func WithUser(user string) IdentityOption {
func WithUser(userName string) ContextOption {
return func(o *identityOptions) error {
o.user = user
o.userName = userName
return nil
}
}

// WithIdentity uses a pre-constructed identity object as the credential for the session
func WithIdentity(identity contextApi.Identity) IdentityOption {
func WithIdentity(identity contextApi.Identity) ContextOption {
return func(o *identityOptions) error {
o.identity = identity
return nil
}
}

// WithOrgName uses a pre-constructed identity object as the credential for the session
func WithOrgName(org string) IdentityOption {
// WithOrg uses the named organization
func WithOrg(org string) ContextOption {
return func(o *identityOptions) error {
o.orgName = org
return nil
}
}

type channelContextOptions struct {
identity contextApi.Identity
orgName string
user string
}

// ChannelContextOption provides parameters for creating a channel context
type ChannelContextOption func(s *channelContextOptions) error

// WithChannelUser uses the named user to load the identity
func WithChannelUser(user string) ChannelContextOption {
return func(o *channelContextOptions) error {
o.user = user
return nil
}
}

// WithChannelIdentity uses orgName to load identity
func WithChannelIdentity(identity contextApi.Identity) ChannelContextOption {
return func(o *channelContextOptions) error {
o.identity = identity
return nil
func (sdk *FabricSDK) newIdentity(options ...ContextOption) (contextApi.Identity, error) {
clientConfig, err := sdk.Config().Client()
if err != nil {
return nil, errors.WithMessage(err, "retrieving client configuration failed")
}
}

// WithChannelOrgName uses a pre-constructed identity object as the credential for the session
func WithChannelOrgName(org string) ChannelContextOption {
return func(o *channelContextOptions) error {
o.orgName = org
return nil
opts := identityOptions{
orgName: clientConfig.Organization,
}
}

func (sdk *FabricSDK) newIdentity(options ...IdentityOption) (contextApi.Identity, error) {
opts := identityOptions{}

for _, option := range options {
err := option(&opts)
Expand All @@ -93,7 +67,7 @@ func (sdk *FabricSDK) newIdentity(options ...IdentityOption) (contextApi.Identit
return opts.identity, nil
}

if opts.user == "" || opts.orgName == "" {
if opts.userName == "" || opts.orgName == "" {
return nil, errors.New("invalid options to create identity")
}

Expand All @@ -102,7 +76,7 @@ func (sdk *FabricSDK) newIdentity(options ...IdentityOption) (contextApi.Identit
return nil, errors.New("invalid options to create identity, invalid org name")
}

user, err := mgr.GetUser(opts.user)
user, err := mgr.GetUser(opts.userName)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/fabsdk/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func TestFabricSDKContext(t *testing.T) {
t.Fatal("context client will have providers even if idenity fails")
}

ctxProvider = sdk.Context(WithUser("INVALID_USER"), WithOrgName("INVALID_ORG_NAME"))
ctxProvider = sdk.Context(WithUser("INVALID_USER"), WithOrg("INVALID_ORG_NAME"))

ctx, err = ctxProvider()

Expand All @@ -96,7 +96,7 @@ func TestFabricSDKContext(t *testing.T) {
t.Fatal("context client will have providers even if idenity fails")
}

ctxProvider = sdk.Context(WithUser(identityValidOptUser), WithOrgName(identityValidOptOrg))
ctxProvider = sdk.Context(WithUser(identityValidOptUser), WithOrg(identityValidOptOrg))

ctx, err = ctxProvider()

Expand Down
30 changes: 8 additions & 22 deletions pkg/fabsdk/fabsdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
// FabricSDK provides access (and context) to clients being managed by the SDK.
type FabricSDK struct {
opts options
provider context.Provider
provider *context.Provider
}

type options struct {
Expand Down Expand Up @@ -175,14 +175,14 @@ func initSDK(sdk *FabricSDK, config core.Config, opts []Option) error {
}

//Initialize sdk provider
sdk.provider = *context.NewProvider(context.WithConfig(config),
sdk.provider = context.NewProvider(context.WithConfig(config),
context.WithCryptoSuite(cryptoSuite),
context.WithSigningManager(signingManager),
context.WithStateStore(stateStore),
context.WithIdentityManager(identityManager))

// Initialize Fabric Provider
fabricProvider, err := sdk.opts.Core.CreateFabricProvider(&sdk.provider)
fabricProvider, err := sdk.opts.Core.CreateFabricProvider(sdk.provider)
if err != nil {
return errors.WithMessage(err, "failed to initialize core fabric provider")
}
Expand Down Expand Up @@ -211,7 +211,7 @@ func initSDK(sdk *FabricSDK, config core.Config, opts []Option) error {
}

//update sdk providers list since all required providers are initialized
sdk.provider = *context.NewProvider(context.WithConfig(config),
sdk.provider = context.NewProvider(context.WithConfig(config),
context.WithCryptoSuite(cryptoSuite),
context.WithSigningManager(signingManager),
context.WithStateStore(stateStore),
Expand All @@ -235,36 +235,22 @@ func (sdk *FabricSDK) Config() core.Config {
}

//Context creates and returns context client which has all the necessary providers
func (sdk *FabricSDK) Context(options ...IdentityOption) contextApi.ClientProvider {
func (sdk *FabricSDK) Context(options ...ContextOption) contextApi.ClientProvider {

clientProvider := func() (contextApi.Client, error) {
identity, err := sdk.newIdentity(options...)
return &context.Client{Providers: &sdk.provider, Identity: identity}, err
return &context.Client{Providers: sdk.provider, Identity: identity}, err
}

return clientProvider
}

//ChannelContext creates and returns channel context
func (sdk *FabricSDK) ChannelContext(channelID string, options ...ChannelContextOption) contextApi.ChannelProvider {
func (sdk *FabricSDK) ChannelContext(channelID string, options ...ContextOption) contextApi.ChannelProvider {

channelProvider := func() (contextApi.Channel, error) {

channelCtxOpts := channelContextOptions{}
for _, param := range options {
param(&channelCtxOpts)
}

var identityOpts []IdentityOption
if channelCtxOpts.identity != nil {
identityOpts = append(identityOpts, WithIdentity(channelCtxOpts.identity))
} else {
identityOpts = append(identityOpts, WithUser(channelCtxOpts.user))
identityOpts = append(identityOpts, WithOrgName(channelCtxOpts.orgName))
}

clientCtxProvider := sdk.Context(identityOpts...)

clientCtxProvider := sdk.Context(options...)
return context.NewChannel(clientCtxProvider, channelID)

}
Expand Down
12 changes: 6 additions & 6 deletions pkg/fabsdk/fabsdk_chconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ func verifySDK(t *testing.T, sdk *FabricSDK) {
sdk.provider.ChannelProvider().(*chpvdr.ChannelProvider).SetChannelConfig(mocks.NewMockChannelCfg("orgchannel"))

// Get a common client context for the following tests
chCtx1 := sdk.ChannelContext("mychannel", WithChannelUser(sdkValidClientUser), WithChannelOrgName(sdkValidClientOrg2))
chCtx2 := sdk.ChannelContext("orgchannel", WithChannelUser(sdkValidClientUser), WithChannelOrgName(sdkValidClientOrg2))
chCtx1 := sdk.ChannelContext("mychannel", WithUser(sdkValidClientUser), WithOrg(sdkValidClientOrg2))
chCtx2 := sdk.ChannelContext("orgchannel", WithUser(sdkValidClientUser), WithOrg(sdkValidClientOrg2))

// Test configuration failure for channel client (mychannel does't have event source configured for Org2)
_, err := channel.New(chCtx1)
Expand Down Expand Up @@ -105,8 +105,8 @@ func TestNewDefaultTwoValidSDK(t *testing.T) {
// Get a common client context for the following tests
//cc1 := sdk1.NewClient(WithUser(sdkValidClientUser))

cc1CtxC1 := sdk1.ChannelContext("mychannel", WithChannelUser(sdkValidClientUser), WithChannelOrgName(sdkValidClientOrg1))
cc1CtxC2 := sdk1.ChannelContext("orgchannel", WithChannelUser(sdkValidClientUser), WithChannelOrgName(sdkValidClientOrg1))
cc1CtxC1 := sdk1.ChannelContext("mychannel", WithUser(sdkValidClientUser), WithOrg(sdkValidClientOrg1))
cc1CtxC2 := sdk1.ChannelContext("orgchannel", WithUser(sdkValidClientUser), WithOrg(sdkValidClientOrg1))

// Test SDK1 channel clients ('mychannel', 'orgchannel')
_, err = channel.New(cc1CtxC1)
Expand All @@ -120,8 +120,8 @@ func TestNewDefaultTwoValidSDK(t *testing.T) {
}

// Get a common client context for the following tests
cc2CtxC1 := sdk1.ChannelContext("mychannel", WithChannelUser(sdkValidClientUser), WithChannelOrgName(sdkValidClientOrg2))
cc2CtxC2 := sdk1.ChannelContext("orgchannel", WithChannelUser(sdkValidClientUser), WithChannelOrgName(sdkValidClientOrg2))
cc2CtxC1 := sdk1.ChannelContext("mychannel", WithUser(sdkValidClientUser), WithOrg(sdkValidClientOrg2))
cc2CtxC2 := sdk1.ChannelContext("orgchannel", WithUser(sdkValidClientUser), WithOrg(sdkValidClientOrg2))

// SDK 2 doesn't have 'mychannel' configured
_, err = channel.New(cc2CtxC1)
Expand Down
2 changes: 1 addition & 1 deletion pkg/fabsdk/fabsdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func TestWithSessionPkg(t *testing.T) {
defer sdk.Close()

// Get resource management
ctx := sdk.Context(WithUser(sdkValidClientUser), WithOrgName(sdkValidClientOrg1))
ctx := sdk.Context(WithUser(sdkValidClientUser), WithOrg(sdkValidClientOrg1))
_, err = resmgmt.New(ctx)
if err != nil {
t.Fatalf("Unexpected error getting channel management client: %s", err)
Expand Down
Loading

0 comments on commit 61c4f1a

Please sign in to comment.