Over a million developers have joined DZone.

How to Build a Custom Mule Connector in Java

DZone's Guide to

How to Build a Custom Mule Connector in Java

Want to learn how to build a custom mule connector in Java? Check out this tutorial to learn how with the ConnectorConfig and SampleDynamicsConnector classes.

· Integration Zone ·
Free Resource

Before we get started, here are some helpful links from Mule Documentation to get you introduced to building mule connectors.

What is Anypoint Connector DevKit?

Creating an Anypoint Connector Project

In this article, we will take a deep dive into how to add additional functionality (tabs), like pooling profile, reconnection in connector configuration, operations (drop-down), and general tab in connector settings.

Building a custom connector involves two things. First, it involves understanding the underlying connectivity logic and operations (CRUD Operations are nothing but our connector functionality listed in the drop-down). If we are building a public cloud connector like Azure Storage services - Blob/Table/Queue, then all of the connectivity and operation functionality is ready offered by Microsoft. Anypoint Connector Devkit provides various annotations to make developer life easier to build and publish connectors faster and wraps the underlying connectivity logic into an intuitive, simple to use, drag and drop connector available in Anypoint Studio that anyone can use without the need to know all the underlying complexity written in Java. This improves user experience with seamless access to rich functionality offered by the connector.

I am going to use Dynamics365 for Operation as a reference to build this new connector. Building a full-fledged Mulesoft Connector is simple and straightforward by leveraging the annotations offered by Anypoint Connector DevKit. Primarily, there is only two classes that we need to focus on — (1) ConnectorConfig java class (2) <<Name of the Connector>>Connector java class.

Part One

Let’s start with the ConnectorConfig Java class. This class is all about setting up the connection with the target system and managing the connection. It can be a SAAS product or cloud service, such as Azure Storage service (Blob, File, Queue) or any system for that matter.

The value we provide in the friendlyName attribute in @ConnectionManagement annotation gets displayed at the top of the connector configuration.

