
org.mule.module.client.MuleClient Maven / Gradle / Ivy
Show all versions of mule-module-client Show documentation
/*
* Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
package org.mule.module.client;
import org.mule.DefaultMuleEvent;
import org.mule.DefaultMuleMessage;
import org.mule.MessageExchangePattern;
import org.mule.VoidMuleEvent;
import org.mule.api.FutureMessageResult;
import org.mule.api.MuleContext;
import org.mule.api.MuleEvent;
import org.mule.api.MuleException;
import org.mule.api.MuleMessage;
import org.mule.api.config.ConfigurationBuilder;
import org.mule.api.config.ConfigurationException;
import org.mule.api.config.MuleConfiguration;
import org.mule.api.config.MuleProperties;
import org.mule.api.context.MuleContextBuilder;
import org.mule.api.endpoint.EndpointBuilder;
import org.mule.api.endpoint.EndpointURI;
import org.mule.api.endpoint.InboundEndpoint;
import org.mule.api.endpoint.OutboundEndpoint;
import org.mule.api.lifecycle.Disposable;
import org.mule.api.lifecycle.InitialisationException;
import org.mule.api.registry.RegistrationException;
import org.mule.api.registry.ServiceException;
import org.mule.api.service.Service;
import org.mule.api.transformer.Transformer;
import org.mule.api.transport.ReceiveException;
import org.mule.client.DefaultLocalMuleClient;
import org.mule.config.DefaultMuleConfiguration;
import org.mule.config.i18n.CoreMessages;
import org.mule.config.spring.SpringXmlConfigurationBuilder;
import org.mule.context.DefaultMuleContextBuilder;
import org.mule.context.DefaultMuleContextFactory;
import org.mule.endpoint.EndpointURIEndpointBuilder;
import org.mule.endpoint.MuleEndpointURI;
import org.mule.security.MuleCredentials;
import org.mule.service.ServiceCompositeMessageSource;
import org.mule.transformer.TransformerUtils;
import org.mule.transport.NullPayload;
import org.mule.util.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* MuleClient
is a simple interface for Mule clients to send and
* receive events from a Mule Server. In most Mule applications events are triggered
* by some external occurrence such as a message being received on a queue or a file
* being copied to a directory. The Mule client allows the user to send and receive
* events programmatically through its API.
*
* The client defines a {@link EndpointURI} which is used to determine how a message is
* sent of received. The url defines the protocol, the endpointUri destination of the
* message and optionally the endpoint to use when dispatching the event. For
* example:
*
* vm://my.object
dispatches to a my.object
destination
* using the VM endpoint. There needs to be a global VM endpoint registered for the
* message to be sent.
*
* jms://jmsProvider/orders.topic
dispatches a JMS message via the
* globally registered jmsProvider over a topic destination called
* orders.topic
.
*
* jms://orders.topic
is equivalent to the above except that the
* endpoint is determined by the protocol, so the first JMS endpoint is used.
*
* Note that there must be a configured MuleManager for this client to work. It will
* use the one available using muleContext
*
* @see org.mule.endpoint.MuleEndpointURI
*/
public class MuleClient implements Disposable
{
/**
* logger used by this class
*/
protected static final Log logger = LogFactory.getLog(MuleClient.class);
/**
* The local MuleContext instance.
*/
private MuleContext muleContext;
private List dispatchers = new ArrayList();
private MuleCredentials user;
private DefaultMuleContextFactory muleContextFactory = new DefaultMuleContextFactory();
private ConcurrentMap inboundEndpointCache = new ConcurrentHashMap();
private ConcurrentMap outboundEndpointCache = new ConcurrentHashMap();
/**
* Creates a Mule client that will use the default serverEndpoint when connecting to a remote
* server instance.
*
* @throws MuleException
*/
protected MuleClient() throws MuleException
{
this(true);
}
public MuleClient(boolean startContext) throws MuleException
{
init(startContext);
}
public MuleClient(MuleContext context) throws MuleException
{
this.muleContext = context;
init(false);
}
/**
* Configures a Mule client instance using the the default
* {@link SpringXmlConfigurationBuilder} to parse configResources
.
*
* @param configResources a config resource location to configure this client
* with
* @throws ConfigurationException if there is a {@link MuleContext} instance already
* running in this JVM or if the builder fails to configure the
* Manager
*/
public MuleClient(String configResources) throws MuleException
{
this(configResources, new SpringXmlConfigurationBuilder(configResources));
}
/**
* Configures a new Mule client and either uses an existing Manager running in
* this JVM or creates a new empty {@link MuleContext}
*
* @param user the username to use when connecting to a remote server instance
* @param password the password for the user
* @throws MuleException
*/
public MuleClient(String user, String password) throws MuleException
{
init(/* startManager */true);
this.user = new MuleCredentials(user, password.toCharArray());
}
/**
* Configures a Mule client instance
*
* @param configResources a config resource location to configure this client
* with
* @param builder the configuration builder to use
* @throws ConfigurationException is there is a {@link MuleContext} instance already
* running in this JVM or if the builder fails to configure the
* Manager
* @throws InitialisationException
*/
public MuleClient(String configResources, ConfigurationBuilder builder)
throws ConfigurationException, InitialisationException
{
if (builder == null)
{
logger.info("Builder passed in was null, using default builder: "
+ SpringXmlConfigurationBuilder.class.getName());
builder = new SpringXmlConfigurationBuilder(configResources);
}
logger.info("Initializing Mule...");
muleContext = muleContextFactory.createMuleContext(builder);
}
/**
* Configures a Mule client instance
*
* @param configResources a config resource location to configure this client
* with
* @param builder the configuration builder to use
* @param user the username to use when connecting to a remote server instance
* @param password the password for the user
* @throws ConfigurationException is there is a {@link MuleContext} instance already
* running in this JVM or if the builder fails to configure the
* Manager
* @throws InitialisationException
*/
public MuleClient(String configResources, ConfigurationBuilder builder, String user, String password)
throws ConfigurationException, InitialisationException
{
this(configResources, builder);
this.user = new MuleCredentials(user, password.toCharArray());
}
/**
* Initialises a default {@link MuleContext} for use by the client.
*
* @param startManager start the Mule context if it has not yet been initialised
* @throws MuleException
*/
private void init(boolean startManager) throws MuleException
{
if (muleContext == null)
{
logger.info("No existing ManagementContext found, creating a new Mule instance");
MuleContextBuilder contextBuilder = new DefaultMuleContextBuilder();
DefaultMuleConfiguration config = new DefaultMuleConfiguration();
config.setClientMode(true);
contextBuilder.setMuleConfiguration(config);
muleContext = muleContextFactory.createMuleContext(contextBuilder);
}
else
{
logger.info("Using existing MuleContext: " + muleContext);
}
if (!muleContext.isStarted() && startManager == true)
{
logger.info("Starting Mule...");
muleContext.start();
}
}
/**
* Dispatches an event asynchronously to a endpointUri via a Mule server. The URL
* determines where to dispatch the event to.
*
* @param url the Mule URL used to determine the destination and transport of the
* message
* @param payload the object that is the payload of the event
* @param messageProperties any properties to be associated with the payload. In
* the case of JMS you could set the JMSReplyTo property in these
* properties.
* @throws org.mule.api.MuleException
*/
public void dispatch(String url, Object payload, Map messageProperties) throws MuleException
{
dispatch(url, new DefaultMuleMessage(payload, messageProperties, muleContext));
}
/**
* Dispatches an event asynchronously to a endpointUri via a Mule server. The URL
* determines where to dispatch the event to.
*
* @param url the Mule URL used to determine the destination and transport of the
* message
* @param message the message to send
* @throws org.mule.api.MuleException
*/
public void dispatch(String url, MuleMessage message) throws MuleException
{
OutboundEndpoint endpoint = getOutboundEndpoint(url, MessageExchangePattern.ONE_WAY, null);
MuleEvent event = getEvent(message, MessageExchangePattern.ONE_WAY);
endpoint.process(event);
}
/**
* Sends an event synchronously to a component
*
* @param component the name of the Mule component to send to
* @param transformers a comma separated list of transformers to apply to the
* result message
* @param payload the object that is the payload of the event
* @param messageProperties any properties to be associated with the payload. as
* null
* @return the result message if any of the invocation
* @throws org.mule.api.MuleException if the dispatch fails or the components or
* transfromers cannot be found
*
* Deprecated from 3.6.0 - Only supported with Services. Sending message to remote flows is not supported.
*/
@Deprecated
public MuleMessage sendDirect(String component, String transformers, Object payload, Map messageProperties)
throws MuleException
{
MuleMessage message = new DefaultMuleMessage(payload, messageProperties, muleContext);
return sendDirect(component, transformers, message);
}
/**
* Sends an event synchronously to a component
*
* @param componentName the name of the Mule component to send to
* @param transformers a comma separated list of transformers to apply to the
* result message
* @param message the message to send
* @return the result message if any of the invocation
* @throws org.mule.api.MuleException if the dispatch fails or the components or
* transfromers cannot be found
*
* Deprecated from 3.6.0 - Only supported with Services. Sending message to remote flows is not supported.
*/
@Deprecated
public MuleMessage sendDirect(String componentName, String transformers, MuleMessage message)
throws MuleException
{
Service service = muleContext.getRegistry().lookupService(componentName);
if (service == null)
{
throw new ServiceException(CoreMessages.objectNotRegistered("Service", componentName));
}
List trans = null;
if (transformers != null)
{
trans = TransformerUtils.getTransformers(transformers, muleContext);
}
InboundEndpoint endpoint = getDefaultClientEndpoint(service, message.getPayload(), true);
MuleEvent event = new DefaultMuleEvent(message, endpoint, service);
if (logger.isDebugEnabled())
{
logger.debug("MuleClient sending event direct to: " + componentName + ". MuleEvent is: " + event);
}
MuleEvent resultEvent = service.sendEvent(event);
MuleMessage result = resultEvent == null || VoidMuleEvent.getInstance().equals(resultEvent)
? null
: resultEvent.getMessage();
if (logger.isDebugEnabled())
{
logger.debug("Result of MuleClient sendDirect is: "
+ (result == null ? "null" : result.getPayload()));
}
if (result != null && trans != null)
{
result.applyTransformers(resultEvent, trans);
}
return result;
}
/**
* Dispatches an event asynchronously to a component
*
* @param component the name of the Mule components to dispatch to
* @param payload the object that is the payload of the event
* @param messageProperties any properties to be associated with the payload. as
* null
* @throws org.mule.api.MuleException if the dispatch fails or the components or
* transfromers cannot be found
*
* Deprecated from 3.6.0 - Only supported with Services. Sending message to remote flows is not supported.
*/
@Deprecated
public void dispatchDirect(String component, Object payload, Map messageProperties) throws MuleException
{
dispatchDirect(component, new DefaultMuleMessage(payload, messageProperties, muleContext));
}
/**
* Dispatches an event asynchronously to a component
*
* @param componentName the name of the Mule components to dispatch to
* @param message the message to send
* @throws org.mule.api.MuleException if the dispatch fails or the components or
* transfromers cannot be found
*
* Deprecated from 3.6.0 - Only supported with Services. Sending message to remote flows is not supported.
*/
@Deprecated
public void dispatchDirect(String componentName, MuleMessage message) throws MuleException
{
Service service = muleContext.getRegistry().lookupService(componentName);
if (service == null)
{
throw new ServiceException(CoreMessages.objectNotRegistered("Service", componentName));
}
InboundEndpoint endpoint = getDefaultClientEndpoint(service, message.getPayload(), false);
MuleEvent event = new DefaultMuleEvent(message, endpoint, service);
if (logger.isDebugEnabled())
{
logger.debug("MuleClient dispatching event direct to: " + componentName + ". MuleEvent is: " + event);
}
service.dispatchEvent(event);
}
/**
* Sends an event request to a URL, making the result of the event trigger
* available as a Future result that can be accessed later by client code.
*
* @param url the url to make a request on
* @param payload the object that is the payload of the event
* @param messageProperties any properties to be associated with the payload. as
* null
* @return the result message if any of the invocation
* @throws org.mule.api.MuleException if the dispatch fails or the components or
* transfromers cannot be found
*/
public FutureMessageResult sendAsync(String url, Object payload, Map messageProperties)
throws MuleException
{
return sendAsync(url, payload, messageProperties, 0);
}
/**
* Sends an event request to a URL, making the result of the event trigger
* available as a Future result that can be accessed later by client code.
*
* @param url the URL to make a request on
* @param message the message to send
* @return the result message if any of the invocation
* @throws org.mule.api.MuleException if the dispatch fails or the components or
* transfromers cannot be found
*/
public FutureMessageResult sendAsync(final String url, final MuleMessage message) throws MuleException
{
return sendAsync(url, message, MuleEvent.TIMEOUT_NOT_SET_VALUE);
}
/**
* Sends an event request to a URL, making the result of the event trigger
* available as a Future result that can be accessed later by client code.
*
* @param url the url to make a request on
* @param payload the object that is the payload of the event
* @param messageProperties any properties to be associated with the payload. as
* null
* @param timeout how long to block in milliseconds waiting for a result
* @return the result message if any of the invocation
* @throws org.mule.api.MuleException if the dispatch fails or the components or
* transfromers cannot be found
*/
public FutureMessageResult sendAsync(final String url,
final Object payload,
final Map messageProperties,
final int timeout) throws MuleException
{
return sendAsync(url, new DefaultMuleMessage(payload, messageProperties, muleContext), timeout);
}
/**
* Sends an event request to a URL, making the result of the event trigger
* available as a Future result that can be accessed later by client code.
*
* @param url the url to make a request on
* @param message the message to send
* @param timeout how long to block in milliseconds waiting for a result
* @return the result message if any of the invocation
* @throws org.mule.api.MuleException if the dispatch fails or the components or
* transfromers cannot be found
*/
public FutureMessageResult sendAsync(final String url, final MuleMessage message, final int timeout)
throws MuleException
{
Callable