Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Stardust/Knowledge Base/Integration/Camel/Camel Route to Send and Receive Email"

(Objective)
(Approach)
Line 10: Line 10:
  
 
We will design a process with following activities:
 
We will design a process with following activities:
Enter Details - user will fill in certain details here including the email ID of the approver.
+
 
Prepare Email Body - A script application activity which will create the body of the email out of data provided to it.
+
* Enter Details - user will fill in certain details here including the email ID of the approver.
Send And Wait Activity - which will send the email and get into hibernated mode. it will look up the email box of the configured user and once approval/reply mail arrives, it will complete itself and move the process.
+
* Prepare Email Body - A script application activity which will create the body of the email out of data provided to it. it also creates a hash code, the script used in this application is:
Show Response - A manual activity to show the received reply/approval email's body.
+
 
 +
<source lang="xml">
 +
function getMeHash(data) {
 +
    var salt = "OX!!0ty6" + Math.floor((Math.random() * 10000000) + 1)%100000;
 +
    var leftShiftNum = Math.floor((Math.random() * 100) + 1)%10;
 +
  var hash = 0, i, chr, len;
 +
  data += salt;
 +
  if (data.length == 0) return hash;
 +
  for (i = 0, len = data.length; i < len; i++) {
 +
    chr  = data.charCodeAt(i);
 +
    hash  = ((hash << leftShiftNum) - hash) + chr ;
 +
    hash |= 0; // Convert to 32bit integer
 +
   
 +
  }
 +
  return hash.toString();
 +
};
 +
var data = EmpData.Name+" "+CEPData.CourseName;
 +
var dataHash = getMeHash(data);
 +
HashValue = dataHash;
 +
MessageBody = "<html><body> " +
 +
"<strong>Please approve CEP for " +
 +
EmpData.Name +"</strong>: <br> Course Name: " +
 +
CEPData.CourseName + "<br> Course Duration: " +
 +
CEPData.Duration + "<br> Course Fee: " +
 +
CEPData.Fee +
 +
"<br> <i>Please use @Decision ... @Decision quote to give your decisions and @Reason ... @Reason quote to provide additional comments<i/>" +
 +
"<p style=\"display:none \">hashCode###"+dataHash+"###</p> </body></html>";
 +
</source>
 +
* Send And Wait Activity - which will send the email and get into hibernated mode. it will look up the email box of the configured user and once approval/reply mail arrives, it will complete itself and move the process.
 +
* Show Response - A manual activity to show the received reply/approval email's body.
  
 
Create a process like shown below:
 
Create a process like shown below:
Line 25: Line 54:
 
Define 2 application Prepare Email Body (Script Invocation) and Send And Wait (Generic Camel Route):
 
Define 2 application Prepare Email Body (Script Invocation) and Send And Wait (Generic Camel Route):
  
[[File:PrepareMessage.jpg]]
+
[[File:PrepareMessage1.jpg]]
  
[[File:SendandWait.jpg]]
+
[[File:SendandWait1.jpg]]
  
 
Details of the routes:
 
Details of the routes:
Line 36: Line 65:
 
  <simple>Please approve the request#${header.ippActivityInstanceOid}</simple>
 
  <simple>Please approve the request#${header.ippActivityInstanceOid}</simple>
 
</setHeader>
 
</setHeader>
<to uri="smtp://localhost?username=testuser&amp;password=testuser&amp;to={header.To}&amp;from=testuser@localhost&amp;mail.smtp.port=25;"/>
+
<setHeader headerName="contentType">
 +
<constant>text/html</constant>
 +
</setHeader>
 +
<to uri="smtp://localhost?username=${fromUser}&amp;password=${fromUserPass}&amp;to={header.To}&amp;from=${fromUser}@localhost&amp;mail.smtp.port=25"/>
 
</source>
 
</source>
 +
 +
 
Setting the header subject including activity instance OID from IPP which has been passed to this route by selecting "Include Process Context Headers".
 
Setting the header subject including activity instance OID from IPP which has been passed to this route by selecting "Include Process Context Headers".
 
then using Camel's smtp endpoint configuring the email and sending it.
 
then using Camel's smtp endpoint configuring the email and sending it.
Line 47: Line 81:
 
<from uri="pop3://localhost:110?connectionTimeout=10000&delete=true&initialDelay=1000&password=testuser&unseen=true&username=testuser&searchTerm.subject=request#"/>
 
<from uri="pop3://localhost:110?connectionTimeout=10000&delete=true&initialDelay=1000&password=testuser&unseen=true&username=testuser&searchTerm.subject=request#"/>
 
<to uri="ipp:authenticate:setCurrent?user=motu&password=motu" />
 
