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

Process variables are deleted when concurrent execution appears

    • Icon: Bug Report Bug Report
    • Resolution: Duplicate
    • Icon: L3 - Default L3 - Default
    • None
    • 7.15.0-alpha2, 7.16.0, 7.17.0-alpha5
    • engine

      Environment (Required on creation):

      • Spring Boot 2.6.4
      • Java 17
      • Camunda DB - MySQL

      dependencies
          - "org.camunda.bpm.springboot:camunda-bpm-spring-boot-starter:7.16.0"
          - "org.camunda.bpm.springboot:camunda-bpm-spring-boot-starter-webapp:7.16.0"
          - "org.camunda.bpm.springboot:camunda-bpm-spring-boot-starter-rest:7.16.0"
          - "com.sun.xml.bind:jaxb-impl:3.0.2"
          - "org.graalvm.js:js:22.0.0.2"
          - "org.graalvm.js:js-scriptengine:22.0.0.2"
          - "org.camunda.bpm.assert:camunda-bpm-assert:14.0.0"

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

      Our team tried to upgrade from camunda 7.14.0 to 7.16.0 (sql patches also applied). After that our `tests` (unit and integration) `started to fail`, but when manually checking camunda behavior - it is ok. First version after 7.14.0 where tests started to fail is 7.15-alpha2. Tests are passing without problems in the same environment with camunda 7.14.0.

      Steps to reproduce (Required on creation):

      ## Unit Test 
      ### Configuration
      ```java
      package camunda.shared.configuration;import java.io.IOException;
      import java.util.List;
      import javax.sql.DataSource;
      import org.camunda.bpm.engine.ProcessEngineConfiguration;
      import org.camunda.bpm.engine.impl.cfg.CompositeProcessEnginePlugin;
      import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
      import org.camunda.bpm.engine.impl.cfg.ProcessEnginePlugin;
      import org.camunda.bpm.engine.impl.cfg.SpringBeanFactoryProxyMap;
      import org.camunda.bpm.engine.impl.el.ExpressionManager;
      import org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration;
      import org.camunda.bpm.extension.process_test_coverage.spring.SpringProcessWithCoverageEngineConfiguration;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.transaction.PlatformTransactionManager;@Configuration
      public class UnitTestsProcessEngineConfiguration {
        @Bean
        public ProcessEngineConfigurationImpl processEngineConfiguration(
            final List<ProcessEnginePlugin> processEnginePlugins,
            final ExpressionManager expressionManager,
            final PlatformTransactionManager transactionManager,
            final DataSource dataSource,
            final ApplicationContext applicationContext
        ) throws IOException {
          SpringProcessEngineConfiguration config =
              new SpringProcessWithCoverageEngineConfiguration();
          config.setExpressionManager(expressionManager);
          config.setTransactionManager(transactionManager);
          config.setDataSource(dataSource);
          config.setDatabaseSchemaUpdate("true");
          config.setHistory(ProcessEngineConfiguration.HISTORY_FULL);
          config.setJobExecutorActivate(false); // <---
          config.setProcessEnginePlugins(
              processEnginePlugins
          );    config.getProcessEnginePlugins().add(
              new CompositeProcessEnginePlugin(processEnginePlugins)
          );
          config.setBeans(new SpringBeanFactoryProxyMap(applicationContext));
          return config;  }
      }```
      
      Here is sample process and test for it:
      ![[DAV-2_POC_1.bpmn]]
      
      ```kotlin
          @Test
          @DeployProcess(["DAV-2_POC_1.bpmn"])
          fun `POC 1 - variables are deleted`() {
              val builder: ProcessInstantiationBuilder = this.processEngine.runtimeService
                      .createProcessInstanceByKey("DAV-2_POC_1")
              builder.setVariable("featureIssueId", 178825)
              builder.setVariable("implementationCategory", "category-value")
              builder.startBeforeActivity("Implement_feature")
              val processInstance: ProcessInstance = builder.execute();        
      // waiting for task to be resolved        
      BpmnAwareTests.assertThat(processInstance).isWaitingAt("Implement_feature")        
      val processExecution: Execution = this.processEngine.runtimeService
                      .createExecutionQuery()
                      .processInstanceId(processInstance.id)
                      .active()
                      .list()
                      .firstOrNull()!!       
      // process variables are there
              assertEquals(178825, getVariable(processExecution.id, "featureIssueId"))
              assertEquals("category-value", getVariable(processExecution.id, "implementationCategory"))
              assertNull(getVariable(processExecution.id, "implementationIssue"))        
      // triggering script task that will set `issueId`
              this.processEngine
      .runtimeService.createProcessInstanceModification(processInstance.id)
                      .startBeforeActivity("Set_issue_id")
                      .execute()        
      // `implementationIssue` is set by event `Implement_feature_issue_id_set` after `issueId` was set
              assertEquals(777, getVariable(processExecution.id, "implementationIssue"))        
      // !!! process variables are not there after event is executed !!!
              assertEquals(178825, getVariable(processExecution.id, "featureIssueId")) // assert fails
              assertEquals("category-value", getVariable(processExecution.id, "implementationCategory")) // assert fails
          }    fun getVariable(executionId: String, variableName: String): Any? {
              return this.processEngine.runtimeService.getVariable(executionId, variableName)
          }
      ```
      
      Output (last asserts): 
      ```
      Expected :178825
      Actual   :null
      
      ```
      ## Integration Test
      ### Configuration
      ```java
      package camunda.shared.configuration;import java.io.IOException;
      import java.util.List;
      import javax.sql.DataSource;
      import org.camunda.bpm.engine.ProcessEngineConfiguration;
      import org.camunda.bpm.engine.impl.cfg.CompositeProcessEnginePlugin;
      import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
      import org.camunda.bpm.engine.impl.cfg.ProcessEnginePlugin;
      import org.camunda.bpm.engine.impl.cfg.SpringBeanFactoryProxyMap;
      import org.camunda.bpm.engine.impl.el.ExpressionManager;
      import org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration;
      import org.camunda.bpm.extension.process_test_coverage.spring.SpringProcessWithCoverageEngineConfiguration;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.transaction.PlatformTransactionManager;@Configuration
      public class IntegrationTestsProcessEngineConfiguration {
        @Bean
        public ProcessEngineConfigurationImpl processEngineConfiguration(
            final List<ProcessEnginePlugin> processEnginePlugins,
            final ExpressionManager expressionManager,
            final PlatformTransactionManager transactionManager,
            final DataSource dataSource,
            final ApplicationContext applicationContext
        ) throws IOException {
          SpringProcessEngineConfiguration config =
              new SpringProcessWithCoverageEngineConfiguration();
          config.setExpressionManager(expressionManager);
          config.setTransactionManager(transactionManager);
          config.setDataSource(dataSource);
          config.setDatabaseSchemaUpdate("true");
          config.setHistory(ProcessEngineConfiguration.HISTORY_FULL);
          config.setJobExecutorActivate(true); // <---
          config.getProcessEnginePlugins().add(
              new CompositeProcessEnginePlugin(processEnginePlugins)
          );
          config.setBeans(new SpringBeanFactoryProxyMap(applicationContext));
          return config;  }
      }```Test is the same as above.
      Output is the same, variables are removed.
      

      Observed Behavior (Required on creation):

      Output (last asserts): 
      ```
      Expected :178825
      Actual   :null
      ```

      Process variables are erased.

      Expected behavior (Required on creation):

      Process variables must not be erased.

      Root Cause (Required on prioritization):

      camunda-bpm engine

      Solution Ideas (Optional):

      Hints (optional):

      ### The place variables are removed
      ExecutionEntity.java
      ```java
      ...
        protected void moveVariableTo(VariableInstanceEntity variable, ExecutionEntity other) {
          if (other.variableStore.containsKey(variable.getName())) {
            // this is executed when ExecutionEntity.replace(PvmExecutionImpl execution) where commant says: // on compaction, move all variables
            CoreVariableInstance existingInstance = other.variableStore.getVariable(variable.getName());
            existingInstance.setValue(variable.getTypedValue(false));
            invokeVariableLifecycleListenersUpdate(existingInstance, this);
            invokeVariableLifecycleListenersDelete( // <-- here VariableInstanceEntityPersistenceListener.delete()
                variable,
                this,
                Collections.singletonList(getVariablePersistenceListener()));
          }
          else {
            // this is executed when new concurrent execution is created 
            // scenario 2 in PvmExecutionImpl.createConcurrentExecution()
            other.variableStore.addVariable(variable);
          }
        }
      ...
      ```
      
      It seems like it is happening when there are `concurrent execution` takes place.
          1. Manual check:
            Started process via Cockpit:

      After 10 seconds - expected results (how it should be in tests)

          1. Modified verison of process with same (failing in tests) result

       

      It is happening when concurrent executions come into play, like message events, timers, boundary events etc...

        This is the controller panel for Smart Panels app

            [CAM-14499] Process variables are deleted when concurrent execution appears

            Hi d.nikolaev,

            Sorry for the late response. Unfortunately, this ticket slipped through.

            In the meantime, were you able to resolve your problem, or are you still interested in a resolution?

            Best,
            Tassilo

            Tassilo Weidner added a comment - Hi d.nikolaev , Sorry for the late response. Unfortunately, this ticket slipped through. In the meantime, were you able to resolve your problem, or are you still interested in a resolution? Best, Tassilo

            Daniil Nikolaev added a comment - - edited

            Hi @Tassilo Weidner!
            Unfortunately problem remains unresolved...
            Yes, I'm interested in a resolution

            Daniil Nikolaev added a comment - - edited Hi @Tassilo Weidner! Unfortunately problem remains unresolved... Yes, I'm interested in a resolution

            Hi d.nikolaev,

            I'll have a look and get back with my input.

            This might take a while. Stay tuned!

            Best,
            Tassilo

            Tassilo Weidner added a comment - Hi d.nikolaev , I'll have a look and get back with my input. This might take a while. Stay tuned! Best, Tassilo

            Hi d.nikolaev,

            I appreciate your patience.

            This bug report duplicates CAM-14506. We plan to fix it by the end of August, which means it will be available with one of the next alpha releases. Please note that plans are always subject to change, and we cannot give a definite deadline by when this bug is fixed.

            Best,
            Tassilo

            Tassilo Weidner added a comment - Hi d.nikolaev , I appreciate your patience. This bug report duplicates CAM-14506 . We plan to fix it by the end of August, which means it will be available with one of the next alpha releases. Please note that plans are always subject to change, and we cannot give a definite deadline by when this bug is fixed. Best, Tassilo

            Hi d.nikolaev,

            We have fixed CAM-14506. It will be released with Camunda Platform 7.18.0-alpha5 and 7.18.0.

            Best,
            Tassilo

            Tassilo Weidner added a comment - Hi d.nikolaev , We have fixed CAM-14506 . It will be released with Camunda Platform 7.18.0-alpha5 and 7.18.0. Best, Tassilo

              tassilo.weidner Tassilo Weidner
              d.nikolaev Daniil Nikolaev
              Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: