Uploaded image for project: 'Spring Integration'
  1. Spring Integration
  2. INT-2460

Allow message ids to be set when using a custom deserializer

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Major
    • Resolution: Complete
    • Affects Version/s: 2.1 GA
    • Fix Version/s: 5.0.M1
    • Component/s: Core
    • Labels:
    • Environment:
      N/A

      Description

      Background

      I have created a mailing Gateway for my application which is configured as follows:

      Gateway -> Direct Channel -> Transformer -> Queue Channel (JDBCMessageStore) -> Outbound Mail Channel Adaptor

      This was working fine when the transformer was creating a SimpleMailMessage which is Serializable. The DefaultSerializer and DefaultDeserializer were able to serialize and then deserialize the entire GenericMessage<SimpleMailMessage>.

      However, in order to send HTML e-mail (a common requirement) I need to replace SimpleMailMessage with MimeMailMessage. This is not serializable. The answer is to replace the (de)serializer with a custom implementation.

      This custom implementation will populate a Serializable object with the properties we need from the MimeMailMessage along with the MessageHeaders. This can then be serialized as before. When we deserialize we need to create a new GenericMessage set the payload to be a new MimeMailMessage and restore the headers.

      This currently doesn't work because when we create a new GenericMessage specifying the MessageHeaders a new id gets generated. This means that the existing message in the database doesn't get removed after being picked up by the poller and the outbound mail adaptor keeps sending it.

      Fix

      The fix must be to allow the id to be specified if we need to. The code says:

      /**
      	 * The key for the Message ID. This is an automatically generated UUID and
      	 * should never be explicitly set in the header map <b>except</b> in the
      	 * case of Message deserialization where the serialized Message's generated
      	 * UUID is being restored.
      	 */
      

      This suggests that we can set it when we do a complete deserialization of the message and headers together (as done by the DefaultDeserializer therefore it seems reasonable that if custom deserializers can be supplied they should also be able to restore the id.

      I have cloned the Github repo and made the following code change to MessageHeaders:

      if (!this.headers.containsKey(ID)) {
      			if (MessageHeaders.idGenerator == null){
      				this.headers.put(ID, UUID.randomUUID());
      			}
      			else {
      				this.headers.put(ID, MessageHeaders.idGenerator.generateId());
      			}
      		}
      

      However this causes a test failure in MessageHeadersTests#testIdOverwritten so clearly it is considered important that the id cannot be set. As I said in my last reply on the forum that functionality seems to be at odds with allowing flexible custom (de)serializers.

        Attachments

          Activity

            People

            • Assignee:
              abilan Artem Bilan
              Reporter:
              alexbarnes Alex Barnes
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: