ヘッダーをスキップ
Oracle® WebLogic Server SIP Container開発者ガイド
11g リリース1(11.1.1)
B61430-01
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

8 Diameter基本プロトコルAPIの使用

この章では、Oracle WebLogic Server SIP Container Diameter基本プロトコル実装を使用して独自のDiameterアプリケーションを作成する方法の概要を説明します。内容は次のとおりです。

8.1 Diameterプロトコル・パッケージ

以下の項では、クライアントおよびサーバー側のDiameterアプリケーションを開発するために使用するDiameter基本プロトコル・パッケージ、クラス、プログラミング・モデルの概要について説明します。また、付属しているDiameterプロトコル・アプリケーションのSIPサーブレット内での使用に関する情報は、以下の項を参照してください。

8.2 Diameter APIの概要

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を使用してメッセージが適切なアプリケーションにルーティングされます。ApplicationIdは、Diameterメッセージに含まれるAuth-Application-Id、Acct-Application-Id、Vendor-Specific-Application-Id AVPのいずれかに相当します。


Session

Diameterセッションを表すクラス。セッション・ベースの処理を実行するアプリケーションでは、リクエストと応答メッセージを管理するためのアプリケーション固有の動作を提供する目的でこのクラスを拡張する必要があります。

メッセージ処理

Message、Request、Answer

Messageクラスは、リクエストおよび応答メッセージのタイプを表すために使用するベース・クラスです。RequestおよびAnswerはベース・クラスを拡張します。


Command

Diameterコマンド・コードを表すクラス。


RAR、RAA

これらのクラスは、RequestおよびAnswerクラスを拡張し、再認証メッセージを表します。


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

受信したメッセージについてデフォルトのメッセージ・レコーダをオーバーライドし、新しいタイプのRequestおよびAnswerオブジェクトをアプリケーションが作成できるようにするインタフェース。

デフォルトのデコーディング処理は、MessageFactoryのインスタンスを使用して、メッセージ・バイトからメッセージ・ヘッダーをデコードすることから開始されます。これは、メッセージ・ヘッダーが無効な場合は早期のエラー・メッセージを生成できるようにするためです。実際のメッセージAVPは、別の手順でdecodeAvpsを呼び出してデコードされます。validateを呼び出すことにより、AVP値を完全にデコードします。その後、メッセージ内の部分的にデコードされた各AVPについてvalidateAvpを呼び出します。


これらの基本のDiameterクラスに加え、com.bea.wcp.diameter.accountingパッケージ内にアカウンティング関連のクラスが、com.bea.wcp.diameter.cc内にクレジット管理関連のクラスが、それぞれ格納されています。これらのパッケージ内のクラスの詳細は、第11章「オンライン・チャージング用のDiameter RfインタフェースAPIの使用」第12章「オフライン・チャージング用のDiameter RoインタフェースAPIの使用」を参照してください。

8.2.1 Diameter APIを使用してアプリケーションをコンパイルするのに必要なファイル

次のjarファイルは、公開されるDiameter APIの一部です。このAPIに対してコンパイルを実行するには、次の場所のファイルにアクセスします。

wlssdiameter.jarファイルはMIDDLEWARE_HOME/server/lib/wlss/にあります。

8.3 Diameterノードの設定

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ノードを単独の処理として実行することもできます。これを行うには、次の操作を行います。

  1. 次のように、ドメインの環境を設定します。

    cd ~/bea/user_projects/domains/diameter/bin
    . ./setDomainEnv.sh
    
  2. 起動するノードのdiameter.xml構成ファイルを検索します。

    cd ../config/custom
    
  3. 使用するdiameter.xml構成ファイルを指定して、Diameterノードを起動します。

    java com.bea.wcp.diameter.Node diameter.xml
    

8.4 Diameterアプリケーションの実装

すべてのDiameterアプリケーションについて、基本Applicationクラス(クライアント・アプリケーションの場合にはClientApplicationクラス)を拡張する必要があります。Diameterアプリケーションを作成するためのモデルは、次の方法でサーブレットを実装する場合のモデルと似ています。

適切なアプリケーション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();
  }
}

8.5 Diameterセッションの設定

セッション・ベースの処理を実行するアプリケーションでは、基本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-2TestApplicationに次のようなファクトリ・メソッドを追加する必要があります。

public class TestApplication extends Application {
  ...
  public TestSession createSession() {
    return new TestSession(this);
  }
}

この後、TestSessionを使用して新しいリクエストを次のように作成できます。

