-
Notifications
You must be signed in to change notification settings - Fork 8.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This change-set introduces support for multiple BCCSP factories. This way, it will be possible to have software-based as well as hardware-based BCCSP implementations. The fatory provides also access to a default BCCSP that represents the BCCSP to be used by default as it is configured via viper. Tests have been added to test the factories. This change-set comes in the context of: https://jira.hyperledger.org/browse/FAB-354 Change-Id: Ib83f1fc31fa0ac77daa76f97684563e4c6e53877 Signed-off-by: Angelo De Caro <[email protected]>
- Loading branch information
Showing
4 changed files
with
298 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/* | ||
Copyright IBM Corp. 2016 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 factory | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"sync" | ||
|
||
"github.com/hyperledger/fabric/core/crypto/bccsp" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
var ( | ||
// Default BCCSP | ||
defaultBCCSP bccsp.BCCSP | ||
|
||
// BCCSP Factories | ||
factories map[string]BCCSPFactory | ||
|
||
// factories' Sync on Initialization | ||
factoriesInitOnce sync.Once | ||
|
||
// Factories' Initialization Error | ||
factoriesInitError error | ||
) | ||
|
||
// BCCSPFactory is used to get instances of the BCCSP interface. | ||
// A Factory has name used to address it. | ||
type BCCSPFactory interface { | ||
|
||
// Name returns the name of this factory | ||
Name() string | ||
|
||
// Get returns an instance of BCCSP using opts. | ||
Get(opts Opts) (bccsp.BCCSP, error) | ||
} | ||
|
||
// Opts contains options for instantiating BCCSPs. | ||
type Opts interface { | ||
|
||
// FactoryName returns the name of the factory to be used | ||
FactoryName() string | ||
|
||
// Ephemeral returns true if the BCCSP has to be ephemeral, false otherwise | ||
Ephemeral() bool | ||
} | ||
|
||
// GetDefault returns a non-ephemeral (long-term) BCCSP | ||
func GetDefault() (bccsp.BCCSP, error) { | ||
if err := initFactories(); err != nil { | ||
return nil, err | ||
} | ||
|
||
return defaultBCCSP, nil | ||
} | ||
|
||
// GetBCCSP returns a BCCSP created according to the options passed in input. | ||
func GetBCCSP(opts Opts) (bccsp.BCCSP, error) { | ||
if err := initFactories(); err != nil { | ||
return nil, err | ||
} | ||
|
||
return getBCCSPInternal(opts) | ||
} | ||
|
||
func initFactories() error { | ||
factoriesInitOnce.Do(func() { | ||
// Initialize factories map | ||
if factoriesInitError = initFactoriesMap(); factoriesInitError != nil { | ||
return | ||
} | ||
|
||
// Create default non-ephemeral (long-term) BCCSP | ||
defaultBCCSP, factoriesInitError = createDefaultBCCSP() | ||
if factoriesInitError != nil { | ||
return | ||
} | ||
}) | ||
return factoriesInitError | ||
} | ||
|
||
func initFactoriesMap() error { | ||
factories = make(map[string]BCCSPFactory) | ||
|
||
// Software-Based BCCSP | ||
f := &SWFactory{} | ||
factories[f.Name()] = f | ||
|
||
return nil | ||
} | ||
|
||
func createDefaultBCCSP() (bccsp.BCCSP, error) { | ||
defaultBCCSPFactoryName := viper.GetString("bccsp.default") | ||
if defaultBCCSPFactoryName == "" { | ||
defaultBCCSPFactoryName = SoftwareBasedFactoryName | ||
} | ||
|
||
return getBCCSPInternal(&DefaultOpts{defaultBCCSPFactoryName, false}) | ||
} | ||
|
||
func getBCCSPInternal(opts Opts) (bccsp.BCCSP, error) { | ||
// Validate arguments | ||
if opts == nil { | ||
return nil, errors.New("Cannot instantiate a factory with 'nil' Opts. A fully instantiated BCCSP Opts struct must be provided.") | ||
} | ||
|
||
f, ok := factories[opts.FactoryName()] | ||
if ok { | ||
return f.Get(opts) | ||
} | ||
|
||
return nil, fmt.Errorf("Factory [%s] does not exist.", opts.FactoryName()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
Copyright IBM Corp. 2016 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 factory | ||
|
||
// DefaultOpts offers a default implementation for Opts | ||
type DefaultOpts struct { | ||
ProviderName string | ||
EphemeralFlag bool | ||
} | ||
|
||
// FactoryName returns the name of the provider | ||
func (o *DefaultOpts) FactoryName() string { | ||
return o.ProviderName | ||
} | ||
|
||
// Ephemeral returns true if the CSP has to be ephemeral, false otherwise | ||
func (o *DefaultOpts) Ephemeral() bool { | ||
return o.EphemeralFlag | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
Copyright IBM Corp. 2016 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 factory | ||
|
||
import "testing" | ||
|
||
func TestGetDefault(t *testing.T) { | ||
bccsp, err := GetDefault() | ||
if err != nil { | ||
t.Fatalf("Failed getting default BCCSP [%s]", err) | ||
} | ||
if bccsp == nil { | ||
t.Fatal("Failed getting default BCCSP. Nil instance.") | ||
} | ||
} | ||
|
||
func TestGetBCCPEphemeral(t *testing.T) { | ||
bccsp1, err := GetBCCSP(&SwOpts{EphemeralFlag: true}) | ||
if err != nil { | ||
t.Fatalf("Failed getting ephemeral software-based BCCSP [%s]", err) | ||
} | ||
|
||
bccsp2, err := GetBCCSP(&SwOpts{EphemeralFlag: true}) | ||
if err != nil { | ||
t.Fatalf("Failed getting ephemeral software-based BCCSP [%s]", err) | ||
} | ||
|
||
if bccsp1 == bccsp2 { | ||
t.Fatal("Ephemeral BCCSPs should point to different instances") | ||
} | ||
} | ||
|
||
func TestGetBCCP2Ephemeral(t *testing.T) { | ||
bccsp1, err := GetBCCSP(&SwOpts{EphemeralFlag: false}) | ||
if err != nil { | ||
t.Fatalf("Failed getting non-ephemeral software-based BCCSP [%s]", err) | ||
} | ||
|
||
bccsp2, err := GetBCCSP(&SwOpts{EphemeralFlag: false}) | ||
if err != nil { | ||
t.Fatalf("Failed getting non-ephemeral software-based BCCSP [%s]", err) | ||
} | ||
|
||
if bccsp1 != bccsp2 { | ||
t.Fatal("Non-ephemeral BCCSPs should point to the same instance") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
Copyright IBM Corp. 2016 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 factory | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"sync" | ||
|
||
"github.com/hyperledger/fabric/core/crypto/bccsp" | ||
"github.com/hyperledger/fabric/core/crypto/bccsp/sw" | ||
) | ||
|
||
const ( | ||
// SoftwareBasedFactoryName is the name of the factory of the software-based BCCSP implementation | ||
SoftwareBasedFactoryName = "SW" | ||
) | ||
|
||
// SWFactory is the factory of the software-based BCCSP. | ||
type SWFactory struct { | ||
initOnce sync.Once | ||
bccsp bccsp.BCCSP | ||
err error | ||
} | ||
|
||
// Name returns the name of this factory | ||
func (f *SWFactory) Name() string { | ||
return SoftwareBasedFactoryName | ||
} | ||
|
||
// Get returns an instance of BCCSP using Opts. | ||
func (f *SWFactory) Get(opts Opts) (bccsp.BCCSP, error) { | ||
// Validate arguments | ||
if opts == nil { | ||
return nil, errors.New("Invalid opts. It must not be nil.") | ||
} | ||
|
||
if opts.FactoryName() != f.Name() { | ||
return nil, fmt.Errorf("Invalid Provider Name [%s]. Opts must refer to [%s].", opts.FactoryName(), f.Name()) | ||
} | ||
|
||
if !opts.Ephemeral() { | ||
f.initOnce.Do(func() { | ||
f.bccsp, f.err = sw.New() | ||
return | ||
}) | ||
return f.bccsp, f.err | ||
} | ||
|
||
return sw.New() | ||
} | ||
|
||
// SwOpts contains options for the SWFactory | ||
type SwOpts struct { | ||
EphemeralFlag bool | ||
} | ||
|
||
// FactoryName returns the name of the provider | ||
func (o *SwOpts) FactoryName() string { | ||
return SoftwareBasedFactoryName | ||
} | ||
|
||
// Ephemeral returns true if the CSP has to be ephemeral, false otherwise | ||
func (o *SwOpts) Ephemeral() bool { | ||
return o.EphemeralFlag | ||
} |