Python Web サービス開発者: 第 4 回: Web サービス ソフトウェア・リポジトリー 第 3 回

Web サービスとして実装するソフトウェア・リポジトリーの作成についての第 3 回目で最終回となる今回の記事では、Mike Olson 氏と Uche Ogbuji 氏が、ソフトウェア・リポジトリーを拡張し、WSDL を使ってその存在をブロードキャストできるようにします。

Mike OlsonFourthought, Inc.

Mike Olson 氏は、企業向けの知識管理アプリケーションのための XML ソリューションを専門とするソフトウェア・ベンダーおよびコンサルタント会社である、Fourthought Inc. のコンサルタントであり、共同設立者です。Fourthoughtは、XML ミドルウェア用のオープン・ソース・プラットフォームである 4Suite を開発しています。



Uche Ogbuji, Consultant, Fourthought, Inc.

Uche photoUche Ogbuji 氏は、Fourthought, Inc. のコンサルタント兼共同設立者です。この会社は、企業のナレッジ・マネジメントのための XML ソリューションを専門とするソフトウェア・ベンダー兼コンサルタント会社です。Fourthought では、XML、RDF、およびナレッジ・マネジメント・アプリケーション用のオープン・ソース・プラットフォームである 4Suite を開発しています。Ogbuji 氏は、ナイジェリア出身のコンピューター・エンジニア兼ライターで、現在は、米国コロラド州ボールダーに住み、そこで働いています。



2001年 6月

リポジトリーの作成についてのこのシリーズの第 2 回は、HTTP Post メソッドと SOAP を使ってリポジトリーにソフトウェアをアップロードする方法を紹介するところで終わりました。ソフトウェア・リポジトリーの作成についての 3 回シリーズのこの第 3 回では、ソフトウェア・リポジトリーを拡張し、WSDL を使ってその存在をブロードキャストする方法を示し、最後にすべての要素をまとめたサンプル・プログラムを紹介します。

はじめに

始める前に、プロトコルと、ソフトウェアの最新の変更内容について少し知っておく必要があります。まず、WSDL (Web Services Description Language) の働きを理解しておきましょう(WSDL の働きを説明した記事については、参考文献を参照してください)。

この第 3 回で紹介する例を実行するには、Python 1.5.2 以上 (Python 2.1 をお勧めします)、4Suite バージョン 0.11.1 以上、4Suite Server バージョン 0.11.1 以上、および WSDL ライブラリーが必要です。前提条件である上記ソフトウェアのダウンロードとインストールについては、参考文献を参照してください。

4Suite Server 0.11.1 の新機能は、4Suite Server のインストールを製品の setup.py ファイルから直接ブートストラップできる、Python の distutils パッケージに対する拡張機能セットです。本稿からダウンロードできる setup.py ファイルには、この実行方法を示す例が含まれています。最終的に、サンプル・アプリケーションをインストールしてブートストラップする場合に必要なのは、setup.py. を実行することだけです。


WSDL の使用

WSDL は、Web サービスの技術的な特性を記述する場合に使う XML 書式です。WSDL を UDDI (Universal Description, Discovery, and Integration) と一緒に使用することで、Web サービスはその存在と機能を披露することができます。これらのテクノロジーを利用すれば、アプリケーションは UDDI リポジトリーに照会し、必要な Web サービスについての情報を探し出して、その Web サービスに要求することができます。

UDDI の説明を始めるとそれだけで 1 つのシリーズになってしまいますので(ただし、本稿から目を離さないでください)、ここでは WSDL の面だけに焦点を当てます。ソフトウェア・リポジトリーに WSDL を追加するには、簡単な文書定義を作成し、それを使って、WSDL 文書の存在に関する簡単なステートメントを作成します。リスト 1 に、WSDL 文書定義を示します。

リスト 1: WSDL 文書定義
<DocDef xmlns='http://namespaces.4suite.org/4ss' name='WSDL'>
  <RdfMapping>
    <Subject>$uri</Subject>
    <Predicate>'http://schema.4suite.org#wsdl'</Predicate>
    <Object>/wsdl:definitions/@name</Object>
  </RdfMapping>
  <NsMapping>
    <Prefix>wsdl</Prefix>
    <Uri>http://schemas.xmlsoap.org/wsdl/</Uri>
  </NsMapping>
</DocDef>

この文書定義は、リポジトリーに WSDL 文書が追加されるたびに、RDF (Resource Description Framework) モデルにステートメントを追加します。WSDL POST ハンドラーは、このステートメントを使って、システム内にあるすべての WSDL 文書を追跡します。


WSDL ハンドラー

前回 (参考文献参照) では、4Suite Server POST ハンドラーを使って新しいコンテンツをシステムに追加する方法を中心に説明しました。この知識をベースに、WSDL の記述を追加、編集、削除できる WSDL 登録ページのセットを作成します。

コードをインストールすると、4Suite Server HTTP サーバーが立ち上がるので、サンプル・アプリケーションを一緒に使用できるようになります。4Suite Server 構成ファイルに、リスト 2 に示す RDF の記述があることを確認する必要があります。

リスト 2: SOAP ハンドラーの RDF の記述
<rdf:Description ID='SoftRepoSoapHandler'>
  <rdf:type resource='http://xmlns.4Suite.org/4ss/properties#HttpHandler'/>    
  <Priority>30</Priority>
  <Module>WebServices4.SoftRepoSoapHandler</Module>
</rdf:Description>  
<rdf:Description ID='SoftRepoWsdlHandler'>
  <rdf:type resource='http://xmlns.4Suite.org/4ss/properties#HttpHandler'/>    
  <Module>WebServices4.WsdlHandler</Module>
</rdf:Description>  
<rdf:Description ID='SoftRepoGetHandler'>
  <rdf:type resource='http://xmlns.4Suite.org/4ss/properties#HttpHandler'/>
  <Module>FtServer.Protocols.Http.GetHandler</Module>
  <DocumentRoot>/WebServices-4</DocumentRoot>
</rdf:Description>
<rdf:Description ID='SoftRepoPostHandler'>
  <rdf:type resource='http://xmlns.4Suite.org/4ss/properties#HttpHandler'/>
  <Module>FtServer.Protocols.Http.PostHandler</Module>
  <DocumentRoot>/WebServices-4</DocumentRoot>
</rdf:Description>
<rdf:Description ID='SoftRepoDeleteHandler'>
  <rdf:type resource='http://xmlns.4Suite.org/4ss/properties#HttpHandler'/>
  <Module>FtServer.Protocols.Http.DeleteHandler</Module>
  <DocumentRoot>/WebServices-4</DocumentRoot>
</rdf:Description>
<rdf:Description ID='PythonSoftRepoServer'>
  <rdf:type resource='http://xmlns.4Suite.org/4ss/properties#PythonServer'/>
  <StartMode>MANUAL</StartMode>
  <Port>8080</Port>
  <PidFile>/tmp/PyHttp.pid</PidFile>
  <ErrorLog>/tmp/PyHttp.all</ErrorLog>
  <TransferLog>/tmp/PyHttp.all</TransferLog>
  <Handler resource='#SoftRepoGetHandler'/>
  <Handler resource='#SoftRepoWsdlHandler'/>
  <Handler resource='#SoftRepoPostHandler'/>
  <Handler resource='#SoftRepoDeleteHandler'/>
  <Handler resource='#SoftRepoSoapHandler'/></rdf:Description>

次に、以下のコマンド行を入力してサーバーを立ち上げます。

[molson@penny molson]$ 4ss_manager start PythonSoftRepoServer
PythonSoftRepoServer started (pid 6045)

