Mule’s extension capabilities multiply its power as an integration platform and range from simple expressions to custom cloud connectors: wherever a configuration value is expected, expressions can be applied in various languages, including our new Mule Expression Language, so that the same value is calculated at run-time; our Scripting processors allow you to execute custom logic in Groovy, Python, Ruby, JavaScript, PHP and indeed any language which implements the JSR-223 scripting spec for the JVM; and of course Java components can be invoked too. Our extensible platform goes even further with the addition of custom Cloud Connectors with already over a hundred to choose from. These greatly simplify any interaction with a public API whether it be exposed on the cloud or on-premise. They come with connection-pooling and automated reconnection strategies.

To make the development of new Connectors extremely easy, MuleSoft provides you with the DevKit which guided by just a few annotations, will compile a Java POJO into a Connector by way of a Maven build. With this blog, we wish to give you a deep overview of the essentials of the .

Use Case

We’ll show you the main ingredients needed in the development of a new Connector by walking you through the code of our LDAP Connector. This will allow you to connect to any LDAP server and perform every LDAP operation:

  • bind: Authenticate against the LDAP server. This occurs automatically before each operation but can also be performed on request
  • search: Perform a LDAP search in a base DN with a given filter
  • lookup: Retrieve a unique LDAP entry
  • add: Creates a new LDAP entry
  • add attribute/s: Add specific attributes to an existing LDAP entry
  • modify: Update an existing LDAP entry
  • modify attribute/s: Update specific attributes of an existing LDAP entry
  • delete: Delete an existing LDAP entry
  • delete attribute/s: Delete specific attributes of an existing LDAP entry

Annotations

There are just a handful of fundamental Annotations to take note of:

  • @Connector, to mark a class as a Connector
  • @Configurable, to involve a field in configuration
  • @Connect, to establish connection to the Service
  • @Processor, to mark a method as an operation
  • @Disconnect, invoked when as part of the maintenance of the Connection Pool
  • @ValidateConnection, invoked before the invocation of an operation

Each of these must be present in order for DevKit to compile your POJO into a fully-fledged Connector which can be made available over an update-site for inclusion in the Studio pallette and thus re-usable across multiple projects. Each of them in turn can be helped by some auxilliary Annotations which we will discuss along the way. LDAPConnector also makes use of the following:

  • @ConnectionIdentifier, invoked for logging purposes
  • @Transformer, which marks a method as a Transformer of data-types / data formats in the context of the Connector

Let’s look at each of these in detail.

@Connector

This class-level annotation identifies your POJO as a Cloud Connector. An alternative is @Module which is used for generic mule extensions. Choosing the right
top-level annotation is important as it will limit the field and method annotations that you can use inside the POJO. As an example the connection management capabilities offered by the DevKit is only available when the POJO is annotated as @Connector. The following is a description of the attributes for this annotation:
  • name: The name of the connector. This is a simple string value which should not contain any spaces in it, it will be used to generate the namespace of the connector.
  • schemaVersion: The version of the generated schema. This usually should match Mule’s schema version, so for Mule 3.3.1 use schemaVersion=”3.3.1″. Keep in mind that if you add or change methods marked as @Processors or add @Configurable fields the generated schema will change and you should bump the version to avoid compatibility issues.
  • friendlyName: This is the name of the connector and is meant to be used only in Studio. This name will appear as the module name in the palette. Contrary to the name parameter, this field can contain spaces.
  • minMuleVersion: The minimum version of Mule that this connector supports. A check will be generated for runtime verification that the Mule version this connector is running on is the correct one.

@Configurable

This field-level annotation marks a field on your POJO as a configurable field which can appear in the xml-schema in your Mule Configuration as an attribute on the <config/> element. In Studio it will appear as an item in the visual dialog. You can mark the same field as @Optional and supply a @Default value when the user doesn’t supply a value. The @FriendlyName and @Placement Annotations can also help Studio decide how to label the field and where to group the same in the configuration dialog.

/**
     * The connection URL to the LDAP server with the following syntax: <code>ldap[s]://hostname:port/base_dn</code>.
     */
    @Configurable
    @Placement(group = "Connection", order = 0)
    @FriendlyName("URL")
    private String url;

@Connect

This annotation, in collaboration with the @Configurable annotation, provides an extremely powerful mechanism to configure the Connector. It marks a method for invocation at server startup and effectively creates a pool of Connections using the username and password parameters to connect to the provider service.

The @ConnectionKey annotated parameter is used as the key to the pool. Thus, the Connector can be invoked using a number of different credentials. In this case the dn is the connection key and can be decided at runtime. The instance of the Connector which corresponds to the key will be retrieved from the pool when an operation on the Connector is invoked. The @Optional and @FriendlyName annotations described above can also be used to add further semantics to the parameters.

The parameters you need to pass to the @Connect annotated method are obviously those which are relevant to the establishment of a new connection, as in this case we use the dn, the password and a value to represent that an anonymous bind to the LDAP server is requested (DevKit doesn’t support null values passed to the @Connect method).

