Skip to content

Commit

Permalink
[FAB-7831] Move funcs that propagate SDK context
Browse files Browse the repository at this point in the history
This change moves SDK provides to a context object
that can be passed around. This removes the need to expose
all methods directly from the SDK object.

The underlying FabricClient method is also refactored
into a smaller Resource interface to limit exposure
from the SDK. This work continues in upcoming
changes.

Change-Id: I9233fd6278683cd2b24a47c6d4c10032e75f7c5f
Signed-off-by: Troy Ronda <[email protected]>
  • Loading branch information
troyronda committed Jan 22, 2018
1 parent 6d35bfc commit 21d796d
Show file tree
Hide file tree
Showing 59 changed files with 835 additions and 782 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ mock-gen:
mockgen -build_flags '$(GO_LDFLAGS_ARG)' github.com/hyperledger/fabric-sdk-go/api/apitxn ProposalProcessor | sed "s/github.com\/hyperledger\/fabric-sdk-go\/vendor\///g" | goimports > api/apitxn/mocks/mockapitxn.gen.go
mockgen -build_flags '$(GO_LDFLAGS_ARG)' github.com/hyperledger/fabric-sdk-go/api/apiconfig Config | sed "s/github.com\/hyperledger\/fabric-sdk-go\/vendor\///g" | goimports > api/apiconfig/mocks/mockconfig.gen.go
mockgen -build_flags '$(GO_LDFLAGS_ARG)' github.com/hyperledger/fabric-sdk-go/api/apifabca FabricCAClient | sed "s/github.com\/hyperledger\/fabric-sdk-go\/vendor\///g" | goimports > api/apifabca/mocks/mockfabriccaclient.gen.go
mockgen -build_flags '$(GO_LDFLAGS_ARG)' github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/api SDK,CoreProviderFactory,ServiceProviderFactory,OrgClientFactory,SessionClientFactory | sed "s/github.com\/hyperledger\/fabric-sdk-go\/vendor\///g" | goimports > pkg/fabsdk/api/mocks/mocksdkapi.gen.go
mockgen -build_flags '$(GO_LDFLAGS_ARG)' github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/api CoreProviders,SvcProviders,Providers,CoreProviderFactory,ServiceProviderFactory,OrgClientFactory,SessionClientFactory | sed "s/github.com\/hyperledger\/fabric-sdk-go\/vendor\///g" | goimports > pkg/fabsdk/api/mocks/mocksdkapi.gen.go

# TODO - Add cryptogen
.PHONY: channel-config-gen
Expand Down
9 changes: 6 additions & 3 deletions api/apicore/fabric.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ import (
"crypto/x509"

"github.com/hyperledger/fabric-sdk-go/api/apiconfig"
"github.com/hyperledger/fabric-sdk-go/api/apifabca"
"github.com/hyperledger/fabric-sdk-go/api/apifabclient"
)

