Руководство по Activiti с Java

Руководство по Activiti с Java

1. обзор

Activiti API - это система управления рабочими процессами и бизнес-процессами. Мы можем определить процесс в нем, выполнить его и манипулировать им различными способами, используя службы, предоставляемые API. Требуется JDK 7+.

Разработка с использованием API может выполняться в любой среде IDE, но для использованияActiviti Designer нам понадобится Eclipse.

Мы можем определить процесс в нем, используя стандарт BPMN 2.0. Есть другой, менее популярный способ - использование классов Java, таких какStartEvent,EndEvent,UserTask,SequenceFlow и т. Д.

Если мы хотим запустить процесс или получить доступ к какой-либо из служб, нам нужно создатьProcessEngineConfiguration.

Мы можем получитьProcessEngine с помощьюProcessEngineConfiguration, некоторыми способами, которые мы обсудим далее в этой статье.. Через_ the _ProcessEngine мы можем выполнять операции рабочего процесса и BPMN.

2. Maven Зависимости

Чтобы использовать этот API, нам нужно включить зависимость Activiti:


    org.activiti
    activiti-engine

3. СозданиеProcessEngine

ProcessEngine в Activiti обычно настраивается с использованием XML-файлаactiviti.cfg.xml. Пример этого файла конфигурации:


    
        
        
        
        
        
    

Теперь мы можем получитьProcessEngine, используя классProcessEngines:

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

Этот оператор будет искать файлactiviti.cfg.xml в пути к классам и создаватьProcessEngine на основе конфигурации в файле.

Пример кода для файла конфигурации показывает, что это просто конфигурация на основе Spring. Но это не означает, что мы можем использовать Activiti только в среде Spring. Возможности Spring используются только для внутреннего использования для созданияProcessEngine.

Давайте напишем тестовый пример JUnit, который создастProcessEngine, используя файл конфигурации, показанный выше:

@Test
public void givenXMLConfig_whenGetDefault_thenGotProcessEngine() {
    ProcessEngine processEngine
      = ProcessEngines.getDefaultProcessEngine();
    assertNotNull(processEngine);
    assertEquals("root", processEngine.getProcessEngineConfiguration()
      .getJdbcUsername());
}

4. API и услуги Activiti Process Engine

Точкой входа для взаимодействия с API являетсяProcessEngine. ЧерезProcessEngine, мы можем получить доступ к различным сервисам, которые предоставляют методы рабочего процесса / BPMN. ProcessEngine и все служебные объекты являются потокобезопасными.

image

КлассProcessEngines будет сканировать файлыactiviti.cfg.xml иactiviti-context.xml. Как упоминалось ранее, для всех файловactiviti.cfg.xmlProcessEngine будет создан обычным способом.

Принимая во внимание, что для всех файловactiviti-context.xml он будет создан способом Spring - я создам контекст приложения Spring и получу от негоProcessEngine. Во время выполнения процесса все шаги будут посещаться в порядке, определенном в файле BPMN.

Во время выполнения процесса все шаги будут посещаться в порядке, определенном в файле BPMN.

A ProcessDefinition represents a business process. Используется для определения структуры и поведения различных этапов процесса. Развертывание определения процесса означает загрузку определения процесса в базу данных Activiti.

Определения процессов в основном определяются стандартом BPMN 2.0. Их также можно определить с помощью кода Java. Все термины, определенные в этом разделе, также доступны в виде классов Java.

Как только мы запустим определение процесса, его можно назвать процессом

AProcessInstance - это одно выполнениеProcessDefinition.

A StartEvent is associated with every business process. It indicates the entry point of the process. Точно так же естьEndEvent, который указывает на конец процесса. Мы можем определить условия для этих событий.

Все шаги (или элементы) между началом и концом обозначаются какTasks. Tasks может быть разных типов. Чаще всего используются задачиUserTasks иServiceTasks.

UserTasks, как следует из названия, таковы, что они должны выполняться пользователем вручную.

С другой стороны,ServiceTasks настраиваются с помощью фрагмента кода. Всякий раз, когда выполнение достигает их, их блок кода будет выполнен.

