@@ -13,10 +13,14 @@ import (
13
13
"reflect"
14
14
"sync"
15
15
16
+ "github.com/hyperledger/fabric/common/flogging"
16
17
"github.com/hyperledger/fabric/core/handlers/auth"
17
18
"github.com/hyperledger/fabric/core/handlers/decoration"
19
+ endorsement2 "github.com/hyperledger/fabric/core/handlers/endorsement/api"
18
20
)
19
21
22
+ var logger = flogging .MustGetLogger ("core/handlers" )
23
+
20
24
// Registry defines an object that looks up
21
25
// handlers by name
22
26
type Registry interface {
@@ -35,14 +39,17 @@ const (
35
39
// Decoration handler - append or mutate the chaincode input
36
40
// passed to the chaincode
37
41
Decoration
42
+ Endorsement
38
43
39
- authPluginFactory = "NewFilter"
40
- decoratorPluginFactory = "NewDecorator"
44
+ authPluginFactory = "NewFilter"
45
+ decoratorPluginFactory = "NewDecorator"
46
+ endorsementPluginFactory = "NewPluginFactory"
41
47
)
42
48
43
49
type registry struct {
44
50
filters []auth.Filter
45
51
decorators []decoration.Decorator
52
+ endorsers map [string ]endorsement2.PluginFactory
46
53
}
47
54
48
55
var once sync.Once
@@ -53,8 +60,11 @@ var reg registry
53
60
type Config struct {
54
61
AuthFilters []* HandlerConfig `mapstructure:"authFilters" yaml:"authFilters"`
55
62
Decorators []* HandlerConfig `mapstructure:"decorators" yaml:"decorators"`
63
+ Endorsers PluginMapping `mapstructure:"endorsers" yaml:"endorsers"`
56
64
}
57
65
66
+ type PluginMapping map [string ]* HandlerConfig
67
+
58
68
// HandlerConfig defines configuration for a plugin or compiled handler
59
69
type HandlerConfig struct {
60
70
Name string `mapstructure:"name" yaml:"name"`
@@ -65,7 +75,7 @@ type HandlerConfig struct {
65
75
// of the registry
66
76
func InitRegistry (c Config ) Registry {
67
77
once .Do (func () {
68
- reg = registry {}
78
+ reg = registry {endorsers : make ( map [ string ]endorsement2. PluginFactory ) }
69
79
reg .loadHandlers (c )
70
80
})
71
81
return & reg
@@ -79,24 +89,28 @@ func (r *registry) loadHandlers(c Config) {
79
89
for _ , config := range c .Decorators {
80
90
r .evaluateModeAndLoad (config , Decoration )
81
91
}
92
+
93
+ for chaincodeID , config := range c .Endorsers {
94
+ r .evaluateModeAndLoad (config , Endorsement , chaincodeID )
95
+ }
82
96
}
83
97
84
98
// evaluateModeAndLoad if a library path is provided, load the shared object
85
- func (r * registry ) evaluateModeAndLoad (c * HandlerConfig , handlerType HandlerType ) {
99
+ func (r * registry ) evaluateModeAndLoad (c * HandlerConfig , handlerType HandlerType , extraArgs ... string ) {
86
100
if c .Library != "" {
87
- r .loadPlugin (c .Library , handlerType )
101
+ r .loadPlugin (c .Library , handlerType , extraArgs ... )
88
102
} else {
89
- r .loadCompiled (c .Name , handlerType )
103
+ r .loadCompiled (c .Name , handlerType , extraArgs ... )
90
104
}
91
105
}
92
106
93
107
// loadCompiled loads a statically compiled handler
94
- func (r * registry ) loadCompiled (handlerFactory string , handlerType HandlerType ) {
108
+ func (r * registry ) loadCompiled (handlerFactory string , handlerType HandlerType , extraArgs ... string ) {
95
109
registryMD := reflect .ValueOf (& HandlerLibrary {})
96
110
97
111
o := registryMD .MethodByName (handlerFactory )
98
112
if ! o .IsValid () {
99
- panic (fmt .Errorf ("Method %s isn't a method of HandlerLibrary" , handlerFactory ))
113
+ logger . Panicf (fmt .Sprintf ("Method %s isn't a method of HandlerLibrary" , handlerFactory ))
100
114
}
101
115
102
116
inst := o .Call (nil )[0 ].Interface ()
@@ -105,24 +119,30 @@ func (r *registry) loadCompiled(handlerFactory string, handlerType HandlerType)
105
119
r .filters = append (r .filters , inst .(auth.Filter ))
106
120
} else if handlerType == Decoration {
107
121
r .decorators = append (r .decorators , inst .(decoration.Decorator ))
122
+ } else if handlerType == Endorsement {
123
+ if len (extraArgs ) != 1 {
124
+ logger .Panicf ("expected 1 argument in extraArgs" )
125
+ }
126
+ r .endorsers [extraArgs [0 ]] = inst .(endorsement2.PluginFactory )
108
127
}
109
128
}
110
129
111
130
// loadPlugin loads a pluggagle handler
112
- func (r * registry ) loadPlugin (pluginPath string , handlerType HandlerType ) {
131
+ func (r * registry ) loadPlugin (pluginPath string , handlerType HandlerType , extraArgs ... string ) {
113
132
if _ , err := os .Stat (pluginPath ); err != nil {
114
- panic (fmt .Errorf ("Could not find plugin at path %s: %s" , pluginPath , err ))
133
+ logger . Panicf (fmt .Sprintf ("Could not find plugin at path %s: %s" , pluginPath , err ))
115
134
}
116
-
117
135
p , err := plugin .Open (pluginPath )
118
136
if err != nil {
119
- panic (fmt .Errorf ("Error opening plugin at path %s: %s" , pluginPath , err ))
137
+ logger . Panicf (fmt .Sprintf ("Error opening plugin at path %s: %s" , pluginPath , err ))
120
138
}
121
139
122
140
if handlerType == Auth {
123
141
r .initAuthPlugin (p )
124
142
} else if handlerType == Decoration {
125
143
r .initDecoratorPlugin (p )
144
+ } else if handlerType == Endorsement {
145
+ r .initEndorsementPlugin (p , extraArgs ... )
126
146
}
127
147
}
128
148
@@ -159,17 +179,37 @@ func (r *registry) initDecoratorPlugin(p *plugin.Plugin) {
159
179
}
160
180
}
161
181
182
+ func (r * registry ) initEndorsementPlugin (p * plugin.Plugin , extraArgs ... string ) {
183
+ if len (extraArgs ) != 1 {
184
+ logger .Panicf ("expected 1 argument in extraArgs" )
185
+ }
186
+ factorySymbol , err := p .Lookup (endorsementPluginFactory )
187
+ if err != nil {
188
+ panicWithLookupError (endorsementPluginFactory , err )
189
+ }
190
+
191
+ constructor , ok := factorySymbol .(func () endorsement2.PluginFactory )
192
+ if ! ok {
193
+ panicWithDefinitionError (endorsementPluginFactory )
194
+ }
195
+ factory := constructor ()
196
+ if factory == nil {
197
+ logger .Panicf ("factory instance returned nil" )
198
+ }
199
+ r .endorsers [extraArgs [0 ]] = factory
200
+ }
201
+
162
202
// panicWithLookupError panics when a handler constructor lookup fails
163
203
func panicWithLookupError (factory string , err error ) {
164
- panic (fmt .Errorf ( "Filter must contain constructor with name %s. Error from lookup: %s" ,
204
+ logger . Panicf (fmt .Sprintf ( "Plugin must contain constructor with name %s. Error from lookup: %s" ,
165
205
factory , err ))
166
206
}
167
207
168
208
// panicWithDefinitionError panics when a handler constructor does not match
169
209
// the expected function definition
170
210
func panicWithDefinitionError (factory string ) {
171
- panic (fmt .Errorf ("Constructor method %s does not match expected definition" ,
172
- authPluginFactory ))
211
+ logger . Panicf (fmt .Sprintf ("Constructor method %s does not match expected definition" ,
212
+ factory ))
173
213
}
174
214
175
215
// Lookup returns a list of handlers with the given
@@ -179,6 +219,8 @@ func (r *registry) Lookup(handlerType HandlerType) interface{} {
179
219
return r .filters
180
220
} else if handlerType == Decoration {
181
221
return r .decorators
222
+ } else if handlerType == Endorsement {
223
+ return r .endorsers
182
224
}
183
225
184
226
return nil
0 commit comments