Uploaded image for project: 'camunda BPM'
  1. camunda BPM
  2. CAM-14153

Cannot change task's formKey via BPMN parse listener

XMLWordPrintable

      Environment (Required on creation):

      • Camunda Platform 7.16.0
      • all distros

      Description (Required on creation; please attach any relevant screenshots, stacktraces, log files, etc. to the ticket):

      Adjusting the formKey of a user task via TaskDefinition#setFormKey from a BpmnParseListener is not considered when retrieving the formKey to display the form in the web apps.

      The app parseListener7-16.zip contains a parse listener that changes the form keys on deployment.

      In the console of the IDE you find log output like

      2021-11-05 12:14:39.760  INFO 19120 --- [nio-8082-exec-5] c.c.consulting.parser.FormKeyAdaptor     : FormKey: embedded:deployment:/members-of-board.html
      2021-11-05 12:14:39.761  INFO 19120 --- [nio-8082-exec-5] c.c.consulting.parser.FormKeyAdaptor     : FormKey changed to: embedded:app:members-of-board.html
      2021-11-05 12:14:39.761  INFO 19120 --- [nio-8082-exec-5] c.c.consulting.parser.FormKeyAdaptor     : FormKey: embedded:app:members-of-board.html
      2021-11-05 12:14:39.761  INFO 19120 --- [nio-8082-exec-5] c.c.consulting.parser.FormKeyAdaptor     : FormKey changed to: embedded:app:members-of-board.html
      2021-11-05 12:14:39.763  INFO 19120 --- [nio-8082-exec-5] c.c.consulting.parser.FormKeyAdaptor     : FormKey: embedded:deployment:/sanction-search-result.html
      2021-11-05 12:14:39.763  INFO 19120 --- [nio-8082-exec-5] c.c.consulting.parser.FormKeyAdaptor     : FormKey changed to: embedded:app:sanction-search-result.html
      2021-11-05 12:14:39.763  INFO 19120 --- [nio-8082-exec-5] c.c.consulting.parser.FormKeyAdaptor     : FormKey: embedded:app:sanction-search-result.html 

      The parse listener seems to work correctly, but it shows no effect in the Tasklist.

      If you switch back to 7.15.0, the parse listener works as expected.

      Steps to reproduce (Required on creation):

      1. Unzip the attached spring boot application parseListener7-16.zip
      2. Start the application in your IDE
      3. Login to http://localhost:8082/
      4. Open Tasklist
      5. Start a process instance
      6. Enter values "a" and "b" on the generated start form and start the process instance.
      7. See a "Form failure: The form with the resource name '/members-of-board.html' cannot be found in deployment with id 64c8962c-3c20-11ec-ac20-3ce1a1c19785"

      Observed Behavior (Required on creation):

      Changing the UserTask's formKey property in a BpmnParseListener no longer works.

      Expected behavior (Required on creation):

      Changing the UserTask's formKey property in a BpmnParseListener via the TaskDefinition class is picked up by the web apps when displaying the form.

      Root Cause (Required on prioritization):

      With this commit, CP now saves parts of the model information in two spots:

      1. TaskDefinition - we have always had the information there, for example, the "formKey"
      2. DefaultFormHandler - the class is not new, saving the form information from the model there however is new. It is used when fetching the necessary form data to display a form now instead of the TaskDefinition.

      Because of this, adjusting the TaskDefinition has no effect.

      Solution Ideas (Optional):

      Hints (optional):

      Currently, you would have to do something like this in the parse listener:

      package com.camunda.consulting.parser;
      
      import java.lang.reflect.Field;
      
      import org.camunda.bpm.engine.delegate.Expression;
      import org.camunda.bpm.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
      import org.camunda.bpm.engine.impl.bpmn.parser.AbstractBpmnParseListener;
      import org.camunda.bpm.engine.impl.el.ExpressionManager;
      import org.camunda.bpm.engine.impl.form.handler.DefaultFormHandler;
      import org.camunda.bpm.engine.impl.form.handler.DefaultTaskFormHandler;
      import org.camunda.bpm.engine.impl.form.handler.DelegateTaskFormHandler;
      import org.camunda.bpm.engine.impl.pvm.process.ActivityImpl;
      import org.camunda.bpm.engine.impl.pvm.process.ScopeImpl;
      import org.camunda.bpm.engine.impl.util.xml.Element;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      
      public class FormKeyAdaptor extends AbstractBpmnParseListener {
        
        private static final Logger LOG = LoggerFactory.getLogger(FormKeyAdaptor.class);
      
        @Override
        public void parseUserTask(Element userTaskElement, ScopeImpl scope, ActivityImpl activity) {
          LOG.debug("Parsing user task {}", activity.getId());
          UserTaskActivityBehavior activityBehavior = (UserTaskActivityBehavior) activity.getActivityBehavior();
          DefaultTaskFormHandler formHandler = (DefaultTaskFormHandler) ((DelegateTaskFormHandler) activityBehavior.getTaskDefinition().getTaskFormHandler()).getFormHandler();
          Expression formKeyExpression = formHandler.getFormKey();
          if (formKeyExpression != null) {
            String formKeyExpressionText = formKeyExpression.getExpressionText();
            LOG.info("FormKey: {}", formKeyExpressionText);  
            String formKeyEmbeddedDeployment = formKeyExpressionText.replace("embedded:deployment:/", "embedded:app:");
            ExpressionManager expressionManager = new ExpressionManager();
            try {
              Field formKeyField = DefaultFormHandler.class.getDeclaredField("formKey");
              formKeyField.setAccessible(true);
              formKeyField.set(formHandler, expressionManager.createExpression(formKeyEmbeddedDeployment));
              LOG.info("FormKey changed to: {}", activityBehavior.getTaskDefinition().getFormKey().getExpressionText());
            } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
              LOG.warn("Couldn't adjust the formKey in the form handler", e);
            }
          } else {
            LOG.info("Formkey ist null for user task {}", activity.getName());
          }
        } 
      }
      

      Disclaimer:

      • This is an internal API so we never guarantee we keep it compatible.
      • The workaround code is very tightly coupled to default classes now, it won't work out of the box with custom form handler classes and such that you can configure in the model.

        This is the controller panel for Smart Panels app

              thorben.lindhauer Thorben Lindhauer
              daniel.ewing Daniel Ewing
              Thorben Lindhauer Thorben Lindhauer
              Tassilo Weidner Tassilo Weidner
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated:
                Resolved: