github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/engine/function/kafkaproducer.go (about) 1 package funcs 2 3 import ( 4 // "context" 5 "encoding/json" 6 "fmt" 7 "time" 8 9 "os" 10 "os/signal" 11 12 "github.com/IBM/sarama" 13 ) 14 15 type SendMessagebyKafka struct { 16 } 17 18 func (cf *SendMessagebyKafka) Execute(f *Funcs) { 19 startTime := time.Now() 20 defer func() { 21 elapsed := time.Since(startTime) 22 f.iLog.PerformanceWithDuration("engine.funcs.SendMessagebyKafka.Execute", elapsed) 23 }() 24 defer func() { 25 if err := recover(); err != nil { 26 f.iLog.Error(fmt.Sprintf("There is error to engine.funcs.SendMessagebyKafka.Execute with error: %s", err)) 27 f.CancelExecution(fmt.Sprintf("There is error to engine.funcs.SendMessagebyKafka.Execute with error: %s", err)) 28 f.ErrorMessage = fmt.Sprintf("There is error to engine.funcs.SendMessagebyKafka.Execute with error: %s", err) 29 return 30 } 31 }() 32 33 f.iLog.Debug(fmt.Sprintf("SendMessagebyKafka Execute: %v", f)) 34 35 namelist, valuelist, _ := f.SetInputs() 36 f.iLog.Debug(fmt.Sprintf("SendMessagebyKafka Execute: %v, %v", namelist, valuelist)) 37 kafkaServer := "" 38 Topic := "" 39 data := make(map[string]interface{}) 40 for i, name := range namelist { 41 if name == "Topic" { 42 Topic = valuelist[i] 43 44 continue 45 } else if name == "Server" { 46 kafkaServer = valuelist[i] 47 } 48 data[name] = valuelist[i] 49 } 50 51 if Topic == "" { 52 f.iLog.Error(fmt.Sprintf("SendMessagebyKafka validate wrong: %v", "Topic is empty")) 53 return 54 } 55 56 if kafkaServer == "" { 57 f.iLog.Error(fmt.Sprintf("SendMessagebyKafka validate wrong: %v", "kafkaServer is empty")) 58 return 59 } 60 61 config := sarama.NewConfig() 62 config.Producer.Return.Successes = true 63 64 producer, err := sarama.NewAsyncProducer([]string{kafkaServer}, config) 65 if err != nil { 66 f.iLog.Error(fmt.Sprintf("Error creating producer: %v", err)) 67 f.ErrorMessage = fmt.Sprintf("Error creating producer: %v", err) 68 return 69 } 70 defer producer.Close() 71 72 signals := make(chan os.Signal, 1) 73 signal.Notify(signals, os.Interrupt) 74 75 // Produce messages to topic (asynchronously) 76 77 jsonData, err := json.Marshal(data) 78 if err != nil { 79 f.iLog.Error(fmt.Sprintf("Error:%v", err)) 80 return 81 } 82 // Convert JSON byte array to string 83 jsonString := string(jsonData) 84 85 f.iLog.Debug(fmt.Sprintf("SendMessagebyKafka Execute: topic, %s, message: %v", Topic, jsonString)) 86 87 ProducerLoop: 88 for { 89 select { 90 case <-signals: 91 break ProducerLoop 92 case err := <-producer.Errors(): 93 f.iLog.Error(fmt.Sprintf("Failed to produce message: %v", err)) 94 case success := <-producer.Successes(): 95 f.iLog.Info(fmt.Sprintf("Produced message to topic %s partition %d offset %d", 96 success.Topic, success.Partition, success.Offset)) 97 } 98 99 message := &sarama.ProducerMessage{ 100 Topic: Topic, 101 Value: sarama.StringEncoder(jsonString), 102 } 103 104 producer.Input() <- message 105 } 106 107 outputs := make(map[string][]interface{}) 108 f.SetOutputs(f.convertMap(outputs)) 109 } 110 111 // Validate validates the SendMessagebyKafka function. 112 // It checks if the namelist and valuelist are empty, 113 // and if the "Topic" name is present in the namelist. 114 // Returns true if the validation passes, otherwise returns false with an error. 115 // It also logs the performance of the function. 116 func (cf *SendMessagebyKafka) Validate(f *Funcs) (bool, error) { 117 startTime := time.Now() 118 defer func() { 119 elapsed := time.Since(startTime) 120 f.iLog.PerformanceWithDuration("engine.funcs.SendMessagebyKafka.Validate", elapsed) 121 }() 122 /* defer func() { 123 if err := recover(); err != nil { 124 f.iLog.Error(fmt.Sprintf("There is error to engine.funcs.SendMessagebyKafka.Validate with error: %s", err)) 125 f.ErrorMessage = fmt.Sprintf("There is error to engine.funcs.SendMessagebyKafka.Validate with error: %s", err) 126 return 127 } 128 }() 129 */ 130 f.iLog.Debug(fmt.Sprintf("SendMessagebyKafka validate: %v", f)) 131 namelist, valuelist, _ := f.SetInputs() 132 133 if len(namelist) == 0 { 134 return false, fmt.Errorf("SendMessagebyKafka validate: %v", "namelist is empty") 135 } 136 137 if len(valuelist) == 0 { 138 return false, fmt.Errorf("SendMessagebyKafka validate: %v", "valuelist is empty") 139 } 140 found := false 141 for _, name := range namelist { 142 if name == "" { 143 return false, fmt.Errorf("SendMessagebyKafka validate: %v", "name is empty") 144 } 145 146 if name == "Topic" { 147 found = true 148 } 149 } 150 if !found { 151 return false, fmt.Errorf("SendMessagebyKafka validate: %v", "Topic is not found") 152 } 153 154 return true, nil 155 }