Access Keys:
Skip to content (Access Key - 0)
Cancel    
Cancel   

Contents

Invoking Component Methods

This example demonstrates different ways in which entry point resolvers are used when you invoke a component. As discussed in the previous example, Mule uses end point resolvers to determine the appropriate method when an endpoint receives data. The type of data determines which kind of resolver to apply. For example, there are different resolvers for dynamic data, pre-defined data type, methods that incorporate annotations, and the Callable interface.

This example also explains how to use a Transformer to transform one Java type to another.

What You Will Learn

This example demonstrates four ways in which end point resolvers can be applied:

  • Case 1 - Using a dynamic data resolver to resolve a lone entry point method
  • Case 2 - Using a dynamic data resolver to resolve between two entry point methods
  • Case 3 - Using the annotated entry point resolver to resolve a method with annotations
  • Case 4 - Using the Callable interface with the onCall method

15 minutes

Build it now!

Prerequisites

This tutorial continues the Adding Business Logic to a Flow example. At this point, you should have created a flow called hello.mflow and a POJO component named Hello with a single method called sayHello. The sayHello method returns the text "Hello " with the name that you pass in.

Case 1 - Using a Dynamic Data Resolver to Resolve a Lone Entry Point Method

In this part, we create a Custom Transformer called HttpRequestToNameString so that we can pass in a string to the Hello component. This entails creating a class for the Transformer, dragging a Transformer into the flow, creating a reference to the class, and running the example to make sure that the dynamic endpoint resolver works.

1. Create a Java class for the new transformer called HttpRequestToNameString. As shown in the previous example, to create a class, you right-click the src/main/java folder and select New→Class. The New Java Class dialog appears.

2. Add the following information in the New Class dialog:

  • Package - com.test.transformer
  • Class name - HttpRequestToNameString
  • Superclass - org.mule.transformer.AbstractMessageTransformer (You can browse for this.)
  • Method stubs - Inherited abstract method

The following figure shows the New Java Class dialog, with the information entered.

3. Click Finish to complete the class specifications. The source editor appears with the code and method stub for the new class, as shown below.

4. Replace the return null: line after the // TODO comment with the following snippet.

The new code defines the incoming data strings and changes the return statement to return the first and last names. Note that the Hello component gets the name and last name strings from the Mule InboundProperty. Mule sets inputs that are passed in the request as inbound properties. You can use the get methods to obtain the values for these properties.

5. Double-click the hello.mflow tab to display the flow graph and drag a Java Transformer into the flow between the http source and the Hello component.

6. Double-click the Customer Transformer icon to display the Pattern Properties dialog. Add the following data:

  • Display Name - HttpRequestToNameString Transformer
  • Transformer Class - com.test.transformer.HttpRequestToNameString

Specifying the Transformer class creates a reference from the flow to the class. Supplying a display name makes it easy to identify the transformer. Click OK.

7. To run the example, right-click hello.mflow in the project tree and select Run As...→Mule Application. Note that Mule prompts you to save any unsaved files before proceeding. Access this URL: http://localhost:8082/?name=jas&lname=bhatia in a browser. Your browser should display Hello jas bhatia as shown in the following figure.

The dynamic data end point resolver finds the sayHello method successfully.

Case 2 - Using a Dynamic Data Resolver to Resolve between Two Entry Point Methods

In this part, we are going to create an object and a transformer and add a method to the component that can accept the object's data.

8. Create a new Java class called User, as you did in steps 1-3, using the following data:

  • Package - com.test
  • Class name - User
  • Superclass - java.lang.Object (the default)
  • Method stubs - none (uncheck any default settings)

9. When the source editor is displayed, add the following code to the class. This code is used to set and return the first name and last name.

10. Create a new Java class under src/main/java called HttpRequestToUser to convert the input string to User object data. Repeat steps 1-3 and supply the following data:

  • Package - com.test.transformer
  • Class name - HttpRequestToUser
  • Superclass - org.mule.transformer.AbstractMessageTransformer
  • Method stubs - Inherited abstract method

Click Finish when you are done.

11. Paste the following code into the Source Editor to match the figure below.

12. Double-click the Transformer icon in the flow and change the transformer to refer to the new class as follows:

  • Display Name - HttpRequestToUser Transformer
  • Transformer Class - com.test.transformer.HttpRequestToUser

13. Right-click the flow in the project tree and select Run As...→Mule Application. This time there is no output, because HelloComponent has only one method and that method can accept a String type only; we sent data of type com.test.User. If you check the output console, you see the message org.mule.model.resolvers.EntryPointNotFoundException. So let's add a second method to handle the user data.

14. Click the HelloComponent.java tab and change the code to add a second method called sayHelloUser, as shown in the following figure.

15. Run the project again and use the same URL:
http://localhost:8082/?name=Jas&lname=bhatia

The reason it works now is that the dynamic data end point resolver has two methods to choose from in HelloComponent. The sayHello method can accept the correct type for the com.test.User object.

Case 3 - Using the Annotated Entry Point Resolver to Resolve a Method with Annotations

Annotations allow flow objects to be created solely within the component code. The @ContainsTransformerMethods annotation for creating Mule transformers makes it easy to define and discover custom transformers. You can perform a conversion in a method by applying the @Transformer annotation

16. Create a new Java class using the following data:

  • Package - com.test.transformer
  • Class name - AnnotatedTransformer
  • Superclass - org.mule.transformer.AbstractMessageTransformer
  • Method stubs - Inherited abstract method

17. Paste the following code into the Source Editor to match the figure below.

This code uses the following annotations:

  • @ContainsTransformerMethods tells Mule that this class contains an annotated transformer method.
  • @Transformer registers this method with Mule so that it can be used when you want to transform String type to com.test.User type.
  • @Payload automatically transforms the payload type to the specified type, in this case, String.
  • @InboundHeaders checks for an inbound header called "name" and assigns it to String name. @InboundHeaders for "lname" works the same way.

At this point, you need to register this class with Mule. Currently Mule Studio does not have the capability to define a Spring bean. The work-around creates a Spring bean in the Configuration XML file.

18. Open the flow and click the Configuration XML tab below the source editing window. Add the following line of code so that it appears as shown in the figure below.

19. Click the Message Flow tab. Delete the existing Java transformer so that your flow looks like the following:

20. Open HelloComponent and remove the sayHello method. Add @Payload to the sayHelloUser method, as shown in the following figure.

21. Run the example again using http://localhost:8082/?name=Jas&lname=bhatia

You will see this working as before:

@Payload has automatically converted String to User object and has initialized User object on the component method.

Case 4 - Using the Callable Interface with the onCall Method

With the Callable interface, your flow can accept multiple types of incoming data with a single method named onCall. If you implement a callable interface on your component, Mule always invokes the_onCall_ method on that component no matter how many other methods are present. The only exception is if you override the Callable interface by defining an annotated method. Thus, it's important to make sure that you have removed annotated methods if you want to invoke the onCall method

22. Change the code in HelloComponent to match the following diagram. In particular, add import org.mule.api.lifecycle.Callable; and implements Callable to the class declaration and paste in the following code:

23. Run the example again using: http://localhost:8082/?name=Jas&lname=bhatia

As you can see, the Callable interface provides yet another technique for resolving component methods.

What Just Happened?

You learned how component entry points are resolved using a dynamic data entry point resolver, annotations, and the Callable interface.

References

Developing Components 
Using Annotations

Next Steps

Next: Using Outbound Endpoints to Publish Data

Previous: Transforming Data in a Flow