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 }