jeremydurham-serviceproxy 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +23 -41
- data/Rakefile +6 -5
- data/bin/wsdl2proxy +41 -0
- data/lib/service_proxy/base.rb +154 -0
- data/spec/service_helper.rb +20 -3
- data/spec/service_proxy_spec.rb +24 -4
- metadata +4 -4
- data/lib/service_proxy.rb +0 -111
data/README
CHANGED
@@ -2,44 +2,26 @@ ServiceProxy
|
|
2
2
|
|
3
3
|
ServiceProxy is a lightweight SOAP library for Ruby.
|
4
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
|
-
soap_envelope(options) do |xml|
|
29
|
-
# your XML here
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def parse_cool1(response)
|
34
|
-
# The response parameter is a simple Net::HTTP response
|
35
|
-
# here, we use Hpricot to parse it, but you could use
|
36
|
-
# Nokogiri, REXML, etc
|
37
|
-
xml = Hpricot.XML(response.body)
|
38
|
-
xml.at("cool1Result").inner_text
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
Next, you can attempt to call the service:
|
43
|
-
|
44
|
-
service = SuperCoolService.new(url_to_wsdl)
|
45
|
-
service.cool1
|
5
|
+
HOW IT WORKS
|
6
|
+
|
7
|
+
Loading the library:
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'service_proxy/base'
|
11
|
+
|
12
|
+
GENERATING A PROXY
|
13
|
+
|
14
|
+
ServiceProxy comes with a simple generator to get started. It can be invoked
|
15
|
+
as follows:
|
16
|
+
|
17
|
+
wsdl2proxy [wsdl]
|
18
|
+
|
19
|
+
This will generate a file named default.rb, in the current directory. The class
|
20
|
+
will be named GeneratedService, and will define build and parse methods for all
|
21
|
+
of the available service methods.
|
22
|
+
|
23
|
+
Please refer to the specs for extended usage examples.
|
24
|
+
|
25
|
+
CONTRIBUTORS
|
26
|
+
|
27
|
+
Rich Cavanaugh
|
data/Rakefile
CHANGED
@@ -3,7 +3,7 @@ require 'rake/gempackagetask'
|
|
3
3
|
require 'rubygems/specification'
|
4
4
|
require 'rake/rdoctask'
|
5
5
|
require 'spec/rake/spectask'
|
6
|
-
require File.join(File.dirname(__FILE__), 'lib', 'service_proxy')
|
6
|
+
require File.join(File.dirname(__FILE__), 'lib', 'service_proxy', 'base')
|
7
7
|
|
8
8
|
NAME = "serviceproxy"
|
9
9
|
AUTHOR = "Jeremy Durham"
|
@@ -18,7 +18,7 @@ PROJECT_SUMMARY = SUMMARY
|
|
18
18
|
PROJECT_DESCRIPTION = SUMMARY
|
19
19
|
|
20
20
|
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
21
|
-
GEM_VERSION = ServiceProxy::VERSION + PKG_BUILD
|
21
|
+
GEM_VERSION = ServiceProxy::Base::VERSION + PKG_BUILD
|
22
22
|
RELEASE_NAME = "REL #{GEM_VERSION}"
|
23
23
|
#
|
24
24
|
# ==== Gemspec and installation
|
@@ -26,7 +26,7 @@ RELEASE_NAME = "REL #{GEM_VERSION}"
|
|
26
26
|
|
27
27
|
spec = Gem::Specification.new do |s|
|
28
28
|
s.name = NAME
|
29
|
-
s.version = ServiceProxy::VERSION
|
29
|
+
s.version = ServiceProxy::Base::VERSION
|
30
30
|
s.platform = Gem::Platform::RUBY
|
31
31
|
s.has_rdoc = true
|
32
32
|
s.extra_rdoc_files = ["README", "LICENSE"]
|
@@ -36,6 +36,7 @@ spec = Gem::Specification.new do |s|
|
|
36
36
|
s.email = EMAIL
|
37
37
|
s.homepage = HOMEPAGE
|
38
38
|
s.require_path = 'lib'
|
39
|
+
s.executables = ['wsdl2proxy']
|
39
40
|
s.files = %w(LICENSE README Rakefile) + Dir.glob("{lib,spec}/**/*")
|
40
41
|
|
41
42
|
s.add_dependency "nokogiri"
|
@@ -48,7 +49,7 @@ end
|
|
48
49
|
|
49
50
|
desc "install the gem locally"
|
50
51
|
task :install => [:clean, :package] do
|
51
|
-
sh %{sudo gem install pkg/#{NAME}-#{ServiceProxy::VERSION} --no-update-sources}
|
52
|
+
sh %{sudo gem install pkg/#{NAME}-#{ServiceProxy::Base::VERSION} --no-update-sources}
|
52
53
|
end
|
53
54
|
|
54
55
|
desc "create a gemspec file"
|
@@ -91,4 +92,4 @@ namespace :spec do
|
|
91
92
|
end
|
92
93
|
|
93
94
|
desc 'Default: run unit tests.'
|
94
|
-
task :default => 'spec'
|
95
|
+
task :default => 'spec'
|
data/bin/wsdl2proxy
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'service_proxy/base'
|
5
|
+
|
6
|
+
def underscore(camel_cased_word)
|
7
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
8
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
9
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
10
|
+
tr("-", "_").
|
11
|
+
downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
unless ARGV.size > 0
|
15
|
+
puts "Usage: #{$0} [endpoint]"
|
16
|
+
exit!
|
17
|
+
end
|
18
|
+
|
19
|
+
template_filename = File.dirname(__FILE__) + '/../lib/templates/proxy.rbt'
|
20
|
+
proxy = ServiceProxy::Base.new(ARGV[0])
|
21
|
+
output_filename = 'default.rb'
|
22
|
+
output_klass_name = 'GeneratedService'
|
23
|
+
output = ''
|
24
|
+
proxy.service_methods.each do |service_method|
|
25
|
+
output << <<-EOS
|
26
|
+
|
27
|
+
def build_#{underscore(service_method)}(options)
|
28
|
+
soap_envelope(options) do |xml|
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_#{underscore(service_method)}(response)
|
33
|
+
Hpricot.XML(response.body)
|
34
|
+
end
|
35
|
+
EOS
|
36
|
+
end
|
37
|
+
template = File.read(template_filename)
|
38
|
+
template.gsub!(/%name%/, output_klass_name)
|
39
|
+
template.gsub!(/%body%/, output)
|
40
|
+
File.open(output_filename, 'w') { |f| f.puts template }
|
41
|
+
puts "Generated proxy #{output_filename} - You can use the proxy by executing #{output_klass_name}.new('#{ARGV[0]}')"
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'net/http'
|
4
|
+
require 'net/https'
|
5
|
+
require 'builder'
|
6
|
+
require 'uri'
|
7
|
+
|
8
|
+
module ServiceProxy
|
9
|
+
class Base
|
10
|
+
VERSION = '0.1.0'
|
11
|
+
|
12
|
+
attr_accessor :endpoint, :service_methods, :soap_actions, :service_uri, :http, :service_http, :uri, :debug, :wsdl, :target_namespace, :service_ports
|
13
|
+
|
14
|
+
def initialize(endpoint)
|
15
|
+
self.endpoint = endpoint
|
16
|
+
self.setup
|
17
|
+
end
|
18
|
+
|
19
|
+
def call_service(options)
|
20
|
+
method = options[:method]
|
21
|
+
headers = { 'content-type' => 'text/xml; charset=utf-8', 'SOAPAction' => self.soap_actions[method] }
|
22
|
+
body = build_request(method, options)
|
23
|
+
response = self.service_http.request_post(self.service_uri.path, body, headers)
|
24
|
+
parse_response(method, response)
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def setup
|
30
|
+
self.soap_actions = {}
|
31
|
+
self.service_methods = []
|
32
|
+
setup_uri
|
33
|
+
self.http = setup_http(self.uri)
|
34
|
+
get_wsdl
|
35
|
+
parse_wsdl
|
36
|
+
setup_namespace
|
37
|
+
end
|
38
|
+
|
39
|
+
def service_uri
|
40
|
+
@service_uri ||= if self.respond_to?(:service_port)
|
41
|
+
self.service_port
|
42
|
+
else
|
43
|
+
self.uri
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def service_http
|
48
|
+
@service_http ||= unless self.service_uri == self.uri
|
49
|
+
local_http = self.setup_http(self.service_uri)
|
50
|
+
setup_https(local_http) if self.service_uri.scheme == 'https'
|
51
|
+
local_http
|
52
|
+
else
|
53
|
+
self.http
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def setup_http(local_uri)
|
58
|
+
raise ArgumentError, "Endpoint URI must be valid" unless local_uri.scheme
|
59
|
+
local_http = Net::HTTP.new(local_uri.host, local_uri.port)
|
60
|
+
setup_https(local_http) if local_uri.scheme == 'https'
|
61
|
+
local_http.set_debug_output(STDOUT) if self.debug
|
62
|
+
local_http.read_timeout = 5
|
63
|
+
local_http
|
64
|
+
end
|
65
|
+
|
66
|
+
def setup_https(local_http)
|
67
|
+
local_http.use_ssl = true
|
68
|
+
local_http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def setup_uri
|
74
|
+
self.uri = URI.parse(self.endpoint)
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_wsdl
|
78
|
+
response = self.http.get("#{self.uri.path}?#{self.uri.query}")
|
79
|
+
self.wsdl = Nokogiri.XML(response.body)
|
80
|
+
end
|
81
|
+
|
82
|
+
def parse_wsdl
|
83
|
+
method_list = []
|
84
|
+
self.wsdl.xpath('//*[name()="soap:operation"]').each do |operation|
|
85
|
+
operation_name = operation.parent.get_attribute('name')
|
86
|
+
method_list << operation_name
|
87
|
+
self.soap_actions[operation_name] = operation.get_attribute('soapAction')
|
88
|
+
end
|
89
|
+
raise RuntimeError, "Could not parse WSDL" if method_list.empty?
|
90
|
+
self.service_methods = method_list.sort
|
91
|
+
|
92
|
+
port_list = {}
|
93
|
+
self.wsdl.xpath('//wsdl:port', {"xmlns:wsdl" => 'http://schemas.xmlsoap.org/wsdl/'}).each do |port|
|
94
|
+
name = underscore(port['name'])
|
95
|
+
location = port.xpath('./*[@location]').first['location']
|
96
|
+
port_list[name] = location
|
97
|
+
end
|
98
|
+
self.service_ports = port_list
|
99
|
+
end
|
100
|
+
|
101
|
+
def setup_namespace
|
102
|
+
self.target_namespace = self.wsdl.namespaces['xmlns:tns']
|
103
|
+
end
|
104
|
+
|
105
|
+
def build_request(method, options)
|
106
|
+
builder = underscore("build_#{method}")
|
107
|
+
self.respond_to?(builder) ? self.send(builder, options).target! :
|
108
|
+
soap_envelope(options).target!
|
109
|
+
end
|
110
|
+
|
111
|
+
def parse_response(method, response)
|
112
|
+
parser = underscore("parse_#{method}")
|
113
|
+
self.respond_to?(parser) ? self.send(parser, response) :
|
114
|
+
raise(NoMethodError, "You must define the parse method: #{parser}")
|
115
|
+
end
|
116
|
+
|
117
|
+
def soap_envelope(options, &block)
|
118
|
+
xsd = 'http://www.w3.org/2001/XMLSchema'
|
119
|
+
env = 'http://schemas.xmlsoap.org/soap/envelope/'
|
120
|
+
xsi = 'http://www.w3.org/2001/XMLSchema-instance'
|
121
|
+
xml = Builder::XmlMarkup.new
|
122
|
+
xml.env(:Envelope, 'xmlns:xsd' => xsd, 'xmlns:env' => env, 'xmlns:xsi' => xsi) do
|
123
|
+
xml.env(:Body) do
|
124
|
+
xml.__send__(options[:method].to_sym, "xmlns" => self.target_namespace) do
|
125
|
+
yield xml if block_given?
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
xml
|
130
|
+
end
|
131
|
+
|
132
|
+
def method_missing(method, *args)
|
133
|
+
method_name = method.to_s
|
134
|
+
case method_name
|
135
|
+
when /_uri$/
|
136
|
+
sp_name = method_name.gsub(/_uri$/, '')
|
137
|
+
super unless self.service_ports.has_key?(sp_name)
|
138
|
+
URI.parse(self.service_ports[sp_name])
|
139
|
+
else
|
140
|
+
options = args.pop || {}
|
141
|
+
super unless self.service_methods.include?(method_name)
|
142
|
+
call_service(options.update(:method => method_name))
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def underscore(camel_cased_word)
|
147
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
148
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
149
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
150
|
+
tr("-", "_").
|
151
|
+
downcase
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
data/spec/service_helper.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'hpricot'
|
2
2
|
|
3
3
|
# Service Endpoints
|
4
|
-
class InstantMessageService < ServiceProxy
|
4
|
+
class InstantMessageService < ServiceProxy::Base
|
5
5
|
|
6
6
|
def parse_get_version(response)
|
7
7
|
xml = Hpricot.XML(response.body)
|
@@ -20,7 +20,7 @@ class InstantMessageService < ServiceProxy
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
class ISBNService < ServiceProxy
|
23
|
+
class ISBNService < ServiceProxy::Base
|
24
24
|
|
25
25
|
def build_is_valid_isbn13(options)
|
26
26
|
soap_envelope(options) do |xml|
|
@@ -32,9 +32,15 @@ class ISBNService < ServiceProxy
|
|
32
32
|
xml = Hpricot.XML(response.body)
|
33
33
|
xml.at("m:IsValidISBN13Result").inner_text == 'true' ? true : false
|
34
34
|
end
|
35
|
+
|
36
|
+
def service_port
|
37
|
+
local_uri = URI.parse(self.isbn_service_soap_uri.to_s)
|
38
|
+
local_uri.path << "?dummy=1"
|
39
|
+
local_uri
|
40
|
+
end
|
35
41
|
end
|
36
42
|
|
37
|
-
class SHAGeneratorService < ServiceProxy
|
43
|
+
class SHAGeneratorService < ServiceProxy::Base
|
38
44
|
|
39
45
|
def build_gen_ssha(options)
|
40
46
|
soap_envelope(options) do |xml|
|
@@ -47,4 +53,15 @@ class SHAGeneratorService < ServiceProxy
|
|
47
53
|
xml = Hpricot.XML(response.body)
|
48
54
|
xml.at("return").inner_text
|
49
55
|
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class InvalidSHAGeneratorService < ServiceProxy::Base
|
59
|
+
|
60
|
+
def build_gen_ssha(options)
|
61
|
+
soap_envelope(options) do |xml|
|
62
|
+
xml.text(options[:text])
|
63
|
+
xml.hashtype(options[:hash_type])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
50
67
|
end
|
data/spec/service_proxy_spec.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'spec'
|
3
|
-
require File.dirname(__FILE__) + '/../lib/service_proxy
|
4
|
-
require File.dirname(__FILE__) + '/service_helper
|
3
|
+
require File.dirname(__FILE__) + '/../lib/service_proxy/base'
|
4
|
+
require File.dirname(__FILE__) + '/service_helper'
|
5
5
|
|
6
6
|
describe ServiceProxy do
|
7
7
|
it "should raise on an invalid URI" do
|
8
|
-
lambda { ServiceProxy.new('bacon') }.should raise_error(ArgumentError)
|
8
|
+
lambda { ServiceProxy::Base.new('bacon') }.should raise_error(ArgumentError)
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should raise on invalid WSDL" do
|
12
|
-
lambda { ServiceProxy.new('http://www.
|
12
|
+
lambda { ServiceProxy::Base.new('http://www.yahoo.com') }.should raise_error(RuntimeError)
|
13
13
|
end
|
14
14
|
|
15
15
|
describe "connecting to an Instant Message Service" do
|
@@ -62,4 +62,24 @@ describe ServiceProxy do
|
|
62
62
|
result.should =~ /^[{SSHA512}]/
|
63
63
|
end
|
64
64
|
end
|
65
|
+
|
66
|
+
describe "making a service call without a parse method" do
|
67
|
+
before do
|
68
|
+
@proxy = InvalidSHAGeneratorService.new('https://sec.neurofuzz-software.com/paos/genSSHA-SOAP.php?wsdl')
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should raise a no method error" do
|
72
|
+
lambda { result = @proxy.genSSHA(:text => 'hello world', :hash_type => 'sha512') }.should raise_error(NoMethodError)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "using the #service_port hook" do
|
77
|
+
before do
|
78
|
+
@proxy = ISBNService.new('http://webservices.daehosting.com/services/isbnservice.wso?WSDL')
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should have the dummy query argument" do
|
82
|
+
@proxy.send(:service_uri).path.should match(/\?dummy=1/)
|
83
|
+
end
|
84
|
+
end
|
65
85
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jeremydurham-serviceproxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Durham
|
@@ -32,8 +32,8 @@ dependencies:
|
|
32
32
|
version:
|
33
33
|
description: Lightweight SOAP library for Ruby
|
34
34
|
email: jeremydurham@gmail.com
|
35
|
-
executables:
|
36
|
-
|
35
|
+
executables:
|
36
|
+
- wsdl2proxy
|
37
37
|
extensions: []
|
38
38
|
|
39
39
|
extra_rdoc_files:
|
@@ -43,7 +43,7 @@ files:
|
|
43
43
|
- LICENSE
|
44
44
|
- README
|
45
45
|
- Rakefile
|
46
|
-
- lib/service_proxy.rb
|
46
|
+
- lib/service_proxy/base.rb
|
47
47
|
- spec/service_helper.rb
|
48
48
|
- spec/service_proxy_spec.rb
|
49
49
|
has_rdoc: true
|
data/lib/service_proxy.rb
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'nokogiri'
|
3
|
-
require 'net/http'
|
4
|
-
require 'net/https'
|
5
|
-
require 'builder'
|
6
|
-
require 'uri'
|
7
|
-
|
8
|
-
class ServiceProxy
|
9
|
-
VERSION = '0.0.1'
|
10
|
-
|
11
|
-
attr_accessor :endpoint, :service_methods, :soap_actions, :service_uri, :http, :uri, :debug, :wsdl, :target_namespace
|
12
|
-
|
13
|
-
def initialize(endpoint)
|
14
|
-
self.endpoint = endpoint
|
15
|
-
self.setup
|
16
|
-
end
|
17
|
-
|
18
|
-
def call_service(options)
|
19
|
-
method = options[:method]
|
20
|
-
headers = { 'content-type' => 'text/xml; charset=utf-8', 'SOAPAction' => self.soap_actions[method] }
|
21
|
-
body = build_request(method, options)
|
22
|
-
response = self.http.request_post(self.uri.path, body, headers)
|
23
|
-
parse_response(method, response)
|
24
|
-
end
|
25
|
-
|
26
|
-
protected
|
27
|
-
|
28
|
-
def setup
|
29
|
-
self.soap_actions = {}
|
30
|
-
self.service_methods = []
|
31
|
-
setup_http
|
32
|
-
get_wsdl
|
33
|
-
parse_wsdl
|
34
|
-
setup_namespace
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def setup_http
|
40
|
-
self.uri = URI.parse(self.endpoint)
|
41
|
-
raise ArgumentError, "Endpoint URI must be valid" unless self.uri.scheme
|
42
|
-
self.http = Net::HTTP.new(self.uri.host, self.uri.port)
|
43
|
-
setup_https if self.uri.scheme == 'https'
|
44
|
-
self.http.set_debug_output(STDOUT) if self.debug
|
45
|
-
end
|
46
|
-
|
47
|
-
def setup_https
|
48
|
-
self.http.use_ssl = true
|
49
|
-
self.http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
50
|
-
end
|
51
|
-
|
52
|
-
def get_wsdl
|
53
|
-
response = self.http.get("#{self.uri.path}?#{self.uri.query}")
|
54
|
-
self.wsdl = Nokogiri.XML(response.body)
|
55
|
-
end
|
56
|
-
|
57
|
-
def parse_wsdl
|
58
|
-
method_list = []
|
59
|
-
self.wsdl.xpath('//*[name()="soap:operation"]').each do |operation|
|
60
|
-
operation_name = operation.parent.get_attribute('name')
|
61
|
-
method_list << operation_name
|
62
|
-
self.soap_actions[operation_name] = operation.get_attribute('soapAction')
|
63
|
-
end
|
64
|
-
raise RuntimeError, "Could not parse WSDL" if method_list.empty?
|
65
|
-
self.service_methods = method_list.sort
|
66
|
-
end
|
67
|
-
|
68
|
-
def setup_namespace
|
69
|
-
self.target_namespace = self.wsdl.namespaces['xmlns:tns']
|
70
|
-
end
|
71
|
-
|
72
|
-
def build_request(method, options)
|
73
|
-
builder = underscore("build_#{method}")
|
74
|
-
self.respond_to?(builder) ? self.send(builder, options).target! : soap_envelope(options).target!
|
75
|
-
end
|
76
|
-
|
77
|
-
def parse_response(method, response)
|
78
|
-
parser = underscore("parse_#{method}")
|
79
|
-
self.respond_to?(parser) ? self.send(parser, response) :
|
80
|
-
raise(NoMethodError, "You must define the parse method: #{parser}")
|
81
|
-
end
|
82
|
-
|
83
|
-
def soap_envelope(options, &block)
|
84
|
-
xsd = 'http://www.w3.org/2001/XMLSchema'
|
85
|
-
env = 'http://schemas.xmlsoap.org/soap/envelope/'
|
86
|
-
xsi = 'http://www.w3.org/2001/XMLSchema-instance'
|
87
|
-
xml = Builder::XmlMarkup.new
|
88
|
-
xml.env(:Envelope, 'xmlns:xsd' => xsd, 'xmlns:env' => env, 'xmlns:xsi' => xsi) do
|
89
|
-
xml.env(:Body) do
|
90
|
-
xml.__send__(options[:method].to_sym, "xmlns" => self.target_namespace) do
|
91
|
-
yield xml if block_given?
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
xml
|
96
|
-
end
|
97
|
-
|
98
|
-
def method_missing(method, *args)
|
99
|
-
options = args.pop || {}
|
100
|
-
super unless self.service_methods.include?(method.to_s)
|
101
|
-
call_service(options.update(:method => method.to_s))
|
102
|
-
end
|
103
|
-
|
104
|
-
def underscore(camel_cased_word)
|
105
|
-
camel_cased_word.to_s.gsub(/::/, '/').
|
106
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
107
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
108
|
-
tr("-", "_").
|
109
|
-
downcase
|
110
|
-
end
|
111
|
-
end
|