Mauricio Salatino [https://community.jboss.org/people/salaboy21] modified the 
document:

"Human Task Module Refactoring"

To view the document, visit: https://community.jboss.org/docs/DOC-18789

--------------------------------------------------------------
This document aims to explain how the human task module should look after 
applying some refactorings which were the results of several experiments.
You can more about this experiments here:  
https://github.com/Salaboy/human-task-poc-proposal 
https://github.com/Salaboy/human-task-poc-proposal

The following sections describe how the module will look like after the 
refactorings

h1. APIs and Service Structure
All the Services Proposed by this refactoring are CDI managed beans. For the 
ones not familiar with CDI, you need to think about it as JPA for Dependency 
Injection frameworks. So we can say
that CDI is to Spring/Guice/Weld what JPA is to Hibernate/Top Link. CDI propose 
some very cool out of the box features that we definitely want to use to make 
our services more clear, robust, easy to maintain. Some of the things provided 
by CDI that I'm using in the experiments are:

* Configuration based on annotations: We can inject services instances without 
needing to specify the implementation, so we keep it pluggable and decoupled 
all the time.
Look at:  
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/impl/TaskInstanceServiceImpl.java
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/impl/TaskInstanceServiceImpl.java
As you can see there, we can define at service level which characteristic the 
service implementation will need to be injected inside a service, but then we 
can provide several alternatives
for that implementation and configure them for different environments. The CDI 
container will do the rest for us, it will choose wisely the implementation 
that fits with all the characteristic required and it will inject the services 
implementation when it's need.


* Event Producers and Observers 
Look at:  
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/internals/lifecycle/MVELLifeCycleManager.java#L246
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/internals/lifecycle/MVELLifeCycleManager.java#L246
and:  
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/lifecycle/listeners/JPATaskLifeCycleEventListener.java
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/lifecycle/listeners/JPATaskLifeCycleEventListener.java
As you can see a simple and out of the box (and defined by an specification) 
Event mechanism is provided, allowing us to keep our Event Producers completely 
Decoupled from our Event Observers. We can also configure the obsevers to be 
instantiated by teh CDI container or we can decide how many instances of our 
observer do we need for a particular use case.


* Decorators/Interceptors: 
We can use both to improve a specific technical or business policy should be 
applied to the execution of our service methods. 
Look at:  
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/internals/lifecycle/UserGroupLifeCycleManagerDecorator.java
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/internals/lifecycle/UserGroupLifeCycleManagerDecorator.java
Decorators and Interceptors can be enabled and disabled based on 
configurations, which give us once again a great flexibility to add or remove 
things based on what we want to achieve.

At the end of the day we have a set of services which can leverage the power of 
the CDI container. We can also hide that we are using CDI/Weld (weld is the 
implementation of the CDI interfaces/spec), look at:  
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/test/java/org/jboss/human/interactions/NewAPITest.java#L259
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/test/java/org/jboss/human/interactions/NewAPITest.java#L259
We can use it internally and if the user wants to get access to the container 
he/she can. 

 
https://community.jboss.org/servlet/JiveServlet/showImage/102-18789-6-19052/TaskServicesProposed.png
  
https://community.jboss.org/servlet/JiveServlet/downloadImage/102-18789-6-19052/450-439/TaskServicesProposed.png
 
All the proposed services are simple POJOs which can contain references to all 
the other services. We can combine them to achive different functionality.
For a more detailed description about each service you can look at:  
https://community.jboss.org/docs/DOC-18641 
https://community.jboss.org/wiki/HumanTaskAPIAndDataStructuresProposal 

The next section describe more advantages about using the CDI/Weld proposed 
programming model to keep our services simple and take out all the code that is 
not related with Human Interaction logic.


h1. Services Working Together
The following image shows how the interactions with the human task module will 
happen. The diagram shows the interfaces and implementations required to 
interact with a TaskInstance
 
https://community.jboss.org/servlet/JiveServlet/showImage/102-18789-6-19050/TaskInstanceServiceSimplified.png
  
https://community.jboss.org/servlet/JiveServlet/downloadImage/102-18789-6-19050/450-252/TaskInstanceServiceSimplified.png
 
The previous figure shows all the components interacting when we want to 
interact with a task instance that was already created. 
So let's say for example that we want to start a task. From the client 
perspective he/she can use the TaskServiceEntryPoint to 
start the task. This TaskServiceEntryPoint will delegate the calls to the 
different service implementations. In this case if we are 
starting a task the TaskInstanceService implementation will delegate the action 
to the LifeCycleManager. As you can see
the LifeCycleManager, no matter the implementation is being decorated by an 
UserGroupDecorator which in charge of handling the
resolution of the identities associated with the operation. The 
LifeCycleManager is also an Event Producer, which means that is in charge
of generating events to communicate to the external world the LifeCycle changes 
of each task. We can then attach external listeners to 
Observer these events to audit what is happening or as callback mechanisms to 
execute actions when a task is completed for example.
Classes and Interfaces to look at this point:
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/api/TaskServiceEntryPoint.java
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/api/TaskServiceEntryPoint.java
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/impl/TaskInstanceServiceImpl.java
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/impl/TaskInstanceServiceImpl.java
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/impl/TaskDefServiceImpl.java
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/impl/TaskDefServiceImpl.java
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/internals/lifecycle/MVELLifeCycleManager.java
 
https://github.com/Salaboy/human-task-poc-proposal/blob/master/human-task-core-cdi-experiment/src/main/java/org/jboss/human/interactions/internals/lifecycle/MVELLifeCycleManager.java

No magic, no complicated debug sessions, the services should be as straight 
forward as possible trying to following the sequence:
*TaskServiceEntryPoint ---(Delegate)--> Task*ServiceImpl -> Storage*

h3. Shared Persistence Context and Transactional Behavior
If you take a look at the previous links you will notice that all the Services, 
for example TaskInstanceServiceImpl and TaskDefServiceImpl are all using an 
Inject EntityManager.
And there is no code related with transactions or loading and merging detached 
entities (em.getTransaction(), ut.begin(), em.merge()). 
The EntityManager that is being injected is being managed by Seam Persistence 
(ASL 2.0) ( 
http://docs.jboss.org/seam/3/persistence/latest/reference/en-US/html_single/ 
http://docs.jboss.org/seam/3/persistence/latest/reference/en-US/html_single/) 
which give us a transparent
way of having all the advantages of the unified programming model of being in 
Managed and Transaction Persistence Context without the hassle of taking care 
of how to share different
instances of an EntityManager or demarcate the transactions based on what is 
available in our context. Seam Persistence provide us a declarative way to deal 
with all this topics, and take all the code
related with these tasks out of the Human Task Module. This also give us the 
possibility to integrate with Spring only configuring our environment and not 
changing our code 
( http://www.javaworld.com/javaworld/jw-05-2008/jw-05-spring-seam3.html 
http://www.javaworld.com/javaworld/jw-05-2008/jw-05-spring-seam3.html)

The Seam 3 Spring module give us all the integration that we can possible want 
and even more with Spring, no need to worry about that stuff at all:  
http://seamframework.org/Seam3/SpringModule 
http://seamframework.org/Seam3/SpringModule

h1. Integration with the Outside World
Using CDI for the integration perspective is just great. Most of the 
integration frameworks out there have CDI integration which make exposing our 
services extremely easy and natural.
I've created an experiment showing how we can do this with Switchyard/Camel, 
and most of this principles can be used for the Process/Rule engine as well:
 
https://github.com/Salaboy/human-task-poc-proposal/tree/master/human-task-switchard
 
https://github.com/Salaboy/human-task-poc-proposal/tree/master/human-task-switchard

The main focus of this project is to contain all the integration configuration 
required to expose our POJO services using different transports. I've being 
focused on JMS because it will allow
us to have asynchronous interactions transparently. 

The following figure shows us teh Switchyard Declarative configuration which is 
using our CDI POJO services to define the integration points:
 
https://community.jboss.org/servlet/JiveServlet/showImage/102-18789-6-19053/subscribers.png
  
https://community.jboss.org/servlet/JiveServlet/downloadImage/102-18789-6-19053/450-190/subscribers.png
 
The previous diagram is showing the following interaction and integration 
points:
1. A client sending a JMS message wants to start a task
2. The Switchyard container is exposing a JMS queue which is expecting "Action" 
messages
3. As soon as we get one of this action messages, Switchyard picks the message 
and propagate it to the correspondant service
4. We can register a listener that will observe the events being fired by our 
components (i.e. TaskLifeCycleEvents)
5. As soon as one of these events is observed by our listener it will be 
redirected to a JMS topic which can contain multiple subscribers
6. Any number of subscribers can pick up the message and do what they want with 
it

More info:  https://community.jboss.org/docs/DOC-18719 
https://community.jboss.org/wiki/HumanTaskModuleSwitchYardIntegration

NOTE: An Executor component can be used to pick the up the notification and 
execute callbacks. I'm right now creating a document which explains how this 
component can be used.
This idea perfectly fits in this scenario. I will add the link as soon as the 
document is ready. 

Cool Facts:

1. This experiment is just showing one of the possibilities of using Switchyard 
and the camel integration for handling async interactions in a very efficient 
way, without including code inside the Human Task Module. We are delegating all 
the interaction points to the Integration framework instead of adding 
complexity to the Human Task Logic.
2. We can integrate with any transport in the same way and we can mix and match 
what we want. For example, we can recieve a REST call and send notifications 
via JMS
3. Switchyard and all the services can run inside a SE or EE environment 
(because of CDI and its programming model)
4. Is all based on configuration, so we can provide a set of well known 
configurations and let the users to customize that if they want
5. Quartz for reminders, cron tasks and all of that comes for free
6. Push us to use a clean programming model, leverage all the CDI features
--------------------------------------------------------------

Comment by going to Community
[https://community.jboss.org/docs/DOC-18789]

Create a new document in jBPM at Community
[https://community.jboss.org/choose-container!input.jspa?contentType=102&containerType=14&container=2034]
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to