Executing or scheduling background task is always an important activity for developers.
There are so many scenarios where background tasks are used like import/export, sending bulk notification or email, processing orders etc.
You can find this interesting link here which talks in length for background tasks.
What it does not offer is implementation example and changes for background task in Liferay 7/DXP
By following few Liferay conventions, we can easily use this weapon.
In this example I will explain creation of background task, pass parameters and handle errors if any.
In next example I will demonstrate check status, progress and display it over UI.
We will be creating two osgi components for this activity.
1. Create osgi module for background task creation and register it to handler
2. Use above module to create background tasks
Render method to create background task every time portlet loads.
@Overridepublic void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { Random random = new Random(12); HttpServletRequest request = PortalUtil .getHttpServletRequest(renderRequest); ThemeDisplay themeDisplay = (ThemeDisplay) renderRequest .getAttribute(WebKeys.THEME_DISPLAY); ServiceContext serviceContext = null; try { serviceContext = ServiceContextFactory.getInstance(renderRequest); } catch (PortalException e) { logger.error("Eror in getting service context", e.getCause()); } // This taskContextMap can be used as transporter to background job MaptaskContextMap = new HashMap<>(); taskContextMap.put("processName", "testing " + random.nextInt()); taskContextMap.put("totalNodes", String.valueOf(random.nextInt())); //taskContextMap.put("serviceContext", serviceContext); try { // Adding the job to liferay background manager com.liferay.portal.kernel.backgroundtask.BackgroundTask backgroundTask = backgroundTaskmanager.addBackgroundTask(themeDisplay.getUserId(), themeDisplay.getScopeGroupId(), SampleBackgroundTaskExecutor.class.getName(),SampleBackgroundTaskExecutor.class.getName(),taskContextMap, serviceContext); // With returned background object you can check status, id etc. renderRequest.setAttribute("backgroundTaskId", backgroundTask.getBackgroundTaskId()); } catch (PortalException e) { logger.error(e.getCause()); } catch (SystemException e) { logger.error(e.getCause()); }
Create Background Task Executor
@Component( immediate = true, property = {"background.task.executor.class.name=com.netcracker.cabinet.background.executor.MigrationBackgroundTaskExecutor"},// Without this property osgi will not register this as background executor/handler service = BackgroundTaskExecutor.class) public class SampleBackgroundTaskExecutor extends BaseBackgroundTaskExecutor {
isSerial - True
// if it's not serial then multiple instances of this executor can run parallel, to run it in queue mode, we use isSerial true@Overridepublic boolean isSerial() { return true; }
Main execute method for the Job
public BackgroundTaskResult execute(BackgroundTask backgroundTask) throws Exception { // taskContextMap which is sent by the caller MaptaskContextMap = backgroundTask.getTaskContextMap(); String taskName = (String)taskContextMap.get("processName") ; String totalNodes = (String)taskContextMap.get("totalNodes"); //ServiceContext serviceContext = (ServiceContext) taskContextMap.get("serviceContext"); if(LOGGER.isDebugEnabled()){ LOGGER.debug("Task Name : "+ taskName); } BackgroundTaskVO messageContent = new BackgroundTaskVO(); messageContent.setTotalNodes(totalNodes); // Sending the data to util for MessageBus SampleDataHandlerStatusMessageSenderUtil.sendStatusMessage(messageContent); // Telling the system if, background task is successful or not BackgroundTaskResult backgroundTaskResult = new BackgroundTaskResult( BackgroundTaskConstants.STATUS_SUCCESSFUL); backgroundTaskResult.setStatusMessage("Wonder full"); return backgroundTaskResult; }
Message Bus update
public static void sendStatusMessage(BackgroundTaskVO messageContent) { // Leave if no background task if (!BackgroundTaskThreadLocal.hasBackgroundTask()) { return; } // Message Creation Message message = createMessage(messageContent); // Send message to message bus MessageBusUtil.sendMessage(DestinationNames.BACKGROUND_TASK_STATUS, message); }
You can download the source code from here
You are just done, Try & Enjoy the function.............:)