66.3. プロセスエンジンのサービス

プロセスエンジンは、ランタイムマネージャー API の上部で実行される高レベルのサービスを提供します。

サービスは、アプリケーションにプロセスエンジンを組み込む最も便利な方法を提供します。KIE Server は、これらのサービスを内部で使用します。

サービスを使用する場合は、ランタイムマネージャー、ランタイムエンジン、セッション、およびその他のプロセスエンジンエンティティーの独自の処理を実装する必要はありません。ただし、必要に応じてサービスを介して基礎となる RuntimeManager オブジェクトにアクセスできます。

注記

サービス API に EJB リモートクライアントを使用する場合、RuntimeManager オブジェクトはシリアル化後にクライアント側で正しく動作しないためです。

66.3.1. プロセスエンジンサービスのモジュール

プロセスエンジンサービスはモジュールのセットとして提供されます。これらのモジュールは、フレームワークの依存関係によってグループ化されます。他のモジュールが使用するフレームワークに依存しなくても、適切なモジュールを選択し、これらのモジュールのみを使用できます。

以下のモジュールが利用できます。

  • jbpm-services-api: API クラスおよびインターフェイスのみ
  • jbpm-kie-services: フレームワークの依存関係なしで純粋な Java でのサービス API のコード実装
  • jbpm-services-cdi: コアサービス実装の上に CDI ラッパー
  • jbpm-services-ejb-api: EJB 要件をサポートするサービス API の拡張機能
  • jbpm-services-ejb-impl: コアサービス実装の上に EJB ラッパー
  • jbpm-services-ejb-timer: タイマーイベントやデッドラインなどの時間ベースの操作をサポートする EJB タイマーサービスに基づくスケジューラーサービス
  • jbpm-services-ejb-client: EJB リモートクライアント実装で現在 Red Hat JBoss EAP のみをサポートします。

66.3.2. デプロイメントサービス

デプロイメントサービスは、プロセスエンジンにユニットをデプロイし、デプロイを解除します。

デプロイメントユニット は、KJAR ファイルの内容を表します。デプロイメントユニットには、プロセス定義、ルール、フォーム、データモデルなどのビジネスアセットが含まれます。ユニットのデプロイ後に、定義したプロセスを実行できます。利用可能なデプロイメントユニットをクエリーすることもできます。

すべてのデプロイメントユニットには、deploymentUnitId として知られる一意の ID 文字列 deploymentId があります。この識別子を使用して、サービスアクションをデプロイメントユニットに適用することができます。

このサービスの典型的なユースケースでは、複数の KJAR を同時に読み込み、アンロードでき、必要に応じてプロセスを同時に実行できます。

以下のコード例は、デプロイメントサービスの簡単な使用例を示しています。

デプロイメントサービスの使用

// Create deployment unit by providing the GAV of the KJAR
DeploymentUnit deploymentUnit = new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION);
// Get the deploymentId for the deployed unit
String deploymentId = deploymentUnit.getIdentifier();
// Deploy the unit
deploymentService.deploy(deploymentUnit);
// Retrieve the deployed unit
DeployedUnit deployed = deploymentService.getDeployedUnit(deploymentId);
// Get the runtime manager
RuntimeManager manager = deployed.getRuntimeManager();

以下の定義は、DeploymentService の完全なインターフェイスを示しています。

DeploymentService インターフェイスの定義

public interface DeploymentService {

    void deploy(DeploymentUnit unit);

    void undeploy(DeploymentUnit unit);

    RuntimeManager getRuntimeManager(String deploymentUnitId);

    DeployedUnit getDeployedUnit(String deploymentUnitId);

    Collection<DeployedUnit> getDeployedUnits();

    void activate(String deploymentId);

    void deactivate(String deploymentId);

    boolean isDeployed(String deploymentUnitId);
}

66.3.3. 定義サービス

デプロイメントサービスを使用してプロセス定義をデプロイすると、定義サービスは自動的に定義をスキャンし、プロセスを解析して、プロセスエンジンが必要とする情報を抽出します。

定義サービス API を使用して、プロセス定義についての情報を取得できます。サービスは、この情報を BPMN2 プロセス定義から直接抽出します。以下の情報が表示されます。

  • ID、名前、説明などの プロセス定義
  • すべての変数の名前とタイプを含む Process variables
  • プロセスで使用される 再利用可能なサブプロセス (存在する場合)
  • ドメイン固有のアクティビティーを表す サービスタスク
  • 割り当て情報を含む ユーザータスク
  • 入力情報および出力情報を含む タスクデータ

以下のコード例は、定義サービスの簡単な使用を示しています。processID は、デプロイメントサービスを使用してデプロイ済みの KJAR ファイルのプロセス定義の ID に対応している必要があります。

定義サービスの使用

String processId = "org.jbpm.writedocument";

Collection<UserTaskDefinition> processTasks =
bpmn2Service.getTasksDefinitions(deploymentUnit.getIdentifier(), processId);

Map<String, String> processData =
bpmn2Service.getProcessVariables(deploymentUnit.getIdentifier(), processId);

Map<String, String> taskInputMappings =
bpmn2Service.getTaskInputMappings(deploymentUnit.getIdentifier(), processId, "Write a Document" );

定義サービスを使用して、KJAR ファイルを使用せずに BPMN2 準拠の XML コンテンツとして指定する定義をスキャンすることもできます。buildProcessDefinition メソッドは、この機能を提供します。

以下の定義は、すべての DefinitionService インターフェイスを示しています。

DefinitionService インターフェイスの定義

public interface DefinitionService {

    ProcessDefinition buildProcessDefinition(String deploymentId, String bpmn2Content, ClassLoader classLoader, boolean cache) throws IllegalArgumentException;

    ProcessDefinition getProcessDefinition(String deploymentId, String processId);

    Collection<String> getReusableSubProcesses(String deploymentId, String processId);

    Map<String, String> getProcessVariables(String deploymentId, String processId);

    Map<String, String> getServiceTasks(String deploymentId, String processId);

    Map<String, Collection<String>> getAssociatedEntities(String deploymentId, String processId);

    Collection<UserTaskDefinition> getTasksDefinitions(String deploymentId, String processId);

    Map<String, String> getTaskInputMappings(String deploymentId, String processId, String taskName);

    Map<String, String> getTaskOutputMappings(String deploymentId, String processId, String taskName);

}

66.3.4. プロセスサービス

デプロイメントおよび定義のサービスは、プロセスエンジンのプロセスデータを準備します。このデータに基づいたプロセスを実行するには、プロセスサービスを使用します。プロセスサービスは、以下のアクションを含むプロセスエンジン実行環境との対話をサポートします。

  • 新規プロセスインスタンスの開始
  • イベントのシグナル送信、情報の詳細の取得、変数の値の設定など、既存のプロセスインスタンスの使用
  • ワークアイテムの使用

プロセスサービスはコマンドエグゼキューターでもあります。このコマンドを使用して、KIE セッションでコマンドを実行して、その機能を拡張できます。

重要

プロセスサービスはランタイム操作向けに最適化されています。シグナルイベントや変更変数など、プロセスインスタンスを変更する必要がある場合に使用します。利用可能なプロセスインスタンスを表示するなどの読み取り操作の場合は、ランタイムデータサービスを使用します。

以下のコード例は、プロセスのデプロイおよび実行を示しています。

デプロイメントおよびプロセスサービスを使用したプロセスのデプロイと実行

KModuleDeploymentUnit deploymentUnit = new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION);

deploymentService.deploy(deploymentUnit);

long processInstanceId = processService.startProcess(deploymentUnit.getIdentifier(), "customtask");

ProcessInstance pi = processService.getProcessInstance(processInstanceId);

startProcess メソッドでは、deploymentId が最初の引数として想定されます。この引数を使用すると、アプリケーションが複数のデプロイメントを持つ可能性がある場合に、特定のデプロイメントでプロセスを開始できます。

たとえば、異なる KJAR ファイルから同じプロセスの異なるバージョンをデプロイする場合などです。その後、正しい deploymentId を使用して必要なバージョンを起動できます。

以下の定義は、完全な ProcessService インターフェイスを示しています。

ProcessService インターフェイスの定義

public interface ProcessService {

	/**
	 * Starts a process with no variables
	 *
	 * @param deploymentId deployment identifier
	 * @param processId process identifier
	 * @return process instance IDentifier
	 * @throws RuntimeException in case of encountered errors
	 * @throws DeploymentNotFoundException in case a deployment with the given deployment identifier does not exist
	 * @throws DeploymentNotActiveException in case the deployment with the given deployment identifier is not active
	 */
	Long startProcess(String deploymentId, String processId);

	/**
	 * Starts a process and sets variables
	 *
	 * @param deploymentId deployment identifier
	 * @param processId process identifier
	 * @param params process variables
	 * @return process instance IDentifier
	 * @throws RuntimeException in case of encountered errors
	 * @throws DeploymentNotFoundException in case a deployment with the given deployment identifier does not exist
	 * @throws DeploymentNotActiveException in case the deployment with the given deployment identifier is not active
	 */
    Long startProcess(String deploymentId, String processId, Map<String, Object> params);

	/**
	 * Starts a process with no variables and assigns a correlation key
	 *
	 * @param deploymentId deployment identifier
	 * @param processId process identifier
	 * @param correlationKey correlation key to be assigned to the process instance - must be unique
	 * @return process instance IDentifier
	 * @throws RuntimeException in case of encountered errors
	 * @throws DeploymentNotFoundException in case a deployment with the given deployment identifier does not exist
     * @throws DeploymentNotActiveException in case the deployment with the given deployment identifier is not active
	 */
	Long startProcess(String deploymentId, String processId, CorrelationKey correlationKey);

	/**
	 * Starts a process, sets variables, and assigns a correlation key
	 *
	 * @param deploymentId deployment identifier
	 * @param processId process identifier
	 * @param correlationKey correlation key to be assigned to the process instance - must be unique
	 * @param params process variables
	 * @return process instance IDentifier
	 * @throws RuntimeException in case of encountered errors
	 * @throws DeploymentNotFoundException in case a deployment with the given deployment identifier does not exist
     * @throws DeploymentNotActiveException in case the deployment with the given deployment identifier is not active
	 */
    Long startProcess(String deploymentId, String processId, CorrelationKey correlationKey, Map<String, Object> params);

    /**
     * Starts a process at the listed nodes, instead of the normal starting point.
     * This method can be used for restarting a process that was aborted. However,
     * it does not restore the context of a previous process instance. You must
     * supply all necessary variables when calling this method.
     * This method does not guarantee that the process is started in a valid state.
     *
     * @param deploymentId deployment identifier
     * @param processId process identifier
     * @param params process variables
     * @param nodeIds list of BPMN node identifiers where the process must start
     * @return process instance IDentifier
     * @throws RuntimeException in case of encountered errors
     * @throws DeploymentNotFoundException in case a deployment with the given deployment identifier does not exist
     * @throws DeploymentNotActiveException in case the deployment with the given deployment identifier is not active
     */
    Long startProcessFromNodeIds(String deploymentId, String processId, Map<String, Object> params, String... nodeIds);

    /**
    * Starts a process at the listed nodes, instead of the normal starting point,
    * and assigns a correlation key.
    * This method can be used for restarting a process that was aborted. However,
    * it does not restore the context of a previous process instance. You must
    * supply all necessary variables when calling this method.
    * This method does not guarantee that the process is started in a valid state.
     *
     * @param deploymentId deployment identifier
     * @param processId process identifier
     * @param key correlation key (must be unique)
     * @param params process variables
     * @param nodeIds list of BPMN node identifiers where the process must start.
     * @return process instance IDentifier
     * @throws RuntimeException in case of encountered errors
     * @throws DeploymentNotFoundException in case a deployment with the given deployment identifier does not exist
     * @throws DeploymentNotActiveException in case the deployment with the given deployment identifier is not active
     */
    Long startProcessFromNodeIds(String deploymentId, String processId, CorrelationKey key, Map<String, Object> params, String... nodeIds);

    /**
     * Aborts the specified process
     *
     * @param processInstanceId process instance unique identifier
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
     */
    void abortProcessInstance(Long processInstanceId);

    /**
     * Aborts the specified process
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceId process instance unique identifier
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
     */
    void abortProcessInstance(String deploymentId, Long processInstanceId);

    /**
	 * Aborts all specified processes
	 *
	 * @param processInstanceIds list of process instance unique identifiers
	 * @throws DeploymentNotFoundException in case the deployment unit was not found
	 * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
	 */
    void abortProcessInstances(List<Long> processInstanceIds);

    /**
     * Aborts all specified processes
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceIds list of process instance unique identifiers
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
     */
    void abortProcessInstances(String deploymentId, List<Long> processInstanceIds);

    /**
	 * Signals an event to a single process instance
	 *
	 * @param processInstanceId the process instance unique identifier
	 * @param signalName the ID of the signal in the process
	 * @param event the event object to be passed with the event
	 * @throws DeploymentNotFoundException in case the deployment unit was not found
	 * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
	 */
    void signalProcessInstance(Long processInstanceId, String signalName, Object event);

    /**
     * Signals an event to a single process instance
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceId the process instance unique identifier
     * @param signalName the ID of the signal in the process
     * @param event the event object to be passed with the event
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
     */
    void signalProcessInstance(String deploymentId, Long processInstanceId, String signalName, Object event);

    /**
	 * Signal an event to a list of process instances
	 *
	 * @param processInstanceIds list of process instance unique identifiers
	 * @param signalName the ID of the signal in the process
	 * @param event the event object to be passed with the event
	 * @throws DeploymentNotFoundException in case the deployment unit was not found
	 * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
	 */
    void signalProcessInstances(List<Long> processInstanceIds, String signalName, Object event);

    /**
     * Signal an event to a list of process instances
     *
     * @param deploymentId deployment to which the process instances belong
     * @param processInstanceIds list of process instance unique identifiers
     * @param signalName the ID of the signal in the process
     * @param event the event object to be passed with the event
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
     */
    void signalProcessInstances(String deploymentId, List<Long> processInstanceIds, String signalName, Object event);

		/**
     * Signal an event to a single process instance by correlation key
     *
     * @param correlationKey the unique correlation key of the process instance
     * @param signalName the ID of the signal in the process
     * @param event the event object to be passed in with the event
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws ProcessInstanceNotFoundException in case a process instance with the given key was not found
     */
    void signalProcessInstanceByCorrelationKey(CorrelationKey correlationKey, String signalName, Object event);

