Skip to content

Commit

Permalink
[FAB-8482] Context function implementation for SDK
Browse files Browse the repository at this point in the history
- Added Context() function in sdk to create
  context client
- Added NewChannelContext() function fabsdk package
  to create channel context
- Removed SessionFactory
- Refactored contexts in channel, ledger, resource packages
- Created common/context package for context related interfaces

Change-Id: I2b06f13ee7b0239858506646ea250a7eb6942801
Signed-off-by: Sudesh Shetty <sudesh.shetty@securekey.com>
  • Loading branch information
sudeshrshetty committed Mar 6, 2018
1 parent 697f96f commit 4889a92
Show file tree
Hide file tree
Showing 75 changed files with 1,228 additions and 969 deletions.
4 changes: 2 additions & 2 deletions Makefile
Expand Up @@ -325,8 +325,8 @@ dockerenv-latest-up: clean
mock-gen:
mockgen -build_flags '$(GO_LDFLAGS_ARG)' github.com/hyperledger/fabric-sdk-go/pkg/context/api/core Config,Providers,IdentityManager | sed "s/github.com\/hyperledger\/fabric-sdk-go\/vendor\///g" | goimports > pkg/context/api/core/mocks/mockcoreapi.gen.go
mockgen -build_flags '$(GO_LDFLAGS_ARG)' github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab ProposalProcessor,Providers | sed "s/github.com\/hyperledger\/fabric-sdk-go\/vendor\///g" | goimports > pkg/context/api/fab/mocks/mockfabapi.gen.go
mockgen -build_flags '$(GO_LDFLAGS_ARG)' github.com/hyperledger/fabric-sdk-go/pkg/context Providers | sed "s/github.com\/hyperledger\/fabric-sdk-go\/vendor\///g" | goimports > pkg/context/mocks/mockcontext.gen.go
mockgen -build_flags '$(GO_LDFLAGS_ARG)' github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/api CoreProviderFactory,ServiceProviderFactory,SessionClientFactory | sed "s/github.com\/hyperledger\/fabric-sdk-go\/vendor\///g" | goimports > pkg/fabsdk/mocks/mockfabsdkapi.gen.go
mockgen -build_flags '$(GO_LDFLAGS_ARG)' github.com/hyperledger/fabric-sdk-go/pkg/common/context Providers,Client | sed "s/github.com\/hyperledger\/fabric-sdk-go\/vendor\///g" | goimports > pkg/common/context/mocks/mockcontext.gen.go
mockgen -build_flags '$(GO_LDFLAGS_ARG)' github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/api CoreProviderFactory,ServiceProviderFactory | sed "s/github.com\/hyperledger\/fabric-sdk-go\/vendor\///g" | goimports > pkg/fabsdk/mocks/mockfabsdkapi.gen.go

