- 5 minutes to read

Custom Connector: Complete Working Example

Copy one working configuration instead of assembling the parts yourself. This Mule ESB configuration shows every part of the Nodinite Custom Connector working together: the connector configuration, the ActiveMQ connection, the logging subflow, and an integration flow that logs at receive, success, and error.

  • ✅ Connector, destination, and logging subflow in one file
  • ✅ Logging at receive, success, and error
  • ✅ Correlation and Context Options on every Log Event

The Configuration

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:http="http://www.mulesoft.org/schema/mule/http"
      xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
      xmlns:file="http://www.mulesoft.org/schema/mule/file"
      xmlns:jms="http://www.mulesoft.org/schema/mule/jms"
      xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
      xmlns:nodinite="http://www.mulesoft.org/schema/mule/nodinite"
      xmlns="http://www.mulesoft.org/schema/mule/core" 
      xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
      xmlns:spring="http://www.springframework.org/schema/beans"
      version="CE-3.8.1">

    <!-- Configuration -->

    <nodinite:config name="Nodinite__Configuration" logAgentValueId="33" doc:name="Nodinite: Configuration"/>

    <spring:beans>
        <spring:bean id="ActiveMQ" class="org.apache.activemq.ActiveMQConnectionFactory">
            <spring:property name="brokerURL" value="tcp://10.0.0.10:61616"/>
        </spring:bean>
    </spring:beans>

    <jms:activemq-connector name="ActiveMQ" specification="1.1" brokerURL="tcp://10.0.0.10:61616" validateConnections="true" doc:name="Active MQ"/>

    <!-- Logging Sub Flow -->

    <sub-flow name="nodinite-logging-subflow">
        <logger message="#[sessionVars.nodiniteLogText]" level="INFO" doc:name="Logger"/>
        <set-variable variableName="payloadBeforeLogging" value="#[payload]" doc:name="Store Payload"/>
        
        <nodinite:create-log-event config-ref="Nodinite__Configuration" 
            endPointName="#[flowVars.endpointName]" 
            endpointUri="#[flowVars.endpointUri]" 
            endPointDirection="#[sessionVars.nodiniteEndPointDirection]" 
            endPointTypeId="60"
            originalMessageTypeName="#[sessionVars.nodiniteMessageTypeName]" 
            logStatus="#[sessionVars.nodiniteLogStatus]" 
            logText="#[sessionVars.nodiniteLogText]" 
            payload="#[payload]" 
            doc:name="Create JSON Log Event">
            <nodinite:context-properties ref="#[sessionVars.nodiniteContextValues]"/>
        </nodinite:create-log-event>
        
        <jms:outbound-endpoint queue="nodinite.log.events" connector-ref="ActiveMQ" doc:name="Post to ActiveMQ"/>
        
        <set-payload value="#[flowVars.payloadBeforeLogging]" doc:name="Restore Payload"/>
    </sub-flow>

    <!-- Main Flow -->

    <flow name="nodinite-mule-flow" doc:name="INT001: Invoice Processing">
        <file:inbound-endpoint path="/drop/invoices" responseTimeout="10000" doc:name="File" moveToDirectory="/processed/invoices"/>
        <set-variable variableName="endpointName" value="INT001: Receive Invoices" doc:name="Set Endpoint Name"/>
        <set-variable variableName="endpointUri" value="file:///drop/invoices" doc:name="Set Endpoint URI"/>
        
        <!-- Log: File Received -->
        <scripting:component doc:name="Set Logging Variables">
            <scripting:script engine="Groovy"><![CDATA[
                sessionVars['correlationId'] = message.id;
                sessionVars['nodiniteMessageTypeName'] = "Invoice#1.0";
                sessionVars['nodiniteLogText'] = "File Received";
                sessionVars['nodiniteLogStatus'] = 0;
                sessionVars['nodiniteEndPointDirection'] = 0;
                sessionVars['nodiniteContextValues'] = [
                    fileName: flowVars['originalFilename'],
                    fileSize: payload.length.toString(),
                    correlationId: sessionVars['correlationId']
                ];
                return payload;
            ]]></scripting:script>
        </scripting:component>
        <flow-ref name="nodinite-logging-subflow" doc:name="Log Receive"/>
        
        <!-- Transform message (your business logic here) -->
        <set-payload value="#['Invoice processed: ' + payload]" doc:name="Transform"/>
        
        <!-- Log: Processing Complete -->
        <scripting:component doc:name="Update Logging Variables">
            <scripting:script engine="Groovy"><![CDATA[
                sessionVars['nodiniteLogText'] = "Processing Complete";
                sessionVars['nodiniteLogStatus'] = 0;
                sessionVars['nodiniteEndPointDirection'] = 1;
                sessionVars['nodiniteContextValues'] = [
                    fileName: flowVars['originalFilename'],
                    invoiceNumber: "INV-12345",
                    amount: "1250.00",
                    currency: "USD",
                    correlationId: sessionVars['correlationId']
                ];
                return payload;
            ]]></scripting:script>
        </scripting:component>
        <flow-ref name="nodinite-logging-subflow" doc:name="Log Success"/>
        
        <file:outbound-endpoint path="/processed/invoices" responseTimeout="10000" doc:name="File"/>
        
        <!-- Exception Handler -->
        <catch-exception-strategy doc:name="Catch Exception Strategy">
            <scripting:component doc:name="Set Error Logging Variables">
                <scripting:script engine="Groovy"><![CDATA[
                    sessionVars['nodiniteMessageTypeName'] = "Invoice#1.0";
                    sessionVars['nodiniteLogText'] = "Processing failed: " + exception.getMessage();
                    sessionVars['nodiniteLogStatus'] = -1;
                    sessionVars['nodiniteEndPointDirection'] = 0;
                    sessionVars['nodiniteContextValues'] = [
                        fileName: flowVars['originalFilename'],
                        errorType: exception.getClass().getSimpleName(),
                        errorMessage: exception.getMessage(),
                        correlationId: sessionVars['correlationId']
                    ];
                    return payload;
                ]]></scripting:script>
            </scripting:component>
            <flow-ref name="nodinite-logging-subflow" doc:name="Log Error"/>
        </catch-exception-strategy>
    </flow>
</mule>

What the Example Shows

  • Connector configuration - LogAgentValueId and ActiveMQ connection
  • Reusable logging subflow - Single point of change for all logging
  • Integration flow - File-based invoice processing with logging at key points
  • Variable management - Setting endpoint names, URIs, and context properties
  • Exception handling - Proper error logging with status code -1; see Log Status Codes
  • Correlation - Consistent correlation ID across all log events; see Mule ESB Correlation
  • Context properties - Business metadata (invoice number, amount, currency)

Each field the connector writes is explained on Log Event Content.

Next Steps

Implement the Custom Connector
Log Event Content
Pickup Log Events Service

Custom Connector for Mule ESB Logging
Context Options
Log Status Codes
Mule ESB Correlation