// FabricProvider allows overriding of fabric objects such as peer and user
// FabricProvider enables access to fabric objects such as peer and user
type FabricProvider interface {
NewClient(user apifabclient.User) (apifabclient.FabricClient, error)
NewChannelClient(user apifabclient.IdentityContext, name string) (apifabclient.Channel, error)
NewResourceClient(user apifabclient.IdentityContext) (apifabclient.Resource, error)
NewCAClient(orgID string) (apifabca.FabricCAClient, error)

NewPeer(url string, certificate *x509.Certificate, serverHostOverride string) (apifabclient.Peer, error)
NewPeerFromConfig(peerCfg *apiconfig.NetworkPeer) (apifabclient.Peer, error)
// EnrollUser(orgID, name, pwd string) (apifabca.User, error)
NewUser(name string, signingIdentity *apifabclient.SigningIdentity) (apifabclient.User, error)
}
8 changes: 1 addition & 7 deletions api/apifabclient/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type Channel interface {
OrganizationUnits() ([]string, error)

// Channel Info
GenesisBlock(request *GenesisBlockRequest) (*common.Block, error)
GenesisBlock() (*common.Block, error)
JoinChannel(request *JoinChannelRequest) error
UpdateChannel() bool
IsReadonly() bool
Expand All @@ -74,14 +74,8 @@ type OrgAnchorPeer struct {
Port int32
}

// GenesisBlockRequest ...
type GenesisBlockRequest struct {
TxnID txn.TransactionID
}

// JoinChannelRequest allows a set of peers to transact on a channel on the network
type JoinChannelRequest struct {
Targets []Peer
GenesisBlock *common.Block
TxnID txn.TransactionID
}
54 changes: 37 additions & 17 deletions api/apifabclient/fabricclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,37 @@ import (
pb "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/peer"
)

// FabricClient ...
// Resource is a client that provides access to fabric resources such as chaincode.
type Resource interface {
Context
client

// TODO refactor into channel provider and remove from Resource (upcoming CR)
NewChannel(name string) (Channel, error)
Channel(name string) Channel
}

type client interface {
CreateChannel(request CreateChannelRequest) (txn.TransactionID, error)
InstallChaincode(request InstallChaincodeRequest) ([]*txn.TransactionProposalResponse, string, error)
QueryInstalledChaincodes(peer Peer) (*pb.ChaincodeQueryResponse, error)
QueryChannels(peer Peer) (*pb.ChannelQueryResponse, error)

ExtractChannelConfig(configEnvelope []byte) ([]byte, error)
SignChannelConfig(config []byte, signer IdentityContext) (*common.ConfigSignature, error)
}

// Context supplies the configuration and signing identity to client objects.
type Context interface {
SigningManager() SigningManager
Config() config.Config
CryptoSuite() apicryptosuite.CryptoSuite
IdentityContext() IdentityContext
}

// FabricClient provides access to infrastructure functionality.
//
// Deprecated: this interface has been renamed.
/*
* Main interaction handler with end user. A client instance provides a handler to interact
* with a network of peers, orderers and optionally member services. An application using the
Expand All @@ -32,24 +62,14 @@ import (
*
*/
type FabricClient interface {
NewChannel(name string) (Channel, error)
Channel(name string) Channel
ExtractChannelConfig(configEnvelope []byte) ([]byte, error)
SignChannelConfig(config []byte, signer User) (*common.ConfigSignature, error)
CreateChannel(request CreateChannelRequest) (txn.TransactionID, error)
Resource

QueryChannelInfo(name string, peers []Peer) (Channel, error)
StateStore() KeyValueStore
SigningManager() SigningManager
CryptoSuite() apicryptosuite.CryptoSuite
SaveUserToStateStore(user User, skipPersistence bool) error

SetIdentityContext(identity IdentityContext)
SaveUserToStateStore(user User) error
LoadUserFromStateStore(name string) (User, error)
InstallChaincode(request InstallChaincodeRequest) ([]*txn.TransactionProposalResponse, string, error)
QueryChannels(peer Peer) (*pb.ChannelQueryResponse, error)
QueryInstalledChaincodes(peer Peer) (*pb.ChaincodeQueryResponse, error)
UserContext() User
SetUserContext(user User)
Config() config.Config // TODO: refactor to a fab client config interface
NewTxnID() (txn.TransactionID, error)
StateStore() KeyValueStore
}

// CreateChannelRequest requests channel creation on the network
Expand Down
12 changes: 10 additions & 2 deletions api/apifabclient/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,18 @@ import "github.com/hyperledger/fabric-sdk-go/api/apicryptosuite"
// An application cannot use the Peer identity to sign things because the application doesn’t
// have access to the Peer identity’s private key.
type User interface {
IdentityContext

Name() string
MspID() string
EnrollmentCertificate() []byte
PrivateKey() apicryptosuite.Key
Roles() []string
}

// IdentityContext supplies the serialized identity and key reference.
//
// TODO - refactor SigningIdentity and this interface.
type IdentityContext interface {
MspID() string
Identity() ([]byte, error)
PrivateKey() apicryptosuite.Key
}
2 changes: 1 addition & 1 deletion api/apitxn/chmgmtclient/chmgmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type SaveChannelRequest struct {
// Path to channel configuration file
ChannelConfig string
// User that signs channel configuration
SigningUser fab.User
SigningIdentity fab.IdentityContext
}

// SaveChannelOpts contains options for saving channel
Expand Down
24 changes: 8 additions & 16 deletions def/factory/defclient/sessfactory.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,21 @@ func NewSessionClientFactory() *SessionClientFactory {
return &f
}

/*
// NewSystemClient returns a new FabricClient.
// TODO: duplicate of core factory method or rename?
func (f *SessionClientFactory) NewSystemClient(sdk apisdk.SDK, session apisdk.Session, config apiconfig.Config) (fab.FabricClient, error) {
return sdk.FabricProvider().NewClient(session.Identity())
}
*/

// NewChannelMgmtClient returns a client that manages channels (create/join channel)
func (f *SessionClientFactory) NewChannelMgmtClient(sdk apisdk.SDK, session apisdk.Session, config apiconfig.Config) (chmgmt.ChannelMgmtClient, error) {
func (f *SessionClientFactory) NewChannelMgmtClient(sdk apisdk.Providers, session apisdk.Session, config apiconfig.Config) (chmgmt.ChannelMgmtClient, error) {
// For now settings are the same as for system client
client, err := sdk.FabricProvider().NewClient(session.Identity())
client, err := sdk.FabricProvider().NewResourceClient(session.Identity())
if err != nil {
return nil, err
}
return chmgmtImpl.NewChannelMgmtClient(client, config)
}

// NewResourceMgmtClient returns a client that manages resources
func (f *SessionClientFactory) NewResourceMgmtClient(sdk apisdk.SDK, session apisdk.Session, config apiconfig.Config, filter resmgmt.TargetFilter) (resmgmt.ResourceMgmtClient, error) {
func (f *SessionClientFactory) NewResourceMgmtClient(sdk apisdk.Providers, session apisdk.Session, config apiconfig.Config, filter resmgmt.TargetFilter) (resmgmt.ResourceMgmtClient, error) {

// For now settings are the same as for system client
client, err := sdk.FabricProvider().NewClient(session.Identity())
client, err := sdk.FabricProvider().NewResourceClient(session.Identity())
if err != nil {
return nil, err
}
Expand All @@ -70,13 +62,13 @@ func (f *SessionClientFactory) NewResourceMgmtClient(sdk apisdk.SDK, session api

// NewChannelClient returns a client that can execute transactions on specified channel
// TODO - better refactoring for testing and/or extract getChannelImpl to another package
func (f *SessionClientFactory) NewChannelClient(sdk apisdk.SDK, session apisdk.Session, config apiconfig.Config, channelID string) (apitxn.ChannelClient, error) {
func (f *SessionClientFactory) NewChannelClient(sdk apisdk.Providers, session apisdk.Session, config apiconfig.Config, channelID string) (apitxn.ChannelClient, error) {
// TODO: Add capablity to override sdk's selection and discovery provider

client := clientImpl.NewClient(sdk.ConfigProvider())
client.SetCryptoSuite(sdk.CryptoSuiteProvider())
client.SetStateStore(sdk.StateStoreProvider())
client.SetUserContext(session.Identity())
client.SetIdentityContext(session.Identity())
client.SetSigningManager(sdk.SigningManager())

channel, err := getChannel(client, channelID)
Expand All @@ -103,7 +95,7 @@ func (f *SessionClientFactory) NewChannelClient(sdk apisdk.SDK, session apisdk.S
}

// getChannel is helper method to initializes and returns a channel based on config
func getChannel(client fab.FabricClient, channelID string) (fab.Channel, error) {
func getChannel(client fab.Resource, channelID string) (fab.Channel, error) {

channel, err := client.NewChannel(channelID)
if err != nil {
Expand Down Expand Up @@ -135,7 +127,7 @@ func getChannel(client fab.FabricClient, channelID string) (fab.Channel, error)
return channel, nil
}

func getEventHub(client fab.FabricClient, channelID string, session apisdk.Session) (*events.EventHub, error) {
func getEventHub(client fab.Resource, channelID string, session apisdk.Session) (*events.EventHub, error) {

peerConfig, err := client.Config().ChannelPeers(channelID)
if err != nil {
Expand Down
41 changes: 8 additions & 33 deletions def/factory/defclient/sessfactory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,12 @@ import (
mockapisdk "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/api/mocks"
)

/*
func TestNewSystemClient(t *testing.T) {
p := newMockProviders(t)
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockSDK := mock_context.NewMockSDK(mockCtrl)
mockSDK.EXPECT().FabricProvider().Return(p.FabricProvider)
factory := NewSessionClientFactory()
session := newMockSession()
client, err := factory.NewSystemClient(mockSDK, session, p.ConfigProvider)
if err != nil {
t.Fatalf("Unexpected error creating system client %v", err)
}
_, ok := client.(*clientImpl.Client)
if !ok {
t.Fatalf("Unexpected client created")
}
}
*/

func TestNewChannelMgmtClient(t *testing.T) {
p := newMockProviders(t)

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockSDK := mockapisdk.NewMockSDK(mockCtrl)
mockSDK := mockapisdk.NewMockProviders(mockCtrl)

mockSDK.EXPECT().FabricProvider().Return(p.FabricProvider)

Expand All @@ -79,7 +54,7 @@ func TestNewResourceMgmtClient(t *testing.T) {

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockSDK := mockapisdk.NewMockSDK(mockCtrl)
mockSDK := mockapisdk.NewMockProviders(mockCtrl)

mockSDK.EXPECT().FabricProvider().Return(p.FabricProvider)
mockSDK.EXPECT().DiscoveryProvider().Return(p.DiscoveryProvider)
Expand All @@ -103,7 +78,7 @@ func TestNewChannelClient(t *testing.T) {

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockSDK := mockapisdk.NewMockSDK(mockCtrl)
mockSDK := mockapisdk.NewMockProviders(mockCtrl)

mockSDK.EXPECT().ConfigProvider().Return(p.ConfigProvider)
mockSDK.EXPECT().CryptoSuiteProvider().Return(p.CryptosuiteProvider)
Expand Down Expand Up @@ -131,7 +106,7 @@ func TestNewChannelClientBadChannel(t *testing.T) {

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockSDK := mockapisdk.NewMockSDK(mockCtrl)
mockSDK := mockapisdk.NewMockProviders(mockCtrl)

mockSDK.EXPECT().ConfigProvider().Return(p.ConfigProvider)
mockSDK.EXPECT().CryptoSuiteProvider().Return(p.CryptosuiteProvider)
Expand All @@ -152,7 +127,7 @@ func TestNewChannelClientBadOrg(t *testing.T) {

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockSDK := mockapisdk.NewMockSDK(mockCtrl)
mockSDK := mockapisdk.NewMockProviders(mockCtrl)

mockSDK.EXPECT().ConfigProvider().Return(p.ConfigProvider)
mockSDK.EXPECT().CryptoSuiteProvider().Return(p.CryptosuiteProvider)
Expand All @@ -170,7 +145,7 @@ func TestNewChannelClientBadOrg(t *testing.T) {
}
}

func getChannelMock(client apifabclient.FabricClient, channelID string) (apifabclient.Channel, error) {
func getChannelMock(client apifabclient.Resource, channelID string) (apifabclient.Channel, error) {
return channel.NewChannel("channel", client)
}

Expand Down Expand Up @@ -235,7 +210,7 @@ func newMockProviders(t *testing.T) *mockProviders {
}

type mockSession struct {
user apifabclient.User
user apifabclient.IdentityContext
}

func newMockSession() *mockSession {
Expand All @@ -250,6 +225,6 @@ func newMockSessionWithUser(username, mspID string) *mockSession {
return &session
}

func (s *mockSession) Identity() apifabclient.User {
func (s *mockSession) Identity() apifabclient.IdentityContext {
return s.user
}
19 changes: 16 additions & 3 deletions def/provider/fabpvdr/fabpvdr.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/hyperledger/fabric-sdk-go/api/apifabclient"
fabricCAClient "github.com/hyperledger/fabric-sdk-go/pkg/fabric-ca-client"
clientImpl "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client"
channelImpl "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/channel"
identityImpl "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/identity"
peerImpl "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/peer"
)
Expand All @@ -38,13 +39,13 @@ func NewFabricProvider(config apiconfig.Config, stateStore apifabclient.KeyValue
return &f
}

// NewClient returns a new FabricClient initialized for the current instance of the SDK
func (f *FabricProvider) NewClient(user apifabclient.User) (apifabclient.FabricClient, error) {
// NewResourceClient returns a new client initialized for the current instance of the SDK
func (f *FabricProvider) NewResourceClient(ic apifabclient.IdentityContext) (apifabclient.Resource, error) {
client := clientImpl.NewClient(f.config)

client.SetCryptoSuite(f.cryptoSuite)
client.SetStateStore(f.stateStore)
client.SetUserContext(user)
client.SetIdentityContext(ic)
client.SetSigningManager(f.signer)

return client, nil
Expand Down Expand Up @@ -76,6 +77,18 @@ func (f *FabricProvider) NewPeerFromConfig(peerCfg *apiconfig.NetworkPeer) (apif
return peerImpl.New(f.config, peerImpl.FromPeerConfig(peerCfg))
}

// NewChannelClient returns a new client initialized for the current instance of the SDK
func (f *FabricProvider) NewChannelClient(ic apifabclient.IdentityContext, name string) (apifabclient.Channel, error) {
client := clientImpl.NewClient(f.config)

client.SetCryptoSuite(f.cryptoSuite)
client.SetStateStore(f.stateStore)
client.SetIdentityContext(ic)
client.SetSigningManager(f.signer)

return channelImpl.NewChannel(name, client)
}

/*
TODO: Unclear that this EnrollUser helper is really needed at this level - I think not.
Note: I renamed NewPreEnrolledUser to NewUser; and the old NewUser to EnrollUser
Expand Down
Loading

0 comments on commit 21d796d

Please sign in to comment.