Showing posts with label jbpm7. Show all posts
Showing posts with label jbpm7. Show all posts

2018/05/21

Contract Net Protocol with jBPM

jBPM provides lots of capabilities that could be used out of the box to build rather sophisticated solutions. In this article I'd like to show one of them - Contract Net Protocol.

Contract Net Protocol (CNP) is a task-sharing protocol in multi-agent systems, consisting of a collection of nodes or software agents that form the 'contract net'. Each node on the network can, at different times or for different tasks, be a manager or a contractor. [1]

This concepts nicely fits into case management capabilities of jBPM 7. It allows to easily model interaction between Initiator and Participant(s).

source http://www.fipa.org/specs/fipa00029/SC00029H.html#_ftnref1
Contract can be announced to many participants (aka bidders) that can either be interested in the contract and then bid or simply reject it and leave the contract net completely.

with jBPM 7, contract net can be modelled as a case definition where individual phases of the protocol can be externalised to processes to carry on with additional work. This improves readability and at the same time promotes reusability of the implementation.


Announce contract and Offer contract are separate processes that can be implemented separately according to needs. For this basic showcase they are based on human decision and look as follows

Each of the participants of the contract net will have dedicated instance of the announce contract process. Each should make the decision if they will place a bid or not. In case they won't do it at all, main contract net case definition keeps a timer event on them to remove given bidder if the deadline was reached.

As soon as all bidders replied (or time for reply elapsed) there are set of business rules that will evaluate all provided bids and select only one. Once it is selected an Offer contract subprocess will be initiated - after milestone of selecting a bid is completed.


So the bidder who placed the selected bid will get the "Work on contract" task assigned to actually perform the work. Once done the worker indicates if the work was done or she failed at doing the work. In case of successful completion of the work additional business rules are invoked to verify it.

Completion of the work (assuming it was done) will show the results of the work to the initiator for final verification. Once the results are reviewed the contract is ended - by that case instance is ready to be closed.

All this in action can be seen in the following screencast




Again, this is just basic implementation but shows the potential that can be unleashed to build advanced Contract Net Protocol solutions.

Complete project that can be easily imported into workbench and executed in KIE server can be found here.

To start the case instance you can use following payload that includes data (both contract and bidders) and case role assignments

{
    "case-data": 
    {
        "contract": 
        {
            "Contract": 
            {
                "name" : "jBPM contract",
                "description" : "provide development expertise for jBPM project",
                "price" : 1234.40
            }
        },
        "bidders": [
        {
            "Bidder": 
            {
                "id" : "maciek",
                "name" : "Maciej Swiderski",
                "email" : "maciek@email.com"   
            }
        },
        {
            "Bidder": 
            {
                "id" : "john",
                "name" : "John doe",
                "email" : "john@email.com"   
            }
        }
        ]
    },

    "case-user-assignments": 
    {
        "Initiator": "mary",
        "Participant": "john"
    },

    "case-group-assignments": 
    {
        
    }
}

If you need more bidders just add them by copying the single bidder in the payload

[1] Source - https://en.wikipedia.org/wiki/Contract_Net_Protocol

2017/12/13

Be lazy with your data

jBPM comes with really handy feature called pluggable variable persistence strategy (or shorter marshalling strategies). This is the mechanism responsible for persisting process instance and task variables to their data store - whatever kind of data store you use.

An important thing to keep in mind when using marshalling strategies is the fact that each time variable is read it will read that from the data store which might be:

  • file system
  • data base
  • REST service
  • document management system e.g. ECM
  • and more
depending on the accessibility of this service and its performance this might not be a big deal but if that data is loaded many times it might become an issue. Especially if the data is of fair size like documents. 
Imagine process instance operates on bunch of documents (word, pdf, etc). Each of this document is of 2MB size which will give 20 MB for 10 documents. That means every time user interact with this process instance all documents will be loaded from external system. And this is not a problem (or it is actually how it should behave) when these documents are needed for the work user intend to perform. 

But what if (s)he is not going to use all documents or even not a single one? Or if it's not a user but an timer is firing of to send reminder to users?

Should all documents be loaded then? Obviously it does not make much sense though the problem with this decision is how would process instance know if given data will be used or not? And because of that it simply loads all variables whenever process instance (or task) is loaded.
This is default mechanism for process instance and task variables that are stored as part of them as it does not make much sense to separate them since their life cycle is bound to each other - always loaded and stored together. So this does not bring any overhead or additional communication effort.

Though situation looks slightly different for variables that are actually stored externally - like physical documents stored in ECM system. In this case, documents (including their content - 2MB each) will be loaded regardless if the data will be used or not. Moreover, in high volume systems this might put unnecessary load on ECM to constantly load and store documents which actually didn't change.

