How do I implement IF in mulesoft - if-statement

I want to make a decision in a Mulesoft flow, and have looked at the Choice Flow Control. My problem, is that I want to do something if the condition is true, and nothing if it is false, something like:
if (condition == true)
do some work
or, in probably incorrect xml:
<choice doc:name="call a subflow if the test is true">
<when expression="#[flowVars.someVariable == True]">
<flow-ref name="doSomething" doc:name="do another thing"/>
</when>
</choice>
no else clause, and no default flow. How is this implemented in a Mulesoft flow?
I could cheat, and throw a logging call into a default flow, but I would prefer not to.

Unfortunately there is no simple 'if' processor in Mule. Choice with a dummy otherwise route or filters are the way to go for now.
There is a good discussion on this here: https://www.mulesoft.org/jira/browse/MULE-6129. THis has further links to possible enhancements such as an if/detour router.
Mule 4 UPDATE
In mule 4, you can now define a choice router with no need for an otherwise route. And filters no longer exist

You can get close with an async or enricher scope and a filter. It's not as elegant as a true <if> processor (or a standalone <when>), but you don't need a wasted <logger> to satisfy the <otherwise>.
Async method (when you don't need the payload afterwards):
<async>
<expression-filter expression="#[payload == 'red']" />
<logger category="com.box.integration.experiment" message="That's my favorite color!" level="INFO" />
</async>
Enricher method (when you do):
<enricher target="#[variable:colorName]">
<processor-chain>
<expression-filter expression="#[payload == 'red']" />
<set-payload value="vermillion" />
</processor-chain>
</enricher>

In a mule flow, when using a message router without setting a Processor in the section, and the MuleMessage does not match any of the clauses, an exception is thrown. To achieve a conditional behavior currently mule requires to set a dummy processor on the otherwise clause. One usability improvement would be letting the message be processed by the remaining part of the flow if no clause was matched and no processor provided
https://www.mulesoft.org/jira/browse/MULE-6129

Related

How to unit test Spring Integration flow - specifically http outbound gateway

I wonder if anyone can help - this has been driving me crazy for days!
I have a fairly simple Spring Integration file that I'd like to unit test. The SI uses an http outbound gateway, and I specifically want to unit test rather than integration test - I do not want to provide a mock http server using something like Spark or MockRestServiceServer.
My SI config looks like this:
<int:channel id="modifiedAttractionChannel" datatype="u.o.n.p.i.a.s.AttractionUuid">
<int:interceptors>
<int:wire-tap channel="attractionModifiedChannelLogging"/>
</int:interceptors>
</int:channel>
<int-http:outbound-gateway
id="serviceGateway"
request-channel="modifiedAttractionChannel"
url="/attractions/{uuid}"
http-method="GET"
expected-response-type="u.o.n.p.i.a.v.m.Attraction"
charset="UTF-8"
reply-timeout="${vader.reply.timeout}"
request-factory="clientHttpRequestFactory"
reply-channel="vaderAttractionChannel">
<int-http:uri-variable name="uuid" expression="headers['#{T(u.o.n.p.i.a.s.AttractionsImportInitializer).HEADER_UUID}'].value" />
</int-http:outbound-gateway>
<int:channel id="attractionChannel" datatype="u.o.n.p.i.a.v.m.Attraction">
<int:interceptors>
<int:wire-tap channel="vaderAttractionChannelLogging"/>
</int:interceptors>
</int:channel>
<int:logging-channel-adapter
id="attractionModifiedChannelLogging"
expression="'attractionModifiedChannel: header=' + headers['#{T(u.o.n.p.i.a.s.AttractionsImportInitializer).HEADER_UUID}'].value + ', payload=' + payload"
level="INFO" />
<int:logging-channel-adapter
id="vaderAttractionChannelLogging"
expression="'attractionModifiedChannel: header=' + headers['#{T(u.o.n.p.i.a.s.AttractionsImportInitializer).HEADER_UUID}'].value + ', payload=' + payload"
level="INFO" />
I have written a unit test that wires up a basic spring context and am able to get the modifiedAttractionChannel and send an appropriately built Message with an AttractionUuid payload and header value.
My unit test can assert that the log message written to attractionModifiedChannelLogging is as I expect it (I created the AttractionUuid and Message, so I know the payload and header values)
What I now need to do is assert the value written to the vaderAttractionChannelLogging wiretap. IE. I need to assert a message with a given header value - no problem, I created the header value as part of the test - but also the payload.
In this case the payload is the output of the outbound gateway. Given that this is a unit test and I don't want any dependency on anything else, I have provided a mock ClientHttpRequestFactory which in turn provides a mock ClientHttpResponse via a mock ClientHttpRequest
This works great in that I can control the response body that the outbound gateway would otherwise receive. However, the RestTemplate calls its HttpRequestExecutingMessageHandler in order to convert the response body into an object via the MessageConverters
Whilst this works in respect of the execution of the SI flow, it means the instance of Attraction that is on the reply-channel vaderAttractionChannel is not in control of the test; and therefore I cannot make any assertions about it in respect of what gets logged on the vaderAttractionChannelLogging wiretap.
I think one way of addressing this is to be able to wire in a mock or stub MessageConvertor instead of the standard set that returns a fixed Attraction instance. But I can't for the life of me work out how to!
Note: The scenario above is a much simplified version of what I'm actually trying to do. I'm not really trying to write unit tests around logged values! I need to test the overall flow of my SI, and being able to control the instance of the Attraction that the outbound gateway returns is very much key to that.
Any help with this would be very much appreciated;
Cheers
Nathan
It's not clear what your issue is; "...the RestTemplate calls its HttpRequestExecutingMessageHandler..." - it's actually the other way around. If you really want to unit test the flow, you should provide a normal result from the mock that will be converted by the standard converters. If you really want to mock the conversion too, use the message-converters attribute.

AngularJs : triggering an event to simulate user action when unit testing a directive

I have seen that in order to simulate user action on the DOM generated by a directive, there are two approaches, both trigering an event:
How to trigger ng-change in directive test in AngularJS
The first approach uses jquery and the second one a function called browserTrigger defined in angular-scenario.js. The second one is supposed to be better as jquery would have a bug on event triggering (which I believe, I am not arguing :) ).
Using the angular-scenario means e2e testing for me. but I have seen egghead video and he seems to do unit testing. How is this possible ?
I guess he just copied the function ?
I think I am going to test directives as e2e tests, it makes more sense as unit test is more fore pure functions.
Well, I just found that browserTrigger is something internal not supposed to be used directly : https://github.com/angular/angular.js/issues/5178
Thanks!
As of 1.3.15 you can use triggerHandler to trigger a event as shown below,
it('should click the element',function(){
element.triggerHandler('click') ;
expect($scope.clicked).toBe(true);
});
simple and it works, example, in unit test env:
spyOn(self, 'updateTransactionPrice');
var el = compile('<form name="form" latest novalidate json-schema="main.schema_discount" json-schema-model="main._data"><input type="text" ng-model="main._data.reverse_discount" ng-class="{ \'form-invalid\': form.reverse_discount.$invalid }" ng-change="main.transactionPrice(form);" name="reverse_discount" class="form-control-basic" placeholder="" ng-disabled="!main.selectedProduct.total_price"></form>')(scope);
el.find('input').triggerHandler('change');
expect(self.updateTransactionPrice).toHaveBeenCalled();

