Skip to content

PubsubMessageWithAttributesCoder should not produce null attributes map #19787

@damccorm

Description

@damccorm

Hi, I just got caught by an issue where PubsubMessage.getAttributeMap() returned null, because the message was created by PubsubMessageWithAttributesCoder which uses a NullableCoder for attributes.

Here are the relevant code snippets:


public class PubsubMessageWithAttributesCoder extends CustomCoder<PubsubMessage> {
  // A message's
payload can not be null
  private static final Coder<byte[]> PAYLOAD_CODER = ByteArrayCoder.of();

 // A message's attributes can be null.
  private static final Coder<Map<String, String>> ATTRIBUTES_CODER
=
      NullableCoder.of(MapCoder.of(StringUtf8Coder.of(), StringUtf8Coder.of()));

  @Override

 public PubsubMessage decode(InputStream inStream) throws IOException {
    return decode(inStream,
Context.NESTED);
  }

  @Override
  public PubsubMessage decode(InputStream inStream, Context context)
throws IOException {
    byte[] payload = PAYLOAD_CODER.decode(inStream);
    Map<String, String>
attributes = ATTRIBUTES_CODER.decode(inStream, context);
    return new PubsubMessage(payload, attributes);

 }
}


 


public class PubsubMessage {

  private byte[] message;
  private Map<String, String> attributes;


 public PubsubMessage(byte[] payload, Map<String, String> attributes) {
    this.message = payload;

   this.attributes = attributes;
  }

  /** Returns the main PubSub message. */
  public byte[]
getPayload() {
    return message;
  }

  /** Returns the given attribute value. If not such attribute
exists, returns null. */
  @Nullable
  public String getAttribute(String attribute) {
    checkNotNull(attribute,
"attribute");
    return attributes.get(attribute);
  }

  /** Returns the full map of attributes.
This is an unmodifiable map. */
  public Map<String, String> getAttributeMap() {
    return attributes;

 }
}

There are a handful of potential solutions:

  • Remove the NullableCoder
  • In PubsubMessageWithAttributesCoder.decode, check for null and create an empty Map before instantiating PubsubMessage
  • Allow attributes to be null for PubsubMessage constructor, but create an empty Map if it is (similar to above, but handle it in PubsubMessage)
  • Allow PubsubMessage.attributes to be nullable, and indicate it as such

Imported from Jira BEAM-8085. Original Jira may contain additional context.
Reported by: chadrik.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions