この章では、Oracle WebLogic Server SIP Container Diameter基本プロトコル実装を使用して独自のDiameterアプリケーションを作成する方法の概要を説明します。内容は次のとおりです。
以下の項では、クライアントおよびサーバー側のDiameterアプリケーションを開発するために使用するDiameter基本プロトコル・パッケージ、クラス、プログラミング・モデルの概要について説明します。また、付属しているDiameterプロトコル・アプリケーションのSIPサーブレット内での使用に関する情報は、以下の項を参照してください。
第9章「プロファイル・サービスAPIの使用」には、Diameter Shアプリケーションを使用してサブスクライバのプロファイル・データにアクセスし、管理する方法が記載されています。
第11章「オフライン・チャージング用のDiameter RfインタフェースAPIの使用」には、Diameter Rfアプリケーションを使用してオフライン・チャージング・リクエストを発行する方法が記載されています。
第12章「オンライン・チャージング用のDiameter RoインタフェースAPIの使用」には、Diameter Roアプリケーションを使用してオンライン・チャージングを実行する方法が記載されています。
Diameter基本プロトコルAPI内のすべてのクラスは、ルートのcom.bea.wcp.diameter
パッケージに格納されます。表8-1では、このパッケージ内の主なクラス、インタフェースおよび例外について説明します。
表8-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
内にクレジット管理関連のクラスが、それぞれ格納されています。これらのパッケージ内のクラスの詳細は、第11章「オンライン・チャージング用のDiameter RfインタフェースAPIの使用」と第12章「オフライン・チャージング用のDiameter RoインタフェースAPIの使用」を参照してください。
Diameterノードは、com.bea.wcp.diameter.Node
クラスで表します。Diameterノードは、diameter.xml
ファイル内の構成に従って、1つまたは複数のDiameterアプリケーションをホストすることが可能です。Diameterアプリケーションにアクセスするには、デプロイされたアプリケーション(SIPサーブレットなど)がDiameterノード・インスタンスを取得して、アプリケーションをリクエストする必要があります。例8-1は、Rfアプリケーションへのアクセスに使用されるコードのサンプルを表したものです。
例8-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ノードは、通常、Oracle WebLogic Server SIP Containerインスタンスの一部として構成し、起動します。ただし、開発やテストのために、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メッセージを削除します。
例8-2は、セッションを使用しない単純なDiameterクライアント・アプリケーションを表したものです。
例8-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オブジェクトに直接に配信されます。Oracle WebLogic Server SIP Containerコンテナが、自動でセッションIDを生成し、各メッセージにIDをエンコードします。セッション属性は、SipApplicationSession
内の属性とほとんど同じ方法でサポートされます。
例8-3は、単純なDiameterセッションの実装を表したものです。
例8-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クラスを使用するには、例8-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);
表8-1には、使用可能な属性タイプと、それらがJavaタイプへマップされる方法が記載されています。
define()
メソッドは新しい属性を登録するか、すでにその属性が定義済の場合はその定義を返します。属性は、参照型等価演算子(==)を使用して比較できます。
Diameter APIにより、SIPおよびDiameter機能の両方を利用するコンバージド・アプリケーションを作成できます。例8-4に示されているように、SIPサーブレットはDiameterノード経由して使用可能なDiameterアプリケーションにアクセスできます。
例8-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ユーザー間の特定のコール・セッションを識別します。Oracle WebLogic Server SIP ContainerはSIPコールIDをDiameterセッションIDにエンコードして、Diameterセッションを現在のアクティブな呼出し状態に自動的にリンクします。Diameterメッセージを受信すると、コンテナは関連付けられた呼出し状態を自動的に取得し、Diameterセッションを検索します。Diameterセッションはシリアライズ可能であるため、セッションを属性として(または、その反対に属性をセッションとして)SipApplicationSession
オブジェクトに格納できます。
コンバージド・アプリケーションでは、セッションがDiameterメッセージを受信した際、Diameter SessionListener
インタフェースを使用して通知を受信できます。SessionListener
インタフェースで単一なメソッドrcvMessage()
が定義されます。例8-5は、実装方法の例を示します。
例8-5 SessionListenerの実装
Session session = app.createSession(); session.setListener(new SessionListener() { public void rcvMessage(Message msg) { if (msg.isRequest()) System.out.println("Got request!"); } });
注意: SessionListener の実装は、分散型アプリケーションの場合はシリアライズ可能である必要があります。 |