Mule not always sending data on outbound HTTP endpoint? - http

I'm fairly new at Mule and trying to get a simple flow to work. The basic idea is to fetch email from an imap box, get the body (text) of the email, put it in a xml / soap message and post to a soap webservice.
I've got my flow set up and it seems to work for about 50% of the mails. In case the message is short, everything works as expected; in case the mail is somewhat longer or containing an attachment, it's working partially.
Here's my flow (only the relevant parts):
<imap:inbound-endpoint host="mailserver" port="143"
user="me" password="mypassword" responseTimeout="10000" doc:name="IMAP"
connector-ref="imap">
<remove-attachment attachmentName="*" />
</imap:inbound-endpoint>
<remove-attachment attachmentName="*" doc:name="Attachment" />
<logger level="INFO" doc:name="Logger" />
<set-variable variableName="mailBody" value="#[payload]"
doc:name="Variable" />
<mulexml:object-to-xml-transformer
doc:name="Object to XML" />
<mulexml:xslt-transformer maxIdleTransformers="2"
maxActiveTransformers="5" xsl-file="submit_to_wfp.xsl" doc:name="XSLT"
ignoreBadInput="true">
<mulexml:context-property key="mailbody"
value="#[mailBody]" />
</mulexml:xslt-transformer>
<object-to-string-transformer doc:name="Object to String"
encoding="UTF-8" ignoreBadInput="true" mimeType="text/xml" />
<message-properties-transformer
doc:name="Message Properties" overwrite="true" encoding="UTF-8"
mimeType="text/xml">
<add-message-property key="content-Type" value="text/xml" />
</message-properties-transformer>
<!-- <file:outbound-endpoint path="/Users/me" outputPattern="xml.txt" responseTimeout="10000"
doc:name="File"/> -->
<http:outbound-endpoint exchange-pattern="request-response"
host="localhost" port="8082" doc:name="HTTP" contentType="text/xml"
path="wfp/services/wfp" encoding="UTF-8" mimeType="text/xml"
responseTimeout="500000" />
The strange thing is that in case I enabled the outbound file endpoint in stead of HTTP, everything works and the flow yields a flawless XML file. In case of the longer message (due to lots of text and / or attachments), Mule fails by not sending any data over the HTTP endpoint (log tells me it's triggered though).
Where should I be looking? Using Mule 3.4CE btw.
Thanks!

Related

Unable to route using spring TCP integration

I have created inbound and outbound adapters for TCP integration and following is the given configuration.
<beans:description>
Uses conversion service and collaborating channel
adapters.
</beans:description>
<context:property-placeholder />
<!-- Client side -->
<gateway id="gw"
service-interface="com.project.configuration.ACDGateway"
default-reply-timeout="20000" default-request-channel="input"
default-reply-channel="gatewayChannel" />
<ip:tcp-connection-factory id="client" type="client"
host="10.90.7.31" port="42027" single-use="false"
serializer="MessageSerializerDeserializerService" deserializer="MessageSerializerDeserializerService"
so-timeout="10000" />
<publish-subscribe-channel id="input" />
<ip:tcp-outbound-channel-adapter id="outAdapter.client"
order="1" channel="input" connection-factory="client" /> <!-- Collaborator -->
<beans:bean id="MessageSerializerDeserializerService"
class="com.project.service.impl.MessageSerializerDeserializerService" />
<ip:tcp-inbound-channel-adapter id="inAdapter.client"
channel="recieve" connection-factory="client" /> <!-- Collaborator -->
<channel id="recieve" />
<header-enricher input-channel="recieve"
output-channel="gatewayChannel">
<header name="replyChannel"
value="gatewayChannel"/>
</header-enricher>
<channel id="gatewayChannel" />
When I run it I message gets send but when response is received at inbound adapter then following exception occurs
no output-channel is available in header.
Then I added one processing element to add that header using header-enricher. After this I am getting
Exception in thread "pool-3-thread-1" java.lang.StackOverflowError
at org.springframework.beans.factory.support.AbstractBeanFactory.transformedBeanName(AbstractBeanFactory.java:1090)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:239)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.integration.support.channel.BeanFactoryChannelResolver.resolveDestination(BeanFactoryChannelResolver.java:88)
at org.springframework.integration.support.channel.BeanFactoryChannelResolver.resolveDestination(BeanFactoryChannelResolver.java:45)
at org.springframework.messaging.core.AbstractDestinationResolvingMessagingTemplate.resolveDestination(AbstractDestinationResolvingMessagingTemplate.java:73)
at org.springframework.messaging.core.AbstractDestinationResolvingMessagingTemplate.send(AbstractDestinationResolvingMessagingTemplate.java:67)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:300)
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractDestinationResolvingMessagingTemplate.send(AbstractDestinationResolvingMessagingTemplate.java:68)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:300)
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115)
Any help is deeply appreciated.
Thanks,
Prashant
You can't just add gatewayChannel as the reply channel header; the replyChannel header is specific to each message and the gatewayChannel is bridged to it for each message. You are bridging the replyChannel to itself; hence the stack overflow.
You can't use channel adapters here; you must use an outbound gateway instead, so the framework can maintain the replyChannel header.
The tcp-client-server-multiplex sample shows one way of how to achieve a similar result using channel adapters, by saving off the replyChannel and correlating the reply, but it's really much simpler to use a gateway instead.

How is Azure ACS authentication secured?

Thanks to Gaurav Mantri for answering my earlier question Azure ACS Set Up in C#.
However can someone explains to me, how the following line is secured?
if (!ClaimsPrincipal.Current.Identity.IsAuthenticated)
The client in the ACS schema is conveniently a man in the middle, he might fail loging into Facebook, for example and this gets relayed to ACS (I'm assuming this portion is secured), but now ACS is telling the client to go back to the relying party about the failure.
How is that last part secured? What stops the client from tampering the ACS message "Fail" to "Success"? How would Asp.Net even knows how to verify signature and decrypt the message?
For that matter what key was it using to encrypt/sign the message exchange? And how would that work in a webfarm/Azure environment?
You specify the key which will be used for message exchange.
When you configure Azure ACS in the management portal, you specify private key which will be used to sign tokens(Certificates and Keys tab).
When you configure web application to use Azure ACS, reference to the certificate to validate signature is added to web.config:
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<authority name="https://xxxxx.accesscontrol.windows.net/">
<keys>
<add thumbprint="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
</keys>
<validIssuers>
<add name="https://xxxxx.accesscontrol.windows.net/" />
</validIssuers>
</authority>
</issuerNameRegistry>
UPDATE
The certificate is passed to the web application by ACS along with signed security token in the X509Certificate element (I've removed namespaces):
<RequestSecurityTokenResponse>
<Lifetime>
<Created>2013-06-19T06:15:16.618Z</Created>
<Expires>2013-06-19T07:15:16.618Z</Expires>
</Lifetime>
<AppliesTo>
<EndpointReference>
<Address>http://xxx.cloudapp.net/</Address>
</EndpointReference>
</AppliesTo>
<RequestedSecurityToken>
<Assertion ID="xxx" IssueInstant="2013-06-19T06:15:16.636Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<Issuer>https://xxx.accesscontrol.windows.net/</Issuer>
<Signature>
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<Reference URI="xxx">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<DigestValue>xxx</ds:DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>xxx</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>xxx</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<Subject>
<NameID>iiiii</NameID>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer" />
</Subject>
<Conditions NotBefore="2013-06-19T06:15:16.618Z" NotOnOrAfter="2013-06-19T07:15:16.618Z">
<AudienceRestriction><Audience>http://xxx.cloudapp.net/</Audience></AudienceRestriction>
</Conditions>
<AttributeStatement>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"><AttributeValue>aaa</AttributeValue></Attribute>
</AttributeStatement>
<AuthnStatement AuthnInstant="2013-06-19T06:15:15.999Z">
<AuthnContext>
<AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
</AuthnContext>
</AuthnStatement>
</Assertion>

How to publish two services with same path but different URLs on Mule 3.2

My need is to publish two services with same path on mule, but different URL's. Like this
https://localhost:8443/etc/app/version1/Service
https://localhost:8443/etc/app/version2/Service
Im using servlet mapping on web.xml
<servlet-mapping>
<servlet-name>muleServlet</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
And tried to use two different connectors since the path attribute doesn't allow me to use "version1/Service" or "version2/Service"
<servlet:connector
name="conectorVersion1"
servletUrl="https://localhost:8443/etc/app/version1/">
</servlet:connector>
<servlet:connector
name="conectorVersion2"
servletUrl="https://localhost:8443/etc/app/version2/">
</servlet:connector>
And finally, the endpoints
<flow
name="FlowVersion1"
processingStrategy="synchronous">
<servlet:inbound-endpoint
connector-ref="conectorVersion1"
path="Service">
<-- processors, jaxws-service, interceptors etc.. -->
</servlet:inbound-endpoint>
</flow>
<flow
name="FlowVersion2"
processingStrategy="synchronous">
<servlet:inbound-endpoint
connector-ref="conectorVersion2"
path="Service">
<-- processors, jaxws-service, interceptors etc.. -->
</servlet:inbound-endpoint>
</flow>
But i got this exception:
[[/etc]] StandardWrapper.Throwable: java.lang.IllegalStateException:
There are at least 2 connectors matching protocol "servlet", so the connector to use must be
specified on the endpoint using the 'connector' property/attribute.
Connectors in your configuration that support "servlet" are: conectorVersion1, conectorVersion2,
Thanks in advance.
I don't think it's valid to declare two servlet connectors: there's only one servlet context so a single connector is enough. Actually, I never declare the Servlet connector, as the default configuration works just fine.
So with only the following configuration:
<flow name="FlowVersion1" processingStrategy="synchronous">
<servlet:inbound-endpoint
path="version1/Service" />
<set-payload value="version 1" />
</flow>
<flow name="FlowVersion2" processingStrategy="synchronous">
<servlet:inbound-endpoint
path="version2/Service" />
<set-payload value="version 2" />
</flow>
I'm able to deploy in a servlet container (Jetty) and I can hit /{context}/app/version1/Service and /{context}/app/version2/Service without problem.

How to convert SOAP request to HTTP GET?

I am trying to construct an REST service query parameters from an incoming SOAP request, and I need GET mode request(doGet:http://localhost:8888/XMPPService/recieveMsg?accessId=admin&accessSeq=admin&accessPwd=admin).
I use property REST_URL_POSTFIX.
My config is:
<target>
<inSequence>
<property name="REST_URL_POSTFIX" value="?accessId=accessId&accessSeq=accessSeq" scope="axis2" />
<send>
<endpoint>
<address uri="http://localhost:8888/XMPPService/recieveMsg" >
</endpoint>
</send>
</inSequence>
<outSequence>
<log level="full" />
<send />
</outSequence>
</target>
<publishWSDL key="XMPPService_wsdl" />
But is also POST mode request, it calls doPost method, not GET mode request.
The receive message is also:
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body>
<p:XMPPService xmlns:p="http://iag.sdp.coship.com/xmpp/">
<accessId>admin</accessId>
<accessSeq>admin</accessSeq>
<accessPwd>admin</accessPwd>
</p:XMPPService>
</soapenv:Body>
</soapenv:Envelope>
I'm not clear on what you are trying. From my understanding, you are trying to construct an REST service query parameters from an incoming SOAP request.
If that is the case use REST_URL_POSTFIX property to set the query parameters.
I have written this post which may help you.

How can I output NLog messages to Visual Studio's Output Window?

I'm trying to send the output to the console (or colouredconsole) ... which I'm hoping would (also?) go to the Visual Studio's Output window for any ASP.NET web site/app/mvc app.
It doesn't by default, but if I change the target to 'file' then it works for sure.
Can NLog output to the Output window for web apps?
You can use this configuration file (nlog.config in the app path):
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="debugger" xsi:type="Debugger" layout="${logger}::${message}"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="debugger" />
</rules>
</nlog>
See also: https://github.com/NLog/NLog/wiki/Debugger-target
-Scott
Adding to Scott P's answer, you can add a filter for when the environment is not "Development" to prevent any slowdowns in Staging/Production etc.
<logger name="*" minlevel="Trace" writeTo="debugger">
<filters defaultAction="Ignore">
<when condition="'${environment:ASPNETCORE_ENVIRONMENT}' == 'Development'" action="Log" />
</filters>
</logger>

Resources