savon_with_adapter 2.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.travis.yml +11 -0
- data/.yardopts +6 -0
- data/CHANGELOG.md +1042 -0
- data/CONTRIBUTING.md +46 -0
- data/Gemfile +18 -0
- data/LICENSE +20 -0
- data/README.md +81 -0
- data/Rakefile +14 -0
- data/donate.png +0 -0
- data/lib/savon.rb +27 -0
- data/lib/savon/block_interface.rb +26 -0
- data/lib/savon/builder.rb +166 -0
- data/lib/savon/client.rb +89 -0
- data/lib/savon/core_ext/string.rb +29 -0
- data/lib/savon/header.rb +70 -0
- data/lib/savon/http_error.rb +27 -0
- data/lib/savon/log_message.rb +48 -0
- data/lib/savon/message.rb +35 -0
- data/lib/savon/mock.rb +5 -0
- data/lib/savon/mock/expectation.rb +71 -0
- data/lib/savon/mock/spec_helper.rb +62 -0
- data/lib/savon/model.rb +80 -0
- data/lib/savon/operation.rb +127 -0
- data/lib/savon/options.rb +336 -0
- data/lib/savon/qualified_message.rb +49 -0
- data/lib/savon/request.rb +89 -0
- data/lib/savon/request_logger.rb +48 -0
- data/lib/savon/response.rb +112 -0
- data/lib/savon/soap_fault.rb +48 -0
- data/lib/savon/version.rb +3 -0
- data/savon.gemspec +52 -0
- data/spec/fixtures/gzip/message.gz +0 -0
- data/spec/fixtures/response/another_soap_fault.xml +14 -0
- data/spec/fixtures/response/authentication.xml +14 -0
- data/spec/fixtures/response/header.xml +13 -0
- data/spec/fixtures/response/list.xml +18 -0
- data/spec/fixtures/response/multi_ref.xml +39 -0
- data/spec/fixtures/response/soap_fault.xml +8 -0
- data/spec/fixtures/response/soap_fault12.xml +18 -0
- data/spec/fixtures/response/taxcloud.xml +1 -0
- data/spec/fixtures/ssl/client_cert.pem +16 -0
- data/spec/fixtures/ssl/client_encrypted_key.pem +30 -0
- data/spec/fixtures/ssl/client_encrypted_key_cert.pem +24 -0
- data/spec/fixtures/ssl/client_key.pem +15 -0
- data/spec/fixtures/wsdl/authentication.xml +63 -0
- data/spec/fixtures/wsdl/betfair.xml +2981 -0
- data/spec/fixtures/wsdl/edialog.xml +15416 -0
- data/spec/fixtures/wsdl/interhome.xml +2137 -0
- data/spec/fixtures/wsdl/lower_camel.xml +52 -0
- data/spec/fixtures/wsdl/multiple_namespaces.xml +92 -0
- data/spec/fixtures/wsdl/multiple_types.xml +60 -0
- data/spec/fixtures/wsdl/taxcloud.xml +934 -0
- data/spec/fixtures/wsdl/team_software.xml +1 -0
- data/spec/fixtures/wsdl/vies.xml +176 -0
- data/spec/fixtures/wsdl/wasmuth.xml +153 -0
- data/spec/integration/centra_spec.rb +72 -0
- data/spec/integration/email_example_spec.rb +32 -0
- data/spec/integration/random_quote_spec.rb +23 -0
- data/spec/integration/ratp_example_spec.rb +28 -0
- data/spec/integration/stockquote_example_spec.rb +28 -0
- data/spec/integration/support/application.rb +82 -0
- data/spec/integration/support/server.rb +84 -0
- data/spec/integration/temperature_example_spec.rb +46 -0
- data/spec/integration/zipcode_example_spec.rb +42 -0
- data/spec/savon/builder_spec.rb +86 -0
- data/spec/savon/client_spec.rb +198 -0
- data/spec/savon/core_ext/string_spec.rb +37 -0
- data/spec/savon/features/message_tag_spec.rb +61 -0
- data/spec/savon/http_error_spec.rb +49 -0
- data/spec/savon/log_message_spec.rb +33 -0
- data/spec/savon/message_spec.rb +40 -0
- data/spec/savon/mock_spec.rb +157 -0
- data/spec/savon/model_spec.rb +154 -0
- data/spec/savon/observers_spec.rb +92 -0
- data/spec/savon/operation_spec.rb +211 -0
- data/spec/savon/options_spec.rb +772 -0
- data/spec/savon/request_spec.rb +493 -0
- data/spec/savon/response_spec.rb +258 -0
- data/spec/savon/soap_fault_spec.rb +126 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/support/endpoint.rb +25 -0
- data/spec/support/fixture.rb +39 -0
- data/spec/support/integration.rb +9 -0
- data/spec/support/stdout.rb +25 -0
- metadata +310 -0
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Contribution Guide
|
2
|
+
|
3
|
+
This page describes how to contribute changes to Savon.
|
4
|
+
|
5
|
+
Please do not create a pull request without reading this guide first.
|
6
|
+
Make sure to read the documentation for your version at [savonrb.com](http://savonrb.com/)
|
7
|
+
and post questions to the [mailing list](https://groups.google.com/forum/#!forum/savonrb).
|
8
|
+
|
9
|
+
**Bug fixes**
|
10
|
+
|
11
|
+
If you really think you found a bug, please make sure to add as many information as possible
|
12
|
+
to the ticket. You're a developer, we are developers and you know we need tests to reproduce
|
13
|
+
problems and make sure they don't come back.
|
14
|
+
|
15
|
+
So if you can reproduce your problem in a spec, that would be awesome! If you can't, please
|
16
|
+
let us know how we could make this easier for you. Also, provide code and the WSDL of the
|
17
|
+
service you're working with so others can try to come up with a spec for your problem.
|
18
|
+
|
19
|
+
After we have a failing spec, it obviously needs to be fixed. Make sure your new spec is the
|
20
|
+
only failing one under the `spec` directory. Travis only runs the "unit tests" at `spec/savon`,
|
21
|
+
but Savon actually has with some additional "integration/example specs" at `spec/integration`,
|
22
|
+
which you need to run locally to make sure the integration with real world services still works.
|
23
|
+
|
24
|
+
Notice that these specs are not run by Travis, because the service's are not guaranteed to work
|
25
|
+
all the time and the specs will timeout after a few seconds when the service is currently down.
|
26
|
+
|
27
|
+
Please follow this basic workflow for pull requests:
|
28
|
+
|
29
|
+
* [Fork the project](https://help.github.com/articles/fork-a-repo)
|
30
|
+
* Create a feature branch and make your bug fix
|
31
|
+
* Add tests for it!
|
32
|
+
* Update the [Changelog](https://github.com/savonrb/savon/blob/master/CHANGELOG.md)
|
33
|
+
* [Send a pull request](https://help.github.com/articles/using-pull-requests)
|
34
|
+
* [Check that your pull request passes the build](https://travis-ci.org/savonrb/savon/pull_requests)
|
35
|
+
|
36
|
+
|
37
|
+
**Improvements and feature requests**
|
38
|
+
|
39
|
+
If you have an idea for an improvement or a new feature, please feel free to
|
40
|
+
[create a new issue](https://github.com/savonrb/savon/issues/new) and describe your idea
|
41
|
+
so that other people can give their insights and opinions. This is also important to avoid
|
42
|
+
duplicate work.
|
43
|
+
|
44
|
+
Pull requests and issues on GitHub are meant to be used to discuss problems and ideas,
|
45
|
+
so please make sure to participate and follow up on questions. In case noone comments
|
46
|
+
on your ticket, please keep updating the ticket with additional information.
|
data/Gemfile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
gemspec
|
3
|
+
|
4
|
+
gem "httpclient", "~> 2.3.4"
|
5
|
+
|
6
|
+
gem "simplecov", :require => false
|
7
|
+
gem "coveralls", :require => false
|
8
|
+
|
9
|
+
platform :rbx do
|
10
|
+
gem 'json'
|
11
|
+
gem 'racc'
|
12
|
+
gem 'rubysl'
|
13
|
+
gem 'rubinius-coverage'
|
14
|
+
end
|
15
|
+
|
16
|
+
platform :jruby do
|
17
|
+
gem 'json'
|
18
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Daniel Harrington
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# Savon
|
2
|
+
|
3
|
+
Heavy metal SOAP client
|
4
|
+
|
5
|
+
[Documentation](http://savonrb.com) | [RDoc](http://rubydoc.info/gems/savon) |
|
6
|
+
[Mailing list](https://groups.google.com/forum/#!forum/savonrb) | [Twitter](http://twitter.com/savonrb)
|
7
|
+
|
8
|
+
[![Build Status](https://secure.travis-ci.org/savonrb/savon.png?branch=version2)](http://travis-ci.org/savonrb/savon)
|
9
|
+
[![Gem Version](https://badge.fury.io/rb/savon.png)](http://badge.fury.io/rb/savon)
|
10
|
+
[![Code Climate](https://codeclimate.com/github/savonrb/savon.png)](https://codeclimate.com/github/savonrb/savon)
|
11
|
+
[![Coverage Status](https://coveralls.io/repos/savonrb/savon/badge.png?branch=version2)](https://coveralls.io/r/savonrb/savon)
|
12
|
+
|
13
|
+
|
14
|
+
## Version 2
|
15
|
+
|
16
|
+
Savon version 2 is available through [Rubygems](http://rubygems.org/gems/savon) and can be installed via:
|
17
|
+
|
18
|
+
```
|
19
|
+
$ gem install savon
|
20
|
+
```
|
21
|
+
|
22
|
+
or add it to your Gemfile like this:
|
23
|
+
|
24
|
+
```
|
25
|
+
gem 'savon', '~> 2.3.0'
|
26
|
+
```
|
27
|
+
|
28
|
+
|
29
|
+
## Maintainer needed
|
30
|
+
|
31
|
+
So I've been maintaining Savon and its dependant projects for the last four years and it's become quite
|
32
|
+
apparent now with my schedule I do not have the time to keep this project going single-handed.
|
33
|
+
|
34
|
+
Luckily there are numerous people helping out from time to time, but maintaining this project is pretty
|
35
|
+
much a full-time job and it keeps me from working on the next major version.
|
36
|
+
|
37
|
+
I'll be able to contribute on a small scale going forward, and will do my best in the meantime to catch
|
38
|
+
up with everything I am behind on.
|
39
|
+
|
40
|
+
If you are interested, please email me at [me at rubiii dot com].
|
41
|
+
I'll do everything I can to help you get started.
|
42
|
+
|
43
|
+
|
44
|
+
## Usage example
|
45
|
+
|
46
|
+
``` ruby
|
47
|
+
require 'savon'
|
48
|
+
|
49
|
+
# create a client for the service
|
50
|
+
client = Savon.client(wsdl: 'http://service.example.com?wsdl')
|
51
|
+
|
52
|
+
client.operations
|
53
|
+
# => [:find_user, :list_users]
|
54
|
+
|
55
|
+
# call the 'findUser' operation
|
56
|
+
response = client.call(:find_user, message: { id: 42 })
|
57
|
+
|
58
|
+
response.body
|
59
|
+
# => { find_user_response: { id: 42, name: 'Hoff' } }
|
60
|
+
```
|
61
|
+
|
62
|
+
For more examples, you should check out the
|
63
|
+
[integration tests](https://github.com/savonrb/savon/tree/version2/spec/integration).
|
64
|
+
|
65
|
+
|
66
|
+
## Give back
|
67
|
+
|
68
|
+
If you're using Savon and you or your company is making money from it, then please consider
|
69
|
+
donating via [Gittip](https://www.gittip.com/rubiii/) so that I can continue to improve it.
|
70
|
+
|
71
|
+
[![donate](donate.png)](https://www.gittip.com/rubiii/)
|
72
|
+
|
73
|
+
|
74
|
+
## Documentation
|
75
|
+
|
76
|
+
Please make sure to [read the documentation](http://savonrb.com/version2/).
|
77
|
+
|
78
|
+
And if you find any problems with it or if you think something's missing,
|
79
|
+
feel free to [help out and improve the documentation](https://github.com/savonrb/savonrb.com).
|
80
|
+
|
81
|
+
Donate icon from the [Noun Project](http://thenounproject.com/noun/donate/#icon-No285).
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new do |t|
|
5
|
+
t.pattern = "spec/savon/**/*_spec.rb"
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "Run RSpec integration examples"
|
9
|
+
RSpec::Core::RakeTask.new "spec:integration" do |t|
|
10
|
+
t.pattern = "spec/integration/**/*_spec.rb"
|
11
|
+
end
|
12
|
+
|
13
|
+
task :default => :spec
|
14
|
+
task :test => :spec
|
data/donate.png
ADDED
Binary file
|
data/lib/savon.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Savon
|
2
|
+
|
3
|
+
Error = Class.new(RuntimeError)
|
4
|
+
InitializationError = Class.new(Error)
|
5
|
+
UnknownOptionError = Class.new(Error)
|
6
|
+
UnknownOperationError = Class.new(Error)
|
7
|
+
InvalidResponseError = Class.new(Error)
|
8
|
+
|
9
|
+
def self.client(globals = {}, &block)
|
10
|
+
Client.new(globals, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.observers
|
14
|
+
@observers ||= []
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.notify_observers(operation_name, builder, globals, locals)
|
18
|
+
observers.inject(nil) do |response, observer|
|
19
|
+
observer.notify(operation_name, builder, globals, locals)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
require "savon/version"
|
26
|
+
require "savon/client"
|
27
|
+
require "savon/model"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Savon
|
2
|
+
class BlockInterface
|
3
|
+
|
4
|
+
def initialize(target)
|
5
|
+
@target = target
|
6
|
+
end
|
7
|
+
|
8
|
+
def evaluate(block)
|
9
|
+
if block.arity > 0
|
10
|
+
block.call(@target)
|
11
|
+
else
|
12
|
+
@original = eval("self", block.binding)
|
13
|
+
instance_eval(&block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def method_missing(method, *args, &block)
|
20
|
+
@target.send(method, *args, &block)
|
21
|
+
rescue NoMethodError
|
22
|
+
@original.send(method, *args, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require "savon/header"
|
2
|
+
require "savon/message"
|
3
|
+
require "nokogiri"
|
4
|
+
require "builder"
|
5
|
+
require "gyoku"
|
6
|
+
|
7
|
+
module Savon
|
8
|
+
class Builder
|
9
|
+
|
10
|
+
SCHEMA_TYPES = {
|
11
|
+
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
|
12
|
+
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance"
|
13
|
+
}
|
14
|
+
|
15
|
+
SOAP_NAMESPACE = {
|
16
|
+
1 => "http://schemas.xmlsoap.org/soap/envelope/",
|
17
|
+
2 => "http://www.w3.org/2003/05/soap-envelope"
|
18
|
+
}
|
19
|
+
|
20
|
+
def initialize(operation_name, wsdl, globals, locals)
|
21
|
+
@operation_name = operation_name
|
22
|
+
|
23
|
+
@wsdl = wsdl
|
24
|
+
@globals = globals
|
25
|
+
@locals = locals
|
26
|
+
|
27
|
+
@types = convert_type_definitions_to_hash
|
28
|
+
@used_namespaces = convert_type_namespaces_to_hash
|
29
|
+
end
|
30
|
+
|
31
|
+
def pretty
|
32
|
+
Nokogiri.XML(to_s).to_xml(:indent => 2)
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
return @locals[:xml] if @locals.include? :xml
|
37
|
+
|
38
|
+
tag(builder, :Envelope, namespaces_with_globals) do |xml|
|
39
|
+
tag(xml, :Header) { xml << header.to_s } unless header.empty?
|
40
|
+
tag(xml, :Body) { xml.tag!(*namespaced_message_tag) { xml << message.to_s } }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def convert_type_definitions_to_hash
|
47
|
+
@wsdl.type_definitions.inject({}) do |memo, (path, type)|
|
48
|
+
memo[path] = type
|
49
|
+
memo
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def convert_type_namespaces_to_hash
|
54
|
+
@wsdl.type_namespaces.inject({}) do |memo, (path, uri)|
|
55
|
+
key, value = use_namespace(path, uri)
|
56
|
+
memo[key] = value
|
57
|
+
memo
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def use_namespace(path, uri)
|
62
|
+
@internal_namespace_count ||= 0
|
63
|
+
|
64
|
+
unless identifier = namespace_by_uri(uri)
|
65
|
+
identifier = "ins#{@internal_namespace_count}"
|
66
|
+
namespaces["xmlns:#{identifier}"] = uri
|
67
|
+
@internal_namespace_count += 1
|
68
|
+
end
|
69
|
+
|
70
|
+
[path, identifier]
|
71
|
+
end
|
72
|
+
|
73
|
+
def namespaces_with_globals
|
74
|
+
namespaces.merge @globals[:namespaces]
|
75
|
+
end
|
76
|
+
|
77
|
+
def namespaces
|
78
|
+
@namespaces ||= begin
|
79
|
+
namespaces = SCHEMA_TYPES.dup
|
80
|
+
|
81
|
+
if namespace_identifier == nil
|
82
|
+
namespaces["xmlns"] = @globals[:namespace] || @wsdl.namespace
|
83
|
+
else
|
84
|
+
namespaces["xmlns:#{namespace_identifier}"] = @globals[:namespace] || @wsdl.namespace
|
85
|
+
end
|
86
|
+
|
87
|
+
key = ["xmlns"]
|
88
|
+
key << env_namespace if env_namespace && env_namespace != ""
|
89
|
+
namespaces[key.join(":")] = SOAP_NAMESPACE[@globals[:soap_version]]
|
90
|
+
|
91
|
+
namespaces
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def env_namespace
|
96
|
+
@env_namespace ||= @globals[:env_namespace] || :env
|
97
|
+
end
|
98
|
+
|
99
|
+
def header
|
100
|
+
@header ||= Header.new(@globals, @locals)
|
101
|
+
end
|
102
|
+
|
103
|
+
def namespaced_message_tag
|
104
|
+
tag_name = message_tag
|
105
|
+
if namespace_identifier == nil
|
106
|
+
[tag_name, message_attributes]
|
107
|
+
elsif @used_namespaces[[tag_name.to_s]]
|
108
|
+
[@used_namespaces[[tag_name.to_s]], tag_name, message_attributes]
|
109
|
+
else
|
110
|
+
[namespace_identifier, tag_name, message_attributes]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def message_tag
|
115
|
+
message_tag = @locals[:message_tag]
|
116
|
+
message_tag ||= @wsdl.soap_input(@operation_name.to_sym) if @wsdl.document?
|
117
|
+
message_tag ||= Gyoku.xml_tag(@operation_name, :key_converter => @globals[:convert_request_keys_to])
|
118
|
+
|
119
|
+
@message_tag = message_tag.to_sym
|
120
|
+
end
|
121
|
+
|
122
|
+
def message_attributes
|
123
|
+
@locals[:attributes] || {}
|
124
|
+
end
|
125
|
+
|
126
|
+
def message
|
127
|
+
element_form_default = @globals[:element_form_default] || @wsdl.element_form_default
|
128
|
+
# TODO: clean this up! [dh, 2012-12-17]
|
129
|
+
Message.new(message_tag, namespace_identifier, @types, @used_namespaces, @locals[:message],
|
130
|
+
element_form_default, @globals[:convert_request_keys_to])
|
131
|
+
end
|
132
|
+
|
133
|
+
def namespace_identifier
|
134
|
+
return @globals[:namespace_identifier] if @globals.include? :namespace_identifier
|
135
|
+
return @namespace_identifier if @namespace_identifier
|
136
|
+
|
137
|
+
operation = @wsdl.operations[@operation_name] if @wsdl.document?
|
138
|
+
namespace_identifier = operation[:namespace_identifier] if operation
|
139
|
+
namespace_identifier ||= "wsdl"
|
140
|
+
|
141
|
+
@namespace_identifier = namespace_identifier.to_sym
|
142
|
+
end
|
143
|
+
|
144
|
+
def namespace_by_uri(uri)
|
145
|
+
namespaces.each do |candidate_identifier, candidate_uri|
|
146
|
+
return candidate_identifier.gsub(/^xmlns:/, '') if candidate_uri == uri
|
147
|
+
end
|
148
|
+
nil
|
149
|
+
end
|
150
|
+
|
151
|
+
def builder
|
152
|
+
builder = ::Builder::XmlMarkup.new
|
153
|
+
builder.instruct!(:xml, :encoding => @globals[:encoding])
|
154
|
+
builder
|
155
|
+
end
|
156
|
+
|
157
|
+
def tag(xml, name, namespaces = {}, &block)
|
158
|
+
if env_namespace && env_namespace != ""
|
159
|
+
xml.tag! env_namespace, name, namespaces, &block
|
160
|
+
else
|
161
|
+
xml.tag! name, namespaces, &block
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
end
|
data/lib/savon/client.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require "savon/operation"
|
2
|
+
require "savon/request"
|
3
|
+
require "savon/options"
|
4
|
+
require "savon/block_interface"
|
5
|
+
require "wasabi"
|
6
|
+
|
7
|
+
module Savon
|
8
|
+
class Client
|
9
|
+
|
10
|
+
def initialize(globals = {}, &block)
|
11
|
+
unless globals.kind_of? Hash
|
12
|
+
raise_version1_initialize_error! globals
|
13
|
+
end
|
14
|
+
|
15
|
+
set_globals(globals, block)
|
16
|
+
|
17
|
+
unless wsdl_or_endpoint_and_namespace_specified?
|
18
|
+
raise_initialization_error!
|
19
|
+
end
|
20
|
+
|
21
|
+
build_wsdl_document
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :globals
|
25
|
+
|
26
|
+
def operations
|
27
|
+
raise_missing_wsdl_error! unless @wsdl.document?
|
28
|
+
@wsdl.soap_actions
|
29
|
+
end
|
30
|
+
|
31
|
+
def operation(operation_name)
|
32
|
+
Operation.create(operation_name, @wsdl, @globals)
|
33
|
+
end
|
34
|
+
|
35
|
+
def call(operation_name, locals = {}, &block)
|
36
|
+
operation(operation_name).call(locals, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
def service_name
|
40
|
+
raise_missing_wsdl_error! unless @wsdl.document?
|
41
|
+
@wsdl.service_name
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def set_globals(globals, block)
|
47
|
+
globals = GlobalOptions.new(globals)
|
48
|
+
BlockInterface.new(globals).evaluate(block) if block
|
49
|
+
|
50
|
+
@globals = globals
|
51
|
+
end
|
52
|
+
|
53
|
+
def build_wsdl_document
|
54
|
+
@wsdl = Wasabi::Document.new
|
55
|
+
|
56
|
+
@wsdl.document = @globals[:wsdl] if @globals.include? :wsdl
|
57
|
+
@wsdl.endpoint = @globals[:endpoint] if @globals.include? :endpoint
|
58
|
+
@wsdl.namespace = @globals[:namespace] if @globals.include? :namespace
|
59
|
+
@wsdl.servicename = @globals[:servicename] if @globals.include? :servicename
|
60
|
+
@wsdl.adapter = @globals[:adapter] if @globals.include? :adapter
|
61
|
+
|
62
|
+
@wsdl.request = WSDLRequest.new(@globals).build
|
63
|
+
end
|
64
|
+
|
65
|
+
def wsdl_or_endpoint_and_namespace_specified?
|
66
|
+
@globals.include?(:wsdl) || (@globals.include?(:endpoint) && @globals.include?(:namespace))
|
67
|
+
end
|
68
|
+
|
69
|
+
def raise_version1_initialize_error!(object)
|
70
|
+
raise InitializationError,
|
71
|
+
"Some code tries to initialize Savon with the #{object.inspect} (#{object.class}) \n" \
|
72
|
+
"Savon 2 expects a Hash of options for creating a new client and executing requests.\n" \
|
73
|
+
"Please read the updated documentation for version 2: http://savonrb.com/version2.html"
|
74
|
+
end
|
75
|
+
|
76
|
+
def raise_initialization_error!
|
77
|
+
raise InitializationError,
|
78
|
+
"Expected either a WSDL document or the SOAP endpoint and target namespace options.\n\n" \
|
79
|
+
"Savon.client(wsdl: '/Users/me/project/service.wsdl') # to use a local WSDL document\n" \
|
80
|
+
"Savon.client(wsdl: 'http://example.com?wsdl') # to use a remote WSDL document\n" \
|
81
|
+
"Savon.client(endpoint: 'http://example.com', namespace: 'http://v1.example.com') # if you don't have a WSDL document"
|
82
|
+
end
|
83
|
+
|
84
|
+
def raise_missing_wsdl_error!
|
85
|
+
raise "Unable to inspect the service without a WSDL document."
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|