github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/orderer/kafka/util.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 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 kafka
    18  
    19  import (
    20  	"crypto/tls"
    21  	"crypto/x509"
    22  	"fmt"
    23  	"strconv"
    24  
    25  	"github.com/Shopify/sarama"
    26  	"github.com/hyperledger/fabric/orderer/localconfig"
    27  	ab "github.com/hyperledger/fabric/protos/orderer"
    28  )
    29  
    30  func newBrokerConfig(kafkaVersion sarama.KafkaVersion, chosenStaticPartition int32, tlsConfig config.TLS) *sarama.Config {
    31  	brokerConfig := sarama.NewConfig()
    32  
    33  	brokerConfig.Consumer.Return.Errors = true
    34  
    35  	brokerConfig.Net.TLS.Enable = tlsConfig.Enabled
    36  	if brokerConfig.Net.TLS.Enable {
    37  		// create public/private key pair structure
    38  		keyPair, err := tls.X509KeyPair([]byte(tlsConfig.Certificate), []byte(tlsConfig.PrivateKey))
    39  		if err != nil {
    40  			panic(fmt.Errorf("Unable to decode public/private key pair. Error: %v", err))
    41  		}
    42  		// create root CA pool
    43  		rootCAs := x509.NewCertPool()
    44  		for _, certificate := range tlsConfig.RootCAs {
    45  			if !rootCAs.AppendCertsFromPEM([]byte(certificate)) {
    46  				panic(fmt.Errorf("Unable to decode certificate. Error: %v", err))
    47  			}
    48  		}
    49  		brokerConfig.Net.TLS.Config = &tls.Config{
    50  			Certificates: []tls.Certificate{keyPair},
    51  			RootCAs:      rootCAs,
    52  			MinVersion:   0, // TLS 1.0 (no SSL support)
    53  			MaxVersion:   0, // Latest supported TLS version
    54  		}
    55  	}
    56  
    57  	// Set the level of acknowledgement reliability needed from the broker.
    58  	// WaitForAll means that the partition leader will wait till all ISRs
    59  	// got the message before sending back an ACK to the sender.
    60  	brokerConfig.Producer.RequiredAcks = sarama.WaitForAll
    61  	// A partitioner is actually not needed the way we do things now,
    62  	// but we're adding it now to allow for flexibility in the future.
    63  	brokerConfig.Producer.Partitioner = newStaticPartitioner(chosenStaticPartition)
    64  	// Set equivalent of Kafka producer config max.request.bytes to the default
    65  	// value of a Kafka broker's socket.request.max.bytes property (100 MiB).
    66  	brokerConfig.Producer.MaxMessageBytes = int(sarama.MaxRequestSize)
    67  
    68  	brokerConfig.Version = kafkaVersion
    69  
    70  	return brokerConfig
    71  }
    72  
    73  func newConnectMessage() *ab.KafkaMessage {
    74  	return &ab.KafkaMessage{
    75  		Type: &ab.KafkaMessage_Connect{
    76  			Connect: &ab.KafkaMessageConnect{
    77  				Payload: nil,
    78  			},
    79  		},
    80  	}
    81  }
    82  
    83  func newRegularMessage(payload []byte) *ab.KafkaMessage {
    84  	return &ab.KafkaMessage{
    85  		Type: &ab.KafkaMessage_Regular{
    86  			Regular: &ab.KafkaMessageRegular{
    87  				Payload: payload,
    88  			},
    89  		},
    90  	}
    91  }
    92  
    93  func newTimeToCutMessage(blockNumber uint64) *ab.KafkaMessage {
    94  	return &ab.KafkaMessage{
    95  		Type: &ab.KafkaMessage_TimeToCut{
    96  			TimeToCut: &ab.KafkaMessageTimeToCut{
    97  				BlockNumber: blockNumber,
    98  			},
    99  		},
   100  	}
   101  }
   102  
   103  func newProducerMessage(cp ChainPartition, payload []byte) *sarama.ProducerMessage {
   104  	return &sarama.ProducerMessage{
   105  		Topic: cp.Topic(),
   106  		Key:   sarama.StringEncoder(strconv.Itoa(int(cp.Partition()))), // TODO Consider writing an IntEncoder?
   107  		Value: sarama.ByteEncoder(payload),
   108  	}
   109  }
   110  
   111  func newOffsetReq(cp ChainPartition, offset int64) *sarama.OffsetRequest {
   112  	req := &sarama.OffsetRequest{}
   113  	// If offset (seek) == -1, ask for the offset assigned to next new message.
   114  	// If offset (seek) == -2, ask for the earliest available offset.
   115  	// The last parameter in the AddBlock call is needed for God-knows-why reasons.
   116  	// From the Kafka folks themselves: "We agree that this API is slightly funky."
   117  	// https://mail-archives.apache.org/mod_mbox/kafka-users/201411.mbox/%3Cc159383825e04129b77253ffd6c448aa@BY2PR02MB505.namprd02.prod.outlook.com%3E
   118  	req.AddBlock(cp.Topic(), cp.Partition(), offset, 1)
   119  	return req
   120  }