Skip to content

Commit e99311d

Browse files
author
Jason Yellick
committed
[FAB-2225] Create organization config handler
https://jira.hyperledger.org/browse/FAB-2225 In order to support organization scoped config (ie AnchorPeers), it's necessary to introduce the notion of organization config. This CR only introduces the notion of the organization handler. Change-Id: I4637f114f36a458fcba82b01b7756d3e4d64da20 Signed-off-by: Jason Yellick <[email protected]>
1 parent 02322a1 commit e99311d

File tree

6 files changed

+203
-10
lines changed

6 files changed

+203
-10
lines changed

common/configtx/handlers/application/sharedconfig.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"fmt"
2121

2222
"github.com/hyperledger/fabric/common/configtx/api"
23+
"github.com/hyperledger/fabric/common/configtx/handlers"
2324
"github.com/hyperledger/fabric/common/configtx/handlers/msp"
2425
cb "github.com/hyperledger/fabric/protos/common"
2526
pb "github.com/hyperledger/fabric/protos/peer"
@@ -65,6 +66,7 @@ var logger = logging.MustGetLogger("peer/sharedconfig")
6566

6667
type sharedConfig struct {
6768
anchorPeers []*pb.AnchorPeer
69+
orgs map[string]*handlers.OrgConfig
6870
}
6971

7072
// SharedConfigImpl is an implementation of Manager and configtx.ConfigHandler
@@ -95,7 +97,9 @@ func (di *SharedConfigImpl) BeginConfig() {
9597
if di.pendingConfig != nil {
9698
logger.Panicf("Programming error, cannot call begin in the middle of a proposal")
9799
}
98-
di.pendingConfig = &sharedConfig{}
100+
di.pendingConfig = &sharedConfig{
101+
orgs: make(map[string]*handlers.OrgConfig),
102+
}
99103
}
100104

101105
// RollbackConfig is used to abandon a new config proposal
@@ -142,5 +146,10 @@ func (pm *SharedConfigImpl) Handler(path []string) (api.Handler, error) {
142146
return nil, fmt.Errorf("Application group allows only one further level of nesting")
143147
}
144148

145-
return pm.mspConfig.Handler(path[1:])
149+
org, ok := pm.pendingConfig.orgs[path[0]]
150+
if !ok {
151+
org = handlers.NewOrgConfig(path[0], pm.mspConfig)
152+
pm.pendingConfig.orgs[path[0]] = org
153+
}
154+
return org, nil
146155
}

common/configtx/handlers/orderer/sharedconfig.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"time"
2525

2626
"github.com/hyperledger/fabric/common/configtx/api"
27+
"github.com/hyperledger/fabric/common/configtx/handlers"
2728
"github.com/hyperledger/fabric/common/configtx/handlers/msp"
2829
cb "github.com/hyperledger/fabric/protos/common"
2930
ab "github.com/hyperledger/fabric/protos/orderer"
@@ -98,6 +99,7 @@ type ordererConfig struct {
9899
kafkaBrokers []string
99100
ingressPolicyNames []string
100101
egressPolicyNames []string
102+
orgs map[string]*handlers.OrgConfig
101103
}
102104

103105
// ManagerImpl is an implementation of configtxapi.OrdererConfig and configtxapi.Handler
@@ -160,7 +162,9 @@ func (pm *ManagerImpl) BeginConfig() {
160162
if pm.pendingConfig != nil {
161163
logger.Fatalf("Programming error, cannot call begin in the middle of a proposal")
162164
}
163-
pm.pendingConfig = &ordererConfig{}
165+
pm.pendingConfig = &ordererConfig{
166+
orgs: make(map[string]*handlers.OrgConfig),
167+
}
164168
}
165169

166170
// RollbackConfig is used to abandon a new config proposal
@@ -281,7 +285,12 @@ func (pm *ManagerImpl) Handler(path []string) (api.Handler, error) {
281285
return nil, fmt.Errorf("Orderer group allows only one further level of nesting")
282286
}
283287

