Debugging Mule flows from FunctionalTestCase test - unit-testing

I'm new to Mule ESB and am trying to figure out how I can debug mule flows when running them from a FunctionalTestCase test class.
Using the visual debugger in Mule Studio works fine when running as a Mule Application, but not when running in a Junit test.
Is there any way to debug a flow that is run from a test? As an example, is there any way to step through TestFlow1 in a test method of a FunctionalTestCase if configured as below?
<flow name="TestFlow1" doc:name="TestFlow1">
<vm:inbound-endpoint exchange-pattern="one-way"
doc:name="VM" path="testIn" />
<choice doc:name="Choice">
<when expression="payload == 'Foo'">
<logger message="Got Foo!" level="INFO" doc:name="Logger"/>
<vm:outbound-endpoint exchange-pattern="one-way" path="testOut0" doc:name="VM"/>
</when>
<otherwise>
<logger message="Got [#payload]!" level="INFO" doc:name="Logger"/>
<vm:outbound-endpoint exchange-pattern="one-way" path="testOut1" doc:name="VM"/>
</otherwise>
</choice>
</flow>
<flow name="TestFlow2" doc:name="TestFlow2">
<vm:inbound-endpoint exchange-pattern="one-way" path="testOut0" doc:name="VM"/>
<test:component />
</flow>
<flow name="TestFlow3" doc:name="TestFlow3">
<vm:inbound-endpoint exchange-pattern="one-way" path="testOut1" doc:name="VM"/>
<test:component />
</flow>

Unfortunately, this is a known issue.
Please upvote the issue and watch it.

Related

Publishing WCF Service to external IIS server with other applications

It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
I understand this is a very common and ambiguous error, and that there's a ton of questions about it already, but none of them have solved my issue. So I'll try to be more thorough and specific:
It's a WCFService that I'm publishing to an external IIS server via FTP. I get this error when I try to view the site in my browser at https://www.domain.com/correctdirectory/JobsService.svc
This is my Web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=*token*" requirePermission="false" />
</configSections>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
<customErrors mode="Off"></customErrors>
<httpModules>
</httpModules>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBindingConfiguration">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WcfServiceAPI.Services.Validation.ValidationService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBindingConfiguration" contract="WcfServiceAPI.Services.Validation.IValidationService"/>
</service>
<service name="WcfServiceAPI.Services.Jobs.JobsService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBindingConfiguration" contract="WcfServiceAPI.Services.Jobs.IJobsService"/>
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="ApplicationInsightsWebTracking" />
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
</modules>
<directoryBrowse enabled="true" />
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
<entityFramework>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
And here's the things I've made sure:
Project is cleaned in both Debug and Release mode.
Project is built in Debug mode.
The Web.config in the IIS root does not conflict with this Web.config. It basically just enforces https, and handles different filetype requests.
The service is hosted as an application on the IIS (not just a virtual directory)
It works fine when I publish it to a server on the internal network, that has no other websites or services.
I know there's a lot of other applications on the server I'm trying to publish to, but my application is at the root level, so that shouldn't matter, right?
If it matters, I also know that at least one of those applications is an ASMX web service. The owner of the server doesn't know the problem either.
I've also tried downgrading my project to .NET 4.0, since I know his ASMX service runs on that.
Any ideas?
I had already tried moving the directory to the root of the virtual directory, via an external FTP Client (Total Commander), without success, but when I used Visual Studio's built in publishing tool and made sure to have an empty Site Path, it finally started working.
I'm still not sure why that is, but I guess I'll do some research on it another time, when I get time. If anyone knows, comments would be very much appreciated!

Viewing ELMAH logs through the web interface on a Live application [duplicate]

This question already has answers here:
Can't access /elmah on production server with Elmah MVC?
(2 answers)
Closed 5 years ago.
I have included elmah.mvc into an Asp.Net MVC application for logging exceptions and custom error logs. It is working fully as intended and I can view the logs within my ELMAH_Error table using a SQL Server, and as well from the web interface through local host URL(http://localhost:20086/elmah).
My question is: How, if possible, can I view my logs through the web interface on a live site and not "http://localhost:20086/elmah". I want to be able to view the Logging information when necessary from any computer. I have implemented Roles and Authentication, so I should be able to go to the correct URL, login with the appropriate credentials, then view the logs.... right?
Is this possible??
No problem. You can use ASP.NET authentication to secure your logs. Basically you want something like this:
<location path="elmah.axd">
<system.web>
<httpHandlers>
<add verb="POST,GET,HEAD"
path="elmah.axd"
type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<authorization>
<allow roles="admin" />
<deny users="*" />
</authorization>
</system.web>
<system.webServer>
<handlers>
<add name="ELMAH"
verb="POST,GET,HEAD"
path="elmah.axd"
type="Elmah.ErrorLogPageFactory, Elmah"
preCondition="integratedMode" />
</handlers>
</system.webServer>
</location>
There's some more details in this ELMAH Tutorial.
It looks like you're using the Elmah.MVC package. With this package you have another option:
<add key="elmah.mvc.requiresAuthentication" value="true" />
<add key="elmah.mvc.allowedRoles" value="admin" />

How to configure the EHCache with CXF in Mule

I have a SOAP webservice as follow :-
<spring:bean id="cacheManager" name="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
<spring:bean id="cache" name="cache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<spring:property name="cacheManager" ref="cacheManager"/>
<spring:property name="cacheName" value="dbCache"/>
<spring:property name="maxElementsInMemory" value="10000"/>
<spring:property name="eternal" value="false"/>
<spring:property name="timeToIdle" value="${timeToIdle}"/>
<spring:property name="timeToLive" value="${timeToLive}"/>
<spring:property name="overflowToDisk" value="true"/>
<spring:property name="maxElementsOnDisk" value="10000000"/>
<spring:property name="diskPersistent" value="false"/>
<spring:property name="diskExpiryThreadIntervalSeconds" value="5"/>
<spring:property name="memoryStoreEvictionPolicy" value="LRU"/>
<!-- Cache Expiry -->
</spring:bean>
</spring:beans>
<ee:object-store-caching-strategy name="cachingStrategy" doc:name="cachingStrategy">
<custom-object-store class="com.anirban.EHCatche.EhcacheObjectStore">
<spring:property name="cache" ref="cache"/>
</custom-object-store>
</ee:object-store-caching-strategy>
<!-- Catch Strategy ends -->
<flow name="ServiceFlow" doc:name="ServiceFlow">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" path="mainData" doc:name="HTTP" />
<ee:cache doc:name="Cache" cachingStrategy-ref="cachingStrategy">
<cxf:jaxws-service serviceClass="com.test.services.schema.maindata.v1.MainData" doc:name="SOAP"/>
<component class="com.test.services.schema.maindata.v1.Impl.MainDataImpl" doc:name="JavaMain_ServiceImpl"/>
</ee:cache>
</flow>
Now as you can see .. I have wrapped the cxf:jaxws-service and component class under ee:cache block ..
The Webservice fetch a set of Data from DB
My main intention is if I trigger the webservice ,it will fetch the Data from DB from the first time and then for the same request it will fetch from cache for a particular time ... In between if I trigger the service with different request it will again fetch data from DB for the first time for that request and then retrieve from the cache for the subsequent same request ..
It will hold the data in cache for a particular time ..
Now the issue is If I trigger the service .. it's always fetching the Data from DB and it's not holding any data in cache for the same request ..
Every time I hit the service it hits the Database directly and the data is not fetched from cache for the same request ..
Please help .. how to configure the cache with CXF in Mule
Break your service flow in two, using a VM endpoint and serializing both the request and response to string. This will make the event cacheable.
<flow name="ServiceFlow" doc:name="ServiceFlow">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" path="mainData" doc:name="HTTP" />
<object-to-string-transformer />
<ee:cache doc:name="Cache" cachingStrategy-ref="cachingStrategy">
<vm:outbound-endpoint path="cxf.service" exchange-pattern="request-response" />
<object-to-string-transformer />
</ee:cache>
</flow>
<flow name="CXFFlow" doc:name="CXFFlow">
<vm:inbound-endpoint path="cxf.service" exchange-pattern="request-response" />
<cxf:jaxws-service serviceClass="com.test.services.schema.maindata.v1.MainData" doc:name="SOAP"/>
<component class="com.test.services.schema.maindata.v1.Impl.MainDataImpl" doc:name="JavaMain_ServiceImpl"/>
</flow>
So, the final solution is as David suggested, by breaking the flow into two and also using <object-to-string-transformer /> for serializing both the request and response which is very important for a Cache to perform

WCF ERROR- (413) Request Entity Too Large

I have 2 WCF service working together. One is Class Library and another one in webservice.
Its working fine until now. But if i try to send large amount of data it throw me 413 error...
An exception was thrown: The remote server returned an error: (413) Request Entity Too Large.
Below is web.config file-
For Class Library-
<add key="SMTP" value ="dummy"/>
<add key="BookingEmailFrom" value ="dummy"/>
<add key="BookingEmailToWBD" value ="dummy"/>
</appSettings>
<connectionStrings/>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<!--
The <authentication> section enables configuration
of the security authentication mode used by
ASP.NET to identify an incoming user.
-->
<authentication mode="Windows"/>
<!--
The <customErrors> section enables configuration
of what to do if/when an unhandled error occurs
during the execution of a request. Specifically,
it enables developers to configure html error pages
to be displayed in place of a error stack trace.
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
-->
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
</system.web>
<!--
The system.webServer section is required for running ASP.NET AJAX under Internet
Information Services 7.0. It is not necessary for previous version of IIS.
-->
<system.serviceModel>
<services>
<service name="JSONWebService.Service1" behaviorConfiguration="JSONWebService.Service1Behavior">
<endpoint address="../Service1.svc" binding="webHttpBinding" contract="JSONWebService.IService1"
behaviorConfiguration="webBehaviour"/>
For web service client-
<?xml version="1.0"?>
<configuration>
<!--
Note: As an alternative to hand editing this file you can use the
web admin tool to configure settings for your application. Use
the Website->Asp.Net Configuration option in Visual Studio.
A full list of settings and comments can be found in
machine.config.comments usually located in
\Windows\Microsoft.Net\Framework\vx.x\Config
-->
<configSections>
</configSections>
<appSettings>
<add key="ConnectionString" value="Server=dummy;uid=sa;pwd=dummy;database=dummy"/>
---------------------- -->
section enables configuration
of the security authentication mode used by
ASP.NET to identify an incoming user.
-->
section enables configuration
of what to do if/when an unhandled error occurs
during the execution of a request. Specifically,
it enables developers to configure html error pages
to be displayed in place of a error stack trace.
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
-->
<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<endpoint address="basic" binding="webHttpBinding" contract="JSONWebService.IService1"
behaviorConfiguration="webBehaviour"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior" >
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before
deployment -->
</bindings>
</system.serviceModel>
</configuration>
Any help would be really appreciated.
Thanks
You are encountering a WCF default limit on the message size. To raise the limit, use the maxReceivedMessageSize attribute in your web.config file (server side).
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding maxReceivedMessageSize="10000000">
</basicHttpBinding>
</bindings>
</system.serviceModel>
This is probably really late, but for anyone else that is also stuck.
The initial problem is solved by what BilalAlam described (increase the maxRecievedMessageSize) but your issue is the bindings need to be tied to the endpoint via the bindingConfiguration in the endpoint and the name in the binding.
Example
<bindings>
<webHttpBinding>
<binding maxReceivedMessageSize="2147483647" name="NAMETOTIEENDPOINT">
<readerQuotas maxStringContentLength="2000000"/>
</binding>
</webHttpBinding>
</bindings>
<services>
<service>
<endpoint address="basic" bindingConfiguration="NAMETOTIEENDPOINT" binding="webHttpBinding" contract="JSONWebService.IService1" />
</service>
</services>

Mule routing Web service using choice flow control

I'm trying to use choice flow control to route SOAP web service, it depends on payload to change to matching web-service. Here is my flow
<flow name="ProxyServiceFlow1" doc:name="ProxyServiceFlow1">
<http:inbound-endpoint exchange-pattern="request-response"
address="http://localhost:8081/hrManagerServiceProxy" doc:name="HTTP" />
<set-variable variableName="clientType"
value="#[message.inboundProperties['http.query.params']['clientType']]"
doc:name="Set clientType" />
<choice doc:name="Choice">
<when expression="#[clientType == 'unsecure']">
<cxf:proxy-service namespace="http://service.freetalk.viettel.com/"
service="RegisterServiceService" payload="body" wsdlLocation="unsecure.wsdl"
enableMuleSoapHeaders="false" doc:name="SOAP" />
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:8081/HR/hrManagerService" doc:name="HTTP"/>
</when>
<otherwise>
<cxf:proxy-service namespace="http://service.freetalk.viettel.com/"
service="RegisterServiceService" payload="body" wsdlLocation="unsecure2.wsdl"
enableMuleSoapHeaders="false" doc:name="SOAP" />
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:8081/HR/hrManagerService" doc:name="HTTP"/>
</otherwise>
</choice>
</flow>
It's just my thought, because I google many times but still get no result. Someone please give me some advises.
Its not the cxf:proxy-service that needs to be used along with the HTTP Outbound.
It should be cxf:proxy-client
Try using cxf:proxy-client with your http:outbound-endpoint.
<choice doc:name="Choice">
<when expression="#[clientType == 'unsecure']">
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:8081/HR/hrManagerService" doc:name="HTTP">
<cxf:proxy-client payload="body" enableMuleSoapHeaders="true">
</cxf:proxy-client>
</http:outbound-endpoint>
</when>
<otherwise>
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:8081/HR/hrManagerService" doc:name="HTTP">
<cxf:proxy-client payload="body" enableMuleSoapHeaders="true">
</cxf:proxy-client>
</http:outbound-endpoint>
</otherwise>
</choice>
Hope this helps.