An alternative to the @Connect annotation is worth a mention here. If you don’t want to exploit the connection pool facility you can use the @Start annotation instead. This will mean you can have a single instance per configuration. If you need to use more than one instance of your Connector, then you should manually configure the extra instances in the Mule Configuration.

@Connect
public void connect(@ConnectionKey @FriendlyName("Principal DN") String authDn, @Optional @FriendlyName("Password") String authPassword, @Optional String authentication) throws ConnectionException
{
    

@Disconnect

This method is invoked as part of the maintenance of the Connection Pool. The pool is configured with a max idle time value. When a connection lies in the pool without use for more than the configured time, then the method annotated with @Disconnect is invoked and subsequently the @Connect method. Also, when the @InvalidateConnectionOn annotation is used on a method to catch Exceptions, then the @Disconnect method will likewise be invoked with the subsequent reconnect.

@ValidateConnection

Prior to each invocation of the operations exposed by the @Processor annotation, the method annotated by @ValidateConnection will be invoked.

@ValidateConnection
public boolean isConnected() throws LDAPException
{

@ConnectionIdentifier

This is used purely for logging purposes.

@Processor

This annotation marks a method to expose it as an operation on your Connector. Any parameters it accepts will be exposed as attributes in the generated schema. Studio will also provide inputs for each of these in the configuration dialog. The LDAP operations highlighted above have each been implemented by @Processor annotated methods in the LDAPConnector class.  

@Processor
public void addFromMap(@Optional @FriendlyName("DN") String dn, @Optional @Default("#[payload:]") Map<String, Object> entry) throws Exception
{
    ...

@Transformer

This annotation marks a method as a Transformer of data-types / data formats in the context of the Connector

Documentation

It´s true to say that every experienced engineer knows that he or she ought to document the code.  It´s also true that we are rather lazy in producing this essential part of our engineering product! True to Mule´s glorious goal of making integration easy, DevKit doesn´t stop at making the development of new Connectors easy, but does the same for their documentation, by way of a simple set of tags (the presence of which is obligatory by default!) and produces an elegant tab-based web-site complete with Installation Guide, JavaDocs and example code.

There are several parts to the documentation:

Module Overview Section

This is produced by the JavaDocs before the Class definition upto the first </p> paragraph ending and produces links for each operation as we have listed them under Use Case above.

Summary Section

Takes the first sentence of the JavaDocs for each @Processor and @Transformer and the @Connect annotated methods in the Connector.

Configuration Section

Creates standard content describing the connection pool configuration followed by each {@sample.config } reference before the Class definition.

Connection Pool Section

Creates standard content describing the connection pool configuration followed by the JavaDocs for the @Connect annotated method.

Reconnection Strategies Section

Creates standard content describing the criteria governing decisions made when connections fail.

Message Processors Section

Lists each @Processor annotated method together with the JavaDocs for that method and the {@sample.config } reference listed there.

Sample.config

We should focus a little on this powerful tag which is embedded inside the JavaDocs for the class and methods. The search() method, for example uses the {@sample.xml ../../../doc/mule-module-ldap.xml.sample ldap:search-1} to reference the example configuration in mule-module-ldap.xml.sample underneath the doc/ directory. This file should contain all of the samples which will be surfaced by DevKit in the generated web-site.

<!-- BEGIN_INCLUDE(ldap:search-1) -->
	<!-- Case 1: Simple SUB_TREE search -->
    <ldap:search baseDn="ou=people,dc=mulesoft,dc=org" filter="(&amp;(objectClass=person)(sn=Doe))" scope="SUB_TREE"/>
<!-- END_INCLUDE(ldap:search-1) -->

Importing Connector into Studio

DevKit needs your connector to be part of a Maven project. You can create one for it like so:

It generates an Eclipse update site as part of its Maven build. All you need do is go to Help > Install New Software

Thus, our new LDAPConnector is ready for action in Studio

Example Configuration

So, how does our new LDAPConnector look in action? Well, take a look at the following config which exposes our Connector over http passing in the value of the cn attribute taken from the url. The flow will return an LDIF of the search results:

And there’s more…

We haven’t covered all of the annotations which you can use to enhance the power of your Connector. We’ll cover those in another post!

No related posts.


3 Responses to “Extending Mule with DevKit – the LDAPConnector”

yyamano October 23rd, 2012, 5:57 pm

Where can I get the latest version of the DevKit?

David Dossot October 23rd, 2012, 8:12 pm

All DevKit versions are in MuleSoft’s Maven repos. Latest release is 3.3.1 in https://repository.mulesoft.org/nexus/content/repositories/releases. Latest snapshot is 3.4-SNAPSHOT in https://repository.mulesoft.org/nexus/content/repositories/snapshots.

Federico Recio October 25th, 2012, 5:52 am

Actually, you don’t need to download anything. Just create your project from the Maven archetype and you can start creating your connector.

HTH,
Fede

Leave a Comment