How to read values from a DB and use them with the SMTP connector in Mule 3 - mule

I would like to read some email details from the DB, and here's what my connector looks like:
<jdbc:connector name="dbConnector" dataSource-ref="dataSource">
<jdbc:query key="sqlQuery"
value="SELECT from, to, subject, body FROM email WHERE status='PENDING'" />
<jdbc:query key="sqlQuery.ack"
value="UPDATE email SET status='IN PROGRESS' WHERE id=#[map-payload:id]" />
</jdbc:connector>
I would then like to use those details to send a bunch of mails. I expect that the inbound-endpoint will be the JDBC Connector and the outbound-endpoint will be SMTP Connector, but I don't know how to store and use data I read from that table. Is there a way to do this without resorting to Java code?

Using transformers should be enough to achieve your goal: the inbound JDBC endpoint will give you a Map payload. From this payload you will extract the properties required by the outbound SMTP endpoint and the body of the message:
<!-- Set SMTP endpoint properties -->
<message-properties-transformer>
<add-message-property key="subject" value="#[map-payload:subject]"/>
...
</message-properties-transformer>
<!-- Set the message Body as new payload -->
<expression-transformer>
<return-argument evaluator="map-payload" expression="body"/>
</expression-transformer>

Related

Timeout Configuration

I am configuring transaction and response timeout for API in Mule 4, Is there anyway that I set different timeout for different methods(GET,POST,DELETE) for single API in Mule Soft because the API has different SLA for different operations ?
As the http timeout is set at the connector level that does not allow you to set timeouts per method.
One way you could try to achieve this is via separating your interface flow from your logic. Then have your interface flow call your logic flow via something like vm where you can set a timeout individually. You can then catch the timeout error and do what you want with it.
Here is an example that has a flow for a POST method. All this flow does is offload the logic to another floe and invokes that logic using v:publish-consume and awaits the response. It sets a timeout of 2 seconds(configurable with properties etc.) and catches VM:QUEUE-TIMEOUT errors and sets an 'SLA exceeded'error message:
<flow name="myPOSTInterface">
<vm:publish-consume queueName="postQueue" config-ref="vm" timeout="2" timeoutUnit="SECONDS" />
<logger level="INFO" message="Result from logic flow: #[payload]" />
<error-handler>
<on-error-continue type="VM:QUEUE_TIMEOUT">
<set-payload value="#[{error: 'SLA exceeded'}]" />
</on-error-continue>
</error-handler>
</flow>
<flow name="myPOSTLogic">
<vm:listener config-ref="vm" queueName="postQueue" />
<set-payload value="#[{result: 'Result from my logic'}]" />
</flow>

Resolving mule app property referring to another property

I have multiple endpoints for different vendor's and we are differentiating it based on the userId for similar service operation and routing calls accordingly.
mule-app.properties
userIds=123,124,125
123.service.uri=http://google.com
124.service.url=http://yahoo.com
Can someone tell if there is a way to dynamically refer property using MEL and flowVariable holding userId value?
<flow name="test">
<http:listener config-ref="mylistenerconfig" path="test" doc:name="Request Listener" />
<set-variable variableName="userId" value="#[message.inboundProperties.userId]" />
<set-variable variableName="userServiceUri" value="${flowVars['userId'].service.uri}" />
<logger level="INFO" message="******* serviceUri=#[userServiceUri] ****" />
</flow>
I tried directly referring that value from message.inboundProperties.userId, referring it using a seperate variable - nothing works. Can someone suggest on how to achieve this?
Load the properties files with Spring:
<util:properties id="muleAppProps"
location="classpath*:mule-app.properties" />
Then you can dynamically refer to values in it with:
#[app.registry.muleAppProps[userId + '.service.uri']]
Assuming userId is a flow var that contains a value like "123"

How to Identify and print the inbound properties in mule

Hi i am working with mule and i want to know how to access incoming message inbound properties.
I am trying to get Mule_Originating_Endpoint property but i am unable to print or set it in some variable.
[message.inboundProperties.MULE_ORIGINATING_ENDPOINT]
Use a logger without any message to log all properties and payload type:
<logger level="ERROR" />
Or log the inbound properties map:
<logger level="ERROR" message="#[message.inboundProperties]" />
Should print out something similar to {MULE_ORIGINATING_ENDPOINT=endpoint.polling.1912630717}
You should be able to access that property via #[message.inboundProperties.MULE_ORIGINATING_ENDPOINT]
Or
[message.inboundProperties['MULE_ORIGINATING_ENDPOINT']]
and so on.

Sending a file attachement with Mule

I have seen this answer but it does not show how you use the MEL to send the file in the value field. If you enter some value in there that is the content of the file. I assume you have to move the payload from the file endpoint connector to the attachment value property using MEL.
Also how can you set the content type dynamically
Mule SMTP - send email with attachment
Thanks
Jaco.
You can use the file-to-string-transformer to transform your file to string. You can also use Mule variables, properties, etc for defining the content type or other params. Example:
<file:inbound-endpoint path="/tmp/attachments" responseTimeout="10000"/>
<file:file-to-byte-array-transformer/>
<set-variable variableName="ct" value="test/plain" />
<set-attachment attachmentName="#[message.outboundProperties.filename]" value="#[payload]" contentType="#[flowVars['ct']]"/>
<set-payload value="this is my message"/>
<smtp:outbound-endpoint...

dynamic inbound endpoint no longer available?

In Mule 2, we used to be able to do the create dynamic inbound endpoint using the following:
<quartz:endpoint-polling-job>
<quartz:job-endpoint
address="jms://retry.queue?selector=JMSTimestamp%3C%3D%23[System.currentTimeMillis() - 30000]" />
</quartz:endpoint-polling-job>
In Mule 3, we are getting an error:
The endpoint "jms://retry.queue?selector=JMSTimestamp<=#[System.currentTimeMillis()
- 30000]" is malformed and cannot be parsed... Only Outbound endpoints can be dynamic
It sounds like they no longer let the expression evaluator process the "address" before creating the inbound. Am I correct in my interpretation?
You are correct, this is not supported anymore in 3.3.
You can use a <poll> element to wrap the following script at the beginning of your flow:
<scripting:component>
<scripting:script engine="groovy">
muleContext.client.request('jms://retry.queue?selector=JMSTimestamp%3C%3D'+(System.currentTimeMillis() - 30000), eventContext.timeout)
</scripting:script>
</scripting:component>