You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@camel.apache.org by "Siano, Stephan" <st...@sap.com> on 2016/06/07 08:32:33 UTC

Support for attachment headers in Camel 2.x

Hi,

Sorry for bringing this up again, but I have received no feedback at all about this topic yet.

The current attachment support in Camel 2.x is essentially a Map<String, DataHandler>. As such it can transport the attachment body (in the DataHandler), the Content-Type (also in the DataHandler and a String value (the map key), which may have different semantics (in camel-mail this is the attachment filename, in camel-cxf it is the content-id).

However real-life attachments can have multiple headers (MIME which the standard for mail attachment as well as for SOAP attachments supports an arbitrary number of those).

As the attachments are part of the camel Message interface (which is one of the most central interfaces in Camel), there must be no incompatible change in that before Camel 3.0 (but this will take a while till we get this).

For the time being I have evaluated three compatible implementation options in https://issues.apache.org/jira/browse/CAMEL-9880 :

Option 1:
Create an Attachment interface that supports headers per attachment. Furthermore create a DefaultAttachment implementation which implements the Attachment interface and extends the DataHandler class. As these DefaultAttachment objects are also DataHandlers they can be put into the map provided by the existing Message interface (and its implementation). Components that supports this can check whether a DataHandler in the map also implements the Attachment interface and can also access the headers in that case.

Advantages:

1.       The Message interface and the DefaultMessage implementation are not changed.

2.       The headers are kept with the attachment data, no inconsistencies can occur if attachments are added/removed.
Disadvantage:

1.       The whole issue is not very transparent. The user needs to know that the DataHandler in the map may also implement the Attachment interface (but the API itself does not indicate this).

Option 2:
Define a specifically named header of type Map<String, Map<String, String>> that contains the content of all attachment headers. Access is done via new methods of the MessageHelper class.

Advantages:

1.       The message interface and the DefaultMessage implementation are not changed.

2.       No new interface
Disadvantages:

1.       Access to these headers is rather complex. If it's simplified a little via MessageHelper calls, these become a public API to access this.

2.       The whole scheme is rather intransparent. The user needs to know about these headers and the naming convention. The API does not give any indication about this.

3.       The headers and attachments are separate entities and can become inconsistent (e.g. if attachment or headers are removed).

Option 3:
Create an Attachment interface as in option 1 but the DefaultAttachment implementation does not implement DataHandler. Therefore the Message interface (and the DefaultMessage implementation) are (compatibly) extended in a way that provides access to the Attachment objects. The underlying Map for the attachments in the DefaultMessage implementation is changed from Map<String, DataHandler> to Map<String, Attachment>. The access methods to the old map return a Map<String, DataHander> implementation that is backed by the new mapped (the the map returned by getAttachments() is still modifiable and all modifications work as before).

Advantages:

1.       The way of implementation is rather clean, the API clearly indicates how the attachment headers can be accessed.

2.       The headers are kept with the attachment data, no inconsistencies can occur if attachments are added/removed
Disadvantages:

1.       The Message interface is extended (in a compatible way). Message implementations that do not extend DefaultMessage will break (but there are none of those in the Camel codeline).

2.       The changes in Default message (with the map view) introduce some additional complexity that may have new bugs.

3.       If someone passes a map to the setAttachments() call that was not retrieved by a preceeding getAttachments() call and then modifies the passed map, these modifications will be lost (because in that case the setAttachments() needs to do a (shallow) copy of the passed map. Note: this is likely not working too well with the current implementation, anyway as the DefauiltMessage implementation cannot make sure that the passed map is LinkedHashMap, so the order of the headers may become random in that case-

What do you think about these approaches. Do you think any of those could go into Camel 2.18?

Best regards
Stephan