Page tree
Skip to end of metadata
Go to start of metadata

Summary

This tutorial shows how to create a simple email workflow in Magnolia 5.3.x or 5.4.x or 5.5.x with Eclipse Luna.

If you have any problems with this tutorial please comment at the bottom.

Prerequisites

Getting your module ready

Create a new module

Set up your module with Maven and use archetype: magnolia-module-archetype (An archetype to create basic Magnolia modules)

Module creation input example
$ mvn archetype:generate -DarchetypeCatalog=https://nexus.magnolia-cms.com/content/groups/public	
[...]
Confirm properties configuration:
groupId: org.mydomain.workflow
artifactId: mycompany-module-myproject-workflow
version: 1.0-SNAPSHOT
package: org.mydomain.workflow
magnolia-version: 5.4.5
module-class-name: MyProjectWorkflowModule
module-name: myproject-workflow
Y: 

Import the module into your IDE

Module dependencies

Ensure that the pom file contains all of the necessary dependencies. As workflow is part of the Enterprise Edition, un-comment the repository at the end of the file.

mycompany-module-myproject-workflow pom
[...]
<dependency>
    <groupId>info.magnolia.workflow</groupId>
    <artifactId>magnolia-module-workflow-jbpm</artifactId>
</dependency>
<dependency>
    <groupId>info.magnolia</groupId>
    <artifactId>magnolia-module-mail</artifactId>
</dependency>
[...] 

In this case I'm letting the parent pom manage the versions. For Magnolia 5.3.7 we are using magnolia-module-workflow-jbpm-5.4.4 and magnolia-module-mail-5.2.1.

Update your module descriptor located under src/main/resources/META-INF/magnolia/myproject-workflow.xml.

