Skip to content

Commit

Permalink
[FAB-8211] Expose ledger from channel svc
Browse files Browse the repository at this point in the history
This patch exposes the ledger interface from
a client's channel service. The integration tests
related to ledger queries are adjusted to use this
interface.

Change-Id: I6ccf8455583f5f62e8fdb1982482853aab315efd
Signed-off-by: Troy Ronda <[email protected]>
  • Loading branch information
troyronda committed Feb 11, 2018
1 parent ac89b89 commit 031b888
Show file tree
Hide file tree
Showing 25 changed files with 532 additions and 351 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ You're good to go, happy coding! Check out the examples for usage demonstrations
### Examples

- [E2E Test](test/integration/e2e/end_to_end.go): Basic example that uses SDK to query and execute transaction
- [Ledger Query Test](test/integration/fab/channel_ledger_test.go): Basic example that uses SDK to query a channel's underlying ledger
- [Multi Org Test](test/integration/orgs/multiple_orgs_test.go): An example that has multiple organisations involved in transaction
- [Dynamic Endorser Selection](test/integration/sdk/sdk_provider_test.go): An example that uses dynamic endorser selection (based on chaincode policy)
- [E2E PKCS11 Test](test/integration/pkcs11/e2e_test.go): E2E Test using a PKCS11 crypto suite and configuration
Expand Down
10 changes: 5 additions & 5 deletions api/apifabclient/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ type Channel interface {

// ChannelLedger provides access to the underlying ledger for a channel.
type ChannelLedger interface {
QueryInfo(targets []ProposalProcessor) (*common.BlockchainInfo, error)
QueryBlock(blockNumber int, targets []ProposalProcessor) (*common.Block, error)
QueryBlockByHash(blockHash []byte, targets []ProposalProcessor) (*common.Block, error)
QueryTransaction(transactionID string, targets []ProposalProcessor) (*pb.ProcessedTransaction, error)
QueryInstantiatedChaincodes(targets []ProposalProcessor) (*pb.ChaincodeQueryResponse, error)
QueryInfo(targets []ProposalProcessor) ([]*common.BlockchainInfo, error)
QueryBlock(blockNumber int, targets []ProposalProcessor) ([]*common.Block, error)
QueryBlockByHash(blockHash []byte, targets []ProposalProcessor) ([]*common.Block, error)
QueryTransaction(transactionID string, targets []ProposalProcessor) ([]*pb.ProcessedTransaction, error)
QueryInstantiatedChaincodes(targets []ProposalProcessor) ([]*pb.ChaincodeQueryResponse, error)
}

// OrgAnchorPeer contains information about an anchor peer on this channel
Expand Down
1 change: 1 addition & 0 deletions api/apifabclient/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type ChannelProvider interface {
// ChannelService supplies services related to a channel.
type ChannelService interface {
ChannelConfig() (ChannelConfig, error)
Ledger() (ChannelLedger, error)
Channel() (Channel, error)
EventHub() (EventHub, error) // TODO support new event delivery
}
4 changes: 2 additions & 2 deletions api/apifabclient/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
type Resource interface {
CreateChannel(request CreateChannelRequest) (TransactionID, error)
InstallChaincode(request InstallChaincodeRequest) ([]*TransactionProposalResponse, string, error)
QueryInstalledChaincodes(peer Peer) (*pb.ChaincodeQueryResponse, error)
QueryChannels(peer Peer) (*pb.ChannelQueryResponse, error)
QueryInstalledChaincodes(peer ProposalProcessor) (*pb.ChaincodeQueryResponse, error)
QueryChannels(peer ProposalProcessor) (*pb.ChannelQueryResponse, error)

GenesisBlockFromOrderer(channelName string, orderer Orderer) (*common.Block, error)
JoinChannel(request JoinChannelRequest) error
Expand Down
36 changes: 30 additions & 6 deletions pkg/fabric-client/channel/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,11 @@ func resolveOrdererURL(ordererURL string) string {
// (height, known peers).
// This query will be made to the primary peer.
func (c *Channel) QueryInfo() (*common.BlockchainInfo, error) {
l := NewLedger(c.clientContext, c.name)
l, err := NewLedger(c.clientContext, c.name)
if err != nil {
return nil, errors.WithMessage(err, "ledger client creation failed")
}

resps, err := l.QueryInfo([]fab.ProposalProcessor{c.PrimaryPeer()})
if err != nil {
return nil, err
Expand All @@ -343,7 +347,11 @@ func (c *Channel) QueryInfo() (*common.BlockchainInfo, error) {
// This query will be made to the primary peer.
// Returns the block.
func (c *Channel) QueryBlockByHash(blockHash []byte) (*common.Block, error) {
l := NewLedger(c.clientContext, c.name)
l, err := NewLedger(c.clientContext, c.name)
if err != nil {
return nil, errors.WithMessage(err, "ledger client creation failed")
}

resps, err := l.QueryBlockByHash(blockHash, []fab.ProposalProcessor{c.PrimaryPeer()})
if err != nil {
return nil, err
Expand All @@ -356,7 +364,11 @@ func (c *Channel) QueryBlockByHash(blockHash []byte) (*common.Block, error) {
// blockNumber: The number which is the ID of the Block.
// It returns the block.
func (c *Channel) QueryBlock(blockNumber int) (*common.Block, error) {
l := NewLedger(c.clientContext, c.name)
l, err := NewLedger(c.clientContext, c.name)
if err != nil {
return nil, errors.WithMessage(err, "ledger client creation failed")
}

resps, err := l.QueryBlock(blockNumber, []fab.ProposalProcessor{c.PrimaryPeer()})
if err != nil {
return nil, err
Expand All @@ -369,7 +381,11 @@ func (c *Channel) QueryBlock(blockNumber int) (*common.Block, error) {
// Returns the ProcessedTransaction information containing the transaction.
// TODO: add optional target
func (c *Channel) QueryTransaction(transactionID string) (*pb.ProcessedTransaction, error) {
l := NewLedger(c.clientContext, c.name)
l, err := NewLedger(c.clientContext, c.name)
if err != nil {
return nil, errors.WithMessage(err, "ledger client creation failed")
}

resps, err := l.QueryTransaction(transactionID, []fab.ProposalProcessor{c.PrimaryPeer()})
if err != nil {
return nil, err
Expand All @@ -380,7 +396,11 @@ func (c *Channel) QueryTransaction(transactionID string) (*pb.ProcessedTransacti
// QueryInstantiatedChaincodes queries the instantiated chaincodes on this channel.
// This query will be made to the primary peer.
func (c *Channel) QueryInstantiatedChaincodes() (*pb.ChaincodeQueryResponse, error) {
l := NewLedger(c.clientContext, c.name)
l, err := NewLedger(c.clientContext, c.name)
if err != nil {
return nil, errors.WithMessage(err, "ledger client creation failed")
}

resps, err := l.QueryInstantiatedChaincodes([]fab.ProposalProcessor{c.PrimaryPeer()})
if err != nil {
return nil, err
Expand All @@ -392,7 +412,11 @@ func (c *Channel) QueryInstantiatedChaincodes() (*pb.ChaincodeQueryResponse, err
// QueryConfigBlock returns the current configuration block for the specified channel. If the
// peer doesn't belong to the channel, return error
func (c *Channel) QueryConfigBlock(peers []fab.Peer, minResponses int) (*common.ConfigEnvelope, error) {
l := NewLedger(c.clientContext, c.name)
l, err := NewLedger(c.clientContext, c.name)
if err != nil {
return nil, errors.WithMessage(err, "ledger client creation failed")
}

return l.QueryConfigBlock(peers, minResponses)
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/fabric-client/channel/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ type Ledger struct {
}

// NewLedger constructs a Ledger client for the current context and named channel.
func NewLedger(ctx fab.Context, chName string) *Ledger {
func NewLedger(ctx fab.Context, chName string) (*Ledger, error) {
l := Ledger{
ctx: ctx,
chName: chName,
}
return &l
return &l, nil
}

// QueryInfo queries for various useful information on the state of the channel
Expand Down
2 changes: 1 addition & 1 deletion pkg/fabric-client/channel/ledger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,5 +181,5 @@ func setupTestLedger() (*Ledger, error) {
func setupLedger(channelID string) (*Ledger, error) {
user := mocks.NewMockUser("test")
ctx := mocks.NewMockContext(user)
return NewLedger(ctx, channelID), nil
return NewLedger(ctx, channelID)
}
5 changes: 5 additions & 0 deletions pkg/fabric-client/mocks/mockchprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,8 @@ func (cs *MockChannelService) Channel() (fab.Channel, error) {
func (cs *MockChannelService) ChannelConfig() (fab.ChannelConfig, error) {
return nil, nil
}

// Ledger ...
func (cs *MockChannelService) Ledger() (fab.ChannelLedger, error) {
return nil, nil
}
4 changes: 2 additions & 2 deletions pkg/fabric-client/mocks/mockresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (c *MockResource) CreateChannel(request fab.CreateChannelRequest) (fab.Tran
}

//QueryChannels ...
func (c *MockResource) QueryChannels(peer fab.Peer) (*pb.ChannelQueryResponse, error) {
func (c *MockResource) QueryChannels(peer fab.ProposalProcessor) (*pb.ChannelQueryResponse, error) {
return nil, errors.New("Not implemented yet")
}

Expand All @@ -77,7 +77,7 @@ func (c *MockResource) JoinChannel(request fab.JoinChannelRequest) error {
}

//QueryInstalledChaincodes mocks query installed chaincodes
func (c *MockResource) QueryInstalledChaincodes(peer fab.Peer) (*pb.ChaincodeQueryResponse, error) {
func (c *MockResource) QueryInstalledChaincodes(peer fab.ProposalProcessor) (*pb.ChaincodeQueryResponse, error) {
if peer == nil {
return nil, errors.New("Generate Error")
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/fabric-client/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ func (c *Resource) createOrUpdateChannel(request fab.CreateChannelRequest, haveE
}

// QueryChannels queries the names of all the channels that a peer has joined.
func (c *Resource) QueryChannels(peer fab.Peer) (*pb.ChannelQueryResponse, error) {
func (c *Resource) QueryChannels(peer fab.ProposalProcessor) (*pb.ChannelQueryResponse, error) {

if peer == nil {
return nil, errors.New("peer required")
Expand All @@ -346,7 +346,7 @@ func (c *Resource) QueryChannels(peer fab.Peer) (*pb.ChannelQueryResponse, error

// QueryInstalledChaincodes queries the installed chaincodes on a peer.
// Returns the details of all chaincodes installed on a peer.
func (c *Resource) QueryInstalledChaincodes(peer fab.Peer) (*pb.ChaincodeQueryResponse, error) {
func (c *Resource) QueryInstalledChaincodes(peer fab.ProposalProcessor) (*pb.ChaincodeQueryResponse, error) {

if peer == nil {
return nil, errors.New("peer required")
Expand Down
3 changes: 2 additions & 1 deletion pkg/fabsdk/api/pvdr.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import (
// FabricProvider enables access to fabric objects such as peer and user based on config or context.
type FabricProvider interface {
CreateChannelClient(user apifabclient.IdentityContext, cfg apifabclient.ChannelCfg) (apifabclient.Channel, error)
CreateChannelLedger(ic apifabclient.IdentityContext, name string) (apifabclient.ChannelLedger, error)
CreateChannelConfig(user apifabclient.IdentityContext, name string) (apifabclient.ChannelConfig, error)
CreateResourceClient(user apifabclient.IdentityContext) (apifabclient.Resource, error)
CreateEventHub(ic apifabclient.IdentityContext, channelID string) (apifabclient.EventHub, error)
CreateEventHub(ic apifabclient.IdentityContext, name string) (apifabclient.EventHub, error)
CreateCAClient(orgID string) (apifabca.FabricCAClient, error)

CreatePeerFromConfig(peerCfg *apiconfig.NetworkPeer) (apifabclient.Peer, error)
Expand Down
5 changes: 5 additions & 0 deletions pkg/fabsdk/provider/chpvdr/chprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,8 @@ func (cs *ChannelService) EventHub() (apifabclient.EventHub, error) {
func (cs *ChannelService) ChannelConfig() (apifabclient.ChannelConfig, error) {
return cs.fabricProvider.CreateChannelConfig(cs.identityContext, cs.cfg.Name())
}

// Ledger providers a client for the current context and named channel.
func (cs *ChannelService) Ledger() (apifabclient.ChannelLedger, error) {
return cs.fabricProvider.CreateChannelLedger(cs.identityContext, cs.cfg.Name())
}
14 changes: 14 additions & 0 deletions pkg/fabsdk/provider/fabpvdr/fabpvdr.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ func (f *FabricProvider) CreateChannelClient(ic apifabclient.IdentityContext, cf
return channel, nil
}

// CreateChannelLedger returns a new client initialized for the current instance of the SDK.
func (f *FabricProvider) CreateChannelLedger(ic apifabclient.IdentityContext, channelName string) (apifabclient.ChannelLedger, error) {
ctx := &fabContext{
ProviderContext: f.providerContext,
IdentityContext: ic,
}
ledger, err := channelImpl.NewLedger(ctx, channelName)
if err != nil {
return nil, errors.WithMessage(err, "NewLedger failed")
}

return ledger, nil
}

// CreateEventHub initilizes the event hub.
func (f *FabricProvider) CreateEventHub(ic apifabclient.IdentityContext, channelID string) (apifabclient.EventHub, error) {
peerConfig, err := f.providerContext.Config().ChannelPeers(channelID)
Expand Down
2 changes: 1 addition & 1 deletion pkg/logging/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func loggerProvider() apilogging.LoggerProvider {
// Otherwise the built-in logger is used
loggerProviderInstance = modlog.LoggerProvider()
logger := loggerProviderInstance.GetLogger(loggerModule)
logger.Info(loggerNotInitializedMsg)
logger.Debug(loggerNotInitializedMsg)
})
return loggerProviderInstance
}
Expand Down
Loading

0 comments on commit 031b888

Please sign in to comment.