Junit Test to test Http Outbound endpoint in Mule Flow - unit-testing

I have a basic Mule ESB application with a basic flow like:
"Http Inbound endpoint (request-response mode) -> logger -> HTTP Outbound Endpoint (request-response mode) -> Java component"
Query: How do I write a junit test case to test the above flow. As can be seen, I have a HTTP Outbound Endpoint (request-response mode) which refers to some big application which does lots of processing and then returns a response. Do I mock this HTTP outbound endpoint?
I don't want to test only the HTTP Outbound Endpoint (request-response mode) individually. I want to junit test the flow as a whole.
Thanks in Advance.
Jai Shammi Raj Kulkarni

You can create a test flow with an HTTP Inbound Endpoint and a test:component for setting the payload, and add the flow file to your test configuration files. However, I prefer to use the Confluex Mock HTTP API to test applications with HTTP Outbound Endpoints. It sets up a mock HTTP server at localhost, where you can respond to different calls with specified data and response codes, so you can run all kinds of failure scenarios as well. Set up the mock server in a #Before annotated method in your FunctionalTestCase class and stop it in the #After method, so it will be available for the test methods.
Mule documentation gives some basic information on how to create functional test cases: http://www.mulesoft.org/documentation/display/current/Functional+Testing

public void httpEndpoint() throws IOException
{
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://localhost:8085/api/search");
HttpResponse response = client.execute(httpGet);
assertNotNull(response);
}

Have you checked Munit?
https://github.com/mulesoft/munit/wiki/First-Munit-test-with-Mule-code
https://github.com/mulesoft/munit/wiki
Also check this:
http://www.mulesoft.org/documentation/display/current/Introduction+to+Testing+Mule

Related

Traces not sampled with Istio and Sleuth

I am using Spring Boot 2 Microservices with Spring Cloud Sleuth with the Dependency Management and Spring Cloud Version Greenwich.SR2.
My service is running in an Istio service mesh.
Sample policy of istio is set to 100 (pilot.traceSampling: 100.0).
To use distributed tracing in the mesh, the applications needs to forward HTTP headers like the X-B3-TraceId and X-B3-SpanID. This is achieved by simply adding Sleuth. All my HTTP request are are traced correctly. The sidecar proxies of Istio (Envoy) send the traces to the Jaeger backend.
Sleuth is also supposed to work with Spring WebSocket. But my incoming websocket requests do not get any trace or span id by sleuth; Logs look like [-,,,].
1. Question: Why is Sleuth not working for websocket?
My WS-Config:
#Configuration
#EnableWebSocket
public class WsConfig implements WebSocketConfigurer {
#Autowired
WebSocketHandler webSocketHandler;
#Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
DefaultHandshakeHandler handshakeHandler = new DefaultHandshakeHandler();
handshakeHandler.setSupportedProtocols(HANDSHAKE_PROTOCOL);
registry.addHandler(webSocketHandler, WS_HANDLER_PATH + WILDCARD)
.setAllowedOrigins("*")
.setHandshakeHandler(handshakeHandler);
}
}
My clients are able to connect to my Service via Websocket. I am implementing WebSocketHandler interface to handle WS messages.
To achieve that my WS connections are logged by Sleuth, I annotate the method that handles my connection with #NewSpan:
#Override
#NewSpan
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
//doWork and call other services via HTTP
}
With this, Sleuth creates trace and spanId and also propagates them to the other Services, which are called via the restTemplate in this method. But HTTP calls are not send to Jaeger. The x-B3-Sampled Header is always set to 0 by the sidcar.
2 Question: Why are those traces not send to the tracing backend?
Thank you in advance!

Combine E2E testing with HTTP web services testing

Can I catch HTTP request\response from the protractor, I want to create E2E tests with validation of the web services using JSON.
You can only capture request, response through a proxy. Selenium-webdriver doesn't support this feature since it is limited to only browser simulation. One of the most well known proxies for inspecting request, response is browsermob-proxy. You can either directly use its API or use the node client browsermob-node. Once You have a proxy running, you can set driver capabilities in your protractor config like below
capabilities: {
'proxy': {
'proxyType': 'manual',
'httpProxy': 'hostname.com:1234'
}
}

WSO2 ESB Unit Testing

We've developed a Proxy Service into WSO2 ESB which is an orchestrator, and calls multiple services aggregating the response.
How can I test each single step (or mediator) of the proxy flow, and how the system reacts to each possible situation (e.g. Success, Failure, Slow response time...)?
We are trying to mock the behaviour of each service called by the proxy (with Wiremock), for each step, but we are not able to dynamically change the endpoints (or the ports) pointed by each call.
Example:
Real service is listening on port 8280
Wiremock is listening on port 8281
We need to dynamically change the endpoint within the Proxy, to let it call the Wiremock service (8281) instead of the real one (8280)
If there are other ways to test, I'm happy to explore different solutions...
I am unable to get your question correctly... can't you in Your proxy service you mention the endpoint url with port as 8281...??
Finally found the solution to the problem.
Using the endpoints of the registry, you are able to get the resources from the registry, change them and update it.
For example you could do something like:
AutomationContext esbContext = new AutomationContext("ESB", TestUserMode.SUPER_TENANT_ADMIN);
String esbSession = esbContext.login();
ResourceAdminServiceClient resourceClient = new ResourceAdminServiceClient(esbContext.getContextUrls().getBackEndUrl(),
esbSession);
String endpoint = resourceClient.getTextContent("/_system/governance/endpoints/HelloService.xml")
.replace(":8280", String.format(":%s", port));
resourceClient.updateTextContent("/_system/governance/endpoints/HelloService.xml", endpoint);