TestSession session = testApp.createSession();
Request req = session.creatRequest();
req.sent();

応答はSessionオブジェクトに直接配信されます。

8.6 Diameterメッセージの設定

基本Messageクラスは、リクエストと応答のいずれのメッセージ・タイプに対しても使用します。メッセージにはアプリケーションIDが常に含まれていて、必要に応じてセッションIDが含まれています。デフォルトでは、メッセージは次の方法で処理されます。

  1. メッセージ・バイトを解析します。

  2. アプリケーションIDおよびセッションIDの値を確認します。

  3. 以下のルールに従って、メッセージを対応するセッションまたはアプリケーションに配信します。

    1. Session-Id AVPが存在する場合は、関連セッションを検索し、セッションのrcvMessage()メソッドを呼び出します。

    2. Session-Id AVPが存在しない場合、またはセッションが見つからない場合は、DiameterアプリケーションのrcvMessage()メソッドを呼び出します。

    3. アプリケーションが見つからない場合は、UNABLE_TO_DELIVERレスポンスを生成します。

メッセージのタイプはDiameterコマンド・コードから特定します。RAR、RAA、ACR、ACA、CCR、CCAなどのような特別なメッセージ・タイプは、便宜上、Messageオブジェクトにgetterおよびsetterメソッドを含みます。

8.6.1 リクエスト・メッセージの送信

SessionまたはApplicationはいずれも、リクエスト・メッセージを送信および受信できます。リクエストは、createRequest()メソッドを使用して生成します。新規のリクエスト・メッセージについては、コマンド・コードを提供する必要があります。ルーティング用に、通常は、送信元のセッションまたはアプリケーションによって宛先ホストまたは宛先レルムAVPが設定されます。

受信した応答は、Request.getAnswer()で取得できます。応答の受信後、getSession()を使用して関連セッションIDを取得し、getResultCode()で結果を判定できます。また、Answer.getRequest()を使用して、オリジナルのリクエスト・メッセージを取得することもできます。

リクエストは、非同期ではsend()メソッドを使用して、同期ではブロッキングsendAndWait()メソッドを使用して送信できます。非同期で送信されたリクエストに対する応答は、送信元のセッションまたはアプリケーションに配信されます。リクエスト・タイムアウト値はメッセージの送信時に指定するか、またはdiameter.xml内のグローバルrequest-timeout構成要素を使用できます。応答を配信する前にタイムアウト値に達した場合、UNABLE_TO_DELIVER結果コードが生成されます。配信された応答上のgetResultCode()によって結果コードが返されます。

8.6.2 応答メッセージの送信

新規の応答メッセージは、createAnswer()を使用してRequestオブジェクトから生成されます。生成された応答はすべて、ResultCodeと、必要に応じてError-Message AVP値を指定します。ResultCodeクラスは、使用可能な事前定義済のコードを含みます。

応答は常にsend()メソッドで配信されます。これは、常に非同期(非ブロッキング)です。

8.6.3 新しいコマンド・コードの作成

Diameterコマンド・コードはメッセージのタイプを特定します。たとえば、リクエスト・メッセージを送信する場合、コマンド・コードを指定する必要があります。

Commandクラスは、Diameter基本プロトコルのための事前定義済のコマンド・コードを表します。このクラスを使用して、新しいコマンド・コードを作成できます。コマンド・コードは、コード自体に基づく共通のネームスペースを共有します。

次のようにして、define()メソッドでコードを定義できます。

static final Command TCA = Command.define(1234, "Test-Request", true, true);

define()メソッドは新しいコマンドを登録するか、すでにそのコマンドが定義済の場合はそのコマンド定義を返します。コマンドは、参照型等価演算子(==)を使用して比較できます。

8.7 AVPの設定

属性値ペア(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));

8.7.1 新しい属性の作成

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()メソッドは新しい属性を登録するか、すでにその属性が定義済の場合はその定義を返します。属性は、参照型等価演算子(==)を使用して比較できます。

表8-2 属性タイプ

Diameterタイプ タイプ定数 Java型

Integer32

Type.INTEGER32

Integer

Integer64

Type.INTEGER64

Long

Float32

Type.FLOAT32

Float

OctetString

Type.BYTES

ByteBuffer(読取り専用)

UTF8String

Type.STRING

String

Address

Type.ADDRESS

InetAddress

Grouped

Type.GROUPED

AvpList


8.8 コンバージドDiameterとSIPアプリケーションの作成

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の実装は、分散型アプリケーションの場合はシリアライズ可能である必要があります。