diff --git a/common/configvalues/root/application.go b/common/configvalues/root/application.go index 711a4da59f8..d312494212e 100644 --- a/common/configvalues/root/application.go +++ b/common/configvalues/root/application.go @@ -53,10 +53,10 @@ func NewApplicationGroup(mspConfig *msp.MSPConfigHandler) *ApplicationGroup { } func (ag *ApplicationGroup) NewGroup(name string) (api.ValueProposer, error) { - return NewApplicationOrgConfig(name, ag.mspConfig), nil + return NewApplicationOrgGroup(name, ag.mspConfig), nil } -// Allocate returns the +// Allocate returns a new instance of the ApplicationConfig func (ag *ApplicationGroup) Allocate() Values { return NewApplicationConfig(ag) } @@ -79,7 +79,7 @@ func (ac *ApplicationConfig) Validate(groups map[string]api.ValueProposer) error ac.applicationOrgs = make(map[string]api.ApplicationOrg) var ok bool for key, value := range groups { - ac.applicationOrgs[key], ok = value.(*ApplicationOrgConfig) + ac.applicationOrgs[key], ok = value.(*ApplicationOrgGroup) if !ok { return fmt.Errorf("Application sub-group %s was not an ApplicationOrgGroup, actually %T", key, value) } diff --git a/common/configvalues/root/applicationorg.go b/common/configvalues/root/applicationorg.go index 1560af24e76..6e573a8b3ac 100644 --- a/common/configvalues/root/applicationorg.go +++ b/common/configvalues/root/applicationorg.go @@ -17,14 +17,10 @@ limitations under the License. package config import ( - "fmt" - api "github.com/hyperledger/fabric/common/configvalues" mspconfig "github.com/hyperledger/fabric/common/configvalues/msp" - cb "github.com/hyperledger/fabric/protos/common" pb "github.com/hyperledger/fabric/protos/peer" - "github.com/golang/protobuf/proto" logging "github.com/op/go-logging" ) @@ -34,82 +30,66 @@ const ( AnchorPeersKey = "AnchorPeers" ) -type applicationOrgConfig struct { - anchorPeers []*pb.AnchorPeer +type ApplicationOrgProtos struct { + AnchorPeers *pb.AnchorPeers } -// SharedConfigImpl is an implementation of Manager and configtx.ConfigHandler -// In general, it should only be referenced as an Impl for the configtx.Manager type ApplicationOrgConfig struct { - *OrganizationGroup - pendingConfig *applicationOrgConfig - config *applicationOrgConfig + *OrganizationConfig + protos *ApplicationOrgProtos + + applicationOrgGroup *ApplicationOrgGroup +} - mspConfig *mspconfig.MSPConfigHandler +// ApplicationOrgGroup defines the configuration for an application org +type ApplicationOrgGroup struct { + *Proposer + *OrganizationGroup + *ApplicationOrgConfig } -// NewSharedConfigImpl creates a new SharedConfigImpl with the given CryptoHelper -func NewApplicationOrgConfig(id string, mspConfig *mspconfig.MSPConfigHandler) *ApplicationOrgConfig { - return &ApplicationOrgConfig{ +// NewApplicationOrgGroup creates a new ApplicationOrgGroup +func NewApplicationOrgGroup(id string, mspConfig *mspconfig.MSPConfigHandler) *ApplicationOrgGroup { + aog := &ApplicationOrgGroup{ OrganizationGroup: NewOrganizationGroup(id, mspConfig), - config: &applicationOrgConfig{}, } + aog.Proposer = NewProposer(aog) + return aog } // AnchorPeers returns the list of valid orderer addresses to connect to to invoke Broadcast/Deliver -func (oc *ApplicationOrgConfig) AnchorPeers() []*pb.AnchorPeer { - return oc.config.anchorPeers +func (aog *ApplicationOrgConfig) AnchorPeers() []*pb.AnchorPeer { + return aog.protos.AnchorPeers.AnchorPeers } -// BeginValueProposals is used to start a new config proposal -func (oc *ApplicationOrgConfig) BeginValueProposals(groups []string) ([]api.ValueProposer, error) { - logger.Debugf("Beginning a possible new org config") - if len(groups) != 0 { - return nil, fmt.Errorf("ApplicationGroup does not support subgroups") - } - if oc.pendingConfig != nil { - logger.Panicf("Programming error, cannot call begin in the middle of a proposal") - } - oc.pendingConfig = &applicationOrgConfig{} - return oc.OrganizationGroup.BeginValueProposals(groups) +func (aog *ApplicationOrgGroup) Allocate() Values { + return NewApplicationOrgConfig(aog) } -// RollbackProposals is used to abandon a new config proposal -func (oc *ApplicationOrgConfig) RollbackProposals() { - logger.Debugf("Rolling back proposed org config") - oc.pendingConfig = nil - oc.OrganizationGroup.RollbackProposals() +func (aoc *ApplicationOrgConfig) Commit() { + aoc.applicationOrgGroup.ApplicationOrgConfig = aoc + aoc.OrganizationConfig.Commit() } -// CommitProposals is used to commit a new config proposal -func (oc *ApplicationOrgConfig) CommitProposals() { - logger.Debugf("Committing new org config") - if oc.pendingConfig == nil { - logger.Panicf("Programming error, cannot call commit without an existing proposal") - } - oc.config = oc.pendingConfig - oc.pendingConfig = nil - oc.OrganizationGroup.CommitProposals() -} +func NewApplicationOrgConfig(aog *ApplicationOrgGroup) *ApplicationOrgConfig { + aoc := &ApplicationOrgConfig{ + protos: &ApplicationOrgProtos{}, + OrganizationConfig: NewOrganizationConfig(aog.OrganizationGroup), -// ProposeValue is used to add new config to the config proposal -func (oc *ApplicationOrgConfig) ProposeValue(key string, configValue *cb.ConfigValue) error { - switch key { - case AnchorPeersKey: - anchorPeers := &pb.AnchorPeers{} - if err := proto.Unmarshal(configValue.Value, anchorPeers); err != nil { - return fmt.Errorf("Unmarshaling error for %s: %s", key, err) - } - if logger.IsEnabledFor(logging.DEBUG) { - logger.Debugf("Setting %s to %v", key, anchorPeers.AnchorPeers) - } - oc.pendingConfig.anchorPeers = anchorPeers.AnchorPeers - default: - return oc.OrganizationGroup.ProposeValue(key, configValue) + applicationOrgGroup: aog, + } + var err error + aoc.standardValues, err = NewStandardValues(aoc.protos, aoc.OrganizationConfig.protos) + if err != nil { + logger.Panicf("Programming error: %s", err) } - return nil + return aoc } -// PreCommit returns nil -func (c *ApplicationOrgConfig) PreCommit() error { return nil } +func (aoc *ApplicationOrgConfig) Validate(groups map[string]api.ValueProposer) error { + if logger.IsEnabledFor(logging.DEBUG) { + logger.Debugf("Anchor peers for org %s are %v", aoc.applicationOrgGroup.name, aoc.protos.AnchorPeers) + } + return aoc.OrganizationConfig.Validate(groups) +} diff --git a/common/configvalues/root/applicationorg_test.go b/common/configvalues/root/applicationorg_test.go index c715263cbf6..c95947fd5eb 100644 --- a/common/configvalues/root/applicationorg_test.go +++ b/common/configvalues/root/applicationorg_test.go @@ -20,67 +20,8 @@ import ( "testing" api "github.com/hyperledger/fabric/common/configvalues" - cb "github.com/hyperledger/fabric/protos/common" - pb "github.com/hyperledger/fabric/protos/peer" - - logging "github.com/op/go-logging" - "github.com/stretchr/testify/assert" ) -func init() { - logging.SetLevel(logging.DEBUG, "") -} - -func makeInvalidConfigValue() *cb.ConfigValue { - return &cb.ConfigValue{ - Value: []byte("Garbage Data"), - } -} - -func groupToKeyValue(configGroup *cb.ConfigGroup) (string, *cb.ConfigValue) { - for _, group := range configGroup.Groups[ApplicationGroupKey].Groups { - for key, value := range group.Values { - return key, value - } - } - panic("No value encoded") -} - func TestApplicationOrgInterface(t *testing.T) { - _ = api.ValueProposer(NewApplicationOrgConfig("id", nil)) -} - -func TestApplicationOrgDoubleBegin(t *testing.T) { - m := NewApplicationOrgConfig("id", nil) - m.BeginValueProposals(nil) - assert.Panics(t, func() { m.BeginValueProposals(nil) }, "Two begins back to back should have caused a panic") -} - -func TestApplicationOrgCommitWithoutBegin(t *testing.T) { - m := NewApplicationOrgConfig("id", nil) - assert.Panics(t, m.CommitProposals, "Committing without beginning should have caused a panic") -} - -func TestApplicationOrgRollback(t *testing.T) { - m := NewApplicationOrgConfig("id", nil) - m.pendingConfig = &applicationOrgConfig{} - m.RollbackProposals() - assert.Nil(t, m.pendingConfig, "Should have cleared pending config on rollback") -} - -func TestApplicationOrgAnchorPeers(t *testing.T) { - endVal := []*pb.AnchorPeer{ - &pb.AnchorPeer{Host: "foo", Port: 234}, - &pb.AnchorPeer{Host: "bar", Port: 237}, - } - invalidMessage := makeInvalidConfigValue() - validMessage := TemplateAnchorPeers("id", endVal) - m := NewApplicationOrgConfig("id", nil) - m.BeginValueProposals(nil) - - assert.Error(t, m.ProposeValue(AnchorPeersKey, invalidMessage), "Should have failed on invalid message") - assert.NoError(t, m.ProposeValue(groupToKeyValue(validMessage)), "Should not have failed on invalid message") - m.CommitProposals() - - assert.Equal(t, m.AnchorPeers(), endVal, "Did not set updated anchor peers") + _ = api.ValueProposer(NewApplicationOrgGroup("id", nil)) } diff --git a/common/configvalues/root/standardvalues.go b/common/configvalues/root/standardvalues.go index 486321206fa..21b0c8fc6c7 100644 --- a/common/configvalues/root/standardvalues.go +++ b/common/configvalues/root/standardvalues.go @@ -38,6 +38,7 @@ func NewStandardValues(protosStructs ...interface{}) (*standardValues, error) { } for _, protosStruct := range protosStructs { + logger.Debugf("Initializing protos for %T\n", protosStruct) if err := sv.initializeProtosStruct(reflect.ValueOf(protosStruct)); err != nil { return nil, err } @@ -63,7 +64,7 @@ func (sv *standardValues) initializeProtosStruct(objValue reflect.Value) error { numFields := objValue.Elem().NumField() for i := 0; i < numFields; i++ { structField := objType.Elem().Field(i) - fmt.Printf("Processing field: %s\n", structField.Name) + logger.Debugf("Processing field: %s\n", structField.Name) switch structField.Type.Kind() { case reflect.Ptr: fieldPtr := objValue.Elem().Field(i)