カテゴリー「Ruby」の3件の記事

2007年9月18日 (火)

RailgoをRubyで使う(パート2)

あー・・・疲れた。

RubyでRailgoのつづきです。

先ほどのエントリで、駅名を検索して取ってくるとこまでできたんですが、
その後、経路検索でどうしてもうまく行かない。

以下のようなプログラムで
SearchCourseメソッドを呼んで経路検索をしようとしたところ、
どうしても変なエラーが出る。 


数時間悩んで(つかれて半分寝てましたが・・)
SOAP4rのバージョンあげて1.5.7というやつを入れてみたところ、
動くようになりますたヨ・・;;


Railgo.rb

require 'soap/wsdlDriver' 
require './RailgoAuthHandler'

module Mashup
WSDL_URL = 'http://wstest.railgo.jp/ExpService06.asmx?wsdl'
class Railgo
@@wsdlFactory = SOAP::WSDLDriverFactory.new(WSDL_URL)
@@driver = @@wsdlFactory.create_rpc_driver
@@driver.generate_explicit_type = true
#For auth
handler = Mashup::RailgoAuthHandler.new
@@driver.headerhandler.add(handler)

#----------------------------------------
# 駅名文字列に対応するStationオブジェクトを返します
#----------------------------------------
def Railgo.getStation(name)
begin
#response =driver.GetDefaultNavigation({})
request = {'StationYomi'=> name,
'AreaType' => "Japan",
'StationType' =>"RailRoad",
'Date'=>'20070913'}
response = @@driver.SearchStation(request)
rescue SOAP::FaultError => err
print err
raise
end
ret = response['SearchStationResult']['Station']
ret = (ret.is_a?(Array))?ret[0]:ret
#ret['Latitude']['bearing']
end

#----------------------------------------------
# 駅名文字列配列に対応するStationオブジェクト配列を返します
#----------------------------------------------
def Railgo.getStations(aryNames)
ret = []
aryNames.each {|station|
ret<< Railgo.getStation(station)
}
ret
end


#-------------------------------------------
# 経路検索
# Station配列を与えると対応するCourse配列を返します。
#-------------------------------------------
def Railgo.getCourses(stations)
begin
resNavi = @@driver.GetDefaultNavigation({})
navi = resNavi['GetDefaultNavigationResult']
request = {'Stations' => stations, 'SearchOption' => navi }
response = @@driver.SearchCourse(request)
rescue SOAP::FaultError => err
print err
raise
end
ret = response['SearchCourseResult']['Course']
#ret = navi
#ret = response
(ret.is_a?(Array))?ret[0]:ret
end
end

end

SearchCourse.cgi

#!/usr/local/bin/ruby -Ku
require 'cgi'
require 'soap/wsdlDriver'
require 'Railgo'

cgi = CGI.new
print cgi.header({"charset" => "utf-8"})

sName = cgi["name"]
stationsStr = ["武蔵小金井", "新宿", "東戸塚"]


stations = Mashup::Railgo.getStations(stationsStr)
response = Mashup::Railgo.getCourses(stations)

# test output
puts "Response:" + response.inspect


エラーでてるまわりのソースみてたらさー、
#ToDo: Test とかあやしいことかいてあるからさー・・
ちっとはあやしいとはおもったんだけどさー・・

まさかバージョンあげたらなおっちゃうとは思いませんでしたよ・・

古いバージョンのlib/soap/mapping/wsdlliteralregistry.rb, line 119

     
119: def complexobj2soap(obj, type, qualified)
120: o = SOAPElement.new(type.name)
121: o.qualified = qualified
122: type.each_element do |child_ele|
123: child = Mapping.get_attribute(obj, child_ele.name.name)
124: if child.nil?
125: if child_ele.nillable
126: # ToDo: test
127: # add empty element
128: child_soap = obj2elesoap(nil, child_ele)
129: o.add(child_soap)
130: elsif Integer(child_ele.minoccurs) == 0
131: # nothing to do
132: else
133: raise MappingError.new("nil not allowed: #{child_ele.name.name}")
134: end
135: elsif child_ele.map_as_array?
136: child.each do |item|
137: child_soap = obj2elesoap(item, child_ele)
138: o.add(child_soap)
139: end
140: else
141: child_soap = obj2elesoap(child, child_ele)
142: o.add(child_soap)
143: end
144: end
145: o
146: end

いやー・・ Ruby 熱いぜ^^
 (まだ業務じゃ使えないっていうのは、こういうところなんだろうねぇ・・残念;)

でも、おかげさまで、TCPモニターなるものを使って調査したり、
回り道でいろいろスキルがつきましたです。

Ruby でproxyサーバ経由のSOAP/HTTP

あ、そうそう、先ほどのSOAPなRailgoをRubyで使うですが、会社で作業しているので、Proxyサーバ経由でアクセスせねばなりませんでした。
ここも、ソースやらその中の正規表現やら追いながらやっとこさ動いた部分なので、メモを残しておきましょう。
 (Ruby初心者なので、なおつら)

