View Javadoc

1   /*
2    * $Id: EndpointPollingJob.java 22396 2011-07-12 21:26:04Z mike.schilling $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport.quartz.jobs;
12  
13  import org.mule.api.MuleContext;
14  import org.mule.api.MuleMessage;
15  import org.mule.api.ThreadSafeAccess;
16  import org.mule.api.config.MuleProperties;
17  import org.mule.api.endpoint.EndpointBuilder;
18  import org.mule.api.endpoint.InboundEndpoint;
19  import org.mule.api.transaction.Transaction;
20  import org.mule.api.transaction.TransactionCallback;
21  import org.mule.api.transport.PropertyScope;
22  import org.mule.module.client.MuleClient;
23  import org.mule.transaction.MuleTransactionConfig;
24  import org.mule.transaction.TransactionCoordination;
25  import org.mule.transaction.TransactionTemplate;
26  import org.mule.transport.AbstractMessageReceiver;
27  import org.mule.transport.quartz.QuartzConnector;
28  import org.mule.transport.quartz.QuartzMessageReceiver;
29  import org.mule.transport.quartz.i18n.QuartzMessages;
30  
31  import java.util.concurrent.atomic.AtomicBoolean;
32  
33  import org.apache.commons.logging.Log;
34  import org.apache.commons.logging.LogFactory;
35  import org.quartz.Job;
36  import org.quartz.JobDataMap;
37  import org.quartz.JobExecutionContext;
38  import org.quartz.JobExecutionException;
39  import org.quartz.SchedulerException;
40  
41  /**
42   * Will receive on an endpoint and dispatch it to the component set via the Receiver information.
43   */
44  public class EndpointPollingJob extends AbstractJob
45  {
46      /**
47       * The logger used for this class
48       */
49      protected transient Log logger = LogFactory.getLog(getClass());
50  
51      protected void doExecute(JobExecutionContext jobExecutionContext) throws JobExecutionException
52      {
53          final JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
54  
55          String receiverKey = (String) jobDataMap.get(QuartzMessageReceiver.QUARTZ_RECEIVER_PROPERTY);
56          if (receiverKey == null)
57          {
58              throw new JobExecutionException(QuartzMessages.receiverNotInJobDataMap().getMessage());
59          }
60  
61          String connectorName = (String) jobDataMap.get(QuartzMessageReceiver.QUARTZ_CONNECTOR_PROPERTY);
62          if (connectorName == null)
63          {
64              throw new JobExecutionException(QuartzMessages.connectorNotInJobDataMap().getMessage());
65          }
66  
67          final QuartzConnector connector = (QuartzConnector) muleContext.getRegistry().lookupConnector(connectorName);
68          if (connector == null)
69          {
70              throw new JobExecutionException(QuartzMessages.noConnectorFound(connectorName).getMessage());
71          }
72  
73          final AbstractMessageReceiver receiver = (AbstractMessageReceiver) connector.lookupReceiver(receiverKey);
74          if (receiver == null)
75          {
76              throw new JobExecutionException(
77                      QuartzMessages.noReceiverInConnector(receiverKey, connectorName).getMessage());
78          }
79  
80  
81          final EndpointPollingJobConfig jobConfig = (EndpointPollingJobConfig) jobDataMap.get(QuartzConnector.PROPERTY_JOB_CONFIG);
82          if (jobConfig == null)
83          {
84              throw new JobExecutionException(
85                      QuartzMessages.missingJobDetail(QuartzConnector.PROPERTY_JOB_CONFIG).getMessage());
86          }
87  
88  
89          try
90          {
91              logger.debug("Attempting to receive event on: " + jobConfig.getEndpointRef());
92              TransactionTemplate<Void> tt;
93              final AtomicBoolean pollGlobalEndpoint = new AtomicBoolean(false);
94  
95              //TODO MULE-5050 work around because the builder is no longer idempotent, we now cache the endpoint instance
96              InboundEndpoint endpoint = muleContext.getRegistry().lookupObject(jobConfig.getEndpointRef() + ".quartz-job");
97              if(endpoint==null)
98              {
99                  final EndpointBuilder epBuilder = muleContext.getRegistry().lookupEndpointBuilder(jobConfig.getEndpointRef());
100                 pollGlobalEndpoint.set(epBuilder != null);
101 
102                 if (pollGlobalEndpoint.get())
103                 {
104                     // referencing a global endpoint, fetch configuration from it
105                     endpoint = epBuilder.buildInboundEndpoint();
106 
107                     //TODO MULE-5050 work around because the builder is no longer idempotent, we now cache the endpoint instance
108                     muleContext.getRegistry().registerObject(jobConfig.getEndpointRef() + ".quartz-job", endpoint);
109                     tt = new TransactionTemplate<Void>(endpoint.getTransactionConfig(), muleContext);
110                 }
111                 else
112                 {
113                     // a simple inline endpoint
114                     tt = new TransactionTemplate<Void>(new MuleTransactionConfig(), muleContext);
115                 }
116             }
117             else
118             {
119                 tt = new TransactionTemplate<Void>(endpoint.getTransactionConfig(), muleContext);
120             }
121 
122 
123             final InboundEndpoint finalEndpoint = endpoint;
124             TransactionCallback<Void> cb = new TransactionCallback<Void>()
125             {
126                 public Void doInTransaction() throws Exception
127                 {
128                     Transaction tx = TransactionCoordination.getInstance().getTransaction();
129                     if (tx != null)
130                     {
131                         tx.begin();
132                     }
133 
134                     MuleMessage result = null;
135                     if (pollGlobalEndpoint.get())
136                     {
137                         result = finalEndpoint.getConnector().request(finalEndpoint, jobConfig.getTimeout());
138                     }
139                     else
140                     {
141                         MuleClient client = new MuleClient(connector.getMuleContext());
142                         result = client.request(jobConfig.getEndpointRef(), jobConfig.getTimeout());
143                     }
144 
145                     if (result != null)
146                     {
147                         if (logger.isDebugEnabled())
148                         {
149                             logger.debug("Received event on: " + jobConfig.getEndpointRef());
150                         }
151                         if (pollGlobalEndpoint.get())
152                         {
153                             result.applyTransformers(null, finalEndpoint.getTransformers());
154                         }
155 
156                         //we need to do this because
157                         result = (MuleMessage) ((ThreadSafeAccess) result).newThreadCopy();
158 
159                         //Add the context properties to the message.
160                         result.addProperties(jobDataMap, PropertyScope.INVOCATION);
161 
162                         receiver.routeMessage(result);
163                     }
164                     // nowhere to return
165                     return null;
166                 }
167             };
168 
169             tt.execute(cb);
170         }
171         catch (RuntimeException rex)
172         {
173             // rethrow
174             throw rex;
175         }
176         catch (Exception e)
177         {
178             throw new JobExecutionException(e);
179         }
180     }
181 }