この章では、OWLCS 基本プロトコル実装を使用して独自の Diameter アプリケーションを作成する方法の概要を説明します。以下の節で構成されています。
以下の節では、クライアントおよびサーバ側の Diameter アプリケーションを開発するために使用する Diameter 基本プロトコル パッケージ、クラス、プログラミング モデルの概要について説明します。また、付属している Diameter プロトコル アプリケーションの SIP サーブレット内での使用に関する情報は、以下の節を参照してください。
第 12 章「プロファイル サービス API の使用」には、Diameter Sh アプリケーションを使用してサブスクライバのプロファイル データにアクセスし、管理する方法が記載されています。
第 14 章「オフライン チャージング用の Diameter Rf インタフェース API の使用」には、Diameter Rf アプリケーションを使用してオフライン チャージング リクエストを発行する方法が記載されています。
第 15 章「オンライン チャージング用の Diameter Ro インタフェース API の使用」では、Diameter Ro アプリケーションを使用してオンライン チャージングを実行する方法が記載されています。
Diameter 基本プロトコル API 内のすべてのクラスは、ルートの com.bea.wcp.diameter
パッケージに格納されます。表 11-1 では、このパッケージ内の主なクラス、インタフェースおよび例外について説明します。
表 11-1 Diameter 基本プロトコル API の主要な要素
カテゴリ |
要素 |
説明 |
Diameter ノード |
Node |
Diameter ノード実装を表すクラス。Diameter ノードは、クライアント ベースまたはサーバ ベースの Diameter アプリケーションおよび Diameter リレー エージェントを表します。 |
Diameter アプリケーション |
Application、ClientApplication |
基本的な Diameter アプリケーションを表すクラス。宛先ホストやレルムの指定などのような、クライアント固有の機能の場合は、ClientApplication で Application を拡張します。Diameter アプリケーションはすべて、これらのクラスのうちの 1 つを拡張してアプリケーション識別子を返すようにする必要があります。また、新しい Diameter セッションを直接作成するために、これらのクラスを使用することもできます。 |
ApplicationId |
Diameter アプリケーション ID を表すクラス。Diameter プロトコルでは、この ID を使用してメッセージが適切なアプリケーションにルーティングされます。 |
|
Session |
Diameter セッションを表すクラス。セッション ベースの処理を実行するアプリケーションでは、リクエストを管理して応答メッセージを送信するといったアプリケーション固有動作を提供するように、このクラスを拡張する必要があります。 |
|
メッセージ処理 |
Message、Request、Answer |
Message クラスは、リクエストおよび応答メッセージのタイプを表すために使用する基本クラスです。Request および Answer は基本クラスを拡張します。 |
Command |
Diameter コマンド コードを表すクラス。 |
|
RAR、RAA |
これらのクラスは、 |
|
ResultCode |
Diameter 結果コードを表すクラス。Diameter 基本プロトコルの結果コードのための定数値を提供します。 |
|
AVP の処理 |
Attribute |
Diameter の属性情報を提供するクラス。 |
Avp、AvpList |
メッセージ内の 1 つまたは複数の属性値ペアを表すクラス。AvpList は、グループ化された AVP に含まれる AVP を表すのにも使用します。 |
|
Type |
サポートする AVP データ型を定義するクラス。 |
|
エラーの処理 |
DiameterException |
Diameter 例外の基本例外クラス。 |
MessageException |
無効な Diameter メッセージが検出された場合に発生する例外。 |
|
AvpException |
無効な AVP メッセージが検出された場合に発生する例外。 |
|
インタフェースのサポート |
Enumerated |
このインタフェースを実装する enum 値は、INTEGER32、INTEGER64 または ENUMERATED 型の AVP 値として使用できます。 |
SessionListener |
Diameter セッションに配信されるメッセージにサブスクライブするためにアプリケーションに実装できるインタフェース。 |
|
MessageFactory |
アプリケーションで、受信したメッセージについてデフォルトのメッセージ レコーダをオーバーライドし新しいタイプの デフォルトのデコーディング処理は、 |
これらの基本の Diameter クラスに加え、com.bea.wcp.diameter.accounting
パッケージ内にアカウンティング関連のクラスが、および com.bea.wcp.diameter.cc
内にクレジット管理関連のクラスが、それぞれ格納されています。これらのパッケージ内のクラスの詳細については、第 14 章「オフライン チャージング用の Diameter Rf インタフェース API の使用」および第 15 章「オンライン チャージング用の Diameter Ro インタフェース API の使用」を参照してください。
Diameter ノードは、com.bea.wcp.diameter.Node
クラスで表します。Diameter ノードは、diameter.xml
ファイル内のコンフィグレーションに従って、1 つまたは複数の Diameter アプリケーションをホストすることが可能です。Diameter アプリケーションにアクセスするには、デプロイされたアプリケーション (SIP サーブレットなど) が Diameter ノード インスタンスを取得して、アプリケーションをリクエストする必要があります。例 11-1 では、Rf アプリケーションへのアクセスに使用されるコードのサンプルが表示されます。
例 11-1 Diameter ノードとアプリケーションへのアクセス
ServletContext sc = getServletConfig().getServletContext(); Node node = sc.getAttribute("com.bea.wcp.diameter.Node"); RfApplication rfApp = (RfApplication) node.getApplication(Charging.RF_APPLICATION_ID);
Diameter ノードは、通常、OWLCS インスタンスの一部としてコンフィグレーションし、起動します。ただし、開発やテストのために、Diameter ノードを単独の処理として実行することもできます。これを行うには、以下の操作を行います。
次のように、ドメインの環境を設定します。
cd ~/bea/user_projects/domains/diameter/bin . ./setDomainEnv.sh
起動するノードの diameter.xml
コンフィグレーション ファイルを検索します。
cd ../config/custom
使用する diameter.xml
コンフィグレーション ファイルを指定して、Diameter ノードを起動します。
java com.bea.wcp.diameter.Node diameter.xml
すべての Diameter アプリケーションについて、基本 Application
クラス (クライアント アプリケーションの場合には ClientApplication
クラス) を拡張する必要があります。Diameter アプリケーションを作成するためのモデルは、次の方法でサーブレットを実装する場合のモデルと似ています。
Diameter アプリケーションにより、初期化のための init()
メソッドがオーバーライドされる。
diameter.xml
内でアプリケーションに対しコンフィグレーションされている初期化パラメータが、アプリケーションに対し使用可能になる。
セッション ファクトリの使用により、新しいアプリケーション セッションが生成される。
適切なアプリケーション ID を返すには、Diameter アプリケーションで getId()
メソッドも実行する必要があります。この ID は、Diameter メッセージを正しいアプリケーションに通信するために使用されます。
必要に応じて、rcvRequest()
または rcvAnswer()
を実装することができます。デフォルトでは、rcvRequest()
は UNABLE_TO_COMPLY という応答を返し、rcvRequest()
は、Diameter メッセージを削除します。
例 11-2 は、セッションを使用しない単純な Diameter クライアント アプリケーションを表したものです。
例 11-2 単純な Diameter アプリケーション
public class TestApplication extends ClientApplication { protected void init() { log("Test application initialized."); } public ApplicationId getId() { return ApplicationId.BASE_ACCOUNTING; } public void rcvRequest(Request req) throws IOException { log("Got request: " + req.getHopByHopId()); req.createAnswer(ResultCode.SUCCESS).send(); } }
セッション ベースの処理を実行するアプリケーションでは、リクエストを管理して応答メッセージを送信するといったアプリケーション固有動作を提供するように、基本 Session クラスを拡張する必要があります。基本 Session クラスを拡張する場合は、rcvRequest()
または rcvAnswer()
のいずれかを実装する必要があります。両方のメソッドを実装することも可能です。
基本 Application クラスを使用して新しい Session オブジェクトを生成します。セッションの作成後、すべてのセッション関連のメッセージが Session オブジェクトに直接に配信されます。OWLCS コンテナが、自動でセッション ID を生成し、各メッセージに ID をエンコードします。セッション属性は、SipApplicationSession
内の属性と非常に似た方法でにサポートされます。
例 11-3 は、単純な Diameter セッションの実装を表したものです。
例 11-3 単純な Diameter セッション
public class TestSession extends Session { public TestSession(TestApplication app) { super(app); } public void rcvRequest(Request req) throws IOException { getApplication().log("rcvReuest: " + req.getHopByHopId()); req.createAnswer(ResultCode.SUCCESS).send(); } }
サンプルの Session クラスを使用するには、例 11-2 の TestApplication
に次のようなファクトリ メソッドを追加する必要があります。
public class TestApplication extends Application { ... public TestSession createSession() { return new TestSession(this); } }
この後、TestSession
を使用して新しいリクエストを次のように作成できます。
TestSession session = testApp.createSession(); Request req = session.creatRequest(); req.sent();
応答は Session オブジェクトに直接配信されます。
基本 Message
クラスは、リクエストおよび応答のいずれのメッセージ タイプに対しても使用します。メッセージにはアプリケーション ID が常に含まれていて、必要に応じてセッション ID が含まれています。デフォルトで、メッセージは以下の方法で処理されます。
メッセージ バイトを解析します。
アプリケーション ID およびセッション ID の値を確認します。
以下のルールに従って、メッセージを対応するセッションまたはアプリケーションに配信します。
Session-Id AVP が存在する場合は、関連セッションを検索し、セッションの rcvMessage()
メソッドを呼び出します。
Session-Id AVP が存在しない場合、またはセッションが見つからない場合は、Diameter アプリケーションの rcvMessage()
メソッドを呼び出します。
アプリケーションが見つからない場合は、UNABLE_TO_DELIVER 応答を生成します。
メッセージのタイプは Diameter コマンド コードから特定します。RAR、RAA、ACR、ACA、CCR、CCA などのような特別なメッセージ タイプは、便宜上、Message
オブジェクトに getter および setter メソッドを含みます。
Session
または Application
はいずれも、リクエスト メッセージを送信および受信できます。リクエストは、createRequest()
メソッドを使用して生成します。新規のリクエスト メッセージについては、コマンド コードを提供する必要があります。ルーティング用に、通常は、送信元のセッションまたはアプリケーションによって宛先ホストまたは宛先レルム AVP が設定されます。
受信した応答は、Request.getAnswer()
で取得できます。応答の受信後、getSession()
を使用して関連セッション ID を取得し、getResultCode()
で結果を判定できます。また、Answer.getRequest()
を使用して、オリジナルのリクエスト メッセージを取得することもできます。
リクエストは、非同期的には send()
メソッドを使用して、同期的にはブロッキング sendAndWait()
メソッドを使用して送信できます。非同期的に送信されたリクエストに対する応答は、送信元のセッションまたはアプリケーションに配信されます。リクエスト タイムアウト値はメッセージの送信時に指定するか、または diameter.xml
内のグローバル request-timeout
コンフィグレーション要素を使用することができます。応答を配信する前にタイムアウト値に達した場合、UNABLE_TO_DELIVER 結果コードが生成されます。配信された応答上の getResultCode()
によって結果コードが返されます。
新規の応答メッセージは、createAnswer()
を使用して Request
オブジェクトから生成されます。生成された応答はすべて、ResultCode と、必要に応じて Error-Message AVP 値を指定します。ResultCode
クラスは、使用可能な事前定義済みのコードを含みます。
応答は常に send()
メソッドで配信されます。これは、常に非同期 (非ブロッキング) です。
Diameter コマンド コードはメッセージのタイプを特定します。たとえば、リクエスト メッセージを送信する場合、コマンド コードを指定する必要があります。
Command
クラスは、Diameter 基本プロトコルのための事前定義済みのコマンド コードを表します。このクラスを使用して、新しいコマンド コードを作成できます。コマンド コードは、コード自体に基づく共通の名前空間を共有します。
以下のようにして、define()
メソッドでコードの定義ができます。
static final Command TCA = Command.define(1234, "Test-Request", true, true);
define()
メソッドは新しいコマンドを登録するか、すでにそのコマンドが定義済みの場合はそのコマンド定義を返します。コマンドは、参照型等価演算子 (==) を使用して比較できます。
属性値ペア (AVP) は、Diameter メッセージに関連する情報をカプセル化する方法です。AVP は Diameter 基本プロトコル、Diameter アプリケーション、または Diameter を使用する上位レベルのアプリケーションで使用されます。
AVP
クラスは、Diameter 属性値のペアを表します。次の方法で、新しい AVP を属性値とともに作成できます。
Avp avp = new Avp(Attribute.ERROR_MESSAGE, "Bad request");
また、以下のように、属性名を直接指定することもできます。
Avp avp = new Avp("Error-Message", "Bad request");
指定する値は、指定した属性タイプで有効な値である必要があります。
グループにまとめた AVP を作成するには、以下のように AvpList
クラスを使用します。
AvpList avps = new AvpList(); avps.add(new Avp("Event-Timestamp", 1234)); avps.add(new Avp("Vendor-Id", 1111));
Diameter アプリケーションを拡張する新しい属性を作成できます。Attribute クラスは AVP 属性を表します。このクラスは AVP コード、名前、フラグ、ベンダ ID (省略可能)、および属性タイプを含みます。また、このクラスは、定義済みの属性のレジストリも保持します。すべての属性は、属性コードおよびベンダ ID に基づく共通の名前空間を共有します。
以下のようにして、define()
メソッドで新しい属性の定義ができます。
static final Attribute TEST = Attribute.define(1234, "Test-Attribute", 0, Attribute.FLAG_MANDATORY, Type.INTEGER32);
表 11-1 には、使用可能な属性タイプと、それらが Java タイプへマップされる方法が記載されています。
define()
メソッドは新しい属性を登録するか、すでにその属性が定義済みの場合はその定義を返します。属性は、参照型等価演算子 (==) を使用して比較できます。
Diameter API により、SIP および Diameter 機能の両方を利用するコンバージド アプリケーションを作成することができます。例 11-4 に示されているように、SIP サーブレットは Diameter ノード経由して使用可能な Diameter アプリケーションにアクセスできます。
例 11-4 SIP サーブレットから Rf アプリケーションへのアクセス
ServletContext sc = getServletConfig().getServletContext(); Node node = (Node) sc.getAttribute("com.bea.wcp.diameter.Node"); RfApplication rfApp = (RfApplication) node.getApplication(Charging.RF_APPLICATION_ID);
SIP はコール ID (SIP-Call-ID ヘッダ) を使用して 2 ユーザ間の特定のコール セッションを識別します。OWLCS ではコール ID を Diameter セッション ID にエンコードして、Diameter セッションを現在のアクティブな呼び出し状態と自動的にリンクします。Diameter メッセージを受信すると、コンテナが自動的に関連付けられた呼び出し状態を取得し、Diameter セッションを検索します。Diameter セッションはシリアライズ可能であり、そのためセッションを属性として (または、その反対に属性をセッションとして) SipApplicationSession
オブジェクトに格納することができます。
コンバージド アプリケーションでは、セッションが Diameter メッセージを受信した際、Diameter SessionListener
インタフェース を使用して通知を受信することができます。SessionListener
インタフェースで単一なメソッド rcvMessage()
が定義.されます。例 11-5 は、メソッドの実装方法の例を示します。
例 11-5 SessionListener の実装
Session session = app.createSession(); session.setListener(new SessionListener() { public void rcvMessage(Message msg) { if (msg.isRequest()) System.out.println("Got request!"); } });
注意 : SessionListener の実装は、分散型アプリケーションの場合はシリアライズ可能である必要があります。 |