Skip to content

Commit

Permalink
Merge changes If522b44a,I3fa2b924
Browse files Browse the repository at this point in the history
* changes:
  [FAB-2120] Move configtx.Filter back to orderer
  [FAB-2097] Add config next proto
  • Loading branch information
binhn authored and Gerrit Code Review committed Feb 10, 2017
2 parents d0e433b + 14e3a11 commit fd536a3
Show file tree
Hide file tree
Showing 22 changed files with 573 additions and 187 deletions.
79 changes: 79 additions & 0 deletions common/configtx/api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
Copyright IBM Corp. 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package api

import (
"github.com/hyperledger/fabric/common/chainconfig"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/msp"
cb "github.com/hyperledger/fabric/protos/common"
)

// Handler provides a hook which allows other pieces of code to participate in config proposals
type Handler interface {
// BeginConfig called when a config proposal is begun
BeginConfig()

// RollbackConfig called when a config proposal is abandoned
RollbackConfig()

// CommitConfig called when a config proposal is committed
CommitConfig()

// ProposeConfig called when config is added to a proposal
ProposeConfig(configItem *cb.ConfigItem) error
}

// Manager provides a mechanism to query and update config
type Manager interface {
Resources

// Apply attempts to apply a configtx to become the new config
Apply(configtx *cb.ConfigEnvelope) error

// Validate attempts to validate a new configtx against the current config state
Validate(configtx *cb.ConfigEnvelope) error

// ChainID retrieves the chain ID associated with this manager
ChainID() string

// Sequence returns the current sequence number of the config
Sequence() uint64
}

// Resources is the common set of config resources for all chains
// Depending on whether chain is used at the orderer or at the peer, other
// config resources may be available
type Resources interface {
// PolicyManager returns the policies.Manager for the chain
PolicyManager() policies.Manager

// ChainConfig returns the chainconfig.Descriptor for the chain
ChainConfig() chainconfig.Descriptor

// MSPManager returns the msp.MSPManager for the chain
MSPManager() msp.MSPManager
}

// Initializer is a structure which is only useful before a configtx.Manager
// has been instantiated for a chain, afterwards, it is of no utility, which
// is why it embeds the Resources interface
type Initializer interface {
Resources
// Handlers returns the handlers to be used when initializing the configtx.Manager
Handlers() map[cb.ConfigItem_ConfigType]Handler
}
51 changes: 16 additions & 35 deletions common/configtx/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import (
"reflect"
"regexp"

"github.com/hyperledger/fabric/common/configtx/api"
"github.com/hyperledger/fabric/common/policies"
cb "github.com/hyperledger/fabric/protos/common"
"github.com/hyperledger/fabric/protos/utils"

logging "github.com/op/go-logging"
)
Expand All @@ -40,38 +42,6 @@ var (
}
)

// Handler provides a hook which allows other pieces of code to participate in config proposals
type Handler interface {
// BeginConfig called when a config proposal is begun
BeginConfig()

// RollbackConfig called when a config proposal is abandoned
RollbackConfig()

// CommitConfig called when a config proposal is committed
CommitConfig()

// ProposeConfig called when config is added to a proposal
ProposeConfig(configItem *cb.ConfigItem) error
}

// Manager provides a mechanism to query and update config
type Manager interface {
Resources

// Apply attempts to apply a configtx to become the new config
Apply(configtx *cb.ConfigEnvelope) error

// Validate attempts to validate a new configtx against the current config state
Validate(configtx *cb.ConfigEnvelope) error

// ChainID retrieves the chain ID associated with this manager
ChainID() string

// Sequence returns the current sequence number of the config
Sequence() uint64
}

// NewConfigItemPolicyKey is the ID of the policy used when no other policy can be resolved, for instance when attempting to create a new config item
const NewConfigItemPolicyKey = "NewConfigItemPolicy"

Expand All @@ -82,11 +52,11 @@ func (ap *acceptAllPolicy) Evaluate(signedData []*cb.SignedData) error {
}

type configManager struct {
Initializer
api.Initializer
sequence uint64
chainID string
config map[cb.ConfigItem_ConfigType]map[string]*cb.ConfigItem
callOnUpdate []func(Manager)
callOnUpdate []func(api.Manager)
}

// computeChainIDAndSequence returns the chain id and the sequence number for a config envelope
Expand Down Expand Up @@ -151,9 +121,20 @@ func validateChainID(chainID string) error {
return nil
}

func NewManagerImplNext(configtx *cb.ConfigEnvelope, initializer api.Initializer, callOnUpdate []func(api.Manager)) (api.Manager, error) {
configNext, err := UnmarshalConfigNext(configtx.Config)
if err != nil {
return nil, err
}

config := ConfigNextToConfig(configNext)

return NewManagerImpl(&cb.ConfigEnvelope{Config: utils.MarshalOrPanic(config), Signatures: configtx.Signatures}, initializer, callOnUpdate)
}