# TODO - Add cryptogen
.PHONY: channel-config-gen
Expand Down
43 changes: 24 additions & 19 deletions pkg/client/channel/chclient.go
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/hyperledger/fabric-sdk-go/pkg/client/channel/invoke"
"github.com/hyperledger/fabric-sdk-go/pkg/client/common/discovery"
"github.com/hyperledger/fabric-sdk-go/pkg/client/common/discovery/greylist"
"github.com/hyperledger/fabric-sdk-go/pkg/common/context"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/core"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
"github.com/hyperledger/fabric-sdk-go/pkg/errors/multi"
Expand All @@ -35,50 +36,54 @@ const (
// An application that requires interaction with multiple channels should create a separate
// instance of the channel client for each channel. Channel client supports non-admin functions only.
type Client struct {
context core.Providers
discovery fab.DiscoveryService
selection fab.SelectionService
context context.Channel
membership fab.ChannelMembership
transactor fab.Transactor
eventHub fab.EventHub
greylist *greylist.Filter
}

// Context holds the providers and services needed to create a Client.
type Context struct {
core.Providers
DiscoveryService fab.DiscoveryService
SelectionService fab.SelectionService
ChannelService fab.ChannelService
type customChannelContext struct {
context.Channel
discoveryService fab.DiscoveryService
}

func (ccc *customChannelContext) DiscoveryService() fab.DiscoveryService {
return ccc.discoveryService
}

// New returns a Client instance.
func New(c Context) (*Client, error) {
func New(c context.Channel) (*Client, error) {

greylistProvider := greylist.New(c.Config().TimeoutOrDefault(core.DiscoveryGreylistExpiry))

eventHub, err := c.ChannelService.EventHub()
if c.ChannelService() == nil {
return nil, errors.New("channel service not initialized")
}

eventHub, err := c.ChannelService().EventHub()
if err != nil {
return nil, errors.WithMessage(err, "event hub creation failed")
}

transactor, err := c.ChannelService.Transactor()
transactor, err := c.ChannelService().Transactor()
if err != nil {
return nil, errors.WithMessage(err, "transactor creation failed")
}

membership, err := c.ChannelService.Membership()
membership, err := c.ChannelService().Membership()
if err != nil {
return nil, errors.WithMessage(err, "membership creation failed")
}

customDiscoveryService := discovery.NewDiscoveryFilterService(c.DiscoveryService(), greylistProvider)

channelClient := Client{
greylist: greylistProvider,
context: c,
discovery: discovery.NewDiscoveryFilterService(c.DiscoveryService, greylistProvider),
selection: c.SelectionService,
context: &customChannelContext{Channel: c, discoveryService: customDiscoveryService},
membership: membership,
transactor: transactor,
eventHub: eventHub,
greylist: greylistProvider,
}

return &channelClient, nil
Expand Down Expand Up @@ -157,8 +162,8 @@ func (cc *Client) prepareHandlerContexts(request Request, o opts) (*invoke.Reque
}

clientContext := &invoke.ClientContext{
Selection: cc.selection,
Discovery: cc.discovery,
Selection: cc.context.SelectionService(),
Discovery: cc.context.DiscoveryService(),
Membership: cc.membership,
Transactor: cc.transactor,
EventHub: cc.eventHub,
Expand Down
83 changes: 44 additions & 39 deletions pkg/client/channel/chclient_test.go
Expand Up @@ -16,7 +16,8 @@ import (

"github.com/hyperledger/fabric-sdk-go/pkg/client/channel/invoke"
txnmocks "github.com/hyperledger/fabric-sdk-go/pkg/client/common/mocks"
"github.com/hyperledger/fabric-sdk-go/pkg/context"
"github.com/hyperledger/fabric-sdk-go/pkg/common/context"
contextImpl "github.com/hyperledger/fabric-sdk-go/pkg/context"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/core"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
"github.com/hyperledger/fabric-sdk-go/pkg/errors/retry"
Expand All @@ -30,6 +31,7 @@ import (

const (
testAddress = "127.0.0.1:47882"
channelID = "testChannel"
)

func TestTxProposalResponseFilter(t *testing.T) {
Expand Down Expand Up @@ -449,29 +451,21 @@ func TestMultiErrorPropogation(t *testing.T) {
}

func TestDiscoveryGreylist(t *testing.T) {

testPeer1 := fcmocks.NewMockPeer("Peer1", "http://peer1.com")
testPeer1.Error = status.New(status.EndorserClientStatus,
status.ConnectionFailed.ToInt32(), "test", []interface{}{testPeer1.URL()})

fabCtx := setupTestContext()

orderer := fcmocks.NewMockOrderer("", nil)
testChannelSvc, err := setupTestChannelService(fabCtx, []fab.Orderer{orderer})
selectionService, err := setupTestSelection(nil, nil)
assert.Nil(t, err, "Got error %s", err)
selectionService.SelectAll = true

discoveryService, err := setupTestDiscovery(nil, []fab.Peer{testPeer1})
assert.Nil(t, err, "Got error %s", err)

selectionService, err := setupTestSelection(nil, nil)
assert.Nil(t, err, "Got error %s", err)
selectionService.SelectAll = true
fabCtx := setupCustomTestContext(t, selectionService, discoveryService, nil)
ctx := contextImpl.NewChannel(fabCtx, channelID)

ctx := Context{
Providers: fabCtx,
DiscoveryService: discoveryService,
SelectionService: selectionService,
ChannelService: testChannelSvc,
}
chClient, err := New(ctx)
assert.Nil(t, err, "Got error %s", err)

Expand All @@ -491,7 +485,7 @@ func TestDiscoveryGreylist(t *testing.T) {
assert.EqualValues(t, status.NoPeersFound.ToInt32(), s.Code, "expected No Peers Found status on greylist")
assert.Equal(t, 1, testPeer1.ProcessProposalCalls, "expected peer 1 to be greylisted")
// Wait for greylist expiry
time.Sleep(ctx.Config().TimeoutOrDefault(core.DiscoveryGreylistExpiry))
time.Sleep(ctx.Providers().Config().TimeoutOrDefault(core.DiscoveryGreylistExpiry))
testPeer1.ProcessProposalCalls = 0
testPeer1.Error = status.New(status.EndorserServerStatus, int32(common.Status_SERVICE_UNAVAILABLE), "test", nil)
// Try again
Expand All @@ -506,20 +500,19 @@ func TestDiscoveryGreylist(t *testing.T) {
}

func setupTestChannelService(ctx context.Client, orderers []fab.Orderer) (fab.ChannelService, error) {
const channelName = "testChannel"
chProvider, err := fcmocks.NewMockChannelProvider(ctx)
if err != nil {
return nil, errors.WithMessage(err, "mock channel provider creation failed")
}

chService, err := chProvider.ChannelService(ctx, channelName)
chService, err := chProvider.ChannelService(ctx, channelID)
if err != nil {
return nil, errors.WithMessage(err, "mock channel service creation failed")
}

transactor := txnmocks.MockTransactor{
Ctx: ctx,
ChannelID: channelName,
ChannelID: channelID,
Orderers: orderers,
}
chService.(*fcmocks.MockChannelService).SetTransactor(&transactor)
Expand All @@ -533,6 +526,31 @@ func setupTestContext() context.Client {
return ctx
}

func setupCustomTestContext(t *testing.T, selectionService fab.SelectionService, discoveryService fab.DiscoveryService, orderers []fab.Orderer) context.Client {
user := fcmocks.NewMockUser("test")
ctx := fcmocks.NewMockContext(user)

if orderers == nil {
orderer := fcmocks.NewMockOrderer("", nil)
orderers = []fab.Orderer{orderer}
}

testChannelSvc, err := setupTestChannelService(ctx, orderers)
assert.Nil(t, err, "Got error %s", err)

//Modify for custom mocks to test scenarios
selectionProvider := ctx.MockProviderContext.SelectionProvider()
selectionProvider.(*fcmocks.MockSelectionProvider).SetCustomSelectionService(selectionService)

channelProvider := ctx.MockProviderContext.ChannelProvider()
channelProvider.(*fcmocks.MockChannelProvider).SetCustomChannelService(testChannelSvc)

discoveryProvider := ctx.MockProviderContext.DiscoveryProvider()
discoveryProvider.(*fcmocks.MockStaticDiscoveryProvider).SetCustomDiscoveryService(discoveryService)

return ctx
}

func setupTestDiscovery(discErr error, peers []fab.Peer) (fab.DiscoveryService, error) {

mockDiscovery, err := txnmocks.NewMockDiscoveryProvider(discErr, peers)
Expand Down Expand Up @@ -560,11 +578,6 @@ func setupChannelClient(peers []fab.Peer, t *testing.T) *Client {

func setupChannelClientWithError(discErr error, selectionErr error, peers []fab.Peer, t *testing.T) *Client {

fabCtx := setupTestContext()
orderer := fcmocks.NewMockOrderer("", nil)
testChannelSvc, err := setupTestChannelService(fabCtx, []fab.Orderer{orderer})
assert.Nil(t, err, "Got error %s", err)

discoveryService, err := setupTestDiscovery(discErr, nil)
if err != nil {
t.Fatalf("Failed to setup discovery service: %s", err)
Expand All @@ -575,12 +588,10 @@ func setupChannelClientWithError(discErr error, selectionErr error, peers []fab.
t.Fatalf("Failed to setup discovery service: %s", err)
}

ctx := Context{
Providers: fabCtx,
DiscoveryService: discoveryService,
SelectionService: selectionService,
ChannelService: testChannelSvc,
}
fabCtx := setupCustomTestContext(t, selectionService, discoveryService, nil)

ctx := contextImpl.NewChannel(fabCtx, channelID)

ch, err := New(ctx)
if err != nil {
t.Fatalf("Failed to create new channel client: %s", err)
Expand All @@ -592,22 +603,16 @@ func setupChannelClientWithError(discErr error, selectionErr error, peers []fab.
func setupChannelClientWithNodes(peers []fab.Peer,
orderers []fab.Orderer, t *testing.T) *Client {

fabCtx := setupTestContext()
testChannelSvc, err := setupTestChannelService(fabCtx, orderers)
assert.Nil(t, err, "Got error %s", err)

discoveryService, err := setupTestDiscovery(nil, nil)
assert.Nil(t, err, "Failed to setup discovery service")

selectionService, err := setupTestSelection(nil, peers)
assert.Nil(t, err, "Failed to setup discovery service")

ctx := Context{
Providers: fabCtx,
DiscoveryService: discoveryService,
SelectionService: selectionService,
ChannelService: testChannelSvc,
}
fabCtx := setupCustomTestContext(t, selectionService, discoveryService, orderers)

ctx := contextImpl.NewChannel(fabCtx, channelID)

ch, err := New(ctx)
assert.Nil(t, err, "Failed to create new channel client")

Expand Down
2 changes: 1 addition & 1 deletion pkg/client/channel/invoke/txnhandler_test.go
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/stretchr/testify/assert"

txnmocks "github.com/hyperledger/fabric-sdk-go/pkg/client/common/mocks"
"github.com/hyperledger/fabric-sdk-go/pkg/context"
"github.com/hyperledger/fabric-sdk-go/pkg/common/context"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
fcmocks "github.com/hyperledger/fabric-sdk-go/pkg/fab/mocks"
)
Expand Down
2 changes: 1 addition & 1 deletion pkg/client/common/mocks/mocktransactor.go
Expand Up @@ -7,7 +7,7 @@ SPDX-License-Identifier: Apache-2.0
package mocks

import (
"github.com/hyperledger/fabric-sdk-go/pkg/context"
"github.com/hyperledger/fabric-sdk-go/pkg/common/context"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/txn"
"github.com/pkg/errors"
Expand Down
38 changes: 11 additions & 27 deletions pkg/client/ledger/ledger.go
Expand Up @@ -12,8 +12,7 @@ import (
"time"

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-sdk-go/pkg/context"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/core"
"github.com/hyperledger/fabric-sdk-go/pkg/common/context"
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/channel"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/chconfig"
Expand All @@ -36,27 +35,13 @@ const (
// An application that requires interaction with multiple channels should create a separate
// instance of the ledger client for each channel. Ledger client supports specific queries only.
type Client struct {
provider core.Providers
identity context.Identity
context context.Client
discovery fab.DiscoveryService
ledger *channel.Ledger
filter TargetFilter
chName string
}

// Context holds the providers and services needed to create a Client.
type Context struct {
core.Providers
context.Identity
DiscoveryService fab.DiscoveryService
ChannelService fab.ChannelService
}

type fabContext struct {
core.Providers
context.Identity
}

// MSPFilter is default filter
type MSPFilter struct {
mspID string
Expand All @@ -68,17 +53,21 @@ func (f *MSPFilter) Accept(peer fab.Peer) bool {
}

// New returns a Client instance.
func New(c Context, chName string, opts ...ClientOption) (*Client, error) {
func New(c context.Client, chName string, opts ...ClientOption) (*Client, error) {

l, err := channel.NewLedger(c, chName)
if err != nil {
return nil, err
}

discoveryService, err := c.DiscoveryProvider().NewDiscoveryService(chName)
if err != nil {
return nil, err
}

ledgerClient := Client{
provider: c,
identity: c,
discovery: c.DiscoveryService,
context: c,
discovery: discoveryService,
ledger: l,
chName: chName,
}
Expand Down Expand Up @@ -284,12 +273,7 @@ func (c *Client) QueryConfig(options ...RequestOption) (fab.ChannelCfg, error) {
return nil, errors.WithMessage(err, "failed to determine target peers for QueryConfig")
}

ctx := fabContext{
Providers: c.provider,
Identity: c.identity,
}

channelConfig, err := chconfig.New(ctx, c.chName, chconfig.WithPeers(targets), chconfig.WithMinResponses(opts.MinTargets))
channelConfig, err := chconfig.New(c.context, c.chName, chconfig.WithPeers(targets), chconfig.WithMinResponses(opts.MinTargets))
if err != nil {
return nil, errors.WithMessage(err, "QueryConfig failed")
}
Expand Down

0 comments on commit 4889a92

Please sign in to comment.