@ConnectionManagement(friendlyName = "OAuth 2.0 Username-Password")
public class ConnectorConfig {

/** The Constant CONNECTION_ID. */
private final static String CONNECTION_ID = "001";

Image title

Any point DevKit makes it easy to add Connection Management functionality to connectors by creating a new @ConnectionStrategy. You will need to create a new class and annotate it with @ConnectionManagement.

Connection Management DevKit Annotations

To use Connection Management in a connector, define and annotate the following methods in the @ConnectionManagement annotated class:

@Connect — Creates a connection

@Disconnect — Explicitly closes a connection

@ValidateConnection — Returns true if a connection is still valid, false otherwise

@ConnectionIdentifier — Returns a prefix used in generating unique identifiers for connector instances in the connection pool

Please refer to Mulesoft Documentation for connection management details.

Refer this link for connector code.

public void getAccessToken(
@Placement(group = "Connection") @FriendlyName("Token Request Endpoint") @ConnectionKey String tokenrequestendpoint, 
@Placement(group = "Connection") @FriendlyName("Resource") String resource, 
@Placement(group = "Connection") @FriendlyName("Client ID") String clientId,
@Placement(group = "Connection") @FriendlyName("Client Secret") String clientsecret,
@Placement(group = "Connection") @FriendlyName("Username") String userName,
@Placement(group = "Connection") @FriendlyName("Password") @Password String password,
@Placement(group = "Connection") @FriendlyName("Read Timeout") String readtimeout,
@Placement(group = "Connection") @FriendlyName("Connection Timeout") String connectiontimeout
) throws ConnectionException {

<< Write required logic to establish the connection using above parameters >>


@Placement — “Connection” is the group (table) name inside the General tab.

@FriendlyName — Is the textbox heading.

@ConnectionKey — Marks a parameter inside the connects method as part of the key for the connector lookup. This can only be used as part of the @Connect method.

Image title

Image title

Image title

public void disconnect() {
    DynamicsClient = null;

public boolean isConnected() {
    return DynamicsClient != null;

    public String connectionId() {
    return CONNECTION_ID;

Part Two

Now, let’s take a look at the SampleDynamicsConnector Java class. In this class, we define operations and write logic to perform those operations. Depending on the connector functionality, it could be anything from a CRUD operation to a more sophisticated functionality offering.

@Connector(name = "Dynamics365", friendlyName = "SampleDynamics", description = "Dynamics 365 for Operation Connector")
public class SampleDynamicsConnector {

ConnectorConfig config;

Here, friendlyName attribute value gets displayed in the connector details section,

Image title

@Processor(friendlyName = "import dynamic message")
public void ImportMessage(@Placement(group = "General", order = 1) @FriendlyName("Uri Path") String uripath,
@Placement(group = "General", order = 2) @FriendlyName("Activity ID") String activityid,
@Placement(group = "General", order = 3) @FriendlyName("Entity Name") String entityname,
@Placement(group = "General", order = 4) @FriendlyName("File Input (String)") String fileinput)
throws Exception {

<< Write required logic to perform the defined Operation (drop-down) using above parameters >

Image title

@Processor annotation — Marks a method as an operation in a connector.

@Placement annotation helps to create a group (table) with attributes to specify the order and the group name.

Example 2: How to Create a Tooltip (Descriptive Pop-up Message)

In the example shown below, we have used both annotations @FriendlyName and @Summary . Here, @FriendlyName is used to define the name of the field that is displayed, and @Summary is used for a descriptive pop-up message.

@Processor(friendlyName = "import dynamic message")
public void ImportMessage(@Placement(group = "General", order = 1) @FriendlyName("Uri Path") String uripath,
@Placement(group = "General", order = 2) @FriendlyName("Activity ID") @Summary("Activity ID from Dynamics 365") String activityid,
@Placement(group = "General", order = 3) @FriendlyName("Entity Name") String entityname,
@Placement(group = "General", order = 4) @FriendlyName("File Input (String)") String fileinput)
throws Exception {

Image title

Example 3

Now, let’s take a look at creating a sophisticated operation:

@Processor(friendlyName = "export dynamic message")
public void ExportMessage(
@Placement(group = "Export Parameters", order = 1) @FriendlyName("Entity Name") String tableName,
@Placement(group = "Export Parameters", order = 2) @FriendlyName("Create Entity If Not Exist") @Default("false") boolean createTableIfNotExist,
@Placement(group = "Export Parameters", order = 3) @FriendlyName("Encrypt Entity While Export(Supports Only String DataType)") @Default("false") boolean encryptEntityWhileInsertion,
@Placement(group = "Export Parameters", order = 4) @FriendlyName("POJO Entity(Define anyone value from below two options)") TestradioButton testradioButton) throws Exception {

@Summary annotation — Use this annotation to instance variables and method parameters to provide a way to override the default inferred description for a @Configurable variable or a @Processor, @Source , @Transformer method parameter.

@FriendlyName annotation — Use this annotation to instance variables and method parameters to provide a way to override the default inferred nickname for a @Configurable variable or a @Processor , @Source , @Transformer method parameter.

public class TestradioButton {

public static final String SUMMARY_JSON_ENTITY_PROPERTIES_AS_STRING = "JSON entity properties as String.";

public static final String SUMMARY_JSON_ENTITY_PROPERTIES_AS_JSON_OBJECT = "JSON entity properties as org.codehaus.jettison.json.JSONObject.";

@FriendlyName(value = "JSON Entity Properties As String")
private String jsonEntityPropertiesAsString;

/** The json entity properties as json object. */
@FriendlyName(value = "JSON Entity Properties As org.codehaus.jettison.json.JSONObject")
private Object jsonEntityPropertiesAsJsonObject;

Here, in the TestradioButton class, the @Summary annotation is used to provide a descriptive pop-up message.

Image title

You might wonder why we have two radio buttons, (1) Reference or expression (2) Define attributes. Here, the second radio button has two values that are coming from “TestradioButton” POJO class. First radio button means, we can give a reference to a relevant bean. In this case, we need to define TestradioButton as a bean and reference it in first radio button.

Connector Development Resources

Sync, automate, and notify lead to customer changes across marketing, CRM, and messaging apps in real-time with the Cloud Elements eventing framework. Learn more.

mulesoft ,connectors ,mule ,mule connectors ,java ,tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}