I want to get a queue:
<jms:inbound-endpoint connector-ref="jmsConnector" queue="queue.dev" >
<jms:selector expression="JMSCorrelationID='353'"/>
</jms:inbound-endpoint>
It works but I want to use an expression in the selector:
<jms:inbound-endpoint connector-ref="jmsConnector" queue="queue.dev" >
<jms:selector expression="JMSCorrelationID='#[header:OUTBOUND:codeReport]'"/>
</jms:inbound-endpoint>
It's no working.
This doesn't make sense: you are trying to use an outbound property in an inbound endpoint. This can not work.
Where is the value for codeReport supposed to come from? If a properties file then use ${codeReport}.
EDIT: It turns out that, based on the OP's comments, the solution is to use a requester on the JMS queue, not an inbound endpoint. The following code demonstrates requesting messages until the queue is empty and returning them in a java.util.List:
<scripting:component>
<scripting:script engine="groovy"><![CDATA[
def jmsMessages = []
for (def muleMessage = muleContext.client.request("jms://out.queue.dev?selector=JMSCorrelationID%3D'"+ message.getInboundProperty('codeReport') +"'", -1L);
muleMessage != null;) {
[] << muleMessage.payload
}
jmsMessages
]]></scripting:script>
</scripting:component>
Related
Having a requirment to filter a message if some session variable is false or true
flow.xml
<spring:beans>
<spring:bean id="serviceBean" class="com.uidai.ServiceBean"/>
</spring:beans>
<flow name="messagefilterFlow1" doc:name="messagefilterFlow1">
<file:inbound-endpoint responseTimeout="10000" doc:name="File" path="D:/sample" />
<invoke object-ref="serviceBean" method="enrichFilter" doc:name="Invoke" methodArguments="#[sessionVars],#[message]"/>
<logger level="INFO" message="#[sessionVars['filter']]" doc:name="Logger"/>
<!--<message-property-filter pattern="#[sessionVars['filter']]=true" caseSensitive="true" doc:name="Message Property"/>-->
<expression-filter expression="#[sessionVars['filter']]" doc:name="Expression"/>
<file:outbound-endpoint responseTimeout="10000" doc:name="File" path="D:/sample2"/>
</flow>
Service bean method
public void enrichFilter(MessagePropertyMapContext mapContext, MessageContext messageContext){
mapContext.put("filter", false);
System.out.println("mapContext" + mapContext);
System.out.println("message Context:::" + messageContext);
}
Reading a file from inbound and setting a session variable in spring bean method. Wanted to filter the message on basis of filter value so that if filter value is true outbound file is not written and message is filtered. Even if filter value is true or false a lock is hold on file by inbound endpoint and processing stops.
I can't reproduce on 3.5.2.
I suggest you to put a breakpoint in ExpressionFilter.class in the method accept() to realize why the line return muleContext.getExpressionManager().evaluateBoolean(expr, message, nullReturnsTrue, !nullReturnsTrue); is always returning false for you.
Another suggestion to leverage the lesser amount of magic possible is to prepend return to your filter expression and/or implement a java filter by implementing the Filter interfance and then using the custom-filter element.
im having trouble getting message inbound properties, somehow its coming as null, here is the code:
<scripting:transformer name="noopLoggingTransformer">
<scripting:script engine="groovy">
log.info "${message.getInboundProperty('user-agent')}"
muleContext.client.dispatch('vm://log-request.in', message)
message
</scripting:script>
</scripting:transformer>
<pattern:web-service-proxy name="service" transformer-refs="noopLoggingTransformer" inboundAddress="${serverName}/services/Logradouros/LogradouroServico" outboundAddress="${targetServer}/servicos/v2/service.svc" wsdlFile="LogradouroServicos.wsdl">
</pattern:web-service-proxy>
<jdbc-ee:postgresql-data-source name="WSA" user="${database.user}" password="${database.pass}" url="${database.url}" transactionIsolation="UNSPECIFIED" doc:name="PostgreSQL Data Source">
</jdbc-ee:postgresql-data-source>
<jdbc-ee:connector name="jdbcConnector" dataSource-ref="WSA" validateConnections="false" transactionPerMessage="true" queryTimeout="10" pollingFrequency="10000" doc:name="JDBC">
<jdbc-ee:query key="wsadb" value="insert into inbound_messages (payload, timestamp, agent, ip_from, endpoint, soap_operation) values ('', now(), #[groovy: return message.getInboundProperty('user-agent').toString()], #[groovy: return message.getInboundProperty('MULE_REMOTE_CLIENT_ADDRESS').toString()], #[groovy: return message.getInboundProperty('http.request').toString()], '');"></jdbc-ee:query>
</jdbc-ee:connector>
<flow name="log-request" doc:name="log-request">
<vm:inbound-endpoint path="log-request.in" />
<logger message="#[message.inboundProperties['user-agent']]" level="INFO" doc:name="Logger"/>
<jdbc-ee:outbound-endpoint exchange-pattern="one-way" queryKey="wsadb" responseTimeout="10000" queryTimeout="-1" connector-ref="jdbcConnector" doc:name="Persist raw message" />
</flow>
What it prints out is "null" and i dont know how to make it print the property from message...
No need to use Groovy:
<logger message="#[message.inboundProperties['user-agent']]" level="INFO" doc:name="Logger"/>
But your bigger issue is that you are not propagating the inbound properties to the outbound scope prior to dispatching to vm://log-request.in.
You need to propagate the properties you want to carry forward:
<scripting:transformer name="noopLoggingTransformer">
<scripting:script engine="groovy">
def props = [:]
props['User-Agent'] = message.getProperty('User-Agent', org.mule.api.transport.PropertyScope.INBOUND)
muleContext.client.dispatch('vm://log-request.in', payload, props)
message
</scripting:script>
</scripting:transformer>
Of course, you can iterate the inbound property names to copy them all.
Property name is User-Agent and as David pointed out, #message.inboundProperties['User-Agent']] is the MEL way to get it.
Did you make sure User-Agent property is set on the mule message when you're trying to access it. It's not always there
Remember inbound properties are not propagated unless you copy property manually like by
<copy-properties propertyName="*"/>
I was trying to develop a Functional Test case for my mule configuration. Here is the code:
protected String getConfigResources() {
// TODO Auto-generated method stub
return "src/test/resources/employee-get-functionalTestCase-config.xml";
}
#Test
public void testMessage() throws Exception {
MuleClient client = muleContext.getClient();
client.dispatch("vm://in", "70009", null);
MuleMessage result = client.request("vm://out", 60000);
Assert.assertNotNull("Response payload was null", result);
Assert.assertNull(result.getExceptionPayload());
Assert.assertFalse(result.getPayload() instanceof NullPayload);
& here is the context of my XMl file:
<spring:beans>
<context:property-placeholder location="classpath:mule-app.properties"/>
</spring:beans>
<flow name="testFlow">
<vm:inbound-endpoint path="in"/>
<logger message="in functional-test-config.xml (v4)" level="INFO" doc:name="Logger"/>
<set-payload value="70010" doc:name="Use fixed employeeId 70010"/>
<vm:outbound-endpoint exchange-pattern="request-response" path="employee-profile-get" doc:name="VM"/>
<logger message="after employee-profile-get; payload: #[payload]" level="INFO" doc:name="Logger"/>
<vm:outbound-endpoint path="out"/>
</flow>
However when I execute this code, I get the following error:
org.mule.api.transport.NoReceiverForEndpointException: There is no receiver registered on connector "connector.VM.mule.default" for endpointUri vm://employee-profile-get
Where do I register the vm endpoint?
You must have an inbound endpoint for every exchange-pattern="request-response" vm endpoint .
When the application is run in your mule studio you may not get any error(at compile time ) but when the message is passed through the flow you will get an error of the above mentioned sort .
This is because VM is an in-memory queue ,where once you put a message, there should be a receiver to pick the message thus when not there this error pops and it is only for the exchange-pattern="request-response" because the flow from where you put the message(outbound endpoint with request-response) will wait for a response from the vm endpoint "employee-profile-get" .
To depict the same error replace the with a localhost http endpoint and try invoking the http endpoint .
To avoid this create another flow with inbound endpoint as vm with path="employee-profile-get" and return a string using set payload component .Then your test case would work.
Regards,
Naveen Raj
I want to post message to exchange with routing key. The message witch I want to send is from payload, but routing key I'm seting in message in inbound properties, and then I set:
routingKey="#[message.inboundProperties.routingKey]" but it not working
<flow name="ExportToFk" doc:name="ExportToFk">
<vm:inbound-endpoint exchange-pattern="one-way" path="rabbitSenderVM" doc:name="SendToRabbit"/>
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[import org.mule.api.transport.PropertyScope
def xml = payload.xml
def routingKey = payload.routing
println "XML: $xml"
println "ROUTINGKEY: $routingKey"
message.setProperty('routingKey', routingKey, PropertyScope.INBOUND)
return xml]]></scripting:script>
</scripting:component>
<amqp:outbound-endpoint exchangeName="${amqp.exchange}" routingKey="#[message.inboundProperties.routingKey]" responseTimeout="10000" connector-ref="AMQP_Connector" doc:name="AMQP"/>
</flow>
This is a known issue, which is currently under development: https://github.com/mulesoft/mule-transport-amqp/issues/24
I'm using Mule Studio (Mule 3.2.1CE) to configure a proxy service which simply calls a remote web service. Everything works fine with calling and getting the proper response (using soapUI). I want to log SOAP message received within the ESB. I'm getting a DepthXMLStreamReader message as expected by the CXF component but I'm facing an odd behavior when I use XMLStreamReader object's next() method. Here is the code I use:
public Object onCall(MuleEventContext context) throws Exception {
MuleMessage message = context.getMessage();
DepthXMLStreamReader streamReader = new DepthXMLStreamReader((XMLStreamReader) message.getPayload());
while(streamReader.hasNext()){
streamReader.next();
if(streamReader.getEventType() == XMLStreamReader.START_ELEMENT)
{
System.out.println(streamReader.getLocalName());
}
}
return context.getMessageAsString();
The above code works and prints XML elements but I get the following error afterwards:
org.apache.cxf.interceptor.Fault: Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=..., connector=HttpConnector
...
Caused by: org.mule.transport.http.HttpResponseException: Internal Server Error, code: 500
I tried using StaxUtils.nextEvent and StaxUtils.toNextElement, but no difference in result. I wonder why parsing XML by next() method affects mule context. If I use System.out.println(context.getMessageAsString()); before the return statement it prints "[Messaage could not be converted to string]" but it works before while statement in the above code.
Here is my mule config:
<flow name="wsFlow1" doc:name="wsFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8090" contentType="text/xml" doc:name="HTTP"/>
<cxf:proxy-service bindingId="..." namespace="http://..." service="..." payload="body" wsdlLocation="..." enableMuleSoapHeaders="false" doc:name="SOAP"/>
<component class="mule.ws.SoapLogging" doc:name="Java"/>
<http:outbound-endpoint exchange-pattern="request-response" address="http://..." contentType="text/xml" doc:name="HTTP"/>
</flow>
Thanks
I don't think this is related to MuleEventContext.
The in-flight payload is a XMLStreamReader. You consume this XMLStreamReader in your component then try to return a String representation of it, which is not possible anymore because you've consumed it.
Try the following in your component:
Serialize the XMLStreamReader to a String
Log this String or part thereof
Return this String from the component.