Skip to content

Commit

Permalink
[FAB-8482] using contexts in ccpolicyprovider
Browse files Browse the repository at this point in the history
 - removed sdk.NewClient() dependency from ccpolicyprovider
 - selection provider initialize will use context providers
instead of sdk
 - removed sdk.FabricProvider()
 - CoreProviderFactory.CreateFabricProvider() renamed to
 CoreProviderFactory.CreateInfraProvider()
 - FabricProvider renamed to InfraProvider
 - refactored integration tests to not to use contexts
 directly for signing identities, added a utility function
 which will be fixed later.




Change-Id: I9e5512b2f55d5a3e3fe293aa7811e9e6925d803d
Signed-off-by: Sudesh Shetty <sudesh.shetty@securekey.com>
  • Loading branch information
sudeshrshetty committed Mar 8, 2018
1 parent 151405c commit d92bc58
Show file tree
Hide file tree
Showing 30 changed files with 309 additions and 224 deletions.
56 changes: 41 additions & 15 deletions pkg/client/common/selection/dynamicselection/ccpolicyprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import (
"github.com/pkg/errors"

"github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
"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/fabsdk"
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/api"
"github.com/hyperledger/fabric-sdk-go/pkg/logging"
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/core/common/ccprovider"
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/common"
Expand All @@ -41,38 +43,46 @@ type CCPolicyProvider interface {
}

// NewCCPolicyProvider creates new chaincode policy data provider
func newCCPolicyProvider(sdk *fabsdk.FabricSDK, channelID string, userName string, orgName string) (CCPolicyProvider, error) {
if channelID == "" || userName == "" || orgName == "" {
return nil, errors.New("Must provide channel ID, user name and organisation for cc policy provider")
func newCCPolicyProvider(providers api.Providers, channelID string, userName string, orgName string) (CCPolicyProvider, error) {
if providers == nil || channelID == "" || userName == "" || orgName == "" {
return nil, errors.New("Must provide providers, channel ID, user name and organisation for cc policy provider")
}

if sdk == nil {
return nil, errors.New("Must provide sdk")
// TODO: Add option to use anchor peers instead of config
targetPeers, err := providers.Config().ChannelPeers(channelID)
if err != nil {
return nil, errors.WithMessage(err, "unable to read configuration for channel peers")
}

client := sdk.NewClient(fabsdk.WithUser(userName), fabsdk.WithOrg(orgName))
//Get identity
mgr, ok := providers.IdentityManager(orgName)
if !ok {
return nil, errors.New("invalid options to create identity, invalid org name")
}

// TODO: Add option to use anchor peers instead of config
targetPeers, err := sdk.Config().ChannelPeers(channelID)
identity, err := mgr.GetUser(userName)
if err != nil {
return nil, errors.WithMessage(err, "unable to read configuration for channel peers")
return nil, errors.WithMessage(err, "unable to create identity for ccl policy provider")
}

cpp := ccPolicyProvider{
config: sdk.Config(),
client: client,
config: providers.Config(),
providers: providers,
channelID: channelID,
identity: identity,
targetPeers: targetPeers,
ccDataMap: make(map[string]*ccprovider.ChaincodeData),
provider: sdk.FabricProvider(),
provider: providers.InfraProvider(),
}

return &cpp, nil
}

type ccPolicyProvider struct {
config core.Config
client *fabsdk.ClientContext
providers context.Providers
channelID string
identity context.Identity
targetPeers []core.ChannelPeer
ccDataMap map[string]*ccprovider.ChaincodeData // TODO: Add expiry and configurable timeout for map entries
mutex sync.RWMutex
Expand Down Expand Up @@ -129,7 +139,11 @@ func (dp *ccPolicyProvider) queryChaincode(ccID string, ccFcn string, ccArgs [][
var queryErrors []string
var response []byte

client, err := dp.client.Channel(dp.channelID)
//prepare channel context
channelContext := dp.getChannelContext()

//get channel client
client, err := channel.New(channelContext)
if err != nil {
return nil, errors.WithMessage(err, "Unable to create channel client")
}
Expand Down Expand Up @@ -193,3 +207,15 @@ func newResolverKey(channelID string, chaincodeIDs ...string) *resolverKey {
}
return &resolverKey{channelID: channelID, chaincodeIDs: arr, key: key}
}

func (dp *ccPolicyProvider) getChannelContext() context.ChannelProvider {
//Get Channel Context
return func() (context.Channel, error) {
//Get Client Context
clientProvider := func() (context.Client, error) {
return &contextImpl.Client{Providers: dp.providers, Identity: dp.identity}, nil
}

return contextImpl.NewChannel(clientProvider, dp.channelID)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,30 @@ import (
"strings"
"testing"

"net"

"github.com/hyperledger/fabric-sdk-go/pkg/core/config"
mocks "github.com/hyperledger/fabric-sdk-go/pkg/fab/mocks"
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
pb "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/peer"
"google.golang.org/grpc"
)

func startEndorserServer(t *testing.T, grpcServer *grpc.Server, testAddress string) (*mocks.MockEndorserServer, string) {
lis, err := net.Listen("tcp", testAddress)
addr := lis.Addr().String()

endorserServer := &mocks.MockEndorserServer{}
pb.RegisterEndorserServer(grpcServer, endorserServer)
if err != nil {
t.Logf("Error starting test server %s", err)
t.FailNow()
}
t.Logf("Starting test server on %s\n", addr)
go grpcServer.Serve(lis)
return endorserServer, addr
}

func TestCCPolicyProvider(t *testing.T) {
// Create SDK setup for channel client with dynamic selection
sdk, err := fabsdk.New(config.FromFile("../../../../../test/fixtures/config/config_test.yaml"))
Expand All @@ -22,38 +42,45 @@ func TestCCPolicyProvider(t *testing.T) {
}
defer sdk.Close()

clientContext := sdk.Context(fabsdk.WithUser("User1"), fabsdk.WithOrg("Org1"))

context, err := clientContext()
if err != nil {
t.Fatal("Failed to create context")
}

// Nil sdk
ccPolicyProvider, err := newCCPolicyProvider(nil, "mychannel", "User1", "Org1")
if err == nil {
t.Fatalf("Should have failed for nil sdk")
}

// Invalid channelID
ccPolicyProvider, err = newCCPolicyProvider(sdk, "", "User1", "Org1")
ccPolicyProvider, err = newCCPolicyProvider(context, "", "User1", "Org1")
if err == nil {
t.Fatalf("Should have failed for empty channel")
}

// Empty user name
ccPolicyProvider, err = newCCPolicyProvider(sdk, "mychannel", "", "Prg1")
ccPolicyProvider, err = newCCPolicyProvider(context, "mychannel", "", "Prg1")
if err == nil {
t.Fatalf("Should have failed for empty user name")
}

// Empty org name
ccPolicyProvider, err = newCCPolicyProvider(sdk, "mychannel", "User1", "")
ccPolicyProvider, err = newCCPolicyProvider(context, "mychannel", "User1", "")
if err == nil {
t.Fatalf("Should have failed for nil sdk")
}

// Invalid channel
ccPolicyProvider, err = newCCPolicyProvider(sdk, "non-existent", "User1", "Org1")
ccPolicyProvider, err = newCCPolicyProvider(context, "non-existent", "User1", "Org1")
if err == nil {
t.Fatalf("Should have failed for invalid channel name")
}

// All good
ccPolicyProvider, err = newCCPolicyProvider(sdk, "mychannel", "User1", "Org1")
ccPolicyProvider, err = newCCPolicyProvider(context, "mychannel", "User1", "Org1")
if err != nil {
t.Fatalf("Failed to setup cc policy provider: %s", err)
}
Expand All @@ -79,16 +106,21 @@ func TestBadClient(t *testing.T) {
}
defer sdk.Close()

clientContext := sdk.Context(fabsdk.WithUser("User1"), fabsdk.WithOrg("Org1"))

context, err := clientContext()
if err != nil {
t.Fatal("Failed to create context")
}

// Non-existent user
ccPolicyProvider, err := newCCPolicyProvider(sdk, "mychannel", "Invalid", "Org1")
_, err = ccPolicyProvider.GetChaincodePolicy("mychannel")
_, err = newCCPolicyProvider(context, "mychannel", "Invalid", "Org1")
if !strings.Contains(err.Error(), "user not found") {
t.Fatalf("Should have failed for invalid user name: %v", err)
}

// Invalid org
ccPolicyProvider, err = newCCPolicyProvider(sdk, "mychannel", "User1", "Invalid")
_, err = ccPolicyProvider.GetChaincodePolicy("mychannel")
_, err = newCCPolicyProvider(context, "mychannel", "User1", "Invalid")
if !strings.Contains(err.Error(), "invalid org name") {
t.Fatalf("Should have failed for invalid org name")
}
Expand Down
17 changes: 9 additions & 8 deletions pkg/client/common/selection/dynamicselection/dynamicselection.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import (
"fmt"
"sync"

"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/fabsdk"
"github.com/pkg/errors"

"github.com/hyperledger/fabric-sdk-go/pkg/client/common/selection/dynamicselection/pgresolver"
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/api"
)

// ChannelUser contains user(identity) info to be used for specific channel
Expand All @@ -28,10 +29,10 @@ type ChannelUser struct {
// SelectionProvider implements selection provider
// TODO: refactor users into client contexts
type SelectionProvider struct {
config core.Config
users []ChannelUser
lbp pgresolver.LoadBalancePolicy
sdk *fabsdk.FabricSDK
config core.Config
users []ChannelUser
lbp pgresolver.LoadBalancePolicy
providers api.Providers
}

// New returns dynamic selection provider
Expand All @@ -52,8 +53,8 @@ type selectionService struct {
}

// Initialize allow for initializing providers
func (p *SelectionProvider) Initialize(sdk *fabsdk.FabricSDK) error {
p.sdk = sdk
func (p *SelectionProvider) Initialize(providers *context.Provider) error {
p.providers = providers
return nil
}

Expand All @@ -75,7 +76,7 @@ func (p *SelectionProvider) CreateSelectionService(channelID string) (fab.Select
return nil, errors.New("Must provide user for channel")
}

ccPolicyProvider, err := newCCPolicyProvider(p.sdk, channelID, channelUser.UserName, channelUser.OrgName)
ccPolicyProvider, err := newCCPolicyProvider(p.providers, channelID, channelUser.UserName, channelUser.OrgName)
if err != nil {
return nil, errors.WithMessage(err, "Failed to create cc policy provider")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-sdk-go/pkg/client/common/selection/dynamicselection/pgresolver"
"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/core/config"
Expand Down Expand Up @@ -324,33 +325,44 @@ func toString(peers []fab.Peer) string {

func TestDynamicSelection(t *testing.T) {

c, err := config.FromFile("../../../../../test/fixtures/config/config_test.yaml")()
// Create SDK setup for channel client with dynamic selection
sdk, err := fabsdk.New(config.FromFile("../../../../../test/fixtures/config/config_test.yaml"))
if err != nil {
t.Fatalf("Failed to create new SDK: %s", err)
}
defer sdk.Close()

clientContext := sdk.Context(fabsdk.WithUser("User1"), fabsdk.WithOrg("Org1"))
ctx, err := clientContext()
if err != nil {
t.Fatalf(err.Error())
t.Fatalf("Failed to to get client context: %s", err)
}

mychannelUser := ChannelUser{ChannelID: "mychannel", UserName: "User1", OrgName: "Org1"}

selectionProvider, err := New(c, []ChannelUser{mychannelUser}, nil)
selectionProvider, err := New(ctx.Config(), []ChannelUser{mychannelUser}, nil)
if err != nil {
t.Fatalf("Failed to setup selection provider: %s", err)
}

selectionProvider.providers = ctx
_, err = selectionProvider.CreateSelectionService("")
if err == nil {
t.Fatalf("Should have failed for empty channel name")
}

selectionProvider.providers = nil
_, err = selectionProvider.CreateSelectionService("mychannel")
if err == nil {
t.Fatalf("Should have failed since sdk not provided")
}

testLBPolicy(t, c, selectionProvider, mychannelUser)
testCustomLBPolicy(t, c, selectionProvider, mychannelUser)
selectionProvider.providers = ctx
testLBPolicy(t, selectionProvider)
testCustomLBPolicy(t, ctx.Config(), selectionProvider, mychannelUser)
}

func testLBPolicy(t *testing.T, c core.Config, selectionProvider *SelectionProvider, mychannelUser ChannelUser) {
func testLBPolicy(t *testing.T, selectionProvider *SelectionProvider) {
factory := DynamicSelectionProviderFactory{
selectionProvider: selectionProvider,
}
Expand Down Expand Up @@ -459,3 +471,9 @@ func (lbp *customLBP) Choose(peerGroups []pgresolver.PeerGroup) pgresolver.PeerG
}
return peerGroups[0]
}

func setupMockContext(userName, orgName string) context.Providers {
user := mocks.NewMockUserWithMSPID(userName, orgName)
ctx := mocks.NewMockContext(user)
return ctx
}
4 changes: 2 additions & 2 deletions pkg/client/resmgmt/resmgmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ type SaveChannelRequest struct {
// Path to channel configuration file
ChannelConfig string
// Users that sign channel configuration
SigningIdentities []context.Identity
SigningIdentities []fab.IdentityContext
}

//RequestOption func for each Opts argument
Expand Down Expand Up @@ -195,7 +195,7 @@ func (rc *Client) JoinChannel(channelID string, options ...RequestOption) error
}

// TODO: handle more than the first orderer.
orderer, err := rc.context.FabricProvider().CreateOrdererFromConfig(&oConfig[0])
orderer, err := rc.context.InfraProvider().CreateOrdererFromConfig(&oConfig[0])
if err != nil {
return errors.WithMessage(err, "failed to create orderers from config")
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/client/resmgmt/resmgmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ func TestJoinChannelNoOrdererConfig(t *testing.T) {
}
ctx.SetConfig(invalidOrdererConfig)
customFabProvider := fabpvdr.New(ctx)
ctx.SetCustomFabricProvider(customFabProvider)
ctx.SetCustomInfraProvider(customFabProvider)

rc = setupResMgmtClient(ctx, nil, t)

Expand Down Expand Up @@ -1299,15 +1299,15 @@ func TestSaveChannelWithMultipleSigningIdenities(t *testing.T) {
cc := setupDefaultResMgmtClient(t)

// empty list of signing identities (defaults to context user)
req := SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig, SigningIdentities: []context.Identity{}}
req := SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig, SigningIdentities: []fab.IdentityContext{}}
err := cc.SaveChannel(req, WithOrdererID(""))
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: []context.Identity{cc.context, secondCtx}}
req = SaveChannelRequest{ChannelID: "mychannel", ChannelConfig: channelConfig, SigningIdentities: []fab.IdentityContext{cc.context, secondCtx}}
err = cc.SaveChannel(req, WithOrdererID(""))
if err != nil {
t.Fatalf("Failed to save channel with multiple signing identities: %s", err)
Expand Down
Loading

0 comments on commit d92bc58

Please sign in to comment.