jBPM 7.6 comes with support for lazy load of variables to resolve these issues. Though it won't magically apply to all your variables that are stored externally, but will provide all the support from the engine side to take advantage of lazy loading. Since the mechanism for loading variables will differ based on the back end data store it's up to user to apply this principle which is rather simple as follows:
  • your variable must implement org.kie.internal.utils.LazyLoaded
  • your marshaler strategy needs to provide kind of service responsible for loading content of the variable - user by load method of the variable
  • your marshalling strategy should not load content by default but set that service on the variable so can be used to lazy load when needed
  • to avoid unnecessary operations to store variable, implement sort of tracking system on your data to identify if variable has changed and store it only if it did, your marshaler should check this tracking mechanism in marshal method and should reset it after loading variable in unmarshal method

jBPM 7.6 provides this mechanism as part of its support for documents (jbpm-document module). The DocumentImpl implements both LazyLoaded and tracking mechanism to resolve both issues (too often load and too often store). This extremely improves overall performance as it reduces number of reads and writes to document service at the same time provides content on demand and only when needed.

I'd like to encourage everyone who stores process or task variables externally to make it lazy loaded and tracked to improve the performance of your system and reduce load on your back end data store.

2017/10/11

where did the authoring go? getting started with workbench and kie server on 7.3 and onwards

Recently there were number of questions on mailing list about authoring perspective missing in recent versions of jBPM and/or drools... that lead me to take few minutes to make this write up and attached screen case to show that ... it was not removed :)

It was actually redesigned for easier access and to improve user experience when using the workbench. Though for people who get used to the "old" way could be a bit lost at first. So here it goes:



What you can see in this screen cast is:

  • where to go to see the projects
  • how to create new project
  • how to import new project 
  • how to import project from external git server
  • how to find the settings and various configuration options of the project
  • how to build and deploy
  • where to find deployed projects into execution servers
  • where to find process definitions
  • where to start new process instance
Nothing fancy but might get you started much easier after moving from previous version.

Comments are more than welcome in terms of improvements and feedback about usability.

2017/06/26

KIE Server welcomes Narayana

KIE Server (with BPM capabilities) requires data base for persistence. That is well known fact, though to have properly managed persistence there is also need for transaction manager that will ensure consistency of the data jBPM persists.

Since version 7 KIE Server is the only provided out of the box execution server (there is no execution server in workbench) so it got some additional attention to make sure it does perform in the best possible way.

KIE Server supports following runtime environments:

  • WildFly 10.x
  • EAP 7.x
  • WebSphere 9
  • WebLogic 12.3
  • Tomcat 8.x

Since all of the above are supported for jBPM usage they all must provide transaction manager capability. For JEE servers (WildFly, EAP, WebSphere, WebLogic) KIE server relies on what the application server provides. Though for Tomcat the story is slightly different...

Tomcat does not have transaction manager capabilities so to make use of jBPM/KIE Server on it, it required an external transaction manager to be configured. Until now it was recommended to use bitronix as jBPM test suite was running on it and it does provide integration with Tomcat (plus it covered db connection pooling and JNDI provider for data source look ups). But this has now changed ...

Starting from jBPM 7.1 KIE Server on Tomcat runs with Narayana, the state of the art transaction manager that nicely integrates with Tomcat and makes the configuration much easier than what was needed with bitronix - and is more native to Tomcat users.

Before I jump into details on how to configure it on Tomcat, I'd like to take the opportunity and give spacial thanks to:

Tom Jenkinson and Gytis Trikleris

for their tremendous help and excellent support while working on this change.

Installation notes - with BPM capabilities