ServiceStack View/Template control when exception occurs?

I added some razor views and use a request filter to check browser version and switch between desktop and mobile views. But when a exception occurs, especially validation exception, it seems the framework return immediately and never touched any custom code. I tried request/response filter, service exception handler, none got executed. It seems to ignore view/template specified in URL query string as well.
Is there way to set view/template during exception? Thanks
The first question is how are you handling validation exceptions?
the most common procedure to perform this kind of task is by using the fluentValidation, the response can return a message for more than one validation at the time, all the validations are against DTOs and you´ll need to implement an AbstractValidator, the first thing you need to do is to register the validators that belons to your applciation like the following:
Plugins.Add(new ValidationFeature());
container.RegisterValidators(typeof(CredentialsAuthValidator).Assembly);
I´m valdiating in this case that the Auth username and password should not be Empty, take a look to the following example:
public class CredentialsAuthValidator : AbstractValidator<ServiceStack.ServiceInterface.Auth.Auth>
{
public CredentialsAuthValidator()
{
RuleSet(ApplyTo.Post, () =>
{
RuleFor(x => x.UserName).NotNull().WithMessage("Username Required").When(x => x.provider == "Credentials");
RuleFor(x => x.Password).NotNull().WithMessage("Password Required").When(x => x.provider == "Credentials");
}
);
}
}
if some of the validation fails you´ll get a responseStatus from the server with the errorCode and the messages.
You can configure a custom httpHandlers in the case you would like to have a handler for specific scenarios or a global error handler, this can be performed in your serviceHost configuration, something like this:
GlobalHtmlErrorHttpHandler = new RazorHandler("/views/error"),
CustomHttpHandlers =
{
{HttpStatusCode.NotFound, new RazorHandler("/views/notfound")},
{HttpStatusCode.Unauthorized, new RazorHandler("/views/login")},
{HttpStatusCode.Forbidden, new RazorHandler("/views/forbidden")},
}
Thanks for the help from Pedro, and especially mythz from ServiceStack. Now I think I start to understand my problems.
ServiceStack is first and foremost a service framework and Razor is just another view over the same result. But I was a little hesitate with a full on client side solution and keep falling back to familiar territory and looking for some kind of code-behind feature. That seems to be the root of lots of my struggles.
After some more research, this is what I come up so far.
ServiceStack for service, of course.
Razor view to build the basic layout and the main page for each major feature
Build a json script tag from model to hold initial data, like in SS's HTML Report
Jquery and Eldarion ajax for all subsequent in-page processing
Handlebars for javascript templating
Verifyjs for validation
So far look promising. Pages are lot smaller in size, running super smooth and mostly pure json flying over the wire.
Still a work in progress, all suggestions welcome.
ViewSwitch works when I changed to use Request Filter instead. Got the correct layout and all the references, etc. Although they have to share the same error page, but there's not much formatting in there.