SOAP4rではHTTPのPROXYをかます方法がいろいろ用意されていますが(環境変数を使う方法等)、
CGIで使う場合はsoap/propertyというファイルを使う方法がよいかなと自分は思いました。

ライブラリパスが通っているところに
soap/というディレクトリをつくり、その中に
propertyという名前で以下のようなファイルをくと
そのプロキシ経由のアクセスとなるようです。


soap/property

[client.protocol.http]
proxy: http://proxy.example.com:8080


プロパティファイル使う手段用意してくれるのはいいけど、
その書式に関するドキュメントが皆無で、サンプルも、
ソース上のコメントもない・・

(ドキュメントが整備されている世界の住人である)Java屋としては、
なかなか新鮮(かつ死にそう)な経験でした。
「ソース読め」ってのがRuby文化なんですかねぇ・・
結構敷居高いなぁ・・

(「Ruby=プログラミングが楽しい」というコンセプトからすると、
  こういうライブラリをバンドルするのは、いかがなものか、
   ドキュメントが整備されるまでは
   外様扱いにしたほうがよいのでは?と思ったです)

まあいいや、
こっからが、本番です^^

SOAPなRailgoをRubyで使う

遅ればせながらマッシュアップなんてものをやってみることになって、いろいろやってます。
まずは電車の経路検索なんかを使ってみようと思い、Railgoというやつを使ってみようと
思いました。

RailgoはSOAPのAPIです。
SOAPやらWSDLやらを扱うプログラムを書いたことがないJavaプログラマで
ちょっとRubyやってみたいなと思っていた自分としては、なんとなく
Rubyでやってみようと決めました。

(Rubyの本にはSOAPのAPIがデフォルトでついてるって書いてあって、
 かつ、どこかにAxis2は依存ライブラリが鬼のようにあってうざいと書いて
 あったからともいう。)


んで、はじめてみると、
実際RubyにはSOAP4rというライブラリがバンドルされていました。
が、ふたを開けてみると、ドキュメントがさっぱりなくて、正直、辟易しました。

 #Google先生がSOAP4r hell なんていうタイトルの英語の記事を教えてくれて、
 #そこにドキュメントもサンプルもなんにもねぇぇ・・死にそうだぁ・・ってかいてあり、
 #ライブラリ作者はいろいろ開発ML等で「ドキュメントは、かかないよー」
 #なんてかいてあり・・
 #
 #途方にくれて、Rubyやめようかともおもったよ・・まったく


自分もドキュメント書くのぜんぜんだめな人なのですが、
すばらしい反面教師に出会ってドキュメント書く能力
(やる気ともいう)があがった気がするので、まあよしとしよう。

本題は、ライブラリのソースみたり、Google先生に聞いたり、
試行錯誤の繰り返しで、とりあえず以下が動いたという報告であります。

 #ソースを追ってたら、Rubyスキルもちょっと上がったかも^^

RubyもSOAPも 初心者なので、変な記述があるかもですが、
現時点で日本語・英語含めて、SOAP4rに関する
情報がほとんどないので・・まあ、こんなんでも
だれかの役にたつかもということで、ポストしときますー


認証用ハンドラ(RailgoAuthHandler.rb)

require 'soap/header/simplehandler' 
require 'xsd/qname'

module Mashup
class RailgoAuthHandler < SOAP::Header::SimpleHandler
def initialize
nsUri = 'http://expart.est.co.jp/ExpService'
name = 'Authentication'
super(XSD::QName.new(nsUri, name).freeze)
end

def on_simple_outbound
{ 'User'=> 'mctuser3', 'Password' =>'symfyws6'}
end
end
end


CGIプログラム(test.cgi)

#!/usr/local/bin/ruby -Ku
require 'cgi'
require 'soap/wsdlDriver'
require './RailgoAuthHandler'

cgi = CGI.new

WSDL_URL = 'http://wstest.railgo.jp/ExpService06.asmx?wsdl'
wsdlFactory = SOAP::WSDLDriverFactory.new(WSDL_URL)
driver = wsdlFactory.create_rpc_driver
driver.generate_explicit_type = true

#For auth
handler = Mashup::RailgoAuthHandler.new
driver.headerhandler.add(handler)


#Call
begin
#response =driver.GetDefaultNavigation({})
request = {'StationYomi'=>"新宿",
'AreaType' => "Japan",
'StationType' =>"RailRoad",
'Date'=>'20070117'}
response =driver.SearchStation(request)
rescue SOAP::FaultError => err
print err
raise
end

# output
print cgi.header({"charset" => "utf-8"})
puts "Response:" + response.inspect

Haruya's Violin

2023年2月
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28        

最近のトラックバック

無料ブログはココログ