Discussion:
How to route multi-part message based on content in Mule ESB?
timothee
2012-02-07 02:06:19 UTC
Permalink
Hello,

I have a flow that takes 'multi-part form' HTTP POST requests typically made of a json object (part 1) and an image (part 2).
I would like to route the message according to the content of the first part (json) by using the "choice" router.

Can I do that without writing a custom expression evaluator to be used in the "choice" module?

Is there any way to do it by using the "attachment" evaluator already available in "choice". I could not find documentation/examples about the latter.

Thanks much!

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Pablo La Greca
2012-02-08 02:29:56 UTC
Permalink
Timothee,

It would be great if you can provide more information about what you want to do inside choice with the message.

You can use expression transformer [1] and put the json attachment as the payload.

<expression-transformer expression="#[attachment:json-part-name]"/>

After that, you can use json or json-node [2] as expressions in the choice router.

HTH, Pablo.

[1] http://www.mulesoft.org/documentation/display/MULE3USER/Using+Expressions
[2] http://www.mulesoft.org/documentation/display/MULE3USER/Expressions+Configuration+Reference

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Timothee Bailloeul
2012-02-11 22:28:33 UTC
Permalink
Hi Pablo,

Thanks a lot for your response. Let me clarify what I'm trying to do.
I am trying to configure Mule ESB in such a way that it would take the following multipart POST request:

curl -F "foo=@file.json;type:application/json" -F "image=@photo.jpeg;type:image/jpeg" http://MyMuleIPAddress:8081/store

with, for instance, the following content for the file.json:

{
"root":
{
"field_1": "test1",
"field_2": "test2"
}
}

What I'd like to do is to get the first attachment called "foo" and parse it in the "choice" router to make sure that root/field_1 = test1. If that condition is true, I would move along the flow and would use the second attachment (the jpeg image) to store it into a repository.
I tried what you suggested with the expression transformer (see flow config below), but it throws an exception. Also, you suggested to put the json attachment as the payload to enable the json evaluator in the "choice" module, but in that case, can I still use the second attachment later ?

Here is the config:

<flow name="testJsonFlow1" doc:name="testJsonFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP"/>
<expression-transformer evaluator="attachment" expression="#[attachment:foo]" returnSourceIfNull="true" doc:name="Expression"/>
<choice doc:name="Choice">
<when expression="root/field_1 = test1" evaluator="json">
<processor-chain>
<logger message="Success!" level="INFO" doc:name="Logger-success"/>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<logger message="Default to otherwise path..." level="INFO" doc:name="Logger-otherwise"/>
</processor-chain>
</otherwise>
</choice>
<echo-component doc:name="Echo"/>
</flow>

If I run the flow and send the curl command above, I get the following error:

ERROR 2012-02-11 14:17:37,974 [[naaas].connector.http.mule.default.receiver.04] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Expression Evaluator "attachment" with expression "#[attachment:foo]" returned null but a value was required. (org.mule.api.expression.RequiredValueException). Message payload is of type: ContentLengthInputStream
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. Expression Evaluator "attachment" with expression "#[attachment:foo]" returned null but a value was required. (org.mule.api.expression.RequiredValueException)
org.mule.expression.MessageAttachmentExpressionEvaluator:55 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/expression/RequiredValueException.html)
2. Expression Evaluator "attachment" with expression "#[attachment:foo]" returned null but a value was required. (org.mule.api.expression.RequiredValueException). Message payload is of type: ContentLengthInputStream (org.mule.api.transformer.TransformerMessagingException)
org.mule.transformer.AbstractTransformer:123 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerMessagingException.html)
--------------------------------------------------------------------------------

Is there any error in my syntax? BTW, I run Mule 3.2.1 with MuleStudio:
version: 1.0.0
buildDate: 2012-01-20 09:37:24

Thanks a lot for the help.

Timothee

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Pablo La Greca
2012-02-13 19:55:47 UTC
Permalink
You won't lose your attachments. You are just replacing the message payload with the content of the json attachment.

I put a wrong expression. You should use:

<expression-transformer evaluator="attachment" expression="#[attachment:foo]" returnSourceIfNull="true" doc:name="Expression"/>

To be sure your attachments is there, and it's name is foo you can put a custom MP element after the inbound endpoint and debug the content of the message. You can extract the exact name from there and use it in the expression-transformer.

Pablo.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Timothee Bailloeul
2012-02-14 19:15:41 UTC
Permalink
Hi Pablo,

I put an echo component right after my inbound endpoint. Here is what I got from the log:

********************************************************************************
* Message received in service: testJsonFlow1. Content is: *
* '------------------------------6cdaba37b3ce
*
* Content-Disposition: form-data; name="foo"; filename="pj...[100 of 745]' *
********************************************************************************

So it looks like I really have an attachment named "foo".

Later, instead of naming the attachment in Mule, I tried to get the list of attachments by inserting the following component:

<expression-transformer doc:name="getAttachment0">
<return-argument evaluator="attachment" expression="#attachments-list:*"/>
</expression-transformer>

I got the same kind of error:

RROR 2012-02-14 11:12:55,434 [[naaas].connector.http.mule.default.receiver.04] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Expression Evaluator "attachment" with expression "#attachments-list:*" returned null but a value was required. (org.mule.api.expression.RequiredValueException). Message payload is of type: ContentLengthInputStream
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. Expression Evaluator "attachment" with expression "#attachments-list:*" returned null but a value was required. (org.mule.api.expression.RequiredValueException)
org.mule.expression.MessageAttachmentExpressionEvaluator:55 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/expression/RequiredValueException.html)
2. Expression Evaluator "attachment" with expression "#attachments-list:*" returned null but a value was required. (org.mule.api.expression.RequiredValueException). Message payload is of type: ContentLengthInputStream (org.mule.api.transformer.TransformerMessagingException)
org.mule.transformer.AbstractTransformer:123 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerMessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
org.mule.api.expression.RequiredValueException: Expression Evaluator "attachment" with expression "#attachments-list:*" returned null but a value was required.
at org.mule.expression.MessageAttachmentExpressionEvaluator.evaluate(MessageAttachmentExpressionEvaluator.java:55)
at org.mule.expression.DefaultExpressionManager.evaluate(DefaultExpressionManager.java:273)
at org.mule.expression.transformers.ExpressionArgument.evaluate(ExpressionArgument.java:119)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************




I am starting to wonder whether I am missing a schema file (at the top of the Mule flow config file) that is needed to process attachments.
Whenever I use the attachment keyword, Mule chokes.

Timothee

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Pablo La Greca
2012-02-15 19:52:26 UTC
Permalink
Timothee,

I'm not sure your expression is right. Try the following instead:

<expression-transformer doc:name="getAttachment0">
<return-argument evaluator="attachments" expression="*"/>
</expression-transformer>

or

<expression-transformer doc:name="getAttachment0">
<return-argument expression="#[attachments:*]"/>
</expression-transformer>

HTH, Pablo.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Loading...