Мультиарендность
|
Этот раздел перенесён из документации Camunda 7 и в дальнейшем будет доработан с учётом особенностей OpenBPM Engine |
Мультиарендность рассматривает случай, когда одна установка Camunda должна обслуживать более одного арендатора (tenant). Для каждого арендатора должны обеспечиваться определенные гарантии изоляции. Например, экземпляры процессов одного арендатора не должны влиять на экземпляры другого.
Мультиарендность можно реализовать двумя разными способами. Первый способ - использовать один process engine на арендатора link:{{< relref "#one-process-engine-per-tenant" >}}[]. Второй способ - использовать один process engine и связывать данные с идентификаторами арендаторов link:{{< relref "#single-process-engine-with-tenant-identifiers" >}}[]. Эти два способа различаются уровнем изоляции данных, затратами на сопровождение и масштабируемостью. Также возможна комбинация обоих подходов.
Один Process Engine с идентификаторами арендаторов
Мультиарендность можно реализовать с одним process engine, который использует идентификаторы арендаторов (tenant-id). Данные всех арендаторов хранятся в одной таблице (одна и та же база и схема). Изоляция обеспечивается за счет идентификатора арендатора, хранящегося в столбце.

Идентификатор арендатора задается при деплое и распространяется на все данные, создаваемые из этого деплоя (например, определения процессов, экземпляры процессов, задачи и т. д.). Для доступа к данным конкретного арендатора process engine позволяет фильтровать запросы по идентификатору арендатора или указывать идентификатор арендатора для команды (например, создание экземпляра процесса). Дополнительно движок предоставляет прозрачные ограничения доступа в комбинации с Identity Service, что позволяет не указывать идентификатор арендатора явно.
Обратите внимание: прозрачное разделение по арендаторам реализовано не для всех API. Например, с помощью deployment API арендатор может задеплоить процесс для другого арендатора. Поэтому прямое предоставление таких API-эндпоинтов арендаторам не является поддерживаемым вариантом использования. Вместо этого поверх Camunda API следует реализовать собственную логику проверки доступа.
Также возможно, чтобы все арендаторы использовали общие process и decision definitions без деплоя для каждого арендатора. Общие определения могут упростить управление деплоями при большом количестве арендаторов.
EXAMPLES: Примеры на GitHub https://github.com/camunda/camunda-bpm-examples показывают, как использовать tenant-identifiers с
Деплой определений для арендатора
Чтобы задеплоить определения для одного арендатора, нужно задать идентификатор арендатора на деплое. Указанный идентификатор распространяется на все определения деплоя, чтобы они принадлежали этому арендатору.
Если идентификатор арендатора не задан, то деплой и его определения принадлежат всем арендаторам. В таком случае все арендаторы могут получать доступ к деплою и определениям. Подробнее о работе с общими определениями см. в разделе link:{{< relref "#shared-definitions-for-all-tenants" >}}[].
Указание идентификатора арендатора через Java API
Когда деплой создается через Repository Service, идентификатор арендатора можно установить в {{< javadocref page="org/camunda/bpm/engine/repository/DeploymentBuilder.html" text="DeploymentBuilder" >}}.
repositoryService
.createDeployment()
.tenantId("tenant1")
.addZipInputStream(inputStream)
.deploy()
Указание идентификатора арендатора через Deployment Descriptor
В случае process application деплой задается в descriptor деплоя processes.xml. Поскольку descriptor может содержать несколько process-archive (то есть деплоев), идентификатор арендатора можно задавать для каждого process-archive через атрибут tenantId.
<process-application
xmlns="http://www.camunda.org/schema/1.0/ProcessApplication"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<process-archive tenantId="tenant1">
<process-engine>default</process-engine>
<properties>
<property name="isDeleteUponUndeploy">false</property>
<property name="isScanForProcessDefinitions">true</property>
</properties>
</process-archive>
</process-application>
Указание идентификатора арендатора через конфигурацию Spring
Когда используется Automatic Resource Deployment в интеграции Spring Framework, идентификатор арендатора можно указать в конфигурации Process Engine через свойство deploymentTenantId.
<bean id="processEngineConfiguration" class="io.openbpm.bpm.engine.spring.SpringProcessEngineConfiguration">
<property name="deploymentResources">
<array>
<value>classpath*:/org/camunda/bpm/engine/spring/test/autodeployment/autodeploy.*.cmmn</value>
<value>classpath*:/org/camunda/bpm/engine/spring/test/autodeployment/autodeploy.*.bpmn20.xml</value>
</array>
</property>
<property name="deploymentTenantId" value="tenant1" />
</bean>
Версионирование tenant-специфичных определений
Когда определение деплоится для арендатора, ему назначается версия, независимая от определений других арендаторов. Например, если новое определение процесса задеплоено для двух арендаторов, оба определения получат версию 1. Версионирование внутри одного арендатора работает так же, как версионирование определений, не принадлежащих ни одному арендатору.
Запрос данных арендатора
Запросы process engine к tenant-специфичным данным (например, Deployment Query, Process Definition Query) позволяют фильтровать по одному или нескольким идентификаторам арендаторов. Если идентификатор не задан, результат содержит данные всех арендаторов.
Обратите внимание: прозрачные ограничения доступа арендаторов link:{{< relref "#transparent-access-restrictions-for-tenants" >}}[] могут влиять на результат запроса, если пользователю не разрешено видеть данные арендатора.
Запрос деплоев арендатора
Чтобы найти деплои конкретных арендаторов, идентификаторы арендаторов нужно передать в tenantIdIn у DeploymentQuery.
List<Deployment> deployments = repositoryService
.createDeploymentQuery()
.tenantIdIn("tenant1", "tenant2")
.orderByTenantId()
.asc()
.list();
В случае общих определений link:{{< relref "#shared-definitions-for-all-tenants" >}}[] полезно фильтровать деплои, не принадлежащие ни одному арендатору, вызовом withoutTenantId().
List<Deployment> deployments = repositoryService
.createDeploymentQuery()
.withoutTenantId()
.list();
Также можно фильтровать деплои, принадлежащие конкретному арендатору или не принадлежащие никому, вызовом includeDeploymentsWithoutTenantId().
List<Deployment> deployments = repositoryService
.createDeploymentQuery()
.tenantIdIn("tenant1")
.includeDeploymentsWithoutTenantId()
.list();
Запрос определений арендатора
Аналогично DeploymentQuery, запросы определений позволяют фильтровать по одному или нескольким арендаторам и по определениям, не принадлежащим ни одному арендатору.
List<ProcessDefinition> processDefinitions = repositoryService
.createProcessDefinitionQuery()
.tenantIdIn("tenant1")
.includeProcessDefinitionsWithoutTenantId();
.list();
Выполнение команд для арендатора
Когда определение задеплоено для нескольких арендаторов, команда может быть неоднозначной (например, запуск экземпляра процесса по key). Если выполнить такую команду, будет выброшен ProcessEngineException. Чтобы команда выполнилась успешно, идентификатор арендатора нужно передать в команду.
Обратите внимание: прозрачные ограничения доступа арендаторов link:{{< relref "#transparent-access-restrictions-for-tenants" >}}[] позволяют не указывать идентификатор арендатора, если пользователь имеет доступ только к одному из определений.
Создание экземпляра процесса
Чтобы создать экземпляр по key определения процесса, задеплоенного для нескольких арендаторов, идентификатор арендатора нужно передать в {{< javadocref page="org/camunda/bpm/engine/runtime/ProcessInstantiationBuilder.html" text="ProcessInstantiationBuilder" >}}.
runtimeService
.createProcessInstanceByKey("key")
.processDefinitionTenantId("tenant1")
.execute();
Корреляция сообщения
Message API можно использовать, чтобы коррелировать сообщение с одним арендатором или со всеми арендаторами. Если сообщение может быть коррелировано с определениями или execution нескольких арендаторов, идентификатор арендатора нужно передать в {{< javadocref page="org/camunda/bpm/engine/runtime/MessageCorrelationBuilder.html" text="MessageCorrelationBuilder" >}}. В противном случае будет выброшен MismatchingMessageCorrelationException.
runtimeService
.createMessageCorrelation("messageName")
.tenantId("tenant1")
.correlate();
Чтобы коррелировать сообщение со всеми арендаторами, не передавайте идентификатор арендатора в builder и вызовите correlateAll().
runtimeService
.createMessageCorrelation("messageName")
.correlateAll();
Отправка сигнала
Signal API можно использовать, чтобы доставить сигнал одному арендатору или всем арендаторам. Передайте идентификатор арендатора в {{< javadocref page="org/camunda/bpm/engine/runtime/SignalEventReceivedBuilder.html" text="SignalEventReceivedBuilder" >}}, чтобы доставить сигнал конкретному арендатору. Если идентификатор не передан, сигнал доставляется всем арендаторам.
runtimeService
.createSignalEvent("signalName")
.tenantId("tenant1")
.send();
Когда сигнал выбрасывается внутри процесса (то есть intermediate signal event или signal end event), он доставляется определениям и execution, которые принадлежат тому же арендатору, что и вызывающий execution, либо не принадлежат ни одному арендатору.
Создание экземпляра кейса
Чтобы создать экземпляр по key определения кейса, задеплоенного для нескольких арендаторов, идентификатор арендатора нужно передать в {{< javadocref page="org/camunda/bpm/engine/runtime/CaseInstanceBuilder.html" text="CaseInstanceBuilder" >}}.
caseService
.withCaseDefinitionByKey("key")
.caseDefinitionTenantId("tenant1")
.execute();
Вычисление таблицы решений
Чтобы вычислить таблицу решений по key, задеплоенную для нескольких арендаторов, идентификатор арендатора нужно передать в {{< javadocref page="org/camunda/bpm/engine/dmn/DecisionEvaluationBuilder.html" text="DecisionEvaluationBuilder" >}}.
decisionService
.evaluateDecisionTableByKey("key")
.decisionDefinitionTenantId("tenant1")
.evaluate();
Прозрачные ограничения доступа для арендаторов
При интеграции OpenBPM Engine в приложение может быть неудобно передавать tenant id в каждый вызов OpenBPM Engine API. Поскольку такое приложение обычно также имеет понятие «аутентифицированного пользователя», можно задать список tenant id при установке аутентификации:
try {
identityService.setAuthentication("mary", asList("accounting"), asList("tenant1"));
// All API calls executed here have "tenant1" transparently set as tenantId
}
finally {
identityService.clearAuthentication();
}
В примере выше все вызовы API между setAuthentication(…) и clearAuthentication() прозрачно выполняются со списком
переданных tenant id.
Пример запроса
Следующий запрос
try {
identityService.setAuthentication("mary", asList("accounting"), asList("tenant1"));
repositoryService.createProcessDefinitionQuery().list();
}
finally {
identityService.clearAuthentication();
}
эквивалентен
repositoryService.createProcessDefinitionQuery()
.tenantIdIn("tenant1")
.includeProcessDefinitionsWithoutTenantId()
.list();
Пример доступа к задачам
Для других команд, например complete(), прозрачная проверка доступа гарантирует, что аутентифицированный пользователь не получит доступ
к ресурсам других арендаторов:
try {
identityService.setAuthentication("mary", asList("accounting"), asList("tenant1"));
// throws an exception if task has tenant id other than "tenant1"
taskService.complete("someTaskId");
}
finally {
identityService.clearAuthentication();
}
Получение tenant id пользователя из Identity Service
Identity Service движка процессов можно использовать для управления пользователями, группами и арендаторами, а также их связями. Следующий пример показывает, как получить списки групп и арендаторов для заданного пользователя и затем использовать эти списки при установке аутентификации:
List<Tenant> groups = identityService.createGroupQuery()
.userMember(userId)
.list();
List<Tenant> tenants = identityService.createTenantQuery()
.userMember(userId)
.includingGroupsOfUser(true)
.list();
try {
identityService.setAuthentication(userId, groups, tenants);
// get all tasks visible to user.
taskService.createTaskQuery().list();
}
finally {
identityService.clearAuthentication();
}
LDAP IDENTITY SERVICE: Пример выше работает только с Database Identity Service (то есть реализацией по умолчанию). LDAP Identity Service не поддерживает арендаторов.
OpenBPM Engine Rest API и веб-приложения
OpenBPM Engine Rest API и веб-приложения Cockpit и Tasklist поддерживают прозрачные ограничения доступа. Когда пользователь входит в систему, он видит и может получать доступ только к данным (например, определениям процессов), которые принадлежат одному из его арендаторов.
Управлять арендаторами и их membership можно в веб-приложении Admin.
Отключение прозрачных ограничений доступа
Прозрачные ограничения доступа включены по умолчанию. Чтобы отключить ограничения, установите свойство tenantCheckEnabled в ProcessEngineConfiguration в false.
Также можно отключить ограничения для отдельной команды (например, для задачи обслуживания). Используйте CommandContext, чтобы отключать и включать ограничения для текущей команды.
commandContext.disableTenantCheck();
// e.g., do maintenance tasks over all tenants
commandContext.enableTenantCheck();
Обратите внимание: ограничения нельзя включить для команды, если они отключены в ProcessEngineConfiguration.
Доступ ко всем арендаторам как администратор
Пользователь-администратор или пользователи, входящие в admin group, могут получать доступ к данным всех арендаторов, даже если они не принадлежат этим арендаторам. Это полезно для администратора мультиарендного приложения, так как ему необходимо управлять данными всех арендаторов.
Назначьте admin users, сделав их участниками группы camunda-admin, или с помощью Admin Authorization Plugin. Admin Authorization Plugin позволяет выдавать административные привилегии пользовательскому пользователю или группе.
Общие определения для всех арендаторов
В разделе Deploy Definitions for a Tenant #_deploy_definitions_for_a_tenant объясняется, как задеплоить Process Definition или Decision Definition для конкретного арендатора. В результате определение видно только тому арендатору, для которого оно задеплоено, но не другим арендаторам. Это полезно, если у арендаторов разные процессы и решения. Однако во многих ситуациях всем арендаторам нужны одни и те же определения. В таких ситуациях желательно задеплоить определение один раз так, чтобы оно было видно всем арендаторам. Затем, когда новый экземпляр создается конкретным арендатором, он должен быть виден только этому арендатору (и, разумеется, администраторам). Этого можно добиться паттерном использования, который мы называем "Shared Definitions". Под паттерном использования понимается, что это не отдельная функциональность OpenBPM Engine сама по себе, а конкретный способ ее использования для достижения нужного поведения.
EXAMPLE: Вы можете найти пример https://github.com/camunda/camunda-bpm-examples/tree/master/multi-tenancy/tenant-identifier-shared-definitions на GitHub https://github.com/camunda/camunda-bpm-examples, который показывает использование shared definitions.
Деплой общего определения
Деплой общего определения - это обычный «регулярный» деплой без присвоения deployment tenant id:
repositoryService
.createDeployment()
.addClasspathResource("processes/default/mainProcess.bpmn")
.addClasspathResource("processes/default/subProcess.bpmn")
.deploy();
Включение общих определений в запрос
Часто в приложении нужно показывать пользователю список «доступных» определений процессов. В мультиарендном контексте с общими ресурсами мы хотим, чтобы список включал определения со следующими свойствами:
-
tenant id равен tenant id текущего пользователя,
-
tenant id равен
null⇒ процесс является общим ресурсом.
Чтобы получить это через запрос, нужно ограничить запрос списком tenant id пользователя (вызвав tenantIdIn(…)) и включить определения без tenant id (includeProcessDefinitionsWithoutTenantId()). Иначе говоря: исключить все определения, у которых tenant id отличается от tenant id текущего пользователя.
Пример:
repositoryService.createProcessDefinitionQuery()
.tenantIdIn("someTenantId")
.includeProcessDefinitionsWithoutTenantId()
.list();
Создание экземпляра из общего определения
При создании (запуске) нового экземпляра процесса tenant id определения процесса распространяется на экземпляр процесса. У shared resources нет tenant id, что означает: tenant id автоматически не распространяется. Чтобы tenant id пользователя, запускающего экземпляр процесса, присваивался экземпляру процесса, нужно предоставить реализацию SPI {{< javadocref page="org/camunda/bpm/engine/impl/cfg/multitenancy/TenantIdProvider.html" text="TenantIdProvider" >}}.
TenantIdProvider получает callback при создании экземпляра process definition, case definition или decision definition. После этого он может назначить tenant id вновь созданному экземпляру (или не назначать).
Следующий пример показывает, как назначить tenant id экземпляру на основе текущей аутентификации:
public class CustomTenantIdProvider implements TenantIdProvider {
@Override
public String provideTenantIdForProcessInstance(TenantIdProviderProcessInstanceContext ctx) {
return getTenantIdOfCurrentAuthentication();
}
@Override
public String provideTenantIdForCaseInstance(TenantIdProviderCaseInstanceContext ctx) {
return getTenantIdOfCurrentAuthentication();
}
@Override
public String provideTenantIdForHistoricDecisionInstance(TenantIdProviderHistoricDecisionInstanceContext ctx) {
return getTenantIdOfCurrentAuthentication();
}
protected String getTenantIdOfCurrentAuthentication() {
IdentityService identityService = Context.getProcessEngineConfiguration().getIdentityService();
Authentication currentAuthentication = identityService.getCurrentAuthentication();
if (currentAuthentication != null) {
List<String> tenantIds = currentAuthentication.getTenantIds();
if (tenantIds.size() == 1) {
return tenantIds.get(0);
} else if (tenantIds.isEmpty()) {
throw new IllegalStateException("no authenticated tenant");
} else {
throw new IllegalStateException("more than one authenticated tenant");
}
} else {
throw new IllegalStateException("no authentication");
}
}
}
Чтобы использовать TenantIdProvider, его нужно задать в Process Engine Configuration, например через camunda.cfg.xml:
<beans>
<bean id="processEngineConfiguration" class="io.openbpm.bpm.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!-- ... -->
<property name="tenantIdProvider" ref="tenantIdProvider" />
</bean>
<bean id="tenantIdProvider" class="io.openbpm.bpm.CustomTenantIdProvider">
</beans>
В случае shared process engine provider можно задать через Process Engine Plugin.
Tenant-специфичное поведение с Call Activity
До этого мы видели, что shared resources - полезный паттерн, если у арендаторов одинаковые определения процессов. Преимущество в том, что не нужно деплоить одни и те же process definitions отдельно для каждого арендатора. Однако во многих реальных приложениях ситуация промежуточная: арендаторы разделяют в основном одинаковые определения процессов, но есть tenant-специфичные вариации.
Распространенный паттерн - вынести tenant-специфичное поведение в отдельный процесс, который затем вызывается через call activity. Также часто используется tenant-специфичная decision-логика (таблицы решений) через business rules task.
Чтобы реализовать это, call activity или business rule task должны выбирать корректное вызываемое определение на основе tenant id текущего экземпляра процесса. Пример Shared Resources Example https://github.com/camunda/camunda-bpm-examples/tree/master/multi-tenancy/tenant-identifier-shared-definitions показывает, как этого добиться.
См. также:
-
Shared Resources Example https://github.com/camunda/camunda-bpm-examples/tree/master/multi-tenancy/tenant-identifier-shared-definitions
-
Case Tenant Id для call activity.
-
Decision Ref Tenant Id для business rule task.
Один Process Engine на арендатора
Мультиарендность можно реализовать, предоставив один process engine на арендатора. Каждый process engine настраивается на отдельный data source, который подключает данные арендатора. Данные арендаторов могут храниться в разных базах, в одной базе с разными схемами или в одной схеме с разными таблицами.

