github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/handlers/library/registry.go (about) 1 /* 2 Copyright hechain, SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package library 8 9 import ( 10 "fmt" 11 "reflect" 12 "sync" 13 14 "github.com/hechain20/hechain/common/flogging" 15 "github.com/hechain20/hechain/core/handlers/auth" 16 "github.com/hechain20/hechain/core/handlers/decoration" 17 endorsement2 "github.com/hechain20/hechain/core/handlers/endorsement/api" 18 validation "github.com/hechain20/hechain/core/handlers/validation/api" 19 ) 20 21 var logger = flogging.MustGetLogger("core.handlers") 22 23 // Registry defines an object that looks up 24 // handlers by name 25 type Registry interface { 26 // Lookup returns a handler with a given 27 // registered name, or nil if does not exist 28 Lookup(HandlerType) interface{} 29 } 30 31 // HandlerType defines custom handlers that can filter and mutate 32 // objects passing within the peer 33 type HandlerType int 34 35 const ( 36 // Auth handler - reject or forward proposals from clients 37 Auth HandlerType = iota 38 // Decoration handler - append or mutate the chaincode input 39 // passed to the chaincode 40 Decoration 41 Endorsement 42 Validation 43 44 authPluginFactory = "NewFilter" 45 decoratorPluginFactory = "NewDecorator" 46 pluginFactory = "NewPluginFactory" 47 ) 48 49 type registry struct { 50 filters []auth.Filter 51 decorators []decoration.Decorator 52 endorsers map[string]endorsement2.PluginFactory 53 validators map[string]validation.PluginFactory 54 } 55 56 var ( 57 once sync.Once 58 reg registry 59 ) 60 61 // InitRegistry creates the (only) instance 62 // of the registry 63 func InitRegistry(c Config) Registry { 64 once.Do(func() { 65 reg = registry{ 66 endorsers: make(map[string]endorsement2.PluginFactory), 67 validators: make(map[string]validation.PluginFactory), 68 } 69 reg.loadHandlers(c) 70 }) 71 return ® 72 } 73 74 // loadHandlers loads the configured handlers 75 func (r *registry) loadHandlers(c Config) { 76 for _, config := range c.AuthFilters { 77 r.evaluateModeAndLoad(config, Auth) 78 } 79 for _, config := range c.Decorators { 80 r.evaluateModeAndLoad(config, Decoration) 81 } 82 83 for chaincodeID, config := range c.Endorsers { 84 r.evaluateModeAndLoad(config, Endorsement, chaincodeID) 85 } 86 87 for chaincodeID, config := range c.Validators { 88 r.evaluateModeAndLoad(config, Validation, chaincodeID) 89 } 90 } 91 92 // evaluateModeAndLoad if a library path is provided, load the shared object 93 func (r *registry) evaluateModeAndLoad(c *HandlerConfig, handlerType HandlerType, extraArgs ...string) { 94 if c.Library != "" { 95 r.loadPlugin(c.Library, handlerType, extraArgs...) 96 } else { 97 r.loadCompiled(c.Name, handlerType, extraArgs...) 98 } 99 } 100 101 // loadCompiled loads a statically compiled handler 102 func (r *registry) loadCompiled(handlerFactory string, handlerType HandlerType, extraArgs ...string) { 103 registryMD := reflect.ValueOf(&HandlerLibrary{}) 104 105 o := registryMD.MethodByName(handlerFactory) 106 if !o.IsValid() { 107 logger.Panicf(fmt.Sprintf("Method %s isn't a method of HandlerLibrary", handlerFactory)) 108 } 109 110 inst := o.Call(nil)[0].Interface() 111 112 if handlerType == Auth { 113 r.filters = append(r.filters, inst.(auth.Filter)) 114 } else if handlerType == Decoration { 115 r.decorators = append(r.decorators, inst.(decoration.Decorator)) 116 } else if handlerType == Endorsement { 117 if len(extraArgs) != 1 { 118 logger.Panicf("expected 1 argument in extraArgs") 119 } 120 r.endorsers[extraArgs[0]] = inst.(endorsement2.PluginFactory) 121 } else if handlerType == Validation { 122 if len(extraArgs) != 1 { 123 logger.Panicf("expected 1 argument in extraArgs") 124 } 125 r.validators[extraArgs[0]] = inst.(validation.PluginFactory) 126 } 127 } 128 129 // Lookup returns a list of handlers with the given 130 // type, or nil if none exist 131 func (r *registry) Lookup(handlerType HandlerType) interface{} { 132 if handlerType == Auth { 133 return r.filters 134 } else if handlerType == Decoration { 135 return r.decorators 136 } else if handlerType == Endorsement { 137 return r.endorsers 138 } else if handlerType == Validation { 139 return r.validators 140 } 141 142 return nil 143 }