Let's see what is actually needed to configure KIE Server on Tomcat with Narayana:
  • (1) Copy following libraries into TOMCAT_HOME/lib
    • javax.security.jacc:javax.security.jacc-api
    • org.kie:kie-tomcat-integration
    • org.slf4j:artifactId=slf4j-api
    • org.slf4j:artifactId=slf4j-jdk14
  • (2) Configure users and roles in tomcat-users.xml (or different user repository if applicable)
  • (3) Configure JACC Valve for security integration Edit TOMCAT_HOME/conf/server.xml and add following in Host section after last Valve declaration 
         <Valve className="org.kie.integration.tomcat.JACCValve" />
  • (4) Create setenv.sh|bat in TOMCAT_HOME/bin with following content
    CATALINA_OPTS="
    -Djbpm.tsr.jndi.lookup=java:comp/env/TransactionSynchronizationRegistry 
    -Dorg.kie.server.persistence.ds=java:comp/env/jdbc/jbpm 
    -Djbpm.tm.jndi.lookup=java:comp/env/TransactionManager 
    -Dorg.kie.server.persistence.tm=JBossTS 
    -Dhibernate.connection.release_mode=after_transaction 
    -Dorg.kie.server.id=tomcat-kieserver 
    -Dorg.kie.server.location=http://localhost:8080/kie-server/services/rest/server 
    -Dorg.kie.server.controller=http://localhost:8080/kie-wb/rest/controller
    "
       Items marked in green are related to persistence and transaction.
       Items marked in blue are general KIE Server parameters needed when running in managed mode.
  • (5) Copy JDBC driver jar into TOMCAT_HOME/lib depending on the data base of your choice
  • (6) Configure data source for jBPM extension of KIE Server 
           Edit TOMCAT_HOME/conf/context.xml and add following within Context tags of the file:
     <Resource 
           name="sharedDataSource" 
           auth="Container" 
           type="org.h2.jdbcx.JdbcDataSource" 
           user="sa" 
           password="sa"
           url="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MVCC=TRUE" 
           description="H2 Data Source" 
           loginTimeout="0" 
           testOnBorrow="false"
           factory="org.h2.jdbcx.JdbcDataSourceFactory"/>
           This is only an example to use H2 as data base, for other data bases look at
           Tomcat's configurations docs.

           Once important note, please keep the name of the data source as sharedDataSource

  • (7) Last but not least is to configure XA recovery 
  • Create xa recovery file next to the context.xml with data base configuration with following content: 
    <?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> 
    <properties> 
      <entry key="DB_1_DatabaseUser">sa</entry> 
      <entry key="DB_1_DatabasePassword">sa</entry> 
      <entry key="DB_1_DatabaseDynamicClass"></entry> 
      <entry key="DB_1_DatabaseURL">java:comp/env/h2DataSource</entry> 
    </properties> 

    Append to CATALINA_OPTS in setenv.sh|bat file following: 
    -Dcom.arjuna.ats.jta.recovery.XAResourceRecovery1= \
    com.arjuna.ats.internal.jdbc.recovery.BasicXARecovery\;
    abs://$CATALINA_HOME/conf/xa-recovery-properties.xml\ \;1
    BasicXARecovery supports following parameters: 
    • path to the properties file 
    • the number of connections defined in the properties file


Installation notes - without BPM capabilities

In case you want to use KIE Server without BPM capabilities - for instance for Rules or Planning - then you can completely skip steps from 4 (in step 4 use only the marked in blue items) and still run KIE Server on Tomcat.

With that, I'd like to say welcome to Narayana in KIE Server - well done!

2017/02/10

jBPM 7 - case management security

Case management puts additional requirements on business automation. In many cases it's much more domain specific than business process management and thus will then have different (or better would be to say - extended) needs. This is no different when it comes to security.

Cases come with so called case roles. These are generic participants that will be involved in case handling. These roles can be assigned to user tasks or used as contact references. Though they are not defined in cases as concrete users or groups of users. Case roles are on case definition level to make the case definition independent of the actual actors involved in given case instance.

Case instances in turn, are those that are focused on individuals that will actually do the work as part of case handling. To provide this required flexibility case management in jBPM comes with case role assignments that allow to provide actual actors or groups for given role. Case role assignment can be given at the time case instance is started or can be set on already active case instance.

Note: Case role assignment can be modified at any time as long as case instance is active though it will not have effect on tasks already created based on previous role assignment.

General recommendation is to always start with case role assignments when starting a case instance as this will prevent situations of assigning tasks to not the correct owners.

How does it work?


By default case instance security is enabled. It does protect each case instance from being seen by users who do not belong to a case in anyway. In other words, if you are not part of case role assignment (either assigned as user or a group member) then you won't be able to get access to the case instance.  This applies to:

  • access to individual case instance 
  • access to case instance details like
    • case file
    • case stages
    • case milestones
  • queries for case instances
There is one situation when the case instance security will not take any effect - it is where there are no case roles defined at all. That essentially disables the security as there is no information to base authorisation on. 

Authorisation can also be turned off by system property: org.jbpm.cases.auth.enabled when set to false.

Above access is just one part of the security for case instances. In addition, there is case instance operations that can be restricted to case roles. Here is the list of currently supported case instance operations that can be configured:
  • CANCEL_CASE
  • DESTROY_CASE
  • REOPEN_CASE
  • ADD_TASK_TO_CASE
  • ADD_PROCESS_TO_CASE
  • ADD_DATA
  • REMOVE_DATA
  • MODIFY_ROLE_ASSIGNMENT
  • MODIFY_COMMENT
by default three of these operations:
  • CANCEL_CASE
  • DESTROY_CASE
  • REOPEN_CASE
are protected with following roles:
  • owner
  • admin
again, these are case roles so based on case role assignments can differ between case instances. Thus allowing maximum flexibility in how to utilise them.

security for case operations is configurable via simple property file called case-authorization.properties that should be available at root of the class path upon start of the case application. Format of this file is extremely simple:
OPERATION=role1,role2,roleN

Some might say that it's too generic to have single config file for all possible case definitions but that's a way of promoting thinking about case management as domain specific and to build tailored application where single configuration for case role security is certainly enough. Moreover (as everything in jBPM) AuthorizationManager for case security is pluggable so if you need any specific handling you can just put your own piece of code to do so.

And at the end, let's see this working in Order IT hardware application, in particular how can we easily restrict access to only involved people or certain actions.


That's it folks, stay tuned and share your feedback!