9 Replies Latest reply on Mar 31, 2008 8:42 AM by dleerob

    Just a Question Regarding Change in Process Definition

    zahidmaqbool

      Hello Everyone,

      I am using JBPM with Seam. I just wanted to know how easy is it to modify process definition once it is deployed. Just for example I want to delete tasks node or add a couple more of them. In Seam with JBPM, what is the best way of doing so. I also do not want to loose my existing data in the Database, so is there any way that by just changing the process definition file and restarting, the changes will take automatically.

      If anyone can help it will be really great.. I would appreciate any help.

      Thanks in Advance...

        • 1. Re: Just a Question Regarding Change in Process Definition
          kukeltje

          how easy it is is completely dependend on what you want to change and what states the processinstances are in. E.g. deleting a tasknode where there are processintances that have tokens in those nodes requires repositioning those tokens. There are many issues similar issues that have to be taken into account. You have to figure out which will apply to you.

          But once these are done, changes will be reflected in the running intances.

          • 2. Re: Just a Question Regarding Change in Process Definition
            dleerob

            Lets say we do take into account all the issues when updating a Process Definition. How do we actually update the Process Definition? Normally when deploying, it creates a completely new version, and doesn't update an existing one. Any ideas?

            • 3. Re: Just a Question Regarding Change in Process Definition

               

              "dleerob" wrote:
              Lets say we do take into account all the issues when updating a Process Definition. How do we actually update the Process Definition? Normally when deploying, it creates a completely new version, and doesn't update an existing one. Any ideas?

              You would have to 'edit' the process definition xml and re-deploy.

              There is no reason why that can't be done programmatically.

              Consider:
              ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource("processdefinition.xml");
              // Change the process definition in memory?
              // e.g. processDefinition.addNode() etc.
              jbpmContext.deployProcessDefinition(processDefinition);



              • 4. Re: Just a Question Regarding Change in Process Definition
                dleerob

                But this would create a new version of the Process Definition, would it not?
                So it doesn't actually replace the process definition files in the database, it simply creates new ones, with a new version?

                I would like to be able to update existing process definition files in the db. Not create a new version.

                • 5. Re: Just a Question Regarding Change in Process Definition

                   

                  "dleerob" wrote:
                  I would like to be able to update existing process definition files in the db. Not create a new version.

                  In that case, you'll have to follow the advice given by kukeltje and tread carefully...

                  • 6. Re: Just a Question Regarding Change in Process Definition
                    dleerob

                    I will tread carefully, thanks! But any ideas how I would actually go about updating the files in the db?

                    • 7. Re: Just a Question Regarding Change in Process Definition
                      kukeltje

                      All tokens, nodes etc are hibernate objects, so just like you normally would with hibernate....

                      • 8. Re: Just a Question Regarding Change in Process Definition
                        dleerob

                        - When clicking deploy on the Eclipse GPD, it sends the Process Definition through to ProcessUploadServlet.
                        - ProcessUploadServlet then parses the ProcessDefinition, and calls jbpmContext.deployProcessDefinition(processDefinition);
                        - Following that call, it ends up at GraphSession.deployProcessDefinition(processDefinition);
                        - This is where the version is incrimented by one, and the ProcessDefinition is saved as a new version.

                        So if I simply update one JSP page (a spelling error perhaps) in a process definition, and I instead keep the process definition version the same as the latest/current one, and save it myself instead of calling the GraphSession.deployProcessDefinition, would this simply update that latest/existing process definition and related files correctly? Do you see any problems doing it this way?

                        • 9. Re: Just a Question Regarding Change in Process Definition
                          dleerob

                          Here's what I finally did to update files stored in the database for a Process Definition, such as JSP pages, xml files, class files (handlers) etc:

                          - I copied ProcessUploadServlet.java from jbpm source, and created my own version in my webapp source code.

                          - In web.xml I used my ProcessUploadServlet.java, instead of the one in the jpbm package.

                          - I copied the method 'GraphSession.deployProcessDefinition(processDefinition)' into my ProcessUploadServlet.java

                          - I copied the method 'GraphSession.findLatestProcessDefinition' into my ProcessUploadServlet.java

                          - In the handleRequest method in my ProcessUploadServlet.java, where the deployProcessDefinition method is called, I replaced it to call my own deployProcessDefinition method, as shown below:

                          String updateProcessDefinitionFilesStr = (String)request.getParameter(Constants.UPDATE_PROCESS_DEFINITION_FILES);
                           boolean updateProcessDefinition = false;
                           if (updateProcessDefinitionFilesStr != null && updateProcessDefinitionFilesStr.equalsIgnoreCase("Yes")) {
                           updateProcessDefinition = true;
                           }


                          - I then modified my copy of the deployProcessDefinition to look as follows:
                          /**
                           * The code for the original method can be found at: jbpm-jpdl-3.2.2\src\jpdl\org\jbpm\db\GraphSession.java
                           * We are using our customized method instead, so we can update Process Definition files if we want,
                           * instead of creating a new version.
                           * Note: if the version of JBPM is updated, we need to re-look at this method to make sure
                           * it will still work according to the new version.
                           * @param processDefinition
                           * @param jbpmContext
                           * @param updateProcessDefinition
                           */
                           private void deployProcessDefinition(ProcessDefinition processDefinition, JbpmContext jbpmContext, boolean updateProcessDefinition) {
                           Session session = jbpmContext.getSession();
                           String processDefinitionName = processDefinition.getName();
                           // if the process definition has a name (process versioning only applies to named process definitions)
                           if (processDefinitionName!=null) {
                           // find the current latest process definition
                           ProcessDefinition previousLatestVersion = findLatestProcessDefinition(processDefinitionName, jbpmContext);
                           // if there is a current latest process definition
                           if (previousLatestVersion!=null) {
                           if (updateProcessDefinition) {
                           log.info("Updating Process Definition '"+previousLatestVersion.getName()+"' version '"+previousLatestVersion.getVersion()+"'");
                           Map fileBytes = processDefinition.getFileDefinition().getBytesMap();
                           FileDefinition previousFileDefinition = previousLatestVersion.getFileDefinition();
                           session.createSQLQuery("delete from jbpm_byteblock where PROCESSFILE_ IN (select ID_ from jbpm_bytearray where FILEDEFINITION_ = "+previousFileDefinition.getId()+")").executeUpdate();
                           session.createSQLQuery("delete from jbpm_bytearray where FILEDEFINITION_ = "+previousFileDefinition.getId()).executeUpdate();
                           for (Iterator it = fileBytes.keySet().iterator();it.hasNext();) {
                           String fileName = (String)it.next();
                           previousFileDefinition.addFile(fileName, (byte[])fileBytes.get(fileName));
                           }
                           //don't change version, but instead update existing process definition
                           session.save(previousFileDefinition);
                           log.info("Process Definition Updated.");
                           return;
                           }
                           else {
                           //new version
                           log.info("Creating new version '"+(previousLatestVersion.getVersion()+1)+"' for Process Definition '"+processDefinition.getName()+"'");
                           processDefinition.setVersion(previousLatestVersion.getVersion()+1);
                           }
                           }
                           else {
                           // start from 1
                           processDefinition.setVersion(1);
                           }
                          
                           session.save(processDefinition);
                          
                           }
                           else {
                           throw new JbpmException("process definition does not have a name");
                           }
                           }


                          - In eclipse, when deploying my Process Definition, under the 'Server Deployer' field, I add on the parameter 'updateProcessDefinitionFiles=Yes'. Eg: /workflow/upload?updateProcessDefinitionFiles=Yes

                          This seems to work for me, if all I want to do is update the ProcessDefinition's FileDefinition object with new files. (ie. updating the files in the database).

                          Any feedback is welcome, I would like to know if there's a better way to do it, or if you see any possible problems/pitfalls with this way of doing it.