<to uri="ipp:authenticate:setCurrent?user=motu&password=motu" />
 +
<convertBodyTo type="java.lang.String"/>
 +
 
<setHeader headerName="CamelLanguageScript">
 
<setHeader headerName="CamelLanguageScript">
 
<constant>
 
<constant>
Line 54: Line 90:
 
var line= request.headers.get("subject");
 
var line= request.headers.get("subject");
 
var part = line.split("#");
 
var part = line.split("#");
 +
setOutHeader("ActOID", parseInt(part[1]));
 +
var body1 = request.body;
 +
var rPart = body1.split("@Decision");
 +
var decision = rPart[1].split("@Decision");
 +
setOutHeader("Decision", decision[0]);
  
  setOutHeader("ActOID", parseInt(part[1]));
+
var comments = body1.split("@Reason");
 +
comments = comments[1].split("@Reason");
 +
setOutHeader("AddComments", comments[0]);
 +
   
 +
setOutHeader("contentType", "text/plain");
 +
setOutHeader("Content-Type", "text/plain");
 +
 
 +
var hash = body1.split("hashCode###");
 +
hash = hash[1].split("###");
 +
setOutHeader("hashValue", hash[0]);
 
</constant>
 
</constant>
 
</setHeader>
 
</setHeader>
<to uri="language:javascript"/>
+
 
<to uri="ipp:activity:find?expectedResultSize=-1&activityInstanceOid=$simple{header.ActOID}&states=Application,Created,Hibernated,Interrupted,Suspended" />
+
<to uri="language:javascript?transform=false"/>
 +
<to uri="ipp:activity:find?expectedResultSize=-1&activityInstanceOid=$simple{header.ActOID}&dataFilters=HashValue::$simple{header.hashValue}&states=Application,Created,Hibernated,Interrupted,Suspended" />
 
<to uri="ipp:activity:complete" />
 
<to uri="ipp:activity:complete" />
 +
 
</source>
 
</source>
Using Camel's pop3 endpoint, it looking up to the user's email box, once the email arrives, it runs little java script to fetch the activity Instance OID from the subject and set it as header for further route to use it. It is the ipp:activit:find route that needs the activity Instance OID to search Stardust Audit trail to find the activity instance and complete it.
+
 
 +
 
 +
Using Camel's pop3 endpoint, it looking up to the user's email box, once the email arrives, it runs little java script to fetch the activity Instance OID from the subject and set it as header for further route to use it. It is the ipp:activit:find route that needs the activity Instance OID to search Stardust Audit trail to find the activity instance and complete it. Here we are also configuring ipp:activity:find route to include dataFilters to ensure it completes itself when the received email has intact hash code sent using producer route.
 +
 
 +
if any of the activity Instance OID or hash code value is changed, the process will not complete this activity, ensuring 1 to 1 match between sent and received email.
  
  
Line 69: Line 125:
 
Complete the activity, it will call both the application activities, prepare email body and send and wait. During execution of send and wait the process instance will hibernate and wait for an approval email. once that arrives it will complete this hibernated activity and activate Show Response Data manual activity where you can see the response email message.
 
Complete the activity, it will call both the application activities, prepare email body and send and wait. During execution of send and wait the process instance will hibernate and wait for an approval email. once that arrives it will complete this hibernated activity and activate Show Response Data manual activity where you can see the response email message.
  
[[File:ExecutionResult.jpg]]
+
[[File:ExecutionResult1.jpg]]
  
  
Artifacts can be downloaded from [[File:EmailSendReciveApproval.zip]]
+
Artifacts can be downloaded from [[File:EmailSendReciveApproval1.zip]]

Revision as of 01:49, 17 September 2014

Objective

In this article we are going to explore usage of Camel route to send an email, pause process there and receive the reply to that email and continue.

For example, an employee fills in certain data and moves the process, the process in turn sends an email to given email ID for approval and pauses the process execution, once the process receives reply/approval to the same email, it resumes the process execution.

We will be sending email in HTML format and will also send a hash code along. The hash code along with activity instance OID will be used to double sure that process is only continuing for that very same email for which it is waiting.

Approach

We will design a process with following activities:

  • Enter Details - user will fill in certain details here including the email ID of the approver.
  • Prepare Email Body - A script application activity which will create the body of the email out of data provided to it. it also creates a hash code, the script used in this application is:
function getMeHash(data) {
    var salt = "OX!!0ty6" + Math.floor((Math.random() * 10000000) + 1)%100000;
    var leftShiftNum = Math.floor((Math.random() * 100) + 1)%10;
  var hash = 0, i, chr, len;
  data += salt;
  if (data.length == 0) return hash;
  for (i = 0, len = data.length; i < len; i++) {
    chr   = data.charCodeAt(i);
    hash  = ((hash << leftShiftNum) - hash) + chr ;
    hash |= 0; // Convert to 32bit integer
 
  }
  return hash.toString();
};
var data = EmpData.Name+" "+CEPData.CourseName;
var dataHash = getMeHash(data);
HashValue = dataHash;
MessageBody = "<html><body> " +
"<strong>Please approve CEP for " + 
EmpData.Name +"</strong>: <br> Course Name: " +
CEPData.CourseName + "<br> Course Duration: " + 
CEPData.Duration + "<br> Course Fee: " + 
CEPData.Fee +
"<br> <i>Please use @Decision ... @Decision quote to give your decisions and @Reason ... @Reason quote to provide additional comments<i/>" + 
"<p style=\"display:none \">hashCode###"+dataHash+"###</p> </body></html>";
  • Send And Wait Activity - which will send the email and get into hibernated mode. it will look up the email box of the configured user and once approval/reply mail arrives, it will complete itself and move the process.
  • Show Response - A manual activity to show the received reply/approval email's body.

Create a process like shown below:

ProcessDiagram.jpg

Define 2 data types CEP Details and Employee Details as shown below:

DataTypes.jpg

Define 2 application Prepare Email Body (Script Invocation) and Send And Wait (Generic Camel Route):

PrepareMessage1.jpg

SendandWait1.jpg

Details of the routes:

Producer Route -

<setHeader headerName="subject">
 <simple>Please approve the request#${header.ippActivityInstanceOid}</simple>
</setHeader>
<setHeader headerName="contentType">
 <constant>text/html</constant>
</setHeader>
<to uri="smtp://localhost?username=${fromUser}&amp;password=${fromUserPass}&amp;to={header.To}&amp;from=${fromUser}@localhost&amp;mail.smtp.port=25"/>


Setting the header subject including activity instance OID from IPP which has been passed to this route by selecting "Include Process Context Headers". then using Camel's smtp endpoint configuring the email and sending it.

Since this application is configured as Send/Receive and Asynchronous, after sending email it will wait for route written in consumer to finish before the activity completes itself, hence gets into hibernated mode.

Consumer Route -

<from uri="pop3://localhost:110?connectionTimeout=10000&delete=true&initialDelay=1000&password=testuser&unseen=true&username=testuser&searchTerm.subject=request#"/>
<to uri="ipp:authenticate:setCurrent?user=motu&password=motu" />
<convertBodyTo type="java.lang.String"/>
 
<setHeader headerName="CamelLanguageScript">
<constant>
function setOutHeader(key, output){
request.setHeader(key, output);
}
var line= request.headers.get("subject");
var part = line.split("#");
setOutHeader("ActOID", parseInt(part[1]));
var body1 = request.body;
var rPart = body1.split("@Decision");
var decision = rPart[1].split("@Decision");
setOutHeader("Decision", decision[0]);
 
var comments = body1.split("@Reason");
comments = comments[1].split("@Reason");
setOutHeader("AddComments", comments[0]);
 
setOutHeader("contentType", "text/plain");
setOutHeader("Content-Type", "text/plain");
 
var hash = body1.split("hashCode###");
hash = hash[1].split("###");
setOutHeader("hashValue", hash[0]);
</constant>
</setHeader>
 
<to uri="language:javascript?transform=false"/>
<to uri="ipp:activity:find?expectedResultSize=-1&activityInstanceOid=$simple{header.ActOID}&dataFilters=HashValue::$simple{header.hashValue}&states=Application,Created,Hibernated,Interrupted,Suspended" />
<to uri="ipp:activity:complete" />


Using Camel's pop3 endpoint, it looking up to the user's email box, once the email arrives, it runs little java script to fetch the activity Instance OID from the subject and set it as header for further route to use it. It is the ipp:activit:find route that needs the activity Instance OID to search Stardust Audit trail to find the activity instance and complete it. Here we are also configuring ipp:activity:find route to include dataFilters to ensure it completes itself when the received email has intact hash code sent using producer route.

if any of the activity Instance OID or hash code value is changed, the process will not complete this activity, ensuring 1 to 1 match between sent and received email.


Deploy the model. When you run the process instance, it will ask you to input details:

Complete the activity, it will call both the application activities, prepare email body and send and wait. During execution of send and wait the process instance will hibernate and wait for an approval email. once that arrives it will complete this hibernated activity and activate Show Response Data manual activity where you can see the response email message.

ExecutionResult1.jpg


Artifacts can be downloaded from File:EmailSendReciveApproval1.zip

Back to the top