		/**
		 * Signal an event to a single process instance by correlation key
		 *
		 * @param deploymentId deployment to which the process instance belongs
		 * @param correlationKey the unique correlation key of the process instance
		 * @param signalName the ID of the signal in the process
		 * @param event the event object to be passed in with the event
		 * @throws DeploymentNotFoundException in case the deployment unit was not found
		 * @throws ProcessInstanceNotFoundException in case a process instance with the given key was not found
		 */
		void signalProcessInstanceByCorrelationKey(String deploymentId, CorrelationKey correlationKey, String signalName, Object event);

		/**
		 * Signal an event to given list of correlation keys
		 *
		 * @param correlationKeys list of unique correlation keys of process instances
		 * @param signalName the ID of the signal in the process
		 * @param event the event object to be passed in with the event
		 * @throws DeploymentNotFoundException in case the deployment unit was not found
		 * @throws ProcessInstanceNotFoundException in case a process instance with one of the given keys was not found
		 */
		void signalProcessInstancesByCorrelationKeys(List<CorrelationKey> correlationKeys, String signalName, Object event);

		/**
		 * Signal an event to given list of correlation keys
		 *
		 * @param deploymentId deployment to which the process instances belong
		 * @param correlationKeys list of unique correlation keys of process instances
		 * @param signalName the ID of the signal in the process
		 * @param event the event object to be passed in with the event
		 * @throws DeploymentNotFoundException in case the deployment unit was not found
		 * @throws ProcessInstanceNotFoundException in case a process instance with one of the given keys was not found
		 */
		void signalProcessInstancesByCorrelationKeys(String deploymentId, List<CorrelationKey> correlationKeys, String signalName, Object event);

    /**
     * Signal an event to a any process instance that listens to a given signal and belongs to a given deployment
     *
     * @param deployment identifier of the deployment
     * @param signalName the ID of the signal in the process
     * @param event the event object to be passed with the event
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     */
    void signalEvent(String deployment, String signalName, Object event);

    /**
	 * Returns process instance information. Will return null if no
	 * active process with the ID is found
	 *
	 * @param processInstanceId The process instance unique identifier
	 * @return Process instance information
	 * @throws DeploymentNotFoundException in case the deployment unit was not found
	 */
    ProcessInstance getProcessInstance(Long processInstanceId);

    /**
     * Returns process instance information. Will return null if no
     * active process with the ID is found
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceId The process instance unique identifier
     * @return Process instance information
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     */
    ProcessInstance getProcessInstance(String deploymentId, Long processInstanceId);

    /**
	 * Returns process instance information. Will return null if no
	 * active process with that correlation key is found
	 *
	 * @param correlationKey correlation key assigned to the process instance
	 * @return Process instance information
	 * @throws DeploymentNotFoundException in case the deployment unit was not found
	 */
    ProcessInstance getProcessInstance(CorrelationKey correlationKey);

    /**
     * Returns process instance information. Will return null if no
     * active process with that correlation key is found
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param correlationKey correlation key assigned to the process instance
     * @return Process instance information
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     */
    ProcessInstance getProcessInstance(String deploymentId, CorrelationKey correlationKey);

    /**
	 * Sets a process variable.
	 * @param processInstanceId The process instance unique identifier
	 * @param variableId The variable ID to set
	 * @param value The variable value
	 * @throws DeploymentNotFoundException in case the deployment unit was not found
	 * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
	 */
    void setProcessVariable(Long processInstanceId, String variableId, Object value);

    /**
     * Sets a process variable.
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceId The process instance unique identifier
     * @param variableId The variable id to set.
     * @param value The variable value.
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
     */
    void setProcessVariable(String deploymentId, Long processInstanceId, String variableId, Object value);

    /**
	 * Sets process variables.
	 *
	 * @param processInstanceId The process instance unique identifier
	 * @param variables map of process variables (key = variable name, value = variable value)
	 * @throws DeploymentNotFoundException in case the deployment unit was not found
	 * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
	 */
    void setProcessVariables(Long processInstanceId, Map<String, Object> variables);

    /**
     * Sets process variables.
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceId The process instance unique identifier
     * @param variables map of process variables (key = variable name, value = variable value)
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
     */
    void setProcessVariables(String deploymentId, Long processInstanceId, Map<String, Object> variables);

    /**
	 * Gets a process instance variable.
	 *
	 * @param processInstanceId the process instance unique identifier
	 * @param variableName the variable name to get from the process
	 * @throws DeploymentNotFoundException in case the deployment unit was not found
	 * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
	*/
    Object getProcessInstanceVariable(Long processInstanceId, String variableName);

    /**
     * Gets a process instance variable.
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceId the process instance unique identifier
     * @param variableName the variable name to get from the process
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
    */
    Object getProcessInstanceVariable(String deploymentId, Long processInstanceId, String variableName);

	/**
	 * Gets a process instance variable values.
	 *
	 * @param processInstanceId The process instance unique identifier
	 * @throws DeploymentNotFoundException in case the deployment unit was not found
	 * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
	*/
	Map<String, Object> getProcessInstanceVariables(Long processInstanceId);

	/**
     * Gets a process instance variable values.
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceId The process instance unique identifier
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
    */
    Map<String, Object> getProcessInstanceVariables(String deploymentId, Long processInstanceId);

	/**
	 * Returns all signals available in current state of given process instance
	 *
	 * @param processInstanceId process instance ID
	 * @return list of available signals or empty list if no signals are available
	 */
    Collection<String> getAvailableSignals(Long processInstanceId);

    /**
     * Returns all signals available in current state of given process instance
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceId process instance ID
     * @return list of available signals or empty list if no signals are available
     */
    Collection<String> getAvailableSignals(String deploymentId, Long processInstanceId);

	/**
	 * Completes the specified WorkItem with the given results
	 *
	 * @param id workItem ID
	 * @param results results of the workItem
	 * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws WorkItemNotFoundException in case a work item with the given ID was not found
	 */
    void completeWorkItem(Long id, Map<String, Object> results);

    /**
     * Completes the specified WorkItem with the given results
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceId process instance ID to which the work item belongs
     * @param id workItem ID
     * @param results results of the workItem
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws WorkItemNotFoundException in case a work item with the given ID was not found
     */
    void completeWorkItem(String deploymentId, Long processInstanceId, Long id, Map<String, Object> results);

    /**
     * Abort the specified workItem
     *
     * @param id workItem ID
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws WorkItemNotFoundException in case a work item with the given ID was not found
     */
    void abortWorkItem(Long id);

    /**
     * Abort the specified workItem
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceId process instance ID to which the work item belongs
     * @param id workItem ID
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws WorkItemNotFoundException in case a work item with the given ID was not found
     */
    void abortWorkItem(String deploymentId, Long processInstanceId, Long id);

    /**
     * Returns the specified workItem
     *
     * @param id workItem ID
     * @return The specified workItem
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws WorkItemNotFoundException in case a work item with the given ID was not found
     */
    WorkItem getWorkItem(Long id);

    /**
     * Returns the specified workItem
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceId process instance ID to which the work item belongs
     * @param id workItem ID
     * @return The specified workItem
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws WorkItemNotFoundException in case a work item with the given ID was not found
     */
    WorkItem getWorkItem(String deploymentId, Long processInstanceId, Long id);

    /**
     * Returns active work items by process instance ID.
     *
     * @param processInstanceId process instance ID
     * @return The list of active workItems for the process instance
     * @throws DeploymentNotFoundException in case the deployment unit was not found
	 * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
     */
    List<WorkItem> getWorkItemByProcessInstance(Long processInstanceId);

    /**
     * Returns active work items by process instance ID.
     *
     * @param deploymentId deployment to which the process instance belongs
     * @param processInstanceId process instance ID
     * @return The list of active workItems for the process instance
     * @throws DeploymentNotFoundException in case the deployment unit was not found
     * @throws ProcessInstanceNotFoundException in case a process instance with the given ID was not found
     */
    List<WorkItem> getWorkItemByProcessInstance(String deploymentId, Long processInstanceId);


    /**
     * Executes the provided command on the underlying command executor (usually KieSession)
     * @param deploymentId deployment identifier
     * @param command actual command for execution
     * @return results of the command execution
     * @throws DeploymentNotFoundException in case a deployment with the given deployment identifier does not exist
     * @throws DeploymentNotActiveException in case the deployment with the given deployment identifier is not active for restricted commands (for example, start process)
     */
    public <T> T execute(String deploymentId, Command<T> command);

    /**
     * Executes the provided command on the underlying command executor (usually KieSession)
     * @param deploymentId deployment identifier
     * @param context context implementation to be used to get the runtime engine
     * @param command actual command for execution
     * @return results of the command execution
     * @throws DeploymentNotFoundException in case a deployment with the given deployment identifier does not exist
     * @throws DeploymentNotActiveException in case the deployment with the given deployment identifier is not active for restricted commands (for example, start process)
     */
    public <T> T execute(String deploymentId, Context<?> context, Command<T> command);

}

66.3.4.1. ランタイムデータサービス

ランタイムデータサービスを使用して、開始したプロセスインスタンスや実行ノードインスタンスなど、プロセスに関するすべてのランタイム情報を取得できます。

たとえば、リストベースの UI をビルドして、ランタイムデータサービスによって提供される情報に基づいて、プロセス定義、プロセスインスタンス、特定ユーザーのタスクなどのデータを表示できます。

このサービスは、必要な情報をすべて提供しながら、できるだけ効率的になるように最適化されます。

以下の例は、このサービスのさまざまな使用方法を示しています。

全プロセス定義の取得

Collection definitions = runtimeDataService.getProcesses(new QueryContext());

アクティブなプロセスインスタンスの取得

Collection<processinstancedesc> instances = runtimeDataService.getProcessInstances(new QueryContext());

特定のプロセスインスタンスでのアクティブなノードの取得

Collection<nodeinstancedesc> instances = runtimeDataService.getProcessInstanceHistoryActive(processInstanceId, new QueryContext());

ユーザー john に割り当てられたタスクの取得

List<tasksummary> taskSummaries = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter(0, 10));

ランタイムデータサービスメソッドは、QueryContext および QueryFilter の 2 つの重要なパラメーターをサポートします。QueryFilterQueryContext の拡張機能です。これらのパラメーターを使用して、結果セット、ページネーション、ソート、順序付けを管理します。ユーザータスクを検索する際に、それらを使用して追加のフィルターリングを適用することもできます。

以下の定義は、完全な RuntimeDataService インターフェイスを示しています。

RuntimeDataService インターフェイスの定義

public interface RuntimeDataService {

    // Process instance information

    Collection<ProcessInstanceDesc> getProcessInstances(QueryContext queryContext);

    Collection<ProcessInstanceDesc> getProcessInstances(List<Integer> states, String initiator, QueryContext queryContext);

    Collection<ProcessInstanceDesc> getProcessInstancesByProcessId(List<Integer> states, String processId, String initiator, QueryContext queryContext);

    Collection<ProcessInstanceDesc> getProcessInstancesByProcessName(List<Integer> states, String processName, String initiator, QueryContext queryContext);

    Collection<ProcessInstanceDesc> getProcessInstancesByDeploymentId(String deploymentId, List<Integer> states, QueryContext queryContext);

    ProcessInstanceDesc getProcessInstanceById(long processInstanceId);

    Collection<ProcessInstanceDesc> getProcessInstancesByProcessDefinition(String processDefId, QueryContext queryContext);

    Collection<ProcessInstanceDesc> getProcessInstancesByProcessDefinition(String processDefId, List<Integer> states, QueryContext queryContext);


    // Node and Variable instance information

    NodeInstanceDesc getNodeInstanceForWorkItem(Long workItemId);

    Collection<NodeInstanceDesc> getProcessInstanceHistoryActive(long processInstanceId, QueryContext queryContext);

    Collection<NodeInstanceDesc> getProcessInstanceHistoryCompleted(long processInstanceId, QueryContext queryContext);

    Collection<NodeInstanceDesc> getProcessInstanceFullHistory(long processInstanceId, QueryContext queryContext);

    Collection<NodeInstanceDesc> getProcessInstanceFullHistoryByType(long processInstanceId, EntryType type, QueryContext queryContext);

    Collection<VariableDesc> getVariablesCurrentState(long processInstanceId);

    Collection<VariableDesc> getVariableHistory(long processInstanceId, String variableId, QueryContext queryContext);


    // Process information

    Collection<ProcessDefinition> getProcessesByDeploymentId(String deploymentId, QueryContext queryContext);

    Collection<ProcessDefinition> getProcessesByFilter(String filter, QueryContext queryContext);

    Collection<ProcessDefinition> getProcesses(QueryContext queryContext);

    Collection<String> getProcessIds(String deploymentId, QueryContext queryContext);

    ProcessDefinition getProcessById(String processId);

    ProcessDefinition getProcessesByDeploymentIdProcessId(String deploymentId, String processId);

	// user task query operations

    UserTaskInstanceDesc getTaskByWorkItemId(Long workItemId);

    UserTaskInstanceDesc getTaskById(Long taskId);

    List<TaskSummary> getTasksAssignedAsBusinessAdministrator(String userId, QueryFilter filter);

    List<TaskSummary> getTasksAssignedAsBusinessAdministratorByStatus(String userId, List<Status> statuses, QueryFilter filter);

    List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, QueryFilter filter);

    List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, List<String> groupIds, QueryFilter filter);

    List<TaskSummary> getTasksAssignedAsPotentialOwnerByStatus(String userId, List<Status> status, QueryFilter filter);

    List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, List<String> groupIds, List<Status> status, QueryFilter filter);

    List<TaskSummary> getTasksAssignedAsPotentialOwnerByExpirationDateOptional(String userId, List<Status> status, Date from, QueryFilter filter);

    List<TaskSummary> getTasksOwnedByExpirationDateOptional(String userId, List<Status> strStatuses, Date from, QueryFilter filter);

    List<TaskSummary> getTasksOwned(String userId, QueryFilter filter);

    List<TaskSummary> getTasksOwnedByStatus(String userId, List<Status> status, QueryFilter filter);

    List<Long> getTasksByProcessInstanceId(Long processInstanceId);

    List<TaskSummary> getTasksByStatusByProcessInstanceId(Long processInstanceId, List<Status> status, QueryFilter filter);

    List<AuditTask> getAllAuditTask(String userId, QueryFilter filter);

}

66.3.4.2. ユーザータスクサービス

ユーザータスクサービスは、個別のタスクの完全なライフサイクルに対応し、サービスを使用して開始から終了までユーザータスクを管理できます。

タスククエリーは、ユーザータスクサービスの一部ではありません。ランタイムデータサービスを使用して、タスクのクエリーを行います。以下を含む、1 つのタスクでスコープ設定された操作にユーザータスクサービスを使用します。

  • 選択したプロパティーの変更
  • タスク変数へのアクセス
  • タスク割り当てへのアクセス
  • タスクコメントへのアクセス

ユーザータスクサービスは、コマンドエグゼキューターでもあります。カスタムタスクコマンドを実行するのに使用できます。

以下の例は、プロセスを開始して、プロセスのタスクを操作する例を示しています。

プロセスの開始、およびこのプロセスのユーザータスクとの対話

long processInstanceId =
processService.startProcess(deployUnit.getIdentifier(), "org.jbpm.writedocument");

List<Long> taskIds =
runtimeDataService.getTasksByProcessInstanceId(processInstanceId);

Long taskId = taskIds.get(0);

userTaskService.start(taskId, "john");
UserTaskInstanceDesc task = runtimeDataService.getTaskById(taskId);

Map<String, Object> results = new HashMap<String, Object>();
results.put("Result", "some document data");
userTaskService.complete(taskId, "john", results);

66.3.5. quartz ベースのタイマーサービス

プロセスエンジンは、Quartz を使用してクラスター対応のタイマーサービスを提供します。サービスを使用すると、いつでも KIE セッションを破棄または読み込むことができます。サービスは、各タイマーを適切に実行するために KIE セッションがアクティブである期間を管理できます。

以下の例は、クラスター環境用の基本的な Quartz 設定ファイルを示しています。

クラスター環境の quartz 設定ファイル

#============================================================================
# Configure Main Scheduler Properties
#============================================================================

org.quartz.scheduler.instanceName = jBPMClusteredScheduler
org.quartz.scheduler.instanceId = AUTO

#============================================================================
# Configure ThreadPool
#============================================================================

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 5

#============================================================================
# Configure JobStore
#============================================================================

org.quartz.jobStore.misfireThreshold = 60000

org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreCMT
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties=false
org.quartz.jobStore.dataSource=managedDS
org.quartz.jobStore.nonManagedTXDataSource=nonManagedDS
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.clusterCheckinInterval = 20000

#=========================================================================
# Configure Datasources
#=========================================================================
org.quartz.dataSource.managedDS.jndiURL=jboss/datasources/psbpmsDS
org.quartz.dataSource.nonManagedDS.jndiURL=jboss/datasources/quartzNonManagedDS

お使いの環境に合わせて、以前の例を変更する必要があります。

66.3.6. クエリーサービス

クエリーサービスは、Dashbuilder データセットに基づく高度な検索機能を提供します。

この方法では、基礎となるデータストアからデータを取得する方法を制御できます。JPA エンティティーテーブルやカスタムシステムのデータベーステーブルなどの外部テーブルで複雑な JOIN ステートメントを使用できます。

クエリーサービスは、以下の 2 つの操作セットの前後に構築されます。

  • 管理操作:

    • クエリー定義の登録
    • クエリー定義の置き換え
    • クエリー定義の登録解除 (削除)
    • クエリー定義の取得
    • 登録済みクエリー定義をすべて取得
  • ランタイム操作:

    • QueryParam をフィルタープロバイダーとする単純なクエリー
    • QueryParamBuilder をフィルタープロバイダーとする高度なクエリー

Dashbuilder データセットは、CSV、SQL、Elastic Search などの複数のデータソースをサポートします。ただし、プロセスエンジンは RDBMS ベースのバックエンドを使用し、SQL ベースのデータセットにフォーカスします。

したがって、プロセスエンジンのクエリーサービスは、単純な API で効率的なクエリーを可能にする Dashbuilder データセット機能のサブセットです。

66.3.6.1. クエリーサービスのキークラス

クエリーサービスは、以下の主要なクラスに依存します。

  • QueryDefinition: データセットの定義を表します。定義は、一意の名前、SQL 式 (クエリー) および source (クエリーの実行時に使用するデータソースの JNDI 名) で設定されます。
  • QueryParam: 個別のクエリーパラメーターまたは条件を表す基本的な構造です。この構造は、列名、演算子、および予想される値で設定されます。
  • QueryResultMapper: raw データセットデータ (行および列) をオブジェクト表現にマッピングするクラス。
  • QueryParamBuilder: クエリー定義に適用されているクエリーフィルターをビルドしてクエリーを呼び出すクラス。

QueryResultMapper

QueryResultMapper は、データベース (データセット) からオブジェクト表現に取得したデータをマッピングします。これは、テーブルをエンティティーにマップする hibernate などの ORM プロバイダーと似ています。

データセット結果を表すのに使用できるオブジェクトタイプが多数あります。したがって、既存のマッパーは、常にニーズに適しているとは限りません。QueryResultMapper のマッパーはプラグ可能で、必要に応じてデータセットデータを必要なタイプに変換するために独自のマッパーを提供できます。

プロセスエンジンは以下のマッパーを提供します。

  • ProcessInstances 名で登録した org.jbpm.kie.services.impl.query.mapper.ProcessInstanceQueryMapper
  • ProcessInstancesWithVariables 名で登録した org.jbpm.kie.services.impl.query.mapper.ProcessInstanceWithVarsQueryMapper
  • ProcessInstancesWithCustomVariables 名で登録した org.jbpm.kie.services.impl.query.mapper.ProcessInstanceWithCustomVarsQueryMapper
  • UserTasks 名で登録した org.jbpm.kie.services.impl.query.mapper.UserTaskInstanceQueryMapper
  • UserTasksWithVariables で登録した org.jbpm.kie.services.impl.query.mapper.UserTaskInstanceWithVarsQueryMapper
  • UserTasksWithCustomVariables で登録した org.jbpm.kie.services.impl.query.mapper.UserTaskInstanceWithCustomVarsQueryMapper
  • TaskSummaries で登録した org.jbpm.kie.services.impl.query.mapper.TaskSummaryQueryMapper
  • RawList で登録した org.jbpm.kie.services.impl.query.mapper.RawListQueryMapper

QueryResultMapper は、一意の文字列名で登録されます。完全なクラス名を参照する代わりに、この名前でマッパーを検索できます。この機能は、クライアント側での特定の実装に依存しないようにするため、サービスの EJB リモート呼び出しを使用する場合に特に重要です。

文字列名で QueryResultMapper を参照するには、jbpm-services-api モジュールの一部である NamedQueryMapper を使用します。このクラスは委譲 (遅延委譲) として機能し、クエリーの実行時に実際のマッパーを検索します。

NamedQueryMapper の使用

queryService.query("my query def", new NamedQueryMapper<Collection<ProcessInstanceDesc>>("ProcessInstances"), new QueryContext());

QueryParamBuilder

QueryParamBuilder は、データセットにフィルターを構築する高度な方法を提供します。

デフォルトでは、ゼロ以上の QueryParam インスタンスを許可する QueryService のクエリーメソッドを使用する場合、このパラメーターはすべて AND 演算子と結合されるため、データエントリーはそれらすべてに一致する必要があります。

ただし、パラメーター間でより複雑な関係が必要になる場合があります。QueryParamBuilder を使用して、クエリーの発行時にフィルターを提供するカスタムビルダーを構築できます。

QueryParamBuilder の既存の実装の 1 つは、プロセスエンジンで使用できます。コア関数 に基づくデフォルトの QueryParams を説明します。

これらのコア機能は、以下の条件を含む SQL ベースの条件です。

  • IS_NULL
  • NOT_NULL
  • EQUALS_TO
  • NOT_EQUALS_TO
  • LIKE_TO
  • GREATER_THAN
  • GREATER_OR_EQUALS_TO
  • LOWER_THAN
  • LOWER_OR_EQUALS_TO
  • BETWEEN
  • IN
  • NOT_IN

クエリーを呼び出す前に、メソッドが null 以外の値を返す間、プロセスエンジンは QueryParamBuilder インターフェイスのビルドメソッドを必要な回数呼び出します。このアプローチにより、QueryParams の単純なリストで表現できない複雑なフィルターオプションを構築できます。

以下の例は、QueryParamBuilder の基本実装を示しています。DashBuilder Dataset API に依存します。

QueryParamBuilder の基本実装

public class TestQueryParamBuilder implements QueryParamBuilder<ColumnFilter> {

    private Map<String, Object> parameters;
    private boolean built = false;
    public TestQueryParamBuilder(Map<String, Object> parameters) {
        this.parameters = parameters;
    }

    @Override
    public ColumnFilter build() {
        // return null if it was already invoked
        if (built) {
            return null;
        }

        String columnName = "processInstanceId";

        ColumnFilter filter = FilterFactory.OR(
                FilterFactory.greaterOrEqualsTo((Long)parameters.get("min")),
                FilterFactory.lowerOrEqualsTo((Long)parameters.get("max")));
        filter.setColumnId(columnName);

        built = true;
        return filter;
    }

}

ビルダーの実装後に、以下の例のように QueryService サービスでクエリーを実行する際にこのクラスのインスタンスを使用できます。

QueryService サービスを使用したクエリーの実行

queryService.query("my query def", ProcessInstanceQueryMapper.get(), new QueryContext(), paramBuilder);

66.3.6.2. 典型的なシナリオでのクエリーサービスの使用

以下の手順では、コードがクエリーサービスを使用する一般的な方法を概説します。

手順

  1. 使用するデータのビューであるデータセットを定義します。サービス API の QueryDefinition クラスを使用して、この操作を完了します。

    データセットの定義

    SqlQueryDefinition query = new SqlQueryDefinition("getAllProcessInstances", "java:jboss/datasources/ExampleDS");
    query.setExpression("select * from processinstancelog");

    この例では、最も簡単なクエリー定義を表しています。

    コンストラクターには以下のパラメーターが必要です。

    • ランタイム時にクエリーを識別する一意の名前
    • この定義でクエリーを実行するのに使用する JNDI データソース名

      setExpression() メソッドのパラメーターは、データセットビューをビルドする SQL ステートメントです。クエリーサービスのクエリーは、このビューのデータを使用し、必要に応じてこのデータをフィルターリングします。

  2. クエリーを登録します。

    クエリーの登録

    queryService.registerQuery(query);

  3. 必要な場合は、フィルターリングせずに、データセットからすべてのデータを収集します。

    データセットからすべてのデータを収集します。

    Collection<ProcessInstanceDesc> instances = queryService.query("getAllProcessInstances", ProcessInstanceQueryMapper.get(), new QueryContext());

    この簡単なクエリーは、ページングとソートに QueryContext のデフォルトを使用します。

  4. 必要な場合は、ページングおよびソートのデフォルト値を変更する QueryContext オブジェクトを使用します。

    QueryContext オブジェクトを使用したデフォルトの変更

    QueryContext ctx = new QueryContext(0, 100, "start_date", true);
             
    Collection<ProcessInstanceDesc> instances = queryService.query("getAllProcessInstances", ProcessInstanceQueryMapper.get(), ctx);

  5. 必要な場合は、クエリーを使用してデータをフィルターリングします。

    クエリーを使用したデータのフィルター

    // single filter param
    Collection<ProcessInstanceDesc> instances = queryService.query("getAllProcessInstances", ProcessInstanceQueryMapper.get(), new QueryContext(), QueryParam.likeTo(COLUMN_PROCESSID, true, "org.jbpm%"));
     
    // multiple filter params (AND)
    Collection<ProcessInstanceDesc> instances = queryService.query("getAllProcessInstances", ProcessInstanceQueryMapper.get(), new QueryContext(),
     QueryParam.likeTo(COLUMN_PROCESSID, true, "org.jbpm%"),
     QueryParam.in(COLUMN_STATUS, 1, 3));

クエリーサービスでは、取得するデータやフィルターリング方法を定義できます。JPA プロバイダーまたはその他の同様の制限は適用されません。データベースクエリーを環境に調整して、パフォーマンスを向上させることができます。

66.3.7. 高度なクエリーサービス

高度なクエリーサービスは、プロセスおよびタスクの属性、プロセス変数、ユーザータスクの内部変数に基づいて、プロセスおよびタスクを検索する機能を提供します。検索は、プロセスエンジン内の既存のプロセスをすべて自動的に対応します。

属性および変数の名前および必要な値は QueryParam オブジェクトで定義されます。

プロセス属性には、プロセスインスタンス ID、相関キー、プロセス定義 ID、およびデプロイメント ID が含まれます。タスク属性には、タスク名、所有者、ステータスが含まれます。

以下の検索方法を使用できます。

  • queryProcessByVariables: プロセス属性とプロセス変数値のリストをもとにプロセスインスタンスを検索します。その結果に追加するには、プロセスインスタンスに一覧表示される属性と、プロセス変数に一覧表示される値が必要です。
  • queryProcessByVariablesAndTask: プロセス属性、プロセス変数値、タスク変数値のリストをもとにプロセスインスタンスを検索します。その結果に追加するには、プロセスインスタンスに一覧表示される属性と、プロセス変数に一覧表示される値が必要です。また、タスク変数にリストされた値を持つタスクも含める必要があります。
  • queryUserTasksByVariables: タスク属性、タスク変数値、プロセス変数値のリストを基にしてユーザータスクを検索します。結果を含めるには、タスクに、一覧表示される属性と、そのタスク変数に値の一覧が含まれている必要があります。また、プロセス変数に一覧表示された値が含まれるプロセスにも組み込む必要があります。

サービスは AdvanceRuntimeDataService クラスによって提供されます。このクラスのインターフェイスは、事前定義のタスクおよびプロセス属性名も定義します。

AdvanceRuntimeDataService インターフェイスの定義

public interface AdvanceRuntimeDataService {

    String TASK_ATTR_NAME = "TASK_NAME";
    String TASK_ATTR_OWNER = "TASK_OWNER";
    String TASK_ATTR_STATUS = "TASK_STATUS";
    String PROCESS_ATTR_INSTANCE_ID = "PROCESS_INSTANCE_ID";
    String PROCESS_ATTR_CORRELATION_KEY = "PROCESS_CORRELATION_KEY";
    String PROCESS_ATTR_DEFINITION_ID = "PROCESS_DEFINITION_ID";
    String PROCESS_ATTR_DEPLOYMENT_ID = "PROCESS_DEPLOYMENT_ID";
    String PROCESS_COLLECTION_VARIABLES = "ATTR_COLLECTION_VARIABLES";

    List<ProcessInstanceWithVarsDesc> queryProcessByVariables(List<QueryParam> attributes,
      List<QueryParam> processVariables, QueryContext queryContext);

    List<ProcessInstanceWithVarsDesc> queryProcessByVariablesAndTask(List<QueryParam> attributes,
       List<QueryParam> processVariables, List<QueryParam> taskVariables,
       List<String> potentialOwners, QueryContext queryContext);

    List<UserTaskInstanceWithPotOwnerDesc> queryUserTasksByVariables(List<QueryParam> attributes,
       List<QueryParam> taskVariables, List<QueryParam> processVariables,
       List<String> potentialOwners, QueryContext queryContext);
}

66.3.8. プロセスインスタンス移行サービス

プロセスインスタンスの移行サービスは、プロセスインスタンスをあるデプロイメントから別のデプロイメントに移行するユーティリティーです。プロセスまたはタスクの変数は移行の影響を受けません。ただし、新規デプロイメントでは異なるプロセス定義を使用することができます。

プロセス移行の最も簡単な方法として、アクティブなプロセスインスタンスを終了して、新しいデプロイメントで新しいプロセスインスタンスを開始することができます。このアプローチがニーズに適していない場合は、プロセスインスタンスの移行を開始する前に、以下の問題を考慮してください。

  • 後方互換性
  • データ変更
  • ノードのマッピングに必要

可能な場合は、プロセス定義を拡張して後方互換性のプロセスを作成します。たとえば、プロセス定義からノードを削除すると、互換性が失われます。このような変更を加える場合は、ノードマッピングを指定する必要があります。アクティブなプロセスインスタンスが削除されたノードにある場合、プロセスインスタンスの移行は、ノードのマッピングを使用します。

ノードマップには、新規プロセス定義内のターゲットノード ID にマップされた古いプロセス定義のソースノード ID が含まれます。ユーザータスクをユーザータスクへなど、同じタイプのノードのみをマップできます。

Red Hat Process Automation Manager は、移行サービスの実装を複数提供します。

移行サービスを実装する ProcessInstanceMigrationService インターフェイスのメソッド

public interface ProcessInstanceMigrationService {
 /**
 * Migrates a given process instance that belongs to the source deployment into the target process ID that belongs to the target deployment.
 * The following rules are enforced:
 * <ul>
 * <li>the source deployment ID must point to an existing deployment</li>
 * <li>the process instance ID must point to an existing and active process instance</li>
 * <li>the target deployment must exist</li>
 * <li>the target process ID must exist in the target deployment</li>
 * </ul>
 * Returns a migration report regardless of migration being successful or not; examine the report for the outcome of the migration.
 * @param sourceDeploymentId deployment to which the process instance to be migrated belongs
 * @param processInstanceId ID of the process instance to be migrated
 * @param targetDeploymentId ID of the deployment to which the target process belongs
 * @param targetProcessId ID of the process to which the process instance should be migrated
 * @return returns complete migration report
 */
 MigrationReport migrate(String sourceDeploymentId, Long processInstanceId, String targetDeploymentId, String targetProcessId);
 /**
 * Migrates a given process instance (with node mapping) that belongs to source deployment into the target process ID that belongs to the target deployment.
 * The following rules are enforced:
 * <ul>
 * <li>the source deployment ID must point to an existing deployment</li>
 * <li>the process instance ID must point to an existing and active process instance</li>
 * <li>the target deployment must exist</li>
 * <li>the target process ID must exist in the target deployment</li>
 * </ul>
 * Returns a migration report regardless of migration being successful or not; examine the report for the outcome of the migration.
 * @param sourceDeploymentId deployment to which the process instance to be migrated belongs
 * @param processInstanceId ID of the process instance to be migrated
 * @param targetDeploymentId ID of the deployment to which the target process belongs
 * @param targetProcessId ID of the process to which the process instance should be migrated
 * @param nodeMapping node mapping - source and target unique IDs of nodes to be mapped - from process instance active nodes to new process nodes
 * @return returns complete migration report
 */
 MigrationReport migrate(String sourceDeploymentId, Long processInstanceId, String targetDeploymentId, String targetProcessId, Map<String, String> nodeMapping);
 /**
 * Migrates given process instances that belong to the source deployment into a target process ID that belongs to the target deployment.
 * The following rules are enforced:
 * <ul>
 * <li>the source deployment ID must point to an existing deployment</li>
 * <li>the process instance ID must point to an existing and active process instance</li>
 * <li>the target deployment must exist</li>
 * <li>the target process ID must exist in the target deployment</li>
 * </ul>
 * Returns a migration report regardless of migration being successful or not; examine the report for the outcome of the migration.
 * @param sourceDeploymentId deployment to which the process instances to be migrated belong
 * @param processInstanceIds list of process instance IDs to be migrated
 * @param targetDeploymentId ID of the deployment to which the target process belongs
 * @param targetProcessId ID of the process to which the process instances should be migrated
 * @return returns complete migration report
 */
 List<MigrationReport> migrate(String sourceDeploymentId, List<Long> processInstanceIds, String targetDeploymentId, String targetProcessId);
 /**
 * Migrates given process instances (with node mapping) that belong to the source deployment into a target process ID that belongs to the target deployment.
 * The following rules are enforced:
 * <ul>
 * <li>the source deployment ID must point to an existing deployment</li>
 * <li>the process instance ID must point to an existing and active process instance</li>
 * <li>the target deployment must exist</li>
 * <li>the target process ID must exist in the target deployment</li>
 * </ul>
 * Returns a migration report regardless of migration being successful or not; examine the report for the outcome of the migration.
 * @param sourceDeploymentId deployment to which the process instances to be migrated belong
 * @param processInstanceIds list of process instance ID to be migrated
 * @param targetDeploymentId ID of the deployment to which the target process belongs
 * @param targetProcessId ID of the process to which the process instances should be migrated
 * @param nodeMapping node mapping - source and target unique IDs of nodes to be mapped - from process instance active nodes to new process nodes
 * @return returns list of migration reports one per each process instance
 */
 List<MigrationReport> migrate(String sourceDeploymentId, List<Long> processInstanceIds, String targetDeploymentId, String targetProcessId, Map<String, String> nodeMapping);
}

KIE Server のプロセスインスタンスを移行するには、以下の実装を使用します。これらのメソッドは ProcessInstanceMigrationService インターフェイスのメソッドと類似しており、KIE Server デプロイメントに同じ移行実装を提供します。

KIE Server デプロイメントの移行サービスを実装する ProcessAdminServicesClient インターフェイスのメソッド

public interface ProcessAdminServicesClient {

    MigrationReportInstance migrateProcessInstance(String containerId, Long processInstanceId, String targetContainerId, String targetProcessId);

    MigrationReportInstance migrateProcessInstance(String containerId, Long processInstanceId, String targetContainerId, String targetProcessId, Map<String, String> nodeMapping);

    List<MigrationReportInstance> migrateProcessInstances(String containerId, List<Long> processInstancesId, String targetContainerId, String targetProcessId);

    List<MigrationReportInstance> migrateProcessInstances(String containerId, List<Long> processInstancesId, String targetContainerId, String targetProcessId, Map<String, String> nodeMapping);
}

1 つのプロセスインスタンスまたは複数のプロセスインスタンスを一度に移行することができます。複数のプロセスインスタンスを移行する場合は、各インスタンスを別のトランザクションに移行し、移行が相互に影響しないようにします。

移行が完了すると、migrate メソッドは以下の情報が含まれる MigrationReport オブジェクトを返します。

  • 移行の開始日および終了日。
  • 移行の結果 (成功または失敗)。
  • INFOWARN、または ERROR タイプのログエントリー。ERROR メッセージは移行を終了します。

プロセスインスタンスの移行の例を以下に示します。

KIE Server デプロイメントのプロセスインスタンスの移行

import org.kie.server.api.model.admin.MigrationReportInstance;
import org.kie.server.api.marshalling.MarshallingFormat;
import org.kie.server.client.KieServicesClient;
import org.kie.server.client.KieServicesConfiguration;

