In this post I dive into the use of a Component Binding in Mule. The context is given here. I will show how I use a component binding to combine the original message and the response message in one message. In the next post I show how I use this combined message to determine (and perform) the next step.
Here is the relevant piece of the Mule config file for the component binding:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <service name="OrderPostService"> <inbound> <vm:inbound-endpoint path="order-post-service" synchronous="true"/> </inbound> <component class="net.pascalalma.mule.OrderAppInvoker"> <binding interface="net.pascalalma.mule.InboundOrderBinding" method="process"> <http:outbound-endpoint address="http://app-server:8090/order-in" synchronous="true"> <response-transformers> <byte-array-to-string-transformer /> </response-transformers> </http:outbound-endpoint> </binding> </component> <default-service-exception-strategy> <vm:outbound-endpoint path="handle-error" /> </default-service-exception-strategy> </service> |
What this service does is it receives the message that has to be send to the order application on a VM channel ‘order-post-service’. To send the message to the order application it is posted on an outbound http channel ‘http://app-server:8090/order-in’. But like I said this outbound endpoint is bound to the component ‘OrderAppInvoker’ by the interface ‘InboundOrderBinding’.
The interface ‘InboundOrderBinding’ looks like this:
1 2 3 4 5 6 | package net.pascalalma.mule; public interface InboundOrderBinding { String process(String o); } |
What you see here is that the binding has a method ‘process’, which takes a String as input and will return a String as output. The name of the method (‘process’) is actually irrelevant here since I bind it to a HTTP endpoint. What is important is that a String is supplied and a String is returned.
The class ‘OrderAppInvoker’ looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | package net.pascalalma.mule; import org.mule.api.lifecycle.Callable; import ...; public class OrderAppInvoker implements Callable { private InboundOrderBinding binding; public InboundOrderBinding getBinding() { return binding; } public void setBinding(InboundOrderBinding binding) { this.binding = binding; } public Object onCall(MuleEventContext ctx) throws Exception { MuleMessage msg = ctx.getMessage(); //Get the original XML message String orgMessageString = (String) msg.getPayload(); // Call the bound method and get the response message String responseString = binding.process(orgMessageString); //Deserialize the String messages to JAXB Objects so it's easier to combine the // two to my new message type InboundOrderType it = unmarshal(InboundOrderType.class, orgMessageString); OrderResponseType or = unmarshal(OrderResponseType.class, responseString); // Now construct the new response containing both the original and the orderResponse // message ObjectFactory of = new ObjectFactory(); MyResponseType responseType = of.createMyResponseType(); responseType.setOrderResponse(or); responseType.setOriginalMsg(it); JAXBElement<myResponseType> response = of.createMyResponse(responseType); // Put the newly constructed as payload on the message and return that message msg.setPayload( marshal(response)); return msg; } private <t> T unmarshal(Class<t> docClass, String input) throws JAXBException { ... } public String marshal(JAXBElement el) throws JAXBException { ... } } |
What I do here is I created a getter and setter for the interface that is used for the bound component and I implemented the ‘onCall’ method. What I actually do in the ‘onCall’ method is that I store the original message in a local variable, I then call the ‘http-endpoint’ via the binding and get the response message. This response message is combined with the original message (by using JAXB) in a new message I created and this new message is put on the payload. So when this component is finished I have both the original message and the response message in one message. This aggregated message is transferred to the next service ‘process-response’ by making use in of a ‘chaining-router’ as described here.
In the next post we will see how I use this combined message and process it further.
Pingback: Example of using Component Binding in Mule2 (part 3) | Redstream Blog
Pingback: Example of using Component Binding in Mule2 (part 3) | Redstream Blog
thanks a lot,i got it,and create a component with binding axis endpoint….
PS:from china
Hi Hu Ming,
Thx for the response. Always nice to here our work is appreciated!