Uploaded image for project: 'Beam'
  1. Beam
  2. BEAM-8085

PubsubMessageWithAttributesCoder should not produce null attributes map

Details

    • Improvement
    • Status: Open
    • P3
    • Resolution: Unresolved
    • None
    • None
    • io-java-gcp
    • 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:

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

      Attachments

        Activity

          People

            Unassigned Unassigned
            chadrik Chad Dombrova
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated: