<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body link="#355491" alink="#4262a1" vlink="#355491" style="background: #e2e2e2; margin: 0; padding: 20px;">

<div>
        <table cellpadding="0" bgcolor="#FFFFFF" border="0" cellspacing="0" style="border: 1px solid #dadada; margin-bottom: 30px; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                <tbody>
                        <tr>

                                <td>

                                        <table border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" style="border: solid 2px #ccc; background: #dadada; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                                                <tbody>
                                                        <tr>
                                                                <td bgcolor="#000000" valign="middle" height="58px" style="border-bottom: 1px solid #ccc; padding: 20px; -moz-border-radius-topleft: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 5px; -webkit-border-top-left-radius: 5px;">
                                                                        <h1 style="color: #333333; font: bold 22px Arial, Helvetica, sans-serif; margin: 0; display: block !important;">
                                                                        <!-- To have a header image/logo replace the name below with your img tag -->
                                                                        <!-- Email clients will render the images when the message is read so any image -->
                                                                        <!-- must be made available on a public server, so that all recipients can load the image. -->
                                                                        <a href="https://community.jboss.org/index.jspa" style="text-decoration: none; color: #E1E1E1">JBoss Community</a></h1>
                                                                </td>

                                                        </tr>
                                                        <tr>
                                                                <td bgcolor="#FFFFFF" style="font: normal 12px Arial, Helvetica, sans-serif; color:#333333; padding: 20px;  -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 5px; -webkit-border-bottom-left-radius: 5px;"><h3 style="margin: 10px 0 5px; font-size: 17px; font-weight: normal;">
    Human Task API and Data Structures Proposal
</h3>
<span style="margin-bottom: 10px;">
    modified by <a href="https://community.jboss.org/people/salaboy21">Mauricio Salatino</a> in <i>jBPM</i> - <a href="https://community.jboss.org/docs/DOC-18641">View the full document</a>
</span>
<hr style="margin: 20px 0; border: none; background-color: #dadada; height: 1px;">

