@@ -11,11 +11,14 @@ import (
11
11
12
12
"github.com/hyperledger/fabric/common/chaincode"
13
13
"github.com/hyperledger/fabric/common/flogging"
14
+ "github.com/hyperledger/fabric/core/ledger/cceventmgmt"
14
15
"github.com/pkg/errors"
15
16
)
16
17
17
18
var (
18
- logger = flogging .MustGetLogger ("discovery/lifecycle" )
19
+ // Logger is the logging instance for this package.
20
+ // It's exported because the tests override its backend
21
+ Logger = flogging .MustGetLogger ("discovery/lifecycle" )
19
22
)
20
23
21
24
// Lifecycle manages information regarding chaincode lifecycle
@@ -36,12 +39,16 @@ type LifeCycleChangeListener interface {
36
39
// HandleMetadataUpdate is triggered upon a change in the chaincode lifecycle change
37
40
type HandleMetadataUpdate func (channel string , chaincodes chaincode.MetadataSet )
38
41
42
+ // go:generate mockery -dir core/cclifecycle -name LifeCycleChangeListener -case underscore -output core/cclifecycle/mocks/
43
+
39
44
// LifeCycleChangeListener runs whenever there is a change to the metadata
40
45
// // of a chaincode in the context of a specific channel
41
46
func (mdUpdate HandleMetadataUpdate ) LifeCycleChangeListener (channel string , chaincodes chaincode.MetadataSet ) {
42
47
mdUpdate (channel , chaincodes )
43
48
}
44
49
50
+ // go:generate mockery -dir core/cclifecycle -name Enumerator -case underscore -output core/cclifecycle/mocks/
51
+
45
52
// Enumerator enumerates chaincodes
46
53
type Enumerator interface {
47
54
// Enumerate returns the installed chaincodes
@@ -56,6 +63,8 @@ func (listCCs Enumerate) Enumerate() ([]chaincode.InstalledChaincode, error) {
56
63
return listCCs ()
57
64
}
58
65
66
+ // go:generate mockery -dir core/cclifecycle -name Query -case underscore -output core/cclifecycle/mocks/
67
+
59
68
// Query queries the state
60
69
type Query interface {
61
70
// GetState gets the value for given namespace and key. For a chaincode, the namespace corresponds to the chaincodeId
@@ -65,8 +74,21 @@ type Query interface {
65
74
Done ()
66
75
}
67
76
68
- // QueryCreator creates a new query
69
- type QueryCreator func () (Query , error )
77
+ // go:generate mockery -dir core/cclifecycle -name QueryCreator -case underscore -output core/cclifecycle/mocks/
78
+
79
+ // QueryCreator creates queries
80
+ type QueryCreator interface {
81
+ // NewQuery creates a new Query, or error on failure
82
+ NewQuery () (Query , error )
83
+ }
84
+
85
+ // QueryCreatorFunc creates a new query
86
+ type QueryCreatorFunc func () (Query , error )
87
+
88
+ // NewQuery creates a new Query, or error on failure
89
+ func (qc QueryCreatorFunc ) NewQuery () (Query , error ) {
90
+ return qc ()
91
+ }
70
92
71
93
// NewLifeCycle creates a new Lifecycle instance
72
94
func NewLifeCycle (installedChaincodes Enumerator ) (* Lifecycle , error ) {
@@ -87,48 +109,48 @@ func NewLifeCycle(installedChaincodes Enumerator) (*Lifecycle, error) {
87
109
// Metadata returns the metadata of the chaincode on the given channel,
88
110
// or nil if not found or an error occurred at retrieving it
89
111
func (lc * Lifecycle ) Metadata (channel string , cc string ) * chaincode.Metadata {
90
- newQuery := lc .queryCreatorsByChannel [channel ]
91
- if newQuery == nil {
92
- logger .Warning ("Requested Metadata for non-existent channel" , channel )
112
+ queryCreator := lc .queryCreatorsByChannel [channel ]
113
+ if queryCreator == nil {
114
+ Logger .Warning ("Requested Metadata for non-existent channel" , channel )
93
115
return nil
94
116
}
95
117
if md , found := lc .deployedCCsByChannel [channel ].Lookup (cc ); found {
96
- logger .Debug ("Returning metadata for channel" , channel , ", chaincode" , cc , ":" , md )
118
+ Logger .Debug ("Returning metadata for channel" , channel , ", chaincode" , cc , ":" , md )
97
119
return & md
98
120
}
99
- query , err := newQuery ()
121
+ query , err := queryCreator . NewQuery ()
100
122
if err != nil {
101
- logger .Error ("Failed obtaining new query for channel" , channel , ":" , err )
123
+ Logger .Error ("Failed obtaining new query for channel" , channel , ":" , err )
102
124
return nil
103
125
}
104
126
md , err := DeployedChaincodes (query , AcceptAll , cc )
105
127
if err != nil {
106
- logger .Error ("Failed querying LSCC for channel" , channel , ":" , err )
128
+ Logger .Error ("Failed querying LSCC for channel" , channel , ":" , err )
107
129
return nil
108
130
}
109
131
if len (md ) == 0 {
110
- logger .Info ("Chaincode" , cc , "isn't defined in channel" , channel )
132
+ Logger .Info ("Chaincode" , cc , "isn't defined in channel" , channel )
111
133
return nil
112
134
}
113
135
114
136
return & md [0 ]
115
137
}
116
138
117
- func (lc * Lifecycle ) initMetadataForChannel (channel string , newQuery QueryCreator ) error {
139
+ func (lc * Lifecycle ) initMetadataForChannel (channel string , queryCreator QueryCreator ) error {
118
140
if lc .isChannelMetadataInitialized (channel ) {
119
141
return nil
120
142
}
121
143
// Create a new metadata mapping for the channel
122
- query , err := newQuery ()
144
+ query , err := queryCreator . NewQuery ()
123
145
if err != nil {
124
146
return errors .WithStack (err )
125
147
}
126
148
ccs , err := queryChaincodeDefinitions (query , lc .installedCCs , DeployedChaincodes )
127
149
if err != nil {
128
150
return errors .WithStack (err )
129
151
}
130
- lc .createMetadataForChannel (channel , newQuery )
131
- lc .loadMetadataForChannel (channel , ccs )
152
+ lc .createMetadataForChannel (channel , queryCreator )
153
+ lc .updateState (channel , ccs )
132
154
return nil
133
155
}
134
156
@@ -146,14 +168,6 @@ func (lc *Lifecycle) isChannelMetadataInitialized(channel string) bool {
146
168
return exists
147
169
}
148
170
149
- func (lc * Lifecycle ) loadMetadataForChannel (channel string , ccs chaincode.MetadataSet ) {
150
- lc .RLock ()
151
- defer lc .RUnlock ()
152
- for _ , cc := range ccs {
153
- lc .deployedCCsByChannel [channel ].Update (cc )
154
- }
155
- }
156
-
157
171
func (lc * Lifecycle ) updateState (channel string , ccUpdate chaincode.MetadataSet ) {
158
172
lc .RLock ()
159
173
defer lc .RUnlock ()
@@ -167,20 +181,23 @@ func (lc *Lifecycle) fireChangeListeners(channel string) {
167
181
md := lc .deployedCCsByChannel [channel ]
168
182
lc .RUnlock ()
169
183
for _ , listener := range lc .listeners {
170
- listener .LifeCycleChangeListener (channel , md .Aggregate ())
184
+ aggregatedMD := md .Aggregate ()
185
+ listener .LifeCycleChangeListener (channel , aggregatedMD )
171
186
}
187
+ Logger .Debug ("Listeners for channel" , channel , "invoked" )
172
188
}
173
189
174
190
// NewChannelSubscription subscribes to a channel
175
- func (lc * Lifecycle ) NewChannelSubscription (channel string , newQuery QueryCreator ) (* Subscription , error ) {
191
+ func (lc * Lifecycle ) NewChannelSubscription (channel string , queryCreator QueryCreator ) (* Subscription , error ) {
176
192
sub := & Subscription {
177
- lc : lc ,
178
- channel : channel ,
179
- newQuery : newQuery ,
193
+ lc : lc ,
194
+ channel : channel ,
195
+ queryCreator : queryCreator ,
196
+ pendingUpdates : make (chan * cceventmgmt.ChaincodeDefinition , 1 ),
180
197
}
181
198
// Initialize metadata for the channel.
182
199
// This loads metadata about all installed chaincodes
183
- if err := lc .initMetadataForChannel (channel , newQuery ); err != nil {
200
+ if err := lc .initMetadataForChannel (channel , queryCreator ); err != nil {
184
201
return nil , errors .WithStack (err )
185
202
}
186
203
lc .fireChangeListeners (channel )
0 commit comments