SOAPとはどういったものかを把握するために、Rubyで構築してみる。
そのために、SOAP用のRubyライブラリであるSOAP4Rを利用する。
Ruby1.9.3で試すため、soap4r-ruby1.9を利用する。
SOAPの処理等はWSDLをはじめ、基本的にRubyでSOAPをすべて利用させてもらいました。

soap4r-ruby1.9

gemをインストール

$ gem install soap4r-ruby1.9

サーバファイルをgenerate

$ wsdl2ruby.rb --wsdl calc.wsdl --type server --force
/Users/matsuda/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': iconv will be deprecated in the future, use String#encode instead.
F, [2013-06-25T15:54:54.594981 #10314] FATAL -- app: Detected an exception. Stopping ... undefined method `split' for nil:NilClass (NoMethodError)
/Users/matsuda/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/soap4r-ruby1.9-2.0.5/lib/wsdl/soap/wsdl2ruby.rb:61:in `create_file'
/Users/matsuda/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/soap4r-ruby1.9-2.0.5/lib/wsdl/soap/wsdl2ruby.rb:42:in `run'
/Users/matsuda/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/soap4r-ruby1.9-2.0.5/bin/wsdl2ruby.rb:46:in `run'
/Users/matsuda/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/logger.rb:741:in `start'
/Users/matsuda/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/soap4r-ruby1.9-2.0.5/bin/wsdl2ruby.rb:137:in `<top (required)>'
/Users/matsuda/.rbenv/versions/1.9.3-p392/bin/wsdl2ruby.rb:23:in `load'
/Users/matsuda/.rbenv/versions/1.9.3-p392/bin/wsdl2ruby.rb:23:in `<main>'
I, [2013-06-25T15:54:54.595080 #10314]  INFO -- app: End of app. (status: -1)

エラーになったので、ライブラリを修正

diff -U0 wsdl/soap/wsdl2ruby.rb.backup wsdl/soap/wsdl2ruby.rb
--- wsdl/soap/wsdl2ruby.rb.backup       2013-06-25 16:01:06.000000000 +0900
+++ wsdl/soap/wsdl2ruby.rb      2013-06-25 16:19:15.000000000 +0900
@@ -61 +61 @@
-    @modulepath = @opt['module_path'].split("::")
+    @modulepath = @opt['module_path'].nil? ? [] : @opt['module_path'].split("::")

再実行

$ wsdl2ruby.rb --wsdl calc.wsdl --type server --force
/Users/matsuda/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': iconv will be deprecated in the future, use String#encode instead.
I, [2013-06-25T16:02:38.087601 #10582]  INFO -- app: Creating class definition.
I, [2013-06-25T16:02:38.087720 #10582]  INFO -- app: Creates file 'CalcService.rb'.
I, [2013-06-25T16:02:38.088057 #10582]  INFO -- app: Creating mapping registry definition.
I, [2013-06-25T16:02:38.088114 #10582]  INFO -- app: Creates file 'CalcServiceMappingRegistry.rb'.
I, [2013-06-25T16:02:38.088722 #10582]  INFO -- app: Creating servant skelton.
I, [2013-06-25T16:02:38.088779 #10582]  INFO -- app: Creates file 'CalcServiceServant.rb'.
I, [2013-06-25T16:02:38.090514 #10582]  INFO -- app: Creating standalone stub.
I, [2013-06-25T16:02:38.090587 #10582]  INFO -- app: Creates file 'CalcServer.rb'.
- Standalone stub can have only 1 port for now.  So creating stub for the first port and rests are ignored.
- Standalone server stub ignores port location defined in WSDL.  Location is http://localhost:10080/ by default.  Generated client from WSDL must be configured to point this endpoint manually.
I, [2013-06-25T16:02:38.096587 #10582]  INFO -- app: End of app. (status: 0)

以下のファイルが生成される

  • CalcService.rb
  • CalcServiceMappingRegistry.rb
  • CalcServiceServant.rb
  • CalcServer.rb

クライアントファイルをgenerate

$ wsdl2ruby.rb --wsdl calc.wsdl --type client --force
/Users/matsuda/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': iconv will be deprecated in the future, use String#encode instead.
I, [2013-06-25T16:19:22.779241 #10924]  INFO -- app: Creating class definition. 
W, [2013-06-25T16:19:22.779349 #10924]  WARN -- app: File 'CalcService.rb' exists but overrides it.
I, [2013-06-25T16:19:22.779635 #10924]  INFO -- app: Creating mapping registry definition.
W, [2013-06-25T16:19:22.779691 #10924]  WARN -- app: File 'CalcServiceMappingRegistry.rb' exists but overrides it.
I, [2013-06-25T16:19:22.780385 #10924]  INFO -- app: Creating driver.
W, [2013-06-25T16:19:22.780452 #10924]  WARN -- app: Creates file 'CalcServiceDriver.rb'.
I, [2013-06-25T16:19:22.786531 #10924]  INFO -- app: Creating client skelton.   
I, [2013-06-25T16:19:22.786624 #10924]  INFO -- app: Creates file 'CalcServerClient.rb'.
I, [2013-06-25T16:19:22.787490 #10924]  INFO -- app: End of app. (status: 0)

以下のファイルが生成される

  • CalcServiceDriver.rb
  • CalcServerClient.rb

debugログ出力の設定

  • サーバ側

      class CalcPortTypeApp < ::SOAP::RPC::StandaloneServer
        def initialize(*arg)
          super(*arg)
          servant = CalcPortType.new
          CalcPortType::Methods.each do |definitions|
            opt = definitions.last
            if opt[:request_style] == :document
              @router.add_document_operation(servant, *definitions)
            else
              @router.add_rpc_operation(servant, *definitions)
            end
          end
          self.mapping_registry = CalcServiceMappingRegistry::EncodedRegistry
          self.literal_mapping_registry = CalcServiceMappingRegistry::LiteralRegistry
          # ログレベルの設定
          @log.level = Logger::Severity::DEBUG
        end
      end
    
  • クライアント側

      # CalcServiceDriver.rb
      def initialize(endpoint_url = nil)
        endpoint_url ||= DefaultEndpointUrl
        super(endpoint_url, nil)
        self.mapping_registry = ::CalcServiceMappingRegistry::EncodedRegistry
        self.literal_mapping_registry = ::CalcServiceMappingRegistry::LiteralRegistry
        # ログ出力先の設定
        self.wiredump_dev = STDOUT
        # ログ出力先の設定(logsディレクトリを予め作成しておくこと)
        # self.wiredump_file_base = "logs/"
        init_methods
      end
    

実行

  • サーバ側

      $ ruby -I. CalcServer.rb
    
  • クライアント側

      $ ruby -I. CalcServerClient.rb
    

参考サイト