システム設定コレクターのプラグインの作成
使用可能なプラグインにない機能の一部を実行するために、Windchill のシステム設定コレクター UI で使用する新しいプラグインを作成する必要がある場合があります。プラグインは、Windchill のコンフィギュレーション、インストール、および実行時の問題をデバッグするために役立ちます。
バックグラウンド
システム設定コレクターは、Windchill の UI ページであり、現時点では、システム管理者 LDPA グループのユーザーとして Windchill にログインしているときに、 > > という UI ナビゲーションパスでアクセスできます。この UI は、システム管理者が PTC テクニカルサポートを含むローカルシステムとリモートシステムの両方に Windchill のシステム情報とコンフィギュレーション情報を収集、保存、および送信するために使用できる機能を提供します。
システム設定コレクターのディレクティブは、Windchill システムに関する適切な情報を一度に可能なかぎり多く収集することを許可しています。ユーザーは、収集された情報をただちに使用して、Windchill インスタンスでシステム上またはコンフィギュレーション上の問題が発生する可能性があるかどうかを診断できます。
システム設定コレクターページでは、システム管理者は、問題のカテゴリ (パフォーマンス関連の問題や実行時関連の問題など) を選択できます。多数の対応するプラグインが実行されます。実行されるプラグインのリストは、UI 上でそれぞれのカテゴリのルートのツリーノードを展開することによって確認できます。プラグインごとに、現在の Windchill システムおよびコンフィギュレーションの離散セットが収集されます。たとえば、一部のプラグインは、Windchill メソッドサーバーのログ、xconf プロパティファイル、JMX Mbean のコンフィギュレーション情報、データベース情報などの情報を収集します。
プラグインは、システム設定コレクターのカテゴリ別にタスクを実行するための手段です。これらのプラグインは、SQL および QML スクリプト、java コマンドユーティリティ (main() メソッドを含んでいる)、Windchill WinDU タスクなどの Java を使用して実行できるタスクを実行するように設計できます。
プラグインは、特定の機能をシステム設定コレクターに追加する、1 つまたは複数のカテゴリの一連のソフトウェアオペレーションから成ります。システム設定コレクターは、提供されている機能を PTC R&D、PTC グローバルサービス、PTVC テクニカルサポート、および PTC ユーザーがカスタマイズできるようにするプラグインアーキテクチャを使用して設計されています。このプラグインアーキテクチャにより、開発者は機能を拡張したり、使用している Windchill システム上のシステム設定コレクターに新しい機能を追加したりできます。したがって、新しいプラグインがシステム設定コレクターによって認識されるようにするために Windchill サーバーを再起動する必要はありません。このプラグインアーキテクチャにより、開発されたプラグインをただちに使用できます。
システム設定コレクタープラグインは、このプラグインアーキテクチャを基盤にしており、ほかの Java システム、データベース、WinDU タスク、スクリプトなどに対しても実行できるため、きわめて強力な機能です。
プラグインは、JMX Management Bean (MBean) でもあります。したがって、Windchill 付属の JConsole や VisualVM などの JMX コンソールを介してプラグインを管理できます。MBean インタフェースを使用すると、プラグインをより簡単に管理および展開できます。
システム設定コレクターとその使用法の詳細については、
システム設定コレクターを参照してください。
JMX MBeans の詳細については、
Windchill MBeansを参照してください。
範囲/適用可能性/前提条件
範囲は、システム設定コレクター UI ページとそのページで実行されるプラグインの作成に限定されます。
たとえば、Windchill システムに問題があり、診断を行う必要がありますが、現在使用できるプラグインにはこの問題を診断するために必要な機能がないとします。
既存のプラグインの機能を拡張するとします。
予測される結果
プラグインが適切に設計され、作成されて、Windchill で展開されていれば、このプラグインはシステム設定コレクターページでただちに使用できます。このプラグインは、診断を行うために役立つ、その設計目的である機能を実行します。
プラグインを作成し、展開した後に、システム設定コレクター UI を再表示すると、展開したプラグインを利用できるようになります。次のスクリーンショットでは、プラグインはユーザー定義の「Custom Plugins」カテゴリに追加されています。このカテゴリには、カスタム作成された Tomcat Property Config File というプラグインのみが含まれています。詳細については、セクション「サンプルコード」を参照してください。
これで、ユーザーが作成した任意のカテゴリでこのプラグインを利用し、それに応じてプラグインを実行できます。
JMX コンソールを介してカスタムプラグインを利用することもできます。Windchill システムにプラグインを作成し、展開した後に、JMX コンソールを介してそのプラグインをロードし、実行することができます。これが可能なのは、各プラグインが JMX MBean でもあるからです。
ユーザーは、まず CustomerSupport MBean で reloadPlugins() MBean オペレーションを実行する必要があります。次のスクリーンショットを参照してください。これにより、プラグインアーキテクチャがすべての MBean を再読み込みし、以前に展開されていたカスタムプラグインを検索します。
このプラグインが再読み込みされると、カスタム作成されたプラグインがプラグインの「MBean」リストに表示されます。
この場合、新しくロードされたプラグインは "TomcatConfigProperties" MBean です。詳細については、セクション「サンプルコード」を参照してください。
これで、JMX コンソールを介してこのプラグインの属性を編集したり、このプラグイン (のオペレーション) を実行したりできます。さらに、既存のカスタムカテゴリにカスタムプラグインを追加できます。JMX MBeans の使用法の詳細については、ドキュメンテーションを参照してください。
JMX MBeans の詳細については、
Windchill MBeansを参照してください。
作成されたプラグインは、システム設定コレクター UI または JMX コンソールから実行されます。
ソリューション
システム設定コレクター UI または JMX コンソールでカスタムプラグインを設計、開発、展開、および実行します。
前提となる知識
このソリューションを適用するには、次のことを理解している必要があります。
• Java を使用した基本的な開発 - プラグインを開発するために必要です。
• Java Management Beans の知識 - 複雑なプラグインを開発するために役立ちます。
• Java Jar Service Provider の知識 - プラグインの展開を理解するためために役立ちます。
ソリューションエレメント
エレメント | タイプ | 説明 |
| | |
PluginMBean | Java クラス - インタフェース | 前述のとおり、各プラグインは MBean であり、PluginMBean インタフェースを実装する必要があります。このインタフェースは、プラグインが MBean として使用されることを確保すると同時に、プラグインを実装するために必要な契約を指定します。このクラスは、追加の機能を提供するために、新しいインタフェース階層に拡張できます。 このクラスの実装により、プラグインは JMX コンソールから実行できる属性とオペレーションを公開できます。 このクラスには、MBean の属性とオペレーションを実装するためのプライマリ API が含まれています。 |
AbstractPlugin | Java クラス - 抽象 | プラグインの PluginMBean インタフェースを実装する際の複雑さのほとんどをラップする抽象クラス。このクラスは、このクラスを拡張するクラスからの継承を介して使用できるメソッドの具象実装を提供します。 これは、すべてのプラグインのベースとなる親クラスであり、カスタムプラグインを作成するときは、このクラスを直接または階層的に拡張する必要があります。 |
SelfAwareMBean | Java クラス - 抽象 | プラグインは、SelfAwareMBean です。つまり、プラグインは、その固有の MBean ObjectName を認識している標準の MBean であり (前述のとおり)、MBean レジストリに重複して登録されることはありません。 すべてのカスタムプラグインが、プラグインを SelfAwareMBean として登録するために、プラグインコンストラクタ () で super() の呼び出しを実装します (セクション「サンプルコード」を参照)。基本クラス AbstractPlugin は、プラグインを SelfAwareMBean として登録するためのメソッド呼び出しを実装します。 各プラグインは最終的には SelfAwareMBean を拡張する基本クラス AbstractPlugin から継承されるため、プラグインはすべて SelfAwareMBean であると言えます。 |
com.ptc.customersupport.plugins | Java パッケージ | この Java パッケージには、PTC が提供するすべてのプラグイン実装が含まれています。このパッケージには、多くの必須メソッドのデフォルト機能を提供することによって多くのプラグインの実装を容易にする抽象ソースファイルが含まれています。 具体的には、このパッケージには以下の Java 抽象クラスが含まれています。 AbstractMultipleFilePlugin AbstractQMLPlugin AbstractReportingPlugin AbstractSQLPlugin AbstactWinDUPlugin AbstractXconfPlugin GatherFilePlugin GatherFolderPlugin GatherLogsPlugin GatherEveryLogPlugin これらのプラグインの機能は、Java 継承を介して直接使用できます。これにより、共通のタイプのプラグイン機能のプラグイン実装がより簡単になります。 |
AbstractMultipleFilePlugin | Java クラス - 抽象 | このクラスは、プラグインに必要な共通の機能をまとめて、ファイルのリストを収集します。 |
AbstractQMLPlugin | Java クラス - 抽象 | このクラスは、プラグインに必要な共通の機能をまとめて、QML (Query Markup Language) ファイル/スクリプトを実行します。通常、これらのスクリプトのファイル拡張子は .qml です。 |
AbstractReportingPlugin | Java クラス - 抽象 | このクラスは、プラグインに必要な共通の機能をまとめて、Windchill Business Reporting に対してプラグインを実行します。 |
AbstractSQLPlugin | Java クラス - 抽象 | このクラスは、プラグインに必要な共通の機能をまとめて、SQL (Structured Query Language) ファイル/スクリプトを実行します。 |
AbstractWinDUPlugin | Java クラス – 抽象 | このクラスは、プラグインに必要な共通の機能をまとめて、WinDU (Windchill Diagnostic Utilitiy) タスクを実行します。 |
AbstractXconfPlugin | Java クラス – 抽象 | このクラスは、プラグインに必要な共通の機能をまとめて、親 xconf ファイルから参照されている xconf ファイルを再帰的に識別します。 |
GatherFilePlugin | Java クラス - 抽象 | このクラスは、プラグインに必要な共通の機能をまとめて、単一のファイルを収集します。 |
GatherFolderPlugin | Java クラス – 抽象 | このクラスは、プラグインに必要な共通の機能をまとめて、親とすべての子ディレクトリを収集します。 |
GatherLogsPlugin | Java クラス - 抽象 | このクラスは、プラグインに必要な共通の機能をまとめて、ログファイルのディレクトリを収集します。このクラスは、GatherFolderPlugin と似ていますが、ファイルの所定の日付範囲、具体的にはファイル修正時間に適用されます。 |
GatherEveryLogPlugin | Java クラス - 抽象 | このクラスは、プラグインに必要な共通の機能をまとめて、ログファイルのディレクトリを収集します。このクラスは、GatherFolderPlugin と似ていますが、ファイルの所定の日付範囲、具体的にはファイル修正時間を無視します。したがって、これはすべてのログファイルに適用されます。 |
CollectorMBean | Java クラス - インタフェース | プラグインが対象とするデータを収集する方法に関する契約を指定する Java MBean インタフェース。AbstractPlugin が実装の詳細を処理するため、この MBean がプラグインによって直接実装される必要はありません。 |
Collector | Java クラス | CollectorMBean インタフェースの具象実装クラス。これは、すべてのプラグインがファイル収集を行うために実質的に依存するクラスです。 |
collect(…) | Java メソッド | 2 つの collect(…) メソッドは、PluginMBean インタフェースの一部であり、すべてのプラグインによって実装される必要があります (すべてのプラグインが PluginMBean インタフェースを実装するため)。 これらのメソッドは、Collector クラスと対話するために必要な API を指定し、最終的にはプラグインの機能を実行します。 一般的に、AbstractPlugin とプラグイン階層内のその他の抽象クラス (上記を参照) は、依存できる collect(…) メソッドのデフォルト実装を提供します。具体的には、多くの場合、AbstractPlugin.java の collectData(…) メソッドは、単純に collect(…) メソッドによって呼び出すことができます。ただし、特異なニーズを処理する高度なプラグインの場合は、これらのメソッドを直接オーバーライドし、実装する必要があります。このようなケースはまれであり、プラグインが単にファイルの収集だけを行うのではなく、いくつかの Java プロセスを実行したり、ファイルの収集が必要となる処理を行うオペレーションを個別に呼び出したりする必要がある場合にのみ発生します。 com.ptc.customer support.plugin.* パッケージに、これを行うプラグインがあります。これらのプラグインは、具体的には MBeanDumpPlugin.java、WDSPlugin.java、および AbstractWinduPlugin.java で例として参照できます。 PluginMBean インタフェースはユーザーがデータを収集できることを 2 つの方法で指定するため、実装する必要がある collect(…) は 2 つあることに注意してください。1 つの API には callNumber パラメータが必要で、もう 1 つの API には topicIdentifier が必要です。これらのパラメータはそれぞれ、収集された情報が保存される場所を示します。 このメソッドには特定のマップの戻り値が必要です。戻り値とこのメソッドの詳細については、セクション「カスタマイズポイント」の「プラグインの抽象化」を参照してください。 |
collectData(…) | Java メソッド | AbstractPlugin.java の collectData(…) メソッドは、PluginMBean インタフェースの collect(…) メソッドを実装する際の複雑さのほとんどをラップします。このメソッドは、プラグインが指定する方法で公表メッセージが各サーバーに整列されるように設定します。これはまた、必要とされる戻り Map 値を正しく構築します。このメソッドは、コレクションフレームワークを直接使用する際の複雑さをラップするため、しばしば collect(…) メソッドが依存することがあります。ほとんどのプラグインにおいて、このメソッドは単純に適切なパラメータ値で呼び出すことができます。 このメソッドには特定のマップの戻り値が必要です。戻り値とこのメソッドの詳細については、セクション「カスタマイズポイント」の「プラグインの抽象化」を参照してください。 |
PluginType | Java クラス | これは、Java 列挙タイプクラスです。プラグインは初期化時に PluginType の列挙タイプのいずれか 1 つを指定するので、Collector クラスはどのような処理を実行し、収集した情報をファイルシステムのどこに配置する必要があるかを認識しています。 |
PluginUtilities | Java クラス | これは、collect(…) メソッドのデフォルトの動作に依存しない高度なプラグインを作成するために役立つユーティリティメソッドを提供する Java クラスです。特に重要なのは、collect(…) メソッドが必要とするマップの戻り値を構築する getReturnMap(boolean, String, String) メソッドです。これは、特定の動作をする collect(…) メソッドを実装する高度なプラグインの実装を簡素化するために役立ちます。 |
PluginPropertyUtils | Java クラス | これは、高度なプラグインを作成するために役立つプロパティ情報用のユーティリティメソッドを提供する Java クラスです。このクラスは、xconf が管理するプロパティ値情報を取得するためのメソッドと、トークン化された xconf パスを完全修飾基準パスに解決するための手段を提供します。 |
*Resource | Java クラス | プラグインの文字列は、さまざまなロケールで表示できるようにローカライズされる必要があります。com.ptc.customersupport.mbeans.plugin* パッケージには、リソースクラスが含まれています。これらの Java リソースクラスは、ローカライズでき、Java ソースコードで使用できる文字列を維持します。 プラグインは、これらのリソースファイルまたは新しいリソースファイルを利用して、ローカライズされた文字列を提供できます。 |
<ファイル名>.jar | Java JAR ファイル | これは、標準の Java .jar ファイルであり、任意の名前を付けることができます。.jar ファイルは、システム設定コレクターで使用されるためにカスタムプラグインを展開する一般的な方法です。 .jar ファイルには、プラグインおよび Java ヘルパークラス用のコンパイルされた .class ファイルと PluginMBean サービスファイル (下記を参照) が含まれています。.jar ファイルでは、.class ファイルとサービスファイルに対して、パッケージのディレクトリ構造が維持されている必要があります。 Java Jar ファイルの仕様の詳細については、セクション「その他のリソース」を参照してください。 |
com.ptc.customersupport.mbeans.PluginMBean | Java JAR サービスファイル | これは、Java .jar ファイルに含まれているサービスファイルであり、これにより、システム設定コレクターの Java クラスローダーは新しいプラグインが展開されたかどうかを確認できます。ファイル構造は厳格で、維持される必要があります。維持されなければ、Java クラスローダーの問題が発生し、プラグインはロードされないか、使用できません。.jar ファイルには、META-INF\services に com.ptc.customersupport.mbeans.PluginMBean ファイルが含まれている必要があります。このファイルの内容は、次のタイプである必要があります。 <java ソースパッケージ><プラグインクラス名> (括弧なし) Java Service Provider インタフェースの詳細については、セクション「その他のリソース」を参照してください。 |
前述のように、プラグインパッケージには、プラグイン開発者がプラグインを作成するために依存できる Java 継承の階層が含まれています。下の UML 図は、抽象クラスと MBean インタフェース API の階層関係を示しています。
上記のように、すべてのプラグインが PluginMBean インタフェースを実装し、最終的には AbstractPlugin クラスを拡張します。カスタムプラグインは、プラグイン階層と、いずれかの抽象クラスによって提供される機能を利用できます。
手順 - カスタムプラグインの作成
以下のセクションでコードの断片として使用されている CustomPlugin.java クラス全体については、セクション「サンプルコード」を参照してください。
プラグインをシステム設定コレクターまたは JMX コンソールで使用するには、その前に 4 つの段階が完了している必要があります。
1. プラグインの設計
2. プラグインの実装
3. プラグインのコンパイル
4. プラグインの展開
プラグインの設計
システム設定コレクターで使用するプラグインを設計するときには、以下の事項を考慮する必要があります。
1. プラグインのクラス名に "Plugin" が含まれている必要はありませんが、含まれていると便利です。クラス名のサフィックスとして "Plugin" を含めることにより、その目的を簡単に識別できます。プラグインのソースファイル名は、<クラス名>Plugin.java という形式である必要があります。<クラス名> もプラグインの目的を示す名前であると便利です。たとえば、PTC 提供の SiteXConfPlugin は、<Windchill>/site.xconf ファイルを収集します。
2. プラグイン開発者は、プラグインで妥当な Java パッケージ構造を維持する必要があります。一般的に、PTC 提供のプラグインでは、その目的と PluginType に関連するパッケージ構造が維持されています (PluginType クラスの詳細については、セクション「ソリューション」を参照してください)。PTC のプラグインの多くは、com.ptc.customersupport.mbeans.plugins パッケージに含まれています。カスタムプラグインをこのパッケージに含めると、カスタムプラグインを簡単にデバッグできるだけではなく、カスタムプラグインの展開後の場所を識別することもできます。これは厳守する必要のある要件ではなく、パッケージ構造は開発者が設定できます。
3. すべてのプラグインが PluginMBean インタフェースを実装する必要があります。PluginMBean インタフェースクラスを実装することにより、プラグインは JMX コンソールから実行できる属性とオペレーションを公開できます。さらに、PluginMBean クラスにより、すべてのプラグインが順守する必要のある、コレクションフレームワークにとってはきわめて重要な API 契約が確実に履行されます (セクション「ソリューション」の CollectorMBean および Collector クラスの説明を参照してください)。
4. すべてのプラグインが AbstractPlugin クラスを拡張する必要があります。AbstractPlugin は、PluginMBean インタフェースを実装する際の複雑さのほとんどをラップします。これにより、プラグインの作成において共通して使用される多くのメソッドのデフォルト実装が提供されます。当然、メソッドのデフォルトの実装は、各種機能を提供するためにオーバーライドできます。
以下に例を示します。
public class CustomPlugin extends AbstractPlugin
implements PluginMBean {}
この例は、PluginMBean インタフェースを実装し、AbstractPlugin クラスを拡張する CustomPlugin クラスを示しています。この例ではインタフェースの必須メソッド、つまり collect(…) メソッドが実装されておらず、この単純なクラスはコンパイルされないことに注意してください。Windchill に付属するサンプルプラグイン実装全体を確認するには、セクション「サンプルコード」を参照してください。
5. すべてのプラグインオブジェクトコンストラクタがスーパークラスのメソッド呼び出しを行う必要があります。これは、すべてのプラグインが SelfAwareMBean として初期化される必要があるからです (SelfAwareMBean の詳細については、セクション「ソリューション」を参照してください)。すべてのプラグインがプラグイン階層を通じて AbstractPlugin クラスを拡張する必要があるため、AbstractPlugin クラスがプラグインを SelfAwareMBean として登録するために適切なメソッド呼び出しを行います。したがって、プラグイン開発者は、実際のプラグインの MBean の登録については考慮する必要はなく、プラグインが構築中に super() 演算子を呼び出すことと、プラグインの継承によって最終的には AbstractPlugin.java が拡張されることが確実に行われるようにする必要があるだけです。
以下に例を示します。
public CustomPlugin() throws NotCompliantMBeanException {
super(null);
// TODO Other initialization of this particular plugin
}
public CustomPlugin(final String displayName,
final String beanName, final String description,
final String pluginVersion)
throws NotCompliantMBeanException {
super(null, displayName, beanName, description, pluginVersion);
// TODO Other initialization of this particular plugin
}
これらのコンストラクタは、AbstractPlugin のコンストラクタを一致させ、super 演算子を通じて AbstractPlugin の呼び出しを行うために実装されます。これにより、CustomPlugin が SelfAwarePlugin として登録されます。
コンストラクタによる super の呼び出しでは、クラスオブジェクトが使用されます。具象クラスが判明している場合はそれを指定でき、判明していない場合は null を使用できます。Java は、イントロスペクションを使用してクラス名を決定します。たとえば、CustomPlugin は PluginMBean を実装するので、super の呼び出しは次のように設定することもできます。
super(PluginMBean.class);
より簡潔なコンストラクタを設計するには、継承に依存するオプションを調べてみてください。
6. PluginMBean インタフェースを実装し、AbstractPlugin を拡張するので、プラグインは 2 つの collect(…) メソッドを実装する必要があります。これらのメソッドは、本質的には、Collector クラスとコレクションフレームワークに対して作業を編成し、引き渡します。
以下に例を示します。
@Override
public Map<String, Object> collect(final long callNumber,
final long maxAgeInDays,final long minAgeInDays,
final String pathTimeStamp) {
// TODO Do actual collection work and return correct Map
return null;
}
@Override
public Map<String, Object> collect(String topicIdentifier,
final long maxAgeInDays, final long minAgeInDays,
final String pathTimeStamp) {
// TODO Do actual collection work and return correct Map
return null;
}
ここに示されている collect(…) メソッドの実装は、特別な処理は行わず、単に明確に説明することを目的としています。これらは、プラグインコレクションが実行する必要のある作業を行い、必要とされる正しい Map<文字列、オブジェクト> 値を返します。
抽象クラスを通じて依存できる collect(…) メソッドのデフォルト実装には多数あります。多くの場合、プラグインは、collect(…) メソッドのパラメータを collectData(…) メソッドに渡すことによって AbstractPlugin.java の collectData(…) メソッドを呼び出す必要があるだけです。collectData(…) メソッドは、collect(…) メソッドで直接コレクションフレームワークを呼び出す際の複雑さをラップします。collect(…) メソッドは、PluginMBean インタフェース API に必要不可欠です。非常に高度なプラグインでは collectData(…) のデフォルトの動作だけでは十分ではないので、開発者が必要に応じて collect(…) メソッドを実装するためには、その柔軟性が必要であるからです。さらに、抽象クラスは、その他のメソッドにも依存できます。これらのメソッドの多くが collectXYZ(…) という形式であり、特定のプラグインの collect(…) メソッドの実装によって呼び出すことができます。これらの collect (…) メソッドは、プラグインが行う作業の抽象タイプの特定の収集実装をラップします。たとえば、GatherFolderPlugin.java クラスには、収集対象の特定のフォルダを (プラグインの初期化で正しく設定されていれば) コレクションフレームワークに渡すように実装されている collect(…) メソッドがあります。
collect(…) メソッドは Map<文字列、オブジェクト> を返す必要があります。この戻り Map 値は、プラグインが実行されたサーバーとプラグインのステータスを確認するためにプラグインフレームワークによって使用されます。この戻り値は、実際には Map; Map<String, Map<文字列、文字列>> 内の Map です。外側の Map にはサーバー情報が含まれていますが、内側の Map にはそのサーバーのプラグイン実行ステータスが含まれています。
カスタマイザが collect(…) メソッドのデフォルト実装に依存せず、抽象クラスの親 collectData(…) またはその他の collect(…) メソッドのどちらかを使用する場合は、戻り Map 値が正しく構築されており、それに有効な値が含まれていることを慎重に確認する必要があります。
collect(...) のデフォルト実装の使用と、メソッドの戻り Map<文字列、オブジェクト> 値の詳細については、セクション「カスタマイズポイント」を参照してください。
7. 最後に、プラグインが行う必要のある実際の作業と、それを行うための最適な方法を検討します。これを行うには、さまざまなクラスを連動して処理を行うように組み合わせたり、すべての処理を 1 つのクラスにラップしたりします。
さらに、セクション「ソリューション」で説明されているようにプラグイン実装を簡素化するために使用できるユーティリティメソッドと抽象クラスが多数あります。プラグインは、プラグインの作成目的であるタスクに応じて、非常に複雑に設計することも、非常にシンプルに設計することもできます。
8. 要するに、適切に設計されているプラグインは、少なくとも以下の特性を持っている必要があります。
◦ PluginMBean インタフェースを実装する。
◦ 直接または継承を通じて AbstractPlugin クラスを拡張する。
◦ 2 つのコンストラクタが super() 演算子を使用して最終的には AbstractPlugin を呼び出す。
◦ 2 つの collect(…) メソッド (親 collect(…) の実装に依存しない場合) を使用する。
プラグインの実装
プラグインの実装は、プラグインに代わって実際の作業を行うコードです。その主な処理は、プラグインが正しく初期化されており (前述の設計に関するステップを参照)、必要なインタフェースが実装されていることを確認することです。最後に、プラグインが作業を行うために必要なメソッドの実装を提供します。
1. プラグインの初期化
プラグインの構築中、オブジェクトはその MBean 属性を初期化する必要があります (プラグインはすべて MBean です)。設計段階の例を使用して、コンストラクタのメソッドを拡張できます。
public CustomPlugin() throws NotCompliantMBeanException {
super(null);
// super(PluginMBean.class);
initializeMBeanAttributes();
}
private void initializeMBeanAttributes() {
if (logger.isDebugEnabled()) {
logger.debug("Initializing " + CUSTOM_PLUGIN_NAME + " Plugin.");
}
// set the plugin display name
setDisplayName(CUSTOM_PLUGIN_NAME);
// set the plugin description
setDescription(CUSTOM_PLUGIN_DESCRIPTION);
// set the plugin MBean name
setMBeanName("TomcatConfigProperties");
// set the plugin enumerated type
setPluginType(PluginType.MISC);
// set the plugin version number
setPluginVersion("1.0");
// set whether the plugin relies on database
// administrator credentials
setDbCredentialsNeeded(false);
// set whether the plugin operates on each
// cluster node
setClusterAware(true);
// set whether the plugin relies on file
// date ranges for data collection
setDateRangeUsed(false);
// set whether the plugin should compress the
// output of its data collection
setCompressOutput(false);
}
ここでは、コンストラクタは、公開されている MBean 値を含むすべてのプラグインの属性を初期化するプライベートメソッドが含まれるように拡張されています。
setMBeanName パラメータの値は、適切な形式の MBean オブジェクト名である必要があります。Mbean ローダーで問題が発生することを回避するために、文字列名にスペースを含めないでください。MBean オブジェクト名の構文の詳細については、セクション「その他のリソース」の「関連 Web サイト」を参照してください。
2. プラグインの collect(…) メソッド
プラグインの作業の大部分は collect(…) メソッドに含まれており、実装の詳細はプラグイン開発者が実装するかどうかを決定します。例については、セクション「サンプルコード」を参照してください。
高度なプラグインでは、一般的に、作業は collect(…) メソッドが処理するには大規模であるため、Java ヘルパークラスとプライベートヘルパーメソッドを実装すると役立ちます。これにより、プラグインで個別のメソッドを使用でき、保守が簡単になります。ヘルパーメソッドの実装は、プラグインと開発者の判断のみに基づいて行われるため、具体的でもあり、プラグインの実装者によって異なります。collect(...) メソッドの詳細については、セクション「カスタマイズポイント」を参照してください。
3. プラグインのローカライズ
Windchill は分散型アプリケーションであり、さまざまなロケールにクライアントが存在する可能性があるので、プラグインで外部化されているすべての Java 文字列をローカライズすることは非常に重要です。
特に重要な文字列は、プラグインの名前と説明です。これらの値は、システム設定コレクター UI でユーザーに対して表示されます。
com.ptc.customersupport.plugins.* パッケージには、多くのプラグインで参照されている、同じパッケージ内にあるさまざまな *Resource.java ファイルが含まれています。これらの *Resource.java ファイルには、MBean プラグインの初期化中にローカライズされ、読み取られるパブリック文字列参照値が含まれています。
ただし、常に Java 文字列をローカライズできるとはかぎりません。値がローカライズされていないと、入力されている値 (上記の例では英語) が使用され、クラスファイルにコンパイルされます。
CustomPlugin の例を使用して、新しいプラグインのメンバー変数を追加します。
private static ResourceBundle RESOURCE =
ResourceBundle.getBundle(
CustomPluginResource.class.getName());
これが、ローカライズ済み Java 文字列が配置される場所への参照になります。CustomPlugin は、この参照を使用して、ローカライズされた値を読み込むことができます。リファクタリングされた setDisplayName(string) メソッドと setDescription(string) メソッドは、次のようになります。
// set the localized plugin display name
setDisplayName(MBeanUtilities.formatMessage(
RESOURCE.getString(
CustomPluginResource.CUSTOM_PLUGIN_NAME)));
// set the localized plugin description
setDescription(MBeanUtilities.formatMessage(
RESOURCE.getString(
CustomPluginResource.CUSTOM_PLUGIN_DESC)));
ローカライズ済み文字列 CUSTOM_PLUGIN_NAME および CUSTOM_PLUGIN_DESC は、正しくローカライズされているクラスファイルから読み込まれます。
注記: プラグインのローカライズ済み文字列は、プラグインの初期化中にサーバーから読み取られるため、サーバーのロケールの影響を受けます。ローカライズされた値は、システム設定コレクター UI のクライアントのロケールではなく、サーバーのロケールに従って表示されます。
プラグインのコンパイル
すべてのプラグインファイルを実装したら、次にこれらを .class ファイルにコンパイルする必要があります。Windchill を実行している Java jdk バージョンを使用して、クラスファイルの互換性が適切であることを確認します。javac コマンドを使用して Java ソースファイルをコンパイルする方法については、セクション「その他のリソース」の「関連 Web サイト」を参照してください。
プラグインの展開
最後に、プラグインのパッケージ化されたファイルをバンドルし、Windchill に展開する必要があります。セクション「プラグインのコンパイル」で説明されているように、システム設定コレクターは、Java クラスローダーを使用して、カスタムプラグインであるすべてのファイルをロードします。クラスローダーがプラグインを認識できるようにするために、サービスファイルを作成し、プラグインとともに展開する必要があります (このファイルについては、「ソリューションエレメント」と「関連 Web サイト」を参照してください)。
機能的に展開されたプラグインを設定する手順は、次のとおりです。
1. ファイルをパッケージ化します。
2. ファイルを JAR ファイルにします。
3. JAR ファイルを展開します。
1. パッケージ化されたソースのディレクトリのルートに META-INF という名前のディレクトリを作成します。そのディレクトリ内に services という名前のサブディレクトリを作成します。services ディレクトリ内に com.ptc.customersupport.mbeans.PluginMBean というテキストファイルを作成します。これが、クラスローダーがプラグインのクラスファイルについて調べるサービスファイルです。このファイルは、ロードするプラグインごとに作成する必要があり、また厳密な構文フォーマットに従っている必要があります。サービスファイル内のプラグインエントリのフォーマットは、次のとおりです。
<java ソースパッケージ>.<プラグインクラス名> (括弧なし)
たとえば、CustomPlugin の例に戻ると、対応するサービスファイルには次の 1 行しか含まれていません。
com.ptc.customersupport.mbeans.plugins.CustomPlugin
ここに、CustomPlugin のソース、クラスファイル、およびサービスファイルのパッケージ構造の例を示します。
以下の点に注意してください。
◦ CustomPlugin のソースへのパッケージ構造 com/ptc/customersupport/mbeans/plugins は維持する必要があります。
◦ .class ファイルは /plugins ディレクトリにあります。オプションで、.java ソースファイルをこのディレクトリに配置することもできます。
◦ META-INF/services ディレクトリが存在します。
◦ /services ディレクトリにはロードされるプラグインごとにエントリがある com.ptc.customersupport.mbeans.PluginMBean が含まれています。
2. パッケージ構造とサービスファイルを作成したら、これらのファイルを Java .jar ファイルにバンドルする必要があります。Java の jar コマンドの詳細については、「関連 Web サイト」を参照してください。
windchill シェルを使用して、ルートのパッケージがある場所に移動し、.jar ファイルを作成します。
パッケージ構造を示す上記の例に戻り、
jar cvfM CustomPlugin.jar ./com ./META-INF
というコマンドを実行すると、/com ディレクトリと /META-INF ディレクトリのサブディレクトリを含むすべての内容を格納する CustomPlugin.jar が生成されます。
3. 最後に、この .jar ファイルをシステム設定コレクターのクラスローダーがある場所に展開する必要があります。このファイルをコピーして、<Windchill>/utilities/SystemConfigurationCollector/plugins ディレクトリに配置します。
これで、プラグインをシステム設定コレクターページで使用できる状態になりました。プラグインを使用するには、ブラウザを再表示し、カスタムプラグインをカスタムカテゴリに追加します。カスタムカテゴリの作成の詳細については、システム設定コレクターの使用方法に関するヘルプを参照してください。
システム設定コレクターとその使用法の詳細については、
システム設定コレクターを参照してください。
プラグインはすべて MBean であるため、JMX コンソールで使用するプラグインを展開することもできます。JMX コンソールを使用して CustomerSupport MBean に移動し、reloadPlugins() オペレーションを実行します。このオペレーションにより、プラグインの MBean ローダーが使用可能なすべてのプラグイン (展開場所にあるものも含む) を再読み込みします。次のスクリーンショットは、ユーザーが reloadPlugins CustomerSupport MBean オペレーションを呼び出しているところを示しています。
reloadPlugins CustomerSupport MBean オペレーションを呼び出したら、プラグインが定義されている個別のプラグインタイプのサブディレクトリにある com.ptc/plugins MBean の下にカスタムプラグインが表示されます。
JMX コンソールからプラグインを再読み込みする方法の詳細とイメージについては、「予測される結果」を参照してください。
カスタマイズポイント
PluginMBean インタフェースの拡張
必ずしもプラグインが PluginMBean インタフェースを直接実装する必要はありません。代わりに、PluginMBean インタフェースを拡張する新しいインタフェースを定義し、具象プラグイン実装によって実装することができます。ただし、新しいプラグインのインタフェースは PluginMBean インタフェースを継承する必要があります。
以下に例を示します。
publicinterface XYZPluginMBean extends PluginMBean {}
ここでは、XYZPluginMBean が PluginMBean を拡張します。このインタフェースでは、さらに、MBean オペレーションを介して公開される必須メソッドまたは属性を定義できます。
具象実装は次のようになります。
publicclassXYZPluginextends AbstractPlugin implements XYZPluginMBean {}
プラグインの抽象化
「PluginMBean インタフェースの拡張」セクションの内容と似ていますが、開発者は、プラグインの MBean 値をデフォルト値に初期化するために、「ソリューションエレメント」で説明したさまざまな抽象クラス、または開発者が定義する抽象クラスに依存できます。前述のとおり、抽象クラスは、プラグインを作成する際の複雑さのほとんどをラップします。開発者は、プラグインの実装のために抽象クラスに依存するだけではなく、collect(…) メソッドの抽象実装にも依存することができます。
AbstractPlugin.java API: public AbstractPlugin(final Class mbeanInterface) throws NotCompliantMBeanException
パラメータ | デフォルト値 | 有効な値 | 必須 | 説明 |
mbeanInterface | なし | クラス | はい | プラグインの具体化であるクラス名。 |
AbstractPlugin.java API: public AbstractPlugin(final Class mbeanInterface, final String displayName, final String mBeanName,
final String description, final String pluginVersion) throws NotCompliantMBeanException {
パラメータ | デフォルト値 | 有効な値 | 必須 | 説明 |
mbeanInterface | なし | クラス | はい | プラグインの具体化であるクラス名。 |
displayName | なし | 文字列 | はい | プラグインの名前の文字列表現。 |
mBeanName | なし | 文字列 | はい | プラグインの MBean の名前の文字列表現。この値は、適切な Java MBean ObjectNames に従っている必要があります。MBean オブジェクト名については、「関連 Web サイト」を参照してください。 |
description | なし | 文字列 | はい | プラグインの説明の文字列表現。 |
pluginVersion | なし | 文字列 | はい | このプラグインに関連付けられているバージョン番号。 |
AbstractPlugin.java API: publicabstract Map<文字列、オブジェクト> collect(long callNumber, long maxAgeInDays, long minAgeInDays, String pathTimeStamp);
このメソッドは抽象なので、開発者はこのメソッドを実装する必要があります。これは、プラグインの作業を行うためのエントリポイントとして UI レイヤーによって呼び出されます。
パラメータ | デフォルト値 | 有効な値 | 必須 | 説明 |
callNumber | なし | long | はい | これは、PTC テクニカルサポートの電話番号に関連した long 値です。これは、プラグインデータを収集する場所として使用されます。この値は、collect(…) メソッドを実行することで、修正する必要はありません。 |
maxAgeInDays | なし | long | はい | ファイルが時間に関連して収集される場合のための、開始時間の値である long 値この値は、collect(…) メソッドを実行することで、修正する必要はありません。 |
minAgeInDays | なし | long | はい | ファイルが時間に関連して収集される場合、終了時間の値である long 値。この値は、collect(…) メソッドを実行することで、修正する必要はありません。 |
pathTimeStamp | なし | 文字列 | はい | プラグインのデータを収集する先の名前として使用されるディレクトリのタイムスタンプの文字列表現。この値は、collect(…) メソッドを実行することで、修正する必要はありません。 |
開発者は、通常、このメソッドのパラメータを AbstractPlugin.java の collectData(…) メソッドに渡すことができます。前述のとおり、collectData(…) メソッドは、コレクションフレームワークを呼び出す際の複雑さを処理します。
開発者は、collectData(…) または抽象クラスの親 collectXYZ(…) メソッドの実装に依存しない方法で collect メソッドを実装できます。ただし、一般的に、これは例外です。収集対象のファイルを構築するための処理をいくらか行う Java プロセスの実行などの特殊な作業を必要とする高度なプラグインのみが、親 collect(…) メソッドの実装に依存しなくて済みます。このような場合でも、Java プロセスが完了し、そのデータが生成された後に、実際の収集を行うためにまだ親クラスに依存することがあります。MBeanDumpPlugin.java と WDSPlugin.java は、親 collect メソッドを呼び出す以外の作業を行う PTC 提供の 2 つのプラグインです。非常に複雑なプラグインを構築したい開発者は、これらのプラグインについてさらに詳しく調べてください。
戻り値 | 有効な値 | 必須 | 説明 |
Map<文字列、オブジェクト> | <文字列、オブジェクト> タイプの Map (Object は <文字列、文字列> タイプのマップ、つまり Map<文字列、文字列>) | はい | リターンタイプは、内側の Map を含んでいる Map です。つまり、Map<String, Map<文字列、文字列>> です。"内側の" Map<文字列、文字列> は、プラグイン実行ステータスを含んでいる Map です。外側の Map<文字列、オブジェクト> は、プラグインが実行されているサーバーを含んでいる Map です。これにより、プラグインフレームワークは、実行されるプラグインごとに、クラスタ全体にわたって情報を報告できます。 |
collect(…) メソッドのリターンタイプを提供するときには注意が必要です。AbstractPlugin.java の collectData(…) メソッドは、プラグインフレームワークが正しく解釈する有効なリターンタイプを作成する際のすべての複雑さをラップします。これも、collect(…) メソッドの実装で collectData(…) メソッドを使用することが効果的である理由の 1 つです。そうしなければ、collect(…) メソッドを実装する際の複雑さが著しく増大します。
外側の Map: Map<文字列、オブジェクト>
String キーは、サーバープロセス ID とプラグインが実行されるサーバーのホスト名で構成されます (たとえば、5524@DSTUSYNSKI03D)。どのような文字列でも有効ですが、プラグインフレームワークは、適切に構築されていないため意味のないデータをユーザーに報告することになります。
Object は、実際には <文字列、文字列> タイプの内側の Map です。
内側の Map: Map<文字列、文字列>
内側の Map には、success、path、message、および location の 4 つのキーエントリが各 String に 1 つある必要があります。
これらのキーの値は、それぞれ、そのキーの適切な値に対応する別の文字列である必要があります。success キーの値は、true か false のどちらかであり、コレクションフレームワークがプラグインのデータの収集を正常に完了したかどうかを示す値です。path キーの値は、コレクションフレームワークによって生成され、プラグインが実行されている特定のサーバーの、収集されるプラグインのデータが配置されている基準のパスの最後のディレクトリを示します。message キーの値は、文字列メッセージであり、コレクションフレームワークによって生成されるプラグインに付随していることがあります。通常、これはプラグインが失敗した理由を示すステータスメッセージです。メッセージが報告されない場合は、null 値が使用されます。location キーの値は、コレクションフレームワークがプラグインのデータを収集する場所への部分パスを表す文字列です。
AbstractPlugin.java の collectData(…) メソッドまたはその他の親抽象クラスに依存しない場合は、必ず collect(…) メソッドのリターンタイプがこの形式に従うようにしてください。従っていなければ、プラグインフレームワークによって正しく処理されません。直接プラグインを実装し、戻り Map<文字列、オブジェクト> 値を構築する場合は、MBeanDump.java および WDSPlugin.java の実装を調べて詳細を把握してください。これらのクラスはどちらも、抽象クラスまたはコレクションフレームワークに直接依存しないので、それぞれの collect(…) メソッドの実装で正しいリターンタイプを構築します。
戻り Map 値が構築される必要のある高度なプラグインの場合、開発者は PluginUtilites.getReturnMap(…) メソッドに依存できます。これについては、このセクションで後述します。
AbstractPlugin.java API: publicabstract Map<文字列、オブジェクト> collect(String topicIdentifier, long maxAgeInDays, long minAgeInDays, String pathTimeStamp);
このメソッドは抽象なので、開発者はこのメソッドを実装する必要があります。これは、プラグインの作業を行うためのエントリポイントとして UI レイヤーによって呼び出されます。
パラメータ | デフォルト値 | 有効な値 | 必須 | 説明 |
topicIdentifier | なし | 文字列 | はい | これは、プラグインのデータの収集先の場所として使用されるディレクトリの文字列表現です。この値は、collect(…) メソッドを実行することで、修正する必要はありません。 |
maxAgeInDays | なし | long | はい | ファイルが時間に関連して収集される場合のための、開始時間の値である long 値この値は、collect(…) メソッドを実行することで、修正する必要はありません。 |
minAgeInDays | なし | long | はい | ファイルが時間に関連して収集される場合、終了時間の値である long 値。この値は、collect(…) メソッドを実行することで、修正する必要はありません。 |
pathTimeStamp | なし | 文字列 | はい | プラグインのデータを収集する先の名前として使用されるディレクトリのタイムスタンプの文字列表現。この値は、collect(…) メソッドを実行することで、修正する必要はありません。 |
このメソッドの使用の詳細については、前に登場した collect(…) メソッドを参照してください。
AbstractPlugin.java API: public Map<文字列、オブジェクト> collectData(String srcPath, finallong callNumber,
finallong maxAgeInDays, finallong minAgeInDays, String pathTimeStamp) {
パラメータ | デフォルト値 | 有効な値 | 必須 | 説明 |
srcPath | なし | 文字列 | はい | これは、プラグインのソースデータが収集される場所の文字列表現です。これは一般的に、トークン化した Windchill プロパティの文字列です。たとえば、WindchillLogsPlugin.java は、$(wt.logs.dir) をパラメータとして渡します。また、この値は収集されるデータの基準のファイルパスになります。しかし、このファイルパスはプラグインが実行されているそれぞれのサーバーに存在しない可能性もあるので、注意が必要です。基準のファイルパスを使用している場合、プラグイン属性 isClusterAware をプラグインの初期化中は false に設定して、プラグインを 1 つのクラスタノードでのみ実行する必要があります。 |
callNumber | なし | long | はい | これは、PTC テクニカルサポートの電話番号に関連した long 値です。これは、プラグインデータを収集する場所として使用されます。 |
maxAgeInDays | なし | long | はい | ファイルが時間に関連して収集される場合、開始時間の値である long 値。 |
minAgeInDays | なし | long | はい | ファイルが時間に関連して収集される場合、終了時間の値である long 値。 |
pathTimeStamp | なし | 文字列 | はい | プラグインのデータを収集する先の名前として使用されるディレクトリのタイムスタンプの文字列表現。 |
これは、プラグインのデータを収集するために直接コレクションフレームワークを使用する際の複雑さをラップするメソッドです。可能なかぎり、これがプラグインの collect(…) メソッドの実装によって呼び出されるようにしてください。多くの場合、collect(…) メソッドの実装は、このメソッドを collect(…) メソッドで呼び出し、その値を返す必要があるだけです。
このメソッドの戻り値は、前述のとおり、collect(…) メソッドの戻り値と同じです。
AbstractPlugin.java API: public Map<文字列、オブジェクト> collectData(String srcPath, final String topicIdentifier,
finallong maxAgeInDays, finallong minAgeInDays, String pathTimeStamp) {
パラメータ | デフォルト値 | 有効な値 | 必須 | 説明 |
srcPath | なし | 文字列 | はい | これは、プラグインのソースデータが収集される場所の文字列表現です。これは一般的に、トークン化した Windchill プロパティの文字列です。たとえば、WindchillLogsPlugin.java は、$(wt.logs.dir) をパラメータとして渡します。また、この値は収集されるデータの基準のファイルパスになります。しかし、このファイルパスはプラグインが実行されているそれぞれのサーバーに存在しない可能性もあるので、注意が必要です。基準のファイルパスを使用している場合、プラグイン属性 isClusterAware をプラグインの初期化中は false に設定して、プラグインを 1 つのクラスタノードでのみ実行する必要があります。 |
topicIdentifier | なし | 文字列 | はい | これは、プラグインのデータの収集先の場所として使用されるディレクトリの文字列表現です。 |
maxAgeInDays | なし | long | はい | ファイルが時間に関連して収集される場合、開始時間の値である long 値。 |
minAgeInDays | なし | long | はい | ファイルが時間に関連して収集される場合、終了時間の値である long 値。 |
pathTimeStamp | なし | 文字列 | はい | プラグインのデータを収集する先の名前として使用されるディレクトリのタイムスタンプの文字列表現。 |
このメソッドの使用の詳細については、前に登場した collect(…) メソッドを参照してください。
PluginUtilities.java API: publicstatic Map<文字列、オブジェクト>
getReturnMap(finalboolean success, final String path, final String message,
final String location) {
パラメータ | デフォルト値 | 有効な値 | 必須 | 説明 |
success | なし | ブール | はい | プラグインフレームワークのステータスとして内側の Map に配置される、プラグインの実行が正常に完了したかどうかを示す値。 |
path | なし | 文字列 | はい | プラグインフレームワークのステータスとして内側の Map に配置される、収集されるファイルが配置されている親ディレクトリを示す値。 |
message | なし | 文字列 | はい | プラグインフレームワークのステータスの内側の Map に配置されるメッセージ。 |
location | なし | 文字列 | はい | プラグインフレームワークのステータスの内側の Map に配置される、PluginType ディレクトリへの部分パス。 |
このメソッドは、collect(…) メソッドの実装で使用される戻り値を構築します。ただし、そのためには、このメソッドに正しい値がそのパラメータを介して渡される必要があります。このメソッドは、collect(…) メソッドの戻り値の作成を簡単にするユーティリティメソッドです。実質的に、これは戻り値の作成をラップするので、collect(…) メソッドの実装者は外側の Map と内側の Map を作成する必要がありません。それぞれのパラメータの説明のとおり、パラメータが内側の Map を生成するために使用され、メソッドの実装が外側の Map<文字列、オブジェクト> の生成を処理します。結果として返される値は Map<文字列、オブジェクト> で、この Object は collect(…) メソッドの戻り値として使用できる Map<文字列、文字列> (<文字列、文字列> タイプの Map) です。
これらのパラメータは必須のパラメータではありませんが、可能なかぎり使用するようにしてください。メソッドの戻り Map<文字列、オブジェクト> 値だけでは十分ではなく、プラグインフレームワークがプラグインの実行ステータスを報告するために必要とする正しいデータが内側の Map に含まれなくなります。
このメソッドは、開発者が AbstractPlugin.java の collectData(…) の実装またはその他の collectXYZ(…) メソッドの実装に依存しない場合に使用するユーティリティとしてのみ効果的です。
制限事項
システム設定コレクターで使用される、または MBean として使用されるプラグインは、かなり強力です。これらのプラグインは、ファイル、ディレクトリ、プロパティの収集だけではなく、Java クラス、WinDU タスク、スクリプトの実行やデータベース情報の収集にも使用されます。現在、プラグインが実行できるのは、SQL スクリプト、QML スクリプト、WinDU タスク、および Java コードのみです。
サンプルコード
CustomPlugin.java
package com.ptc.customersupport.mbeans.plugins;
import java.util.Map;
import java.util.ResourceBundle;
import javax.management.NotCompliantMBeanException;
import org.apache.log4j.Logger;
import wt.jmx.core.MBeanUtilities;
import wt.log4j.LogR;
import com.ptc.customersupport.mbeans.AbstractPlugin;
import com.ptc.customersupport.mbeans.PluginMBean;
import com.ptc.customersupport.mbeans.PluginType;
public class CustomPlugin extends AbstractPlugin implements PluginMBean {
private static ResourceBundle RESOURCE =
ResourceBundle.getBundle(CustomPluginResource.class.getName());
private static final Logger logger = LogR.getLogger(CustomPlugin.class.getName());
public CustomPlugin() throws NotCompliantMBeanException {
super(null);
// super(PluginMBean.class);
initializeMBeanAttributes();
}
public CustomPlugin(final String displayName,
final String beanName, final String description,
final String pluginVersion)
throws NotCompliantMBeanException {
// super(PluginMBean.class, displayName, beanName,
// description, pluginVersion);
super(null, displayName, beanName, description, pluginVersion);
}
@Override
public Map<String, Object> collect(final long callNumber,
final long maxAgeInDays,final long minAgeInDays,
final String pathTimeStamp) {
// TODO Do actual collection work and return correct Map
return null;
}
@Override
public Map<String, Object> collect(String topicIdentifier,
final long maxAgeInDays, final long minAgeInDays,
final String pathTimeStamp) {
// TODO Do actual collection work and return correct Map
return null;
}
private void initializeMBeanAttributes() {
if (logger.isDebugEnabled()) {
logger.debug("Initializing " +
MBeanUtilities.formatMessage(
RESOURCE.getString(
CustomPluginResource.
CUSTOM_PLUGIN_NAME))
+ " Plugin.");
}
// set the localized plugin display name
setDisplayName(MBeanUtilities.formatMessage(
RESOURCE.getString(
CustomPluginResource.CUSTOM_PLUGIN_NAME)));
// set the localized plugin description
setDescription(MBeanUtilities.formatMessage(
RESOURCE.getString(
CustomPluginResource.CUSTOM_PLUGIN_DESC)));
// set the plugin MBean name
setMBeanName("TomcatConfigProperties");
// set the plugin enumerated type
setPluginType(PluginType.MISC);
// set the plugin version number
setPluginVersion("1.0");
// set whether the plugin relies on database
// administrator credentials
setDbCredentialsNeeded(false);
// set whether the plugin operates on each
// cluster node
setClusterAware(true);
// set whether the plugin relies on file
// date ranges for collection
setDateRangeUsed(false);
// set whether the plugin should compress the
// output of its collected data
setCompressOutput(false);
}
}
CustomPluginResource.java
package com.ptc.customersupport.mbeans.plugins;
import wt.util.resource.RBEntry;
import wt.util.resource.RBUUID;
import wt.util.resource.WTListResourceBundle;
@RBUUID("com.ptc.customersupport.mbeans.plugins.CustomPluginResource")
public class CustomPluginResource extends WTListResourceBundle{
@RBEntry("My Custom Plugin")
public static final String CUSTOM_PLUGIN_NAME = "0";
@RBEntry("A plugin that does xyz.")
public static final String CUSTOM_PLUGIN_DESC = "1";
}
TomcatConfigPropertiesPlugin.java
このサンプルコードは、wt.property 値である installedProduct.location.Tomcat がある場所で config.properties ファイルを収集します。このプラグインは、簡潔にするためにローカライズされていません。
package demo;
import java.util.Map;
import javax.management.NotCompliantMBeanException;
import org.apache.log4j.Logger;
import wt.log4j.LogR;
import com.ptc.customersupport.mbeans.PluginType;
import com.ptc.customersupport.mbeans.plugins.GatherFilePlugin;
/**
* A sample Plugin that gathers the Tomcat config.properties file.
* The location of this file is controlled by the location of
* Tomcat on an installed system. Generally, this location is
* <Windchill>/tomcat/config.properties. However, there exists a
* wt.property which points to where the tomcat instance is
* installed. This property is installed.Product.location.Tomcat,
* and it is used to build a tokenized path to the location of the
* config.properties file.
* <BR><BR>
* This class extends the
* {@link com.ptc.customersupport.mbeans.files.GatherFilePlugin
* GatherFilePlugin} which is used to provide functionality that is
* already implemented that this Plugin can rely upon for default
* behavior. Most plugins will be able to make use of existing
* Abstract plugin classes for much of their behavior and method
* implementations. See the
* {@link com.ptc.customersupport.mbeans.files.GatherFilePlugin
* GatherFilePlugin} for more infomration on the parent class of
* this Plugin and it's methods.
* <BR><BR>
*/
public class TomcatConfigPropertiesPlugin extends GatherFilePlugin {
/*
* Optionally provide some form of localization for plugin strings.
*
* In order to localize the values like name, description,
* and version, follow these steps:
*
* 1. Create a tomcatConfigPropertiesPluginResource.rbInfo
* file with the correct values.
*
* 2. Get an instance of a ResouceBundle like this: private static
* ResourceBundle RESOURCE =
* ResourceBundle.getBundle(
* tomcatConfigPropertiesPluginResource.class.getName());
*
* 3. Set the name (or other value) like this:
* setDisplayName(MBeanUtilities.formatMessage(
* RESOURCE.getString(
* tomcatConfigPropertiesPluginResource.
* PLUGIN_DISPLAY_NAME)));
*/
// Set member variables for ease of use.
private static final String TCP_PLUGIN_NAME =
"Tomcat Property Config File";
private static final String TCP_PLUGIN_DESCRIPTION =
"<tomcat_home>/config.properties file.";
/*
* Optionally, provide some logging capabilities. Doing so
* can facilitate easier Plugin debugging or provide
* status/information messages to the running servers.
*/
private static final Logger logger = LogR.getLogger(
TomcatConfigPropertiesPlugin.class.getName());
/**
* Default constructor that sets all the required values.
*/
public TomcatConfigPropertiesPlugin() throws
NotCompliantMBeanException {
/*
* The operator call to super() allows the
* TomcatConfigPropertiesPlugin to rely on the parent class for
* much of the Plugin initialization. This call will set
* default values which are later overridden as necessary. This
* also sets up and initializes this Plugin as a SelfAwareMBean
* as the inheritance hierarchy eventually reaches
* AbstractPlugin.
*/
super();
/*
* This method call is simply for convenience of setting
* all the Plugin values in one place that we are
* overriding the default values for which were set when
* super() was called.
*/
initializeMBeanAttributes();
}
/**
* Initializes all the Plugin values for this specific Plugin.
* Those values which were initially set by parent classes are
* overidden.
*/
private void initializeMBeanAttributes() {
// Log a debug message that the Plugin is being initialized.
if (logger.isDebugEnabled()) {
logger.debug("Initializing " + TCP_PLUGIN_NAME + "" +
" Plugin.");
}
/*
* Set the attribute values that are common to all Plugins,
* regardless of the PluginType.
*/
// The name that will be used for this Plugin.
setDisplayName(TCP_PLUGIN_NAME);
// The description that will be displayed for this Plugin.
setDescription(TCP_PLUGIN_DESCRIPTION);
// Set the MBean ObjectName.
setMBeanName("TomcatConfigProperties");
/*
* Set the PluginType value. This will control where the
* data is collected to in terms of directory structure.
*/
setPluginType(PluginType.PROPERTY);
// Set the Plugin version information.
setPluginVersion("1.0");
/*
* Set the file name that we want to collect. This value
* overrides the default value set by the parent. The
* GatherFilePluginMBean Interface of the parent class
* specifies this method must be implemented. Since we
* are extending the parent class and want to collect a
* specific file (not the default file the parent specifies)
* we override the value and set it to the location:
* $(installedProduct.location.Tomcat)$(dir.sep)
* config.properties
*
* This is a tokenized wt.property value. When the
* collection framework operates on this Plugin, these
* tokenized values are replaced by their canonicalized
* paths and a file path results. This is how the collection
* framework knows where to find files to collect. Ideally
* tokenized or property values should be used to create
* a path to the file. If hard-coded file paths are used
* the Plugin will not operate across a cluster correctly.
*/
setFileName("$(installedProduct.location.Tomcat)" +
"$(dir.sep)config.properties");
}
/**
* Override the collect methods as needed. Incidentally, this
* Plugin does not dictate the collect(...) methods be
* overridden. The implementation of this method is actually
* the same as the parent implementation. However, for clarity
* of the example the collect(...) methods are shown.
*/
@Override
public Map<String, Object> collect(final long callNumber,
final long maxAgeInDays, final long minAgeInDays,
final String pathTimeStamp) {
/*
* Here we call the collectData(...) method of AbstractPlugin
* which will handle the actual collecting of the file
* specified as the first parameter. Here the first parameter
* is returned by the getFileName() method of the parent
* class.
*
* The collectData method sets up and hides all the complexity
* of using the collection framework and allows a developer to
* avoid implementing a specific collect(...) implementation.
*
* However, there are instances when certain Plugins require
* specific collect(...) method behavior, these instances
* are usually reserved for very advanced Plugins.
*/
return collectData(getFileName(), callNumber, maxAgeInDays,
minAgeInDays, pathTimeStamp);
}
@Override
public Map<String, Object> collect(final String topicIdentifier,
final long maxAgeInDays, final long minAgeInDays,
final String pathTimeStamp) {
return collectData(getFileName(), topicIdentifier,
maxAgeInDays, minAgeInDays, pathTimeStamp);
}
}
Windchill コードでの使用例
com.ptc.customersupport.mbeans パッケージ
この Java パッケージには、AbstractPlugin および PluginMBean インタフェースが含まれています。また、PluginType.java や PluginUtilities.java などのプラグインを作成するときに使用できる追加のユーティリティクラスも含まれています。
com.ptc.customersupport.mbeans.plugin パッケージ
この Java パッケージには、UML 図に示されている、「ソリューションエレメント」で説明した抽象クラスの多くが含まれています。このパッケージに含まれているものは、
com.ptc.customersupport.mbeans.plugin.logs パッケージ
この Java パッケージには、PluginType logs の具象プラグイン実装が含まれています。これらのプラグインは、一般的に、ログファイルを収集するために使用されます。Log4jFilesPlugin、WindchillLogsPlugin、WDSLogsPlugin などがその例で、複雑さはそれぞれ異なります
com.ptc.customersupport.mbeans.plugin.misc パッケージ
この Java パッケージには、PluginType misc の具象プラグイン実装が含まれています。これらのプラグインは、一般的に、特殊な情報を収集するために使用されます。UpgradeFolderPlugin、MigrationReportsFolderPlugin、WtSafeAreaFolderPlugin などがその例で、複雑さはそれぞれ異なります
com.ptc.customersupport.mbeans.plugin.properties パッケージ
この Java パッケージには、PluginType properties の具象プラグイン実装が含まれています。これらのプラグインは、一般的に、プロパティファイルを収集するために使用されます。DbPropertiesPlugin、DeclarationsXconfPlugin、IePropertiesPlugin などがその例で、複雑さはそれぞれ異なります
com.ptc.customersupport.mbeans.plugin.third パッケージ
この Java パッケージには、PluginType third の具象プラグイン実装が含まれています。これらのプラグインは、一般的に、サードパーティ製品情報を収集するために使用されます。ApacheConfFolderPlugin、ApacheLogsPlugin、CogStartupXmlPlugin などがその例で、複雑さはそれぞれ異なります
com.ptc.customersupport.mbeans.plugin.util パッケージ
この Java パッケージには、PluginType util の具象プラグイン実装が含まれています。これらのプラグインは、一般的に、ユーティリティ情報を収集するために使用されます。GatherInfoScriptPlugin、MBeanDumpPlugin、WDSMBeanDumpPlugin などがその例で、複雑さはそれぞれ異なります
MBeanDumpPlugin.java は、抽象クラスの collect(…) メソッドに依存しない複雑なプラグインです。collect(…) メソッドの抽象クラスの実装を使用しない、またはコレクションフレームワークを直接使用しないように collect(…) メソッドを実装する複雑なプラグインを作成する場合は、このプラグインを調べると、役立つ情報を入手できます。
パッケージ化されたサンプル
PTC は、パッケージ化されたプラグインのサンプルコードを提供しています。これは、<Windchill>/utilities/SystemConfigurationCollector/plugins/examples にあります。このディレクトリには、サンプルのサブディレクトリで com.ptc.customersupport.* パッケージを維持するパッケージ化されたサンプルが含まれています。これらのサンプルを調べることによって、プラグイン内で SQL、QML、Java コマンドなどを使用する方法を確認できます。
その他のリソース
関連パッケージ/クラスの Javadoc
com.ptc.customersupport.mbeans* パッケージには、Java プラグインインタフェース、共通の機能を提供する多数の抽象プラグイン、および具象プラグイン実装が含まれています。
関連 Windchill ドキュメント
システム設定コレクターとその使用法の詳細については、
システム設定コレクターを参照してください。
関連 Web サイト
• Java Jar Service Provider の仕様
• Java JAR ファイルの仕様
• Java MBean オブジェクト名
• Java のコンパイル
• Java JAR コマンド