Skip navigation

Prachi M's Blog

2 posts

Every organization has its own way of implementing and managing the various user roles, names, groups and their memberships.

jBPM provides a flexible way of incorporating one's own identity management component. jBPM includes an optional identity component that can be easily replaced with a company's own identity data store.

An assignee is identified by its ID in jBPM terminology. jBPM has only knowledge about assignee's ids and they are represented as java.lang.String for maximum flexibility.

 

 

Implementing Custom Identity Management Component

jBPM code contains a class called "IdentitySessionImpl" which takes care of the identity implementation. By simply overriding this class's methods, one can use its own implementation.

 

A sample class overriding the default identity class is shown below. Here, a dummy table "demo_identity" is taken as reference, which is present in Hsql Database and contains the following parameters:

 

 

UsernameGroupnameRole
JohnManagermanager
ChrisAdminlead

 

The demo class "CustomIdentitySession" is shown below:

 

public class IdentitySessionImpl implements IdentitySession{

public Group findGroupById(String arg0) {
try
{
List<Group> groups = new ArrayList<Group>();
Group group = null;
Class.forName("org.hsqldb.jdbcDriver");
String url = "jdbc:hsqldb:hsql://localhost:1701";
Connection conn = DriverManager.getConnection(url,"sa","");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT groupname FROM demo_identity WHERE groupname = '"+arg0+"'");
while(rs.next())
{
group = new GroupImpl(rs.getString("groupname"));
}
return group;
}
catch (Exception e)
{
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
return null;
}


public List<Group> findGroupsByUser(String arg0) {
// TODO Auto-generated method stub
try
{
..
ResultSet rs = stmt.executeQuery("SELECT groupname FROM demo_identity WHERE username = '"+arg0+"'");
System.out.println("in my findGroupsByUser");
while(rs.next())
{
group = new GroupImpl(rs.getString(1));
System.out.println(group);
groups.add(group);
}
return groups;
}
catch (Exception e)
.. }


public User findUserById(String arg0) {
try
{
...
ResultSet rs = stmt.executeQuery("SELECT username FROM demo_identity WHERE username = '"+arg0+"'");
System.out.println("in my user impl, method: findUserByid");
while(rs.next())
{
user = new UserImpl(rs.getString(1), "givenName", "familyName");
}
return user;
}
… }


and so on.

In the example above, we are using a simple query using ResultSet to retrieve the user values. You can easily replace this code with the identity management code that you'd want to implement.

Make sure to add your new impl class's absolute address to the jbpm.cfg.xml file, so that this new class is read and implemented when the engine starts.

 

Implementing Custom Address Resolvers

jBPM sends notifications and triggers by using its default identity management component. However, in case you want to implement your own address resolvers to send notifications, you can do so by simply tweaking the default address resolver class provided by jBPM.

 

The custom address resolver class uses your custom identity session impl class (as described above) to extract the user information and then resolves the address for him/her.

 

A simple custom address resolver class is shown below:

 

package org.addressresolver

import java.util.List;
import javax.mail.Address;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import org.jbpm.api.identity.Group;
import org.jbpm.api.identity.User;
import org.jbpm.pvm.internal.email.spi.AddressResolver;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.identity.spi.IdentitySession;


public class CustomAddressResolver implements AddressResolver{
public Address resolveAddress(User userName) {
try {
return new InternetAddress(userName.getId()+"@xyz.com");
     } catch (AddressException e) 
     {
System.out.println("In error block of address resolver");
     }
return null;
}


public Address[] resolveAddresses(Group group) {
System.out.println("In custom mail address resolver class: resolve group address");
System.out.println(group.getId());
List<User> users = EnvironmentImpl.getFromCurrent(IdentitySession.class)
                   .findUsersByGroup(group.getId());
int userCount = users.size();
Address[] addresses = new Address[userCount];
for (int i = 0; i < userCount; i++) {
addresses[i] = resolveAddress(users.get(i));
}
return addresses;
}
}

 

To implement the new resolver, simply add the below in your jbpm.cfg.xml file:

 

<transaction-context>
<!-- Custom Identity implementation-->
     <object class="org.identity.impl.IdentitySessionImpl"/>
     <object class="org.addressresolver.CustomAddressResolver"/>
     <mail-session>
          <mail-server>
          <session-properties resource="jbpm.mail.properties" />
          <address-resolver class="org.addressresolver.CustomAddressResolver"/>
           </mail-server>
      </mail-session>
</transaction-context>

 

And there you are! Your custom classes are ready.

You can use them as per your implementation requirements.

 

Happy learning ..

mukh.prac

Sending Mails: jBPM 4

Posted by mukh.prac Dec 28, 2010

jBPM provides a rich and customizable way of sending emails to multiple recepients.


In this blog, we'll discuss the various ways provided by jBPM to send mails, reminders and what not!


 

 

 

 

Inline mails

With inline mail sending, one can write the necessary information on the node itself.

The below example shows a mail node, on which all the parameters for sending mails are written in the process definition file itself.

 

<process name="InlineMail" xmlns="http://jbpm.org/4.4/jpdl">
  <start>
    <transition to="send birthday reminder note" />
  </start>
  <mail>
    <to addresses="jbpmLearner@some-company.com" />
    <subject>Reminder: ${person} celebrates his birthday!</subject>
    <text>Do not forget: ${date} is the birthday of ${person} </text>
    <attachments>
      <attachment resource="org/example/birthday_card.png"/>
      <attachment name="picture.jpg" expression="${picture}" mime-type="image/jpeg"/>
    </attachments>
    <transition to="end" />
  </mail>
  <state/>

 

Notice that mail details are written on the node itself.


Disadvantages: Any minor change in mail parameters require redeployment of the process definition, flexibility to change mail information is reduced.

 


Mail templates

To define mail as a template, we can use a mail node and configure it as:


<mail name="rectify" template="rectify-template />


And this template can be defined in a mail.templates.xml file (you can use any name for the templates file).

To specify that the above mail template should be used, the same should be imported in jbpm.cfg.xml file as:


<import resource="com/jbpm/demo/resources/mail.templates.xml" />


The templates file would be like:


<jbpm-configuration>
   
 <process-engine-context>

     <mail-template name="rectify-template">
               <to addresses="jbpmLearner@some-company.com" />
               <subject>Reminder: ${person} celebrates his birthday!</subject>
               <text>Do not forget: ${date} is the birthday of ${person} </text>
     <attachments>
           <attachment resource="org/example/birthday_card.png"/>
           <attachment name="picture.jpg" expression="${picture}" mime-type="image/jpeg"/>
     </attachments>
        
     </mail-template>

 </process-engine-context> 


To specify smtp details, a jbpm.mail.properties file is maintained. The file can contain parameters as below:


mail.smtp.host     gmail.com
mail.smtp.port     25
mail.from          demo-noreply@gmail.com

 


Sending mail using event listeners

To send mail at any point of time (on transition, nodes etc.), one can leverage event listeners provided by jBPM.

A sample example of a simple event listener for mail execution is as below:



import javax.mail.Message;
import org.jbpm.api.Execution;
import org.jbpm.pvm.internal.email.impl.MailProducerImpl;
import org.jbpm.pvm.internal.email.impl.MailTemplate;
import org.jbpm.pvm.internal.email.impl.MailTemplateRegistry;
import org.jbpm.pvm.internal.email.spi.MailProducer;
import org.jbpm.pvm.internal.email.spi.MailSession;
import org.jbpm.pvm.internal.env.EnvironmentImpl;

import org.jbpm.api.listener.EventListener;
import org.jbpm.api.listener.EventListenerExecution;



public class MyEventListener implements EventListener
{
        public void notify(EventListenerExecution execution) throws Exception
     {
         sendMail("my-email-templete", execution);
     }

     private void sendMail(String templateName, Execution execution)
     {
         MailTemplateRegistry mailTemplateRegistry = EnvironmentImpl.getFromCurrent(MailTemplateRegistry.class);
         MailSession mailSession = EnvironmentImpl.getFromCurrent(MailSession.class);
         MailTemplate template = templateRegistry.getTemplate(templateName);


         MailProducerImpl mailProducer = new MailProducerImpl();
         mailProducer.setTemplate(template);
         Collection<Message> emails = mailProducer.produce(execution);
        
         mailSession.send(emails);



Mails on transition

Even on transitions, mails can be sent as:


<transition to="Approve">
      <mail template="notify-birthday" />
</transition>

 


Up Ahead, Advanced mail support, and customizing address resolvers.

Happy learning !