// NewManagerImpl creates a new Manager unless an error is encountered, each element of the callOnUpdate slice
// is invoked when a new config is committed
func NewManagerImpl(configtx *cb.ConfigEnvelope, initializer Initializer, callOnUpdate []func(Manager)) (Manager, error) {
func NewManagerImpl(configtx *cb.ConfigEnvelope, initializer api.Initializer, callOnUpdate []func(api.Manager)) (api.Manager, error) {
for ctype := range cb.ConfigItem_ConfigType_name {
if _, ok := initializer.Handlers()[cb.ConfigItem_ConfigType(ctype)]; !ok {
return nil, errors.New("Must supply a handler for all known types")
Expand Down
16 changes: 8 additions & 8 deletions common/configtx/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package configtx_test
package configtx

import (
"errors"
"fmt"
"testing"

. "github.com/hyperledger/fabric/common/configtx"
"github.com/hyperledger/fabric/common/configtx/api"
mockconfigtx "github.com/hyperledger/fabric/common/mocks/configtx"
"github.com/hyperledger/fabric/common/policies"
cb "github.com/hyperledger/fabric/protos/common"
Expand All @@ -30,8 +30,8 @@ import (

var defaultChain = "DefaultChainID"

func defaultHandlers() map[cb.ConfigItem_ConfigType]Handler {
handlers := make(map[cb.ConfigItem_ConfigType]Handler)
func defaultHandlers() map[cb.ConfigItem_ConfigType]api.Handler {
handlers := make(map[cb.ConfigItem_ConfigType]api.Handler)
for ctype := range cb.ConfigItem_ConfigType_name {
handlers[cb.ConfigItem_ConfigType(ctype)] = NewBytesHandler()
}
Expand Down Expand Up @@ -87,22 +87,22 @@ func makeMarshaledConfig(chainID string, configItems ...*cb.ConfigItem) []byte {
func TestOmittedHandler(t *testing.T) {
_, err := NewManagerImpl(&cb.ConfigEnvelope{
Config: makeMarshaledConfig(defaultChain, makeConfigItem("foo", "foo", 0, []byte("foo"))),
}, &mockconfigtx.Initializer{PolicyManagerVal: &mockPolicyManager{&mockPolicy{}}, HandlersVal: map[cb.ConfigItem_ConfigType]Handler{}}, nil)
}, &mockconfigtx.Initializer{PolicyManagerVal: &mockPolicyManager{&mockPolicy{}}, HandlersVal: map[cb.ConfigItem_ConfigType]api.Handler{}}, nil)

if err == nil {
t.Fatal("Should have failed to construct manager because handlers were missing")
}
}

func TestCallback(t *testing.T) {
var calledBack Manager
callback := func(m Manager) {
var calledBack api.Manager
callback := func(m api.Manager) {
calledBack = m
}

cm, err := NewManagerImpl(&cb.ConfigEnvelope{
Config: makeMarshaledConfig(defaultChain, makeConfigItem("foo", "foo", 0, []byte("foo"))),
}, &mockconfigtx.Initializer{PolicyManagerVal: &mockPolicyManager{&mockPolicy{}}, HandlersVal: defaultHandlers()}, []func(Manager){callback})
}, &mockconfigtx.Initializer{PolicyManagerVal: &mockPolicyManager{&mockPolicy{}}, HandlersVal: defaultHandlers()}, []func(api.Manager){callback})

if err != nil {
t.Fatalf("Error constructing config manager: %s", err)
Expand Down
32 changes: 5 additions & 27 deletions common/configtx/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,15 @@ package configtx
import (
"github.com/hyperledger/fabric/common/cauthdsl"
"github.com/hyperledger/fabric/common/chainconfig"
"github.com/hyperledger/fabric/common/configtx/api"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/msp"
mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
cb "github.com/hyperledger/fabric/protos/common"
)

// Resources is the common set of config resources for all chains
// Depending on whether chain is used at the orderer or at the peer, other
// config resources may be available
type Resources interface {
// PolicyManager returns the policies.Manager for the chain
PolicyManager() policies.Manager

// ChainConfig returns the chainconfig.Descriptor for the chain
ChainConfig() chainconfig.Descriptor

// MSPManager returns the msp.MSPManager for the chain
MSPManager() msp.MSPManager
}

// Initializer is a structure which is only useful before a configtx.Manager
// has been instantiated for a chain, afterwards, it is of no utility, which
// is why it embeds the Resources interface
type Initializer interface {
Resources
// Handlers returns the handlers to be used when initializing the configtx.Manager
Handlers() map[cb.ConfigItem_ConfigType]Handler
}

type resources struct {
handlers map[cb.ConfigItem_ConfigType]Handler
handlers map[cb.ConfigItem_ConfigType]api.Handler
policyManager policies.Manager
chainConfig chainconfig.Descriptor
mspConfigHandler *mspmgmt.MSPConfigHandler
Expand All @@ -71,12 +49,12 @@ func (r *resources) MSPManager() msp.MSPManager {
}

// Handlers returns the handlers to be used when initializing the configtx.Manager
func (r *resources) Handlers() map[cb.ConfigItem_ConfigType]Handler {
func (r *resources) Handlers() map[cb.ConfigItem_ConfigType]api.Handler {
return r.handlers
}

// NewInitializer creates a chain initializer for the basic set of common chain resources
func NewInitializer() Initializer {
func NewInitializer() api.Initializer {
mspConfigHandler := &mspmgmt.MSPConfigHandler{}
policyProviderMap := make(map[int32]policies.Provider)
for pType := range cb.Policy_PolicyType_name {
Expand All @@ -93,7 +71,7 @@ func NewInitializer() Initializer {

policyManager := policies.NewManagerImpl(policyProviderMap)
chainConfig := chainconfig.NewDescriptorImpl()
handlers := make(map[cb.ConfigItem_ConfigType]Handler)
handlers := make(map[cb.ConfigItem_ConfigType]api.Handler)

for ctype := range cb.ConfigItem_ConfigType_name {
rtype := cb.ConfigItem_ConfigType(ctype)
Expand Down
Loading

0 comments on commit fd536a3

Please sign in to comment.