github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/gossip/service/eventer.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package service 18 19 import ( 20 "reflect" 21 22 "github.com/hyperledger/fabric/common/config" 23 24 "github.com/hyperledger/fabric/protos/peer" 25 ) 26 27 // Config enumerates the configuration methods required by gossip 28 type Config interface { 29 // ChainID returns the chainID for this channel 30 ChainID() string 31 32 // Organizations returns a map of org ID to ApplicationOrgConfig 33 Organizations() map[string]config.ApplicationOrg 34 35 // Sequence should return the sequence number of the current configuration 36 Sequence() uint64 37 } 38 39 // ConfigProcessor receives config updates 40 type ConfigProcessor interface { 41 // ProcessConfig should be invoked whenever a channel's configuration is initialized or updated 42 ProcessConfigUpdate(config Config) 43 } 44 45 type configStore struct { 46 anchorPeers []*peer.AnchorPeer 47 orgMap map[string]config.ApplicationOrg 48 } 49 50 type configEventReceiver interface { 51 configUpdated(config Config) 52 } 53 54 type configEventer struct { 55 lastConfig *configStore 56 receiver configEventReceiver 57 } 58 59 func newConfigEventer(receiver configEventReceiver) *configEventer { 60 return &configEventer{ 61 receiver: receiver, 62 } 63 } 64 65 // ProcessConfigUpdate should be invoked whenever a channel's configuration is intialized or updated 66 // it invokes the associated method in configEventReceiver when configuration is updated 67 // but only if the configuration value actually changed 68 // Note, that a changing sequence number is ignored as changing configuration 69 func (ce *configEventer) ProcessConfigUpdate(config Config) { 70 logger.Debugf("Processing new config for channel %s", config.ChainID()) 71 72 if ce.lastConfig != nil && reflect.DeepEqual(ce.lastConfig.orgMap, config.Organizations()) { 73 logger.Debugf("Ignoring new config for channel %s because it contained no anchor peer updates", config.ChainID()) 74 return 75 } 76 77 var newAnchorPeers []*peer.AnchorPeer 78 for _, group := range config.Organizations() { 79 newAnchorPeers = append(newAnchorPeers, group.AnchorPeers()...) 80 } 81 82 newConfig := &configStore{ 83 orgMap: config.Organizations(), 84 anchorPeers: newAnchorPeers, 85 } 86 ce.lastConfig = newConfig 87 88 logger.Debugf("Calling out because config was updated for channel %s", config.ChainID()) 89 ce.receiver.configUpdated(config) 90 }