github.com/psiphon-inc/goarista@v0.0.0-20160825065156-d002785f4c67/kafka/openconfig/encoder.go (about)

     1  // Copyright (C) 2016  Arista Networks, Inc.
     2  // Use of this source code is governed by the Apache License 2.0
     3  // that can be found in the COPYING file.
     4  
     5  package openconfig
     6  
     7  import (
     8  	"encoding/json"
     9  	"fmt"
    10  	"time"
    11  
    12  	"github.com/Shopify/sarama"
    13  	"github.com/aristanetworks/glog"
    14  	"github.com/aristanetworks/goarista/elasticsearch"
    15  	"github.com/aristanetworks/goarista/kafka"
    16  	"github.com/aristanetworks/goarista/openconfig"
    17  	"github.com/golang/protobuf/proto"
    18  )
    19  
    20  // UnhandledMessageError is used for proto messages not matching the handled types
    21  type UnhandledMessageError struct {
    22  	message proto.Message
    23  }
    24  
    25  func (e UnhandledMessageError) Error() string {
    26  	return fmt.Sprintf("Unexpected type %T in proto message: %#v", e.message, e.message)
    27  }
    28  
    29  // UnhandledSubscribeResponseError is used for subscribe responses not matching the handled types
    30  type UnhandledSubscribeResponseError struct {
    31  	response *openconfig.SubscribeResponse
    32  }
    33  
    34  func (e UnhandledSubscribeResponseError) Error() string {
    35  	return fmt.Sprintf("Unexpected type %T in subscribe response: %#v", e.response, e.response)
    36  }
    37  
    38  // ElasticsearchMessageEncoder defines the encoding from SubscribeResponse to
    39  // sarama.ProducerMessage for Elasticsearch
    40  func ElasticsearchMessageEncoder(topic string, key sarama.Encoder,
    41  	message proto.Message) (*sarama.ProducerMessage, error) {
    42  	response, ok := message.(*openconfig.SubscribeResponse)
    43  	if !ok {
    44  		return nil, UnhandledMessageError{message: message}
    45  	}
    46  	update := response.GetUpdate()
    47  	if update == nil {
    48  		return nil, UnhandledSubscribeResponseError{response: response}
    49  	}
    50  	updateMap, err := openconfig.NotificationToMap(update,
    51  		elasticsearch.EscapeFieldName)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	// Convert time to ms to make Elasticsearch happy
    56  	updateMap["_timestamp"] = updateMap["_timestamp"].(int64) / 1000000
    57  	updateJSON, err := json.Marshal(updateMap)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	glog.V(9).Infof("kafka: %s", updateJSON)
    62  	return &sarama.ProducerMessage{
    63  		Topic:    topic,
    64  		Key:      key,
    65  		Value:    sarama.ByteEncoder(updateJSON),
    66  		Metadata: kafka.Metadata{StartTime: time.Unix(0, update.Timestamp), NumMessages: 1},
    67  	}, nil
    68  }