Webservice test isolation - but when to verify the webservice itself?

I am isolating my webservice-related tests from the actual webservices with Stubs.
How do you/should i incorporate tests to ensure that my crafted responses match the actual webservice ones (i don't have control over it)?
I don't want to know how to do it, but when and where?
Should i create a testsuite-testsuite for testdata testing?...
I would use something like this excellent tool
Storm
If you can, install the service in a small, completely controlled environment. Drawback: You must find a way to be notified when a new version is rolled out.
If that's not possible, write a test that calls the real service and checks for vital points (do I get a response? Are all parts there and where I expect them? Can I parse the result?)
Avoid things like checking timestamps, result size, etc., that is things that can and do change all the time.
You can test the possible failures using EasyMock as follows:
public void testDisplayProductsWhenWebServiceThrowsRemoteLookupException() {
...
EasyMock.expect(mockWebService.getProducts(category)).andThrow(new RemoteLookupException());
...
someServiceOrController.someMethodThatUsesMockWebService(...);
}
Repeat for all possible failure scenarios. The other solution is to implement a dummy SEI yourself. Using JAX-WS, you can trivially annotate a java class that generates an interface consistent with the client you consume. All of the methods can just return dummy data. You can then deploy the services on your own server and point your test environment at the dummy location.
Perhaps more importantly than any of the crap I've said so far, you can take the advice of the authors of The Pragmatic Programmer and program with assertions. That is, given that you must inevitably make certain assumptions about the web service you consume given that you have no control over it's implementation, you can add code such as:
if(resultOfWebService == null || resultOfWebService.getId() == null)
throw new AssertionError("WebService violated contract by doing xyz: result => " + resultOfWebServivce);
That way, if your assumptions don't hold, you'll at least find out about it instead of potentially silently fail!
You can also turn on schema validations and protocol validations to ensure that the service is operating according to spec.

Using Spring to inject EasyMock mocks causes ClassCastException

I am trying to get Spring to inject EasyMock mocks in my unit tests.
In my applicationContext.xml, I have this:
<bean id="mockService" class="org.easymock.EasyMock" factory-method="createMock" name="MockService">
<constructor-arg index="0" value="my.project.Service"/>
</bean>
In my unit test I have this:
#Autowired
#Qualifier("mockService")
private Service service;
public void testGetFoo() {
Foo foo = new Foo();
expect(service.findFoo()).andReturn(foo);
replay(service); // <-- This is line 45, which causes the exception
// Assertions go here...
}
When I try to run my test, I get this stack trace:
java.lang.ClassCastException: org.springframework.aop.framework.JdkDynamicAopProxy
at org.easymock.EasyMock.getControl(EasyMock.java:1330)
at org.easymock.EasyMock.replay(EasyMock.java:1279)
at TestFooBar.testGetFoo(TestVodServiceLocator.java:45)
I am quite new to both Spring and EasyMock, but it seems to me that the error is caused by EasyMock trying to call a method on what it assumes to be an instance of EasyMock, but is in reality a dynamic proxy created by Spring. As I understand it, dynamic proxies only implement the methods defined in the interface, in this case the interface for Service.
What I don't understand is that from what I read (also here), what I'm trying to achieve at least seems to be possible.
So my question is: What I'm I not doing or what am I doing wrong?
You can also create a helper method to unwrap the EasyMock proxy from the Spring proxy to define expected behaviour then:
public static <T> T unwrap(T proxiedInstance) {
if (proxiedInstance instanceof Advised) {
return unwrap((T) ((Advised) proxiedInstance).getTargetSource().getTarget());
}
return proxiedInstance;
}
Note the recusive call as in worst case you have multiple proxies wrapped around the actual target.
Solved!
I had overlooked this in my applicationContext.xml:
<bean id="txProxyAutoCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Service</value>
<!-- ^^^^^^^^
This is the problem!
-->
</list>
</property>
<property name="interceptorNames">
<list>
<value>txAdvisor</value>
</list>
</property>
</bean>
... which causes Spring to automatically create proxy objects for all beans with names that end in "Service".
My solution was to explicitly list the beans instead of using a wild card. This seems a little brittle to me, however, so if anyone knows how to specify all *Service beans except FooService, I would be grateful.
Something's odd here. You're clearly quickly mastering both Spring and EasyMock. The autoproxies, the factory methods, all good signs that you're diving deep into Spring's capabilities.
Still, it's kind of odd that you're injecting a mock bean into a class at all. You may have a great reason, but to me it's a code smell. I'd advise you to consider only wiring in real services into your test classes and then initializing the mock objects as needed. Why spend 3 lines in java and another 3 lines in XML (plus 1 line to reset them) to create a mock object with no dependencies? Just say Service service = (Service)createMock(Service.class). I would advise creating them in the methods that you need them for, set expectations, inject, use them, and then discard them. In your model, you'll have to remember to reset the mock object every time you use it, which is less clear than just creating a new one.
Of course, this is a style issue and not a correctness issue, so ignore as desired.
I know this question is old, but I just stumbled upon it searching for a similar problem.
The problem is that Spring doesn't know the type of the mock object. The method you use looks like this:
public static <T> T createMock(final Class<T> toMock) {
return createControl().createMock(toMock);
}
Spring isn't smart enough to derive T from the constructor argument (at least the last time I've checked), so it thinks the returned object is of type java.lang.Object. As a consequence, the created proxy doesn't implement my.project.Service and therefore can't be injected.
The answer therefore is to tell Spring the required type.