SequenceFlows подключаетTasks. Мы можем определитьSequenceFlows по исходному и целевому элементам, которые они будут соединять. Опять же, мы также можем определить условия дляSequenceFlows для создания условных путей в процессе.

4.2. Сервисы

Кратко обсудим услуги, предоставляемые Activiti:

  • RepositoryService помогает нам управлять развертыванием определений процессов. Этот сервис работает со статическими данными, связанными с определением процесса

  • RuntimeService управляетProcessInstances (запущенными в данный момент процессами), а также переменными процесса.

  • TaskService отслеживаетUserTasks. Tasks, которые должны выполняться пользователем вручную, лежат в основе Activiti API. Мы можем создать задачу, подать заявку и выполнить задачу, манипулировать получателем задачи и т. Д. используя этот сервис

  • FormService - дополнительная услуга. API можно использовать без него и без ущерба для каких-либо его функций. Он используется для определения начальной формы и формы задачи в процессе.

  • IdentityService управляетUsers иGroups

  • HistoryService отслеживает историю Activiti Engine. Мы также можем установить разные уровни истории.

  • ManagementService относится к метаданным и обычно не требуется при создании приложения.

  • DynamicBpmnService помогает нам изменить что-либо в процессе, не развертывая его заново.

5. Работа с Activiti Services

Чтобы узнать, как мы можем работать с различными службами и запускать процесс, рассмотрим пример процесса для запроса на отпуск сотрудника:

image

В файле BPMN 2.0,VacationRequest.bpmn20.xml, для этого процесса будет начальное событие, определенное как:


    
        
        
        
     

Аналогично, первая пользовательская задача, назначенная группе пользователей «Управление», будет выглядеть так:


    ${employeeName} would like to take ${numberOfDays} day(s)
      of vacation (Motivation: ${reason}).
    
        
        
    
    
      
        management
      
    

С помощьюServiceTask, нам нужно определить фрагмент кода, который нужно выполнить. У нас есть этот кусок кода как класс Java:


Условный поток будет показан путем добавления тега“conditionExpression” в“sequenceFlow”:


    
      
    

ЗдесьvacationApproved - этоformProperty изUserTask, показанного выше.

Как мы видим на диаграмме, это очень простой процесс. Сотрудник делает запрос на отпуск, указывая количество дней и дату начала отпуска. Запрос отправляется менеджеру. Они могут одобрить / отклонить запрос.

В случае одобрения определена задача обслуживания для отправки электронного письма с подтверждением. В случае отклонения сотрудник может либо изменить запрос и повторно отправить запрос, либо ничего не делать.

Служебным задачам предоставляется некоторый фрагмент кода для выполнения (здесь, как класс Java). Мы дали классSendEmailServiceTask.java.

Эти типы классов должны расширятьJavaDelegate.. Также нам необходимо переопределить его методexecute(), который будет выполняться, когда выполнение процесса достигнет этого шага.

5.1. Развертывание процесса

Чтобы сделать наш процесс известным для Activiti Engine, нам нужно развернуть этот процесс. Мы можем сделать это программно, используяRepositoryService.. Давайте напишем тест JUnit, чтобы показать это:

@Test
public void givenBPMN_whenDeployProcess_thenDeployed() {
    ProcessEngine processEngine
      = ProcessEngines.getDefaultProcessEngine();
    RepositoryService repositoryService
      = processEngine.getRepositoryService();
    repositoryService.createDeployment()
      .addClasspathResource(
      "org/activiti/test/vacationRequest.bpmn20.xml")
      .deploy();
    Long count=repositoryService.createProcessDefinitionQuery().count();
    assertEquals("1", count.toString());
}

Развертывание означает, что ядро ​​будет анализировать файл BPMN и преобразовывать его во что-то исполняемое. Кроме того, запись будет добавлена ​​в таблицу Repository для каждого развертывания.

Следовательно, после этого мы можем запросить службуRepository, чтобы получить развернутые процессы; ProcessDefinitions.

5.2. ЗапускProcessInstance

После развертыванияProcessDefinition в Activiti Engine мы можем выполнить процесс, создавProcessInstances. ProcessDefinition - это план, аProcessInstance - его выполнение во время выполнения.

