WebAPIサーバプログラム、WebAPI公開方法
【課題】OSGiバンドルが備える機能をWebAPI経由で容易に公開することのできる技術を提供する。
【解決手段】本発明に係るWebAPIサーバプログラムは、OSGiフレームワーク上に登録されているOSGiバンドル(OSGiサービス)のクラス名とメソッド名をHTTPリクエストとして受け取り、これらに合致するOSGiバンドル(OSGiサービス)を呼び出して実行し、その結果をHTTPレスポンスとして返信する。
【解決手段】本発明に係るWebAPIサーバプログラムは、OSGiフレームワーク上に登録されているOSGiバンドル(OSGiサービス)のクラス名とメソッド名をHTTPリクエストとして受け取り、これらに合致するOSGiバンドル(OSGiサービス)を呼び出して実行し、その結果をHTTPレスポンスとして返信する。
【発明の詳細な説明】
【技術分野】
【0001】
本発明は、OSGiフレームワーク仕様に対応したOSGiバンドルをWebAPI経由で公開する技術に関するものである。
【背景技術】
【0002】
図1は、OSGiフレームワークの構成を示す図である。OSGiフレームワークとは、Java(登録商標)Virtual Machine上で動作し、JavaプログラムをPluginモジュールとして取り扱い、動的にアプリケーションへ追加できるようにする、サービスプラットフォームである。OSGiフレームワークは、OSGi Allianceによって開発・定義されている(非特許文献1)。
【0003】
図1において、OSGiフレームワーク13は、ホスト10上で動作するOS(Operating System)11およびその配下で動作するJavaVM12上のJavaアプリケーションとして実装されている。OSGiフレームワーク13は、Javaモジュールの提供するサービスをOSGiプラットフォーム13上に登録するためのインターフェースである、サービスレジストリ131を公開している。OSGiフレームワーク仕様に準拠し、OSGiフレームワーク13に登録することができるよう(OSGiフレームワーク上で動作するよう)に構成されているJavaモジュールのことを、OSGiバンドルと呼ぶ。OSGiバンドルの実体は、Javaクラス(Javaクラス群 or Javaパッケージ or 複数のJavaクラスから成るJavaパッケージ)および関連する設定ファイル等である。また、OSGiバンドルの提供するサービスのことをOSGiサービスと呼ぶ。OSGiサービスの実体は、Javaクラスである。
【0004】
例えば、OSGiフレームワーク13上でOSGiバンドルA14が既に動作していると仮定する。JavaVM12は、OSGiフレームワーク13を利用することにより、OSGiバンドルA14と連携して動作するOSGiバンドルB15を、OSGiバンドルA14を再起動することなくアプリケーション上に追加することができる。
【0005】
ここでいう連携とは、OSGiバンドルA14からOSGiバンドルB15が有するメソッドを呼び出す、OSGiバンドルB15からOSGiバンドルA14が有するメソッドを呼び出す、両バンドル間でデータを共有する、などの動作のことをいう。
【0006】
OSGiバンドル同士の連携は、OSGiフレームワーク13が提供するサービスレジストリ131を介して行なわれる。例えば、OSGiバンドルB15が備える機能B151(メソッド(クラス))をOSGiバンドルA14から使用したい場合、所定のコマンドを発行することにより、OSGiバンドルB15をサービスレジストリ131に登録する。
【0007】
サービスレジストリ131に登録されたOSGiバンドルB15の機能Bは、OSGiサービスB132として、サービスレジストリ131上で公開される。OSGiバンドルA14は、サービスレジストリ131からOSGiサービスB132を取得し、機能B151に対応する(機能Bの有する)メソッドを実行することができる。
【0008】
一方、OSGiバンドルB15が備える機能151を、ホスト10の外部から使用するためには、そのための通信インターフェースをOSGiバンドルB15内に設けておく必要がある。例えばHTTP(Hyper Text Transfer Protocol)を用いて機能151をクライアント端末20から使用するためには、WebAPIサーバとしての機能を備えたWebAPIサーバ部152をOSGiバンドルB15内に設ける必要がある。
【0009】
ここでいうWebAPIサーバとは、例えばCGI(Common Gateway Interface)のように、HTTPを用いてネットワーク経由でアプリケーションを実行してその結果を取得するためのインターフェース、およびそのためのWebサーバ機能のことを総称的に指したものである。具体的な実装手段はCGIに限られるものではなく、HTTPを介してリクエストを受け付け、その実行結果をHTTPレスポンスとして返すものであれば、任意の実装手法を用いることができる。
【先行技術文献】
【非特許文献】
【0010】
【非特許文献1】OSGi Service Platform Release 4、URL:http://www.osgi.org/Release4/HomePage(2010年8月9日取得)
【発明の概要】
【発明が解決しようとする課題】
【0011】
OSGiバンドルが備える機能をネットワーク上で公開し、ネットワーク経由で使用できるようにするためには、図1に示したWebAPIサーバ部152のようなサーバ機能および機能を公開するためのインターフェースが必要となる。しかし、機能を公開するOSGiバンドル毎に上述のような機能を実装することは、開発工数などの面から負担が大きい。
【0012】
本発明は、上記のような課題を解決するためになされたものであり、OSGiバンドルが備える機能をWebAPI経由で容易に公開することのできる技術を提供することを目的とする。
【課題を解決するための手段】
【0013】
本発明に係るWebAPIサーバプログラムは、OSGiフレームワーク上に登録されているOSGiバンドルのクラス名とメソッド名をHTTPリクエストとして受け取り、これらに合致するOSGiバンドルを呼び出して実行し、その結果をHTTPレスポンスとして返信する。
【発明の効果】
【0014】
本発明に係るWebAPIサーバプログラムによれば、ネットワーク上で機能を公開したいOSGiバンドル(OSGiサービス)をOSGiフレームワークに登録するのみで、自動的にWebAPI経由でネットワーク上に公開することができる。したがって、個々のOSGiバンドルにはWebAPIサーバ機能を実装する必要がなくなり、開発負担をかけずに、OSGiバンドルをWebサービスとして提供することができる。
【図面の簡単な説明】
【0015】
【図1】OSGiフレームワークの構成を示す図である。
【図2】実施形態1に係るWebシステム100の構成図である。
【図3】WebAPIバンドル17の機能ブロック図を示す。
【図4】OSGiサービスの実体を模式的に示す図である。
【図5】OSGiバンドルB15をサービスレジストリ131に登録し、OSGiサービスとして実行するまでの様子を示す概念図である。
【図6】クラス名とメソッド名を指定して実行結果を返信するよう要求するHTTPリクエストとそのレスポンスの対応関係を示す図である。
【図7】サービスレジストリ131に登録されているOSGiサービスの一覧を返信するよう要求するHTTPリクエストとそのレスポンスを例示する図である。
【図8】WebAPIバンドル17の動作フローである。
【図9】実施形態2において、WebAPIバンドル17がOSGiサービスをWebAPIとして公開する様子を示す図である。
【図10】WebAPIバンドル17を介してOSGiサービスを呼び出す際に指定することのできるHTTPリクエストパラメータとレスポンス例を示す図である。
【図11】レスポンスの記述形式としてXMLを用いる例を示す図である。
【発明を実施するための形態】
【0016】
<実施の形態1>
図2は、本発明の実施形態1に係るWebシステム100の構成図である。Webシステム100は、ホスト10上で動作するアプリケーションを、ネットワークを介してクライアント20から利用する形態のシステムである。クライアント20は、HTTPを用いてホスト10にアクセスし、利用したい機能をリクエストし、その実行結果をHTTPレスポンスとして受信する。
【0017】
ホスト10は、図1で説明したOSGiバンドルA14に代えて、WebAPIバンドル17を備える。その他の構成は、図1と同様である(バンドルBはWebAPIサーバ部を持たない)。なお、以下の説明の便宜上、OSGiバンドルB15が持つJavaオブジェクトである機能BをOSGiフレームワーク13に登録したときの名称を、ServiceB132として表記することにする。
【0018】
ホスト10は、OS11、JavaVM12などを実行するCPU(Central Processing Unit)などの演算装置、これらプログラムおよび各OSGiバンドルを格納するHDD(Hard Disk Drive)などの記憶装置、必要なメモリおよびネットワークインターフェースなどの、ホストコンピュータとして必要な構成を適宜備えるものとする。
【0019】
以下では説明の便宜上、OSGiフレームワーク13や各OSGiバンドルなどのプログラムを動作主体として説明するが、実際にこれらプログラムを実行するのは、ホスト10が備えるCPU、さらにはCPUが実行するJavaVM12であることを付言しておく。
【0020】
WebAPIバンドル17は、OSGiバンドルとして実装されている。WebAPIバンドル17は、サービスレジストリ131に(OSGiサービスを)登録するためのものではなく、クライアント20からリクエストを受け付けてサービスレジストリ131に登録されているサービスを呼び出して実行し、その結果を返信するモジュールである。WebAPIバンドル17は、JavaVM12の配下で動作し、クライアント20からのHTTPリクエストを待ち受けるWebサーバ機能を提供する。WebAPIバンドル17は、本発明における「WebAPIサーバプログラム」に相当する。
【0021】
クライアント20は、HTTPを用いてWebAPIバンドル17が公開するWebAPIにアクセスし、WebAPIバンドル17が提供するサービス(ここではServiceB132)を実行するようリクエストする。WebAPIバンドル17はそのリクエストを処理し、実行結果をHTTPレスポンスとしてクライアント20に返信する。
【0022】
図3は、WebAPIバンドル17の機能ブロック図を示す。WebAPIバンドル17は、HTTPサーバ部171、OSGiサービス実行部172、OSGiサービス一覧取得部173を備える。これら機能部は、WebAPIバンドル17が備えるJavaメソッドとして実装することができる。
【0023】
HTTPサーバ部171は、クライアント20からHTTPリクエストを受け付け、HTTPレスポンスを返信する、Webサーバとしての機能を備える。OSGiサービス実行部172は、サービスレジストリ131に登録されているOSGiサービスを取得し、実行する。OSGiサービス一覧取得部173は、サービスレジストリ131に登録されているOSGiサービスの一覧を取得する。
【0024】
図4は、OSGiサービスの実体を模式的に示す図である。ここでは、OSGiバンドルB15の持つ機能BをOSGiサービスであるServiceB132として登録する場合の例を示した。
【0025】
OSGiサービスの実体は、サービスレジストリ131に登録されたOSGiバンドルを構成する(OSGiバンドルが持つ)Javaクラスのインスタンスである。OSGiサービスをサービスレジストリ131に登録するとは、OSGiバンドルを構成する(OSGiバンドルが持つ)Javaクラスのインスタンスを生成し、その参照をサービスレジストリ131に引き渡すことである。
【0026】
OSGiサービスを利用する側では、サービスレジストリ131が保持しているこのJavaインスタンスを、クラス名をキーとして取得し、そのクラスが有するメソッドを実行することにより、OSGiサービスを利用する。
【0027】
図4に示す例では、OSGiサービスを利用する側のJavaクラス(例えばWebAPIバンドル17)は、クラス名「ServiceB」をキーにしてサービスレジストリ131からServiceB132を取得し、メソッド「func1」「func2」などを実行する。これらのメソッドは、OSGiバンドルB15が提供する機能151に相当する。
【0028】
図5は、OSGiバンドルB15をサービスレジストリ131に登録し、OSGiサービスとして実行するまでの様子を示す概念図である。OSGiサービスとJavaインスタンスの関連イメージを示すため、ごく簡略化したサンプルソースコードを併記した。同ソースコードは説明のためのものであり、必ずしも実際のソースコードを示すものではないことを付言しておく。
【0029】
OSGiサービスの提供元であるOSGiバンドルB15は、ServiceBオブジェクトを生成し、サービスレジストリ131に登録する。サービスレジストリ131は、ServiceBクラスのインスタンスへの参照を保持する。
【0030】
OSGiサービスを利用する側であるWebAPIバンドル17のOSGiサービス実行部172は、利用しようとしているOSGiサービスのバンドルに対応するクラス名「ServiceB」をキーにして、サービスレジストリ131からServiceBオブジェクトへの参照を取得する。OSGiサービス実行部172(実際にはJavaVM12)は、取得したServiceBオブジェクトを、ホスト10が備えるメモリ上に確保する(参照なのでオブジェクト用のメモリは不要。参照を入れる変数用のメモリのみ要)。
【0031】
WebAPIバンドル17のOSGiサービス実行部172は、ServiceBオブジェクトが有するメソッド、例えば「func1」メソッドを実行する。HTTPサーバ部171は、その結果をクライアント20にHTTPレスポンス形式で返信する。
【0032】
図5で説明した例では、OSGiサービスを提供するOSGiバンドルのクラス名およびメソッド名が、WebAPIバンドル17にとって既知であることを前提とした。ただし、一般にはOSGiバンドルのクラス名およびメソッド名は必ずしも既知ではなく、Webシステム100の設計仕様などによって個別に異なる。また、図5のように実装すると、WebAPIバンドル17とOSGiバンドルB15の結びつきが強くなり、OSGiフレームワーク13がPlugin機構を提供することの利点が減じられてしまう。
【0033】
そこで以下では、OSGiサービスを提供するOSGiバンドルのクラス名およびメソッド名をWebAPIバンドル17の外部から与え、任意のクラス名およびメソッド名をサービスレジストリ131から呼び出すことができるように構成することを考える。
【0034】
図6は、クライアント20からWebAPIバンドル17に対して、クラス名とメソッド名を指定して実行結果を返信するよう要求するHTTPリクエストとそのレスポンスの対応関係を示す図である。1行目はServiceB132の「func1」メソッドを呼び出す場合の例、2行目はServiceB132の「func2」メソッドを呼び出す場合の例を示す。
【0035】
クライアント20は、WebAPIバンドル17にHTTPリクエストを発行する際に、リクエストパラメータとして、OSGiサービスを提供するクラス名、そのメソッド名、メソッドの引数を、リクエスト内に含めておく。引数が複数ある場合は、その分だけリクエストパラメータを設ける。
【0036】
WebAPIバンドル17のHTTPサーバ部171は、上記HTTPリクエストを受け取ると、リクエストパラメータ部分を切り出してOSGiサービス実行部172に引き渡す。
【0037】
OSGiサービス実行部172は、リクエストパラメータに記述されているクラス名をキーにして、サービスレジストリ131から同クラス名に該当するOSGiサービスを呼び出す。OSGiサービス実行部172は、リクエストパラメータに記述されているメソッド名に対応するメソッドを実行し、HTTPサーバ部171を介して、その結果をクライアント20に返信する。HTTPレスポンスはテキスト形式であるため、記述形式は任意でよい。図6では、リクエストパラメータと同様の形式を用いた例を示した。メソッドの戻り値が複数ある場合は、その旨をHTTPレスポンス内に併せて記述する。
【0038】
クライアント20が、サービスレジストリ131上に存在しないクラス名またはメソッド名をリクエストパラメータ内で指定した場合、またはクラスとメソッドは存在するが引数の型が合致しない場合、OSGiサービス実行部172およびHTTPサーバ部171は、例外を発行してその旨をクライアント20に返信する。
【0039】
OSGiサービス実行部172が、リクエストパラメータに記述されているクラス名を用いてOSGiサービスのクラスを取得するとき、図5の左上ソースコード例に示すように、サービスレジストリ131は、汎用クラス型であるObject型としてOSGiクラスを引き渡す。これは、任意のクラス型をサービスレジストリ131に登録できるようにするために必要な仕様であると思われる。
【0040】
ただし、Object型は汎用クラス型であるため、ごく基本的なメソッドしか備えておらず、ServiceBクラスが有する「func1」「func2」のようなメソッドは備えていない。そこでWebAPIバンドル17は、文字列変数が保持している文字列を用いて任意のメソッドを起動することのできる、java.lang.reflectパッケージの機能を利用する。
【0041】
同パッケージの機能を用いると、Objectクラス型をServiceBクラス型に変換することなく、Object型のままで任意のメソッドを起動することができる。このことは、任意クラスの任意メソッドを実行することができるメリットの他に、特定クラスへの依存性をなくすことができる点でも有利である。
【0042】
すなわち、通常であれば、WebAPIバンドル17は、ServiceB132のクラス名をクライアント20からリクエストパラメータとして与えられたとき、サービスレジストリ131から取得したObject型をいったんServiceB型に変換した上で、「func1」などのメソッドを実行する。Object型は同メソッドを有さないからである。しかしそのためには、WebAPIバンドル17内でServiceBクラスをあらかじめ取り込んでおかなければならず、その時点でWebAPIバンドル17の汎用性が減じられてしまう。
【0043】
これに対し上記手法によれば、リクエストパラメータで与えられたクラス型に変換する処理は発生しないので、同クラスを取り込む必要はなくなり、クラス型に対する中立性・汎用性を保つことができる。
【0044】
図7は、クライアント20からWebAPIバンドル17に対して、サービスレジストリ131に登録されているOSGiサービスの一覧を返信するよう要求するHTTPリクエストとそのレスポンスを例示する図である。クライアント20は、WebAPIバンドル17にHTTPリクエストを発行する際に、OSGiサービスの一覧を返信するよう要求する旨を、リクエストパラメータとしてリクエスト内に含めておく。図7に示す例ではパラメータ「getservicelist=true」がこれに相当する。
【0045】
WebAPIバンドル17のHTTPサーバ部171は、上記HTTPリクエストを受け取ると、リクエストパラメータ部分を切り出してOSGiサービス実行部172に引き渡す。
【0046】
OSGiサービス一覧取得部173は、サービスレジストリ131に登録されているOSGiサービスのクラス名一覧を取得する。さらに、java.lang.reflectパッケージの機能を利用して、各OSGiサービスのクラスが有するメソッド名、メソッド引数、メソッド戻り型などの情報を取得する。OSGiサービス一覧取得部173は、HTTPサーバ部171を介して、取得結果をクライアント20に返信する。
【0047】
OSGiサービス一覧取得部173の機能は、例えばクライアント20が利用したいサービスに対応するクラス名やメソッド名がサービスレジストリ131内に存在するか否かを確認するためなどに用いられる。
【0048】
図8は、WebAPIバンドル17の動作フローである。以下、図8の各ステップについて説明する。
【0049】
(図8:ステップS801)
WebAPIバンドル17が起動すると、HTTPサーバ部171はクライアント20からのHTTPリクエストを待機する。クライアント20からHTTPリクエストが到着すると、HTTPサーバ部171は、そのリクエストがOSGiサービスの一覧を取得するリクエストであるか、OSGiサービスを呼び出すリクエストであるかを判定する。前者であればステップS802へ進み、後者であればステップS803へ進む。
【0050】
(図8:ステップS802)
OSGiサービス一覧取得部173は、サービスレジストリ131に登録されているOSGiサービスのクラス名、メソッド名、メソッド引数、メソッド戻り型などの一覧を取得する。HTTPサーバ部171は、その取得結果をHTTPレスポンスとしてクライアント20に返信し、本動作フローを終了する。HTTPサーバ部171は、再びHTTPリクエストを待機する。
【0051】
(図8:ステップS803)
OSGiサービス実行部172は、クライアント20からのHTTPリクエストで指定されたクラス名、メソッド名などを用いて、サービスレジストリ131から該当するOSGiサービスを呼び出す。呼び出しに成功した場合はステップS804へ進み、失敗した場合はステップS805へ進む。
【0052】
(図8:ステップS804)
OSGiサービス実行部172は、ステップS803で呼び出したOSGiサービス(呼び出したクラス)のメソッドを実行する。実行に成功した場合はステップS806へ進み、失敗した場合はステップS805へ進む。
【0053】
(図8:ステップS805)
HTTPサーバ部171は、エラーが発生した旨のHTTPレスポンスを、クライアント20に返信する。HTTPサーバ部171は、再びHTTPリクエストを待機する。本ステップにおいて、HTTPレスポンスの内容部分にエラーが発生した旨を記述してもよいし、単純にHTTPが規定するエラーコードを返信してもよい。どのようなエラーが発生したのか明示する観点では、前者のほうが望ましい。
【0054】
(図8:ステップS806)
HTTPサーバ部171は、OSGiサービス実行部172がOSGiサービスを実行した結果をHTTPレスポンス内に記述し、クライアント20に返信する。HTTPサーバ部171は、再びHTTPリクエストを待機する。
【0055】
<実施の形態1:まとめ>
以上のように、本実施形態1に係るWebAPIバンドル17は、実行したいOSGiサービスのクラス名、メソッド名などを指定するHTTPリクエストを受け取り、当該メソッドを実行してその結果をHTTPレスポンスとして返信する。これにより、ネットワーク上で公開したいOSGiバンドルの持つOSGiサービスをサービスレジストリ131に登録しておけば、自動的にWebAPIとしてネットワークに公開することができるので、個別にHTTPサーバ機能などを実装する必要がなくなり、開発負担を低減することができる。
【0056】
また、本実施形態1に係るWebAPIバンドル17は、サービスレジストリ131からOSGiサービスを取得した後、汎用クラス型であるObject型をOSGiバンドルのクラス型に変換することなく、クライアント20が指定したメソッドをそのまま実行する。これにより、WebAPIバンドル17をOSGiバンドルのクラス型から切り離し、クラス間の依存関係をなくして汎用性を高めることができる。すなわち、WebAPIバンドル17は、サービスレジストリ131にどのようなOSGiサービスが登録されていても、そのクラス型をあらかじめ読み込んでおくことなく、指定されたクラスおよびメソッドを呼び出して実行することができる。
【0057】
また、本実施形態1に係るWebAPIバンドル17は、サービスレジストリ131に登録されているクラス名、メソッド名などの一覧をクライアント20に提供することができる。これにより、クライアント20はリクエストを発行する前にエラーが発生する可能性を事前に知ることができるので、メソッドを実行してエラーが返ってくるか否かにより当該メソッドの存否を調べるような非効率な処理をしなくてすむ。
【0058】
<実施の形態2>
実施形態1では、サービスレジストリ131に登録されているOSGiバンドルは無条件にネットワーク上へ公開される。しかし、OSGiフレームワーク13の機能を利用するためサービスレジストリ131に登録されているOSGiバンドルのなかには、ネットワークに公開したくないものも含まれている可能性がある。そこで本発明の実施形態2では、ネットワーク上に公開するOSGiバンドルとそうでないOSGiバンドルを区別するための手法を説明する。その他の構成は実施形態1と同様であるため、以下では差異点を中心に説明する。
【0059】
図9は、本実施形態2において、WebAPIバンドル17がOSGiサービスをWebAPIとして公開する様子を示す図である。本実施形態2では、OSGiバンドルのうちネットワーク上にWebAPIとして公開するものについては、メンバ変数153(フィールド)「openapi」を設けることとする。
【0060】
WebAPIバンドル17は、OSGiサービスを実行するようリクエストを受けたとき、またはサービスレジストリ131に登録されているOSGiサービスの一覧を取得するようリクエストを受けたとき、サービスレジストリ131から取得したOSGiバンドルクラスのメンバ変数「openapi」を取得する。同メンバ変数の値が「true」である場合は、当該クラスが有するメソッドをWebAPIとして公開してよいものと判断する。同メンバ変数の値が「true」でない場合、または同メンバ変数が存在しない場合は、当該クラスが有するメソッドをWebAPIとして公開しない。
【0061】
WebAPIバンドル17は、WebAPIとして公開しないクラスについてサービス実行リクエストを受けた場合は、エラーを返信する。また、WebAPIとして公開しないクラスについては、サービスレジストリ131に登録されているOSGiサービスの一覧をクライアント20に返信するとき、その一覧に当該クラスを記述しないこととする。
【0062】
WebAPIバンドル17がサービスレジストリ131からOSGiバンドルクラス(OSGiサービスクラス)を取得したとき、図5で説明したように、クラス型はObject型となっている。そこでWebAPIバンドル17は、java.lang.reflectパッケージの機能を利用して、メンバ変数「openapi」にアクセスする。この手法によれば、同メンバ変数がprivate指定されている(当該クラスの外部からアクセスすることを禁止する旨の宣言)場合でも、同メンバ変数にアクセスすることができる。
【0063】
なお、メンバ変数「openapi」をprivate宣言する場合、他のOSGiバンドルから同変数を参照することはできないので、他のOSGiバンドルにとっては同変数が存在しないに等しい。すなわち、本実施形態2に固有のメンバ変数を設けているか否かによらず、OSGiフレームワーク13にとっては全てのOSGiバンドルを同等に取り扱うことができるので、本実施形態2固有の格別の配慮を要さない点で便宜である。
【0064】
<実施の形態2:まとめ>
以上のように、本実施形態2に係るWebAPIバンドル17は、サービスレジストリ131に登録されているOSGiバンドルのメンバ変数「openapi」の値をチェックし、当該クラスをWebAPIとして公開してよいか否かを判定する。これにより、ネットワークに公開したいOSGiバンドルのみを選択的に公開することができるので、公開すべきでないOSGiバンドルを不用意にネットワークへ公開する可能性を低減することができる。
【0065】
<実施の形態3>
本発明の実施形態3では、クライアント20とWebAPIバンドル17の間のHTTPリクエストおよびHTTPレスポンスの形式について補足する。Webシステム100の構成は、実施形態1〜2と同様である。
【0066】
図10は、WebAPIバンドル17を介してOSGiサービスを呼び出す際に指定することのできるHTTPリクエストパラメータとレスポンス例を示す図である。
【0067】
HTTPはテキストベースのプロトコルであるため、Javaオブジェクトをそのままリクエストおよびレスポンス内で用いることは難しい。したがって、クライアント20からのリクエスト上およびクライアント20へのレスポンス上で用いることができるのは、テキストベースで表現することのできる、Java基本型およびString(文字列)型に限られる。すなわち、独自のクラス型や、任意のクラス型を含む配列(例えばArrayList)などは用いることができない。
【0068】
また、Dictionary型(内部的に複数の値を格納している、配列に似たクラス型)はレスポンス内で用いることはできるが、リクエストパラメータとして用いることは好ましくない。これは、HTTPリクエストパラメータの記述形式に起因する。
【0069】
HTTPレスポンスは改行コードを含む任意のテキスト形式で記述することができるため、Javaメソッドの実行結果がDictionary型であり、そのなかに複数の値が含まれている場合でも、全ての値をレスポンス内に記述することができる。
【0070】
しかし、HTTPリクエストパラメータは「arg1=1」のように、パラメータ名とその値を1つずつペアにして記述するため、パラメータ値がDictionary型になっていて内部的に複数の値を含む場合、「arg1=(age=30&height=170)」のように多重的に記載せざるを得ず、煩雑になってしまう。また実際上、引数としてDictionary型を用いる必要性はあまりない。そこで図10では、リクエストパラメータとしてDictionary型を用いないこととした。
【0071】
図11は、レスポンスの記述形式としてXML(eXtensible Markup Language)を用いる例を示す図である。レスポンスの内容は、図6と同様である。このようなXML形式のレスポンスを、REST(Representational State Transfer)形式とも呼ぶ。レスポンスをXML形式に変換する処理は、OSGiサービスとの関連が少ない処理であるため、例えばHTTPサーバ部171が実施すればよい。
【0072】
レスポンスのほか、HTTPリクエストもXML形式で記述することもできる。例えばSOAP(Simple Object Access Protocol)形式のXMLメッセージをクライアント20からWebAPIバンドル17に発行し、HTTPサーバ部171がそのメッセージを解析して必要なパラメータのみをOSGiサービス実行部172に引き渡すようにすればよい。
【0073】
<実施の形態4>
以上の実施形態1〜3では、WebAPIバンドル17はHTTPリクエストとしてOSGiサービスのクラス名などを直接受け取ることとしたが、必ずしもクラス名などそのものを記述したリクエストパラメータを用いなくともよい。
【0074】
例えば、WebAPIバンドル17は、クラス名やメソッド名を所定規則で変換した文字列をリクエストパラメータとして受け取り、WebAPIバンドル17の内部、または適当な変換モジュールなどを介して、OSGiサービスのクラス名、メソッド名などに変換してもよい。すなわち、WebAPIバンドル17は、少なくともOSGiサービスのクラス名、メソッド名などを特定することのできるリクエストパラメータを受け取れば足りる。
【符号の説明】
【0075】
10:ホスト、11:OS、12:JavaVM、13:OSGiフレームワーク、131:サービスレジストリ、132:ServiceB、14:OSGiバンドルA、15:OSGiバンドルB、151:機能B、152:WebAPIサーバ部、153:メンバ変数、17:WebAPIバンドル、171:HTTPサーバ部、172:OSGiサービス実行部、173:OSGiサービス一覧取得部、20:クライアント、100:Webシステム。
【技術分野】
【0001】
本発明は、OSGiフレームワーク仕様に対応したOSGiバンドルをWebAPI経由で公開する技術に関するものである。
【背景技術】
【0002】
図1は、OSGiフレームワークの構成を示す図である。OSGiフレームワークとは、Java(登録商標)Virtual Machine上で動作し、JavaプログラムをPluginモジュールとして取り扱い、動的にアプリケーションへ追加できるようにする、サービスプラットフォームである。OSGiフレームワークは、OSGi Allianceによって開発・定義されている(非特許文献1)。
【0003】
図1において、OSGiフレームワーク13は、ホスト10上で動作するOS(Operating System)11およびその配下で動作するJavaVM12上のJavaアプリケーションとして実装されている。OSGiフレームワーク13は、Javaモジュールの提供するサービスをOSGiプラットフォーム13上に登録するためのインターフェースである、サービスレジストリ131を公開している。OSGiフレームワーク仕様に準拠し、OSGiフレームワーク13に登録することができるよう(OSGiフレームワーク上で動作するよう)に構成されているJavaモジュールのことを、OSGiバンドルと呼ぶ。OSGiバンドルの実体は、Javaクラス(Javaクラス群 or Javaパッケージ or 複数のJavaクラスから成るJavaパッケージ)および関連する設定ファイル等である。また、OSGiバンドルの提供するサービスのことをOSGiサービスと呼ぶ。OSGiサービスの実体は、Javaクラスである。
【0004】
例えば、OSGiフレームワーク13上でOSGiバンドルA14が既に動作していると仮定する。JavaVM12は、OSGiフレームワーク13を利用することにより、OSGiバンドルA14と連携して動作するOSGiバンドルB15を、OSGiバンドルA14を再起動することなくアプリケーション上に追加することができる。
【0005】
ここでいう連携とは、OSGiバンドルA14からOSGiバンドルB15が有するメソッドを呼び出す、OSGiバンドルB15からOSGiバンドルA14が有するメソッドを呼び出す、両バンドル間でデータを共有する、などの動作のことをいう。
【0006】
OSGiバンドル同士の連携は、OSGiフレームワーク13が提供するサービスレジストリ131を介して行なわれる。例えば、OSGiバンドルB15が備える機能B151(メソッド(クラス))をOSGiバンドルA14から使用したい場合、所定のコマンドを発行することにより、OSGiバンドルB15をサービスレジストリ131に登録する。
【0007】
サービスレジストリ131に登録されたOSGiバンドルB15の機能Bは、OSGiサービスB132として、サービスレジストリ131上で公開される。OSGiバンドルA14は、サービスレジストリ131からOSGiサービスB132を取得し、機能B151に対応する(機能Bの有する)メソッドを実行することができる。
【0008】
一方、OSGiバンドルB15が備える機能151を、ホスト10の外部から使用するためには、そのための通信インターフェースをOSGiバンドルB15内に設けておく必要がある。例えばHTTP(Hyper Text Transfer Protocol)を用いて機能151をクライアント端末20から使用するためには、WebAPIサーバとしての機能を備えたWebAPIサーバ部152をOSGiバンドルB15内に設ける必要がある。
【0009】
ここでいうWebAPIサーバとは、例えばCGI(Common Gateway Interface)のように、HTTPを用いてネットワーク経由でアプリケーションを実行してその結果を取得するためのインターフェース、およびそのためのWebサーバ機能のことを総称的に指したものである。具体的な実装手段はCGIに限られるものではなく、HTTPを介してリクエストを受け付け、その実行結果をHTTPレスポンスとして返すものであれば、任意の実装手法を用いることができる。
【先行技術文献】
【非特許文献】
【0010】
【非特許文献1】OSGi Service Platform Release 4、URL:http://www.osgi.org/Release4/HomePage(2010年8月9日取得)
【発明の概要】
【発明が解決しようとする課題】
【0011】
OSGiバンドルが備える機能をネットワーク上で公開し、ネットワーク経由で使用できるようにするためには、図1に示したWebAPIサーバ部152のようなサーバ機能および機能を公開するためのインターフェースが必要となる。しかし、機能を公開するOSGiバンドル毎に上述のような機能を実装することは、開発工数などの面から負担が大きい。
【0012】
本発明は、上記のような課題を解決するためになされたものであり、OSGiバンドルが備える機能をWebAPI経由で容易に公開することのできる技術を提供することを目的とする。
【課題を解決するための手段】
【0013】
本発明に係るWebAPIサーバプログラムは、OSGiフレームワーク上に登録されているOSGiバンドルのクラス名とメソッド名をHTTPリクエストとして受け取り、これらに合致するOSGiバンドルを呼び出して実行し、その結果をHTTPレスポンスとして返信する。
【発明の効果】
【0014】
本発明に係るWebAPIサーバプログラムによれば、ネットワーク上で機能を公開したいOSGiバンドル(OSGiサービス)をOSGiフレームワークに登録するのみで、自動的にWebAPI経由でネットワーク上に公開することができる。したがって、個々のOSGiバンドルにはWebAPIサーバ機能を実装する必要がなくなり、開発負担をかけずに、OSGiバンドルをWebサービスとして提供することができる。
【図面の簡単な説明】
【0015】
【図1】OSGiフレームワークの構成を示す図である。
【図2】実施形態1に係るWebシステム100の構成図である。
【図3】WebAPIバンドル17の機能ブロック図を示す。
【図4】OSGiサービスの実体を模式的に示す図である。
【図5】OSGiバンドルB15をサービスレジストリ131に登録し、OSGiサービスとして実行するまでの様子を示す概念図である。
【図6】クラス名とメソッド名を指定して実行結果を返信するよう要求するHTTPリクエストとそのレスポンスの対応関係を示す図である。
【図7】サービスレジストリ131に登録されているOSGiサービスの一覧を返信するよう要求するHTTPリクエストとそのレスポンスを例示する図である。
【図8】WebAPIバンドル17の動作フローである。
【図9】実施形態2において、WebAPIバンドル17がOSGiサービスをWebAPIとして公開する様子を示す図である。
【図10】WebAPIバンドル17を介してOSGiサービスを呼び出す際に指定することのできるHTTPリクエストパラメータとレスポンス例を示す図である。
【図11】レスポンスの記述形式としてXMLを用いる例を示す図である。
【発明を実施するための形態】
【0016】
<実施の形態1>
図2は、本発明の実施形態1に係るWebシステム100の構成図である。Webシステム100は、ホスト10上で動作するアプリケーションを、ネットワークを介してクライアント20から利用する形態のシステムである。クライアント20は、HTTPを用いてホスト10にアクセスし、利用したい機能をリクエストし、その実行結果をHTTPレスポンスとして受信する。
【0017】
ホスト10は、図1で説明したOSGiバンドルA14に代えて、WebAPIバンドル17を備える。その他の構成は、図1と同様である(バンドルBはWebAPIサーバ部を持たない)。なお、以下の説明の便宜上、OSGiバンドルB15が持つJavaオブジェクトである機能BをOSGiフレームワーク13に登録したときの名称を、ServiceB132として表記することにする。
【0018】
ホスト10は、OS11、JavaVM12などを実行するCPU(Central Processing Unit)などの演算装置、これらプログラムおよび各OSGiバンドルを格納するHDD(Hard Disk Drive)などの記憶装置、必要なメモリおよびネットワークインターフェースなどの、ホストコンピュータとして必要な構成を適宜備えるものとする。
【0019】
以下では説明の便宜上、OSGiフレームワーク13や各OSGiバンドルなどのプログラムを動作主体として説明するが、実際にこれらプログラムを実行するのは、ホスト10が備えるCPU、さらにはCPUが実行するJavaVM12であることを付言しておく。
【0020】
WebAPIバンドル17は、OSGiバンドルとして実装されている。WebAPIバンドル17は、サービスレジストリ131に(OSGiサービスを)登録するためのものではなく、クライアント20からリクエストを受け付けてサービスレジストリ131に登録されているサービスを呼び出して実行し、その結果を返信するモジュールである。WebAPIバンドル17は、JavaVM12の配下で動作し、クライアント20からのHTTPリクエストを待ち受けるWebサーバ機能を提供する。WebAPIバンドル17は、本発明における「WebAPIサーバプログラム」に相当する。
【0021】
クライアント20は、HTTPを用いてWebAPIバンドル17が公開するWebAPIにアクセスし、WebAPIバンドル17が提供するサービス(ここではServiceB132)を実行するようリクエストする。WebAPIバンドル17はそのリクエストを処理し、実行結果をHTTPレスポンスとしてクライアント20に返信する。
【0022】
図3は、WebAPIバンドル17の機能ブロック図を示す。WebAPIバンドル17は、HTTPサーバ部171、OSGiサービス実行部172、OSGiサービス一覧取得部173を備える。これら機能部は、WebAPIバンドル17が備えるJavaメソッドとして実装することができる。
【0023】
HTTPサーバ部171は、クライアント20からHTTPリクエストを受け付け、HTTPレスポンスを返信する、Webサーバとしての機能を備える。OSGiサービス実行部172は、サービスレジストリ131に登録されているOSGiサービスを取得し、実行する。OSGiサービス一覧取得部173は、サービスレジストリ131に登録されているOSGiサービスの一覧を取得する。
【0024】
図4は、OSGiサービスの実体を模式的に示す図である。ここでは、OSGiバンドルB15の持つ機能BをOSGiサービスであるServiceB132として登録する場合の例を示した。
【0025】
OSGiサービスの実体は、サービスレジストリ131に登録されたOSGiバンドルを構成する(OSGiバンドルが持つ)Javaクラスのインスタンスである。OSGiサービスをサービスレジストリ131に登録するとは、OSGiバンドルを構成する(OSGiバンドルが持つ)Javaクラスのインスタンスを生成し、その参照をサービスレジストリ131に引き渡すことである。
【0026】
OSGiサービスを利用する側では、サービスレジストリ131が保持しているこのJavaインスタンスを、クラス名をキーとして取得し、そのクラスが有するメソッドを実行することにより、OSGiサービスを利用する。
【0027】
図4に示す例では、OSGiサービスを利用する側のJavaクラス(例えばWebAPIバンドル17)は、クラス名「ServiceB」をキーにしてサービスレジストリ131からServiceB132を取得し、メソッド「func1」「func2」などを実行する。これらのメソッドは、OSGiバンドルB15が提供する機能151に相当する。
【0028】
図5は、OSGiバンドルB15をサービスレジストリ131に登録し、OSGiサービスとして実行するまでの様子を示す概念図である。OSGiサービスとJavaインスタンスの関連イメージを示すため、ごく簡略化したサンプルソースコードを併記した。同ソースコードは説明のためのものであり、必ずしも実際のソースコードを示すものではないことを付言しておく。
【0029】
OSGiサービスの提供元であるOSGiバンドルB15は、ServiceBオブジェクトを生成し、サービスレジストリ131に登録する。サービスレジストリ131は、ServiceBクラスのインスタンスへの参照を保持する。
【0030】
OSGiサービスを利用する側であるWebAPIバンドル17のOSGiサービス実行部172は、利用しようとしているOSGiサービスのバンドルに対応するクラス名「ServiceB」をキーにして、サービスレジストリ131からServiceBオブジェクトへの参照を取得する。OSGiサービス実行部172(実際にはJavaVM12)は、取得したServiceBオブジェクトを、ホスト10が備えるメモリ上に確保する(参照なのでオブジェクト用のメモリは不要。参照を入れる変数用のメモリのみ要)。
【0031】
WebAPIバンドル17のOSGiサービス実行部172は、ServiceBオブジェクトが有するメソッド、例えば「func1」メソッドを実行する。HTTPサーバ部171は、その結果をクライアント20にHTTPレスポンス形式で返信する。
【0032】
図5で説明した例では、OSGiサービスを提供するOSGiバンドルのクラス名およびメソッド名が、WebAPIバンドル17にとって既知であることを前提とした。ただし、一般にはOSGiバンドルのクラス名およびメソッド名は必ずしも既知ではなく、Webシステム100の設計仕様などによって個別に異なる。また、図5のように実装すると、WebAPIバンドル17とOSGiバンドルB15の結びつきが強くなり、OSGiフレームワーク13がPlugin機構を提供することの利点が減じられてしまう。
【0033】
そこで以下では、OSGiサービスを提供するOSGiバンドルのクラス名およびメソッド名をWebAPIバンドル17の外部から与え、任意のクラス名およびメソッド名をサービスレジストリ131から呼び出すことができるように構成することを考える。
【0034】
図6は、クライアント20からWebAPIバンドル17に対して、クラス名とメソッド名を指定して実行結果を返信するよう要求するHTTPリクエストとそのレスポンスの対応関係を示す図である。1行目はServiceB132の「func1」メソッドを呼び出す場合の例、2行目はServiceB132の「func2」メソッドを呼び出す場合の例を示す。
【0035】
クライアント20は、WebAPIバンドル17にHTTPリクエストを発行する際に、リクエストパラメータとして、OSGiサービスを提供するクラス名、そのメソッド名、メソッドの引数を、リクエスト内に含めておく。引数が複数ある場合は、その分だけリクエストパラメータを設ける。
【0036】
WebAPIバンドル17のHTTPサーバ部171は、上記HTTPリクエストを受け取ると、リクエストパラメータ部分を切り出してOSGiサービス実行部172に引き渡す。
【0037】
OSGiサービス実行部172は、リクエストパラメータに記述されているクラス名をキーにして、サービスレジストリ131から同クラス名に該当するOSGiサービスを呼び出す。OSGiサービス実行部172は、リクエストパラメータに記述されているメソッド名に対応するメソッドを実行し、HTTPサーバ部171を介して、その結果をクライアント20に返信する。HTTPレスポンスはテキスト形式であるため、記述形式は任意でよい。図6では、リクエストパラメータと同様の形式を用いた例を示した。メソッドの戻り値が複数ある場合は、その旨をHTTPレスポンス内に併せて記述する。
【0038】
クライアント20が、サービスレジストリ131上に存在しないクラス名またはメソッド名をリクエストパラメータ内で指定した場合、またはクラスとメソッドは存在するが引数の型が合致しない場合、OSGiサービス実行部172およびHTTPサーバ部171は、例外を発行してその旨をクライアント20に返信する。
【0039】
OSGiサービス実行部172が、リクエストパラメータに記述されているクラス名を用いてOSGiサービスのクラスを取得するとき、図5の左上ソースコード例に示すように、サービスレジストリ131は、汎用クラス型であるObject型としてOSGiクラスを引き渡す。これは、任意のクラス型をサービスレジストリ131に登録できるようにするために必要な仕様であると思われる。
【0040】
ただし、Object型は汎用クラス型であるため、ごく基本的なメソッドしか備えておらず、ServiceBクラスが有する「func1」「func2」のようなメソッドは備えていない。そこでWebAPIバンドル17は、文字列変数が保持している文字列を用いて任意のメソッドを起動することのできる、java.lang.reflectパッケージの機能を利用する。
【0041】
同パッケージの機能を用いると、Objectクラス型をServiceBクラス型に変換することなく、Object型のままで任意のメソッドを起動することができる。このことは、任意クラスの任意メソッドを実行することができるメリットの他に、特定クラスへの依存性をなくすことができる点でも有利である。
【0042】
すなわち、通常であれば、WebAPIバンドル17は、ServiceB132のクラス名をクライアント20からリクエストパラメータとして与えられたとき、サービスレジストリ131から取得したObject型をいったんServiceB型に変換した上で、「func1」などのメソッドを実行する。Object型は同メソッドを有さないからである。しかしそのためには、WebAPIバンドル17内でServiceBクラスをあらかじめ取り込んでおかなければならず、その時点でWebAPIバンドル17の汎用性が減じられてしまう。
【0043】
これに対し上記手法によれば、リクエストパラメータで与えられたクラス型に変換する処理は発生しないので、同クラスを取り込む必要はなくなり、クラス型に対する中立性・汎用性を保つことができる。
【0044】
図7は、クライアント20からWebAPIバンドル17に対して、サービスレジストリ131に登録されているOSGiサービスの一覧を返信するよう要求するHTTPリクエストとそのレスポンスを例示する図である。クライアント20は、WebAPIバンドル17にHTTPリクエストを発行する際に、OSGiサービスの一覧を返信するよう要求する旨を、リクエストパラメータとしてリクエスト内に含めておく。図7に示す例ではパラメータ「getservicelist=true」がこれに相当する。
【0045】
WebAPIバンドル17のHTTPサーバ部171は、上記HTTPリクエストを受け取ると、リクエストパラメータ部分を切り出してOSGiサービス実行部172に引き渡す。
【0046】
OSGiサービス一覧取得部173は、サービスレジストリ131に登録されているOSGiサービスのクラス名一覧を取得する。さらに、java.lang.reflectパッケージの機能を利用して、各OSGiサービスのクラスが有するメソッド名、メソッド引数、メソッド戻り型などの情報を取得する。OSGiサービス一覧取得部173は、HTTPサーバ部171を介して、取得結果をクライアント20に返信する。
【0047】
OSGiサービス一覧取得部173の機能は、例えばクライアント20が利用したいサービスに対応するクラス名やメソッド名がサービスレジストリ131内に存在するか否かを確認するためなどに用いられる。
【0048】
図8は、WebAPIバンドル17の動作フローである。以下、図8の各ステップについて説明する。
【0049】
(図8:ステップS801)
WebAPIバンドル17が起動すると、HTTPサーバ部171はクライアント20からのHTTPリクエストを待機する。クライアント20からHTTPリクエストが到着すると、HTTPサーバ部171は、そのリクエストがOSGiサービスの一覧を取得するリクエストであるか、OSGiサービスを呼び出すリクエストであるかを判定する。前者であればステップS802へ進み、後者であればステップS803へ進む。
【0050】
(図8:ステップS802)
OSGiサービス一覧取得部173は、サービスレジストリ131に登録されているOSGiサービスのクラス名、メソッド名、メソッド引数、メソッド戻り型などの一覧を取得する。HTTPサーバ部171は、その取得結果をHTTPレスポンスとしてクライアント20に返信し、本動作フローを終了する。HTTPサーバ部171は、再びHTTPリクエストを待機する。
【0051】
(図8:ステップS803)
OSGiサービス実行部172は、クライアント20からのHTTPリクエストで指定されたクラス名、メソッド名などを用いて、サービスレジストリ131から該当するOSGiサービスを呼び出す。呼び出しに成功した場合はステップS804へ進み、失敗した場合はステップS805へ進む。
【0052】
(図8:ステップS804)
OSGiサービス実行部172は、ステップS803で呼び出したOSGiサービス(呼び出したクラス)のメソッドを実行する。実行に成功した場合はステップS806へ進み、失敗した場合はステップS805へ進む。
【0053】
(図8:ステップS805)
HTTPサーバ部171は、エラーが発生した旨のHTTPレスポンスを、クライアント20に返信する。HTTPサーバ部171は、再びHTTPリクエストを待機する。本ステップにおいて、HTTPレスポンスの内容部分にエラーが発生した旨を記述してもよいし、単純にHTTPが規定するエラーコードを返信してもよい。どのようなエラーが発生したのか明示する観点では、前者のほうが望ましい。
【0054】
(図8:ステップS806)
HTTPサーバ部171は、OSGiサービス実行部172がOSGiサービスを実行した結果をHTTPレスポンス内に記述し、クライアント20に返信する。HTTPサーバ部171は、再びHTTPリクエストを待機する。
【0055】
<実施の形態1:まとめ>
以上のように、本実施形態1に係るWebAPIバンドル17は、実行したいOSGiサービスのクラス名、メソッド名などを指定するHTTPリクエストを受け取り、当該メソッドを実行してその結果をHTTPレスポンスとして返信する。これにより、ネットワーク上で公開したいOSGiバンドルの持つOSGiサービスをサービスレジストリ131に登録しておけば、自動的にWebAPIとしてネットワークに公開することができるので、個別にHTTPサーバ機能などを実装する必要がなくなり、開発負担を低減することができる。
【0056】
また、本実施形態1に係るWebAPIバンドル17は、サービスレジストリ131からOSGiサービスを取得した後、汎用クラス型であるObject型をOSGiバンドルのクラス型に変換することなく、クライアント20が指定したメソッドをそのまま実行する。これにより、WebAPIバンドル17をOSGiバンドルのクラス型から切り離し、クラス間の依存関係をなくして汎用性を高めることができる。すなわち、WebAPIバンドル17は、サービスレジストリ131にどのようなOSGiサービスが登録されていても、そのクラス型をあらかじめ読み込んでおくことなく、指定されたクラスおよびメソッドを呼び出して実行することができる。
【0057】
また、本実施形態1に係るWebAPIバンドル17は、サービスレジストリ131に登録されているクラス名、メソッド名などの一覧をクライアント20に提供することができる。これにより、クライアント20はリクエストを発行する前にエラーが発生する可能性を事前に知ることができるので、メソッドを実行してエラーが返ってくるか否かにより当該メソッドの存否を調べるような非効率な処理をしなくてすむ。
【0058】
<実施の形態2>
実施形態1では、サービスレジストリ131に登録されているOSGiバンドルは無条件にネットワーク上へ公開される。しかし、OSGiフレームワーク13の機能を利用するためサービスレジストリ131に登録されているOSGiバンドルのなかには、ネットワークに公開したくないものも含まれている可能性がある。そこで本発明の実施形態2では、ネットワーク上に公開するOSGiバンドルとそうでないOSGiバンドルを区別するための手法を説明する。その他の構成は実施形態1と同様であるため、以下では差異点を中心に説明する。
【0059】
図9は、本実施形態2において、WebAPIバンドル17がOSGiサービスをWebAPIとして公開する様子を示す図である。本実施形態2では、OSGiバンドルのうちネットワーク上にWebAPIとして公開するものについては、メンバ変数153(フィールド)「openapi」を設けることとする。
【0060】
WebAPIバンドル17は、OSGiサービスを実行するようリクエストを受けたとき、またはサービスレジストリ131に登録されているOSGiサービスの一覧を取得するようリクエストを受けたとき、サービスレジストリ131から取得したOSGiバンドルクラスのメンバ変数「openapi」を取得する。同メンバ変数の値が「true」である場合は、当該クラスが有するメソッドをWebAPIとして公開してよいものと判断する。同メンバ変数の値が「true」でない場合、または同メンバ変数が存在しない場合は、当該クラスが有するメソッドをWebAPIとして公開しない。
【0061】
WebAPIバンドル17は、WebAPIとして公開しないクラスについてサービス実行リクエストを受けた場合は、エラーを返信する。また、WebAPIとして公開しないクラスについては、サービスレジストリ131に登録されているOSGiサービスの一覧をクライアント20に返信するとき、その一覧に当該クラスを記述しないこととする。
【0062】
WebAPIバンドル17がサービスレジストリ131からOSGiバンドルクラス(OSGiサービスクラス)を取得したとき、図5で説明したように、クラス型はObject型となっている。そこでWebAPIバンドル17は、java.lang.reflectパッケージの機能を利用して、メンバ変数「openapi」にアクセスする。この手法によれば、同メンバ変数がprivate指定されている(当該クラスの外部からアクセスすることを禁止する旨の宣言)場合でも、同メンバ変数にアクセスすることができる。
【0063】
なお、メンバ変数「openapi」をprivate宣言する場合、他のOSGiバンドルから同変数を参照することはできないので、他のOSGiバンドルにとっては同変数が存在しないに等しい。すなわち、本実施形態2に固有のメンバ変数を設けているか否かによらず、OSGiフレームワーク13にとっては全てのOSGiバンドルを同等に取り扱うことができるので、本実施形態2固有の格別の配慮を要さない点で便宜である。
【0064】
<実施の形態2:まとめ>
以上のように、本実施形態2に係るWebAPIバンドル17は、サービスレジストリ131に登録されているOSGiバンドルのメンバ変数「openapi」の値をチェックし、当該クラスをWebAPIとして公開してよいか否かを判定する。これにより、ネットワークに公開したいOSGiバンドルのみを選択的に公開することができるので、公開すべきでないOSGiバンドルを不用意にネットワークへ公開する可能性を低減することができる。
【0065】
<実施の形態3>
本発明の実施形態3では、クライアント20とWebAPIバンドル17の間のHTTPリクエストおよびHTTPレスポンスの形式について補足する。Webシステム100の構成は、実施形態1〜2と同様である。
【0066】
図10は、WebAPIバンドル17を介してOSGiサービスを呼び出す際に指定することのできるHTTPリクエストパラメータとレスポンス例を示す図である。
【0067】
HTTPはテキストベースのプロトコルであるため、Javaオブジェクトをそのままリクエストおよびレスポンス内で用いることは難しい。したがって、クライアント20からのリクエスト上およびクライアント20へのレスポンス上で用いることができるのは、テキストベースで表現することのできる、Java基本型およびString(文字列)型に限られる。すなわち、独自のクラス型や、任意のクラス型を含む配列(例えばArrayList)などは用いることができない。
【0068】
また、Dictionary型(内部的に複数の値を格納している、配列に似たクラス型)はレスポンス内で用いることはできるが、リクエストパラメータとして用いることは好ましくない。これは、HTTPリクエストパラメータの記述形式に起因する。
【0069】
HTTPレスポンスは改行コードを含む任意のテキスト形式で記述することができるため、Javaメソッドの実行結果がDictionary型であり、そのなかに複数の値が含まれている場合でも、全ての値をレスポンス内に記述することができる。
【0070】
しかし、HTTPリクエストパラメータは「arg1=1」のように、パラメータ名とその値を1つずつペアにして記述するため、パラメータ値がDictionary型になっていて内部的に複数の値を含む場合、「arg1=(age=30&height=170)」のように多重的に記載せざるを得ず、煩雑になってしまう。また実際上、引数としてDictionary型を用いる必要性はあまりない。そこで図10では、リクエストパラメータとしてDictionary型を用いないこととした。
【0071】
図11は、レスポンスの記述形式としてXML(eXtensible Markup Language)を用いる例を示す図である。レスポンスの内容は、図6と同様である。このようなXML形式のレスポンスを、REST(Representational State Transfer)形式とも呼ぶ。レスポンスをXML形式に変換する処理は、OSGiサービスとの関連が少ない処理であるため、例えばHTTPサーバ部171が実施すればよい。
【0072】
レスポンスのほか、HTTPリクエストもXML形式で記述することもできる。例えばSOAP(Simple Object Access Protocol)形式のXMLメッセージをクライアント20からWebAPIバンドル17に発行し、HTTPサーバ部171がそのメッセージを解析して必要なパラメータのみをOSGiサービス実行部172に引き渡すようにすればよい。
【0073】
<実施の形態4>
以上の実施形態1〜3では、WebAPIバンドル17はHTTPリクエストとしてOSGiサービスのクラス名などを直接受け取ることとしたが、必ずしもクラス名などそのものを記述したリクエストパラメータを用いなくともよい。
【0074】
例えば、WebAPIバンドル17は、クラス名やメソッド名を所定規則で変換した文字列をリクエストパラメータとして受け取り、WebAPIバンドル17の内部、または適当な変換モジュールなどを介して、OSGiサービスのクラス名、メソッド名などに変換してもよい。すなわち、WebAPIバンドル17は、少なくともOSGiサービスのクラス名、メソッド名などを特定することのできるリクエストパラメータを受け取れば足りる。
【符号の説明】
【0075】
10:ホスト、11:OS、12:JavaVM、13:OSGiフレームワーク、131:サービスレジストリ、132:ServiceB、14:OSGiバンドルA、15:OSGiバンドルB、151:機能B、152:WebAPIサーバ部、153:メンバ変数、17:WebAPIバンドル、171:HTTPサーバ部、172:OSGiサービス実行部、173:OSGiサービス一覧取得部、20:クライアント、100:Webシステム。
【特許請求の範囲】
【請求項1】
OSGiフレームワーク仕様に対応したOSGiバンドルをWebAPI経由で公開する処理をコンピュータに実行させるプログラムであって、前記コンピュータに、
前記OSGiフレームワーク上でOSGiバンドルまたはOSGiサービスとして登録されているクラスのクラス名と当該クラスが有するメソッド名を特定することができるパラメータを含むHTTPリクエストを受け付ける受信ステップと、
前記OSGiフレームワーク上でOSGiバンドルまたはOSGiサービスとして登録されているクラスのうち前記クラス名に合致するものを、前記OSGiフレームワークが公開しているインターフェースを介して呼び出すサービス呼出ステップと、
前記サービス呼出ステップで呼び出したクラスが有するメソッドのうち前記メソッド名に合致するものを実行するサービス実行ステップと、
前記サービス実行ステップの結果を、前記HTTPリクエストの送信元にHTTPレスポンスの形式で返信する返信ステップと、
を実行させることを特徴とするWebAPIサーバプログラム。
【請求項2】
前記サービス呼出ステップでは、前記コンピュータに、
前記OSGiフレームワーク上でOSGiバンドル(OSGiサービス)として登録されているクラスのうち前記クラス名に合致するものを、汎用クラス型として呼び出させ、
前記サービス実行ステップでは、前記コンピュータに、
前記サービス呼出ステップで呼び出したクラスが有するメソッドのうち前記メソッド名に合致するものを、前記汎用クラス型から前記クラス名に対応するクラス型に変換する処理を介さずに実行させる
ことを特徴とする請求項1記載のWebAPIサーバプログラム。
【請求項3】
前記OSGiバンドルは、
当該OSGiバンドルを構成しているクラスが有するメソッドをWebAPI経由で公開してよいか否かを示すメンバ変数を有しており、
前記WebAPIサーバプログラムは、前記コンピュータに、
前記サービス呼出ステップで呼び出したクラスが有する前記メンバ変数の値をチェックすることにより、当該クラスが有するメソッドをWebAPI経由で公開してよいか否かを判定する公開判定ステップを実行させ、
前記公開判定ステップにおいてWebAPI経由で公開してよいと判定したクラスが有するメソッドについてのみ前記サービス実行ステップおよび前記返信ステップを実行させる
ことを特徴とする請求項1または2記載のWebAPIサーバプログラム。
【請求項4】
前記コンピュータに、
前記OSGiフレームワーク上でOSGiバンドルまたはOSGiサービスとして登録されているクラスのクラス名、当該クラスが有するメソッド名、当該メソッドの引数、および当該メソッドの戻り型の一覧を取得するサービス一覧取得ステップと、
前記サービス一覧取得ステップの結果を、前記HTTPリクエストの送信元にHTTPレスポンスの形式で返信するステップと、
を実行させることを特徴とする請求項1から3のいずれか1項記載のWebAPIサーバプログラム。
【請求項5】
前記WebAPIサーバプログラムは、OSGiフレームワーク仕様に対応したOSGiバンドルとして実装されている
ことを特徴とする請求項1から4のいずれか1項記載のWebAPIサーバプログラム。
【請求項6】
前記受信ステップおよび前記返信ステップにおいて、前記コンピュータに、
SOAP形式またはREST形式の通信データを用いて、前記HTTPリクエストの送信元との間で通信させる
ことを特徴とする請求項1から5のいずれか1項記載のWebAPIサーバプログラム。
【請求項7】
OSGiフレームワーク仕様に対応したOSGiバンドルの提供するOSGiサービスをWebAPI経由で公開する方法であって、
前記OSGiフレームワーク上でOSGiバンドルまたはOSGiサービスとして登録されているクラスのクラス名と当該クラスが有するメソッド名を特定することができるパラメータを含むHTTPリクエストを受け付けるステップと、
前記OSGiフレームワーク上でOSGiバンドルとして登録されているクラスのうち前記クラス名に合致するものを、前記OSGiフレームワークが公開しているインターフェースを介して呼び出すサービス呼出ステップと、
前記サービス呼出ステップで呼び出したクラスが有するメソッドのうち前記メソッド名に合致するものを実行するサービス実行ステップと、
前記サービス実行ステップの結果を、前記HTTPリクエストの送信元にHTTPレスポンスの形式で返信するステップと、
を有することを特徴とするWebAPI公開方法。
【請求項1】
OSGiフレームワーク仕様に対応したOSGiバンドルをWebAPI経由で公開する処理をコンピュータに実行させるプログラムであって、前記コンピュータに、
前記OSGiフレームワーク上でOSGiバンドルまたはOSGiサービスとして登録されているクラスのクラス名と当該クラスが有するメソッド名を特定することができるパラメータを含むHTTPリクエストを受け付ける受信ステップと、
前記OSGiフレームワーク上でOSGiバンドルまたはOSGiサービスとして登録されているクラスのうち前記クラス名に合致するものを、前記OSGiフレームワークが公開しているインターフェースを介して呼び出すサービス呼出ステップと、
前記サービス呼出ステップで呼び出したクラスが有するメソッドのうち前記メソッド名に合致するものを実行するサービス実行ステップと、
前記サービス実行ステップの結果を、前記HTTPリクエストの送信元にHTTPレスポンスの形式で返信する返信ステップと、
を実行させることを特徴とするWebAPIサーバプログラム。
【請求項2】
前記サービス呼出ステップでは、前記コンピュータに、
前記OSGiフレームワーク上でOSGiバンドル(OSGiサービス)として登録されているクラスのうち前記クラス名に合致するものを、汎用クラス型として呼び出させ、
前記サービス実行ステップでは、前記コンピュータに、
前記サービス呼出ステップで呼び出したクラスが有するメソッドのうち前記メソッド名に合致するものを、前記汎用クラス型から前記クラス名に対応するクラス型に変換する処理を介さずに実行させる
ことを特徴とする請求項1記載のWebAPIサーバプログラム。
【請求項3】
前記OSGiバンドルは、
当該OSGiバンドルを構成しているクラスが有するメソッドをWebAPI経由で公開してよいか否かを示すメンバ変数を有しており、
前記WebAPIサーバプログラムは、前記コンピュータに、
前記サービス呼出ステップで呼び出したクラスが有する前記メンバ変数の値をチェックすることにより、当該クラスが有するメソッドをWebAPI経由で公開してよいか否かを判定する公開判定ステップを実行させ、
前記公開判定ステップにおいてWebAPI経由で公開してよいと判定したクラスが有するメソッドについてのみ前記サービス実行ステップおよび前記返信ステップを実行させる
ことを特徴とする請求項1または2記載のWebAPIサーバプログラム。
【請求項4】
前記コンピュータに、
前記OSGiフレームワーク上でOSGiバンドルまたはOSGiサービスとして登録されているクラスのクラス名、当該クラスが有するメソッド名、当該メソッドの引数、および当該メソッドの戻り型の一覧を取得するサービス一覧取得ステップと、
前記サービス一覧取得ステップの結果を、前記HTTPリクエストの送信元にHTTPレスポンスの形式で返信するステップと、
を実行させることを特徴とする請求項1から3のいずれか1項記載のWebAPIサーバプログラム。
【請求項5】
前記WebAPIサーバプログラムは、OSGiフレームワーク仕様に対応したOSGiバンドルとして実装されている
ことを特徴とする請求項1から4のいずれか1項記載のWebAPIサーバプログラム。
【請求項6】
前記受信ステップおよび前記返信ステップにおいて、前記コンピュータに、
SOAP形式またはREST形式の通信データを用いて、前記HTTPリクエストの送信元との間で通信させる
ことを特徴とする請求項1から5のいずれか1項記載のWebAPIサーバプログラム。
【請求項7】
OSGiフレームワーク仕様に対応したOSGiバンドルの提供するOSGiサービスをWebAPI経由で公開する方法であって、
前記OSGiフレームワーク上でOSGiバンドルまたはOSGiサービスとして登録されているクラスのクラス名と当該クラスが有するメソッド名を特定することができるパラメータを含むHTTPリクエストを受け付けるステップと、
前記OSGiフレームワーク上でOSGiバンドルとして登録されているクラスのうち前記クラス名に合致するものを、前記OSGiフレームワークが公開しているインターフェースを介して呼び出すサービス呼出ステップと、
前記サービス呼出ステップで呼び出したクラスが有するメソッドのうち前記メソッド名に合致するものを実行するサービス実行ステップと、
前記サービス実行ステップの結果を、前記HTTPリクエストの送信元にHTTPレスポンスの形式で返信するステップと、
を有することを特徴とするWebAPI公開方法。
【図1】
【図2】
【図3】
【図4】
【図5】
【図6】
【図7】
【図8】
【図9】
【図10】
【図11】
【図2】
【図3】
【図4】
【図5】
【図6】
【図7】
【図8】
【図9】
【図10】
【図11】
【公開番号】特開2012−48391(P2012−48391A)
【公開日】平成24年3月8日(2012.3.8)
【国際特許分類】
【出願番号】特願2010−188642(P2010−188642)
【出願日】平成22年8月25日(2010.8.25)
【出願人】(000233055)株式会社日立ソリューションズ (1,610)
【Fターム(参考)】
【公開日】平成24年3月8日(2012.3.8)
【国際特許分類】
【出願日】平成22年8月25日(2010.8.25)
【出願人】(000233055)株式会社日立ソリューションズ (1,610)
【Fターム(参考)】
[ Back to top ]