Skip to content

Commit 5b0c2e4

Browse files
author
Jason Yellick
committed
[FAB-5815] Make resources config immutable
Although very recently introduced, the resources config followed the same mutable model as the channel config. This leads to some awkward looking code with far more lines than are actually needed. This CR converts the resources config to follow the same bundle model that the channel config does. It does not intrduce a bundle source like the channel config because for the moment, the resource config may not be changed. Change-Id: I35614c5f7f6bee3b9ab2848033a1834ef8c76383 Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
1 parent f3600cc commit 5b0c2e4

File tree

4 files changed

+57
-155
lines changed

4 files changed

+57
-155
lines changed

common/config/resources/initializer.go renamed to common/config/resources/bundle.go

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ import (
1010
"fmt"
1111

1212
"github.com/hyperledger/fabric/common/cauthdsl"
13-
newchannelconfig "github.com/hyperledger/fabric/common/channelconfig"
14-
"github.com/hyperledger/fabric/common/config"
1513
"github.com/hyperledger/fabric/common/configtx"
1614
configtxapi "github.com/hyperledger/fabric/common/configtx/api"
15+
"github.com/hyperledger/fabric/common/flogging"
1716
"github.com/hyperledger/fabric/common/policies"
1817
"github.com/hyperledger/fabric/msp"
1918
cb "github.com/hyperledger/fabric/protos/common"
@@ -22,15 +21,25 @@ import (
2221

2322
const RootGroupKey = "Resources"
2423

24+
var logger = flogging.MustGetLogger("common/config/resource")
25+
26+
// PolicyMapper is an interface for
27+
type PolicyMapper interface {
28+
// PolicyRefForResource takes the name of a resource, and returns the policy name for a resource
29+
// or the empty string is the resource is not found
30+
PolicyRefForResource(resourceName string) string
31+
}
32+
2533
type Bundle struct {
26-
vpr *valueProposerRoot
34+
rg *resourceGroup
2735
cm configtxapi.Manager
2836
pm policies.Manager
2937
rpm policies.Manager
3038
}
3139

3240
// New creates a new resources config bundle
3341
// TODO, change interface to take config and not an envelope
42+
// TODO, add an atomic BundleSource
3443
func New(envConfig *cb.Envelope, mspManager msp.MSPManager, channelPolicyManager policies.Manager) (*Bundle, error) {
3544
policyProviderMap := make(map[int32]policies.Provider)
3645
for pType := range cb.Policy_PolicyType_name {
@@ -64,9 +73,14 @@ func New(envConfig *cb.Envelope, mspManager msp.MSPManager, channelPolicyManager
6473
return nil, err
6574
}
6675

76+
resourceGroup, err := newResourceGroup(configEnvelope.Config.ChannelGroup)
77+
if err != nil {
78+
return nil, err
79+
}
80+
6781
b := &Bundle{
68-
vpr: newValueProposerRoot(),
6982
rpm: resourcesPolicyManager,
83+
rg: resourceGroup,
7084
pm: &policyRouter{
7185
channelPolicyManager: channelPolicyManager,
7286
resourcesPolicyManager: resourcesPolicyManager,
@@ -78,26 +92,13 @@ func New(envConfig *cb.Envelope, mspManager msp.MSPManager, channelPolicyManager
7892
return nil, err
7993
}
8094

81-
err = newchannelconfig.InitializeConfigValues(b.vpr, &cb.ConfigGroup{
82-
Groups: map[string]*cb.ConfigGroup{
83-
RootGroupKey: configEnvelope.Config.ChannelGroup,
84-
},
85-
})
86-
if err != nil {
87-
return nil, err
88-
}
89-
9095
return b, nil
9196
}
9297

9398
func (b *Bundle) RootGroupKey() string {
9499
return RootGroupKey
95100
}
96101

97-
func (b *Bundle) ValueProposer() config.ValueProposer {
98-
return b.vpr
99-
}
100-
101102
func (b *Bundle) ConfigtxManager() configtxapi.Manager {
102103
return b.cm
103104
}
@@ -107,5 +108,5 @@ func (b *Bundle) PolicyManager() policies.Manager {
107108
}
108109

109110
func (b *Bundle) ResourcePolicyMapper() PolicyMapper {
110-
return b.vpr
111+
return b.rg
111112
}

common/config/resources/initializer_test.go renamed to common/config/resources/bundle_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ func TestBundleGreenPath(t *testing.T) {
6969

7070
t.Run("Code coverage nits", func(t *testing.T) {
7171
assert.Equal(t, b.RootGroupKey(), RootGroupKey)
72-
assert.NotNil(t, b.ValueProposer())
7372
assert.NotNil(t, b.ConfigtxManager())
7473
assert.NotNil(t, b.PolicyManager())
7574
})

common/config/resources/resources.go

Lines changed: 38 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,83 +7,60 @@ SPDX-License-Identifier: Apache-2.0
77
package resources
88

99
import (
10-
"github.com/hyperledger/fabric/common/config"
10+
"fmt"
11+
12+
cb "github.com/hyperledger/fabric/protos/common"
1113
pb "github.com/hyperledger/fabric/protos/peer"
1214

1315
"github.com/golang/protobuf/proto"
1416
)
1517

1618
// ResourceGroup represents the ConfigGroup at the base of the resource configuration
1719
type resourceGroup struct {
18-
pendingResourceToPolicyRef map[string]string
19-
vpr *valueProposerRoot
20-
}
21-
22-
func newResourceGroup(vpr *valueProposerRoot) *resourceGroup {
23-
return &resourceGroup{
24-
vpr: vpr,
25-
pendingResourceToPolicyRef: make(map[string]string),
26-
}
27-
}
28-
29-
// BeginValueProposals is invoked for each sub-group. These sub-groups are only for defining policies, not other config
30-
// so, an emptyGroup is returned to handle them
31-
func (rg *resourceGroup) BeginValueProposals(tx interface{}, groups []string) (config.ValueDeserializer, []config.ValueProposer, error) {
32-
subGroups := make([]config.ValueProposer, len(groups))
33-
for i := range subGroups {
34-
subGroups[i] = emptyGroup{}
35-
}
36-
return &resourceGroupDeserializer{rg: rg}, subGroups, nil
37-
}
38-
39-
// RollbackConfig a no-op
40-
func (rg *resourceGroup) RollbackProposals(tx interface{}) {}
41-
42-
// PreCommit is a no-op
43-
func (rg *resourceGroup) PreCommit(tx interface{}) error { return nil }
44-
45-
// CommitProposals writes the pendingResourceToPolicyRef map to the resource config root
46-
func (rg *resourceGroup) CommitProposals(tx interface{}) {
47-
rg.vpr.updatePolicyRefForResources(rg.pendingResourceToPolicyRef)
20+
resourcePolicyRefs map[string]string
4821
}
4922

50-
type resourceGroupDeserializer struct {
51-
rg *resourceGroup
23+
func (rg *resourceGroup) PolicyRefForResource(resourceName string) string {
24+
return rg.resourcePolicyRefs[resourceName]
5225
}
5326

54-
// Deserialize unmarshals bytes to a pb.Resource
55-
func (rgd *resourceGroupDeserializer) Deserialize(key string, value []byte) (proto.Message, error) {
56-
resource := &pb.Resource{}
57-
if err := proto.Unmarshal(value, resource); err != nil {
58-
return nil, err
27+
func newResourceGroup(root *cb.ConfigGroup) (*resourceGroup, error) {
28+
resourcePolicyRefs := make(map[string]string)
29+
30+
for key, value := range root.Values {
31+
resource := &pb.Resource{}
32+
if err := proto.Unmarshal(value.Value, resource); err != nil {
33+
return nil, err
34+
}
35+
36+
// If the policy is fully qualified, ie to /Channel/Application/Readers leave it alone
37+
// otherwise, make it fully qualified referring to /Resources/policyName
38+
if '/' != resource.PolicyRef[0] {
39+
resourcePolicyRefs[key] = "/" + RootGroupKey + "/" + resource.PolicyRef
40+
} else {
41+
resourcePolicyRefs[key] = resource.PolicyRef
42+
}
5943
}
6044

61-
// If the policy is fully qualified, ie to /Channel/Application/Readers leave it alone
62-
// otherwise, make it fully qualified referring to /Resources/policyName
63-
if '/' != resource.PolicyRef[0] {
64-
rgd.rg.pendingResourceToPolicyRef[key] = "/" + RootGroupKey + "/" + resource.PolicyRef
65-
} else {
66-
rgd.rg.pendingResourceToPolicyRef[key] = resource.PolicyRef
45+
for _, subGroup := range root.Groups {
46+
if err := verifyNoMoreValues(subGroup); err != nil {
47+
return nil, err
48+
}
6749
}
6850

69-
return resource, nil
51+
return &resourceGroup{
52+
resourcePolicyRefs: resourcePolicyRefs,
53+
}, nil
7054
}
7155

72-
type emptyGroup struct{}
73-
74-
func (eg emptyGroup) BeginValueProposals(tx interface{}, groups []string) (config.ValueDeserializer, []config.ValueProposer, error) {
75-
subGroups := make([]config.ValueProposer, len(groups))
76-
for i := range subGroups {
77-
subGroups[i] = emptyGroup{}
56+
func verifyNoMoreValues(subGroup *cb.ConfigGroup) error {
57+
if len(subGroup.Values) > 0 {
58+
return fmt.Errorf("sub-groups not allowed to have values")
7859
}
79-
return failDeserializer("sub-groups not allowed to have values"), subGroups, nil
60+
for _, subGroup := range subGroup.Groups {
61+
if err := verifyNoMoreValues(subGroup); err != nil {
62+
return err
63+
}
64+
}
65+
return nil
8066
}
81-
82-
// RollbackConfig a no-op
83-
func (eg emptyGroup) RollbackProposals(tx interface{}) {}
84-
85-
// PreCommit is a no-op
86-
func (eg emptyGroup) PreCommit(tx interface{}) error { return nil }
87-
88-
// CommitConfig is a no-op
89-
func (eg emptyGroup) CommitProposals(tx interface{}) {}

common/config/resources/root.go

Lines changed: 0 additions & 75 deletions
This file was deleted.

0 commit comments

Comments
 (0)