4Suite Server を構成して実行すると、ブラウザーで http://localhost:8080/index.html にアクセスして、WSDL マネージャーの索引ページを表示することができます。索引ページ (図 1) から、既存の WSDL の記述を表示したり、新しい WSDL の記述をシステムに追加することができます。

図 1: WSDL マネージャーの索引ページ
図 1: WSDL マネージャーの索引ページ

最初はシステム内に WSDL の記述は入っていないので、追加します。Add New WSDL Description リンクをクリックします。新しい WSDL 記述の入力を求める新しいページが表示されます。リスト 3 (このリストも、サンプル・ファイル data/softrepo.wsdl 内にあります) に、ソフトウェア・リポジトリーの WSDL の記述例を示します。

リスト 3: 新しい WSDL 文書定義
<?xml version="1.0"?>
<definitions name="Software Repository"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:tns="http://4Suite.org/webservices-4.wsdl"
             xmlns="http://schemas.xmlsoap.org/wsdl/">
  
  <message name="AddSoftwareInput">
    <part name="title"/>
    <part name="creator"/>
    <part name="home"/>
    <part name="version"/>
    <part name="description"/>
  </message>
  <portType name="AddSoftwarePortType">
    <operation name="AddSoftware">
      <input message="tns:AddSoftwareInput"/>
    </operation>
  </portType>
                          
  <binding name="SoftwareRepoBinding"
           type="tns:AddSoftwarePortType">
    <soap:binding style="document"
                  transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="Add">
      <soap:operation soapAction="http://localhost/Add"/> 
      <input>
        <soap:body use="literal" 
                   namespace="http://spam.com/softrepo"/>
      </input>             
    </operation>
  </binding>
  <service name="SoftwareRepoService">
    <documentation>Example Software Repository Service</documentation>
    <port name="SoftwareRepoPort" binding="tns:SoftwareRepoBinding"> 
      <soap:address location="http://localhost/Add"/>
    </port>
  </service>
                         
</definitions>
リスト 4: add.xslt ファイル
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0"
>
  <xsl:output method='text'/>
  <xsl:param name='wsdl'/>
  <xsl:template match='/'>
    <xsl:value-of select='$wsdl'/>
  </xsl:template>
</xsl:stylesheet>

システムに新しい WSDL を追加するには、サンプルの記述をテキスト入力ボックスにコピーします。ファイル add.docadd.xslt にメッセージを追加し、システム内に WSDL を生成します。入力したとおりの WSDL を追加したいので、XSLT は単に XSLT 変数 wsdl の値を出力にコピーするだけです。正しく書式設定されるように (そして、文字エンティティーがエスケープされないように)、output method は text に設定しなければならなかったことに注意しましょう。リスト 4 は、add.xslt の内容です。

WSDL を追加すると、図 2 のようなビュー画面が表示されます。これは、索引ページで「View WSDL Definitions」をクリックしたときに表示される画面と同じです。この画面で、WSDL 定義を編集したり、リポジトリーから WSDL 定義を削除したりできます(編集機能と削除機能は比較的簡単なので、ここでは説明しません)。

図 2: WSDL マネージャーのビュー・ページ
図 2: WSDL マネージャーのビュー・ページ

一つにまとめる

これで、小さいソフトウェア・リポジトリーが出来上がり、SOAP を使ってそのリポジトリーに接続する方法を学習し、WSDL を使って記述を設定、取得できるようになりました。次に、こうした記述をすべて使ってシステムにソフトウェアを追加する小さいプログラムを作成します。作成するプログラムは、前回作成したアプリケーションを拡張したものですが、今回は、リポジトリーに照会して、利用可能なソフトウェア・リポジトリー・サービスを探します。照会の結果から、アプリケーションは必要な情報を入力するようユーザーに求め、システムに新しいソフトウェア項目を追加します。

Web サービスの世界では、UDDI レジストリーは、Web サービスの WSDL を格納する場所です。残念ながら、適切な UDDI 例を作成し、説明するコラムを書くとなると 1 年かかってしまうので、ここでは独自の方法を使って、リポジトリー内の Web サービスを探します。

