我已将日志导出启用到pub子主题。我正在使用数据流来处理这些日志并在BigQuery中存储相关列。有人可以帮助将pubsub消息有效负载转换为LogEntry
对象。
我尝试了以下代码:
@ProcessElement
public void processElement(ProcessContext c) throws Exception {
PubsubMessage pubsubMessage = c.element();
ObjectMapper mapper = new ObjectMapper();
byte[] payload = pubsubMessage.getPayload();
String s = new String(payload, "UTF8");
LogEntry logEntry = mapper.readValue(s, LogEntry.class);
}
但是我收到了以下错误:
com.fasterxml.jackson.databind.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class com.google.protobuf.Descriptors$FieldDescriptor]
编辑: 我尝试了以下代码:
try {
ByteArrayInputStream stream = new ByteArrayInputStream(Base64.decodeBase64(pubsubMessage.getPayload()));
LogEntry logEntry = LogEntry.parseDelimitedFrom(stream);
System.out.println("Log Entry = " + logEntry);
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
但我现在收到以下错误:
com.google.protobuf.InvalidProtocolBufferException: Protocol message end-group tag did not match expected tag
答案 0 :(得分:0)
JSON format parser应该能够做到这一点。 Java不是我的力量,但我认为你正在寻找类似的东西:
@ProcessElement
public void processElement(ProcessContext c) throws Exception {
LogEntry.Builder entryBuilder = LogEntry.newBuilder();
JsonFormat.Parser.usingTypeRegistry(
JsonFormat.TypeRegistry.newBuilder()
.add(LogEntry.getDescriptor())
.build())
.ignoringUnknownFields()
.merge(c.element(), entryBuilder);
LogEntry entry = entryBuilder.build();
...
}
您可以在不注册类型的情况下离开。我认为在C ++中,proto类型链接到全局注册表。
如果服务添加新字段并导出它们并且您尚未更新proto描述符的副本,则需要“ignoringUnknownFields”。导出的JSON中的任何“@type”字段也会导致问题。
您可能需要对有效负载进行特殊处理(即,如果从JSON中剥离,然后单独解析)。如果它是JSON,我希望解析器尝试填充不存在的子消息。如果它是原型......如果你也注册Any类型,它实际上可能有用。