How to Create a Custom Connector in New Mule SDK 4.1.1
In this article, I'd like to walk you through how to develop your own connector using Mule SDK.
Join the DZone community and get the full member experience.
Join For FreeIntroduction
MuleSoft's Anypoint Connectors helps to connect third-party APIs and service through the Mule flow. You can use the connector to send or receive a message from Mule flow to one or more external services over protocol or API. Mule flow designing is graphical, so you don't need to write a single line of code to connect external services when you are using Anypoint connectors. Today, MuleSoft has a large collection of different connectors to connect and integrate diverse systems including Salesforce, Database, different Google and AWS services, and many more.
You can develop your own connector using new Mule SDK platform, which is the replacement of earlier Mule devkit tool. In this article, I'd like to walk you through how to develop your own connector using Mule SDK.
Prerequisites
- Java JDK Version 8.x
- Anypoint Studio 7.x
- Apache Maven 3.3.9 or higher
Steps to Create a Connector
- Go to the directory where you want to create connector (studio-workspace) and execute a command to create project structure with sample test cases: 1
$ mvn org.mule.extensions:mule-extensions-archetype-maven-plugin:generate
- Complete the configuration through the console by answering a couple of questions:
- Enter the name of the extension (empty for default):
- Enter the extension's groupId (empty for default):
- Enter the extension's artifactId (empty for default):
- Enter the extension's version (empty for default):
- Enter the extension's main package (empty for default):
- Go to Anypoint studio, File > Open Project from File System, and select the project directory you have created in the last step.
- After you open this project in Anypoint studio, you will get the number of classes, annotated with mule SDK annotations as below:
- The connector is called as an extension in Mule 4, and it's class defined by the annotation @Extension. A @Configurations annotation is used to point the configuration class. 171
package org.mule.extension.internal;
2
3import org.mule.runtime.extension.api.annotation.Extension;
4import org.mule.runtime.extension.api.annotation.Configurations;
5import org.mule.runtime.extension.api.annotation.dsl.xml.Xml;
6
7
8/**
9* This is the main class of an extension, is the entry point from which configurations, connection providers, operations
10* and sources are going to be declared.
11*/
12prefix = "my-name") (
13name = "My name") (
14MynameConfiguration.class) (
15public class MynameExtension {
16
17}
- Configuration class defines the parameters that we expect appears in configuration part of the connector. We can use @ConnectionProvider and @Operation annotation with this class to point out the connection providers and the operations connector has implemented. 211
package org.mule.extension.internal;
2
3import org.mule.runtime.extension.api.annotation.Operations;
4import org.mule.runtime.extension.api.annotation.connectivity.ConnectionProviders;
5import org.mule.runtime.extension.api.annotation.param.Parameter;
6
7/**
8* This class represents an extension configuration, values set in this class are commonly used across multiple
9* operations since they represent something core from the extension.
10*/
11MynameOperations.class) (
12MynameConnectionProvider.class) (
13public class MynameConfiguration {
14
1516private String configId;
17
18public String getConfigId(){
19return configId;
20}
21}
- The next important class is MynameConnectionProvider, which is annotated as @ConnectionProviders in configuration class.
- This class is used to manage and provide the connection with the targeted system.
- The connection provider must implement the one of the connection provider available in Mule. Here, we are implementing the PoolingConnectionProvider, other options are CachedConnectionProvider and ConnectionProvider.
- Parameter required to establish connection must be defined into the ConnectionProvider class.
- Also, you must override connect, disconnect, and validate methods to provide the functionality specific to this connection provider. x1
package org.mule.extension.internal;
2
3import org.mule.runtime.api.connection.ConnectionException;
4import org.mule.runtime.extension.api.annotation.param.Parameter;
5import org.mule.runtime.extension.api.annotation.param.Optional;
6import org.mule.runtime.api.connection.ConnectionValidationResult;
7import org.mule.runtime.api.connection.PoolingConnectionProvider;
8import org.mule.runtime.api.connection.ConnectionProvider;
9import org.mule.runtime.api.connection.CachedConnectionProvider;
10import org.mule.runtime.extension.api.annotation.param.display.DisplayName;
11
12import org.slf4j.Logger;
13import org.slf4j.LoggerFactory;
14
15
16/**
17* This class (as it's name implies) provides connection instances and the funcionality to disconnect and validate those
18* connections.
19* <p>
20* All connection related parameters (values required in order to create a connection) must be
21* declared in the connection providers.
22* <p>
23* This particular example is a {@link PoolingConnectionProvider} which declares that connections resolved by this provider
24* will be pooled and reused. There are other implementations like {@link CachedConnectionProvider} which lazily creates and
25* caches connections or simply {@link ConnectionProvider} if you want a new connection each time something requires one.
26*/
27public class MynameConnectionProvider implements PoolingConnectionProvider<MynameConnection> {
28
29private final Logger LOGGER = LoggerFactory.getLogger(MynameConnectionProvider.class);
30
31/**
32* A parameter that is always required to be configured.
33*/
3435private String requiredParameter;
36
37/**
38* A parameter that is not required to be configured by the user.
39*/
40"Friendly Name") (
4142defaultValue = "100") (
43private int optionalParameter;
44
4546public MynameConnection connect() throws ConnectionException {
47return new MynameConnection(requiredParameter + ":" + optionalParameter);
48}
49
5051public void disconnect(MynameConnection connection) {
52try {
53connection.invalidate();
54} catch (Exception e) {
55LOGGER.error("Error while disconnecting [" + connection.getId() + "]: " + e.getMessage(), e);
56}
57}
58
5960public ConnectionValidationResult validate(MynameConnection connection) {
61return ConnectionValidationResult.success();
62}
63}
- The Connection class is used by connection providers to handle the connection. By having the single connection class and multiple connection providers, we can create multiple connection configurations for our Connector. 221
package org.mule.extension.internal;
2
3
4/**
5* This class represents an extension connection just as example (there is no real connection with anything here c:).
6*/
7public final class MynameConnection {
8
9private final String id;
10
11public MynameConnection(String id) {
12this.id = id;
13}
14
15public String getId() {
16return id;
17}
18
19public void invalidate() {
20// do something to invalidate this connection!
21}
22}
- And finally, we have operation class. We can define any number of operation classes and all public methods from this class will be treated as a connector operation. We can inject configurations and connection to particular operation using @Config and @Connection annotation in method arguments. 371
package org.mule.extension.internal;
2
3import static org.mule.runtime.extension.api.annotation.param.MediaType.ANY;
4
5import org.mule.runtime.extension.api.annotation.param.MediaType;
6import org.mule.runtime.extension.api.annotation.param.Config;
7import org.mule.runtime.extension.api.annotation.param.Connection;
8
9
10/**
11* This class is a container for operations, every public method in this class will be taken as an extension operation.
12*/
13public class MynameOperations {
14
15/**
16* Example of an operation that uses the configuration and a connection instance to perform some action.
17*/
18value = ANY, strict = false) (
19public String retrieveInfo( MynameConfiguration configuration, MynameConnection connection){
20return "Using Configuration [" + configuration.getConfigId() + "] with Connection id [" + connection.getId() + "]";
21}
22
23/**
24* Example of a simple operation that receives a string parameter and returns a new string message that will be set on the payload.
25*/
26value = ANY, strict = false) (
27public String sayHi(String person) {
28return buildHelloMessage(person);
29}
30
31/**
32* Private Methods are not exposed as operations
33*/
34private String buildHelloMessage(String person) {
35return "Hello " + person + "!!!";
36}
37}
- The connector is called as an extension in Mule 4, and it's class defined by the annotation @Extension. A @Configurations annotation is used to point the configuration class.
- We can install this connector into local maven repository using the command: 11
$mvn clean install
- You can use this connector in your Mule 4 application by adding the following dependency in pom.xml: 61
<dependency>
2<groupId>org.mule.extension</groupId>
3<artifactId>mule-basic-extension</artifactId>
4<version>1.0.0-SNAPSHOT</version>
5<classifier>mule-plugin</classifier>
6</dependency>
Am I missing something here? Let me know in the comments section and I'll add to it!
This is just start of the Mule SDK 4.x.x. In the upcoming article, I'd like to share how to add test cases and how to use this connector in Mule flow.
Thanks.
Opinions expressed by DZone contributors are their own.
Comments