github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/gossip/service/eventer.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package service 8 9 import ( 10 "reflect" 11 12 "github.com/hyperledger/fabric/common/config" 13 14 "github.com/hyperledger/fabric/protos/peer" 15 ) 16 17 // Config enumerates the configuration methods required by gossip 18 type Config interface { 19 // ChainID returns the chainID for this channel 20 ChainID() string 21 22 // Organizations returns a map of org ID to ApplicationOrgConfig 23 Organizations() map[string]config.ApplicationOrg 24 25 // Sequence should return the sequence number of the current configuration 26 Sequence() uint64 27 } 28 29 // ConfigProcessor receives config updates 30 type ConfigProcessor interface { 31 // ProcessConfig should be invoked whenever a channel's configuration is initialized or updated 32 ProcessConfigUpdate(config Config) 33 } 34 35 type configStore struct { 36 anchorPeers []*peer.AnchorPeer 37 orgMap map[string]config.ApplicationOrg 38 } 39 40 type configEventReceiver interface { 41 configUpdated(config Config) 42 } 43 44 type configEventer struct { 45 lastConfig *configStore 46 receiver configEventReceiver 47 } 48 49 func newConfigEventer(receiver configEventReceiver) *configEventer { 50 return &configEventer{ 51 receiver: receiver, 52 } 53 } 54 55 // ProcessConfigUpdate should be invoked whenever a channel's configuration is intialized or updated 56 // it invokes the associated method in configEventReceiver when configuration is updated 57 // but only if the configuration value actually changed 58 // Note, that a changing sequence number is ignored as changing configuration 59 func (ce *configEventer) ProcessConfigUpdate(config Config) { 60 logger.Debugf("Processing new config for channel %s", config.ChainID()) 61 orgMap := cloneOrgConfig(config.Organizations()) 62 if ce.lastConfig != nil && reflect.DeepEqual(ce.lastConfig.orgMap, orgMap) { 63 logger.Debugf("Ignoring new config for channel %s because it contained no anchor peer updates", config.ChainID()) 64 return 65 } 66 67 var newAnchorPeers []*peer.AnchorPeer 68 for _, group := range config.Organizations() { 69 newAnchorPeers = append(newAnchorPeers, group.AnchorPeers()...) 70 } 71 72 newConfig := &configStore{ 73 orgMap: orgMap, 74 anchorPeers: newAnchorPeers, 75 } 76 ce.lastConfig = newConfig 77 78 logger.Debugf("Calling out because config was updated for channel %s", config.ChainID()) 79 ce.receiver.configUpdated(config) 80 } 81 82 func cloneOrgConfig(src map[string]config.ApplicationOrg) map[string]config.ApplicationOrg { 83 clone := make(map[string]config.ApplicationOrg) 84 for k, v := range src { 85 clone[k] = &appGrp{ 86 name: v.Name(), 87 mspID: v.MSPID(), 88 anchorPeers: v.AnchorPeers(), 89 } 90 } 91 return clone 92 } 93 94 type appGrp struct { 95 name string 96 mspID string 97 anchorPeers []*peer.AnchorPeer 98 } 99 100 func (ag *appGrp) Name() string { 101 return ag.name 102 } 103 104 func (ag *appGrp) MSPID() string { 105 return ag.mspID 106 } 107 108 func (ag *appGrp) AnchorPeers() []*peer.AnchorPeer { 109 return ag.anchorPeers 110 }