Web サービスを見つける適切な方法は、利用可能な Web サービスを照会できる新しいメッセージを受け取るように SOAP ハンドラーを拡張することです。ただし、4Suite Server で SOAP ハンドラーを作成する方法はすでに紹介したので、この例では、HTTP 1.1 要求で許されるメソッドを拡張して、"WSDL" の要求タイプを取り込むことにします。この要求では、調べる Web サービスの名前である name のヘッダー・フィールドが必要です。リスト 5 に、カスタムの 4Suite Server WSDL ハンドラーのコードを示します。

ハンドラーについて注意すべきことは 3 つあります。1 つは、ハンドラーは CommonHandler から継承したものであるということです。これは基本クラスで、このクラスを使えばハンドラー・クラスを簡単に作成できます。このクラスには、_safeHandleRequest_createErrorResponse (どちらもハンドラーで使用します) のような数多くの共通機能が追加されています。_safeHandleRequest は、tryexcept ブロックの内側の 2 つ目の引き数である関数を呼び出します。"URI unknown" や "access denied" などの数多くの標準例外をキャッチし、それらを適切な HTTP 応答 (この場合は、それぞれ 404 と 403) に変換します。

リスト 5: カスタムの WSDL ハンドラー
from FtServer.Protocols.Http import CommonHandler
from FtServer import Core
class WsdlHandler(CommonHandler.CommonHandler):
    def handle(self, request):
        return self._safeHandleRequest(self._handle, request)
    def _handle(self,request):
        #See if the required name header is present
        if not request.headers.has_key('name'): return None
        name = request.headers['name']
        repo = Core.GetRepository()
        try:
            model = repo.getModel()
            #Get all of the statements from the model that define WSDL
            #documents with the requested name
            stmts = model.complete(None,"http://schema.4suite.org#wsdl",name)
            if not stmts:
                return self._createErrorResponse(request, 404, uri=name)
            #Fetch the document
            uri = stmts[0].subject
            body = repo.fetchDocument(uri).getContent()
        finally:
            repo.txRollback()
        headers = {'Content-type' : 'text/xml; charset=iso-8859-1',
                   'Content-length' : len(body),
                   }
        return CommonHandler.Response(200, headers, body)
        
def Register(properties):
    #Register are new handler to accept "WSDL" requests
    handler = WsdlHandler()
    return [(handler.handle, 'WSDL')]

2 つ目に注意することは、ファイルの一番下にある Register 関数です。サーバーは、起動時にこの Register 関数を呼び出します。Register は、構成ファイルからプロパティーのディクショナリーを取得して、タプルのリストを戻します。各タプルの最初の項目は、呼び出し可能オブジェクト (この場合は、メソッド・ポインター)で、2 つ目の項目は、そのメソッドを呼び出す必要がある HTTP 要求タイプです。この場合は、すべての WSDL 要求タイプで呼び出す必要があります。

最後に注意することは、_handle 関数の先頭で、ヘッダーに name キーがあるかどうかを確認することです。このキーがないと、None が戻されます。None を戻すことで、要求を処理しようとしなかったことをサーバーに伝えます。次に、サーバーは、WSDL 要求メソッドを受信待機している登録済みのハンドラーが他にないかどうか探します。ある場合は、そのハンドラーを呼び出します。要求を処理するハンドラーがない場合は、501 エラーが戻されます。

POST 要求に対して定義されているハンドラーは 3 つあることに注意してください。SoapHandlerPostHandlerDeleteHandler です。次に、これらの 3 つのハンドラーすべてがどのようにして共存しているかというメカニズムを説明します。まず、SoapHandler がメッセージを見ます。SOAPAction ヘッダーがないと、None を戻します。次に、PostHandler が要求を見ます。template-xslt 照会引き数がないと、None を戻します。最後に、DeleteHandler が要求を見ます。delete 照会引き数がないと、None を戻します。結果的にチェーン内のこれらのハンドラーのいずれかが要求を処理するので、エラーは発生しないというしくみになっています。

