Package org.mule.transport.vm

Source Code of org.mule.transport.vm.VMMessageReceiver

/*
* 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.transport.vm;

import org.mule.DefaultMuleMessage;
import org.mule.api.DefaultMuleException;
import org.mule.api.MessagingException;
import org.mule.api.MuleContext;
import org.mule.api.MuleEvent;
import org.mule.api.MuleException;
import org.mule.api.MuleMessage;
import org.mule.api.ThreadSafeAccess;
import org.mule.api.construct.FlowConstruct;
import org.mule.api.endpoint.InboundEndpoint;
import org.mule.api.execution.ExecutionCallback;
import org.mule.api.execution.ExecutionTemplate;
import org.mule.api.lifecycle.CreateException;
import org.mule.api.transport.Connector;
import org.mule.transport.ContinuousPollingReceiverWorker;
import org.mule.transport.PollingReceiverWorker;
import org.mule.transport.TransactedPollingMessageReceiver;
import org.mule.util.queue.Queue;
import org.mule.util.queue.QueueSession;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.RejectedExecutionException;

/**
* <code>VMMessageReceiver</code> is a listener for events from a Mule service which then simply passes
* the events on to the target service.
*/
public class VMMessageReceiver extends TransactedPollingMessageReceiver
{

    private VMConnector connector;

    public VMMessageReceiver(Connector connector, FlowConstruct flowConstruct, InboundEndpoint endpoint)
        throws CreateException
    {
        super(connector, flowConstruct, endpoint);
        this.setReceiveMessagesInTransaction(endpoint.getTransactionConfig().isTransacted());
        this.connector = (VMConnector) connector;
    }

    /*
     * We only need to start scheduling this receiver if event queueing is enabled on the connector; otherwise
     * events are delivered via onEvent/onCall.
     */
    @Override
    protected void schedule() throws RejectedExecutionException, NullPointerException, IllegalArgumentException
    {
        if (!endpoint.getExchangePattern().hasResponse())
        {
            super.schedule();
        }
    }

    @Override
    protected void doDispose()
    {
        // template method
    }

    @Override
    protected void doConnect() throws Exception
    {
        if (!endpoint.getExchangePattern().hasResponse())
        {
            // Ensure we can create a vm queue
            QueueSession queueSession = connector.getQueueSession();
            Queue q = queueSession.getQueue(endpoint.getEndpointURI().getAddress());
            if (logger.isDebugEnabled())
            {
                logger.debug("Current queue depth for queue: " + endpoint.getEndpointURI().getAddress() + " is: "
                             + q.size());
            }
        }
    }

    @Override
    protected void doDisconnect() throws Exception
    {
        // template method
    }

    public void onMessage(MuleMessage message) throws MuleException
    {
        // Rewrite the message to treat it as a new message
        MuleMessage newMessage = new DefaultMuleMessage(message.getPayload(), message, endpoint.getMuleContext());
        routeMessage(newMessage);
    }

    public MuleMessage onCall(final MuleMessage message) throws MuleException
    {

        ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
        //TODO remove code to change message MuleContext once MULE-7357 gets fixed
        MuleContext originaMuleContext = message.getMuleContext();
        try
        {
            Thread.currentThread().setContextClassLoader(endpoint.getMuleContext().getExecutionClassLoader());
            ((DefaultMuleMessage)message).setMuleContext(originaMuleContext);
            ExecutionTemplate<MuleEvent> executionTemplate = createExecutionTemplate();
            MuleEvent resultEvent = executionTemplate.execute(new ExecutionCallback<MuleEvent>()
            {
                @Override
                public MuleEvent process() throws Exception
                {
                    MuleEvent event = routeMessage(message);
                    MuleMessage returnedMessage = event == null ? null : event.getMessage();
                    if (returnedMessage != null)
                    {
                        returnedMessage.release();
                    }
                    return event;
                }
            });
            if (resultEvent != null)
            {
                DefaultMuleMessage resultMessage = (DefaultMuleMessage) resultEvent.getMessage();
                resultMessage.setMuleContext(originaMuleContext);
                return resultMessage;
            }
            else
            {
                return null;
            }
        }
        catch (MessagingException e)
        {
            //Already handled by TransactionTemplate, return ES result
            return e.getMuleMessage();
        }
        catch (MuleException e)
        {
            endpoint.getMuleContext().getExceptionListener().handleException(e);
            throw e;
        }
        catch (Exception e)
        {
            endpoint.getMuleContext().getExceptionListener().handleException(e);
            throw new DefaultMuleException(e);
        }
        finally
        {
            ((DefaultMuleMessage) message).setMuleContext(originaMuleContext);
            message.release();
            Thread.currentThread().setContextClassLoader(originalClassLoader);
        }
    }

