github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/handlers/library/plugin.go (about)

     1  //go:build !noplugin && cgo
     2  // +build !noplugin,cgo
     3  
     4  /*
     5   Copyright hechain, SecureKey Technologies Inc. All Rights Reserved.
     6  
     7   SPDX-License-Identifier: Apache-2.0
     8  */
     9  
    10  package library
    11  
    12  import (
    13  	"fmt"
    14  	"os"
    15  	"plugin"
    16  
    17  	"github.com/hechain20/hechain/core/handlers/auth"
    18  	"github.com/hechain20/hechain/core/handlers/decoration"
    19  	endorsement "github.com/hechain20/hechain/core/handlers/endorsement/api"
    20  	validation "github.com/hechain20/hechain/core/handlers/validation/api"
    21  )
    22  
    23  // loadPlugin loads a pluggable handler
    24  func (r *registry) loadPlugin(pluginPath string, handlerType HandlerType, extraArgs ...string) {
    25  	if _, err := os.Stat(pluginPath); err != nil {
    26  		logger.Panicf(fmt.Sprintf("Could not find plugin at path %s: %s", pluginPath, err))
    27  	}
    28  	p, err := plugin.Open(pluginPath)
    29  	if err != nil {
    30  		logger.Panicf(fmt.Sprintf("Error opening plugin at path %s: %s", pluginPath, err))
    31  	}
    32  
    33  	if handlerType == Auth {
    34  		r.initAuthPlugin(p)
    35  	} else if handlerType == Decoration {
    36  		r.initDecoratorPlugin(p)
    37  	} else if handlerType == Endorsement {
    38  		r.initEndorsementPlugin(p, extraArgs...)
    39  	} else if handlerType == Validation {
    40  		r.initValidationPlugin(p, extraArgs...)
    41  	}
    42  }
    43  
    44  // initAuthPlugin constructs an auth filter from the given plugin
    45  func (r *registry) initAuthPlugin(p *plugin.Plugin) {
    46  	constructorSymbol, err := p.Lookup(authPluginFactory)
    47  	if err != nil {
    48  		panicWithLookupError(authPluginFactory, err)
    49  	}
    50  	constructor, ok := constructorSymbol.(func() auth.Filter)
    51  	if !ok {
    52  		panicWithDefinitionError(authPluginFactory)
    53  	}
    54  
    55  	filter := constructor()
    56  	if filter != nil {
    57  		r.filters = append(r.filters, filter)
    58  	}
    59  }
    60  
    61  // initDecoratorPlugin constructs a decorator from the given plugin
    62  func (r *registry) initDecoratorPlugin(p *plugin.Plugin) {
    63  	constructorSymbol, err := p.Lookup(decoratorPluginFactory)
    64  	if err != nil {
    65  		panicWithLookupError(decoratorPluginFactory, err)
    66  	}
    67  	constructor, ok := constructorSymbol.(func() decoration.Decorator)
    68  	if !ok {
    69  		panicWithDefinitionError(decoratorPluginFactory)
    70  	}
    71  	decorator := constructor()
    72  	if decorator != nil {
    73  		r.decorators = append(r.decorators, constructor())
    74  	}
    75  }
    76  
    77  func (r *registry) initEndorsementPlugin(p *plugin.Plugin, extraArgs ...string) {
    78  	if len(extraArgs) != 1 {
    79  		logger.Panicf("expected 1 argument in extraArgs")
    80  	}
    81  	factorySymbol, err := p.Lookup(pluginFactory)
    82  	if err != nil {
    83  		panicWithLookupError(pluginFactory, err)
    84  	}
    85  
    86  	constructor, ok := factorySymbol.(func() endorsement.PluginFactory)
    87  	if !ok {
    88  		panicWithDefinitionError(pluginFactory)
    89  	}
    90  	factory := constructor()
    91  	if factory == nil {
    92  		logger.Panicf("factory instance returned nil")
    93  	}
    94  	r.endorsers[extraArgs[0]] = factory
    95  }
    96  
    97  func (r *registry) initValidationPlugin(p *plugin.Plugin, extraArgs ...string) {
    98  	if len(extraArgs) != 1 {
    99  		logger.Panicf("expected 1 argument in extraArgs")
   100  	}
   101  	factorySymbol, err := p.Lookup(pluginFactory)
   102  	if err != nil {
   103  		panicWithLookupError(pluginFactory, err)
   104  	}
   105  
   106  	constructor, ok := factorySymbol.(func() validation.PluginFactory)
   107  	if !ok {
   108  		panicWithDefinitionError(pluginFactory)
   109  	}
   110  	factory := constructor()
   111  	if factory == nil {
   112  		logger.Panicf("factory instance returned nil")
   113  	}
   114  	r.validators[extraArgs[0]] = factory
   115  }
   116  
   117  // panicWithLookupError panics when a handler constructor lookup fails
   118  func panicWithLookupError(factory string, err error) {
   119  	logger.Panicf("Plugin must contain constructor with name %s. Error from lookup: %s", factory, err)
   120  }
   121  
   122  // panicWithDefinitionError panics when a handler constructor does not match
   123  // the expected function definition
   124  func panicWithDefinitionError(factory string) {
   125  	logger.Panicf("Constructor method %s does not match expected definition", factory)
   126  }