![]() ![]() ![]() ![]() |
以下の節では、Oracle Communications Converged Application Server Diameter 基本プロトコル実装を使用して独自の Diameter アプリケーションを作成する方法について、概要を説明します。
Diameter は、属性値ペア (AVP) の配信を行うピアツーピア プロトコルです。Diameter メッセージには、1 つのヘッダと 1 つまたは複数の AVP が含まれています。各メッセージ内の AVP のコレクションは Diameter アプリケーションの種類によって決まります。また、Diameter プロトコルは、コマンドや AVP を新しく追加することで拡張することもできます。Diameter は、複数のピアがそれぞれの処理能力を相互に比較することを可能にし、それによりセッション処理機能およびアカウンティング機能のルールを定義します。
Oracle Communications Converged Application Server には、RFC 3588 に説明されているように、中核機能およびアカウンティング機能をサポートする Diameter 基本プロトコルの実装が含まれています。このドキュメントに後述されているように、Oracle Communications Converged Application Server は、Sh、Rf、Ro などの複数の Diameter アプリケーションを実装するために Diameter の基本機能を使用します。
また、Diameter 基本プロトコルを使用して、クライアントやサーバ側の Diameter アプリケーションを追加で実装することもできます。Diameter 基本 API はサーブレットに似た単純なプログラミング モデルを提供します。これにより、コンバージド アプリケーション内で Diameter 機能と SIP または HTTP 機能を組み合わせることが可能になります。
以下の節では、クライアントおよびサーバ側の Diameter アプリケーションを開発するために使用する Diameter 基本プロトコル パッケージ、クラス、プログラミング モデルの概要について説明します。また、付属している Diameter プロトコル アプリケーションの SIP サーブレット内での使用に関する情報は、以下の節を参照してください。
Diameter 基本プロトコル API 内のすべてのクラスは、ルートの com.bea.wcp.diameter
パッケージに格納されます。表 1-1 では、このパッケージ内の主なクラス、インタフェースおよび例外について説明します。
これらの基本の Diameter クラスに加え、com.bea.wcp.diameter.accounting
パッケージ内にアカウンティング関連のクラスが、com.bea.wcp.diameter.cc
内にクレジット管理関連のクラスが、それぞれ格納されています。これらのパッケージ内のクラスの詳細については、「オンライン チャージング用の Diameter Ro インタフェース アプリケーションの使用」と「オフライン チャージング用の Diameter Rf インタフェース アプリケーションの使用」を参照してください。
Diameter ノードは、com.bea.wcp.diameter.Node
クラスで表します。Diameter ノードは、diameter.xml
ファイル内のコンフィグレーションに従って、1 つまたは複数の Diameter アプリケーションをホストすることが可能です。Diameter アプリケーションにアクセスするには、デプロイされたアプリケーション (SIP サーブレットなど) が Diameter ノード インスタンスを取得して、アプリケーションをリクエストする必要があります。コード リスト 1-1 は、Rf アプリケーションへのアクセスに使用されるコードのサンプルを表したものです。
ServletContext sc = getServletConfig().getServletContext();
Node node = sc.getAttribute(“com.bea.wcp.diameter.Node”);
RfApplication rfApp = (RfApplication) node.getApplication(Charging.RF_APPLICATION_ID);
Diameter ノードは、通常、Oracle Communications Converged Application Server インスタンスの一部としてコンフィグレーションし、起動します。ただし、開発やテストのために、Diameter ノードを単独の処理として実行することもできます。これを行うには、以下の操作を行います。
すべての Diameter アプリケーションについて、基本 Application
クラス (クライアント アプリケーションの場合には ClientApplication
クラス) を拡張する必要があります。Diameter アプリケーションを作成するためのモデルは、次の方法でサーブレットを実装する場合のモデルと似ています。
適切なアプリケーション ID を返すには、Diameter アプリケーションで getId()
メソッドも実行する必要があります。この ID は、Diameter メッセージを正しいアプリケーションに通信するために使用されます。
必要に応じて、rcvRequest()
または rcvAnswer()
を実装することができます。デフォルトでは、rcvRequest()
は UNABLE_TO_COMPLY という応答を返し、rcvRequest()
は、Diameter メッセージを削除します。
コード リスト 1-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 クラスは Diameter セッションを表します。基本 Session クラスを拡張する場合は、rcvRequest()
または rcvAnswer()
のいずれかを実装する必要があります。両方のメソッドを実装することも可能です。
基本 Application クラスを使用して新しい Session オブジェクトを生成します。セッションの作成後、すべてのセッション関連のメッセージが Session オブジェクトに直接に配信されます。Oracle Communications Converged Application Server コンテナが、自動でセッション ID を生成し、各メッセージに ID をエンコードします。セッション属性は、SipApplicationSession
内の属性とほとんど同じ方法でサポートされます。
コード リスト 1-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 クラスを使用するには、コード リスト 1-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();
基本 Message
クラスは、リクエストと応答の両方のメッセージ タイプに対しても使用します。メッセージにはアプリケーション ID が常に含まれていて、必要に応じてセッション ID が含まれています。デフォルトでは、メッセージは以下の方法で処理されます。
メッセージのタイプは Diameter コマンド コードから特定します。RAR、RAA、ACR、ACA、CCR、CCA などのような特別なメッセージ タイプは、便宜上、Message
オブジェクトに getter および setter メソッドを含みます。
Session
または Application
はいずれも、リクエスト メッセージを送信および受信できます。リクエストは、createRequest()
メソッドを使用して生成します。新規のリクエスト メッセージについては、コマンド コードを提供する必要があります。ルーティングには、一般的に送信元のセッションまたはアプリケーションによって宛先ホストまたは宛先レルム AVP も設定されます。
リクエストは、非同期では send()
メソッドを使用して、同期ではブロッキング sendAndWait()
メソッドを使用して送信できます。非同期で送信されたリクエストに対する応答は、送信元のセッションまたはアプリケーションに配信されます。リクエスト タイムアウト値はメッセージの送信時に指定するか、または diameter.xml
内のグローバル request-timeout
コンフィグレーション要素を使用することができます。応答を配信する前にタイムアウト値に達した場合、UNABLE_TO_DELIVER 結果コードが生成されます。配信された応答上の getResultCode()
によって結果コードが返されます。
新規の応答メッセージは、createAnswer()
を使用して Request
オブジェクトから生成されます。生成されたすべての応答は、必ず ResultCode を、必要に応じて Error-Message AVP 値を指定する必要があります。ResultCode
クラスは、使用可能な事前定義済みのコードを含みます。
応答は常に send()
メソッドで配信されます。これは、常に非同期 (非ブロッキング) です。
受信した応答は、Request.getAnswer()
で取得できます。応答の受信後、getSession()
を使用して関連セッション ID を取得し、getResultCode()
で結果を判定できます。また、Answer.getRequest()
を使用して、オリジナルのリクエスト メッセージを取得することもできます。
Command
クラスは、Diameter 基本プロトコルのための事前定義済みのコマンド コードを表します。このクラスを使用して、新しいコマンド コードを作成できます。コマンド コードは、コード自体に基づく共通の名前空間を共有します。
以下のようにして、define()
メソッドでコードの定義ができます。
static final Command TCA = Command.define(1234, “Test-Request”, true, true);
define()
メソッドは新しいコマンドを登録するか、すでにそのコマンドが定義済みの場合はそのコマンド定義を返します。コマンドは、参照型等価演算子 (==) を使用して比較できます。
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));
Attribute クラスは AVP 属性を表します。このクラスは AVP コード、名前、フラグ、ベンダ ID (省略可能)、および属性タイプを含みます。また、このクラスは、定義済みの属性のレジストリも保持します。すべての属性は、属性コードおよびベンダ ID に基づく共通の名前空間を共有します。
以下のようにして、define()
メソッドで新しい属性の定義ができます。
static final Attribute TEST = Attribute.define(1234, “Test-Attribute”, 0, Attribute.FLAG_MANDATORY, Type.INTEGER32);
表 1-2 には、使用可能な属性タイプと、それらが Java タイプへマップされる方法が記載されています。
define()
メソッドは新しい属性を登録するか、すでにその属性が定義済みの場合はその定義を返します。属性は、参照型等価演算子 (==) を使用して比較できます。
Diameter API により、SIP および Diameter 機能の両方を利用するコンバージド アプリケーションを作成することができます。コード リスト 1-4 に示されているように、SIP サーブレットは Diameter ノード経由して使用可能な Diameter アプリケーションにアクセスできます。
ServletContext sc = getServletConfig().getServletContext();
Node node = (Node) sc.getAttribute(“com.bea.wcp.diameter.Node”);
RfApplication rfApp = (RfApplication) node.getApplication(Charging.RF_APPLICATION_ID);
Oracle Communications Converged Application Server では、Call-id を Diameter セッション ID にエンコードして、Diameter セッションを現在のアクティブな呼び出し状態と自動的にリンクします。Diameter メッセージを受信すると、コンテナが自動的に関連付けられた呼び出し状態を取得し、Diameter セッションを検索します。Diameter セッションはシリアライズ可能であるため、セッションを属性として (または、その反対に属性をセッションとして) SipApplicationSession
オブジェクトに格納することができます。
コンバージド アプリケーションでは、セッションが Diameter メッセージを受信した際、Diameter SessionListener
インタフェース を使用して通知を受信することができます。SessionListener
インタフェースで単一なメソッド rcvMessage()
が定義.されます。コード リスト 1-5
は、実装方法の例を示します。
Session session = app.createSession();
session.setListener(new SessionListener() {
public void rcvMessage(Message msg) {
if (msg.isRequest()) System.out.println(“Got request!”);
}
});
注意 : | SessionListener の実装は、分散型アプリケーションの場合はシリアライズ可能である必要があります。 |
![]() ![]() ![]() |