Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit 48f4a75

Browse files
sudeshrshettytroyronda
authored andcommitted
[FAB-10279] endpointConfig TLS/network refactoring
- Fixed TLSConfig.Bytes() not to read from disk everytime - Refactored EndpointConfig.TLSClientCerts private key loading to reuse existing util functions - Fixed EndpointConfig.TLSClientCerts threadsafety issues - Removed EntityMatchers from NetworkConfig since there were no apparent reasons to expose them - Removed EndpointConfig.PeerMSPID() from interface since it wasn't being used anywhere - Moved EndpointConfig.MSPID() to comm.MSPID() as a static utility function Change-Id: I7d9139ea47aedccf53084f7207494569c557c920 Signed-off-by: Sudesh Shetty <sudesh.shetty@securekey.com>
1 parent 1a4824e commit 48f4a75

23 files changed

+509
-443
lines changed

pkg/common/providers/fab/network.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ type NetworkConfig struct {
2323
Orderers map[string]OrdererConfig
2424
Peers map[string]PeerConfig
2525
CertificateAuthorities map[string]msp.CAConfig
26-
EntityMatchers map[string][]MatchConfig
2726
}
2827

2928
// ChannelNetworkConfig provides the definition of channels for the network

pkg/common/providers/fab/provider.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ type CommManager interface {
8080
//EndpointConfig contains endpoint network configurations
8181
type EndpointConfig interface {
8282
Timeout(TimeoutType) time.Duration
83-
MSPID(org string) (string, bool)
84-
PeerMSPID(name string) (string, bool)
8583
OrderersConfig() ([]OrdererConfig, bool)
8684
OrdererConfig(nameOrURL string) (*OrdererConfig, bool)
8785
PeersConfig(org string) ([]PeerConfig, bool)

pkg/common/providers/test/mockfab/mockfab.gen.go

Lines changed: 0 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/core/config/endpoint/endpoint.go

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -77,43 +77,40 @@ type TLSConfig struct {
7777
// If Path is available, then it will be used to load the cert
7878
// if Pem is available, then it has the raw data of the cert it will be used as-is
7979
// Certificate root certificate path
80+
// If both Path and Pem are available, pem takes the precedence
8081
Path string
8182
// Certificate actual content
8283
Pem string
84+
//bytes from Pem/Path
85+
bytes []byte
8386
}
8487

85-
// Bytes returns the tls certificate as a byte array by loading it either from the embedded Pem or Path
86-
func (cfg TLSConfig) Bytes() ([]byte, error) {
87-
var bytes []byte
88-
var err error
88+
// Bytes returns the tls certificate as a byte array
89+
func (cfg *TLSConfig) Bytes() []byte {
90+
return cfg.bytes
91+
}
8992

93+
//LoadBytes preloads bytes from Pem/Path
94+
//Pem takes precedence over Path
95+
//TODO to be removed since separate TLSConfig should only be used in parsing
96+
func (cfg *TLSConfig) LoadBytes() error {
97+
var err error
9098
if cfg.Pem != "" {
91-
bytes = []byte(cfg.Pem)
99+
cfg.bytes = []byte(cfg.Pem)
92100
} else if cfg.Path != "" {
93-
bytes, err = ioutil.ReadFile(cfg.Path)
94-
101+
cfg.bytes, err = ioutil.ReadFile(cfg.Path)
95102
if err != nil {
96-
return nil, errors.Wrapf(err, "failed to load pem bytes from path %s", cfg.Path)
103+
return errors.Wrapf(err, "failed to load pem bytes from path %s", cfg.Path)
97104
}
98105
}
99-
100-
return bytes, nil
106+
return nil
101107
}
102108

103109
// TLSCert returns the tls certificate as a *x509.Certificate by loading it either from the embedded Pem or Path
104-
func (cfg TLSConfig) TLSCert() (*x509.Certificate, error) {
105-
bytes, err := cfg.Bytes()
106-
107-
if err != nil {
108-
return nil, err
109-
}
110-
111-
return loadCert(bytes)
112-
}
110+
//TODO to be removed since separate TLSConfig should only be used in parsing
111+
func (cfg *TLSConfig) TLSCert() (*x509.Certificate, error) {
113112

114-
// loadCAKey
115-
func loadCert(rawData []byte) (*x509.Certificate, error) {
116-
block, _ := pem.Decode(rawData)
113+
block, _ := pem.Decode(cfg.bytes)
117114

118115
if block != nil {
119116
pub, err := x509.ParseCertificate(block.Bytes)

pkg/core/config/endpoint/endpoint_test.go

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ package endpoint
99
import (
1010
"strings"
1111
"testing"
12+
13+
"github.com/stretchr/testify/assert"
1214
)
1315

1416
func TestIsTLSEnabled(t *testing.T) {
@@ -105,10 +107,11 @@ O94CDp7l2k7hMQI0zQ==
105107
Pem: pPem,
106108
}
107109

108-
b, e := tlsConfig.Bytes()
110+
e := tlsConfig.LoadBytes()
109111
if e != nil {
110112
t.Fatalf("error loading bytes for sample cert %s", e)
111113
}
114+
b := tlsConfig.Bytes()
112115
if len(b) == 0 {
113116
t.Fatalf("cert's Bytes() call returned empty byte array")
114117
}
@@ -118,20 +121,23 @@ O94CDp7l2k7hMQI0zQ==
118121

119122
// test with empty pem
120123
tlsConfig.Pem = ""
121-
b, e = tlsConfig.Bytes()
124+
tlsConfig.Path = "../testdata/config_test.yaml"
125+
e = tlsConfig.LoadBytes()
122126
if e != nil {
123127
t.Fatalf("error loading bytes for empty pem cert %s", e)
124128
}
125-
if len(b) > 0 {
126-
t.Fatalf("cert's Bytes() call returned non empty byte array for empty pem")
129+
b = tlsConfig.Bytes()
130+
if len(b) == 0 {
131+
t.Fatalf("cert's Bytes() call returned empty byte array")
127132
}
128133

129134
// test with wrong pem
130135
tlsConfig.Pem = "wrongpemvalue"
131-
b, e = tlsConfig.Bytes()
136+
e = tlsConfig.LoadBytes()
132137
if e != nil {
133138
t.Fatalf("error loading bytes for wrong pem cert %s", e)
134139
}
140+
b = tlsConfig.Bytes()
135141
if len(b) != len([]byte("wrongpemvalue")) {
136142
t.Fatalf("cert's Bytes() call returned different byte array for wrong pem")
137143
}
@@ -143,6 +149,11 @@ func TestTLSConfig_TLSCertPostive(t *testing.T) {
143149
Pem: "",
144150
}
145151

152+
e := tlsConfig.LoadBytes()
153+
if e != nil {
154+
t.Fatalf("error loading certificate for sample cert path %s", e)
155+
}
156+
146157
c, e := tlsConfig.TLSCert()
147158
if e != nil {
148159
t.Fatalf("error loading certificate for sample cert path %s", e)
@@ -215,3 +226,35 @@ func TestTLSConfig_TLSCertNegative(t *testing.T) {
215226
}
216227

217228
}
229+
230+
func TestTLSConfigBytes(t *testing.T) {
231+
232+
// test with wrong path
233+
tlsConfig := &TLSConfig{
234+
Path: "../testdata/config_test.yaml",
235+
Pem: "",
236+
}
237+
238+
err := tlsConfig.LoadBytes()
239+
bytes1 := tlsConfig.Bytes()
240+
assert.Nil(t, err, "tlsConfig.Bytes supposed to succeed")
241+
assert.NotEmpty(t, bytes1, "supposed to get valid bytes")
242+
243+
tlsConfig.Path = "../testdata/config_test_pem.yaml"
244+
bytes2 := tlsConfig.Bytes()
245+
assert.Nil(t, err, "tlsConfig.Bytes supposed to succeed")
246+
assert.NotEmpty(t, bytes2, "supposed to get valid bytes")
247+
248+
//even after changing path, it should return previous bytes
249+
assert.Equal(t, bytes1, bytes2, "any update to tlsconfig path after load bytes call should not take effect")
250+
251+
//call preload now
252+
err = tlsConfig.LoadBytes()
253+
bytes2 = tlsConfig.Bytes()
254+
assert.Nil(t, err, "tlsConfig.Bytes supposed to succeed")
255+
assert.NotEmpty(t, bytes2, "supposed to get valid bytes")
256+
257+
//even after changing path, it should return previous bytes
258+
assert.NotEqual(t, bytes1, bytes2, "tlsConfig.LoadBytes() should refresh bytes")
259+
260+
}

pkg/core/config/lookup/lookup_test.go

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ const orgChannelID = "orgchannel"
3131

3232
var backend *mocks.MockConfigBackend
3333

34+
type testEntityMatchers struct {
35+
matchers map[string][]fab.MatchConfig
36+
}
37+
3438
func TestMain(m *testing.M) {
3539
backend = setupCustomBackend("key")
3640
r := m.Run()
@@ -227,10 +231,12 @@ func TestUnmarshalWithMultipleBackend(t *testing.T) {
227231

228232
//output struct
229233
networkConfig := fab.NetworkConfig{}
234+
entityMatchers := testEntityMatchers{}
235+
230236
assert.Nil(t, testLookup.UnmarshalKey("client", &networkConfig.Client), "unmarshalKey supposed to succeed")
231237
assert.Nil(t, testLookup.UnmarshalKey("channels", &networkConfig.Channels), "unmarshalKey supposed to succeed")
232238
assert.Nil(t, testLookup.UnmarshalKey("certificateAuthorities", &networkConfig.CertificateAuthorities), "unmarshalKey supposed to succeed")
233-
assert.Nil(t, testLookup.UnmarshalKey("entityMatchers", &networkConfig.EntityMatchers), "unmarshalKey supposed to succeed")
239+
assert.Nil(t, testLookup.UnmarshalKey("entityMatchers", &entityMatchers.matchers), "unmarshalKey supposed to succeed")
234240
assert.Nil(t, testLookup.UnmarshalKey("organizations", &networkConfig.Organizations), "unmarshalKey supposed to succeed")
235241
assert.Nil(t, testLookup.UnmarshalKey("orderers", &networkConfig.Orderers), "unmarshalKey supposed to succeed")
236242
assert.Nil(t, testLookup.UnmarshalKey("peers", &networkConfig.Peers), "unmarshalKey supposed to succeed")
@@ -253,15 +259,15 @@ func TestUnmarshalWithMultipleBackend(t *testing.T) {
253259
assert.Equal(t, networkConfig.CertificateAuthorities["local.ca.org2.example.com"].URL, "https://ca.org2.example.com:8054")
254260

255261
//EntityMatchers
256-
assert.Equal(t, len(networkConfig.EntityMatchers), 4)
257-
assert.Equal(t, len(networkConfig.EntityMatchers["peer"]), 8)
258-
assert.Equal(t, networkConfig.EntityMatchers["peer"][0].MappedHost, "local.peer0.org1.example.com")
259-
assert.Equal(t, len(networkConfig.EntityMatchers["orderer"]), 4)
260-
assert.Equal(t, networkConfig.EntityMatchers["orderer"][0].MappedHost, "local.orderer.example.com")
261-
assert.Equal(t, len(networkConfig.EntityMatchers["certificateauthority"]), 2)
262-
assert.Equal(t, networkConfig.EntityMatchers["certificateauthority"][0].MappedHost, "local.ca.org1.example.com")
263-
assert.Equal(t, len(networkConfig.EntityMatchers["channel"]), 1)
264-
assert.Equal(t, networkConfig.EntityMatchers["channel"][0].MappedName, "ch1")
262+
assert.Equal(t, len(entityMatchers.matchers), 4)
263+
assert.Equal(t, len(entityMatchers.matchers["peer"]), 8)
264+
assert.Equal(t, entityMatchers.matchers["peer"][0].MappedHost, "local.peer0.org1.example.com")
265+
assert.Equal(t, len(entityMatchers.matchers["orderer"]), 4)
266+
assert.Equal(t, entityMatchers.matchers["orderer"][0].MappedHost, "local.orderer.example.com")
267+
assert.Equal(t, len(entityMatchers.matchers["certificateauthority"]), 2)
268+
assert.Equal(t, entityMatchers.matchers["certificateauthority"][0].MappedHost, "local.ca.org1.example.com")
269+
assert.Equal(t, len(entityMatchers.matchers["channel"]), 1)
270+
assert.Equal(t, entityMatchers.matchers["channel"][0].MappedName, "ch1")
265271

266272
//Organizations
267273
assert.Equal(t, len(networkConfig.Organizations), 3)
@@ -331,15 +337,17 @@ func TestLookupUnmarshalAgainstViperUnmarshal(t *testing.T) {
331337
/*
332338
TEST NETWORK CONFIG ENTITY MATCHERS
333339
*/
340+
entityMatchers := testEntityMatchers{}
334341
//get entityMatchers backend lookup
335-
err = testLookup.UnmarshalKey("entityMatchers", &networkConfig.EntityMatchers)
342+
err = testLookup.UnmarshalKey("entityMatchers", &entityMatchers.matchers)
336343
if err != nil {
337344
t.Fatal(err)
338345
}
339346
//get entityMatchers from viper
340-
sampleViper.UnmarshalKey("entityMatchers", &networkConfigViper.EntityMatchers)
347+
viperEntityMatchers := testEntityMatchers{}
348+
sampleViper.UnmarshalKey("entityMatchers", &viperEntityMatchers.matchers)
341349
//now compare
342-
assert.True(t, reflect.DeepEqual(&networkConfig.EntityMatchers, &networkConfigViper.EntityMatchers), "unmarshalled value from config lookup supposed to match unmarshalled value from viper")
350+
assert.True(t, reflect.DeepEqual(&entityMatchers, &viperEntityMatchers), "unmarshalled value from config lookup supposed to match unmarshalled value from viper")
343351

344352
/*
345353
TEST NETWORK CONFIG ORGANIZATIONS
@@ -382,10 +390,10 @@ func TestLookupUnmarshalAgainstViperUnmarshal(t *testing.T) {
382390

383391
//Just to make sure that empty values are not being compared
384392
assert.True(t, len(networkConfigViper.Channels) > 0, "expected to get valid unmarshalled value")
385-
assert.True(t, len(networkConfigViper.Organizations) > 0, "expected to get valid unmarshalled value")
393+
assert.True(t, len(viperEntityMatchers.matchers) > 0, "expected to get valid unmarshalled value")
386394
assert.True(t, len(networkConfigViper.Orderers) > 0, "expected to get valid unmarshalled value")
387395
assert.True(t, len(networkConfigViper.Peers) > 0, "expected to get valid unmarshalled value")
388-
assert.True(t, len(networkConfigViper.EntityMatchers) > 0, "expected to get valid unmarshalled value")
396+
assert.True(t, len(entityMatchers.matchers) > 0, "expected to get valid unmarshalled value")
389397
assert.True(t, networkConfigViper.Client.Organization != "", "expected to get valid unmarshalled value")
390398

391399
}

pkg/core/config/testdata/config_test.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,4 +330,5 @@ certificateAuthorities:
330330
enrollId: admin
331331
enrollSecret: adminpw
332332
# [Optional] The optional name of the CA.
333-
caName: ca.org2.example.com
333+
caName: ca.org2.example.com
334+
#first one

pkg/core/config/testdata/config_test_pem.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,3 +382,4 @@ certificateAuthorities:
382382
enrollSecret: adminpw
383383
# [Optional] The optional name of the CA.
384384
caName: ca.org2.example.com
385+
#second one

pkg/fab/comm/network.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ SPDX-License-Identifier: Apache-2.0
77
package comm
88

99
import (
10+
"strings"
11+
1012
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
1113
"github.com/pkg/errors"
1214
)
@@ -63,3 +65,18 @@ func SearchPeerConfigFromURL(cfg fab.EndpointConfig, url string) (*fab.PeerConfi
6365

6466
return nil, errors.Errorf("unable to get peerconfig for given url : %s", url)
6567
}
68+
69+
// MSPID returns the MSP ID for the requested organization
70+
func MSPID(cfg fab.EndpointConfig, org string) (string, bool) {
71+
networkConfig, ok := cfg.NetworkConfig()
72+
if !ok {
73+
return "", false
74+
}
75+
// viper lowercases all key maps, org is lower case
76+
mspID := networkConfig.Organizations[strings.ToLower(org)].MSPID
77+
if mspID == "" {
78+
return "", false
79+
}
80+
81+
return mspID, true
82+
}

pkg/fab/comm/network_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,24 @@ func TestSearchPeerConfigFromURL(t *testing.T) {
8888
assert.Equal(t, peer0Org1.EventURL, peerConfig.EventURL)
8989

9090
}
91+
92+
func TestMSPID(t *testing.T) {
93+
configBackend, err := config.FromFile(configTestFilePath)()
94+
if err != nil {
95+
t.Fatalf("Unexpected error reading config backend: %v", err)
96+
}
97+
98+
sampleConfig, err := fabImpl.ConfigFromBackend(configBackend...)
99+
if err != nil {
100+
t.Fatalf("Unexpected error reading config: %v", err)
101+
}
102+
103+
mspID, ok := MSPID(sampleConfig, "invalid")
104+
assert.False(t, ok, "supposed to fail for invalid org name")
105+
assert.Empty(t, mspID, "supposed to get valid MSP ID")
106+
107+
mspID, ok = MSPID(sampleConfig, "org1")
108+
assert.True(t, ok, "supposed to pass with valid org name")
109+
assert.NotEmpty(t, mspID, "supposed to get valid MSP ID")
110+
assert.Equal(t, "Org1MSP", mspID, "supposed to get valid MSP ID")
111+
}

0 commit comments

Comments
 (0)