Mule 4: Migrating DevKit projects to the new Mule SDK

mule 4 runtime

A few days ago, we proudly announced the GA release of Mule 4 and Studio 7, a major evolution of the core runtime behind Anypoint Platform. Mule 4 enhances application development velocity with up to 50% fewer steps and concepts to learn, including a simplified language for connectivity, clear access to data, automatic tuning, and smoother upgrade processes.

A major part of this release is the availability of the new Mule SDK. Mule SDK is the successor for Anypoint Connector DevKit, which we all know and love from Mule 3. Building on top of DevKit ideas, the new SDK allows extending Mule runtime with your own modules and connectors. Mule SDK is so powerful, that we even used it to rewrite all of Mule’s core modules and connectors (HTTP, JMS, Database, FTP, File, etc).

Among the SDK’s new capabilities are:

– No more generated code: Before, DevKit would take your project and generate code around it, creating a wrapper that would then bridge your code and Mule runtime internals. Now, the SDK relies on Mule APIs (more precisely, the Extensions API), and does not need to generate code between your connector and the runtime internals. This makes it easier to build connectors that are both backwards and forward compatible across version of the runtime. This also allows the runtime to inject cross-cutting functionality (such as streaming, media-type handling, reconnection, enrichment, etc), into existing modules without the need to rebuild them.

– Classloader isolation: Any artifact built with  Mule SDK will be completely isolated from the runtime. This will allow users to use any dependency or library without worrying about version conflicts with those shipped in the runtime.

– Consistent connector experience: The SDK automatically enforces consistency and adds cross-cutting functionality – such as repeatable streaming, embeddable DataWeave scripts, automatic static DataSense, and mimeTypes support – across your connector operations. For a list of functionalities, read the SDK documentation.

– Transactions: A transaction is a series of actions that work in an atomic way. For example, if you need to execute 5 steps, but the 4th fails, the first 3 steps are rollbacked. As a result, the system state does not change; instead, it prevents having an inconsistent state. Transactions are not permanent actions until the entire sequence of events are complete. You can now build both operations and message sources capable of participating in single resource or XA transactions.

– Non-blocking: Leveraging Mule 4’s new reactive engine, you can now develop non-blocking operations easily.

– Dynamic configurations: You can now use expressions on the module’s config elements. This makes it super easy to develop modules which enable simultaneous connections to many different credentials.

– Improved error handling: Support for leveraging the new error handling capabilities in Mule 4. Each component in your module lists the full list of possible errors, making it easier for users to handle errors.

– Better support for message sources: Now it’s possible to develop request-response message sources. They are naturally asynchronous and allow the use of embedded DataWeave expressions to build the response.

– Improved support for DataSense: There’s new, more powerful, model to describe your dynamic types. Now, the SDK supports dynamic DataSense for every individual parameter and for message sources. DataSense for static types is generated automatically

– Expression functions: You can now expose custom pieces of logic as DataWeave functions.

– And much more: Support for TLS, exclusive and null protected parameters, subtyping and importing types from other modules, support for scopes, routers, and more.

Migrating from DevKit

Anypoint Connector DevKit is not compatible with Mule 4. If you developed your own DevKit project for Mule 3, you’ll need to migrate it to the new SDK in order to use it in a Mule 4 application.

To help you with that, we developed a DevKit migration tool. By running this tool on your existing DevKit project, a new project will be generated which adapts your existing code into an SDK compatible project.

This tool is aimed to assist you on your migration. The tool will perform the heavy lifting for you, but it will still require your review and adjustment.

For example, the code that the tool generates serves as a bridge between the DevKit’s APIs and the SDK’s. Although that’s great for getting you started, in the long run, you will probably want to refactor the code in order to make it more maintainable.

Another common situation will be around concepts available in DevKit, which no longer exist in Mule 4/SDK. This includes concepts such as inbound/outbound message properties or the ability to directly manipulate the Mule Message/Event. Others concepts have changed considerably, such as the DataSense model. The tool will not be capable to migrate the specific pieces which are affected by unsupported components. However, it will clearly mark the error and will point you to documentation where you can find next steps to resolve the issue.

For example, consider the following processor taken from the Mule 3 Salesforce connector, which was developed using DevKit:

public XMLStreamReader invokeApexSoapMethod(String soapMethodName, XMLStreamReader input, MuleEvent event) {
  ...
}

This operation is migrated like this:

    @OnException(SalesforceSessionExpiredExceptionSalesforceSocketConnectionExceptionEnricher.class)
    @OutputResolver(output = ApexSoapMetadataCategoryResolver.class)
    public XMLStreamReader invokeApexSoapMethod(@Connection AbstractConfig connection,
            @DisplayName("Apex Class Method Name") @MetadataKeyId(ApexSoapMetadataCategoryResolver.class) String soapMethodName,
            @Content @TypeResolver(ApexSoapMetadataCategoryResolver.class) XMLStreamReader input)
            throws SalesforceException, SoapCallException {
        SalesforceConnector connector = new SalesforceConnector();
        connector.setConfig(connection);
        connector.initialize();
        // TODO: Accessing the Message or Event is no longer permitted in SDK operations.
        // Operations should clearly define which data they need through their parameters. This helps ensuring that:
        // -> Strict type checking works on every component
        // -> Avoid operations which only works if placed in a particular part of the flow or before/after some
        // component
        // -> No operation can access flowVars (they are exclusive to the user)
        // For more information about SDK operations, see: https://docs.mulesoft.com/mule-sdk/v/1.1/operations
        XMLStreamReader result = connector.invokeApexSoapMethod(soapMethodName, input, ((MuleEvent) null));
        return result;
    }

This operation cannot be directly migrated because it directly references the MuleEvent, which is not available on Mule SDK. The migration tool will still help you by adding a comment that explains the problem and points you to documentation on how to do an equivalent thing with Mule SDK.

For more information on how to use the DevKit migration tool, please refer to the documentation.

Learn more about Mule SDK

For more details on Mule SDK, please look at the SDK documentation and check out the below resources:


 


We'd love to hear your opinion on this post