This document describes how a process run definition is working. In general, processing runs are used to keep logs of a process run request execution. Processing Run Definition can be applied once or on a recurring basis, based on the scheduling settings as defined on the definition. All the runs that were performed based on each definition can be viewed within the definition. The following example construct a process run mechanism that sends messages using threats.
In order to implement a process run definition, the first thing to do is to create a new module in metadata. This new module has a module id and a new feature with its own process id and a method that will be explained later. The next step is to create a Java class smsMessageRunDefintion which extends viewObject class. It is includes a processRunDefinition and a schedulerTask objects which are necessary for a process run definition. Then, some action inputs should be defined to specify certain fields that describe a process run (broadcastPeriod, broadcastInterval etc.) whilst some criteria if are available. The example below, illustrates the java class, ass was explained:
public class smsMessageRunDefintion extends ViewObject{
private static final long serialVersionUID = 1L;
private CRMDOProcessRunDefinition processRunDefinition;
private SchedulerTask schedulerTask;
//Action inputs
private MessageType messageType;
private CRMDOCommunicationQueueExternalSystem communicationQueueExternalSystem;
private Integer broadcastPeriod;
private Integer broadcastInterval;
private Integer processImmediately;
//Criteria - Not any available
//Get and Set methods
public CRMDOProcessRunDefinition getProcessRunDefinition() {
return processRunDefinition;
}
public void setProcessRunDefinition(
CRMDOProcessRunDefinition processRunDefinition) {
this.processRunDefinition = processRunDefinition;
}
public MessageType getMessageType() {
return messageType;
}
public void setMessageType(MessageType messageType) {
this.messageType = messageType;
}
public CRMDOCommunicationQueueExternalSystem getCommunicationQueueExternalSystem() {
return communicationQueueExternalSystem;
}
public void setCommunicationQueueExternalSystem(
CRMDOCommunicationQueueExternalSystem communicationQueueExternalSystem) {
this.communicationQueueExternalSystem = communicationQueueExternalSystem;
}
public Integer getBroadcastPeriod() {
return broadcastPeriod;
}
public void setBroadcastPeriod(Integer broadcastPeriod) {
this.broadcastPeriod = broadcastPeriod;
}
public Integer getBroadcastInterval() {
return broadcastInterval;
}
public void setBroadcastInterval(Integer broadcastInterval) {
this.broadcastInterval = broadcastInterval;
}
public Integer getProcessImmediately() {
return processImmediately;
}
public void setProcessImmediately(Integer processImmediately) {
this.processImmediately = processImmediately;
}
public SchedulerTask getSchedulerTask() {
return schedulerTask;
}
public void setSchedulerTask(SchedulerTask schedulerTask) {
this.schedulerTask = schedulerTask;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
@Override
protected LinkedHashMap<String, CRMDO> getAssociatedDataObjects() {
LinkedHashMap<String, CRMDO> dataObjects=new LinkedHashMap<String, CRMDO>();
dataObjects.put("processRunDefinition", getProcessRunDefinition());
return dataObjects;
}
@Override
public LinkedHashMap<String, String> getViewMandatoryFields() {
LinkedHashMap<String, String> viewMandatoryFields = new LinkedHashMap<String, String>();
viewMandatoryFields.put( "broadcastPeriod", "key_broadcast_period");
viewMandatoryFields.put( "broadcastInterval", "key_broadcast_interval");
return viewMandatoryFields;
}
}
In the following steps, five summary pages need to be implemented in order to have a complete image of a process run definition screen, thus the image below illustrates the run definition summary page. The main summary page includes other four, starting from the first summary page, which is shown in the process runs drill-own. This drill-down also includes another two summary pages for successful and failed entries accordingly and lastly one summary page for the previous versions, as we can see.
In this case, a UI class have to implement as well, extending the CRMUIProcessRunDefinitionBean. Also, module id and process id, must be defined in the UI as they declared in the module.xml file. To implement the basic functionality, we will need to create the following methods: createButton, loadForm, editButton, saveButton, submitButton, deleteButton and amendButton, as demonstrated below:
/**
* Session Bean implementation class CRMUISmsMessageRunDefinition
*/
@Stateless(mappedName = "ejb/CRMUISmsMessageRunDefinition")
@LocalBean
public class CRMUISmsMessageRunDefinitionBean extends CRMUIProcessRunDefinitionBean {
private static final long serialVersionUID = 1L;
private static final String PROCESS_RUN_LOG_ENTRIES_EXIST = "PROCESS_RUN_LOG_ENTRIES_EXIST";
private static final String IS_PROCESS_RUN_DEF_LATEST_VERSION = "IS_PROCESS_RUN_DEF_LATEST_VERSION";
//Declare module and process id as defined in metadata
private static final String MODULE_ID = "SMS_SERVICES";
private static final String PROCESS_ID = "SMS_MESSAGE_PROCESS";
@EJB private CRMBOProcessRunDefinitionBean processRunDefinitionBean;
@EJB private CRMBOProcessRunLogBean processRunLogBean;
@EJB private smsInfocasMessageRunDefinitionXMLUtilBean smsInfocasMessageRunDefinitionXMLUtilBean;
/**
* Default constructor.
*/
public CRMUISmsMessageRunDefinitionBean() {
// TODO Auto-generated constructor stub
}
public smsMessageRunDefintion createButton() throws Exception {
smsMessageRunDefintion definition = new smsMessageRunDefintion();
CRMDOProcessRunDefinition processRunDefinition = (CRMDOProcessRunDefinition)processRunDefinitionBean.construct();
processRunDefinition.setModule(MODULE_ID);
processRunDefinition.setProcess(PROCESS_ID);
definition.setProcessRunDefinition(processRunDefinition);
definition.setSchedulerTask(new SchedulerTask());
definition.setMandatoryFields();
return definition;
}
public smsMessageRunDefintion loadForm(String id) throws Exception {
CRMDOProcessRunDefinition processRunDefinition = (CRMDOProcessRunDefinition)processRunDefinitionBean.load(id);
smsMessageRunDefintion definition = new smsMessageRunDefintion();
definition.setProcessRunDefinition(processRunDefinition);
definition = smsMessageRunDefinitionXMLUtilBean.loadProcessingRunDefinition(definition);
ArrayList<CRMDO> provisioningRequestProcessingRuns = processRunLogBean.load(definition.getProcessRunDefinition());
if (provisioningRequestProcessingRuns!=null && provisioningRequestProcessingRuns.size() > 0)
{
definition.setAlias(PROCESS_RUN_LOG_ENTRIES_EXIST, "1");
}
else
{
definition.setAlias(PROCESS_RUN_LOG_ENTRIES_EXIST, "0");
}
Boolean isLatestVersion = isLatestVersion(processRunDefinition);
if (isLatestVersion)
{
definition.setAlias(IS_PROCESS_RUN_DEF_LATEST_VERSION, "1");
}
else
{
definition.setAlias(IS_PROCESS_RUN_DEF_LATEST_VERSION, "0");
}
definition.setMandatoryFields();
return definition;
}
public smsMessageRunDefintion editButton(smsMessageRunDefintion definition) throws Exception {
CRMDOProcessRunDefinition processRundefinition = (CRMDOProcessRunDefinition)processRunDefinitionBean.load(definition.getProcessRunDefinition().getId());
if (processRundefinition==null)
{
processRundefinition = processRunDefinitionBean.loadLatest(definition.getProcessRunDefinition().getCode());
}
definition = loadForm(processRundefinition.getId());
if (definition.getAlias(PROCESS_RUN_LOG_ENTRIES_EXIST).equals("1"))
{
definition = amendMessageRunDefinition(definition);
}
return definition;
}
public smsMessageRunDefintion saveButton(smsMessageRunDefintion definition) throws Exception, MandatoryFieldException {
definition.setMandatoryFields();
validateMandatoryFields(definition);
definition = smsMessageRunDefinitionXMLUtilBean.setMessageRunDefinitionXML(definition);
CRMDOProcessRunDefinition processRunDefinition = definition.getProcessRunDefinition();
if (processRunDefinition.getCode()==null)
{
processRunDefinition.setCode(processRunDefinitionBean.getNextSequenceNumber(SequenceNumber.PROCESSRUNDEFINITIONCODES));
}
processRunDefinitionBean.validateAndSave(definition.getProcessRunDefinition());
if (definition.getBroadcastPeriod()==null)
{
throw new MandatoryFieldException(getCRMSession(), "key_broadcast_period");
}
if (definition.getBroadcastInterval()==null)
{
throw new MandatoryFieldException(getCRMSession(), "key_broadcast_interval");
}
ArrayList<CRMDO> provisioningRequestProcessingRuns = processRunLogBean.load(definition.getProcessRunDefinition());
if (provisioningRequestProcessingRuns!=null && provisioningRequestProcessingRuns.size() > 0)
{
definition.setAlias(PROCESS_RUN_LOG_ENTRIES_EXIST, "1");
}
else
{
definition.setAlias(PROCESS_RUN_LOG_ENTRIES_EXIST, "0");
}
Boolean isLatestVersion = isLatestVersion(processRunDefinition);
if (isLatestVersion)
{
definition.setAlias(IS_PROCESS_RUN_DEF_LATEST_VERSION, "1");
}
else
{
definition.setAlias(IS_PROCESS_RUN_DEF_LATEST_VERSION, "0");
}
return definition;
}
public smsMessageRunDefintion submitButton(smsMessageRunDefintion definition) throws Exception {
CRMDOProcessRunLog processRunLog = (CRMDOProcessRunLog)processRunLogBean.construct(definition.getProcessRunDefinition());
submit(processRunLog);
return loadForm(definition.getProcessRunDefinition().getId());
}
public smsMessageRunDefintion deleteButton(smsMessageRunDefintion definition) throws Exception {
processRunDefinitionBean.validateAndDelete(definition.getProcessRunDefinition());
return definition;
}
public smsMessageRunDefintion amendMessageRunDefinition(smsMessageRunDefintion definition) throws Exception {
CRMDOProcessRunDefinition processRunDefinition = definition.getProcessRunDefinition();
CRMDOProcessRunDefinition newProcessRunDefinition = (CRMDOProcessRunDefinition)processRunDefinition.clone();
newProcessRunDefinition.setVersion(new Integer(processRunDefinition.getVersion().intValue()+1));
newProcessRunDefinition.setProperty("name", new FieldAttribute("1"));
newProcessRunDefinition.setProperty("altCode", new FieldAttribute("1"));
definition.setProcessRunDefinition(newProcessRunDefinition);
definition.setAlias(PROCESS_RUN_LOG_ENTRIES_EXIST, "0");
definition.setAlias(IS_PROCESS_RUN_DEF_LATEST_VERSION, "1");
return definition;
}
}
Later on, data entry page must be implemented by giving the ability to the user create, view, modify, delete or apply other operations on a process run record. Below, we can see the detail page of the process run definition and specifically the process runs tab, showing the successful whilst failed runs.
In addition, an XMLUtilBean need to be implemented, in order to save action inputs, criteria and schedule settings in the xml. Also this, messageRunDefinitionXMLUtilBean extends ProcessRunDefinitionXMLUtilBean.
On the last step, the CRMProcessRunBean mentioned in the module.xml as additional process need to be implemented whilst the method executeMessageProcess which executes the process runs via threats mechanism like in Implement a Multithreaded Process section. Firstly, process run method saves the action inputs. Then each process run request processed from a thread and if procedure works correctly, the next process run prepares to been processed and the current one saved as completed. On the other hand, if something goes wrong, the current process run is saved as failed and moves to process the next request. This procedure continues until all the process run requests pass from the multi-threading mechanism. As a result, all the successful and failed process runs are illustrated in the summary page image above. Also, below is illustrated the example of the multi-threaded method implemented:
public class CRMProcessSmsRunBean extends CRMProcessRunBean {
@EJB private smsMessageRunDefinitionXMLUtilBean messageRunDefinitionXMLUtilBean;
...
public void executeMessageProcess(CRMDOProcessRunLog processRun) throws Exception {
CRMDOProcessRunDefinition processRunDefinition = processRun.getProcessRunDefinition();
smsMessageRunDefintion messageRunDefinition= new smsMessageRunDefintion();
messageRunDefinition.setProcessRunDefinition(processRunDefinition);
messageRunDefinition = messageRunDefinitionXMLUtilBean.loadProcessingRunDefinition(messageRunDefinition);
CRMDOProvProvider provProvider = exsetProviderBean.loadEffective();
provProvider = exsetProviderBean.setObjectsFromXML(provProvider);
processRun.setStatus(ProcessRunLogStatus.IN_PROGRESS);
processRun.setStartDate(getCurrentDate());
processRunLogBean.save(processRun);
Boolean processComplete = new Boolean(false);
JDBCConnection connection= null;
try
{
//At this point is implemented the threats mechanism like in Implement a Multithreaded Process section
catch (Exception e)
{
saveEntityLogRecord(
processRun,
"",
"",
ProcessRunLogEntityStatus.FAILED,
e.getClass().getSimpleName(),
ExceptionUtil.getStackTrace(e));
processRun.setEndDate(getCurrentDate());
processRun.setStatus(ProcessRunLogStatus.FAILED);
processRunLogBean.save(processRun);
processRun = saveNextProcessRun(processRun);
if(connection!=null)
connection.close();
}
if (processComplete)
{
processRun.setStatus(ProcessRunLogStatus.COMPLETED);
processRun.setEndDate(getCurrentDate());
processRun = saveNextProcessRun(processRun);
processRunLogBean.save(processRun);
}
}
...
}