github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/orderer/consensus/kafka/consenter.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package kafka 8 9 import ( 10 "github.com/Shopify/sarama" 11 "github.com/hechain20/hechain/common/flogging" 12 "github.com/hechain20/hechain/common/metrics" 13 "github.com/hechain20/hechain/orderer/common/localconfig" 14 "github.com/hechain20/hechain/orderer/consensus" 15 "github.com/hechain20/hechain/orderer/consensus/inactive" 16 "github.com/hyperledger/fabric-lib-go/healthz" 17 cb "github.com/hyperledger/fabric-protos-go/common" 18 "github.com/pkg/errors" 19 ) 20 21 //go:generate counterfeiter -o mock/health_checker.go -fake-name HealthChecker . healthChecker 22 23 // healthChecker defines the contract for health checker 24 type healthChecker interface { 25 RegisterChecker(component string, checker healthz.HealthChecker) error 26 } 27 28 // New creates a Kafka-based consenter. Called by orderer's main.go. 29 func New(config localconfig.Kafka, mp metrics.Provider, healthChecker healthChecker, icr InactiveChainRegistry, mkChain func(string)) (consensus.Consenter, *Metrics) { 30 if config.Verbose { 31 flogging.ActivateSpec(flogging.Global.Spec() + ":orderer.consensus.kafka.sarama=debug") 32 } 33 34 brokerConfig := newBrokerConfig( 35 config.TLS, 36 config.SASLPlain, 37 config.Retry, 38 config.Version, 39 defaultPartition) 40 41 metrics := NewMetrics(mp, brokerConfig.MetricRegistry) 42 43 return &consenterImpl{ 44 mkChain: mkChain, 45 inactiveChainRegistry: icr, 46 brokerConfigVal: brokerConfig, 47 tlsConfigVal: config.TLS, 48 retryOptionsVal: config.Retry, 49 kafkaVersionVal: config.Version, 50 topicDetailVal: &sarama.TopicDetail{ 51 NumPartitions: 1, 52 ReplicationFactor: config.Topic.ReplicationFactor, 53 }, 54 healthChecker: healthChecker, 55 metrics: metrics, 56 }, metrics 57 } 58 59 // InactiveChainRegistry registers chains that are inactive 60 type InactiveChainRegistry interface { 61 // TrackChain tracks a chain with the given name, and calls the given callback 62 // when this chain should be created. 63 TrackChain(chainName string, genesisBlock *cb.Block, createChain func()) 64 } 65 66 // consenterImpl holds the implementation of type that satisfies the 67 // consensus.Consenter interface --as the HandleChain contract requires-- and 68 // the commonConsenter one. 69 type consenterImpl struct { 70 mkChain func(string) 71 brokerConfigVal *sarama.Config 72 tlsConfigVal localconfig.TLS 73 retryOptionsVal localconfig.Retry 74 kafkaVersionVal sarama.KafkaVersion 75 topicDetailVal *sarama.TopicDetail 76 healthChecker healthChecker 77 metrics *Metrics 78 inactiveChainRegistry InactiveChainRegistry 79 } 80 81 // HandleChain creates/returns a reference to a consensus.Chain object for the 82 // given set of support resources. Implements the consensus.Consenter 83 // interface. Called by consensus.newChainSupport(), which is itself called by 84 // multichannel.NewManagerImpl() when ranging over the ledgerFactory's 85 // existingChains. 86 func (consenter *consenterImpl) HandleChain(support consensus.ConsenterSupport, metadata *cb.Metadata) (consensus.Chain, error) { 87 // Check if this node was migrated from Raft 88 if consenter.inactiveChainRegistry != nil { 89 logger.Infof("This node was migrated from Kafka to Raft, skipping activation of Kafka chain") 90 consenter.inactiveChainRegistry.TrackChain(support.ChannelID(), support.Block(0), func() { 91 consenter.mkChain(support.ChannelID()) 92 }) 93 return &inactive.Chain{Err: errors.Errorf("channel %s is not serviced by me", support.ChannelID())}, nil 94 } 95 96 lastOffsetPersisted, lastOriginalOffsetProcessed, lastResubmittedConfigOffset := getOffsets(metadata.Value, support.ChannelID()) 97 ch, err := newChain(consenter, support, lastOffsetPersisted, lastOriginalOffsetProcessed, lastResubmittedConfigOffset) 98 if err != nil { 99 return nil, err 100 } 101 consenter.healthChecker.RegisterChecker(ch.channel.String(), ch) 102 return ch, nil 103 } 104 105 // commonConsenter allows us to retrieve the configuration options set on the 106 // consenter object. These will be common across all chain objects derived by 107 // this consenter. They are set using local configuration settings. This 108 // interface is satisfied by consenterImpl. 109 type commonConsenter interface { 110 brokerConfig() *sarama.Config 111 retryOptions() localconfig.Retry 112 topicDetail() *sarama.TopicDetail 113 Metrics() *Metrics 114 } 115 116 func (consenter *consenterImpl) Metrics() *Metrics { 117 return consenter.metrics 118 } 119 120 func (consenter *consenterImpl) brokerConfig() *sarama.Config { 121 return consenter.brokerConfigVal 122 } 123 124 func (consenter *consenterImpl) retryOptions() localconfig.Retry { 125 return consenter.retryOptionsVal 126 } 127 128 func (consenter *consenterImpl) topicDetail() *sarama.TopicDetail { 129 return consenter.topicDetailVal 130 }