9.3. Fuse Online エクステンションの開発
Fuse Online がインテグレーションの作成に必要な機能を提供しない場合、開発者が必要な動作を提供するエクステンションを作成することができます。Syndesis エクステンションリポジトリー https://github.com/syndesisio/syndesis-extensions にエクステンションの例が含まれています。
ビジネスインテグレーターは、エクステンションを作成する開発者と要件を共有します。開発者は、エクステンションが含まれる .jar
ファイルを提供します。ビジネスインテグレーターは Fuse Online に .jar
ファイルをアップロードして、カスタムコネクター、カスタムステップ、またはライブラリーリソースを Fuse Online で使用できるようにします。
Red Hat Developer Studio への Fuse Tooling プラグインは、ステップのエクステンションまたはコネクターのエクステンションの開発に役立つウィザードを提供します。Developer Studio またはその他の IDE で、ステップエクステンションまたはコネクターエクステンションを開発するかどうかは、個人的に選択できます。Developer Studio プラグインの使用に関する詳細は、Developing extensions for Fuse Online integrations を参照してください。
選択した IDE でエクステンションを開発するための手順の概要、要件の説明、および追加の例については以下を参照してください。
9.3.1. エクステンション開発の一般的な手順
エクステンションの開発を開始する前に、実行する必要のあるタスクについて理解しておく必要があります。
前提条件
インテグレーション Pod は、フラットなクラスパスを持つ Java プロセスで実行されます。バージョンの競合を避けるため、エクステンションが使用する依存関係が、以下のすべてのソースからインポートされた BOM (Bill of Materials) に対応することを確認してください。
-
org.springframework.boot:spring-boot-dependencies:$SPRING_BOOT_VERSION
-
org.apache.camel:camel-spring-boot-dependencies:$CAMEL_VERSION
-
io.syndesis.integration:integration-bom:$syndesis_VERSION
インポートされた BOM の一部ではない追加の依存関係がある場合、以下を行う必要があります。
-
lib
ディレクトリーにあるエクステンション JAR ファイルでパッケージ化する必要があります。 -
エクステンションの JSON 記述子ファイルの
dependencies
プロパティーから省略します。
手順
- 拡張された機能の動作の理解します。機能要件を理解するために、ビジネスの関係者と話し合います。
- ステップエクステンション、コネクターエクステンション、またはライブラリーエクステンションを開発する必要があるかどうかを判断します。
- エクステンションを開発する Maven プロジェクトを設定します。
ステップエクステンションを開発する場合は以下を行います。
-
Camel ルートとして実装するか、または Syndesis
Step
API を使用して実装するかを決定します。Syndesis API に関する情報は http://javadoc.io/doc/io.syndesis.extension/extension-api を参照してください。 -
Camel ルートとしてエクステンションを実装する場合は、XML フラグメント、
RouteBuilder
クラス、または Bean を実装するかどうかを決定します。 -
Maven プロジェクトで、
schemaVersion
、エクステンションname
、extensionId
などの必要なメタデータを指定します。
-
Camel ルートとして実装するか、または Syndesis
- 機能を実装するクラスを作成します。
-
依存関係をプロジェクトの
pom.xml
ファイルに追加します。 コネクターおよびライブラリーエクステンションと、XML に実装するステップエクステンションに、エクステンションを定義する JSON ファイルを作成します。
Java に実装するステップエクステンションでは、Maven プロジェクトで対応するデータ構造の値を指定するときに Maven は JSON エクステンション定義ファイルを生成できます。
- Maven を実行してエクステンションを構築し、エクステンションの JAR ファイルを作成します。
- JAR ファイルを Fuse Online 開発環境にアップロードして、エクステンションをテストします。
- エクステンションをパッケージ化する JAR ファイルを Fuse Online 本番環境にアップロードするビジネス関係者に、そのファイルを提供します。JAR ファイルを提供するときに、Fuse Online の Web インターフェイスに表示される情報以外の設定について、ビジネス関係者に説明します。
9.3.2. エクステンションの種類の説明
エクステンションは以下のいずれかを定義します。
- コネクション間のインテグレーションデータを操作する 1 つ以上のカスタムステップ。各カスタムステップは 1 つのアクションを実行します。これは、ステップエクステンションです。
- インテグレーションランタイムが使用するライブラリーリソース。たとえば、ライブラリーエクステンションは、Oracle などのプロプライエタリー SQL データベースに接続するための JDBC ドライバーを提供できます。
統合する特定のアプリケーションまたはサービスへのコネクションを作成するための単一のカスタムコネクター。これは、コネクターエクステンションです。
注記Fuse Online は OpenAPI ドキュメントを使用して REST API クライアントのコネクターを作成できます。REST API クライアントコネクターの開発 を参照してください。
ビジネスインテグレーターは、エクステンションを作成する開発者と要件を共有します。開発者は、エクステンションが含まれる .jar
ファイルを提供します。ビジネスインテグレーターは Fuse Online で .jar
ファイルをアップロードし、カスタムコネクター、カスタムステップ、または Fuse Online 内で使用できるライブラリーリソースを作成します。
Fuse Online にアップロードするエクステンション .jar
ファイルには、常に 1 つのエクステンションが含まれます。
コネクション間のデータを操作するステップを提供するエクステンションのアップロード例および使用例については、 AMQ から REST API へのサンプルインテグレーションのチュートリアル を参照してください。
9.3.3. エクステンションコンテンツおよび構造の概要
エクステンションとは、.jar
ファイルにパッケージ化されるクラス、依存関係、およびリソースのコレクションです。
Fuse Online は Spring Boot を使用してエクステンションをロードします。そのため、Spring Boot の実行可能な JAR 形式に従い、エクステンションをパッケージ化する必要があります。たとえば、ZipEntry.STORED()
を使用して、ネストされた JAR ファイルを保存するようにします。
エクステンションをパッケージ化する .jar
ファイルの構造は次のとおりです。
extension.jar | +- META-INF | | | +- syndesis | | | +- syndesis-extension-definition.json 1 | +- mycompany | | | +-project | | | +-YourClasses.class 2 | +- lib 3 | +-dependency1.jar | +-dependency2.jar
9.3.4. エクステンション定義の JSON ファイルの要件
各エクステンションには、名前、説明、サポートされるアクション、依存関係などのデータ構造の値を指定してエクステンションを定義する .json
ファイルが必要です。以下の表は、Maven がエクステンション定義 JSON ファイルを生成するかどうかと、必要になるデータ構造をエクステンションタイプ別に示しています。
エクステンションタイプ | Maven によるエクステンション定義の生成 | 必要なデータ構造 |
---|---|---|
Java のステップエクステンション | 可能 |
|
XML のステップエクステンション | 不可能 |
|
コネクターエクステンション | いいえ |
|
ライブラリーエクステンション | 不可能 |
|
* dependencies
の指定は必ずしも必要ではありませんが、ほとんどの場合で指定する必要がある依存関係があります。
通常、エクステンション定義ファイルのレイアウトは次のようになります。
{ "schemaVersion": "v1", "name": "", "description": "", "version": "", "extensionId": "", "extensionType": "", "properties": { }, "actions": [ ], "dependencies": [ ], }
- schemaVersion は、エクステンション定義スキーマのバージョンを定義します。Syndesis は内部的に schemaVersion を使用して、エクステンション定義を内部モデルにマップする方法を決定します。これにより、古いバージョンの Syndesis に対して開発されたエクステンションを、より新しいバージョンの Syndesis にデプロイすることが可能になります。
- name は、エクステンションの名前です。Fuse Online にエクステンションをアップロードするときに、この名前が表示されます。
- description は、指定する便利な情報です。Fuse Online はこの値を操作しません。
- version は、エクステンションへの更新を区別するのに便利です。Fuse Online はこの値を操作しません。
- extensionId は、エクステンションの一意の ID を定義します。これは、少なくとも Syndesis 環境全体で一意である必要があります。
extensionType は、エクステンションが提供するものを Syndesis に示します。Syndesis バージョン 1.3 時点で、以下のエクステンションタイプがサポートされます。
-
Steps
-
コネクター
-
Libraries
-
コネクターエクステンションのトップレベルで properties が必要です。このオブジェクトは、Fuse Online ユーザーがコネクターを選択してコネクションを作成する時に Fuse Online で何を表示するかを制御します。この
properties
オブジェクトには、コネクションを作成するための各フォームコントロールのプロパティーセットが含まれます。以下は例になります。"myControlName": { "deprecated": true|false, "description": "", "displayName": "", "group": "", "kind": "", "label": "", "required": true|false, "secret": true|false, "javaType": "", "type": "", "defaultValue": "", "enum": { } }
コネクターエクステンションでは、ネストされた
properties
オブジェクトはコネクションアクションを設定するための HTML フォームコントロールを定義します。ステップエクステンションでは、actions
オブジェクトにproperties
オブジェクトが含まれます。properties
オブジェクトは、ステップを設定するための各フォームコントロールのプロパティーセットを定義します。ユーザーインターフェイスプロパティーの説明 も参照してください。actions はコネクターが実行できるオペレーションや、コネクション間のステップが実行できるオペレーションを定義します。コネクターおよびステップエクステンションのみが指定するアクションを使用します。アクションの指定形式は以下のようになります。
{ "id": "", "name": "", "description": "", "actionType": "step|connector", "descriptor": { } }
- id は、アクションの一意の ID です。これは、少なくとも Syndesis 環境内で一意である必要があります。
- name は、Fuse Online に表示されるアクション名です。インテグレーターは、この値をコネクションアクションの名前またはコネクション間のインテグレーションデータを操作するステップの名前として解釈します。
- description は、Fuse Online に表示されるアクションの説明です。インテグレーターがアクションの動作を理解するよう、このフィールドを使用します。
- actionType は、アクションがコネクションまたはコネクション間のステップによって実行されるかどうかを示します。
-
descriptor は、
kind
、entrypoint
、inputDataType
、outputDatatype
などのネストされた属性を指定します。
dependencies は、このエクステンションが必要とする Fuse Online が提供するリソースを定義します。
以下のように依存関係を定義します。
{ "type": "MAVEN", "id" : "org.apache.camel:camel-telegram:jar:2.21.0" }
- type は依存関係のタイプを示します。MAVEN を指定します。(他のタイプは今後サポートされる予定です)
- id は、Maven 依存関係 (Maven GAV) の ID です。
9.3.5. ユーザーインターフェイスプロパティーの説明
コネクターエクステンションおよびステップエクステンションで、エクステンション定義 JSON ファイルまたは Java クラスファイルにユーザーインターフェイスプロパティーを指定します。これらのプロパティーの設定は、Fuse Online ユーザーがコネクションの作成、コネクションアクションの設定、またはエクステンションによって提供されるステップの設定を行うときに Fuse Online が表示する HTML フォームコントロールを定義します。
Fuse Online コンソールのエクステンションのユーザーインターフェイスに表示する各フォームコントロールのプロパティーを指定する必要があります。各フォームコントロールで、一部またはすべてのプロパティーを任意の順序で指定します。
ユーザーインターフェイスプロパティーの指定例
IRC コネクターの一部である JSON ファイルでは、トップレベルの properties
オブジェクトは、Fuse Online ユーザーがコネクションを作成するための IRC コネクターを選択した後に HTML フォームコントロールを定義します。3 つのフォームコントロールには、hostname
、password
、および port
の 3 つのセットのプロパティー定義があります。
"properties": { "hostname": { "description": "IRC Server hostname", "displayName": "Hostname", "labelHint": "Hostname of the IRC server to connect to", "order": "1", "required": true, "secret": false, "type": "string" }, "password": { "description": "IRC Server password", "displayName": "Password", "labelHint": "Required if IRC server requires it to join", "order": "3", "required": false, "secret": true, "type": "string" }, "port": { "description": "IRC Server port", "displayName": "Port", "labelHint": "Port of the IRC server to connect to", "order": "2", "required": true, "secret": false, "tags": [], "type": "int" } },
これらのプロパティー指定を基にして、Fuse Online ユーザーが IRC コネクターを選択すると、Fuse Online に以下のダイアログが表示されます。ユーザーが 2 つの必須フィールドに値を入力し、Next をクリックすると、Fuse Online は Fuse Online ユーザーが入力する値で IRC コネクションを作成します。
エクステンション定義 JSON ファイルの properties
オブジェクト
コネクターエクステンションでは以下が行われます。
-
トップレベルの
properties
オブジェクトが必要です。このオブジェクトは、Fuse Online ユーザーがコネクターを選択してコネクションを作成する時に Fuse Online で何を表示するかを制御します。このproperties
オブジェクトには、コネクションを作成するための各フォームコントロールのプロパティーセットが含まれます。 -
action
オブジェクトでは、アクションごとにproperties
オブジェクトがあります。これらのproperties
オブジェクトごとに、そのアクションを設定するための各フォームコントロールのプロパティーセットがあります。
ステップエクステンションでは、actions
オブジェクトに properties
オブジェクトが含まれます。properties
オブジェクトは、ステップを設定するための各フォームコントロールのプロパティーセットを定義します。JSON 階層は、以下のようになります。
"actions": [ { ... "propertyDefinitionSteps": [ { ... "properties": { "control-ONE": { "type": "string", "displayName": "Topic Name", "order": "2", ..., } "control-TWO": { "type": "boolean", "displayName": "Urgent", "order": "3", ... } "control-THREE": { "type": "textarea", "displayName": "Comment", "order": "1", ..., } } } ]
Java ファイルのユーザーインターフェイスプロパティー
Java ファイルでユーザーインターフェイスのフォームコントロールを定義するには、コネクション、アクション、またはステップのユーザー設定を定義する各クラスファイルに io.syndesis.extension.api.annotations.ConfigurationProperty
をインポートします。Fuse Online コンソールが表示する各フォームコントロールに対して、@ConfigurationProperty
アノテーションと後続のプロパティーリストを指定します。指定できるプロパティーに関する詳細は、このセクションの最後にあるユーザーインターフェイスプロパティーの参照テーブルを参照してください。
以下のコードは、単一のフォームコントロールのプロパティー定義を表しています。このコードは、RouteBuilder
で Camel ルートを開発する例になります。
public class LogAction extends RouteBuilder { @ConfigurationProperty( name = "prefix", description = "The Log body prefix message", displayName = "Log Prefix", type = "string")
以下のコードは、2 つのコントロールのプロパティー定義を表しています。このコードは、Syndesis Step API をした例です。
@Action(id = "split", name = "Split", description = "Split your exchange") public class SplitAction implements Step { @ConfigurationProperty( name = "language", displayName = "Language", description = "The language used for the expression") private String language; @ConfigurationProperty( name = "expression", displayName = "Expression", description = "The expression used to split the exchange private String language;
コントロールフォーム入力ファイルの説明
各 HTML フォームコントロールのプロパティーセットでは、type
プロパティーが Fuse Online が表示するフォームコントロールの入力タイプを定義します。HTML フォームの入力タイプに関する詳細は、https://www.w3schools.com/html/html_form_input_types.asp を参照してください。
以下の表に、Fuse Online フォームコントロールの可能な入力タイプを示します。制御のプロパティーのセットで、不明な type
の値を指定すると、Fuse Online は 1 行のテキストを許可する入力フィールドを表示します。デフォルトは "type": "text"
です。
type プロパティーの値 | HTML | Fuse Online が表示するもの |
---|---|---|
|
| ユーザーが選択可能または不可能なチェックボックス。 |
|
Fuse Online ユーザーが時間の単位を選択できるようにするカスタム制御。ミリ秒、秒、分、時、または日を選択できます。また、ユーザーは番号を入力し、Fuse Online はミリ秒数を返します。例: | |
|
| このフィールドは Fuse Online コンソールに表示されません。他のプロパティーを使用して、テキストデータなどのこのフィールドに関連するデータを指定できます。Fuse Online ユーザーはこのデータを表示または変更できませんが、ユーザーが Fuse Online ページの View Source を選択すると、ソース表示に非表示のフィールドが表示されます。そのため、セキュリティーの目的で非表示フィールドを使用しないでください。 |
|
| 数字を許可する入力フィールドです。 |
|
| ユーザーが入力する文字を通常はアスタリスクでマスクする入力フィールド。 |
|
|
フォームコントロールの |
|
| 1 行のテキストを許可する入力フィールド。 |
|
| textarea 要素が使用されます。 |
コントロールフォームのユーザーインターフェイスプロパティーの説明
コネクターまたはステップエクステンションでは、Fuse Online コンソールに表示される各 HTML フォームコントロールに対して、以下の表に説明があるプロパティーを 1 つ以上指定できます。HTML フォームの入力タイプに関する詳細は、https://www.w3schools.com/html/html_form_input_types.asp を参照してください。
プロパティー名 | タイプ | 説明 |
---|---|---|
| string | Fuse Online が表示するフォームコントロールの種類を制御します。詳細は、前述の表を参照してください。 |
| number |
|
| string |
設定された場合、値はフォームコントロール要素の HTML |
| array |
|
|
|
Fuse Online は、最初にこの値をフォームフィールドに表示します。 |
| string | 設定されている場合、Fuse Online はこの値をフォームコントロールの下に表示します。通常、これはコントロールに関する短い便利なメッセージです。 |
| string | Fuse Online はこの値を表示します。 |
| array |
設定した場合、Fuse Online は |
| string |
設定されている場合、表示名の横に |
| number |
|
| number |
|
| Boolean |
|
| number |
Fuse Online コンソールでの制御の順序を決定します。Fuse Online は昇順を適用します。つまり、 |
| string | 設定された場合、ユーザーに想定される入力を分かりやすく示すため、この値を薄いフォントで入力フィールドに表示します。 |
| Boolean |
|
| number |
|
| Boolean |
指定された場合、Fuse Online はコントロールの |
9.3.6. エクステンションをサポートする Maven プラグインの説明
extension-maven-plugin
は、エクステンションを有効な Spring Boot モジュールとしてパッケージ化し、エクステンションの開発をサポートします。Java に実装するステップエクステンションでは、このプラグインでエクステンション定義 JSON ファイルを生成できます。
Maven プロジェクトの pom.xml
ファイルに、以下のプラグイン宣言を追加します。
<plugin> <groupId>io.syndesis.extension</groupId> <artifactId>extension-maven-plugin</artifactId> <version>${syndesis.version}</version> <executions> <execution> <goals> <goal>generate-metadata</goal> <goal>repackage-extension</goal> </goals> </execution> </executions> </plugin>
extension-maven-plugin
は以下のゴールを定義します。
generate-metadata は、生成された JAR ファイルに含まれる JSON エクステンション定義ファイルを以下のように生成します。
Maven は
META-INF/syndesis/syndesis-extension-definition.json
ファイルにあるデータ構造の指定から開始します (このファイルがある場合)。XML でコーディングする場合、エクステンション定義 JSON ファイルを独自に定義する必要があり、そのファイルに必要なデータ構造をすべて指定する必要があります。
コネクターまたはライブラリーエクステンションを開発する場合、エクステンション定義 JSON ファイルを独自に定義する必要があり、そのファイルに必要なデータ構造をすべて指定する必要があります。
Java でステップエクステンションを開発する場合、以下を行うことが可能です。
- エクステンション定義 JSON ファイルをユーザー自身が作成します。
- Java コードで、必要なデータ構造すべてを定義するアノテーションを指定します。ユーザーはエクステンション定義 JSON ファイルを作成しません。
- エクステンション定義 JSON ファイルを作成し、一部のデータ構造を指定します。
- Java で開発するステップエクステンションの場合、Maven はコードアノテーションから、不足している指定を取得します。
-
Maven は、scope が
provided
で、extension-bom
を介して管理される依存関係を指定する、依存関係リストを追加します。
repackage-extension はエクステンションをパッケージ化します。
-
extension-bom
を介して管理されない依存関係および関連する推移的依存関係は、生成された JAR のlib
フォルダーにあります。 -
ライブラリーエクステンションの場合、scope が
system
の依存関係は、生成された JAR のlib
フォルダーにあります。
-
たとえば、Maven プロジェクトに以下の pom.xml
ファイルがあるとします。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.company</groupId> <artifactId>my-extension</artifactId> <version>1.0.0</version> <name>MyExtension</name> <description>A Sample Extension</description> <packaging>jar</packaging> <dependencyManagement> <dependencies> <dependency> <groupId>io.syndesis.extension</groupId> <artifactId>extension-bom</artifactId> <version>1.3.10</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>io.syndesis.extension</groupId> <artifactId>extension-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>com.github.lalyos</groupId> <artifactId>jfiglet</artifactId> <version>0.0.8</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>io.syndesis.extension</groupId> <artifactId>extension-maven-plugin</artifactId> <version>1.3.10</version> <executions> <execution> <goals> <goal>generate-metadata</goal> <goal>repackage-extension</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
この pom.xml
ファイルを基にすると、生成されたエクステンション定義 JSON ファイルは以下のようになります。
{ "name": "MyExtension", "description": "A Sample Extension", "extensionId": "com.company:my-extension", "version": "1.0.0", "dependencies": [ { "type": "MAVEN", "id": "io.syndesis.extension:extension-api:jar:1.3.10" } ], "extensionType": "Libraries", "schemaVersion": "v1" }
生成されたアーカイブの構造と内容は次のようになります。
my-extension-1.0.0.jar | +- lib | | | + jfiglet-0.0.8.jar | +- META-INF | +- MANIFEST.MF | +- syndesis | +- syndesis-extension-definition.json
9.3.7. エクステンションでデータシェイプを指定する方法
データシェイプは、データマッパーによって使用されるデータタイプメタデータを保持します。データマッパーはこのメタデータを、データマッパーユーザーインターフェイスでソースおよびターゲットデータフィールドを表示するために使用する内部ドキュメントに変換します。コネクターまたはカスタムステップのエクステンション定義 JSON ファイルでは、各アクションの指定が入力データシェイプ (inputDataShape
) および出力データシェイプ (outputDataShape
) を定義します。
エクステンションを開発する場合、データマッパーがソースおよびターゲットフィールドを正しく処理および表示できるようにするデータシェイププロパティーを指定することが重要になります。以下のデータシェイププロパティーは、データマッパーの動作に影響します。
-
kind
-
type
-
specification
-
name
-
description
kind
プロパティー
データシェイプ kind
プロパティーは DataShapeKinds
列挙によって表されます。kind
プロパティーで使用可能な値は次のとおりです。
java
は、データタイプが Java クラスによって表されることを示します。type
プロパティーの完全修飾クラス名を指定して、"kind": "java"
宣言に従います。以下は例になります。"outputDataShape": { "kind": "java", "type": "org.apache.camel.component.telegram.model.IncomingMessage" },
json-schema
はデータタイプが JSON スキーマによって表されることを示します。kind
がjson-schema
に設定された場合、JSON スキーマをデータシェイプのspecification
プロパティーの値として指定します。以下は例になります。"inputDataShape": { "description": "Person data", "kind": "json-schema", "name": "Person", "specification": "{\"$schema\":\"http://json-schema.org/draft-04/schema#\",\"title\":\"Person\",\"type\":\"object\",\"properties\":{\"firstName\":{...}}}" }
SAP Concur コネクターのコードには、JSON スキーマによって指定されるデータシェイプの例 が含まれています。
json-instance
は、データタイプが JSON インスタンスで表されることを示しています。kind
がjson-instance
に設定された場合、JSON インスタンスをデータシェイプのspecification
プロパティーの値として指定します。以下は例になります。"inputDataShape": { "description": "Person data", "kind": "json-instance", "name": "Person", "specification": "{\"firstName\":\"John\",...}" }
xml-schema
は、データタイプが XML スキーマで表されることを示しています。kind
がxml-schema
に設定された場合、XML スキーマをデータシェイプのspecification
プロパティーの値として指定します。以下は例になります。"inputDataShape": { "description": "Person data", "kind": "xml-schema", "name": "Person", "specification": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">...</xs:schema>" }
xml-instance
は、データタイプが XML インスタンスによって表されることを示しています。kind
がxml-instance
に設定された場合、XML インスタンスをデータシェイプのspecification
プロパティーの値として指定します。以下は例になります。"inputDataShape": { "description": "Person data", "kind": "xml-instance", "name": "Person", "specification": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><Person><firstName>Jane</firstName></Person>" }
any
は、データタイプが構造化されていないことを示します。たとえば、バイト配列やフリーフォーマットテキストであることがあります。データマッパーは、kind
プロパティーがany
に設定されている場合にデータシェイプを無視します。つまり、データはデータマッパーに表示されないため、このデータとフィールドの間にマッピングを作成することはできません。しかし、
kind
プロパティーがany
に設定された場合、カスタムコネクターから作成したコネクションを設定するときに、Fuse Online は入力および出力データタイプを指定するよう要求します。これは、コネクションをインテグレーションに追加するときに発生します。データシェイプのスキーマの種類、指定するスキーマの種類に対応するドキュメント、およびデータタイプの名前を指定できます。-
none
はデータタイプがないことを示します。入力データシェイプでは、コネクションまたはステップがデータを読み取らないことを示します。出力データシェイプでは、コネクションまたはステップがデータを変更しないことを示します。たとえば、入力メッセージボディーが出力メッセージボディーに転送される場合は、kind
プロパティーをnone
に設定すると、データが通過することを意味します。データマッパーは、kind
がnone
に設定された場合にデータシェイプを無視します。つまり、データはデータマッパーに表示されないため、このデータとフィールドの間にマッピングを作成することはできません。
type
プロパティー
kind
プロパティーの値が java
の場合、"kind": "java"
宣言の後に完全修飾 Java クラス名を指定する type
宣言が続きます。以下は例になります。
"outputDataShape": { "kind": "java", "type": "org.apache.camel.component.telegram.model.IncomingMessage" },
kind
プロパティーが java
以外に設定された場合、type
プロパティーの設定は無視されます。
specification
プロパティー
kind
プロパティーの設定は、以下の表のように、specification
プロパティーの設定を決定します。
kind プロパティーの設定 | specification プロパティーの設定 |
---|---|
| Java インスペクションの結果。
Java で作成する各エクステンションに、
Java で記述されたステップエクステンションの場合、 |
| 実際の JSON スキーマのドキュメント。設定をドキュメントへの参照とすることはできず、参照の手段として JSON スキーマが他の JSON スキーマドキュメントを示すことはできません。 |
| サンプルデータが含まれる実際の JSON ドキュメント。データマッパーは、サンプルデータからデータタイプを取得します。この設定をドキュメントへの参照とすることはできません。 |
| 実際の XML スキーマドキュメント。設定をドキュメントへの参照とすることはできず、参照の手段として XML スキーマが他の XML スキーマドキュメントを示すことはできません。 |
| 実際の XML インスタンスドキュメントです。この設定をドキュメントへの参照とすることはできません。 |
|
|
|
|
name
プロパティー
データシェイプの name
プロパティーは、データタイプの人間が判読できる名前を指定します。データマッパーは、この名前をデータフィールドのラベルとしてユーザーインターフェイスに表示します。以下のイメージの Person は、name
プロパティーの値が表示される場所の例になります。
この名前は、Fuse Online フロービジュアライゼーションのデータタイプインジケーターにも表示されます。
description
プロパティー
データシェイプの description
プロパティーは、データマッパーユーザーインターフェイスのデータタイプ名にカーソルを合わせたときにツールチップとして表示されるテキストを指定します。
9.3.8. ステップエクステンションの開発例
ステップエクステンションは、1 つまたは複数のカスタムステップを実装します。各カスタムステップは、コネクション間のインテグレーションデータを処理するために 1 つのアクションを実装します。以下の例は、ステップエクステンション開発の代替を示します。
Syndesis は、syndesis-extension-plugin
とともに使用できる、カスタム Java アノテーションを提供します。ステップエクステンションまたはコネクターエクステンションを Java で実装する場合、Maven がアクション定義をエクステンション定義 JSON ファイルに追加できるようにするアノテーションを指定できます。アノテーションの処理を有効にするには、以下の依存関係を Maven プロジェクトに追加します。
<dependency> <groupId>io.syndesis.extension</groupId> <artifactId>extension-annotation-processor</artifactId> <optional>true</optional> </dependency>
Spring Boot はインテグレーションランタイムであるため、Bean を Camel コンテキストにインジェクトするには、Spring Boot の標準の方法に従う必要があります。たとえば、自動設定クラスを作成 し、そこに Bean を作成します。ただし、デフォルトの動作では、エクステンションコードはパッケージスキャンの対象ではありません。したがって、ステップエクステンションの META-INF/spring.factories
ファイルを作成し、内容を追加する必要があります。
9.3.8.1. XML フラグメントでの Camel ルートの開発例
カスタムステップを開発するには、 direct
などの入力がある Camel ルートである XML フラグメントとして、アクションを実装できます。Syndesis ランタイムは、このルートを他の Camel ルートを呼び出す同じ方法で呼び出します。
たとえば、任意の接頭辞を持つメッセージのボディーをログに記録するステップを作成する場合に以下の XML はこれを行う Camel ルートを定義します。
<?xml version="1.0" encoding="UTF-8"?> <routes xmlns="http://camel.apache.org/schema/spring" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <route id="log-body-with-prefix"> <from uri="direct:log"/> <choice> <when> <simple>${header.prefix} != ''</simple> <log message="${header.prefix} ${body}"/> </when> <otherwise> <log message="Output ${body}"/> </otherwise> </choice> </route> </routes>
XML でエクステンションを開発する場合は、エクステンション定義 JSON ファイルを独自に作成する必要があります。この XML フラグメントに対し、src/main/resources/META-INF/syndesis/syndesis-extension-definition.json
ファイルは以下のようにアクションを定義できます。
{ "actionType": "step", "id": "log-body-with-prefix", "name": "Log body with prefix", "description": "A simple body log with a prefix", "descriptor": { "kind": "ENDPOINT", 1 "entrypoint": "direct:log", 2 "resource": "classpath:log-body-action.xml", 3 "inputDataShape": { "kind": "none" }, "outputDataShape": { "kind": "none" }, "propertyDefinitionSteps": [ { "description": "extension-properties", "name": "extension-properties", "properties": { 4 "prefix": { "componentProperty": false, "deprecated": false, "description": "The Log body prefix message", "displayName": "Log Prefix", "javaType": "String", "kind": "parameter", "required": false, "secret": false, "type": "string" } } } ] } }
- 1
- アクションのタイプは
ENDPOINT
に設定されます。ランタイムは、Camel エンドポイントを呼び出して、このカスタムステップによって提供されるアクションを実行します。 - 2
- 呼び出す Camel エンドポイントは
direct:log
です。これはルートのfrom
指定です。 - 3
- これは、XML フラグメントの場所になります。
- 4
- これらは、このカスタムステップでアクションが定義したプロパティーで、このステップをインテグレーションに追加するインテグレーターに公開します。Fuse Online では、インテグレーターがユーザーインターフェイスで指定する値は、プロパティーと同じ名前を持つメッセージヘッダーにマップされます。この例では、インテグレーターは Log Prefix 表示名を持つ 1 つの入力フィールドを確認できます。詳細は ユーザーインターフェイスプロパティーの説明 を参照してください。
Syndesis は、完全な Camel XML 設定をサポートしません。Syndesis は <routes> タグのみをサポートします。
9.3.8.2. RouteBuilder
を使った Camel ルートの開発例
カスタムステップを実装するには、RouteBuilder
クラスを利用してアクションを Camel ルートとして開発します。このようなルートには、direct
などの入力があります。Syndesis は、他の Camel ルートの呼び出しと同じ方法でこのルートを呼び出します。
任意の接頭辞でメッセージのボディーをログに記録するステップを作成する例を実装するには、以下のように記述します。
import org.apache.camel.builder.RouteBuilder; import io.syndesis.extension.api.annotations.Action; import io.syndesis.extension.api.annotations.ConfigurationProperty; @Action( 1 id = "log-body-with-prefix", name = "Log body with prefix", description = "A simple body log with a prefix", entrypoint = "direct:log") public class LogAction extends RouteBuilder { @ConfigurationProperty( 2 name = "prefix", description = "The Log body prefix message", displayName = "Log Prefix", type = "string") private String prefix; @Override public void configure() throws Exception { from("direct::start") 3 .choice() .when(simple("${header.prefix} != ''")) .log("${header.prefix} ${body}") .otherwise() .log("Output ${body}") .endChoice(); } }
- 1
@Action
アノテーションは、アクション定義を示します。- 2
@ConfigurationProperty
アノテーションは、ユーザーインターフェイスのフォームコントロールの定義を示します。詳細は ユーザーインターフェイスプロパティーの説明 を参照してください。- 3
- これはアクションの実装です。
この Java コードは Syndesis アノテーションを使用するため、extension-maven-plugin
はアクション定義を自動的に生成できます。エクステンション定義 JSON ファイルのアクション定義は以下のようになります。
{ "id": "log-body-with-prefix", "name": "Log body with prefix", "description": "A simple body log with a prefix", "descriptor": { "kind": "ENDPOINT", 1 "entrypoint": "direct:log", 2 "resource": "class:io.syndesis.extension.log.LogAction", 3 "inputDataShape": { "kind": "none" }, "outputDataShape": { "kind": "none" }, "propertyDefinitionSteps": [ { "description": "extension-properties", "name": "extension-properties", "properties": { 4 "prefix": { "componentProperty": false, "deprecated": false, "description": "The Log body prefix message", "displayName": "Log Prefix", "javaType": "java.lang.String", "kind": "parameter", "required": false, "secret": false, "type": "string", "raw": false } } } ] }, "actionType": "step" }
- 1
- アクションのタイプは
ENDPOINT
です。ランタイムは Camel エンドポイントを呼び出して、このステップが実装するアクションを実行します。 - 2
- これが呼び出す Camel エンドポイントです。これはルートの
from
指定です。 - 3
- これは、
RoutesBuilder
を実装するクラスです。 - 4
- これらは、このカスタムステップでアクションが定義したプロパティーで、このステップをインテグレーションに追加するインテグレーターに公開します。Fuse Online では、インテグレーターがユーザーインターフェイスで指定する値は、プロパティーと同じ名前を持つメッセージヘッダーにマップされます。この例では、インテグレーターは Log Prefix 表示名を持つ 1 つの入力フィールドを確認できます。詳細は ユーザーインターフェイスプロパティーの説明 を参照してください。
9.3.8.3. RouteBuilder
および Spring Boot を使った Camel ルートの開発例
カスタムステップを実装するには、RouteBuilder
クラスと Spring Boot を利用してアクションを Camel ルートとして開発します。この例では、Spring Boot は RouteBuilder
オブジェクトを Camel コンテキストに登録するファシリティーです。Syndesis は、他の Camel ルートの呼び出しと同じ方法でこのルートを呼び出します。
任意の接頭辞でメッセージのボディーをログに記録するステップを作成する例を実装するには、以下のように記述します。
import io.syndesis.extension.api.annotations.Action; import io.syndesis.extension.api.annotations.ConfigurationProperty; import org.apache.camel.builder.RouteBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ActionsConfiguration { @Action( 1 id = "log-body-with-prefix", name = "Log body with prefix", description = "A simple body log with a prefix", entrypoint = "direct:log") @ConfigurationProperty( 2 name = "prefix", description = "The Log body prefix message", displayName = "Log Prefix", type = "string") @Bean 3 public RouteBuilder logBodyWithprefix() { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct::start") 4 .choice() .when(simple("${header.prefix} != ''")) .log("${header.prefix} ${body}") .otherwise() .log("Output ${body}") .endChoice(); } }; } }
- 1
@Action
アノテーションは、アクション定義を示します。- 2
@ConfigurationProperty
アノテーションは、ユーザーインターフェイスのフォームコントロールの定義を示します。詳細は ユーザーインターフェイスプロパティーの説明 を参照してください。- 3
RouteBuilder
オブジェクトを Bean として登録します。- 4
- これはアクションの実装です。
この Java コードは Syndesis アノテーションを使用するため、extension-maven-plugin
はアクション定義を自動的に生成できます。エクステンション定義 JSON ファイルのアクション定義は以下のようになります。
{ "id": "log-body-with-prefix", "name": "Log body with prefix", "description": "A simple body log with a prefix", "descriptor": { "kind": "ENDPOINT", 1 "entrypoint": "direct:log", 2 "inputDataShape": { "kind": "none" }, "outputDataShape": { "kind": "none" }, "propertyDefinitionSteps": [ { "description": "extension-properties", "name": "extension-properties", "properties": { 3 "prefix": { "componentProperty": false, "deprecated": false, "description": "The Log body prefix message", "displayName": "Log Prefix", "javaType": "java.lang.String", "kind": "parameter", "required": false, "secret": false, "type": "string", "raw": false } } } ] }, "actionType": "step" }
- 1
- アクションのタイプは
ENDPOINT
です。ランタイムは Camel エンドポイントを呼び出して、このステップが実装するアクションを実行します。 - 2
- これが呼び出す Camel エンドポイントです。これはルートの
from
指定です。 - 3
- これらは、このカスタムステップでアクションが定義したプロパティーで、このステップをインテグレーションに追加するインテグレーターに公開します。Fuse Online では、インテグレーターがユーザーインターフェイスで指定する値は、プロパティーと同じ名前を持つメッセージヘッダーにマップされます。この例では、インテグレーターは Log Prefix 表示名を持つ 1 つの入力フィールドを確認できます。詳細は ユーザーインターフェイスプロパティーの説明 を参照してください。
Spring Boot が設定クラスを検出できるようにするには、以下のように META-INF/spring.factories
という名前のファイルにこれらのクラスを記載する必要があります。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.company.ActionsConfiguration
Spring Boot では、設定クラスに最終的に登録するすべての Bean を Camel コンテキストで利用できます。詳細は、独自の自動設定を作成 するための Spring Boot ドキュメントを参照してください。
9.3.8.4. Camel Bean の使用例
アクションを Camel Bean プロセッサーとして開発すると、カスタムステップを実装できます。任意の接頭辞でメッセージのボディーをログに記録するステップを作成する例を実装するには、以下のように記述します。
import org.apache.camel.Body;
import org.apache.camel.Handler;
import org.apache.camel.Header;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.syndesis.extension.api.annotations.Action;
import io.syndesis.extension.api.annotations.ConfigurationProperty;
@Action(
id = "log-body-with-prefix",
name = "Log body with prefix",
description = "A simple body log with a prefix")
public class LogAction {
private static final Logger LOGGER = LoggerFactory.getLogger(LogAction.class);
@ConfigurationProperty(
name = "prefix",
description = "The Log body prefix message",
displayName = "Log Prefix",
type = "string")
private String prefix;
@Handler 1
public void process(@Header("prefix") String prefix, @Body Object body) {
if (prefix == null) {
LOGGER.info("Output {}", body);
} else {
LOGGER.info("{} {}", prefix, body);
}
}
}
- 1
- これは、アクションを実装する関数です。
この Java コードは Syndesis アノテーションを使用するため、extension-maven-plugin
はアクション定義を自動的に生成できます。エクステンション定義 JSON ファイルのアクション定義は以下のようになります。
{ "id": "log-body-with-prefix", "name": "Log body with prefix", "description": "A simple body log with a prefix", "descriptor": { "kind": "BEAN", 1 "entrypoint": "io.syndesis.extension.log.LogAction::process", 2 "inputDataShape": { "kind": "none" }, "outputDataShape": { "kind": "none" }, "propertyDefinitionSteps": [ { "description": "extension-properties", "name": "extension-properties", "properties": { "prefix": { 3 "componentProperty": false, "deprecated": false, "description": "The Log body prefix message", "displayName": "Log Prefix", "javaType": "java.lang.String", "kind": "parameter", "required": false, "secret": false, "type": "string", "raw": false } } } ] }, "actionType": "step" }
- 1
- アクションのタイプは
BEAN
です。ランタイムは、Camel Bean プロセッサーを呼び出して、このカスタムステップのアクションを実行します。 - 2
- この Camel Bean を呼び出します。
- 3
- これらは、このカスタムステップでアクションが定義したプロパティーで、このステップをインテグレーションに追加するインテグレーターに公開します。Fuse Online では、インテグレーターがユーザーインターフェイスで指定する値は、プロパティーと同じ名前を持つメッセージヘッダーにマップされます。この例では、インテグレーターは Log Prefix 表示名を持つ 1 つの入力フィールドを確認できます。詳細は ユーザーインターフェイスプロパティーの説明 を参照してください。
Bean を使用する場合、交換ヘッダーからユーザープロパティーを取得する代わりに、ユーザープロパティーを Bean にインジェクトすると便利である可能性があります。これには、インジェクトするプロパティーに getter および setter メソッドを実装します。アクション実装は以下のようになります。
import org.apache.camel.Body; import org.apache.camel.Handler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.syndesis.extension.api.annotations.Action; import io.syndesis.extension.api.annotations.ConfigurationProperty; @Action( id = "log-body-with-prefix", name = "Log body with prefix", description = "A simple body log with a prefix") public class LogAction { private static final Logger LOGGER = LoggerFactory.getLogger(LogAction.class); @ConfigurationProperty( name = "prefix", description = "The Log body prefix message", displayName = "Log Prefix", type = "string") private String prefix; public void setPrefix(String prefix) { 1 this.prefix = prefix; } public String getPrefix() { 2 return prefix; } @Handler public void process(@Body Object body) { if (this.prefix == null) { LOGGER.info("Output {}", body); } else { LOGGER.info("{} {}", this.prefix, body); } } }
9.3.8.5. Syndesis Step API の使用例
Syndesis Step
API を使用することで、カスタムステップを実装できます。これにより、ランタイムルートの作成と対話することが可能になります。ProcessorDefinition
クラスによって提供されるすべてのメソッドを使用でき、さらに複雑なルートを作成できます。Syndesis API に関する情報は http://javadoc.io/doc/io.syndesis.extension/extension-api を参照してください。
以下は、スプリットアクションを実装するために Syndesis Step
API を使用するステップエクステンションの例になります。
import java.util.Map;
import java.util.Optional;
import io.syndesis.extension.api.Step;
import io.syndesis.extension.api.annotations.Action;
import io.syndesis.extension.api.annotations.ConfigurationProperty;
import org.apache.camel.CamelContext;
import org.apache.camel.model.ProcessorDefinition;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.Expression;
import org.apache.camel.builder.Builder;
import org.apache.camel.processor.aggregate.AggregationStrategy;
import org.apache.camel.processor.aggregate.UseOriginalAggregationStrategy;
import org.apache.camel.spi.Language;
@Action(id = "split", name = "Split", description = "Split your exchange")
public class SplitAction implements Step {
@ConfigurationProperty(
name = "language",
displayName = "Language",
description = "The language used for the expression")
private String language;
@ConfigurationProperty(
name = "expression",
displayName = "Expression",
description = "The expression used to split the exchange")
private String expression;
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getExpression() {
return expression;
}
public void setExpression(String expression) {
this.expression = expression;
}
@Override
public Optional<ProcessorDefinition> configure(
CamelContext context,
ProcessorDefinition route,
Map<String, Object> parameters) { 1
String languageName = language;
String expressionDefinition = expression;
if (ObjectHelper.isEmpty(languageName) && ObjectHelper.isEmpty(expressionDefinition)) {
route = route.split(Builder.body());
} else if (ObjectHelper.isNotEmpty(expressionDefinition)) {
if (ObjectHelper.isEmpty(languageName)) {
languageName = "simple";
}
final Language splitLanguage = context.resolveLanguage(languageName);
final Expression splitExpression = splitLanguage.createExpression(expressionDefinition);
final AggregationStrategy aggreationStrategy = new UseOriginalAggregationStrategy(null, false);
route = route.split(splitExpression).aggregationStrategy(aggreationStrategy);
}
return Optional.of(route);
}
}
- 1
- これは、カスタムステップが実行するアクションの実装です。
この Java コードは Syndesis アノテーションを使用するため、extension-maven-plugin
はアクション定義を自動的に生成できます。エクステンション定義 JSON ファイルのアクション定義は以下のようになります。
{ "id": "split", "name": "Split", "description": "Split your exchange", "descriptor": { "kind": "STEP", 1 "entrypoint": "io.syndesis.extension.split.SplitAction", 2 "inputDataShape": { "kind": "none" }, "outputDataShape": { "kind": "none" }, "propertyDefinitionSteps": [ { "description": "extension-properties", "name": "extension-properties", "properties": { "language": { "componentProperty": false, "deprecated": false, "description": "The language used for the expression", "displayName": "Language", "javaType": "java.lang.String", "kind": "parameter", "required": false, "secret": false, "type": "string", "raw": false }, "expression": { "componentProperty": false, "deprecated": false, "description": "The expression used to split the exchange", "displayName": "Expression", "javaType": "java.lang.String", "kind": "parameter", "required": false, "secret": false, "type": "string", "raw": false } } } ] }, "tags": [], "actionType": "step" }
その他のリソース
ユーザーインターフェイスプロパティーの詳細は ユーザーインターフェイスプロパティーの説明 を参照してください。
9.3.9. コネクターエクステンションの開発例
Fuse Online が、インテグレーションで接続するアプリケーションやサービスのコネクターを提供しない場合、経験のある開発者は Fuse Online に新しいコネクターを提供するエクステンションを作成できます。このドキュメントは、初心者向けのコネクターエクステンションの開発に関する情報を提供します。コネクターの開発に関する詳細は、Syndesis コミュニティーの Web サイトにある Developing Syndesis connectors を参照してください。
コネクターエクステンションでは、Java コードからエクステンション定義 JSON ファイルを自動的に生成できません。
コネクターは基本的に Camel コンポーネントのプロキシーになります。コネクターは基盤のコンポーネントを設定し、エクステンション定義で定義されるオプションや、Fuse Online Web インターフェイスが収集するユーザー提供のオプションに応じてエンドポイントを作成します。
コネクターエクステンションの定義は、以下の追加のデータ構造を使用して、ステップエクステンションに必要なエクステンション定義を拡張します。
componentScheme
コネクターが使用する Camel コンポーネントを定義します。コネクターまたはアクションに
componentScheme
を設定できます。componentScheme
をコネクターとアクションの両方に設定した場合、アクションの設定が優先されます。connectorCustomizers
ComponentProxyCustomizer クラスを実装するクラスの一覧を指定します。各クラスはコネクターの動作をカスタマイズします。たとえば、クラスはプロパティーが基礎となるコンポーネントやエンドポイントに適用される前にプロパティーを操作したり、クラスは事前または事後のエンドポイントロジックを追加する場合があります。各クラスに対して、
com.mycomponent.MyCustomizer
のように実装の完全クラス名を指定します。connectorCustomizers
はアクションおよびコネクターに設定できます。Fuse Online は設定に応じて、カスタマイザーを最初にコネクターに適用した後、アクションに適用します。connectorFactory
基盤のコンポーネント/エンドポイントの作成や設定を行う、ComponentProxyFactory クラスを実装するクラスを定義します。実装の完全クラス名を指定します。コネクターまたはアクションの
connectorFactory
を設定できます。アクションには優先順位があります。
カスタマイザーの例
以下のカスタマイザーの例は、個別のオプションから DataSource
を設定します。
public class DataSourceCustomizer implements ComponentProxyCustomizer, CamelContextAware { private final static Logger LOGGER = LoggerFactory.getLogger(DataSourceCustomizer.class); private CamelContext camelContext; @Override public void setCamelContext(CamelContext camelContext) { 1 this.camelContext = camelContext; } @Override public CamelContext getCamelContext() { 2 return this.camelContext; } @Override public void customize(ComponentProxyComponent component, Map<String, Object> options) { if (!options.containsKey("dataSource")) { if (options.containsKey("user") && options.containsKey("password") && options.containsKey("url")) { try { BasicDataSource ds = new BasicDataSource(); consumeOption(camelContext, options, "user", String.class, ds::setUsername); 3 consumeOption(camelContext, options, "password", String.class, ds::setPassword); 4 consumeOption(camelContext, options, "url", String.class, ds::setUrl); 5 options.put("dataSource", ds); } catch (@SuppressWarnings("PMD.AvoidCatchingGenericException") Exception e) { throw new IllegalArgumentException(e); } } else { LOGGER.debug("Not enough information provided to set-up the DataSource"); } } } }
プロパティーのインジェクト例
カスタマイザーが Java Bean の慣例に従う場合、以下のようにプロパティーもインジェクトできます (前述の例を編集)。
public class DataSourceCustomizer implements ComponentProxyCustomizer, CamelContextAware { private final static Logger LOGGER = LoggerFactory.getLogger(DataSourceCustomizer.class); private CamelContext camelContext; private String userName; private String password; private String url; @Override public void setCamelContext(CamelContext camelContext) { 1 this.camelContext = camelContext; } @Override public CamelContext getCamelContext() { 2 return this.camelContext; } public void setUserName(String userName) { 3 this.userName = userName; } public String getUserName() { 4 return this.userName; } public void setPassword(String password) { 5 this.password = password; } public String getPassword() { 6 return this.password; } public void setUrl(String url) { 7 this.url = url; } public String getUrl() { 8 return this.url; } @Override public void customize(ComponentProxyComponent component, Map<String, Object> options) { if (!options.containsKey("dataSource")) { if (userName != null && password != null && url != null) { try { BasicDataSource ds = new BasicDataSource(); ds.setUserName(userName); ds.setPassword(password); ds.setUrl(url); options.put("dataSource", ds); } catch (@SuppressWarnings("PMD.AvoidCatchingGenericException") Exception e) { throw new IllegalArgumentException(e); } } else { LOGGER.debug("Not enough information provided to set-up the DataSource"); } } } }
カスタマイザーを使用した before/after 論理の設定
以下の例のように、カスタマイザーを使用して before/after 論理を設定できます。
public class AWSS3DeleteObjectCustomizer implements ComponentProxyCustomizer { private String filenameKey; public void setFilenameKey(String filenameKey) { this.filenameKey = filenameKey; } public String getFilenameKey() { return this.filenameKey; } @Override public void customize(ComponentProxyComponent component, Map<String, Object> options) { component.setBeforeProducer(this::beforeProducer); } public void beforeProducer(final Exchange exchange) throws IOException { exchange.getIn().setHeader(S3Constants.S3_OPERATION, S3Operations.deleteObject); if (filenameKey != null) { exchange.getIn().setHeader(S3Constants.KEY, filenameKey); } } }
ComponentProxyComponent
の動作のカスタマイズ
ComponentProxyFactory クラスは、基礎となるコンポーネント/エイドポイントの作成や設定を行います。ComponentProxyFactory
が作成する ComponentProxyComponent オブジェクトの動作をカスタマイズするには、以下のメソッドのいずれかをオーバーライドします。
createDelegateComponent()
Syndesis は、プロキシーの開始時にこのメソッドを呼び出し、最終的に
componentScheme
オプションによって定義されたスキームでコンポーネントの専用インスタンスを作成します。このメソッドのデフォルトの動作は、いずれかのコネクター/アクションオプションがコンポーネントレベルで適用されるかどうかを判断します。同じオプションをエンドポイントに適用できない場合のみ、メソッドによってカスタムコンポーネントインスタンスが作成され、適用可能なオプションに応じて設定されます。
configureDelegateComponent()
Syndesis は、委譲されたコンポーネントインスタンスの追加の動作を設定するためにカスタムコンポーネントインスタンスが作成された場合に限り、このメソッドを呼び出します。
createDelegateEndpoint()
Syndesis は、プロキシーがエンドポイントを作成するときにこのメソッドを呼び出し、デフォルトで Camel カタログファシリティーを使用してエンドポイントを作成します。
configureDelegateEndpoint()
委譲されたエンドポイントの作成後に、Syndesis がこのメソッドを呼び出し、委譲されたエンドポイントインスタンスの追加動作を設定します。以下に例を示します。
public class IrcComponentProxyFactory implements ComponentProxyFactory { @Override public ComponentProxyComponent newInstance(String componentId, String componentScheme) { return new ComponentProxyComponent(componentId, componentScheme) { @Override protected void configureDelegateEndpoint(ComponentDefinition definition, Endpoint endpoint, Map<String, Object> options) throws Exception { if (!(endpoint instanceof IrcEndpoint)) { throw new IllegalStateException("Endpoint should be of type IrcEndpoint"); } final IrcEndpoint ircEndpoint = (IrcEndpoint)endpoint; final String channels = (String)options.remove("channels"); if (ObjectHelper.isNotEmpty(channels)) { ircEndpoint.getConfiguration().setChannel( Arrays.asList(channels.split(",")) ); } } }; } }
9.3.10. ライブラリーエクステンションの開発方法
ライブラリーエクステンションは、インテグレーションがランタイムに必要なリソースを提供します。ライブラリーエクステンションは、ステップやコネクターを Fuse Online に提供しません。
インテグレーションを保存するときに、必要の応じて、インテグレーションと含まれるようにするインポートされたライブラリーエクステンションを 1 つまたは複数選択できます。
ライブラリーエクステンションは、いかなるアクションも定義しません。以下は、ライブラリーエクステンションの定義例になります。
{ "schemaVersion" : "v1", "name" : "Example Library Extension", "description" : "Syndesis Extension for adding a runtime library", "extensionId" : "io.syndesis.extensions:syndesis-library", "version" : "1.0.0", "tags" : [ "my-libraries-extension" ], "extensionType" : "Libraries" }
ライブラリーエクステンションの例は https://github.com/syndesisio/syndesis-extensions でも参照できます。
ライブラリーエクステンションの構造は、アクションがないこと以外は、ステップまたはコネクターエクステンションの構造と同じです。
ライブラリーエクステンションを作成する Maven プロジェクトで、Maven リポジトリーから使用できない依存関係を追加するには、以下のように system
依存関係を指定します。
<dependency> <groupId>com.company</groupId> <artifactId>my-library-extension</artifactId> <version>1.0</version> <scope>system</scope> <systemPath>${project.basedir}/lib/my-library-extension.jar</systemPath> </dependency>
9.3.11. JDBC ドライバーライブラリーエクステンションの作成
Apache Derby、MySQL、および PostgreSQL 以外の SQL データベースに接続するには、接続するデータベースの JDBC ドライバーをラップするライブラリーエクステンションを作成します。Fuse Online にこのエクステンションをアップロードした後、Fuse Online が提供する Database コネクターはドライバーにアクセスしてプロプライエタリーデータベースへのコネクションを検証および作成することができます。特定のデータベースに新しいコネクターを作成しません。
Syndesis オープンソースコミュニティーは、JDBC ドライバーをラップするエクステンションを作成するためのプロジェクトを提供します。
エクステンションで 1 つのドライバーのみをパッケージ化します。これにより、特定のデータベースを管理する一環として、エクステンションの管理が容易になります。ただし、複数のドライバーをラップするライブラリーエクステンションを作成することは可能です。
前提条件
Syndesis プロジェクトを使用するには、GitHub アカウントが必要です。
手順
以下のいずれかを行って、接続するデータベースの JDBC ドライバーへアクセスできるようにします。
- ドライバーが Maven リポジトリーにあることを確認します。
- ドライバーをダウンロードします。
- ブラウザーのタブで https://github.com/syndesisio/syndesis-extensions にアクセスします。
-
syndesis-extensions
リポジトリーを GitHub アカウントにフォークします。 - フォークからローカルのクローンを作成します。
syndesis-extensions
のクローンで以下を行います。-
このドライバーが Maven リポジトリーにない場合、
syndesis-library-jdbc-driver/lib
フォルダーにコピーします。 syndesis-library-jdbc-driver/pom.xml
ファイルを編集します。-
Name
要素の値を更新し、このエクステンションに選択する名前にします。 -
Description
要素の値を更新し、このエクステンションに関する便利な情報を提供します。 -
ドライバーを
syndesis-library-jdbc-driver/lib
にコピーした場合、pom.xml
のsystemPath
がそのドライバーファイルを示すようにしてください。必要に応じて、groupId
、artifactId
、およびversion
を変更し、ドライバーに応じた適切な値を反映するようにします。 -
このドライバーが Maven リポジトリーにある場合は、その Maven 依存関係への参照が
pom.xml
ファイルにあることを確認します。 -
pom.xml
ファイルの残りの内容を確認し、必要に応じて関連するメタデータを変更します。
-
-
./mvnw -pl :syndesis-library-jdbc-driver clean package
を実行し、エクステンションをビルドします。
-
このドライバーが Maven リポジトリーにない場合、
生成された .jar
ファイルは syndesis-library-jdbc-driver/target
フォルダーにあります。この .jar
ファイルを Fuse Online でエクステンションとしてインポートします。
ライブラリーエクステンションのインポート後、Fuse Online にインテグレーションを保存するときに、必要に応じて、インポートされたライブラリーエクステンションを選択し、インテグレーションに関連付けることができます。