Back to Home

The following simple component is handy for printing headers. It can also be used for transformers and using the OutBoundHeaders

import java.util.Iterator;
import java.util.Map;
 
import org.mule.api.annotations.param.InboundHeaders;
import org.mule.api.annotations.param.Payload;
 
 
public class FileDetails {
 
	public String fileDetails(@Payload String data,@InboundHeaders(value = "*") Map headers){
 
		Iterator iter = headers.keySet().iterator();
		String key;
		while ( iter.hasNext() ){
			key = (String)iter.next();
			System.out.println(key + ": " + headers.get(key));
		}
 
		return "";
	}
 
}

Accessing variables use a java transformer

public class ProcessData implements   MessageProcessor {
 
@Override
public MuleEvent process(MuleEvent event) throws MuleException {		 
     System.err.println("Got variable " + event.getFlowVariable("name"));
     return null;
}

Unit Testing Mule

This example shows how to test an asynchronous unit test retrieving data from vm's

import java.io.File;
 
import org.junit.Test;
import org.mule.api.MuleException;
import org.mule.api.MuleMessage;
import org.mule.client.DefaultLocalMuleClient;
import org.mule.tck.junit4.FunctionalTestCase;
 
 
public class TestQueue extends FunctionalTestCase {
 
	@Override
	protected String getConfigResources() {
		return "./src/main/app/asyncmule.xml";
	}
 
	@Test 
	public void testQueue () throws Exception {
		DefaultLocalMuleClient client = (DefaultLocalMuleClient) muleContext.getClient();
		client.dispatch("vm://DATA_IN", "WHAT F*CK", null);
		MuleMessage result = client.request("vm://DATA_OUT", 30000L);
		System.err.println ("got result: " + result.getPayloadAsString());
	}
}

Reading Properties with Java

properties can be saved in a flow, setting the appropriate scope is important.

In java properties can be read from the context in a number of ways:

Using components that extend from Callable

