7

I have a java class that creates a clean MongoDB database with seeded collections. It automatically identifies if the database is missing and creates it. I would like to run this when I start MuleEsb. This way I don't need to remember to invoke it before I start mule. I was hoping to put it inside a flow and run that flow once, automatically when mule starts up.

Is there a way to do this one-time operation when mule starts?

--- Update ---

As per the conversation below I added the following to my mule config and the flow is automatically triggered.

<quartz:connector name="Quartz" validateConnections="true"/>

<flow name="testService1">
    <quartz:inbound-endpoint name="runOnce" repeatCount="0" repeatInterval="1" jobName="job1" connector-ref="Quartz">
        <quartz:event-generator-job>
            <quartz:payload>foo</quartz:payload>
        </quartz:event-generator-job>
    </quartz:inbound-endpoint>

    <logger message="INBOUND HEADERS = #[headers:inbound:*]" level="WARN"/>
</flow>
General Grievance
  • 4,555
  • 31
  • 31
  • 45
TERACytE
  • 7,553
  • 13
  • 75
  • 111

2 Answers2

12

I created a JIRA a month ago to request such a feature: http://www.mulesoft.org/jira/browse/MULE-6877

For now, you can use a trick: a Quartz inbound endpoint with an event generator job repeatCount = 0 that will trigger your flow only once at startup.

Alternatively, you can listen to context events and invoke a flow when a specific event is triggered. The following shows a listener that invokes a startup and a shutdown flow:

package com.acme;

import org.mule.DefaultMuleEvent;
import org.mule.DefaultMuleMessage;
import org.mule.MessageExchangePattern;
import org.mule.api.MuleException;
import org.mule.api.MuleRuntimeException;
import org.mule.api.context.notification.MuleContextNotificationListener;
import org.mule.config.i18n.MessageFactory;
import org.mule.construct.Flow;
import org.mule.context.notification.MuleContextNotification;

public class FlowInvokingContextListener implements MuleContextNotificationListener<MuleContextNotification>
{
    private Flow startingFlow;
    private Flow stoppingFlow;

    public void onNotification(final MuleContextNotification notification)
    {
        if (notification.getAction() == MuleContextNotification.CONTEXT_STARTED)
        {
            sendNotificationToFlow(notification, startingFlow);
        }
        else if (notification.getAction() == MuleContextNotification.CONTEXT_STOPPING)
        {
            sendNotificationToFlow(notification, stoppingFlow);
        }
    }

    private void sendNotificationToFlow(final MuleContextNotification notification, final Flow flow)
    {
        try
        {
            final DefaultMuleEvent event = new DefaultMuleEvent(new DefaultMuleMessage(notification,
                notification.getMuleContext()), MessageExchangePattern.REQUEST_RESPONSE, startingFlow);
            flow.process(event);
        }
        catch (final MuleException me)
        {
            throw new MuleRuntimeException(MessageFactory.createStaticMessage("Failed to invoke: "
                                                                              + startingFlow), me);
        }
    }

    public void setStartingFlow(final Flow startingFlow)
    {
        this.startingFlow = startingFlow;
    }

    public void setStoppingFlow(final Flow stoppingFlow)
    {
        this.stoppingFlow = stoppingFlow;
    }
}

Configured with:

<spring:beans>
    <spring:bean name="flowInvokingContextListener"
        class="com.acme.FlowInvokingContextListener"
        p:startingFlow-ref="startFlow" p:stoppingFlow-ref="stopFlow" />
</spring:beans>

<notifications>
    <notification event="CONTEXT" />
    <notification-listener ref="flowInvokingContextListener" />
</notifications>
David Dossot
  • 33,403
  • 4
  • 38
  • 72
  • Nice answer! Thank-you. If I create a quartz inbound-endpoint, don't I also need to specify an outbound-endpoint? – TERACytE Jul 04 '13 at 00:42
  • No you don't, a single quartz inbound-endpoint in your flow will do it. – David Dossot Jul 04 '13 at 00:43
  • Since I'm using v3.2.1, the DefaultMuleMessage() constructor does not have a FlowConstruct option. Plus I think the quartz solution is a little cleaner since it appears I can put the quartz:inbound-endpoint inside the flow I want to automatically run. I'm not familiar with running a flow through quartz though. Are there any examples of this? – TERACytE Jul 04 '13 at 15:55
  • Sure, look at the example there http://www.mulesoft.org/documentation/display/current/Quartz+Transport+Reference#QuartzTransportReference-EventGeneratorJob – David Dossot Jul 04 '13 at 16:07
  • Very helpful David. Thank-you. I updated the question above with the quartz example I am running. It successfully triggers at start-up, though it runs twice instead of once. – TERACytE Jul 04 '13 at 17:17
  • A repeatCount of zero is what's needed. Not one. I'll update the question. Thank-you again for your help! – TERACytE Jul 04 '13 at 17:19
  • Perfect, I fixed my answer. Gotta start thinking of upgrading BTW... Mule 3.2.1 is antiquated :) – David Dossot Jul 04 '13 at 17:24
  • what is p:startingFlow-ref - I don't see that namespace defined anywhere and all google searches I have done find this post and clones thereof. Would be great to know what p: is – user192127 Apr 20 '16 at 21:13
  • This is the standard p namespace from Spring. – David Dossot Apr 20 '16 at 21:14
  • Not sure if I understand, what's the startFlow and stopFlow should look like? Cause console screams, that it's not recognizible. Cannot resolve reference to bean 'startFlow' while setting bean property 'startingFlow'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'startFlow' is defined – deyvw Dec 04 '17 at 14:54
  • @DawidWiniarz They both should be private flows. – David Dossot Dec 05 '17 at 15:20
  • Yes, I've checked it already. Is there any chance to start it in general, to listen to all flows? – deyvw Dec 06 '17 at 16:30
  • Cause, my mian goal is to inform me, when for example someone will undeploy my mule app. So, there is a listener which will tell me, when the 'undeploy' event occurs. – deyvw Dec 12 '17 at 13:36
  • @DawidWiniarz Mule notification framework will definitely raise events that you can listen to to be notified of an app going down. – David Dossot Dec 12 '17 at 23:02
0

Another option is to use a custom agent that does it:
http://www.mulesoft.org/documentation/display/current/Mule+Agents

Seba
  • 2,319
  • 15
  • 14