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