001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskConstants;
018    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskLockHelperUtil;
019    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskStatus;
020    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskStatusRegistry;
021    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocalManager;
022    import com.liferay.portal.kernel.bean.BeanReference;
023    import com.liferay.portal.kernel.cluster.Clusterable;
024    import com.liferay.portal.kernel.exception.PortalException;
025    import com.liferay.portal.kernel.messaging.DestinationNames;
026    import com.liferay.portal.kernel.messaging.Message;
027    import com.liferay.portal.kernel.messaging.MessageBusUtil;
028    import com.liferay.portal.kernel.repository.model.Folder;
029    import com.liferay.portal.kernel.transaction.TransactionCommitCallbackRegistryUtil;
030    import com.liferay.portal.kernel.util.ContentTypes;
031    import com.liferay.portal.kernel.util.OrderByComparator;
032    import com.liferay.portal.kernel.util.StringPool;
033    import com.liferay.portal.kernel.util.StringUtil;
034    import com.liferay.portal.kernel.util.Validator;
035    import com.liferay.portal.model.BackgroundTask;
036    import com.liferay.portal.model.User;
037    import com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil;
038    import com.liferay.portal.service.ServiceContext;
039    import com.liferay.portal.service.base.BackgroundTaskLocalServiceBaseImpl;
040    import com.liferay.portal.util.PortletKeys;
041    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
042    
043    import java.io.File;
044    import java.io.InputStream;
045    import java.io.Serializable;
046    
047    import java.util.Date;
048    import java.util.HashMap;
049    import java.util.List;
050    import java.util.Map;
051    import java.util.concurrent.Callable;
052    
053    /**
054     * @author Daniel Kocsis
055     * @author Michael C. Han
056     */
057    public class BackgroundTaskLocalServiceImpl
058            extends BackgroundTaskLocalServiceBaseImpl {
059    
060            @Override
061            public BackgroundTask addBackgroundTask(BackgroundTask backgroundTask) {
062                    Map<String, Serializable> taskContextMap =
063                            backgroundTask.getTaskContextMap();
064    
065                    if (taskContextMap == null) {
066                            taskContextMap = new HashMap<>();
067    
068                            backgroundTask.setTaskContextMap(taskContextMap);
069                    }
070    
071                    _backgroundTaskThreadLocalManager.serializeThreadLocals(taskContextMap);
072    
073                    backgroundTask = super.addBackgroundTask(backgroundTask);
074    
075                    final long backgroundTaskId = backgroundTask.getBackgroundTaskId();
076    
077                    TransactionCommitCallbackRegistryUtil.registerCallback(
078                            new Callable<Void>() {
079    
080                                    @Override
081                                    public Void call() throws Exception {
082                                            backgroundTaskLocalService.triggerBackgroundTask(
083                                                    backgroundTaskId);
084    
085                                            return null;
086                                    }
087    
088                            });
089    
090                    return backgroundTask;
091            }
092    
093            @Override
094            public BackgroundTask addBackgroundTask(
095                            long userId, long groupId, String name,
096                            String[] servletContextNames, Class<?> taskExecutorClass,
097                            Map<String, Serializable> taskContextMap,
098                            ServiceContext serviceContext)
099                    throws PortalException {
100    
101                    User user = userPersistence.findByPrimaryKey(userId);
102    
103                    final long backgroundTaskId = counterLocalService.increment();
104    
105                    BackgroundTask backgroundTask = backgroundTaskPersistence.create(
106                            backgroundTaskId);
107    
108                    backgroundTask.setCompanyId(user.getCompanyId());
109                    backgroundTask.setGroupId(groupId);
110                    backgroundTask.setUserId(userId);
111                    backgroundTask.setUserName(user.getFullName());
112                    backgroundTask.setName(name);
113                    backgroundTask.setServletContextNames(
114                            StringUtil.merge(servletContextNames));
115                    backgroundTask.setTaskExecutorClassName(taskExecutorClass.getName());
116    
117                    if (taskContextMap == null) {
118                            taskContextMap = new HashMap<>();
119                    }
120    
121                    _backgroundTaskThreadLocalManager.serializeThreadLocals(taskContextMap);
122    
123                    backgroundTask.setTaskContextMap(taskContextMap);
124    
125                    backgroundTask.setStatus(BackgroundTaskConstants.STATUS_NEW);
126    
127                    backgroundTaskPersistence.update(backgroundTask);
128    
129                    TransactionCommitCallbackRegistryUtil.registerCallback(
130                            new Callable<Void>() {
131    
132                                    @Override
133                                    public Void call() throws Exception {
134                                            backgroundTaskLocalService.triggerBackgroundTask(
135                                                    backgroundTaskId);
136    
137                                            return null;
138                                    }
139    
140                            });
141    
142                    return backgroundTask;
143            }
144    
145            @Override
146            public void addBackgroundTaskAttachment(
147                            long userId, long backgroundTaskId, String fileName, File file)
148                    throws PortalException {
149    
150                    BackgroundTask backgroundTask = getBackgroundTask(backgroundTaskId);
151    
152                    Folder folder = backgroundTask.addAttachmentsFolder();
153    
154                    PortletFileRepositoryUtil.addPortletFileEntry(
155                            backgroundTask.getGroupId(), userId, BackgroundTask.class.getName(),
156                            backgroundTask.getPrimaryKey(), PortletKeys.BACKGROUND_TASK,
157                            folder.getFolderId(), file, fileName, ContentTypes.APPLICATION_ZIP,
158                            false);
159            }
160    
161            @Override
162            public void addBackgroundTaskAttachment(
163                            long userId, long backgroundTaskId, String fileName,
164                            InputStream inputStream)
165                    throws PortalException {
166    
167                    BackgroundTask backgroundTask = getBackgroundTask(backgroundTaskId);
168    
169                    Folder folder = backgroundTask.addAttachmentsFolder();
170    
171                    PortletFileRepositoryUtil.addPortletFileEntry(
172                            backgroundTask.getGroupId(), userId, BackgroundTask.class.getName(),
173                            backgroundTask.getPrimaryKey(), PortletKeys.BACKGROUND_TASK,
174                            folder.getFolderId(), inputStream, fileName,
175                            ContentTypes.APPLICATION_ZIP, false);
176            }
177    
178            @Override
179            public BackgroundTask amendBackgroundTask(
180                    long backgroundTaskId, Map<String, Serializable> taskContextMap,
181                    int status, ServiceContext serviceContext) {
182    
183                    return amendBackgroundTask(
184                            backgroundTaskId, taskContextMap, status, null, serviceContext);
185            }
186    
187            @Override
188            public BackgroundTask amendBackgroundTask(
189                    long backgroundTaskId, Map<String, Serializable> taskContextMap,
190                    int status, String statusMessage, ServiceContext serviceContext) {
191    
192                    BackgroundTask backgroundTask =
193                            backgroundTaskPersistence.fetchByPrimaryKey(backgroundTaskId);
194    
195                    if (backgroundTask == null) {
196                            return null;
197                    }
198    
199                    if (taskContextMap != null) {
200                            _backgroundTaskThreadLocalManager.serializeThreadLocals(
201                                    taskContextMap);
202    
203                            backgroundTask.setTaskContextMap(taskContextMap);
204                    }
205    
206                    if ((status == BackgroundTaskConstants.STATUS_FAILED) ||
207                            (status == BackgroundTaskConstants.STATUS_SUCCESSFUL)) {
208    
209                            backgroundTask.setCompleted(true);
210                            backgroundTask.setCompletionDate(new Date());
211                    }
212    
213                    backgroundTask.setStatus(status);
214    
215                    if (Validator.isNotNull(statusMessage)) {
216                            backgroundTask.setStatusMessage(statusMessage);
217                    }
218    
219                    backgroundTaskPersistence.update(backgroundTask);
220    
221                    return backgroundTask;
222            }
223    
224            @Clusterable(onMaster = true)
225            @Override
226            public void cleanUpBackgroundTask(
227                    final BackgroundTask backgroundTask, final int status) {
228    
229                    try {
230                            BackgroundTaskLockHelperUtil.unlockBackgroundTask(backgroundTask);
231                    }
232                    catch (Exception e) {
233                    }
234    
235                    TransactionCommitCallbackRegistryUtil.registerCallback(
236                            new Callable<Void>() {
237    
238                                    @Override
239                                    public Void call() throws Exception {
240                                            Message message = new Message();
241    
242                                            message.put(
243                                                    "backgroundTaskId",
244                                                    backgroundTask.getBackgroundTaskId());
245                                            message.put("name", backgroundTask.getName());
246                                            message.put("status", status);
247                                            message.put(
248                                                    "taskExecutorClassName",
249                                                    backgroundTask.getTaskExecutorClassName());
250    
251                                            MessageBusUtil.sendMessage(
252                                                    DestinationNames.BACKGROUND_TASK_STATUS, message);
253    
254                                            return null;
255                                    }
256    
257                            }
258                    );
259            }
260    
261            @Clusterable(onMaster = true)
262            @Override
263            public void cleanUpBackgroundTasks() {
264                    List<BackgroundTask> backgroundTasks =
265                            backgroundTaskPersistence.findByStatus(
266                                    BackgroundTaskConstants.STATUS_IN_PROGRESS);
267    
268                    for (BackgroundTask backgroundTask : backgroundTasks) {
269                            backgroundTask.setStatus(BackgroundTaskConstants.STATUS_FAILED);
270    
271                            cleanUpBackgroundTask(
272                                    backgroundTask, BackgroundTaskConstants.STATUS_FAILED);
273                    }
274            }
275    
276            @Override
277            public BackgroundTask deleteBackgroundTask(BackgroundTask backgroundTask)
278                    throws PortalException {
279    
280                    long folderId = backgroundTask.getAttachmentsFolderId();
281    
282                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
283                            PortletFileRepositoryUtil.deletePortletFolder(folderId);
284                    }
285    
286                    if (backgroundTask.getStatus() ==
287                                    BackgroundTaskConstants.STATUS_IN_PROGRESS) {
288    
289                            cleanUpBackgroundTask(
290                                    backgroundTask, BackgroundTaskConstants.STATUS_CANCELLED);
291                    }
292    
293                    return backgroundTaskPersistence.remove(backgroundTask);
294            }
295    
296            @Override
297            public BackgroundTask deleteBackgroundTask(long backgroundTaskId)
298                    throws PortalException {
299    
300                    BackgroundTask backgroundTask =
301                            backgroundTaskPersistence.findByPrimaryKey(backgroundTaskId);
302    
303                    return deleteBackgroundTask(backgroundTask);
304            }
305    
306            @Override
307            public void deleteCompanyBackgroundTasks(long companyId)
308                    throws PortalException {
309    
310                    List<BackgroundTask> backgroundTasks =
311                            backgroundTaskPersistence.findByCompanyId(companyId);
312    
313                    for (BackgroundTask backgroundTask : backgroundTasks) {
314                            deleteBackgroundTask(backgroundTask);
315                    }
316            }
317    
318            @Override
319            public void deleteGroupBackgroundTasks(long groupId)
320                    throws PortalException {
321    
322                    List<BackgroundTask> backgroundTasks =
323                            backgroundTaskPersistence.findByGroupId(groupId);
324    
325                    for (BackgroundTask backgroundTask : backgroundTasks) {
326                            deleteBackgroundTask(backgroundTask);
327                    }
328            }
329    
330            @Override
331            public BackgroundTask fetchBackgroundTask(long backgroundTaskId) {
332                    return backgroundTaskPersistence.fetchByPrimaryKey(backgroundTaskId);
333            }
334    
335            @Override
336            public BackgroundTask fetchFirstBackgroundTask(
337                    long groupId, String taskExecutorClassName, boolean completed,
338                    OrderByComparator<BackgroundTask> orderByComparator) {
339    
340                    return backgroundTaskPersistence.fetchByG_T_C_First(
341                            groupId, taskExecutorClassName, completed, orderByComparator);
342            }
343    
344            @Override
345            public BackgroundTask fetchFirstBackgroundTask(
346                    String taskExecutorClassName, int status) {
347    
348                    return fetchFirstBackgroundTask(taskExecutorClassName, status, null);
349            }
350    
351            @Override
352            public BackgroundTask fetchFirstBackgroundTask(
353                    String taskExecutorClassName, int status,
354                    OrderByComparator<BackgroundTask> orderByComparator) {
355    
356                    return backgroundTaskPersistence.fetchByT_S_First(
357                            taskExecutorClassName, status, orderByComparator);
358            }
359    
360            @Override
361            public BackgroundTask getBackgroundTask(long backgroundTaskId)
362                    throws PortalException {
363    
364                    return backgroundTaskPersistence.findByPrimaryKey(backgroundTaskId);
365            }
366    
367            @Override
368            public List<BackgroundTask> getBackgroundTasks(long groupId, int status) {
369                    return backgroundTaskPersistence.findByG_S(groupId, status);
370            }
371    
372            @Override
373            public List<BackgroundTask> getBackgroundTasks(
374                    long groupId, String taskExecutorClassName) {
375    
376                    return backgroundTaskPersistence.findByG_T(
377                            groupId, taskExecutorClassName);
378            }
379    
380            @Override
381            public List<BackgroundTask> getBackgroundTasks(
382                    long groupId, String taskExecutorClassName, int status) {
383    
384                    return backgroundTaskPersistence.findByG_T_S(
385                            groupId, taskExecutorClassName, status);
386            }
387    
388            @Override
389            public List<BackgroundTask> getBackgroundTasks(
390                    long groupId, String taskExecutorClassName, int start, int end,
391                    OrderByComparator<BackgroundTask> orderByComparator) {
392    
393                    return backgroundTaskPersistence.findByG_T(
394                            groupId, taskExecutorClassName, start, end, orderByComparator);
395            }
396    
397            @Override
398            public List<BackgroundTask> getBackgroundTasks(
399                    long groupId, String name, String taskExecutorClassName, int start,
400                    int end, OrderByComparator<BackgroundTask> orderByComparator) {
401    
402                    return backgroundTaskPersistence.findByG_N_T(
403                            groupId, name, taskExecutorClassName, start, end,
404                            orderByComparator);
405            }
406    
407            @Override
408            public List<BackgroundTask> getBackgroundTasks(
409                    long groupId, String[] taskExecutorClassNames) {
410    
411                    return backgroundTaskPersistence.findByG_T(
412                            groupId, taskExecutorClassNames);
413            }
414    
415            @Override
416            public List<BackgroundTask> getBackgroundTasks(
417                    long groupId, String[] taskExecutorClassNames, int status) {
418    
419                    return backgroundTaskPersistence.findByG_T_S(
420                            groupId, taskExecutorClassNames, status);
421            }
422    
423            @Override
424            public List<BackgroundTask> getBackgroundTasks(
425                    long groupId, String[] taskExecutorClassNames, int start, int end,
426                    OrderByComparator<BackgroundTask> orderByComparator) {
427    
428                    return backgroundTaskPersistence.findByG_T(
429                            groupId, taskExecutorClassNames, start, end, orderByComparator);
430            }
431    
432            @Override
433            public List<BackgroundTask> getBackgroundTasks(
434                    String taskExecutorClassName, int status) {
435    
436                    return backgroundTaskPersistence.findByT_S(
437                            taskExecutorClassName, status);
438            }
439    
440            @Override
441            public List<BackgroundTask> getBackgroundTasks(
442                    String taskExecutorClassName, int status, int start, int end,
443                    OrderByComparator<BackgroundTask> orderByComparator) {
444    
445                    return backgroundTaskPersistence.findByT_S(
446                            taskExecutorClassName, status, start, end, orderByComparator);
447            }
448    
449            @Override
450            public List<BackgroundTask> getBackgroundTasks(
451                    String[] taskExecutorClassNames, int status) {
452    
453                    return backgroundTaskPersistence.findByT_S(
454                            taskExecutorClassNames, status);
455            }
456    
457            @Override
458            public List<BackgroundTask> getBackgroundTasks(
459                    String[] taskExecutorClassNames, int status, int start, int end,
460                    OrderByComparator<BackgroundTask> orderByComparator) {
461    
462                    return backgroundTaskPersistence.findByT_S(
463                            taskExecutorClassNames, status, start, end, orderByComparator);
464            }
465    
466            @Override
467            public int getBackgroundTasksCount(
468                    long groupId, String taskExecutorClassName) {
469    
470                    return backgroundTaskPersistence.countByG_T(
471                            groupId, taskExecutorClassName);
472            }
473    
474            @Override
475            public int getBackgroundTasksCount(
476                    long groupId, String taskExecutorClassName, boolean completed) {
477    
478                    return backgroundTaskPersistence.countByG_T_C(
479                            groupId, taskExecutorClassName, completed);
480            }
481    
482            @Override
483            public int getBackgroundTasksCount(
484                    long groupId, String name, String taskExecutorClassName) {
485    
486                    return backgroundTaskPersistence.countByG_N_T(
487                            groupId, name, taskExecutorClassName);
488            }
489    
490            @Override
491            public int getBackgroundTasksCount(
492                    long groupId, String name, String taskExecutorClassName,
493                    boolean completed) {
494    
495                    return backgroundTaskPersistence.countByG_N_T_C(
496                            groupId, name, taskExecutorClassName, completed);
497            }
498    
499            @Override
500            public int getBackgroundTasksCount(
501                    long groupId, String[] taskExecutorClassNames) {
502    
503                    return backgroundTaskPersistence.countByG_T(
504                            groupId, taskExecutorClassNames);
505            }
506    
507            @Override
508            public int getBackgroundTasksCount(
509                    long groupId, String[] taskExecutorClassNames, boolean completed) {
510    
511                    return backgroundTaskPersistence.countByG_T_C(
512                            groupId, taskExecutorClassNames, completed);
513            }
514    
515            @Clusterable(onMaster = true)
516            @Override
517            public String getBackgroundTaskStatusJSON(long backgroundTaskId) {
518                    BackgroundTaskStatus backgroundTaskStatus =
519                            _backgroundTaskStatusRegistry.getBackgroundTaskStatus(
520                                    backgroundTaskId);
521    
522                    if (backgroundTaskStatus != null) {
523                            return backgroundTaskStatus.getAttributesJSON();
524                    }
525    
526                    return StringPool.BLANK;
527            }
528    
529            @Clusterable(onMaster = true)
530            @Override
531            public void resumeBackgroundTask(long backgroundTaskId) {
532                    BackgroundTask backgroundTask =
533                            backgroundTaskPersistence.fetchByPrimaryKey(backgroundTaskId);
534    
535                    if ((backgroundTask == null) ||
536                            (backgroundTask.getStatus() !=
537                                    BackgroundTaskConstants.STATUS_QUEUED)) {
538    
539                            return;
540                    }
541    
542                    Message message = new Message();
543    
544                    message.put("backgroundTaskId", backgroundTaskId);
545    
546                    MessageBusUtil.sendMessage(DestinationNames.BACKGROUND_TASK, message);
547            }
548    
549            @Clusterable(onMaster = true)
550            @Override
551            public void triggerBackgroundTask(long backgroundTaskId) {
552                    Message message = new Message();
553    
554                    message.put("backgroundTaskId", backgroundTaskId);
555    
556                    MessageBusUtil.sendMessage(DestinationNames.BACKGROUND_TASK, message);
557            }
558    
559            @BeanReference(type = BackgroundTaskStatusRegistry.class)
560            private BackgroundTaskStatusRegistry _backgroundTaskStatusRegistry;
561    
562            @BeanReference(type = BackgroundTaskThreadLocalManager.class)
563            private BackgroundTaskThreadLocalManager _backgroundTaskThreadLocalManager;
564    
565    }