DataFlow SDK 2.x:如何使用java序列化从PubSubIO中使用

时间:2018-03-27 10:31:47

标签: java google-cloud-dataflow apache-beam google-cloud-pubsub

我是Dataflow的新手,我将把以下代码片段从Java SDK 1.9.0迁移到2.3.0:

//SDK 1.9.0
PCollection<MyType> pubsub = p.apply(
  PubsubIO.Read.named("Read from Pubsub")
  .topic(myTopic)
  .withCoder(SerializableCoder.of(MyType.class))
  .timestampLabel("myDate"));

我将其转换为

//SDK 2.3.0
PCollection<MyType> pubsub = p.apply("Read from Pubsub",
  PubsubIO.<MyType>read () // <-- COMPILE ERROR here, private method
  .fromTopic(myTopic)
  .withTimestampAttribute ("myDate"))
.setCoder(SerializableCoder.of(MyType.class));

但是PubsubIO.read()方法在java SDK 2.3.0中是私有的。

所以我需要使用带有MyType的序列化实例的消息,但PubsubIO公开的方法似乎只适用于短信,avro,protobuf等。

如何阅读消息中包含序列化java对象的 PubsubIO 主题?

更新:

我可以这样调整它(尚未尝试过)......

PCollection<MyType> pubsub = p.apply("Read from Pubsub",
  PubsubIO.readMessagesWithAttributes ()
  .fromTopic(myTopic)
  .withTimestampAttribute ("myDate"))
.apply (MapElements.via(new SimpleFunction<PubsubMessage, MyType> () {
        @Override
        public MyType apply (final PubsubMessage message) {
            final byte[] payload = message.getPayload ();
            try {
                try (final ObjectInputStream stream = new ObjectInputStream (new ByteArrayInputStream (payload))) {
                    return (MyType) stream.readObject ();
                }
            } catch (IOException e) {
                throw new RuntimeException (e);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException (e);
            }
        }
    }))

1 个答案:

答案 0 :(得分:1)

您的更新代码看起来应该有效。请注意,如果您未使用属性映射,则还会PubsubIO.readPubsubMessagesWithoutAttributes()

先前的功能已在PR#2634中删除,后者将其替换为最常见编码类型(proto,avro,Strings)的专用方法。

我怀疑由于依赖Java序列化的固有危险,SerializableCoder的任意对象解码都没有被保留。请参阅SerializableCoder javadoc 或相关问题Java serialization - advantages and disadvantages, use or avoid?。但是,如果您觉得缺少API,则Beam SDK是开源的,社区欢迎contributions