    /**
     * It's impossible to process all messages in the receive transaction
     */
    @Override
    protected List<MuleMessage> getMessages() throws Exception
    {
        if (isReceiveMessagesInTransaction())
        {
            MuleEvent message = getFirstMessage();
            if (message == null)
            {
                return null;
            }
           
            List<MuleMessage> messages = new ArrayList<MuleMessage>(1);
            ((DefaultMuleMessage)message.getMessage()).setMuleContext(endpoint.getMuleContext());
            messages.add(message.getMessage());
            return messages;
        }
        else
        {
            return getFirstMessages();
        }
    }
   
    protected List<MuleMessage> getFirstMessages() throws Exception
    {
        // The queue from which to pull events
        QueueSession qs = connector.getTransactionalResource(endpoint);
        Queue queue = qs.getQueue(endpoint.getEndpointURI().getAddress());

        // The list of retrieved messages that will be returned
        List<MuleMessage> messages = new LinkedList<MuleMessage>();

        int batchSize = getBatchSize(queue.size());

        // try to get the first event off the queue
        MuleEvent message = (MuleEvent) queue.poll(connector.getQueueTimeout());

        if (message != null)
        {
            // keep first dequeued event
            ((DefaultMuleMessage)message.getMessage()).setMuleContext(endpoint.getMuleContext());
            messages.add(message.getMessage());

            // keep batching if more events are available
            for (int i = 0; i < batchSize && message != null; i++)
            {
                message = (MuleEvent)queue.poll(0);
                if (message != null)
                {
                    messages.add(new DefaultMuleMessage(message.getMessage(), endpoint.getMuleContext()));
                }
            }
        }

        // let our workManager handle the batch of events
        return messages;
    }
   
    protected MuleEvent getFirstMessage() throws Exception
    {
        // The queue from which to pull events
        QueueSession qs = connector.getTransactionalResource(endpoint);
        Queue queue = qs.getQueue(endpoint.getEndpointURI().getAddress());
        // try to get the first event off the queue
        return (MuleEvent) queue.poll(connector.getQueueTimeout());
    }

    @Override
    protected boolean hasNoMessages()
    {
        try
        {
            QueueSession qs = connector.getQueueSession();
            Queue queue = qs.getQueue(endpoint.getEndpointURI().getAddress());
            return queue.size() == 0;
        }
        catch (Exception e)
        {
            return false;
        }
    }

    @Override
    protected void processMessage(Object msg) throws Exception
    {
        MuleMessage message = (MuleMessage) msg;

        if (message instanceof ThreadSafeAccess)
        {
            message = (MuleMessage)((ThreadSafeAccess) message).newThreadCopy();
        }
        routeMessage(message);
    }

    /*
     * We create our own "polling" worker here since we need to evade the standard scheduler.
     */
    @Override
    protected PollingReceiverWorker createWork()
    {
        return new ContinuousPollingReceiverWorker(this);
    }   
}
TOP

Related Classes of org.mule.transport.vm.VMMessageReceiver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.