はじめに
この合併吸収の時代において、ソリューション設計者が直面している共通の問題は、一貫したユーザーエクスペリエンスを提供しながら製品ラインを統合することです。2006年4月に、Lawson Software, Inc.(編集部注:コンビニのローソンではありません)がIntentia International ABと合併した際に開発担当者が直面した課題は、新しい会社の主要製品ラインを拡大する一方で、ユーザーの生産性や満足度を上げ情報をさらに統合できる、シームレスで同質なユーザーエクスペリエンスを作り出すということでした。(”M3“として知られる製品は製造を中心とする業界を対象とし、製品、資産の製造(Make)、輸送(Move)、保守(Maintain)を行います。また、”S3“として知られる製品はサービス業界を対象とし、顧客のニーズを満たすために、人(Staff)、資源(Source)、サービス(Service)を提供します。)
本事例研究では、Lawsonのジレンマに対するアプローチを研究するとともに、ソリューションとシステム全体のアーキテクチャに関するいくつかの興味深い面を技術的な観点から詳細に見ていきます。
問題領域
合併以前、LawsonとIntentiaはともに企業資源計画(ERP)ソリューションを、それぞれが選んだ市場と地域を対象に提供していました。Lawsonの主要製品ラインであるS3は、主にアメリカにおいて、特にサービスを中心とする業界に向けて設計されていました。顧客を“人(staff)、資源(source)、サービス(serve)”の面で支援するので、S3アプリケーションは、企業業績管理、事業プロセス管理、企業財務管理、サプライチェーン管理、サービス管理、人的資本管理といったERPのあらゆる機能を有していました。同じ意図を持ちながら、IntentiaのM3製品は主に欧州医薬品審査庁(EMEA)やAPACの運送・製造会社の顧客、つまり、品物や機器を“作り(make)、運び(move)、保守(maintain)する”顧客を対象としていました。M3アプリケーションが有していたのは、製造業務、サプライチェーンの実行と最適化、顧客への販売とサービス、企業資産管理、財務管理・統制、ビジネスプロセス管理サービスでした。製品ライン、地域、対象とする産業が相補的であることを見れば、2つの会社の合併の理論的根拠は明らかです。
両社のシステムは類似点があったとはいえ、実装方法はかなり異なっていました。IntentiaのM3システムはサーバー側のJavaビジネスロジック層を中心として、多くの異なるクライアントアプリケーションがアクセスするシステムでした。Intentiaのクライアントユーザーインターフェース(UI)は、マイクロフォーカス コボル/C++のリッチクライアントを始めとして、アクティブサーバーページ(ASP)、シンクライアントソリューションベースのJavaサーバーページ(JSP)を経て何年もかけて発展し、Workplace Foundationとして知られるAJAX/JSPベースのシンクライアントポータルに至っています。LawsonのS3アプリケーションスイートはJavaベースと第4世代言語(4GL)ベースのソリューションが混在したものですが、全体的には同じ方法でピュアなJavaベースへと発展しつつあります。二つの会社の間では、Workplace FoundationウェブポータルからC#ベースのモバイル販売リッチクライアントまで、数多くの異なるクライアント技術が活用されていました。
合併により、Lawsonは両社の主要製品ラインを活用できるクライアントアプリケーションを作成する方法を探していました。クライアントアプリーションに特に望んだことは次の通りです。
- Windows XP、Vistaクライアントからアクセスされるアプリケーションは、操作性(look and feel)が共通していること。(顧客ベースの98%はWindowsクライアントからソフトウェアにアクセスしていました)
- アプリケーションの起動方法とメッセージを受け取る方法が共通していること。
- 新しいアプリケーションや機能をホストする方法は明確で抜き挿し可能であること。
- リッチで生産的なユーザーエクスペリエンスを提供すること。
- 異なるクライアントから共有できるようにビジネスロジックをサーバー側に置き、“一つのコードベース”から実行できること。
- JavaとJava以外のビジネスロジック層の両方と情報のやり取りを行うこと。
- 旧クライアントと新しく開発されたクライアントが同じサーバーインスタンスを使えること。
ソリューション概要
新しいクライアントアプリケーションの技術をより適切に選択するために、Lawsonは frog design europe社(www.frogdesign.com)(英語)に現行・新規のユーザーインターフェース技術の分析を支援してもらえるよう、協力を仰ぐことに決めました。共に検討し、提示された要求に対する最良のソリューションは、Microsoftの新製品であるWindows Presentation Foundation(WPF)と、新しいWindows Communication Foundation(WCF)の一部のコンポーネントを利用してリッチクライアントアプリケーションを作成することだと結論を出しました。(両方とも .Net 3.0 のフレームワークの一部です。)この選択に寄与した数多くの要因は、次の通りです。
- この新製品の開始はWindows Vista Launchと同時なので、Lawsonは競合各社の中で最初にこの技術を利用する会社になる。
- WindowsはLawsonの顧客の98%が選択するプラットフォームなので、.Netの主要なコンポーネントを採用することは顧客の投資を支援する方法だと考えられる。
- Windows Presentation Foundation(WPF) は関連しあうものを分離するのがうまく、グラフィック設計をほかの実装の細部から分離することが可能である。
- WPFはフォーム、制御、音声、映像、画面上・固定フォーマットの文書、2D・3Dグラフィクスを組み合わせる単一のプラットフォームを提供する。
- WPFは拡張性のある、解像度に依存しないUIレンダリングを提供する。
- Windows Communications Foundation(WCF) は通信用に簡単に拡張できるプログラミングモデル/フレームワークを提供する。
- WCFはアプリケーションコードと通信コードをうまく切り離す。どこにサービスがあろうと、(複数のアプリケーションドメインやプロセスに渡っていても、同じマシンでも、複数のマシンに渡っていても、etc.)WCFを使うクライアントコードは同じである。
- WCFは複合アプリケーションやサービス指向アーキテクチャに宣言型モデルを提供する。
- WCFのエンドポイントはデプロイメントの後に設定できる。
クライアントアプリケーション
上の図からわかるように、新しいリッチクライアント("Lawson Smart Client"という名称で知られる)には、3つの重要な設計レイヤーに、ユーザーのデータやプリファレンス設定をサポートする部分が考慮され、加えられています。最初のレイヤーであるプレゼンテーションレイヤーは、ユーザーとの対話やホストされたウィジェットのライフサイクルの管理を行い、基本的にはクライアントの“キャンバス”となります。それぞれの異なるアプリケーションタイプ(M3、S3など)からのウィジェットをキャンバスに追加でき、ユーザーはタスクを起動したり入力イベントに応答することができます。さらに、ユーザーはキャンバスの“皮”を取り替えることによってクライアントの操作性を変更することができます。
表示ロジックレイヤーは、抜き挿し可能な多くの“エンジン”から構成され、アプリケーションライン特有のコンテンツの画像を描画します。コンテンツはメタデータ、ユーザーデータ、他の定義済みのリソースを組み合わせ、一貫した操作性を確保しながら実行時に作成されます。
データアクセスレイヤーは、WPFデータバインディングを利用して、UIコンポーネントをビジネスロジックまたはデータコンポーネントと結び付けます。この方法によって複数のデータ記憶ストラテジーを利用できるので、UIはユーザープリファレンス、クライアント構成、セッションコンテキストなどからデータを集めることができます。これらのストラテジーに最も多く見られるのは、サーバー側のコンポーネントとWebサービス経由で接続しているWCFエンドポイントを使うことです。
ユーザープリファレンス、使用実績統計、ユーザーの状態を保存するために、マイクロソフト SQL サーバーコンパクトエディションが使われます。ユーザーが“ローミングプロファイル”を設定すれば、すべてのLawson Smart Client機器からアクセスできるサーバー上にユーザーデータを複製できるので、これらのユーザーデータはクライアントで利用できるようになります。
サーバー側
上の図を見ておわかりのように、LawsonとIntentiaは何年もかけて、産業特有のサーバー側のビジネスロジックを大量に開発してきました。実際、図に示されたすべてのサーバー側のコンポーネントは、新たにSmart Clientが開発される前になんらかの形で存在していました。顧客の投資や人材を保護しながら拡張し、新しい技術への移行を簡単にするために既存のサーバー側のコンポーネントをJavaでもJava以外でもいずれも使い続けることはLawsonにとって最良の選択でした。
最初のクライアントプロトタイプの迅速な作成を手助けするために、マイクロソフトのJava変換ツールを使って、M3モバイル販売リッチクライアントに使われていたJ2EE コネクタアーキテクチャ(JCA)/共通クライアントインターフェース(CCI)コネクタがJ#に変換されました。これによって、クライアントの開発者がJ#クライアント側コネクタを使って既存のバックエンドシステムとインターフェースをとれるようになりました。生産クライアントのコネクタは、生成されたJ#コネクタに取り替えられました。このクライアントは、LawsonWebサービスフレームワークが作成したWebサービスにアクセスするためにWCFエンドポイントを利用するからです。
Webサービスフレームワークを使うことによって、ビジネスサーバーが提供するメタデータをWebサービス定義言語(WSDL)とJavaコネクタコードに変換することができます。Lawsonの開発者たちはJ2EE Workplace Foundationアプリケーションの既存のサーバーコンポーネントを再構築・再利用し、AJAXベースのWorkplaceシンクライアントと新しいLawson Smart Clientが、同じビジネスロジックやサービスを利用できるようにしました。
ドリルダウン#1 Webサービスを経由したJavaと.NETの統合
新しいLawson Smart Clientは新製品であるWindows Presentation FoundationとWindows Communication Foundationの機能を利用しています。下の図を見ていただければわかるように、クライアントウィジェットは拡張可能アプリケーションマークアップ言語(XAML)を使うことによって動的にC#データソースに結合します。データソースはプロキシオブジェクトを利用して適切なWebサービスと通信します。Microsoft Windows ソフトウェア開発キット(SDK)にあるService Model Metadata Utility Tool (SvcUtil.exe)によって生成されたプロキシはWebサービスとの通信やC#とWebサービスパラダイム間の変換を行います。Webサービスコールはハイパーテキスト変換プロトコル(HTTP)上のシンプルオブジェクトアクセスプロトコル(SOAP)を使って行われます。
Smart ClientウィジェットからWebサービスを呼び出す例
© 2007 Lawson Software株式会社。無断複写・転載を禁じます。本文書は情報提供のみを目的とします。Lawson Softwareはこの要約に関し、明示、暗示にかかわらずいかなる保証もいたしません。
非同期結合(XAML)の例 クライアントウィジェットをデータソースに結合する
<ObjectDataProvider x:Key="datasourceCRS990"
ObjectType="{x:Type ds:CRS990DataSource}" />
<ListView x:Name="SelectionList"
ItemsSource={Binding Source=dataSourceCRS990,
Path=ResultCollection, IsAsync=True, Mode=OneWay} >
<... />
</ListView>
C#データソースのコードの例 Webサービスプロキシの呼び出しを表示する
Public ObservableCollectionResultCollection
{
get
{
InitBrowseCollection data = new InitBrowseCollection();
data.InitBrowseItem = GetCallContext();
try {
CRS990MIClient crs990 =
WSHelper.CreateClient();
InitBrowseResponseItem[] responseCollection = crs990.InitBrowse(
WSHelper.GetLWSCredentials(), data);
return FilterResponse(responseCollection);
}
}
}
生成されたWebサービスプロキシのメソッドの例
...
public InitBrowseResponseItem[] InitBrowse(headerType mws,
InitBrowseCollection initBrowse)
{
InitBrowseRequest inValue = new InitBrowseRequest();
inValue.mws = mws;
inValue.InitBrowse = initBrowse;
InitBrowseResponse retVal =
((SmartClient.Widgets.WS.CRS990MI)(this)).InitBrowse(inValue);
return retVal.InitBrowseResponse1;
}
...
Lawson M3サーバーサイドアプリケーションスイートの心臓部はWebサービスフレームワークです。Javaで実装されたフレームワークは、クライアント側に設計ツールを持ち、それを使うことでビジネスシステム・アプリケーションプログラミングインターフェース(API)に基づいたWebサービスの作成、テスト、ホット・デプロイメントを行うことができます。この設計ツールは、WebサービスとビジネスAPIの間を仲介するコードを生成します。Webサービスリクエストの拡張可能マークアップ言語(XML)がペイロードを構文解析し、ビジネスシステムから戻ってきた応答を並べてXML応答ペイロードに戻すことによってこれを行います。各バックエンドAPIの場所やアーキテクチャは大きく異なります。一例として、M3システムは基本的にスタンドアローンのサーバー側アプリケーションで、性能を最大限に上げるために、伝送制御プロトコル(TCP)/ソケットベースのAPIを通してアクセスされます。
下の図を見ておわかりの通り、ビジネスAPIをWebサービスとして公開するのに必要となるすべての接続材料、構成データはフレームワークによって作成されます。多くのツールが利用され、例えば、Java/XML 結合のためにApache XMLBeansが、Webサービスペイロードの構文解析や検証のためにStAX(XML用ストリーミングAPI)が使われます。また、多数のWSDLs、サービス用XML記述子、特別なビジネスサービスを起動するのに必要なコネクタコードなども有しています。
IBM® WebSphere® アプリケーションサーバのサーブレットコンテナにデプロイされたLawson Webサーバーは、この生成コードを利用する実行時のエンジンです。アパッチ財団のWebサービスのAxis2コアエンジンを中心に構築されたWebサーバーは、実行時の設定、接続のプール、セキュリティにも対応します。Axis2エンジンは性能がよく、WS-I ベーシックプロファイルやWSセキュリティ(メッセージの暗号化を行う)を標準サポートしています。Webサービスの分離はクラスローダーを分離することで行います。生成された各Webサービスはそれぞれ別個のクラスローダーによりロードされます。
ドリルダウン#2 メタデータからUIを描画する
Lawsonの旧ビジネスアプリケーションの多くは、クライアント/サーバー通信においてXMLを利用しています。旧クライアントが使い続けているために、これらのサービス/アプリケーションの実装を変えることができませんでした。Lawsonはこの制約に様々な方法で対応をはかってきました。拡張可能スタイルシート言語変換(XSLT)を利用することで、既存のシンクライアントアプリケーション(AJAX/JSPベース)のメタデータと実行データの組み合わせを、XMLからハイパーテキストマークアップ言語(HTML)に変換します。XSLT/HTMLだけでは対応できなかった“特別の代物”はすべて、Javaスクリプトを使って対応します。
リッチクライアントアプリケーションの場合は、UIを作成するのに同じXMLデータを使う必要がありました。従来のJavaリッチクライアントアプリケーションの一つでは、動的にUIが作成されていたので、Lawson Smart ClientではこのパターンがC#に適用されています。
XMLで描画を行ってUIを作るために、最初にWYSIWYGフォーム構築ツールを使ってビジネスアプリケーションの画面を設計します。スクリーンの定義が終了すると、新しく作成するパネルのすべての制御が記述されたメタデータが設計ツールからエクスポートされます。このメタデータはまた、サーバー側のビジネスアプリケーションから取り出した情報とこのデータの翻訳方法を記述する結合情報を持っています。
メタデータの記述から作成したパネルの例
© 2007 Lawson Software株式会社。無断複写・転載を禁じます。本文書は情報提供のみを目的とします。Lawson Softwareはこの要約に関し、明示、暗示にかかわらずいかなる保証もいたしません。
UIのパネルを記述するメタデータのスニペット
<Panel name="MMA001E0" rtype="DETAIL" modDateField="WMLMDT" regDateField="WMRGDT" changedByField="MMCHID">
<PanelHeader>MMS001/E</PanelHeader>
<PanelDescription langId="MM00101"/>
<Objects>
<GroupBox langId="MX_0235" justification="LEFT">
<Position left="1" top="1" width="73" height="1"/>
</GroupBox>
<Caption langId="WIT0115" tab="256">
<Position left="1" top="2" width="14" height="1"/>
</Caption>
<EntryField name="MMITNO" fieldHelp="ITNO" suppressLeadingZero="true" protected="IN41|!IN45" tab="270">
<Constraints maxLength="15" uppercase="UC"/>
<BrowsePosition top="4" left="18"/>
<Position left="15" top="2" width="16" height="1"/>
</EntryField>
<GroupBox langId="MX_0238" justification="LEFT">
<Position left="1" top="4" width="73" height="1"/>
</GroupBox>
<Caption langId="WNA0115" visible="!IN21" tab="1024">
<Position left="1" top="5" width="14" height="1"/>
</Caption>
<EntryField name="MMITDS" fieldHelp="ITDS" suppressLeadingZero="true" visible="!IN21"
protected="IN01|IN21|IN45&!IN41" tab="1038">
<Constraints maxLength="30"/>
<BrowsePosition top="5" left="18"/>
<Position left="15" top="5" width="31" height="1"/>
</EntryField>
<...>
<FunctionKeys value="001011111001000000000000">
<FunctionKey fKey="F3" langId="XF03000"/>
<FunctionKey fKey="F5" langId="XF05000"/>
<FunctionKey fKey="F6" langId="XF06000" visible="!IN41" reverse="!IN41&IN57"/>
<FunctionKey fKey="F7" langId="XF07000" visible="!(!IN45)"/>
<FunctionKey fKey="F8" langId="XF08000" visible="!(!IN45)"/>
<FunctionKey fKey="F9" langId="XF09000" visible="!IN41"/>
<FunctionKey fKey="F12" langId="XF12000"/>
</FunctionKeys>
</Objects>
<RecordFields length="634">
<RecordField name="WWCLIN" type="DECIMAL" pos="18" length="3" refField="CLIN"/>
<RecordField name="WWCPOS" type="DECIMAL" pos="21" length="3" refField="CPOS"/>
<RecordField name="MMITNO" pos="24" length="15" refFile="MITMAS" refField="MMITNO"/>
<...>
</RecordFields>
</Panel>
各メタデータファイルは、次にWebアプリケーションにデプロイされます。Webアプリケーションはメタデータとビジネスアプリケーションから取り出した実行時データを結び付け、新たに両方のデータセットを持つXML構造を作成します。この新しいXMLフォーマットは、UIウィジェットが描画の指定をするのに必要なすべての情報を持っています。画面上のウィジェットの場所、フォーマット情報(たとえば、小数点以下の桁数など)、入力上の制約(数字入力が必須、など)といったデータが含まれます。このXMLのフォームは、描画を行うAJAX/JSPシンクライアントのコードと新しいLawson Smart Clientの両方から使われます。
メタデータと実行時データの結合を示すXMLのスニペット
<Panel name="MMA001E0">
<Objs>
<FKeys val="001011001001000000000000">
<FKey val="F3">End</FKey>
<FKey val="F5">Refresh</FKey>
<FKey val="F6">Text</FKey>
<FKey val="F9">Field Audit</FKey>
<FKey val="F12">Cancel</FKey>
</FKeys>
<EFld tab="270" name="MMITNO" hlp="ITNO" acc="WD">
<Pos l="15" t="2" w="16" h="1"/>
<Constr maxL="15" type="CHAR" uc="UC"/>
B000007
</EFld>
<EFld tab="1038" name="MMITDS" hlp="ITDS" acc="WE">
<Pos l="15" t="5" w="31" h="1"/>
<Constr maxL="30" type="CHAR"/>
Air Filter, Fleetguard AF1811
</EFld>
<...>
<ChkBox name="MMECMA" hlp="ECMA" tab="4149" acc="WE">
<Pos l="54" t="17" w="3" h="1"/>
0
</ChkBox>
<...>
<CBox name="MMSTCD" hlp="STCD" tab="4366" acc="WE">
<Pos l="15" t="18" w="16" h="1"/>
<CBV val="0">0-No inv account</CBV>
<CBV val="1" sel="true">1-Inv accounting</CBV>
<CBV val="2">2-No, but planned</CBV>
<CBV val="3">3-No, but as func</CBV>
</CBox>
<...>
<GroupBox r="t">
<Pos l="1" t="1" w="73" h="1"/>
Panel Header
</GroupBox>
<GroupBox r="t">
<Pos l="1" t="4" w="73" h="1"/>
Basic Information
</GroupBox>
<...>
</Objs>
<PHead>MMS001/E</PHead>
<PDesc>Item. Open</PDesc>
</Panel>
The Lawson Smart Client receives this XML document from the Web Server. A client side component interprets this XML, dynamically creates and positions all of the UI widgets, initializes the widgets with data and constraints, and adds them to a panel. The component also considers user and other UI settings during this process.
Lawson Smart ClientはWebサーバーからこのXML文書を受け取ります。クライアント側のコンポーネントはXMLを解釈して、動的にすべてのUIウィジェットを作成して位置決めし、そのウィジェットをデータや制約で初期化し、パネルに追加します。この処理の間、コンポーネントもまたユーザとUIセッティングのことを十分考えています。
動的にラベルを描画するコード例
private void ReadCaption(XMLNode n) {
string text = n.InnerText;
if (text.Length > 0) {
XMLAttribute a = n.Attributes["tip"];
string name = GetStringAttribute(n, "id");
string tooltip = a != null ? a.Value : null;
bool isFixed = n.Attributes["fixFnt"] != null;
bool isAdditionalInfo = n.Attributes["addInfo"] != null;
bool isEmphasized = n.Attributes["emp"] != null;
bool isColon = n.Attributes["cl"] != null;
CreateLabel(name, text, tooltip, isFixed, false, isAdditionalInfo, isEmphasized, isColon);
ReadPosition(n);
SetPosition();
SetWidth();
ReadAccess(n);
SetAccess();
AddElement();
}
}
protected void CreateLabel(string name, string text, string tooltip,
bool isFixed, bool wrap, bool isAdditionalInfo,
bool isEmphasized, bool isColon) {
Style s;
HorizontalAlignment hAlign = HorizontalAlignment.Left;
if (isAdditionalInfo) {
s = StyleManager.StyleAdditionalInfo;
} else if (isEmphasized) {
s = StyleManager.StyleEmphasized;
} else {
s = StyleManager.StyleLabel;
}
label = controlPool.Create(ControlPool.TypeLabel, s)
as Label;
currentElement = label;
label.Name = name;
CreateControlTag();
controlTag.AdditionalInfo = isAdditionalInfo;
if (wrap) {
TextBlock tb = new TextBlock();
tb.Text = text;
tb.TextWrapping = TextWrapping.Wrap;
label.Content = tb;
} else {
if (!isAdditionalInfo) {
if (isColon) {
// Only labels with colon can be right-aligned.
// The colon is only displayed for left align
if (UserSettings.Current.RightAlignLabels) {
hAlign = HorizontalAlignment.Right;
} else {
text += ":";
}
}
}
label.VerticalAlignment = VerticalAlignment.Center;
label.Content = text;
}
label.HorizontalAlignment = hAlign;
if (isFixed) {
label.FontFamily = StyleManager.FontFamilyFixed;
} else {
label.FontFamily = StyleManager.FontFamilyBaseUI;
}
label.ToolTip = tooltip;
}
ドリルダウン#3 システムの安定性を強化するためのルールエンジンの使用
サーバー側のLawsonアプリケーションは複数のプラットフォーム上にデプロイされるように設計されています。客先でインストールされたシステムは、様々なハードウェアやオペレーションシステム上で動作しており、データは複数のリレーショナルデータベース管理システムに格納されています。このような環境の多様性によって、システム性能の保守や監視は困難な作業になっています。システムの問題を解決するために複数のレイヤーで対応しなければならない恐れもあり、結果として重要なビジネスの遅れや情報損失を招くかもしれません。
安定性を強化するために、Lawsonは基盤安定化システム「Foundataion Stabilizer」を作成しました。Foundation Stabilizerはルールベースの監視システムで、サポート担当者や開発担当者が定義した一般的な制約やパターンに基づいています。動作中のシステムの性能や構成情報を集めますが、この情報には、オペレーティングシステムより下層(CPUの使用状況など)のデータや、Java ネイテイブインターフェース(JNI)ベースのコンポーネントと通信して受け取ったデータも含まれることがあります。潜在的な問題が識別されると、Stabilizerは警告メッセージをサポート担当者に出し(RSS、電子メール、htmlによって)、対応可能なら措置を講じて(有罪スレッドの優先度を下げるなど)安定したシステム基盤を確保します。手動システム監視のために集められた膨大な量のシステムデータをルールやパターン照合の基準として使用できます。システムデータとは次のようなものが挙げられます。
- パフォーマンス・カウンター
- プロパティファイルからのデータ
- Javaパラメータとプロパティ
- システム環境情報
- ジョブ情報、ジョブの状態、活動レベルなど
- Java仮想マシン(JVM)の状態とリソースの消費
- プロパティ値に対する、プラットフォーム特有またはプラットフォームに依存しない制約
例3:Foundation Stabilizerが出した警告 © 2007 Lawson Software株式会社。無断複写・転載を禁じます。本文書は情報提供のみを目的とします。Lawson Softwareはこの要約に関し、明示、暗示にかかわらずいかなる保証もいたしません。
ルールエンジンはJavaで構築され、プロログで書かれたルールの上で動作します。下の例のメソッドstabilize() はループするJavaスレッドから、設定可能な間隔で定期的に起動されます。Javaスレッドは同じJava仮想マシンにあり、ビジネスアプリケーションとして動作します。
boolean stabilize() throws Exception {
KnowledgeBase kb = engine.getKnowledge();
engine.consult("mvx/res/Stabilizer.rules");
engine.consult("mvx/res/Constraints.rules");
engine.setQuery("cleanup");
try {
addSysInfo(kb);
} catch (IOException ex) {
KQLOG.EX("MvxStabilizer:Failed to collect system information", ex);
return false;
}
KQLOG.DT("Run Stabilizer");
boolean res = engine.setQuery("stabilize");
if (!res) {
KQLOG.E("Could not stabilize - rule engine failed");
return false;
}
KQLOG.DT("End Stabilizer");
Enumeration en = kb.elements();
while (en.hasMoreElements()) {
// Handle results from the rules engine
}
return true;
}
- メソッドはルールエンジンの既存の知識ベースを抽出することから始まります。知識ベースには作成、計算されたシステムに関するファクトがあります。ファクトはoperator termまたは operator term1 term2 といった形でシンプルに表現されます。典型的な例では以下のようになるでしょう:
"jobName" "IKDXLZ9A.corp.lawson.net:26100" 4676 "Looping" "jobCPU" "IKDXLZ9A.corp.lawson.net:26100" 4676 55 - ルール(この例では2セット)は、エンジンと関連付けられています。
- 古い情報は“掃除”を実行することで知識ベースから取り除かれます。
- 知識ベースは現在のシステム情報で更新されます。
- “stabilize”を評価することで仕掛けられたルールによって新しいファクトが集められます。
- すべてのルールが評価されると、知識ベース全体が新しいファクトで再チェックされ、結果が処理されます。
...
rule(looping_nostat1):-
jobCPU(Addr, Id, CPU),
CPU>40,
jobChange(Addr, Id, Change),
(Change==0;Change>999),
not(loopingMem(Addr, Id, _)),
info(currentTime, Time),
assert(loopingMem(Addr, Id, Time)).
rule(looping_nostat2):-
loopingMem(Addr, Id, LTime),
jobCPU(Addr, Id, CPU),
CPU>40,
jobChange(Addr, Id, Change),
(Change==0;Change>999),
info(currentTime, Time),
Time-LTime>5,
jobType(Addr, Id, JobType),
jobName(Addr, Id, Name),
assert(warning(2, 4, 'Job may be looping', 'Job', JobType, Addr, Name, Id)).
rule(looping_nostat3):-
loopingMem(Addr, Id, LTime),
not(jobName(Addr, Id, _)),
retract(loopingMem(Addr, Id, LTime)).
...
上記の3つのルールが、CPUを過剰に使用しているジョブを検出するのに使われます。
最初のルールはどのようなジョブであろうとも、過剰にCPUを使っているジョブを検出し、監視を始めます。ファクトjobCPUを基に、特定のアドレス、ID、CPU使用率のジョブが選択されます。そのジョブが40%以上CPUを使用しており、増減率が0か、999より多い場合、新しいファクト(loopingMem)が作成され、Timeが設定されます。
2番目のルールは、5分以上監視されているジョブを検出し、報告します。ファクトloopingMem(最初のルールが設定した)を使って知識ベースの中からこれらのジョブを探します。最初のルールでチェックされたのと同様に、同じファクトがチェックされます。Timeの値が更新され、ファクトjobTypeとjobNameが追加されます。これらのファクトはM3ビジネスエンジンにおいて警告を表示するのに使われます。
3番目のルールは実行を中止しているジョブを検出し、それらを観察リストから取り除きます。ファクトloopingMemが知識ベースの中からこれらのジョブを探します。知識ベースの中にジョブが見つからない場合、そのエントリーは観察リストから削除されます。
結論
2006年に行われたLawsonとIntentiaの合併は、開発者に解決しなければならない重要な問題を残しました。数多くの全く異なる技術を使って構築されたレガシーアプリケーションと業務を統合し、提示することです。両社の主要ERP製品ラインにおいて同質のユーザーエクスペリエンスを提供するためには、クライアントソリューションは、Javaベースであっても、第4世代言語ベースであってもビジネス層と対話することが要求されると思われます。
Frog design Europe社の支援のもとでユーザーインターフェース技術を細かく検討した後、LawsonはMicrosoftの.NET 3.0フレームワークを活用することに決めました。Windows Presentation Foundation (WPF)データバインディングを利用してUIコンポーネントとビジネスロジック/データコンポーネントを結びつけ、Windows Communication Foundation(WCF)で既存のWebサービスフレームワークと通信することにより(多少の小さな再構築は行いましたが)、Lawsonの開発者は速やかにニーズに合うクライアントアプリケーションを作成することができました。Lawsonの新しいSmart Clientは抜き挿し可能なクライアントアーキテクチャを定義しています。このアーキテクチャでは、レガシービジネスロジックをWebサービス経由で活用しながらも、新しいアプリケーションや機能をホストすることができます。Lawsonの過去のアプリケーションも同じビジネスサービスを利用でき、その結果、全社で1つのコードベースを使うことで保守性が上がりました。Lawson Smart Clientを作成する過程において、開発者は宣言型プログラミングモデルの性質について重要な教訓を得ました。宣言型言語の学習曲線は下側にやや大きくカーブするかもしれず、使うのがいつも簡単であるとは限りませんし、必ずしも直感的であるとは言えません。しかし、一旦これらの言語を正しく活用する思考方法を身につけてしまえば、生産性において大きな収穫があります。Lawsonの開発者の経験において、生産性が増加したことは理論的枠組みを習得する初期の努力に匹敵するものだと思われます。
Lawson Smart Clientアーキテクチャの最初の構想は、パワフルで柔軟なユーザーインターフェースコンポーネントを持つ新種のアプリケーションを作り出すことでした。その目的は、ユーザーの生産性や満足度を向上させながら、顧客にLawsonの主要な製品ラインに及ぶシームレスなユーザーエクスペリエンスを提示することでした。最初の顧客反応は、Lawsonがこの取り組みにおいて、確かに成功したことを示しています。
原文はこちらです:http://www.infoq.com/articles/lawson-casestudy
(このArticleは2007年5月21日に原文が掲載されました)