284-
return pm.mspConfig.Handler(path[1:])
288+
org, ok := pm.pendingConfig.orgs[path[0]]
289+
if !ok {
290+
org = handlers.NewOrgConfig(path[0], pm.mspConfig)
291+
pm.pendingConfig.orgs[path[0]] = org
292+
}
293+
return org, nil
285294
}
286295

287296
// This does just a barebones sanity check.
+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
Copyright IBM Corp. 2017 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package handlers
18+
19+
import (
20+
"fmt"
21+
22+
"github.com/hyperledger/fabric/common/configtx/api"
23+
mspconfig "github.com/hyperledger/fabric/common/configtx/handlers/msp"
24+
"github.com/hyperledger/fabric/msp"
25+
cb "github.com/hyperledger/fabric/protos/common"
26+
27+
"github.com/op/go-logging"
28+
)
29+
30+
// Org config keys
31+
const (
32+
// MSPKey is value key for marshaled *mspconfig.MSPConfig
33+
MSPKey = "MSP"
34+
)
35+
36+
var logger = logging.MustGetLogger("common/configtx/handlers")
37+
38+
type orgConfig struct {
39+
msp msp.MSP
40+
}
41+
42+
// SharedConfigImpl is an implementation of Manager and configtx.ConfigHandler
43+
// In general, it should only be referenced as an Impl for the configtx.Manager
44+
type OrgConfig struct {
45+
id string
46+
pendingConfig *orgConfig
47+
config *orgConfig
48+
49+
mspConfig *mspconfig.MSPConfigHandler
50+
}
51+
52+
// NewSharedConfigImpl creates a new SharedConfigImpl with the given CryptoHelper
53+
func NewOrgConfig(id string, mspConfig *mspconfig.MSPConfigHandler) *OrgConfig {
54+
return &OrgConfig{
55+
id: id,
56+
config: &orgConfig{},
57+
mspConfig: mspConfig,
58+
}
59+
}
60+
61+
// BeginConfig is used to start a new config proposal
62+
func (oc *OrgConfig) BeginConfig() {
63+
logger.Debugf("Beginning a possible new org config")
64+
if oc.pendingConfig != nil {
65+
logger.Panicf("Programming error, cannot call begin in the middle of a proposal")
66+
}
67+
oc.pendingConfig = &orgConfig{}
68+
}
69+
70+
// RollbackConfig is used to abandon a new config proposal
71+
func (oc *OrgConfig) RollbackConfig() {
72+
logger.Debugf("Rolling back proposed org config")
73+
oc.pendingConfig = nil
74+
}
75+
76+
// CommitConfig is used to commit a new config proposal
77+
func (oc *OrgConfig) CommitConfig() {
78+
logger.Debugf("Committing new org config")
79+
if oc.pendingConfig == nil {
80+
logger.Panicf("Programming error, cannot call commit without an existing proposal")
81+
}
82+
oc.config = oc.pendingConfig
83+
oc.pendingConfig = nil
84+
}
85+
86+
// ProposeConfig is used to add new config to the config proposal
87+
func (oc *OrgConfig) ProposeConfig(key string, configValue *cb.ConfigValue) error {
88+
switch key {
89+
case MSPKey:
90+
logger.Debugf("Initializing org MSP for id %s", oc.id)
91+
return oc.mspConfig.ProposeConfig(key, configValue)
92+
default:
93+
logger.Warningf("Uknown org config item with key %s", key)
94+
}
95+
return nil
96+
}
97+
98+
// Handler returns the associated api.Handler for the given path
99+
func (oc *OrgConfig) Handler(path []string) (api.Handler, error) {
100+
if len(path) == 0 {
101+
return oc, nil
102+
}
103+
104+
return nil, fmt.Errorf("Organizations do not further nesting")
105+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
Copyright IBM Corp. 2017 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package handlers
18+
19+
import (
20+
"testing"
21+
22+
configtxapi "github.com/hyperledger/fabric/common/configtx/api"
23+
24+
logging "github.com/op/go-logging"
25+
)
26+
27+
func init() {
28+
logging.SetLevel(logging.DEBUG, "")
29+
}
30+
31+
func TestInterface(t *testing.T) {
32+
_ = configtxapi.SubInitializer(NewOrgConfig("id", nil))
33+
}
34+
35+
func TestDoubleBegin(t *testing.T) {
36+
defer func() {
37+
if err := recover(); err == nil {
38+
t.Fatalf("Should have panicked on multiple begin configs")
39+
}
40+
}()
41+
42+
m := NewOrgConfig("id", nil)
43+
m.BeginConfig()
44+
m.BeginConfig()
45+
}
46+
47+
func TestCommitWithoutBegin(t *testing.T) {
48+
defer func() {
49+
if err := recover(); err == nil {
50+
t.Fatalf("Should have panicked on multiple begin configs")
51+
}
52+
}()
53+
54+
m := NewOrgConfig("id", nil)
55+
m.CommitConfig()
56+
}
57+
58+
func TestRollback(t *testing.T) {
59+
m := NewOrgConfig("id", nil)
60+
m.pendingConfig = &orgConfig{}
61+
m.RollbackConfig()
62+
if m.pendingConfig != nil {
63+
t.Fatalf("Should have cleared pending config on rollback")
64+
}
65+
}

common/configtx/test/helper.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/hyperledger/fabric/common/configtx"
2424
configtxapplication "github.com/hyperledger/fabric/common/configtx/handlers/application"
2525
configtxmsp "github.com/hyperledger/fabric/common/configtx/handlers/msp"
26+
configtxorderer "github.com/hyperledger/fabric/common/configtx/handlers/orderer"
2627
genesisconfig "github.com/hyperledger/fabric/common/configtx/tool/localconfig"
2728
"github.com/hyperledger/fabric/common/configtx/tool/provisional"
2829
"github.com/hyperledger/fabric/common/genesis"
@@ -86,11 +87,13 @@ func OrdererTemplate() configtx.Template {
8687

8788
// MSPTemplate returns the test MSP template
8889
func MSPTemplate() configtx.Template {
89-
mspConf, err := msp.GetLocalMspConfig(sampleMSPPath, "SAMPLE")
90+
const sampleID = "SAMPLE"
91+
mspConf, err := msp.GetLocalMspConfig(sampleMSPPath, sampleID)
9092
if err != nil {
9193
logger.Panicf("Could not load sample MSP config: %s", err)
9294
}
93-
return configtx.NewSimpleTemplate(configtxmsp.TemplateGroupMSP([]string{configtxapplication.GroupKey}, mspConf))
95+
return configtx.NewSimpleTemplate(configtxmsp.TemplateGroupMSP([]string{configtxapplication.GroupKey, sampleID}, mspConf),
96+
configtxmsp.TemplateGroupMSP([]string{configtxorderer.GroupKey, sampleID}, mspConf))
9497
}
9598

9699
// ApplicationTemplate returns the test application template

orderer/sample_clients/broadcast_config/newchain.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@ package main
1818

1919
import (
2020
"github.com/hyperledger/fabric/common/configtx"
21-
"github.com/hyperledger/fabric/common/configtx/tool/provisional"
21+
configtxtest "github.com/hyperledger/fabric/common/configtx/test"
22+
//"github.com/hyperledger/fabric/common/configtx/tool/provisional"
2223
"github.com/hyperledger/fabric/msp"
2324
cb "github.com/hyperledger/fabric/protos/common"
2425
)
2526

2627
func newChainRequest(consensusType, creationPolicy, newChannelId string) *cb.Envelope {
27-
genConf.Orderer.OrdererType = consensusType
28-
generator := provisional.New(genConf)
29-
channelTemplate := generator.ChannelTemplate()
28+
//genConf.Orderer.OrdererType = consensusType
29+
//generator := provisional.New(genConf)
30+
//channelTemplate := generator.ChannelTemplate()
31+
channelTemplate := configtxtest.CompositeTemplate()
3032

3133
signer, err := msp.NewNoopMsp().GetDefaultSigningIdentity()
3234
if err != nil {

0 commit comments

Comments
 (0)