Details
-
Improvement
-
Status: Open
-
P3
-
Resolution: Unresolved
-
None
-
None
-
None
Description
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