go_study/fabric-main/core/handlers/library/plugin.go

127 lines
3.6 KiB
Go

//go:build !noplugin && cgo
// +build !noplugin,cgo
/*
Copyright IBM Corp, SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package library
import (
"fmt"
"os"
"plugin"
"github.com/hyperledger/fabric/core/handlers/auth"
"github.com/hyperledger/fabric/core/handlers/decoration"
endorsement "github.com/hyperledger/fabric/core/handlers/endorsement/api"
validation "github.com/hyperledger/fabric/core/handlers/validation/api"
)
// loadPlugin loads a pluggable handler
func (r *registry) loadPlugin(pluginPath string, handlerType HandlerType, extraArgs ...string) {
if _, err := os.Stat(pluginPath); err != nil {
logger.Panicf(fmt.Sprintf("Could not find plugin at path %s: %s", pluginPath, err))
}
p, err := plugin.Open(pluginPath)
if err != nil {
logger.Panicf(fmt.Sprintf("Error opening plugin at path %s: %s", pluginPath, err))
}
if handlerType == Auth {
r.initAuthPlugin(p)
} else if handlerType == Decoration {
r.initDecoratorPlugin(p)
} else if handlerType == Endorsement {
r.initEndorsementPlugin(p, extraArgs...)
} else if handlerType == Validation {
r.initValidationPlugin(p, extraArgs...)
}
}
// initAuthPlugin constructs an auth filter from the given plugin
func (r *registry) initAuthPlugin(p *plugin.Plugin) {
constructorSymbol, err := p.Lookup(authPluginFactory)
if err != nil {
panicWithLookupError(authPluginFactory, err)
}
constructor, ok := constructorSymbol.(func() auth.Filter)
if !ok {
panicWithDefinitionError(authPluginFactory)
}
filter := constructor()
if filter != nil {
r.filters = append(r.filters, filter)
}
}
// initDecoratorPlugin constructs a decorator from the given plugin
func (r *registry) initDecoratorPlugin(p *plugin.Plugin) {
constructorSymbol, err := p.Lookup(decoratorPluginFactory)
if err != nil {
panicWithLookupError(decoratorPluginFactory, err)
}
constructor, ok := constructorSymbol.(func() decoration.Decorator)
if !ok {
panicWithDefinitionError(decoratorPluginFactory)
}
decorator := constructor()
if decorator != nil {
r.decorators = append(r.decorators, constructor())
}
}
func (r *registry) initEndorsementPlugin(p *plugin.Plugin, extraArgs ...string) {
if len(extraArgs) != 1 {
logger.Panicf("expected 1 argument in extraArgs")
}
factorySymbol, err := p.Lookup(pluginFactory)
if err != nil {
panicWithLookupError(pluginFactory, err)
}
constructor, ok := factorySymbol.(func() endorsement.PluginFactory)
if !ok {
panicWithDefinitionError(pluginFactory)
}
factory := constructor()
if factory == nil {
logger.Panicf("factory instance returned nil")
}
r.endorsers[extraArgs[0]] = factory
}
func (r *registry) initValidationPlugin(p *plugin.Plugin, extraArgs ...string) {
if len(extraArgs) != 1 {
logger.Panicf("expected 1 argument in extraArgs")
}
factorySymbol, err := p.Lookup(pluginFactory)
if err != nil {
panicWithLookupError(pluginFactory, err)
}
constructor, ok := factorySymbol.(func() validation.PluginFactory)
if !ok {
panicWithDefinitionError(pluginFactory)
}
factory := constructor()
if factory == nil {
logger.Panicf("factory instance returned nil")
}
r.validators[extraArgs[0]] = factory
}
// panicWithLookupError panics when a handler constructor lookup fails
func panicWithLookupError(factory string, err error) {
logger.Panicf("Plugin must contain constructor with name %s. Error from lookup: %s", factory, err)
}
// panicWithDefinitionError panics when a handler constructor does not match
// the expected function definition
func panicWithDefinitionError(factory string) {
logger.Panicf("Constructor method %s does not match expected definition", factory)
}