|
39 | 39 | import kafdrop.service.MessageInspector; |
40 | 40 | import kafdrop.service.TopicNotFoundException; |
41 | 41 | import kafdrop.util.AvroMessageDeserializer; |
| 42 | +import kafdrop.util.AvroMessageSerializer; |
42 | 43 | import kafdrop.util.DefaultMessageDeserializer; |
| 44 | +import kafdrop.util.DefaultMessageSerializer; |
43 | 45 | import kafdrop.util.Deserializers; |
44 | 46 | import kafdrop.util.KeyFormat; |
45 | 47 | import kafdrop.util.MessageDeserializer; |
46 | 48 | import kafdrop.util.MessageFormat; |
| 49 | +import kafdrop.util.MessageSerializer; |
47 | 50 | import kafdrop.util.MsgPackMessageDeserializer; |
| 51 | +import kafdrop.util.MsgPackMessageSerializer; |
48 | 52 | import kafdrop.util.ProtobufMessageDeserializer; |
| 53 | +import kafdrop.util.ProtobufMessageSerializer; |
49 | 54 | import kafdrop.util.ProtobufSchemaRegistryMessageDeserializer; |
| 55 | + |
| 56 | +import java.io.File; |
| 57 | +import java.util.ArrayList; |
| 58 | +import java.util.Comparator; |
| 59 | +import java.util.List; |
| 60 | + |
| 61 | + |
| 62 | +import kafdrop.util.Serializers; |
| 63 | +import org.apache.kafka.clients.producer.RecordMetadata; |
50 | 64 | import org.springframework.http.MediaType; |
51 | 65 | import org.springframework.stereotype.Controller; |
52 | 66 | import org.springframework.ui.Model; |
|
57 | 71 | import org.springframework.web.bind.annotation.RequestParam; |
58 | 72 | import org.springframework.web.bind.annotation.ResponseBody; |
59 | 73 |
|
60 | | -import java.io.File; |
61 | | -import java.util.ArrayList; |
62 | | -import java.util.Comparator; |
63 | 74 | import java.util.Date; |
64 | | -import java.util.List; |
| 75 | + |
| 76 | +import org.springframework.web.bind.annotation.PostMapping; |
| 77 | +import kafdrop.model.CreateMessageVO; |
65 | 78 |
|
66 | 79 | @Tag(name = "message-controller", description = "Message Controller") |
67 | 80 | @Controller |
@@ -195,6 +208,60 @@ public String viewMessageForm(@PathVariable("name") String topicName, |
195 | 208 | return "message-inspector"; |
196 | 209 | } |
197 | 210 |
|
| 211 | + @PostMapping("/topic/{name:.+}/addmessage") |
| 212 | + public String addMessage( |
| 213 | + @PathVariable("name") |
| 214 | + String topicName, |
| 215 | + @ModelAttribute("addMessageForm") CreateMessageVO body, |
| 216 | + Model model) { |
| 217 | + try { |
| 218 | + final MessageFormat defaultFormat = messageFormatProperties.getFormat(); |
| 219 | + final MessageFormat defaultKeyFormat = messageFormatProperties.getKeyFormat(); |
| 220 | + |
| 221 | + final var serializers = new Serializers( |
| 222 | + getSerializer(topicName, defaultKeyFormat, "", ""), |
| 223 | + getSerializer(topicName, defaultFormat, "", "")); |
| 224 | + RecordMetadata recordMetadata = kafkaMonitor.publishMessage(body, serializers); |
| 225 | + |
| 226 | + final var deserializers = new Deserializers( |
| 227 | + getDeserializer(topicName, defaultKeyFormat, "", ""), |
| 228 | + getDeserializer(topicName, defaultFormat, "", "") |
| 229 | + ); |
| 230 | + |
| 231 | + final PartitionOffsetInfo defaultForm = new PartitionOffsetInfo(); |
| 232 | + |
| 233 | + defaultForm.setCount(100l); |
| 234 | + defaultForm.setOffset(recordMetadata.offset()); |
| 235 | + defaultForm.setPartition(body.getTopicPartition()); |
| 236 | + defaultForm.setFormat(defaultFormat); |
| 237 | + defaultForm.setKeyFormat(defaultFormat); |
| 238 | + |
| 239 | + model.addAttribute("messageForm", defaultForm); |
| 240 | + |
| 241 | + final TopicVO topic = kafkaMonitor.getTopic(topicName) |
| 242 | + .orElseThrow(() -> new TopicNotFoundException(topicName)); |
| 243 | + |
| 244 | + model.addAttribute("topic", topic); |
| 245 | + |
| 246 | + model.addAttribute("defaultFormat", defaultFormat); |
| 247 | + model.addAttribute("messageFormats", MessageFormat.values()); |
| 248 | + model.addAttribute("defaultKeyFormat", defaultKeyFormat); |
| 249 | + model.addAttribute("keyFormats", KeyFormat.values()); |
| 250 | + model.addAttribute("descFiles", protobufProperties.getDescFilesList()); |
| 251 | + model.addAttribute("messages", |
| 252 | + messageInspector.getMessages(topicName, |
| 253 | + body.getTopicPartition(), |
| 254 | + recordMetadata.offset(), |
| 255 | + 100, |
| 256 | + deserializers)); |
| 257 | + model.addAttribute("isAnyProtoOpts", List.of(true, false)); |
| 258 | + |
| 259 | + } catch (Exception ex) { |
| 260 | + model.addAttribute("errorMessage", ex.getMessage()); |
| 261 | + } |
| 262 | + return "message-inspector"; |
| 263 | + } |
| 264 | + |
198 | 265 | /** |
199 | 266 | * Human friendly view of searching messages. |
200 | 267 | * |
@@ -339,6 +406,11 @@ List<Object> getPartitionOrMessages( |
339 | 406 | } |
340 | 407 | } |
341 | 408 |
|
| 409 | + private MessageDeserializer getDeserializer(String topicName, MessageFormat format, String descFile, |
| 410 | + String msgTypeName) { |
| 411 | + return getDeserializer(topicName, format, descFile, msgTypeName, false); |
| 412 | + } |
| 413 | + |
342 | 414 | private MessageDeserializer getDeserializer(String topicName, MessageFormat format, String descFile, |
343 | 415 | String msgTypeName, boolean isAnyProto) { |
344 | 416 | final MessageDeserializer deserializer; |
@@ -370,6 +442,30 @@ private MessageDeserializer getDeserializer(String topicName, MessageFormat form |
370 | 442 | return deserializer; |
371 | 443 | } |
372 | 444 |
|
| 445 | + private MessageSerializer getSerializer(String topicName, MessageFormat format, String descFile, String msgTypeName) { |
| 446 | + final MessageSerializer serializer; |
| 447 | + |
| 448 | + if (format == MessageFormat.AVRO) { |
| 449 | + final var schemaRegistryUrl = schemaRegistryProperties.getConnect(); |
| 450 | + final var schemaRegistryAuth = schemaRegistryProperties.getAuth(); |
| 451 | + |
| 452 | + serializer = new AvroMessageSerializer(topicName, schemaRegistryUrl, schemaRegistryAuth); |
| 453 | + } else if (format == MessageFormat.PROTOBUF) { |
| 454 | + // filter the input file name |
| 455 | + final var descFileName = descFile.replace(".desc", "") |
| 456 | + .replaceAll("\\.", "") |
| 457 | + .replaceAll("/", ""); |
| 458 | + final var fullDescFile = protobufProperties.getDirectory() + File.separator + descFileName + ".desc"; |
| 459 | + serializer = new ProtobufMessageSerializer(fullDescFile, msgTypeName); |
| 460 | + } else if (format == MessageFormat.MSGPACK) { |
| 461 | + serializer = new MsgPackMessageSerializer(); |
| 462 | + } else { |
| 463 | + serializer = new DefaultMessageSerializer(); |
| 464 | + } |
| 465 | + |
| 466 | + return serializer; |
| 467 | + } |
| 468 | + |
373 | 469 | /** |
374 | 470 | * Encapsulates offset data for a single partition. |
375 | 471 | */ |
|
0 commit comments