<div class="jive-rendered-content"><h1><div class="toc" style="border: 1px dashed black; padding: 10px;"><ul><li>
<a class="jive-link-anchor-small" href="#Introduction">Introduction</a>
</li>
<li>
<a class="jive-link-anchor-small" href="#Task_Def_Service">Task Def Service</a>
</li>
<ul><ul><li>
<a class="jive-link-anchor-small" href="#Task_Def_Structure">Task Def Structure</a>
</li>
<li>
<a class="jive-link-anchor-small" href="#Task_Instance_Queries">Task Instance Queries</a>
</li>
</ul></ul><ul><li>
<a class="jive-link-anchor-small" href="#Task_Presentation_Service">Task Presentation Service</a>
</li>
<li>
<a class="jive-link-anchor-small" href="#Task_Assignments_Service">Task Assignments Service</a>
</li>
<li>
<a class="jive-link-anchor-small" href="#Task_Delegation_Service">Task Delegation Service</a>
</li>
<li>
<a class="jive-link-anchor-small" href="#Task_Notification_Service_">Task Notification Service </a>
</li>
</ul><li>
<a class="jive-link-anchor-small" href="#Task_Instance_Service">Task Instance Service</a>
</li>
<ul><ul><li>
<a class="jive-link-anchor-small" href="#Task_Instance_Structure">Task Instance Structure</a>
</li>
<li>
<a class="jive-link-anchor-small" href="#Task_Instance_Queries_574510">Task Instance Queries</a>
</li>
</ul></ul><ul><li>
<a class="jive-link-anchor-small" href="#Task_Query_Service">Task Query Service</a>
</li>
<li>
<a class="jive-link-anchor-small" href="#Task_Admin_Service">Task Admin Service</a>
</li>
<li>
<a class="jive-link-anchor-small" href="#Task_Attachment_and_Comment_Services_">Task Attachment and Comment Services </a>
</li>
<li>
<a class="jive-link-anchor-small" href="#_Task_Events_Callbacks_Listeners_Service"> Task Events, Callbacks,&#160; Listeners Service</a>
</li>
</ul></ul></div></h1><h1 id="Introduction">Introduction</h1><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>Based on the previous document for reviewing the architecture and APIs exposed by the Human Task module I've came up with this first schetck of proposal for changes.</p><p>I've decided for this stage to show a more modular approach that the one provided by the current implementation. </p><p>This modular approach will let us scale if more functionality is required without the need of chainging the interfaces of the already existing services. It will also allow us to </p><p>provide different implementations for each of the modules which will give us a lot of flexibility to integrate with different technologies. For example provide an Attachments Service</p><p>which uses a Content Repository and keep the comments in a database. We will be able to mix and match based on the scenario requirement.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>The main focus of this proposal is to decouple all the logical services provided by the Human Task module and enable different implementations to cohexist under the same set of APIs.</p><p>This document describe also the Data Structures and Interfaces that will be exposed to the end User. All the other internal mechanisms and classes will be hidden.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>The figure shows the logical organization of the proposed services. The services are logically grouped Task Definition Services and Task Instances Services.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>All the services will be created using CDI beans, which will allow us to expose them via Switchyard / Camel&#160; (<a class="jive-link-external-small" href="https://docs.jboss.org/author/display/SWITCHYARD/Bean+Services">https://docs.jboss.org/author/display/SWITCHYARD/Bean+Services</a>)etc. In other words, these services will be completely agnostic of the</p><p>transports that different applications under different scenarios can use to interact with them. Using CDI will enable us to define different profiles and configurations for the module</p><p>depending on the scenario that we want to use it. Meaning that if you don't need a service, you just don't use it and you don't need to suffer the footprint of that unused service.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>The following repository contains some experiments towards the direction described in this wiki page:</p><p><a class="jive-link-external-small" href="https://github.com/Salaboy/human-task-poc-proposal">https://github.com/Salaboy/human-task-poc-proposal</a></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>The following sections explain the scope of the proposed services:</p><p><a href="https://community.jboss.org/servlet/JiveServlet/showImage/102-18641-3-18930/TaskServices.png"><span> https://community.jboss.org/servlet/JiveServlet/downloadImage/102-18641-3-18930/446-600/TaskServices.png </span></a></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><h1 id="Task_Def_Service">Task Def Service</h1><p>A Task Definition is a structure that contains a reusable structure to define a Human Interaction. By reusable I mean, a Task that can be executed multiple times and</p><p>that shares static information, such as Assignments, Delegation options, Deadlines, Notifications, etc. If all this information can be shared we can reduce the definition time</p><p>just providing the users to select on of the provided definitions, instead of defining all this information every time that a task is required.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>The task service def service will deal with static Human Task Definitions. These definitions can be generated by the userTasks from a business processes or via the</p><p>provided APIs by third parties applications. We will be able to deploy new task definitions to the service, list all the available definitions based on different criterias, etc. </p><p>A set of more specific services will be provided to store and manage additional information about Task Definitions.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code jive-java">&#160;&#160;&#160;&#160;&#160;&#160;&#160; TaskDefService taskDefService = container.instance().select(TaskDefService.class).get();
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="darkgreen">// We can automatically create TaskDef based on the BPMN2 file</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="darkgreen">//&#160; We can enrich those tasks with the form builder</font>
&#160;
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="darkgreen">//From the spec: register, port == taskdefid </font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160; String port = taskDefService.deployTaskDef(id, taskdef);
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="darkgreen">// list</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160; taskDefService.listTaskDef();
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="darkgreen">// getById</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160; taskDefService.getTaskDef(id);
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="darkgreen">// unregister</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160; taskDefService.undeployTaskDef(id);
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><h3 id="Task_Def_Structure">Task Def Structure</h3><p>TBD</p><h3 id="Task_Instance_Queries">Task Instance Queries</h3><p>TBD</p><h2 id="Task_Presentation_Service">Task Presentation Service</h2><p>The task presentation service will allow us to provide more information about how a task will be presented to the users. This will include the I18N options for all the texts</p><p>related to a task such as Subject, Description, Goals, etc. Decoupling this logic and structures in a different service will allow us to only query this information when it's needed and</p><p>not everytime that we want to interact with a task. Because this is not a core service, we can choose to not use it and disable it if our implementation doesn't require such presentation information.</p><p>This service will allow us to define common presentation elements that can be shared among different task definitions.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code jive-java">&#160; TaskPresentationService taskPresentationService = container.instance().select(TaskPresentationService.class).get();
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="darkgreen">//Internally it will use taskDef.getTaskDef(id).getPresentationElements()</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160; List&lt;PresentationElement&gt; presentationElements = taskPresentationService.getPresentationElements(taskId);
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><h2 id="Task_Assignments_Service">Task Assignments Service</h2><p>The task Assignment service will be in charge of hosting information about task assignments. This information will describe the potentialOwners, excludedOwners, StakeHolders, BusinessAdmins, etc.</p><p>All this information will be related with a task definition and not with a task instance. In other words this is about static definitions (doing on modeling time) of the task and not about the </p><p>assignments that will be defined at runtime when a Task Instance is created. Having this information decoupled will allow us to define different strategies for validating, querying and interacting with </p><p>an external identity service. When a Task instance is created, using this information plus the runtime context and the defined strategies the concrete assigments will be applied to the Task instance.</p><p>Instead of store and duplicate assignment information per task , we can reuse the assignments from previously defined tasks.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><h2 id="Task_Delegation_Service">Task Delegation Service</h2><p>This service will host different delegation schemas that can be used by the task definitions. Depending on the business scenario were the human interactions will be defined, this service will host common patterns that can be reused by Task Definitions. Instead of store and duplicate delegation/escalation information per task , we can reuse the delegationescalation information from previously defined tasks.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><h2 id="Task_Notification_Service_">Task Notification Service </h2><p>The service expose an interface that allows us to define templates for notifications that can be used on Task Deadlines, Lifecycle Events, Callbacks.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><h1 id="Task_Instance_Service">Task Instance Service</h1><p>Once we have a Task Definiton deployed we can start creating instances of a specific Task Definition Type. The instance will use the static information provided </p><p>by the task definition to create the new Task Instance. The information about assignments, deadlines and escalations/delegations will be defined inside the Task Definition (which support </p><p>expressions) . When a new instance is created all the expressions are resolved and the task will only contain the relevant data for execution. If at runtime more information about the Task Definition is required, the Task Instance Service can use the Task Definition Service internally to get generic information. </p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>The Task Instance Service will expose the life cycle methods to interact with a Task Instance, such as: start, complete, forward, claim, release, etc (WS-HT defined methods). </p><p>Internally, the Task Instance Service will contain the core logic to represent the task life cycle. </p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>Having this Service decoupled from the rest will allow us to improve that logic and have a well defined boundary of the module capabilties and responsabilities. Because we are working</p><p>to provide a pluggable life cycle mechanism, different Task Instances Services implementation can be provided. Using CDI decorators and qualifiers the API usage will be extremely improved </p><p>and it will easily allow us to run the component in any environment (From standalone to EE with major changes).</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>Sync and Async Services should be modeled using CDI qualifiers instead of different interfaces.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code jive-java"><font color="darkgreen">// Lifecycle and query methods for task instances only!!!! </font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160; TaskInstanceService taskInstanceService = container.instance().select(TaskInstanceService.class).get();
&#160;
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>long</b></font> taskId = taskInstanceService.newTask(port, params);
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; taskInstanceService.start(taskId);
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; taskInstanceService.complete(taskId, params);
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; taskInstanceService.forward(taskId, <font color="red">"user"</font>);
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><h3 id="Task_Instance_Structure">Task Instance Structure</h3><p>TBD</p><h3 id="Task_Instance_Queries_574510">Task Instance Queries</h3><p>TBD</p><h2 id="Task_Query_Service">Task Query Service</h2><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><h2 id="Task_Admin_Service">Task Admin Service</h2><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><h2 id="Task_Attachment_and_Comment_Services_">Task Attachment and Comment Services </h2><p>Both services are decoupled to allow fine grained control on how the attachments are handled and stored. Depending on the context on the task and the architecture we the Human Interactions will happen is how we will want to handle attachments. Providing a decoupled interface for these services will allow us to gradually support different ways to store this information that is related with a specific task instance.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code jive-java">&#160;&#160;&#160;&#160;&#160;&#160; TaskAttachmentService taskAttachmentService = container.instance().select(TaskAttachmentService.class).get();
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; taskAttachmentService.addAttachment(taskId, attachment);
&#160;&#160;&#160;&#160;&#160;&#160;&#160; List&lt;Attachment&gt; attachs = taskAttachmentService.getAttachments(taskId);
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; TaskCommentService taskCommentService = container.instance().select(TaskCommentService.class).get();
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; taskCommentService.addComment(taskId, comment);
&#160;&#160;&#160;&#160;&#160;&#160;&#160; List&lt;Comment&gt; comments = taskCommentService.getComments(taskId);
&#160;&#160;&#160;&#160;&#160;&#160;&#160; taskCommentService.removeComment(commentId);
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><h2 id="_Task_Events_Callbacks_Listeners_Service"> Task Events, Callbacks,&#160; Listeners Service</h2><p>This service will expose a set of APIs that will allow external applications to register interest and callback functions to a Task Instance or a group of Task Instances (could be also by Task Definition). </p><p>When a third party application creates a task inside the human task module, it will automatically becomes the owner of the task. If the application is interested in being notified about the Task Lifecycle or just a small set of events, the application will need to register a callback function or identifier which enables the component to contact back the application. This callbacks and listeners information should be (once again) agnostic to the transport. This information will represent a logic description about how to contact a third party application if it is needed, but several implementations can be plugged to achieve the desired behavior on runtime. We can leverage the Events features of CDI for listeners and callbacks.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>Having this service as a decoupled module will allow us to: </p><ul><li>Provide different strategies for different environments</li><li>Allow external components to be notified (pull) or to poll the task events notifications and execute the callbacks for us. Meaning that we expose the information<br/>about what needs to happen but not how it will happen. Reducing the complexity of the component and leveraging already implemented features from frameworks like Switchard / Camel.</li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><h2></h2></div>

<div style="background-color: #f4f4f4; padding: 10px; margin-top: 20px;">
    <p style="margin: 0;">Comment by <a href="https://community.jboss.org/docs/DOC-18641">going to Community</a></p>

        <p style="margin: 0;">Create a new document in jBPM at <a href="https://community.jboss.org/choose-container!input.jspa?contentType=102&containerType=14&container=2034">Community</a></p>
</div></td>
                        </tr>
                    </tbody>
                </table>


                </td>
            </tr>
        </tbody>
    </table>

</div>

</body>
</html>