Process engine могут работать на одном сервере, чтобы совместно использовать вычислительные ресурсы, например data source (при изоляции через схемы или таблицы) или thread pool для асинхронного выполнения job.
TUTORIAL: Вы можете посмотреть пример https://github.com/camunda/camunda-bpm-examples/tree/master/multi-tenancy/schema-isolation с реализацией мультиарендности с изоляцией данных по схемам.
Настройка Process Engine
Process engine можно настроить в конфигурационном файле или через Java API. Каждый engine должен иметь имя, связанное с арендатором, чтобы его можно было идентифицировать по арендатору. Например, каждый engine можно назвать по имени арендатора, которого он обслуживает. Подробнее см. раздел Bootstrapping Process Engine.
Изоляция баз данных
Если разные арендаторы должны работать с полностью разными базами данных, им нужно использовать разные JDBC-настройки или разные data source.
Изоляция схем или таблиц
Для изоляции на уровне схем или таблиц можно использовать единый data source, то есть ресурсы вроде connection pool могут разделяться между несколькими engine. Для этого:
-
можно использовать опцию конфигурации databaseTablePrefix для настройки доступа к базе.
-
рекомендуется включить настройку
useSharedSqlSessionFactory. Эта настройка определяет, должен ли каждый экземпляр process engine разбирать и хранить локальную копию mybatis mapping files или можно использовать одну общую копию. Поскольку mappings занимают много heap-памяти (>30MB), рекомендуется включить эту настройку. Тогда потребуется выделить только одну копию.
CONSIDERATIONS FOR USESHAREDSQLSESSIONFACTORY SETTING:
Настройка useSharedSqlSessionFactory приводит к кешированию mybatis sql session factory в статическом поле после его создания.
При использовании этой настройки нужно учитывать, что
-
ее можно использовать только если все process engine, использующие эту настройку, разделяют один и тот же datasource и transaction factory
-
ссылка в поле, однажды установленная, никогда не очищается. Обычно это не проблема, но при необходимости пользователи должны очищать поле вручную, явно устанавливая
nullчерез
ProcessEngineConfigurationImpl.cachedSqlSessionFactory = null
Job Executor для нескольких Process Engine
Для фонового выполнения процессов и задач у process engine есть компонент job executor. Job executor периодически получает job из базы данных и отправляет их в thread pool на выполнение. Для всех process application на одном сервере используется один thread pool для выполнения job. Кроме того, возможно разделять acquisition thread между несколькими engine. Это позволяет сохранять управляемость ресурсов даже при использовании большого количества process engine. Подробнее см. раздел Job Executor и несколько Process Engine.
Пример конфигурации для изоляции по схемам
Настройки мультиарендности можно применять разными способами конфигурирования process engine. Ниже пример файла bpm-platform.xml, который задает engine для двух арендаторов, использующих одну базу данных, но работающих с разными схемами:
<?xml version="1.0" encoding="UTF-8"?>
<bpm-platform xmlns="http://www.camunda.org/schema/1.0/BpmPlatform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.camunda.org/schema/1.0/BpmPlatform http://www.camunda.org/schema/1.0/BpmPlatform">
<job-executor>
<job-acquisition name="default" />
</job-executor>
<process-engine name="tenant1">
<job-acquisition>default</job-acquisition>
<configuration>io.openbpm.bpm.engine.impl.cfg.StandaloneProcessEngineConfiguration</configuration>
<datasource>java:jdbc/ProcessEngine</datasource>
<properties>
<property name="databaseTablePrefix">TENANT_1.</property>
<property name="history">full</property>
<property name="databaseSchemaUpdate">true</property>
<property name="authorizationEnabled">true</property>
<property name="useSharedSqlSessionFactory">true</property>
</properties>
</process-engine>
<process-engine name="tenant2">
<job-acquisition>default</job-acquisition>
<configuration>io.openbpm.bpm.engine.impl.cfg.StandaloneProcessEngineConfiguration</configuration>
<datasource>java:jdbc/ProcessEngine</datasource>
<properties>
<property name="databaseTablePrefix">TENANT_2.</property>
<property name="history">full</property>
<property name="databaseSchemaUpdate">true</property>
<property name="authorizationEnabled">true</property>
<property name="useSharedSqlSessionFactory">true</property>
</properties>
</process-engine>
</bpm-platform>
Деплой определений для арендатора
При разработке process application (то есть process definitions и вспомогательного кода) часть процессов может деплоиться на engine каждого арендатора, а часть быть tenant-специфичной. Descriptor деплоя processes.xml, входящий в каждое process application, предоставляет такую гибкость через концепцию process archives. Одно приложение может содержать любое количество деплоев process archive, и каждый из них можно деплоить в разный process engine с разными ресурсами. Подробности см. в разделе descriptor деплоя processes.xml.
Ниже пример, который деплоит разные определения процессов для двух арендаторов. Используется конфигурационное свойство resourceRootPath, задающее путь в деплое, где находятся определения процессов для деплоя. Соответственно, все процессы под processes/tenant1 в classpath приложения деплоятся в engine tenant1, а все процессы под processes/tenant2 - в engine tenant2.
<process-application
xmlns="http://www.camunda.org/schema/1.0/ProcessApplication"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<process-archive name="tenant1-archive">
<process-engine>tenant1</process-engine>
<properties>
<property name="resourceRootPath">classpath:processes/tenant1/</property>
<property name="isDeleteUponUndeploy">false</property>
<property name="isScanForProcessDefinitions">true</property>
</properties>
</process-archive>
<process-archive name="tenant2-archive">
<process-engine>tenant2</process-engine>
<properties>
<property name="resourceRootPath">classpath:processes/tenant2/</property>
<property name="isDeleteUponUndeploy">false</property>
<property name="isScanForProcessDefinitions">true</property>
</properties>
</process-archive>
</process-application>
Доступ к Process Engine арендатора
Чтобы получить доступ к process engine конкретного арендатора во время выполнения, его нужно идентифицировать по имени. Движок OpenBPM Engine предоставляет доступ к именованным engine в разных моделях программирования:
-
Plain Java API: через ProcessEngineService можно получить доступ к любому именованному engine.
-
CDI Integration: именованные engine beans можно внедрять из коробки. встроенный CDI bean producer можно специализировать для динамического доступа к engine текущего арендатора.
-
Через JNDI в Wildfly: в Wildfly любой process engine, управляемый контейнером, можно получить через JNDI.
Веб-приложения OpenBPM Engine Cockpit, Tasklist и Admin поддерживают tenant-специфичные представления из коробки за счет переключения между разными process engine.
Лицензия и атрибуция
Эта документация была создана на базе материала "Camunda 7 Docs" от Camunda, находится под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported License .
Оригинал документации: https://docs.camunda.org