  public Object onCall(MuleEventContext eventContext, @Payload String payload) throws Exception {
   String returnPath = eventContext.getMessage().getProperty("myReturnPath", PropertyScope.OUTBOUND);

If the MuleMessage is passed:

 public void process(@Payload MuleMessage payload ){
 String returnPath = messge.getProperty("myReturnPath", PropertyScope.OUTBOUND);

Using an OuttboundHeader annotation

  public void process(@Payload String payload, @OutboundHeaders Map headers ){
    String prop = headers.get("propname");

Mule Callable

public class SqlDatasource implements Callable, MuleContextAware {
  DefaultMuleContext mulecontext;
 
	public Object onCall(MuleEventContext eventContext) throws Exception {
//		return "Hello Callable user "
//				+ eventContext.getMessage().getInboundProperty("name");
		JdbcConnector jdbcConnector = (JdbcConnector) context.getRegistry().lookupConnector("C3p0Connector"); 
		DataSource  datasource = (DataSource)jdbcConnector.getDataSource(); 
 
		MuleMessage msg = eventContext.requestEvent("jdbc://SELECT * FROM TEST", 0);
		return msg;
	}
 
	@Override
	public void setMuleContext(MuleContext context) {
		mulecontext = (DefaultMuleContext) context;
 
	}
 
 
}

Java and Groovy Direct SQl Acess

In Java

public String process(@Payload String message) throws Exception {
  	// return "Hello Callable user "
		// + eventContext.getMessage().getInboundProperty("name");
 
		JdbcConnector jdbcConnector = (JdbcConnector) mulecontext.getRegistry()
				.lookupConnector("LocalOracle");
		DataSource datasource = (DataSource) jdbcConnector.getDataSource();
		Connection connection = (Connection) datasource.getConnection();
 
		String query = "select * from PAYMENT where PAYMENT_ID = 438254";
		Statement stat = connection.createStatement();
		ResultSet rs = stat.executeQuery(query);
 
		if ( rs != null ){
			return printResultSet(rs);
		}
 
		return "";
 
	}
 
	public String  printResultSet(ResultSet rs) {
		try {
		String result = "";
		ResultSetMetaData metaData = rs.getMetaData();
		int columns = metaData.getColumnCount();
		while (rs.next()) {// reading one record
			for (int i = 1; i <= columns; ++i) {// this reads column by column
				result += "<" + metaData.getColumnName(i) + ">";
				result += rs.getString(i);
				result += "</" + metaData.getColumnName(i) + ">\n";
			}// closes for loop
		}// closes while loop
		return result;
		} catch (Exception e ){
			System.err.println ("Error printing result set .. ");
			return ("Error printing result set .. ");
 
		}
	}

In Groovy:

import groovy.sql.Sql
import java.sql.Connection;
import java.sql.Statement;
import javax.sql.DataSource;
import org.mule.transport.jdbc.JdbcConnector;
 
System.err.println("Running local oracle")
JdbcConnector jdbcConnector = (JdbcConnector) muleContext.getRegistry()
  			.lookupConnector("LocalOracle");
DataSource datasource = (DataSource) jdbcConnector.getDataSource();
Connection connection = (Connection) datasource.getConnection();
 
Sql sql = new Sql();
sql.setConnection(connection)
sql.eachRow("select * from PAYMENT where PAYMENT_ID = 438254")
{ 
   println "$it.PAYMENT_ID -- ${it.DATE_PAYED} --" 
}

Queues

Throttling Queues

Sometimes custom message processors are unable to process messages at the same rate as they are consumed from the inbound JMS queue, so controlling the consumption rate becomes necessary. This issue can be addressed by using the TransactedPollingJmsMessageReceiver in combination with either local or XA transaction and pollingFrequency property. First, configure your connector as follows (ActiveMQ connector is used in this example, but any other JMS connector, standard or implementation-specific, can be used):

<jms:activemq-connector name="activeMQJmsConnector" 
                        brokerURL="tcp://localhost:61616" 
                        disableTemporaryReplyToDestinations="true"
                         numberOfConcurrentTransactedReceivers="1" 
                        maxRedelivery="100000">
    <service-overrides transactedMessageReceiver="com.mulesoft.mule.transport.jms.TransactedPollingJmsMessageReceiver"/> 
</jms:activemq-connector>

Then have your inbound JMS endpoint configured as follows:

<jms:inbound-endpoint queue="mule.in">
    <jms:transaction action="ALWAYS_BEGIN"/>
    <property key="pollingFrequency" value="10000"/>
</jms:inbound-endpoint>

The numberOfConcurrentTransactedReceivers parameter controls the batch size, and the pollingFrequency property controls how often queue will be polled. In this example, one message will be consumed every 10 seconds.

Groovy Queues

Note if we have multiple connectors (e.g. ACTIVE_MQ and ACTIVEM_MQ2, we can specify it in the URI

def message = muleContext.client.request("jms://stagingQueue?connector=ACTIVE_MQ1", 0)

or

 
muleContext.client.dispatch("vm://IN"), message, null )
  • note:* the vm needs to be in lower case

JMS Retry Policy

Exposing the Command Line

https://github.com/mulesoft/mule-jockey

@Command("list-some-things")
@Options([
    @Option(name="x", longName="url", description="URL", defaultValue="http://localhost/api"),
    @Option(name="u", longName="username", description="Username", defaultValue="admin"),
    @Option(name="p", longName="password", description="Password", defaultValue="admin"),
])

Http Component: Simple Web Server

Mule http endpoints can be used to serve up static pages (including javascript)

<flow name="main-http">
    <http:inbound-endpoint address="http://localhost:8080/static"/>
    <http:static-resource-handler resourceBase="${app.home}/docroot"  defaultFile="index.html"/>
</flow>

Note:

  • you can also have hard coded paths as in this example
  • and put the http path to a hard code value like “static” as below .. to avoid conflict with other http and choice blocks on the same ip.
<flow name="dbflowFlow1" doc:name="dbflowFlow1">
		<http:inbound-endpoint exchange-pattern="request-response"
			host="localhost" port="8089" doc:name="HTTP" path="static"/>              
                <http:static-resource-handler  resourceBase="C:\\Users\\Owner\\data\\" defaultFile="hello.html"></http:static-resource-handler>               
	</flow>

Http Component: Logging access

the logger can be used to create an access.log of http access

 <logger
            message="#[header:INBOUND:Host] #[header:INBOUND:http.version] #[header:INBOUND:http.method] #[header:INBOUND:http.request] #[header:INBOUND:MULE_REMOTE_CLIENT_ADDRESS] #[header:INBOUND:User-Agent]"
            category="mule.http.accesslog"
            level="INFO />

Jetty

Jetty can be added as a Global Element

Exploded Development No-cache in place development ..point the jetty servlet at the local resource files and edit away

<jetty:connector name="Jetty"  doc:name="Jetty">
		<!--  "${app.home}/classes/docroot" /> -->
		<jetty:webapps port="8091" host="127.0.0.1"
directory="/home/richard/workspace/workspace_reverseMapping_rights/rightsdashboard2/src/main/resources/docroot" />
	</jetty:connector>

For Production:

   <jetty:connector name="jettyConnector" doc:name="Jetty">
        <jetty:webapps port="8089" host="0.0.0.0" directory="${app.home}/docroot"/>
    </jetty:connector>

One tip is that the default folder for a Jetty webapp is root, so the doc root structure needs to be: and doc root in the src/main/resources as this is the folder that gets deployed.

Back to Home

Mule Components

Components Notes
Expression Transformer Purpose: Executes one or more expressions on the current message. The results of these expressions becomes the payload of the current message.

Jetty with Cache Control

This is the default web.xml with default servlet configuration ..

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">

	<servlet>
		<servlet-name>default</servlet-name>
		<servlet-class>org.mortbay.jetty.servlet.DefaultServlet</servlet-class>
		<!--  <init-param>
			<param-name>aliases</param-name>
			<param-value>false</param-value>
		</init-param>
		<init-param>
			<param-name>acceptRanges</param-name>
			<param-value>true</param-value>
		</init-param>
		<init-param>
			<param-name>dirAllowed</param-name>
			<param-value>true</param-value>
		</init-param>
		<init-param>
			<param-name>welcomeServlets</param-name>
			<param-value>false</param-value>
		</init-param>
		<init-param>
			<param-name>redirectWelcome</param-name>
			<param-value>false</param-value>
		</init-param>
		<init-param>
			<param-name>maxCacheSize</param-name>
			<param-value>0</param-value>
		</init-param>
		<init-param>
			<param-name>maxCachedFileSize</param-name>
			<param-value>0</param-value>
		</init-param>
		<init-param>
			<param-name>maxCachedFiles</param-name>
			<param-value>2048</param-value>
		</init-param>
		<init-param>
			<param-name>gzip</param-name>
			<param-value>true</param-value>
		</init-param>
		<init-param>
			<param-name>useFileMappedBuffer</param-name>
			<param-value>false</param-value>
		</init-param> -->
		<!-- <init-param> <param-name>resourceCache</param-name> <param-value>resourceCache</param-value> </init-param> -->
		<init-param>
			<param-name>cacheControl</param-name>
			<param-value>no-store,no-cache,must-revalidate</param-value>
			<!--  <param-value>max-age=0,public</param-value> -->
		</init-param>
		<load-on-startup>0</load-on-startup>  
	</servlet>

	<servlet>
		<servlet-name>proxy</servlet-name>
		<servlet-class>org.mortbay.servlet.ProxyServlet$Transparent</servlet-class>
		<init-param>
			<param-name>ProxyTo</param-name>
			<param-value>http://localhost:8090/jsonTest</param-value>
		</init-param>
		<init-param>
			<param-name>Prefix</param-name>
			<param-value>/</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>proxy</servlet-name>
		<url-pattern>/jsonTest</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>default</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>
</web-app>

Jetty Proxy

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:javaee="http://java.sun.com/xml/ns/javaee"
	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 
	<session-config>
		<session-timeout>10</session-timeout>
	</session-config>
 
	<servlet>
		<servlet-name>GoogleProxy</servlet-name>
		<servlet-class>org.mortbay.servlet.ProxyServlet$Transparent</servlet-class>
		<load-on-startup>1</load-on-startup>
		<init-param>
			<param-name>ProxyTo</param-name>
			<param-value>http://www.google.com</param-value>
		</init-param>
		<init-param>
			<param-name>Prefix</param-name>
			<param-value>/google</param-value>
		</init-param>
	</servlet>
 
	<servlet-mapping>
		<servlet-name>GoogleProxy</servlet-name>
		<url-pattern>/google/*</url-pattern>
	</servlet-mapping>
 
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
 
</web-app>

Routing Based on Properties

in this example a property is set prior to choice

message.setProperty("error", "true")

And the choice block roots with

#[groovy:message.getProperty('error').equals('true')]

Mule JDBC Component

Jdbc driver may not load on the server with “no suitable driver”, one solution is to add the drivers to mule-enterprise-standalone-3.2.2\lib\endorsed

Allegedly the “connection pool needs to be set up even before the application is instantiated.

Poor Variable Substitution in Queries (and a workaround)

For a simple deal:

select DEAL_TYPE from DEAL where DEAL_ID = 394 

returns the arrayList [[DEAL_TYPE:M]]

When we try and use a variable:

<set-variable variableName="col" value="DEAL_TYPE" doc:name="Variable"/> 

Use the variable in the expression, either

select #[variable:col] from DEAL where DEAL_ID = 394 

or

select #[groovy:message.getInvocationProperty('col')] from DEAL where DEAL_ID = 394 

then the result is different value [[:1:DEAL_TYPE]]

The Work around

There is a legacy generic component

<outbound-endpoint address="jdbc://select #[variable:col] from DEAL where DEAL_ID = 394" exchange-pattern="request-response" connector-ref="Database" doc:name="Generic"/>

That seems to support substitution much better

Database

Using the databsae form java

import java.sql.Connection;
import java.sql.SQLException;
 
import javax.sql.DataSource;
 
import org.mule.DefaultMuleContext;
import org.mule.api.MuleContext;
import org.mule.api.annotations.param.Payload;
import org.mule.api.context.MuleContextAware;
import org.mule.transport.jdbc.JdbcConnector;
 
 
public class DBConnection implements MuleContextAware {
  DefaultMuleContext context ;
 
	public void process(@Payload String payload ) throws SQLException{
		JdbcConnector jdbcConnector = (JdbcConnector) context.getRegistry().lookupConnector("C3p0Connector");
        DataSource  datasource = (DataSource)jdbcConnector.getDataSource();
        Connection c = datasource.getConnection();
        // available methods   etc.
        c.commit();
        c.rollback();
 
	}
 
	@Override
	public void setMuleContext(MuleContext context) {
		this.context = (DefaultMuleContext) context;
 
	}

JDBC quick and dirty database debug

If one tries to output the default jdbc query result to a web page, it will prompt you to download the result 2 work arounds are:

  1. add a groovy component with return payload.toString()
  2. on the jdbc query “references” tab set the Response transformer to Object_to_String and mime type to plain/text

Java Components

  • Singleton - only one object is created for all requests
<component >
     <singleton-object class="com.foo.Bar"/>
</component>
  • Prototype - a new object is created for every request or every time the object is requested from the registry this is the default component
<component >
     <prototype-object class="com.foo.Bar">
</component>
 
<!—or short form -->
 
<component class="com.foo.Bar"/>
  • Pooled - Only applies to component object
<pooled-component class="com.foo.Bar"/>

Message Processors

Message Processor Description
All Broadcast a message to multiple targets
Async Run a chain of message processors in a separate thread
Choice Send a message to the first matching message processor
Collection Aggregator Aggregate messages into a message collection
Collection Splitter Split a message that is a collection
Custom Aggregator A custom-written class that aggregates messages
Custom Processor A custom-written message processor
First Successful Iterate through message processors until one succeeds (added in 3.0.1)
Idempotent Message Filter Filter out duplicate message by message ID
Idempotent Secure Hash Message Filter Filter out duplicate message by message content
Message Chunk Aggregator Aggregate messages into a single message
Message Chunk Splitter Split a message into fixed-size chunks
Message Filter Filter messages using a filter
Processor Chain Create a message chain from multiple targets
Recipient List Send a message to multiple endpoints
Request Reply Receive a message for asynchronous processing and accept the asynchronous response on a different channel
Resequencer Reorder a list of messages
Round Robin Round-robin among a list of message processors (added in 3.0.1)
Until Successful Repeatedly attempt to process a message until successful
Splitter Split a message using an expression
WireTap Send a message to an extra message processor as well as to the next message processor in the chain

Collection Splitter

Takes an array type collection and splits elements to flows, can be used nicly with async scope to to parallel processing over a list. Note: doesn't work with map's or collections:

Map Splitter

A hidden component (not on the pallet), but will work with a Map like the collection splitter.

Some what cryptically the key is passed in the invocation propety and the map data in the payload

def key = message.getInvocationProperty('key')
System.err.println 'got key: ' + key
System.err.println 'got data ' + payload

WireTap

<wire-tap></wire-tap>

Choice

Used to wrap a when block ? <choice doc:name=“Choice”>

until successful

http://blogs.mulesoft.org/meet-until-successful-store-and-forward-for-mule/

  • Dispatching to outbound endpoints, for example when you’re reaching out to a remote web service that may have availability issues,
  • Execution of a component method, for example to retry an action on a Spring Bean that may depend on unreliable resources,
  • A sub-flow execution, to keep re-executing several actions until they all succeed, Any other message processor execution, to allow more complex scenarios.
     <until-successful objectStore-ref="objectStore"
                          failureExpression="#[header:INBOUND:http.status != 202]"
                          maxRetries="6"
                          secondsBetweenRetries="600">
            <http:outbound-endpoint address="http://acme.com/api/flakey"
                                    exchange-pattern="request-response"
                                    method="POST" />
        </until-successful>

Starting and Stopping Flows

<script:component>
  <script:script engine="groovy">
  if ( payload.equals("start")){
 System.err.println("starting endpoint .. ")
 muleContext.getRegistry().lookupFlowConstruct("MockRestFlow1").start() // or stop()
} else {
 System.err.println("starting endpoint .. ")
 muleContext.getRegistry().lookupFlowConstruct("MockRestFlow1").stop() // or stop()
}
  </script:script>
</script:component>

Also available thru the mbeans console

Mule and FTP Server

Add the following dependencies to the pom or download and add to the project.

  	<!--  mina ftp server  -->
		<dependency>
			<groupId>org.apache.ftpserver</groupId>
			<artifactId>ftpserver-core</artifactId>
			<version>1.0.6</version>
		</dependency>

Create the java class and configure:

  • the path to user property files
  • this example has an example of creating a new users
import java.io.File;
 
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.User;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.SaltedPasswordEncryptor;
import org.apache.ftpserver.usermanager.UserFactory;
 
public class StartFtpServer {
 
  public StartFtpServer() {
		try {
			FtpServerFactory serverFactory = new FtpServerFactory();
			ListenerFactory factory = new ListenerFactory();
			// set the port of the listener
			factory.setPort(2221);
 
			// replace the default listener
			serverFactory.addListener("default", factory.createListener());
			PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
			userManagerFactory.setFile(new File("/home/richard/workspace/workspace_strim/ftpserver/src/main/resources/user.properties"));
			userManagerFactory.setPasswordEncryptor(new SaltedPasswordEncryptor());
 
 
			UserManager userManagement = userManagerFactory.createUserManager();
			UserFactory userFact = new UserFactory();
			userFact.setName("rich");
			userFact.setPassword("rich");
			userFact.setHomeDirectory("C:/");
			User user = userFact.createUser();
			userManagement.save(user);
 
			serverFactory.setUserManager(userManagement);
			serverFactory.setUserManager(userManagerFactory.createUserManager());
			// start the server
			FtpServer server = serverFactory.createServer();
			server.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
 
}

Adding write permissions

      // Allow user to write to directory
  		List<Authority> authorities = new ArrayList<Authority>();
			authorities.add(new WritePermission());
			userFact.setAuthorities(authorities);

Mule Ajax/Cometd

  • What’s Comet? Pushing Data to The Net over HTTP
  • What’s Bayeux? Channel & JSON Based Comet Protocol
  • What’s CometD? Comet Client and Server Implementation using Bayeux
  • What’s WebSockets? Html5 standard

The Ajax transport is implemented using CometD (http://cometd.org/). It's basically a server dedicated to handling bi-directional HTTP events.

Mule provides a Javascript client based on the Dojo JS library that communicates with the CometD server, which is established by Mule when an Ajax connector and outbound endpoint are configured.

The Ajax connector specifies a serverUrl, like:

   <ajax:connector name="ajaxServer" serverUrl="http://0.0.0.0:8090/ajax/" ... />

Mule provide their own Mule.js as part of the ajax component

Mule RSS, Atom, Scraper

Rest Proxy

  <http:inbound-endpoint
        address="http://localhost:8082/rest-proxy"
        exchange-pattern="request-response" doc:name="HTTP"/>
    <copy-properties propertyName="*" doc:name="Property"/>
        <scripting:component doc:name="Groovy">
            <scripting:script engine="Groovy"><![CDATA[System.err.println("relative path :" + message.getInboundProperty('http.relative.path') )
System.err.println("query string :" + message.getInboundProperty('http.query.string') )]]></scripting:script>
        </scripting:component>
        <round-robin doc:name="Round Robin">
            <http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:8082/goodbye/nick" doc:name="HTTP"/>
            <http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:8081/#[message.inboundProperties['http.relative.path']]/#[message.inboundProperties['http.query.string']]" doc:name="Copy_of_HTTP"/>
        </round-robin>
    <response>
        <copy-properties propertyName="*" doc:name="Property"/>
    </response>

Working with OpenCSV

Processing a CSV into a database with more control ..

public class ProcessFile implements MuleContextAware {
	DefaultMuleContext context
	char delimiter = ';'
 
	public void process(@Payload InputStream inFile ){
		// get the database connection 
		JdbcConnector jdbcConnector = (JdbcConnector) context.getRegistry().lookupConnector("LocalDb");
		DataSource datasource = (DataSource) jdbcConnector.getDataSource();
		Connection connection = (Connection) datasource.getConnection();
 
		// process the csv 
		CSVReader reader = new CSVReader(new InputStreamReader(inFile), delimiter)
		String [] nextLine
		int lineCount = 0
		while ((nextLine = reader.readNext()) != null) {
			if ( lineCount != 0 ){
				String sql = "insert in row where values (\"${nextLine[1]}\",\"${nextLine[2]}\", \"${nextLine[3]}\", \"${nextLine[4]}\")"
				Statement stat = connection.createStatement();
				ResultSet rs = stat.executeUpdate(stat)
			}
			lineCount++
		}
		inFile.close()
	}

Saving Database to CSV

OpenCsv also works with a ResultSet to return a CSV

try {
			statement = connection.createStatement();
			String sql = "Select * from io_file_log where io_file_log_id > " + config.io_file_log_id
			System.err.println("Running:" + sql)
			result = statement.executeQuery(sql);
			if (result != null ){
				StringWriter output = new StringWriter();
				CSVWriter writer = new CSVWriter(output)				
				writer.writeAll(result, true);
				System.err.println(output.toString())				
				return output.toString()
 
			} 

Misc

mule-module-throttling-ee-3.4.0 - SimpleThrottlingPolicy

mule-module-management-3.4.0.jar - has a yourKit profiler - Log4jagent - mx4jagent org\mule\module\management\util\ManagementUtils

mule-module-pgp-3.4.0.jar mmc-agent-impl-3.4.0.jar

“Custom Business events ” mule-module-tracking-ee-3.4.0.jar com\mulesoft\mule\tracking\event\ ServerNotifications EventNotifcations TransactionMessageProcessor.class EventNotification.class AbstractEventNotificationFiringMessageProcessor.class EventMessageProcessor.class ServerNotifications.class EventNotificationListener.class

 
mule_components.txt · Last modified: 2014/06/09 13:46 by root
 
RSS - 200 © CrosswireDigitialMedia Ltd