Для одногоProcessDefinition может быть несколькоProcessInstances.

Все подробности, относящиеся кProcessInstances, можно получить черезRuntimeService.

В нашем примере при запуске события нам нужно указать количество дней отпуска, дату начала и причину. Мы будем использовать переменные процесса и передавать их при созданииProcessInstance.

Давайте напишем тестовый пример JUnit, чтобы лучше понять:

@Test
public void givenDeployedProcess_whenStartProcessInstance_thenRunning() {
    //deploy the process definition
    Map variables = new HashMap>();
    variables.put("employeeName", "John");
    variables.put("numberOfDays", 4);
    variables.put("vacationMotivation", "I need a break!");

    RuntimeService runtimeService = processEngine.getRuntimeService();
    ProcessInstance processInstance = runtimeService
      .startProcessInstanceByKey("vacationRequest", variables);
    Long count=runtimeService.createProcessInstanceQuery().count();

    assertEquals("1", count.toString());
}

Несколько экземпляров одного определения процесса будут различаться в зависимости от переменных процесса.

Есть несколько способов запустить экземпляр процесса. Здесь мы используем ключ процесса. После запуска экземпляра процесса мы можем получить информацию о нем, запросивRuntimeService.

5.3. Завершение задач

Когда наш экземпляр процесса запускается, первым шагом является пользовательская задача, назначенная группе пользователей“management”.

Пользователь может иметь папку «Входящие», в которой будет список задач, которые он должен выполнить. Теперь, если мы хотим продолжить выполнение процесса, пользователь должен завершить эту задачу. Для Activiti Engine это называется «завершение задачи».

Мы можем запроситьTaskService,, чтобы получить объект задачи, а затем завершить его.

Код, который нам нужно написать для этого, выглядит следующим образом:

@Test
public void givenProcessInstance_whenCompleteTask_thenGotNextTask() {
    // deploy process and start process instance
    TaskService taskService = processEngine.getTaskService();
    List tasks = taskService.createTaskQuery()
      .taskCandidateGroup("management").list();
    Task task = tasks.get(0);

    Map taskVariables = new HashMap<>();
    taskVariables.put("vacationApproved", "false");
    taskVariables.put("comments", "We have a tight deadline!");
    taskService.complete(task.getId(), taskVariables);

    Task currentTask = taskService.createTaskQuery()
      .taskName("Modify vacation request").singleResult();
    assertNotNull(currentTask);
}

Обратите внимание, что методcomplete() дляTaskService также принимает необходимые переменные процесса. Проходим ответ от менеджера.

После этого процесс обработки переходит к следующему шагу. Здесь следующий шаг спрашивает сотрудника, нужно ли повторно отправить запрос на отпуск или нет.

Итак, нашProcessInstance теперь ожидает этогоUserTask, с именем“Modify vacation request ».

5.4. Приостановка и активация процесса

Мы можем приостановить aProcessDefinition, а также aProcessInstance. Если мы приостановимProcessDefinition,, мы не сможем создать его экземпляр, пока он приостановлен. Мы можем сделать это с помощьюRepositoryService:

@Test(expected = ActivitiException.class)
public void givenDeployedProcess_whenSuspend_thenNoProcessInstance() {
    // deploy the process definition
    repositoryService.suspendProcessDefinitionByKey("vacationRequest");
    runtimeService.startProcessInstanceByKey("vacationRequest");
}

Чтобы активировать его снова, нам просто нужно вызвать один из методовrepositoryService.activateProcessDefinitionXXX.

Точно так же мы можем приостановитьProcessInstance,, используяRuntimeService.

6. Заключение

В этой статье мы увидели, как мы можем использовать Activiti с Java. Мы создали образец файлаProcessEngineCofiguration, который помогает нам создатьProcessEngine.

Используя его, мы получили доступ к различным услугам, предоставляемым API. Эти службы помогают нам управлять и отслеживатьProcessDefinitions,ProcessInstances,UserTasks и т. Д.

Как всегда, код примеров, которые мы видели в статье, лежитover on GitHub.