Flex Gateway新着情報
Governance新着情報
Monitoring API Manager以下の原則は、モジュールまたはコネクタのすべてのコンポーネントに適用されます。これらは、すべての操作、配信元、設定、接続プロバイダー、関数に適用されます。
Anypoint Platform のコンテキストで言えば、コネクタの目的は配信先システムを Mule 言語に翻訳することです。コネクタは、高レベルの抽象表現を追加したり、特定のビジネスユースケースを実装する操作を含めたりしてはなりません。
たとえば、請求書を作成し、請求書に項目を追加して、請求書を送信するためのリソースを持つ請求 API があるとします。このような API のコネクタは、これらのリソースのそれぞれに対して操作を 1 つずつ含む必要がありますが、3 つのコールを 1 つに組み合わせる操作を含んではなりません。
例外としては自動ページング操作があり、ページング効果を実現するために、単一の Mule 操作からの出力の処理において、複数のコールを実行します。
1 つのコネクタは、同時に 1 種類のプロトコルにのみ接続する必要があります。たとえば、1 つの外部システムが REST API、SOAP API、そして OData API を公開するとします。
これらは同じ外部システムにアクセスしていますが、Anypoint Platform では 3 つの異なる API が存在することになります。そのため、1 つのコネクタで 3 種類のプロトコルを処理するのではなく、それぞれの API に対して別々のコネクタを用意する必要があります。
このセクションを読む前に、Mule SDK の「クラスローディング分離」を参照してください。
モジュールは、モジュールで定義されたパッケージのみをエクスポートする必要があります。連動関係ライブラリからのパッケージをエクスポートしてはなりません。
モジュールは JDK からのパッケージをエクスポートせずにコンシュームするだけであるため、これらのパッケージは扱いが異なります。Mule は、使用するモジュールで使用できるすべての Java パッケージを自動的にエクスポートします。
ですが、モジュールは、そのモジュールと互換性のある Mule バージョンでサポートされているすべての JDK で使用できる Java パッケージのみを使用する必要があります。com.sun などのベンダー固有のパッケージを使用してはなりません。
Mule 4.2.0 からは JDK 11 もサポートされるようになりました。そのため、ネイティブ Java API に依存しているモジュールでは、必要な API が Java の新しいモジュール型アーキテクチャ (Java 9 で初めて登場した Project Jigsaw) で使用できない場合があるという事実を考慮する必要があります。
たとえば、モジュールが Java トランザクション API (JTA) を必要とする場合、そのモジュールは pom.xml ファイルで次の依存関係を宣言する必要があります。
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>1.2</version>
</dependency>
Java Mail API を使用する場合は次のように宣言します。
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.2</version>
</dependency>
Mule は、同時性の高いワークロード向けにデザインされたリアクティブ実行エンジンです。そのため、すべてのコンポーネントは、最小限の競合で同時実行をサポートするように常にデザインする必要があります。
スレッドセーフは、同時実行を扱い慣れた Java 開発者にとっては基本的な概念です。SDK のユーザーも、この概念に慣れておくことが期待されます。
@Content パラメーターは、MuleSoft 「コンテンツパラメーター」ドキュメントに従って正しく使用してください。
Mule 4 では、変数にはエンドユーザーのみがアクセスできます。モジュールから直接フロー変数にアクセスすべきではありません。
SDK にはフロー変数にアクセスするための API は用意されていませんが、省略可能なパラメーターを利用することでこの制約を破ることができます。次に例を示します。
@Optional(defaultValue = "#[vars.foo]") String foo
@Optional(defaultValue = "#[vars]") Map<String, TypedValue<Object>> vars
ただし、これらのステートメント (およびモジュール内から vars にアクセスする他の手段) は禁止されています。モジュールで必要とされるすべての情報は、パラメーターで明確に提供するべきです。変数に値を割り当てるかどうかはエンドユーザーが決めることです。
このルールに違反すると、位置の独立性にも違反することになります。
コンポーネントでは、属性オブジェクトが同じモジュールの一部として定義されている場合であっても、メッセージ属性としても使用される種別のパラメーターを定義すべきではありません。
たとえば、コネクタに LocalFileAttributes クラスを出力属性として使用する操作がある場合、次の定義は不正です。
public void checkAccess(@Content LocalFileAttributes attributes) {
doCheckAccess(attributes);
}
その代わりに、実際に必要な属性クラスからの情報を反映したパラメーターを追加してください。
public void checkAccess(String path) {
...
}
複数のエンコードを受け入れるシステムに接続する場合は、使用するエンコードを設定の上書きによって設定可能にする必要があります。つまり、使用するエンコードを設定レベルだけではなく、エンコードを必要とする各コンポーネント (操作、配信元、関数など) でもパラメーター化可能とすべきです。
設定レベルでは、エンコードパラメーターのデフォルトを、@DefaultEncoding アノテーションで取得できる Mule のデフォルトエンコードとする必要があります。
次に例を示します。
public class MyConfig implements Initialisable {
@DefaultEncoding
private String defaultEncoding;
@Parameter
@Optional
private String encoding;
public void initialise() throws InitialisationException {
if (encoding == null) {
encoding = defaultEncoding;
}
}
public String getEncoding() {
return encoding;
}
}
多くのモジュールでは、タイムアウトやキャッシュエビクションといった期間を設定する必要があります。
期間は、2 つのパラメーターの組み合わせとして表現する必要があります。
Timeout サフィックスの付いた int (整数) スカラーパラメーター
スカラーを限定する java.util.concurrent.TimeUnit パラメーター
このパラメーターの名前は、対応するスカラーと完全に同じ名前に TimeUnit サフィックスを付けたものである必要があります。TimeUnit パラメーターのデフォルトは SECONDS にすべきです。
次に例を示します。
/**
* The socket connection timeout value. This attribute works in tandem with {@link #connectionTimeoutUnit}.
*/
@Parameter
@Optional(defaultValue = "5")
@Placement(tab = ADVANCED_TAB, order = 1)
@Summary("Socket connection timeout value")
private int connectionTimeout;
/**
* A {@link TimeUnit} that qualifies the {@link #connectionTimeout}
*/
@Parameter
@Optional(defaultValue = "SECONDS")
@Placement(tab = ADVANCED_TAB, order = 2)
@Summary("Time unit to be used in the Timeout configurations")
private TimeUnit connectionTimeoutUnit;
タイムアウトの影響を受ける操作を実行するすべてのコンポーネントでは、パラメーターの設定の上書きによってタイムアウトを設定できるようにする必要があります。
これらのタイムアウトは、期間パラメーターとして表現する必要があります。
プライマリコンテンツ以外のパラメーターのデフォルトをペイロードにすべきではありません。つまり、以下の定義を使用すべきではありません。
@Optional(defaultValue = "#[payload]")
日付と時刻のパラメーターは、java.time.LocalDate 種別、java.time.LocalDateTime、または java.time.ZonedDateTime 種別を使用して実装する必要があります。java.util.Date や java.util.Calendar は使用しないでください。
モジュールをパブリッシュする前に、Anypoint Studio と Anypoint Design Center でモジュールをテストします。使い勝手とエクスペリエンスが優れていることを確認してください。正常に機能しても使い勝手が悪ければ、そのモジュールは不完全です。
以下を確認する必要があります。
すべての入力パラメーターと出力値について DataSense が正しく解決される。
各コンポーネントのパラメーターのレイアウトが正しい。
表示ラベルや説明にタイプミスがない。
モジュールの主なユースケースを使用するアプリケーションをユーザーが簡単にビルドできる。
SDK では、入力パラメーターと出力データ型のどちらでも POJO を使用できます。ですが、これらの使用はお勧めできません。すべてのモジュールでは、JSON または XML を使用するように工夫すべきです。動的データ型の場合は、Java マップも使用できます。
このルールは、POJO を使用するユースケースが存在しない、あるいはすべての構造を JSON または Java マップに変換する必要があるという意味ではありません。このルールは単に、他のコンポーネントとの相互運用性が高く、逐次化の問題を回避できるデータ形式を使用した方がよいという意味です。
たとえば、Mule アプリケーションで活用するための Java 税金ライブラリを組織で開発したとします。このライブラリが POJO を返す場合は、このライブラリをラップする SDK モジュールをビルドし、その税金モジュールが POJO を受け入れて POJO を生成することになっても問題はありません。
一方、JSON を返す税金 API を利用する場合には、税金コネクタはその JSON を POJO に変換するのではなく、API と同じ JSON を返すべきです。
公開されるすべての POJO は (出力データ型、入力パラメーター、メッセージ属性として使用されるため) DataWeave に準拠する必要があります。つまり、@Parameter アノテーションが付けられた各項目に対して、デフォルトのコンストラクターと getter メソッドが必要です。
ユーザーは、モジュールを実装するために使用されている Java 型を知らなくてもモジュールを使用できる必要があります。
たとえば、次の変換を考えてみましょう。
{
name: "Pedro",
address: {
x: 11,
y: 12
}
} as com.foo.Person
このモジュールは、このような明確な変換が必要ないような方法で定義される必要があります。これを実現するには次のような方法があります。
POJO を使用して個人を表現しない (推奨)
com.foo.Person を DataWeave に準拠した具体的なクラスにする
入力パラメーターとして使用する場合は、抽象型やインターフェースを使用するのではなく、com.foo.Person を明確に参照する
操作またはメッセージ配信元から返されるメッセージ属性オブジェクトは、Java で逐次化可能である必要があります。そうでなければ、ObjectStore、VM キュー、またはクラスターモードの Mule では使用できません。
MuleContext は非推奨であるため、どのモジュールやコネクタからもアクセスしてはなりません。
ほとんどの場合、モジュールが MuleContext にアクセスする理由は特定の Runtime サービスを取得するためです。次に例を示します。
muleContext.getRegistry().lookupByType(ObjectStoreManager.class)
その代わりに、@Inject を使用してこれらのサービスを取得します。
public class MyComponent {
@Inject
ObjectStoreManager osm;
}
すべてのログは、SLF4J API を使用して記録する必要があります。
この API との連動関係は MuleSoft が提供する親 pom ファイルで定義されているため、モジュールでは連動関係を定義してはなりません。
ロガーの作成にはリソースを大量に消費します。そのため、すべてのロガーは、非公開、静的、そして最終版である必要があります。
次に例を示します。
public class Operation {
private static final Logger LOGGER = LoggerFactory.getLogger(Operation.class);
...
}
通常、開発者は特定の製品で使用可能な最新バージョンを使用する傾向にあります。これは SDK の場合には適用すべきではありません。Mule を拡張するには、次の手順を実行します。
必要な機能を特定する。
必要な機能が含まれる下位バージョンを選択します。
適切な SDK バージョンの選択についての詳細は、「SDK バージョンの選択」を参照してください。
ブールパラメーターは、ネイティブブール型である必要があります。ボックス入力のブールはパラメーターの型としては使用できません。
すべてのブールパラメーターは省略可能とみなされ、デフォルトは false である必要があります。@Optional アノテーションを使用して、ブールパラメーターのデフォルトを変更できますが、必須パラメーターにすることはできません。
Java コレクション、マップ、配列、または何らかの配列 (JSON 配列など) を表す他の型として実装されているすべてのパラメーターには、複数形の名前を付ける必要があります。
モジュールは、 Semantic Versioning 標準を使用してバージョン設定する必要があります。