68.4. EJB との統合
プロセスエンジンは、Enterprise Java Bean (EJB) の完全な統合レイヤーを提供します。このレイヤーは、ローカルおよびリモートの EJB 対話の両方をサポートします。
以下のモジュールは EJB サービスを提供します。
-
jbpm-services-ejb-api
:jbpm-services-api
モジュールを EJB 固有のインターフェイスおよびオブジェクトで拡張する API モジュール -
jbpm-services-ejb-impl
: コアサービスの EJB 拡張 -
jbpm-services-ejb-timer
: EJB Timer サービスに基づくプロセスエンジンスケジューラーサービスの実装 -
jbpm-services-ejb-client
: デフォルトでは Red Hat JBoss EAP をサポートするリモート対話の EJB リモートクライアント実装
EJB レイヤーはプロセスエンジンサービスに基づいています。リモートインターフェイスを使用する場合はいくつかの制限がありますが、コアモジュールとほぼ同じ機能を提供します。
デプロイメントサービスの主な制限は、リモート EJB サービスとして使用されている場合に、以下の方法のみをサポートします。
-
deploy()
-
undeploy()
-
activate()
-
deactivate()
-
isDeployed()
他のメソッドは、リモートインターフェイスに使用できない RuntimeManager
などのランタイムオブジェクトのインスタンスを返すため除外されます。
他のすべてのサービスは、コアモジュールに含まれているバージョンと同じ機能を EJB 上で提供します。
68.4.1. EJB サービスの実装
プロセスエンジンのコアサービスの拡張として、EJB サービスは EJB ベースの実行セマンティクスを提供し、さまざまな EJB 固有の機能をベースにしています。
-
DeploymentServiceEJBImpl
は、コンテナー管理の同時実行性を備えた EJB シングルトンとして実装されます。ロックタイプはwrite
に設定されます。 -
DefinitionServiceEJBImpl
は、コンテナー管理の同時実行性を備えた EJB シングルトンとして実装されます。この全体的なロックタイプはread
に設定されます。buildProcessDefinition()
メソッドの場合は ロックタイプがwrite
に設定されます。 -
ProcessServiceEJBImpl
は、ステートレスセッション Bean として実装されます。 RuntimeDataServiceEJBImpl
は、EJB シングルトンとして実装されます。ほとんどのメソッドでは、ロックタイプがread
に設定されます。以下のメソッドでは、ロックタイプがwrite
に設定されます。-
onDeploy()
-
onUnDeploy()
-
onActivate()
-
onDeactivate()
-
-
UserTaskServiceEJBImpl
は、ステートレスセッション Bean として実装されます。
トランザクション
EJB コンテナーは EJB サービスでトランザクションを管理します。このため、アプリケーションコード内でトランザクションマネージャーまたはユーザートランザクションを設定する必要はありません。
アイデンティティープロバイダー
デフォルトのアイデンティティープロバイダーは EJBContext
インターフェイスをベースとし、名前とロールの両方に呼び出し元プリンシパル情報に依存します。IdentityProvider
インターフェイスは、ロールに関連する 2 つのメソッドを提供します。
-
EJBContext
インターフェイスは特定ユーザーの全ロールを取得するオプションを提供しないため、getRoles()
によって空のリストが返されます。 -
hasRole()
はコンテキストのisCallerInRole()
メソッドに委譲されます。
EJB 環境で有効な情報を利用できるようにするには、標準の JEE セキュリティープラクティスに従ってユーザーを認証および承認する必要があります。EJB サービスに認証または承認が設定されていない場合、匿名ユーザーは常に仮定されます。
別のセキュリティーモデルを使用する場合は、EJB サービスの IdentityProvider
オブジェクトに CDI 形式の挿入を使用できます。この場合は、org.kie.internal.identity.IdentityProvider
インターフェイスを実装する有効な CDI Bean を作成し、アプリケーションでの挿入でこの Bean を利用できるようにします。この実装は、EJBContext
ベースのアイデンティティープロバイダーよりも優先されます。
デプロイメントの同期
デプロイメントの同期はデフォルトで有効になり、3 秒ごとにすべてのデプロイメントの同期を試みます。コンテナー管理コンカレンシーを使用する EJB シングルトンとして実装されます。ロックタイプは write
に設定されます。EJB タイマーサービスを使用して同期ジョブをスケジュールします。
EJB スケジューラーサービス
プロセスエンジンは、スケジューラーサービスを使用してタイマーイベントやデッドラインなどの時間ベースのアクティビティーを処理します。EJB 環境で実行する場合、プロセスエンジンは EJB タイマーサービスに基づいてスケジューラーを使用します。すべての RuntimeManager
インスタンスに対してこのスケジューラーを登録します。
クラスター操作に対応するためにアプリケーションサーバーに固有の設定を使用しないといけない場合があります。
UserGroupCallback
および UserInfo
実装の選択
UserGroupCallback
インターフェイスおよび UserInfo
インターフェイスに必要な実装は、さまざまなアプリケーションで異なる場合があります。これらのインターフェイスに EJB を直接挿入することはできません。以下のシステムプロパティーを使用して、既存の実装を選択するか、プロセスエンジンにこれらのインターフェイスのカスタム実装を使用できます。
org.jbpm.ht.callback
: このプロパティーは、UserGroupCallback
インターフェイスの実装を選択します。-
mvel
: 通常、テストに使用するデフォルトの実装です。 -
ldap
: LDAP ベースの実装。この実装には、jbpm.usergroup.callback.properties
ファイルで追加の設定が必要です。 -
db
: データベースベースの実装。この実装には、jbpm.usergroup.callback.properties
ファイルで追加の設定が必要です。 -
jaas
: コンテナーからユーザー情報を要求する実装。 -
props
: 単純なプロパティーベースのコールバック。この実装には、ユーザーおよびグループすべてが含まれる追加のプロパティーファイルが必要です。 -
custom
: カスタム実装。実装の完全修飾クラス名をorg.jbpm.ht.custom.callback
システムプロパティーに指定する必要があります。
-
org.jbpm.ht.userinfo
: このプロパティーはUserInfo
インターフェイスの実装を選択します。-
ldap
: LDAP ベースの実装。この実装には、jbpm-user.info.properties
ファイルで追加の設定が必要です。 -
db
: データベースベースの実装。この実装には、jbpm-user.info.properties
ファイルで追加の設定が必要です。 -
props
: 単純なプロパティーベースの実装。この実装には、すべてのユーザー情報が含まれる追加のプロパティーファイルが必要です。 -
custom
: カスタム実装。実装の完全修飾クラス名をorg.jbpm.ht.custom.userinfo
システムプロパティーに指定する必要があります。
-
通常、アプリケーションサーバーまたは JVM の起動時にシステムプロパティーを設定します。サービスを使用する前に、コードでプロパティーを設定することもできます。たとえば、これらのシステムプロパティーを設定するカスタムの @Startup
Bean を指定できます。
68.4.2. ローカル EJB インターフェイス
以下のローカル EJB サービスインターフェイスはコアサービスを拡張します。
-
org.jbpm.services.ejb.api.DefinitionServiceEJBLocal
-
org.jbpm.services.ejb.api.DeploymentServiceEJBLocal
-
org.jbpm.services.ejb.api.ProcessServiceEJBLocal
-
org.jbpm.services.ejb.api.RuntimeDataServiceEJBLocal
-
org.jbpm.services.ejb.api.UserTaskServiceEJBLocal
これらのインターフェイスを挿入ポイントとして使用し、@EJB
アノテーションを付ける必要があります。
ローカルの EJB サービスインターフェイスの使用
@EJB private DefinitionServiceEJBLocal bpmn2Service; @EJB private DeploymentServiceEJBLocal deploymentService; @EJB private ProcessServiceEJBLocal processService; @EJB private RuntimeDataServiceEJBLocal runtimeDataService;
これらのインターフェイスを挿入した後に、コアモジュールと同じ方法で操作を呼び出します。ローカルインターフェイスの使用には制限がありません。
68.4.3. リモート EJB インターフェイス
以下の専用のリモート EJB インターフェイスはコアサービスを拡張します。
-
org.jbpm.services.ejb.api.DefinitionServiceEJBRemote
-
org.jbpm.services.ejb.api.DeploymentServiceEJBRemote
-
org.jbpm.services.ejb.api.ProcessServiceEJBRemote
-
org.jbpm.services.ejb.api.RuntimeDataServiceEJBRemote
-
org.jbpm.services.ejb.api.UserTaskServiceEJBRemote
これらのインターフェイスは、カスタムタイプの処理を除き、ローカルインターフェイスと同じ方法で使用できます。
カスタムタイプは 2 つの方法で定義できます。グローバル に定義されたタイプは、アプリケーションクラスパスで利用でき、エンタープライズアプリケーションに含まれます。ローカルでデプロイメントユニット にタイプを定義する場合、タイプはプロジェクトの依存関係 (KJAR ファイルなど) で宣言され、デプロイメント時に解決されます。
グローバルで利用可能なタイプには、特別な処理は必要ありません。EJB コンテナーは、リモートリクエストの処理時にデータを自動的にマーシャルします。ただし、ローカルカスタムタイプは、デフォルトでは EJB コンテナーに表示されません。
プロセスエンジン EJB サービスは、カスタムタイプと連携するメカニズムを提供します。他にも、以下の 2 つのタイプが提供されます。
-
org.jbpm.services.ejb.remote.api.RemoteObject
: シングル値パラメーターのシリアライズ可能なラッパークラス org.jbpm.services.ejb.remote.api.RemoteMap
: カスタムオブジェクト入力を受け入れるサービスメソッドのリモート呼び出しを単純化する専用のjava.util.Map
実装。マップの内部実装は、送信時に追加のシリアライズを回避するために、すでにシリアライズされているコンテンツを保持します。この実装には、通常データ送信時には使用されない
java.util.Map
のメソッドが含まれません。
これらの特別なオブジェクトは、ObjectInputStream
オブジェクトを使用してバイトに対してシリアライズを実行します。EJB クライアント/コンテナーでのデータのシリアライズに必要なものを削除します。シリアライズは必要ないため、カスタムデータモデルを EJB コンテナーと共有する必要はありません。
以下のコード例は、ローカルタイプおよびリモート EJB サービスと動作します。
リモート EJB サービスでのローカルタイプの使用
// Start a process with custom types via remote EJB Map<String, Object> parameters = new RemoteMap(); Person person = new org.jbpm.test.Person("john", 25, true); parameters.put("person", person); Long processInstanceId = processService.startProcess(deploymentUnit.getIdentifier(), "custom-data-project.work-on-custom-data", parameters); // Fetch task data and complete a task with custom types via remote EJB Map<String, Object> data = userTaskService.getTaskInputContentByTaskId(taskId); Person fromTaskPerson = data.get("_person"); fromTaskPerson.setName("John Doe"); RemoteMap outcome = new RemoteMap(); outcome.put("person_", fromTaskPerson); userTaskService.complete(taskId, "john", outcome);
同様に、RemoteObject
クラスを使用してイベントをプロセスインスタンスに送信できます。
// Send an event with a custom type via remote EJB Person person = new org.jbpm.test.Person("john", 25, true); RemoteObject myObject = new RemoteObject(person); processService.signalProcessInstance(processInstanceId, "MySignal", myObject);
68.4.4. リモート EJB クライアント
リモートクライアントサポートは、アプリケーションサーバー固有のコード向けのファサードである ClientServiceFactory
インターフェイスの実装によって提供されます。
ClientServiceFactory
インターフェイスの定義
/** * Generic service factory used for remote lookups that are usually container specific. * */ public interface ClientServiceFactory { /** * Returns unique name of given factory implementation * @return */ String getName(); /** * Returns remote view of given service interface from selected application * @param application application identifier on the container * @param serviceInterface remote service interface to be found * @return * @throws NamingException */ <T> T getService(String application, Class<T> serviceInterface) throws NamingException; }
ServiceLoader
メカニズムを使用して実装を動的に登録できます。デフォルトでは、Red Hat JBoss EAP で利用可能な実装は 1 つだけです。
各 ClientServiceFactory
実装は名前を指定する必要があります。この名前は、クライアントレジストリー内で登録するために使用されます。名前で実装を検索できます。
以下のコードは、デフォルトの Red Hat JBoss EAP リモートクライアントを取得します。
デフォルトの Red Hat JBoss EAP リモートクライアントの取得
// Retrieve a valid client service factory ClientServiceFactory factory = ServiceFactoryProvider.getProvider("JBoss"); // Set the application variable to the module name String application = "sample-war-ejb-app"; // Retrieve the required service from the factory DeploymentServiceEJBRemote deploymentService = factory.getService(application, DeploymentServiceEJBRemote.class);
サービスを取得したら、そのメソッドを使用できます。
Red Hat JBoss EAP とリモートクライアントを使用する際に、以下の Maven 依存関係を追加して、すべての EJB クライアントライブラリーを取り込むことができます。
<dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-ejb-client-bom</artifactId> <version>7.3.0.Final</version> <!-- use the valid version for the server you run on --> <optional>true</optional> <type>pom</type> </dependency>