001
014
015 package com.liferay.portal.backgroundtask.messaging;
016
017 import com.liferay.portal.kernel.backgroundtask.BackgroundTaskConstants;
018 import com.liferay.portal.kernel.backgroundtask.BackgroundTaskExecutor;
019 import com.liferay.portal.kernel.backgroundtask.BackgroundTaskResult;
020 import com.liferay.portal.kernel.backgroundtask.BackgroundTaskStatusMessageTranslator;
021 import com.liferay.portal.kernel.backgroundtask.BackgroundTaskStatusRegistryUtil;
022 import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocal;
023 import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocalManager;
024 import com.liferay.portal.kernel.backgroundtask.ClassLoaderAwareBackgroundTaskExecutor;
025 import com.liferay.portal.kernel.backgroundtask.SerialBackgroundTaskExecutor;
026 import com.liferay.portal.kernel.backgroundtask.ThreadLocalAwareBackgroundTaskExecutor;
027 import com.liferay.portal.kernel.lock.DuplicateLockException;
028 import com.liferay.portal.kernel.log.Log;
029 import com.liferay.portal.kernel.log.LogFactoryUtil;
030 import com.liferay.portal.kernel.messaging.BaseMessageListener;
031 import com.liferay.portal.kernel.messaging.DestinationNames;
032 import com.liferay.portal.kernel.messaging.Message;
033 import com.liferay.portal.kernel.messaging.MessageBusUtil;
034 import com.liferay.portal.kernel.util.ClassLoaderUtil;
035 import com.liferay.portal.kernel.util.InstanceFactory;
036 import com.liferay.portal.kernel.util.StackTraceUtil;
037 import com.liferay.portal.kernel.util.StringUtil;
038 import com.liferay.portal.kernel.util.Validator;
039 import com.liferay.portal.model.BackgroundTask;
040 import com.liferay.portal.service.BackgroundTaskLocalServiceUtil;
041 import com.liferay.portal.service.ServiceContext;
042
043
046 public class BackgroundTaskMessageListener extends BaseMessageListener {
047
048 public void setBackgroundTaskThreadLocalManager(
049 BackgroundTaskThreadLocalManager backgroundTaskThreadLocalManager) {
050
051 _backgroundTaskThreadLocalManager = backgroundTaskThreadLocalManager;
052 }
053
054 @Override
055 protected void doReceive(Message message) throws Exception {
056 long backgroundTaskId = (Long)message.get("backgroundTaskId");
057
058 BackgroundTaskThreadLocal.setBackgroundTaskId(backgroundTaskId);
059
060 ServiceContext serviceContext = new ServiceContext();
061
062 BackgroundTask backgroundTask =
063 BackgroundTaskLocalServiceUtil.amendBackgroundTask(
064 backgroundTaskId, null,
065 BackgroundTaskConstants.STATUS_IN_PROGRESS, serviceContext);
066
067 if (backgroundTask == null) {
068 return;
069 }
070
071 BackgroundTaskExecutor backgroundTaskExecutor = null;
072 BackgroundTaskStatusMessageListener
073 backgroundTaskStatusMessageListener = null;
074
075 int status = backgroundTask.getStatus();
076 String statusMessage = null;
077
078 try {
079 ClassLoader classLoader = ClassLoaderUtil.getPortalClassLoader();
080
081 String servletContextNames =
082 backgroundTask.getServletContextNames();
083
084 if (Validator.isNotNull(servletContextNames)) {
085 classLoader = ClassLoaderUtil.getAggregatePluginsClassLoader(
086 StringUtil.split(servletContextNames), false);
087 }
088
089 backgroundTaskExecutor =
090 (BackgroundTaskExecutor)InstanceFactory.newInstance(
091 classLoader, backgroundTask.getTaskExecutorClassName());
092
093 backgroundTaskExecutor = wrapBackgroundTaskExecutor(
094 backgroundTaskExecutor, classLoader);
095
096 BackgroundTaskStatusRegistryUtil.registerBackgroundTaskStatus(
097 backgroundTaskId);
098
099 BackgroundTaskStatusMessageTranslator
100 backgroundTaskStatusMessageTranslator =
101 backgroundTaskExecutor.
102 getBackgroundTaskStatusMessageTranslator();
103
104 if (backgroundTaskStatusMessageTranslator != null) {
105 backgroundTaskStatusMessageListener =
106 new BackgroundTaskStatusMessageListener(
107 backgroundTaskId,
108 backgroundTaskStatusMessageTranslator);
109
110 MessageBusUtil.registerMessageListener(
111 DestinationNames.BACKGROUND_TASK_STATUS,
112 backgroundTaskStatusMessageListener);
113 }
114
115 backgroundTask = BackgroundTaskLocalServiceUtil.fetchBackgroundTask(
116 backgroundTask.getBackgroundTaskId());
117
118 BackgroundTaskResult backgroundTaskResult =
119 backgroundTaskExecutor.execute(backgroundTask);
120
121 status = backgroundTaskResult.getStatus();
122 statusMessage = backgroundTaskResult.getStatusMessage();
123 }
124 catch (DuplicateLockException e) {
125 status = BackgroundTaskConstants.STATUS_QUEUED;
126 }
127 catch (Exception e) {
128 status = BackgroundTaskConstants.STATUS_FAILED;
129
130 if (backgroundTaskExecutor != null) {
131 statusMessage = backgroundTaskExecutor.handleException(
132 backgroundTask, e);
133 }
134
135 if (_log.isInfoEnabled()) {
136 if (statusMessage != null) {
137 statusMessage = statusMessage.concat(
138 StackTraceUtil.getStackTrace(e));
139 }
140 else {
141 statusMessage = StackTraceUtil.getStackTrace(e);
142 }
143 }
144
145 _log.error("Unable to execute background task", e);
146 }
147 finally {
148 BackgroundTaskLocalServiceUtil.amendBackgroundTask(
149 backgroundTaskId, null, status, statusMessage, serviceContext);
150
151 BackgroundTaskStatusRegistryUtil.unregisterBackgroundTaskStatus(
152 backgroundTaskId);
153
154 if (backgroundTaskStatusMessageListener != null) {
155 MessageBusUtil.unregisterMessageListener(
156 DestinationNames.BACKGROUND_TASK_STATUS,
157 backgroundTaskStatusMessageListener);
158 }
159
160 Message responseMessage = new Message();
161
162 responseMessage.put(
163 "backgroundTaskId", backgroundTask.getBackgroundTaskId());
164 responseMessage.put("name", backgroundTask.getName());
165 responseMessage.put("status", status);
166 responseMessage.put(
167 "taskExecutorClassName",
168 backgroundTask.getTaskExecutorClassName());
169
170 MessageBusUtil.sendMessage(
171 DestinationNames.BACKGROUND_TASK_STATUS, responseMessage);
172 }
173 }
174
175 protected BackgroundTaskExecutor wrapBackgroundTaskExecutor(
176 BackgroundTaskExecutor backgroundTaskExecutor,
177 ClassLoader classLoader) {
178
179 if (classLoader != ClassLoaderUtil.getPortalClassLoader()) {
180 backgroundTaskExecutor = new ClassLoaderAwareBackgroundTaskExecutor(
181 backgroundTaskExecutor, classLoader);
182 }
183
184 if (backgroundTaskExecutor.isSerial()) {
185 backgroundTaskExecutor = new SerialBackgroundTaskExecutor(
186 backgroundTaskExecutor);
187 }
188
189 backgroundTaskExecutor = new ThreadLocalAwareBackgroundTaskExecutor(
190 backgroundTaskExecutor, _backgroundTaskThreadLocalManager);
191
192 return backgroundTaskExecutor;
193 }
194
195 private static final Log _log = LogFactoryUtil.getLog(
196 BackgroundTaskMessageListener.class);
197
198 private BackgroundTaskThreadLocalManager _backgroundTaskThreadLocalManager;
199
200 }