public class ProcessInstanceMigrationTest{

	private static final String SOURCE_CONTAINER = "com.redhat:MigrateMe:1.0";
  private static final String SOURCE_PROCESS_ID = "MigrateMe.MigrateMev1";
	private static final String TARGET_CONTAINER = "com.redhat:MigrateMe:2";
  private static final String TARGET_PROCESS_ID = "MigrateMe.MigrateMeV2";

	public static void main(String[] args) {

		KieServicesConfiguration config = KieServicesFactory.newRestConfiguration("http://HOST:PORT/kie-server/services/rest/server", "USERNAME", "PASSWORD");
		config.setMarshallingFormat(MarshallingFormat.JSON);
		KieServicesClient client = KieServicesFactory.newKieServicesClient(config);

		long sourcePid = client.getProcessClient().startProcess(SOURCE_CONTAINER, SOURCE_PROCESS_ID);

    // Use the 'report' object to return migration results.
		MigrationReportInstance report = client.getAdminClient().migrateProcessInstance(SOURCE_CONTAINER, sourcePid,TARGET_CONTAINER, TARGET_PROCESS_ID);

		System.out.println("Was migration successful:" + report.isSuccessful());

		client.getProcessClient().abortProcessInstance(TARGET_CONTAINER, sourcePid);

	}
}

プロセスインスタンス移行の既知の制限

以下の状況では、移行の失敗や移行の誤った状況が発生する可能性があります。

  • 新規または変更されたタスクには、移行したプロセスインスタンスでは利用できない入力が必要です。
  • 変更がさらなる処理に影響を与えるアクティブなタスクの前にタスクを変更します。
  • 現在アクティブなヒューマンタスクを削除します。ヒューマンタスクを置き換えるには、別のヒューマンタスクにマップする必要があります。
  • 単一のアクティブなタスクと並行して新しいタスクを追加します。AND ゲートウェイのすべての分岐がアクティブになっていないため、プロセスは停止します。
  • アクティブなタイマーイベントを削除します (これらのイベントはデータベースでは変更しません)。
  • アクティブなタスクでの入力および出力を修正または更新します (タスクデータは移行されません)。

タスクノードへのマッピングを適用する場合は、タスクノード名と説明のみがマッピングされます。TaskName 変数を含む他のタスクフィールドは、新規タスクにマップされません。

66.3.9. デプロイメントおよび異なるプロセスバージョン

デプロイメントサービスは、ビジネスアセットを実行環境に配置します。ただし、場合によっては、正しいコンテキストでアセットを使用できるようにするために追加の管理が必要になる場合があります。特に、同じプロセスを複数バージョンにデプロイする場合は、プロセスインスタンスが正しいバージョンを使用するようにする必要があります。

デプロイメントのアクティブ化および非アクティブ化

ケースによっては、デプロイメントで複数のプロセスインスタンスが実行し、ランタイム環境に同じプロセスの新しいバージョンを追加する場合があります。

既存のアクティブなインスタンスが以前のバージョンを続行する必要がある間、このプロセス定義の新規インスタンスは新しいバージョンを使用する必要があります。

このシナリオを有効にするには、デプロイメントサービスの以下の方法を使用します。

  • activate: 対話に使用できるデプロイメントを有効にします。そのプロセス定義を一覧表示し、このデプロイメントの新規プロセスインスタンスを開始できます。
  • deactivate: デプロイメントを非アクティブにします。プロセス定義を一覧表示し、デプロイメント内のプロセスの新規プロセスインスタンスを開始するオプションを無効にします。ただし、シグナルイベントやユーザータスクとの対話など、すでにアクティブなプロセスインスタンスを引き続き使用できます。

この機能を使用して、プロセスインスタンスの移行を必要とせずに、プロジェクトバージョン間のスムーズな移行を行うことができます。

プロセスの最新バージョンの呼び出し

プロジェクトのプロセスの最新版を使用する必要がある場合は、latest のキーワードを使用して、サービス内の複数の操作と対話することができます。このアプローチは、全バージョンでプロセス ID が同じままである場合にのみサポートされます。

以下の例では、機能について説明します。

最初のデプロイメントユニットは org.jbpm:HR:1.0 です。これには、採用プロセスの最初のバージョンが含まれています。

数週間後、新しいバージョンを開発し、org.jbpm:HR.2.0 として実行サーバーにデプロイします。これには、採用プロセスのバージョン 2 が含まれています。

プロセスを呼び出して最新バージョンを使用する場合は、以下のデプロイメント ID を使用することができます。

org.jbpm.HR:latest

このデプロイメント ID を使用する場合、プロセスエンジンは、プロジェクトの利用可能な最新バージョンを見つけます。以下の識別子を使用します。

  • groupId: org.jbpm
  • artifactId: HR

バージョン番号は、Maven ルールによって照合され、最新バージョンを見つけることができます。

以下のコード例は、複数のバージョンのデプロイメントと最新バージョンの操作を示しています。

プロセスの複数のバージョンをデプロイし、最新バージョンと対話する

KModuleDeploymentUnit deploymentUnitV1 = new KModuleDeploymentUnit("org.jbpm", "HR", "1.0");
deploymentService.deploy(deploymentUnitV1);

long processInstanceId = processService.startProcess("org.jbpm:HR:LATEST", "customtask");
ProcessInstanceDesc piDesc = runtimeDataService.getProcessInstanceById(processInstanceId);

// We have started a process with the project version 1
assertEquals(deploymentUnitV1.getIdentifier(), piDesc.getDeploymentId());

// Next we deploy version 2
KModuleDeploymentUnit deploymentUnitV2 = new KModuleDeploymentUnit("org.jbpm", "HR", "2.0");
deploymentService.deploy(deploymentUnitV2);

processInstanceId = processService.startProcess("org.jbpm:HR:LATEST", "customtask");
piDesc = runtimeDataService.getProcessInstanceById(processInstanceId);

// This time we have started a process with the project version 2
assertEquals(deploymentUnitV2.getIdentifier(), piDesc.getDeploymentId());

注記

この機能は、KIE Server REST API でも利用できます。デプロイメント ID でリクエストを送信する場合は、LATEST をバージョン識別子として使用できます。

66.3.10. デプロイメントの同期

プロセスエンジンサービスには、すべてのデプロイメントのデプロイメント記述子を含め、使用可能なデプロイメントをデータベースに格納するデプロイメントシンクロナイザーが含まれています。

また、シンクロナイザーはこのテーブルを監視して、同じデータソースを使用している可能性のある他のインストールと同期させます。この機能は、クラスターで実行している場合や、Business Central とカスタムアプリケーションが同じアーティファクト上で動作する必要がある場合に特に重要です。

デフォルトでは、コアサービスを実行する場合は同期を設定する必要があります。EJB および CDI の拡張機能では、同期は自動的に有効になります。

以下のコードサンプルは同期を設定します。

同期の設定

TransactionalCommandService commandService = new TransactionalCommandService(emf);

DeploymentStore store = new DeploymentStore();
store.setCommandService(commandService);

DeploymentSynchronizer sync = new DeploymentSynchronizer();
sync.setDeploymentService(deploymentService);
sync.setDeploymentStore(store);

DeploymentSyncInvoker invoker = new DeploymentSyncInvoker(sync, 2L, 3L, TimeUnit.SECONDS);
invoker.start();
....
invoker.stop();

この設定では、デプロイメントは 3 秒ごとに同期され、初期の遅延は 2 秒となっています。