JAX-WS client | Sending client requests with security header

I have implemented a Spring WS using XWSS for security. I have added a security configuration policy file into my application.
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config"
dumpMessages="true">
<xwss:RequireTimestamp
id="tsp"
maxClockSkew="60"
timestampFreshnessLimit="300">
</xwss:RequireTimestamp>
<xwss:RequireUsernameToken
id="token"
passwordDigestRequired="false"
nonceRequired="false"/>
<xwss:Timestamp></xwss:Timestamp>
<xwss:UsernameToken
name="service"
password="service"
id="uToken"
digestPassword="true"
useNonce="true"/>
</xwss:SecurityConfiguration>
Now I am developing a client to access the WS. The security works fine. But I am unable to test the SUCCESS case in which the client can successfully get a response from my service. The problem is I don't know how to make my client send the usernametoken and timestamp along with the request. I am using NetBeans IDE and I am implementing a JAX-WS client to access the Spring WS using this tutorial.
Please let me know what needs to be done.
For Spring WSS there is not much difference between adding a security header to the ingoing soap messages or to the outgoing ones. The process is very similar.
In both cases, you should create a interceptor for adding the security header. It is described here. So, if you create the WS client using Spring you should not have problems, especially if you have already developed the server side, but the tutorial you referenced doesn't look like using Spring for implementing the client.
You can do this by adding the following code in you client class / class extending the webservicetgatewaysupport.
SoapHeader header = msg.getSoapHeader();
StringSource headerSource = new StringSource("<wsse:Security xmlns:wsse=\"http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" mustUnderstand=\"1\"> <wsse:UsernameToken>
<wsse:Username>"+userName+"</wsse:Username> <wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/
oasis-200401-wss-username-token-profile-1.0#PasswordText\">"+password+"</wsse:Password> </wsse:UsernameToken>"
+"</wsse:Security>");
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(headerSource, header.getResult());
The above has to go in the message call back handler of the marshalSendANDRecieve metho of the webserviceTemplate
Check this sample for client.
And you could use SoapUI to test your server. Import WSDL, then select any request and open "Properties" window in left-bottom corner. You would see "Username", "Password" and "WSS-Password Type" related settings.

CXF: Providing decoupled endpoint via existing Servlet transport

I have an application which provides services using CXF's Servlet transport and Jetty 6.1. This application also needs to consume external services. All services support WS-Addressing specification (and WS-RM on top). To consume an external service, I run a generated service client from the application.
The problem is that when I provide a decoupled endpoint for the client (WS-RM needs this endpoint to receive incoming messages via a separate http connection), CXF runs another instance of Jetty server (in spite of the fact that Servlet transport (which provides services) and the client (which consumes some external service) share the same bus). I don't need two instances of Jetty (not saying that they can't run on the same HTTP port).
Is there a way I can provide a decoupled endpoint using an existing Jetty server and Servlet transport?
So far, I enable a decoupled endpoint like this:
Client client = ClientProxy.getClient(port);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
httpConduit.getClient().setDecoupledEndpoint(
"http://domain.com:port/services/dec_endpoints/TestDecEndpoint");
If I provide a relative path ("/dec_endpoints/TestDecEndpoint", just like relative paths are used with provision of services via Servlet transport), HTTP conduit does not specify a full path in a SOAP message's headers so this doesn't work either (server just can't send a message to /dec_endpoints/TestDecEndpoint).
Ok, I have found a solution myself. You need to specify a relative path for decoupled endpoint and change message's addressing properties manually (after MAPAggregator interceptor, 'cause it sets up the decoupled destination) so the server can send replies to your address.
So what we have:
decoupled destination using a relative path: /dec_endpoints/SomeDestination
<ReplyTo> header with an absolute path: http://addr.com:port/servlet_path/dec_endpoints/SomeDestination
Here's an example how the path can be changed:
public class ReplyToInterceptor extends AbstractPhaseInterceptor<Message>
{
public ReplyToInterceptor() {
super(Phase.PRE_LOGICAL);
addAfter(MAPAggregator.class.getName());
}
public void handleMessage(Message message) {
AddressingProperties maps = ContextUtils.retrieveMAPs(message, false,
true);
EndpointReferenceType replyTo = maps.getReplyTo();
replyTo.getAddress().setValue(
"http://address.com:port/servlet_path/dec_endpoints/SomeDestination");
}
}