myproject-workflow.xml
[...]    
<dependency>
    <name>workflow-jbpm</name>
    <version>5.5/*</version>
</dependency>
<dependency>
    <name>mail</name>
    <version>5.3/*</version>
</dependency>
[...] 

Defining the workflow

Create a new process

  1. Create a new jBPM Process Diagram.
  2. Save the MyPublication.bpmn2 file under /src/main/resources.
  3. You will now have an empty process file in your module.

Custom workitems

To create custom workitems you have to create two files inside the META-INF folder of your project.

The two files are not used at runtime, but are necessary for modeling your process

  1. drools.rulebase.conf file contains a drools.workDefinitions property which points to a space-separated list of workItem definition file.

    drools.rulebase.conf

    drools.workDefinitions = MyDefinitions.wid

  2. Inside the *.wid files is where you define your workItems. In this case we create a workItem email and define the parameters used to send the email.

    MyDefinitions.wid
    import org.drools.process.core.datatype.impl.type.StringDataType
     
    [
       // the Email notification work item
       [
         "name" : "email",
         "parameters" : [
           "subject" : new StringDataType(),
           "body" : new StringDataType(),
           "recipient" : new StringDataType()
         ],
         "displayName" : "EmailNotification"
       ]
    ]

Add workitem

  1. If your MyPublication.bpmn2 file was open when you added the drools.rulebase.conf and MyDefinitions.wid files then close it and reopen it. This should trigger the email workitem that was defined in the previous step to appear in the Custom Tasks drawer of the modeler's palette.

  2. Add the newly added EmailNotification workItem from the palette into your process.
  3. Connect the Start Event to the EmailNotification by:

    1. hovering over the Start Event.
    2. clicking the arrow icon.
    3. dragging the arrow to point to the EmailNotification.
  4. Add an End Event.
  5. Connect the EmailNotification to the End Event.

Publication steps

To add the publication steps we call Magnolia's Publication process from within our custom process. (This involves a 'Reusable Process' or 'Call Activity' Learn more). Because we are targeting the jBPM runtime we do not need to explicitly import our process definition from the external file. Just add the process ID to the Called Activity field of the Call Activity. The jBPM runtime will resolve the IDs at runtime or throw a runtime exception if the called process is not available.

  1. Under the Sub Processes drawer you will find a Reusable Process. Drag the Reusable Process into your process before the EmailNotification. (Note: In other versions of Eclipse you may find this under Activities –> Call Activity)
  2. Double-click the Call Activity to set a Name and Called Activity. info.magnolia.workflow.Publication will be the Called Activity at this step.

    If you are using Magnolia 5.4 then use info.magnolia.workflow.ReviewForPublication for the Called Activity.


Process parameters

Magnolia's standard publication process depends on parameters aggregated from various steps before the workflow starts. These parameters hold a map identified as mgnlData. To ensure that these parameters are properly passed to the publication process you need to set input and output parameters.

To access the  mgnlData map throughout the process, define a variable and add a type import at the process level.

  1. Add an import for our parameters map. Click on the process background and select the Properties tab from the bottom window. Click Definitions from the side menu of the Properties tab. Expand Imports and add java.util.Map using the green plus button. (Note: If the Properties tab doesn't show when you click the process background then enable it through the Window menu of Eclipse)

  2. Define a process variable  mgnlData
  3. Create variables for taskId and commandName

  4. Create a mapping for mgnlData input and output parameters inside the Call Activity .


     
     

  5. Create additional input mappings for taskId and commandName

  6. To access the parameters in our email workitem, create input mappings in the custom email task. First map the subject.
  7. Map the remaining parameters body, recipient, and mgnlData.

Configure the workflow

Configuring the workflow is done by registering a workflows folder in your custom module.

Here I've registered the myPublication workflow within my custom module.

Workitem handlers

When you have customized your workflow, the next step is to integrate the workflow design into your project. This is achieved using workItemHandlers.

Implementing a workitem handler

A workItemHandler takes care of executing or aborting workItems. Start by implementing the  org.kie.api.runtime.process.WorkItemHandler interface.

EmailWorkItemHandler.java
package org.mydomain.workflow.workitems;
 
import org.kie.api.runtime.process.WorkItem;
import org.kie.api.runtime.process.WorkItemHandler;
import org.kie.api.runtime.process.WorkItemManager;
 
public class EmailWorkItemHandler implements WorkItemHandler {
 
    private static final Logger log = LoggerFactory.getLogger(EmailWorkItemHandler.class);
 
    @Override
    public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
 
        // read data from our email work items parameters
        String subject = String.valueOf(workItem.getParameter("subject"));
        String body = String.valueOf(workItem.getParameter("body"));
        String recipient = String.valueOf(workItem.getParameter("recipient"));
 
        // read data from mgnlData parameter map
        Map<String, Object> data = (Map<String, Object>) workItem.getParameter("mgnlData");
        String path = (String) data.get("path");
        body = String.format(body, path);
 
        log.warn("Sending email to " + recipient);
        log.warn("Subject: " + subject);
        log.warn("Body: " + body);
    }
 
    @Override
    public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {}
}

Configuring a workitem handler

Configuring the workItemHandler is done by registering a workItemHandlers folder in your custom module.

Here I've registered my email workItemHandler within my custom module myproject-workflow.

Test the workflow

Now you test your workflow configuration and make sure everything is in place correctly.

  1. Change the property /modules/workflow/commands/workflow/activate/activate@workflow to point to your workflow.
  2. Set up a subscriber configuration to point to a test public instance.
  3. Activate a page from the pages app and verify in the log that you see a successful activation and the log messages from the email workItemHandler.

Define the email workitem handler

Create an email workitem handler definition that will allow for configuration of the mail template and the command to be used when sending the mail.

package org.mydomain.workflow.workitems;

import info.magnolia.module.workflow.jbpm.workitem.handler.definition.ConfiguredWorkItemHandlerDefinition;

public class EmailWorkItemHandlerDefinition extends ConfiguredWorkItemHandlerDefinition {
 
    private String mailCommand;
    private String mailTemplate;
 
    public EmailWorkItemHandlerDefinition() {
        setImplementationClass(EmailWorkItemHandler.class);
    }
 
    public String getMailTemplate() {
        return mailTemplate;
    }
    public String getMailCommand() {
        return mailCommand;
    }
    public void setMailTemplate(String mailTemplate) {
        this.mailTemplate = mailTemplate;
    }
    public void setMailCommand(String mailCommand) {
        this.mailCommand = mailCommand;
    }
}

Update the email workitem handler configuration

Update the configuration to use the new definition class.

Update the email workitem handler implementation

Now that we have a definition class we can get the configured template and command for use in the workitem handler implementation.

package org.mydomain.workflow.workitems;

import info.magnolia.commands.CommandsManager;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import org.kie.api.runtime.process.WorkItem;
import org.kie.api.runtime.process.WorkItemHandler;
import org.kie.api.runtime.process.WorkItemManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EmailWorkItemHandler implements WorkItemHandler {

    private static final Logger log = LoggerFactory.getLogger(EmailWorkItemHandler.class);

    private static final String TEMPLATE_PARAMETER_NAME= "mailTemplate";
    private static final String DATA_PARAMETER_NAME= "mgnlData";
     
    private final EmailWorkItemHandlerDefinition definition;
    private final CommandsManager commandsManager;
     
    @Inject
    public EmailWorkItemHandler(EmailWorkItemHandlerDefinition definition, CommandsManager commandsManager) {
        this.definition = definition;
        this.commandsManager = commandsManager;
    }
     
    @Override
    public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
        
        Map<String, Object> mailParameters = new HashMap<String, Object>();
        mailParameters.put(TEMPLATE_PARAMETER_NAME, definition.getMailTemplate());
        mailParameters.put(DATA_PARAMETER_NAME, workItem.getParameter(DATA_PARAMETER_NAME));
        try {
            commandsManager.executeCommand(definition.getMailCommand(), mailParameters);
        } catch (Exception e) {
            log.error("Sending email failed.", e);
        }

		manager.completeWorkItem(workItem.getId(), parameters);
 	}
  
    @Override
    public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {}
}

 

Mail template configuration

Create a freemarker template

Create a Freemarker template in your module's class path. (For example in src/main/resources/myproject-workflow/email/myPublication.ftl). The template will dump the whole mgnlData map.

<html>
	<head>
		My Publication
	</head>
	<body> 
		<dl>
		[#list mgnlData?keys as key]
    		<dt>${key}</dt>
		[#if mgnlData[key]?is_string]
    		<dd>${mgnlData[key]}</dd>
		[#else]
    		<dd>value not a string</dd>
		[/#if]
		[/#list]
		</dl>
	</body>
</html>

Configure the template

Configure the template within the mail module.

Configure the mailCommand and mailTemplate

Create properties for the mailCommand and mailTemplate on the email workItemHandler definition.

  • No labels

7 Comments

  1. Hi Richard,

    I have only one remark. By extending the workflow "info.magnolia.workflow.Publication", I get the error mentioned in this support ticket. Then, I changed and extended this one "info.magnolia.workflow.ReviewForPublication" instead, and it worked.

    Did I do something wrong ?

    In advance, thanks (smile)

    1. Ah yes, that makes sense if you are using 5.4. I will update the tutorial today. In the end, if you use 5.3 you can use either of those workflows. If you use 5.4 then you can only use the ReviewForPublication for the reason you pointed to.

      1. Thanks a lot !  

        Great tutorial by the way, it really helped me to understand the publication workflow.

  2. Hi Richard,

    I'm trying to follow your tutorial, i managed to create the 2 META-INF files in my module, but when i close and open the empty process file, it doesn't appear the "Custom Tasks" options in the side bar. ¿Can you please give me a hint about it?

    Thanks in advance.

    1. Hi-

      Are you using a different version of Eclipse then Luna? Sometimes the different versions behave differently when using the plugin. I can say it works well with Luna.

      HTH

      1. Hi Richard, Hi Francisco,

        With Eclipse Luna, if you use the Marketplace to download the JBPM plugin, it seems that it will bring a version (1.1.xx if I remember well) which will cause exactly the behaviour described by Francisco.

        I would advise you to use Eclipse Neon, then download the plugin through the Marketplace (should be version 1.3.x). Then you should be able to play with this tutorial.
        The screenshots showing JBPM plugin are slightly different with the version 1.3. 

        1. I changed the Eclipse Neon version as you suggested, and it works well.

          Thanks Adrien!!