サンプル・ハンドラーをテストするため、サンプル・アプリケーションの作成を始めます。アプリケーションでは、リポジトリーに接続し、Software Repository に関する WSDL 記述を取得し、WSDL で定義されているインターフェースを満足させるパラメーター・セットをユーザーに問い合わせ、最後に新しいソフトウェアを追加する要求を作成します。

最初のステップについては、リスト 6 を参照してください。ここでは、Python の標準 httplib を使用してサーバーに接続し、タイプが WSDL の HTTP 要求を作成して、応答を取得します。

ソフトウェア・リポジトリーの WSDL ができたので、それを構文解析し、実行できることを確認する必要があります。このためには、Python wsdllib.py モジュールを使用します。ダウンロード方法とインストール方法については、参考文献を参照してください。リスト 7 に、サーバーから WSDL を構文解析するサンプル・スクリプトの一部を示します。

リスト 7: WSDL 応答を構文解析する example1.py
    #now that we have gotten the WSDL, parse it in
    wsdl = wsdllib.ReadFromString(reply_body)

WSDL を構文解析したら、関数 CreateSOAPMessage を呼び出します。この関数は、WSDL を使用して、SOAP メッセージに対する必須入力をユーザーに求め、応答の本文を作成します。コードにこのような簡単な記述とコメントを挿入することで、関数で何が発生しているかを把握できるようになります。

前回と同じように、SOAP 要求をサーバーに送り、構文解析して、応答を表示します。リスト 8 に、サンプル・プログラム全体を示し、リスト 9 に、完全なプログラムの実行例を示します。

リスト 9: example1.py、サンプルの実行
[molson@penny code]$ python src/example1.py 
Please enter a selection for 'Service'
  0.  SoftwareRepoService
Selection: 0
Please enter a selection for 'Service Port'
  0.  SoftwareRepoPort
Selection: 0
Please enter a selection for 'Operation'
  0.  AddSoftware
Selection: 0
Please enter value for 'title': New Software
Please enter value for 'description': This is a new software
Please enter value for 'version': 0.001
Please enter value for 'home': http://new-software.com
Please enter value for 'creator': Mike.Olson@fourthought.com
New Document (uri = /softrepo/incoming/New Software-0.001.xml)
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:dc="http://purl.org/dc/elements/1.1 
xmlns="http://namespaces.4suite.org/www/software-map"
 >
   <Software rdf:ID="New Software">
     <dc:Title>New Software</dc:Title>
     <dc:Creator>Mike.Olson@fourthought.com</dc:Creator>
     <Home rdf:resource="http://new-software.com"/>
     <CurrentVersion>0.001</CurrentVersion>
     <dc:Description>This is a new software</dc:Description>
   </Software>
 </rdf:RDF>
[molson@penny code]$

ソフトウェア・リポジトリーのまとめ

4Suite Server を使って Web サービスを実装する方法を紹介しました。第 1 回では、HTTP を使ってリポジトリーからソフトウェア・パッケージを表示、取得する、ソフトウェア・リポジトリーを構築しました。第 2 回では、第 1 回の例を拡張し、HTTP POST を使って、ソフトウェア・リポジトリーに新しいエントリーを作成しました。また、SOAP を使ってリポジトリーにパッケージを追加する方法も示しました。今回は、ソフトウェア・リポジトリー・サービスを定義する WSDL 文書を作成し、リポジトリーに接続して、WSDL を使って SOAP メッセージを作成して新しいパッケージをリポジトリーに追加しました。

次回は、Python で SOAP メッセージを処理する場合のそのほかのオプションを紹介します。

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=SOA and web services
ArticleID=241877
ArticleTitle=Python Web サービス開発者: 第 4 回: Web サービス ソフトウェア・リポジトリー 第 3 回
publish-date=062001