Skip to content
Tuomo Ala-Vannesluoma edited this page Aug 21, 2023 · 16 revisions

nFlow Frequently Asked Questions

Why Spring throws exception "No bean named 'nflowDatabaseInitializer' is defined" when starting?

org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'workflowInstanceDao' defined in URL 
[jar:file:/some/path/nflow-engine-0.2.1-SNAPSHOT.jar!/com/nitorcreations/nflow/engine/internal/dao/WorkflowInstanceDao.class]: 
Unsatisfied dependency expressed through constructor argument with index 1 of type [com.nitorcreations.nflow.engine.internal.dao.ExecutorDao]: : 
No bean named 'nflowDatabaseInitializer' is defined; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No bean named 'nflowDatabaseInitializer' is defined

This may be caused by missing Spring profile that selects database engine. You should use one of these spring profiles nflow.db.mysql, nflow.db.postgresql, nflow.db.oracle or nflow.db.h2. E.g use this system property: -Dspring.profiles.active=nflow.db.mysql.

Spring throws "Parameter 0 of method jacksonCodecCustomizer in org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration$JacksonCodecConfiguration required a single bean, but 2 were found"

Parameter 0 of method jacksonCodecCustomizer in org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration$JacksonCodecConfiguration required a single bean, but 2 were found:
	- nflowObjectMapper: defined by method 'nflowObjectMapper' in class path resource [io/nflow/engine/config/EngineConfiguration.class]
	- nflowRestObjectMapper: defined by method 'nflowRestObjectMapper' in class path resource [io/nflow/rest/config/RestConfiguration.class]

To make it possible to customize ObjectMapper you might need to define your own bean for example:

@Bean
@Primary
@NFlow
public ObjectMapper nflowObjectMapper() {
  ObjectMapper mapper = new ObjectMapper();
  mapper.setSerializationInclusion(NON_EMPTY);
  mapper.registerModule(new JodaModule());
  return mapper;
}

How to include nflow-engine in my application without starting workflow processing?

Set nflow.autostart=false, e.g use system property -Dnflow.autostart=false when starting your application. With this property nFlow instance won't start a dispatcher thread and thus the instance will not process any workflows.

Why WorkflowState symbol is not found?

error: cannot find symbol
    public enum State implements WorkflowState {
                                 ^
  symbol:   class WorkflowState
  location: class MyWorkflow

Use fully qualified class name for io.nflow.engine.workflow.definition.WorkflowState. This seems to be a JDK bug.

How to fix exception java.lang.NoClassDefFoundError: javax/activation/DataSource with JDK 10?

Include javax.activation library. It seems that they are no longer part of the JDK 10.

<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>

When the parent workflow goes to end state, what happens to child workflows?

Nothing special happens to child workflows, they continue execute normally.

What is the difference between businessId and externalId?

businessId can be used in for grouping workflow instances that are related to the same business logic entity. It has no effect to nFlow processing and the same value can be used in any number of workflow instances.

externalId must be unique within workflow instances of the same workflow type. It can be defined to avoid creating more than 1 instance of workflow instances of given type. If externalId is undefined when creating the workflow instance, nFlow will generate a random value (UUID.randomUUID().toString()) for it.

Is the code in end states executed?

Yes.

How to log workflow type/id/state variables?

You can use MDC via WorkflowLogContextListener.

Inject this to Spring context at startup:

@Bean
public WorkflowExecutorListener[] listeners() {
    return new WorkflowExecutorListener[] {new WorkflowLogContextListener("workflow")};
}

Add %X{CONTEXT_NAME} to logging pattern:

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%thread] %-5level %logger %X{workflow} - %msg%n</pattern>
        </encoder>
    </appender>

Can the amount of workflow actions and state variables archived per batch be controlled?

Background: MariaDB Galera Cluster has a limit for rows per writeset. This limit may be exceeded during the archive process when the archived workflows have a lot of actions or state variables. When the limit is exceeded, archiving fails.

Answer: Not currently. You can try to mitigate the problem using one or more of these methods:

  • Tune wsrep_max_ws_rows setting
  • Use MaintenanceConfiguration.ConfigurationItem.batchSize to control the number of workflow instances archived per batch
  • Configure you workflow history clean-up (WorkflowSettings.historyDeleteableAfter) to delete old actions and state variables more aggressively
  • Implement a custom workflow that deletes old actions and state variables before archiving as you wish
  • Disable the archiving provided by MaintenanceWorkflow altogether (you may still use the deleting part)
  • Implement a custom archiving process

How to move a workflow instance from a manual state to some other state e.g. after the manual processing has been done?

Changing the state of a specific workflow instance outside the workflow itself can be done by updating the workflow instance using Java or REST API.

Using Java API WorkflowInstanceService.updateWorkflowInstance:

WorkflowInstance instance = workflowInstanceFactory.newWorkflowInstanceBuilder().setId(workflowInstanceId).setNextActivation(now).setState(nextState).setStateText(description).build();
WorkflowInstanceAction action = new WorkflowInstanceAction.Builder(instance).setType(WorkflowActionType.externalChange).setStateText(description).setExecutionEnd(now).build();
boolean updated = workflowInstanceService.updateWorkflowInstance(instance, action);

Using REST API PUT /v1/workflow-instance/id/{workflowInstanceId}: See Swagger UI or example code in nflow-tests for details.

Clone this wiki locally