wash_out 0.10.0.beta.1 → 0.10.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/.travis.yml +23 -3
- data/Appraisals +11 -5
- data/Gemfile +2 -2
- data/README.md +66 -2
- data/Rakefile +6 -7
- data/app/helpers/wash_out_helper.rb +49 -18
- data/app/views/{wash_with_soap → wash_out}/document/error.builder +0 -0
- data/app/views/{wash_with_soap → wash_out}/document/response.builder +1 -3
- data/app/views/{wash_with_soap → wash_out}/document/wsdl.builder +15 -15
- data/app/views/{wash_with_soap → wash_out}/rpc/error.builder +0 -0
- data/app/views/{wash_with_soap → wash_out}/rpc/response.builder +1 -3
- data/app/views/{wash_with_soap → wash_out}/rpc/wsdl.builder +16 -16
- data/gemfiles/rails_3.1.3.gemfile +20 -0
- data/gemfiles/rails_3.2.12.gemfile +20 -0
- data/gemfiles/rails_4.0.0.gemfile +19 -0
- data/gemfiles/rails_4.1.0.gemfile +19 -0
- data/gemfiles/rails_4.2.0.gemfile +19 -0
- data/lib/wash_out.rb +48 -16
- data/lib/wash_out/configurable.rb +41 -0
- data/lib/wash_out/dispatcher.rb +212 -0
- data/lib/wash_out/engine.rb +12 -0
- data/lib/wash_out/middleware.rb +41 -0
- data/lib/wash_out/model.rb +29 -0
- data/lib/wash_out/param.rb +43 -16
- data/lib/wash_out/router.rb +95 -0
- data/lib/wash_out/soap.rb +48 -0
- data/lib/wash_out/soap_config.rb +93 -0
- data/lib/wash_out/type.rb +20 -13
- data/lib/wash_out/version.rb +1 -1
- data/lib/wash_out/wsse.rb +29 -10
- data/spec/dummy/config/environments/test.rb +1 -0
- data/spec/lib/wash_out/dispatcher_spec.rb +28 -13
- data/spec/lib/wash_out/middleware_spec.rb +33 -0
- data/spec/lib/wash_out/param_spec.rb +47 -17
- data/spec/lib/wash_out/router_spec.rb +22 -0
- data/spec/lib/wash_out/type_spec.rb +9 -9
- data/spec/lib/wash_out_spec.rb +139 -87
- data/spec/spec_helper.rb +7 -1
- metadata +32 -25
- data/lib/wash_out/exceptions/programmer_error.rb +0 -10
- data/lib/wash_out/exceptions/soap_error.rb +0 -19
- data/lib/wash_out/middlewares/catcher.rb +0 -42
- data/lib/wash_out/middlewares/router.rb +0 -132
- data/lib/wash_out/rails/active_record.rb +0 -27
- data/lib/wash_out/rails/controller.rb +0 -201
- data/lib/wash_out/rails/engine.rb +0 -74
- data/spec/lib/wash_out/rack_spec.rb +0 -55
data/spec/spec_helper.rb
CHANGED
@@ -27,7 +27,11 @@ RSpec.configure do |config|
|
|
27
27
|
|
28
28
|
config.mock_with :rspec
|
29
29
|
config.before(:all) do
|
30
|
-
WashOut::
|
30
|
+
WashOut::Engine.config.wash_out = {
|
31
|
+
snakecase_input: false,
|
32
|
+
camelize_wsdl: false,
|
33
|
+
namespace: false
|
34
|
+
}
|
31
35
|
end
|
32
36
|
|
33
37
|
config.after(:suite) do
|
@@ -52,6 +56,8 @@ end
|
|
52
56
|
def mock_controller(options = {}, &block)
|
53
57
|
Object.send :remove_const, :ApiController if defined?(ApiController)
|
54
58
|
Object.send :const_set, :ApiController, Class.new(ApplicationController) {
|
59
|
+
include RSpec::Matchers
|
60
|
+
|
55
61
|
soap_service options.reverse_merge({
|
56
62
|
snakecase_input: true,
|
57
63
|
camelize_wsdl: true,
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wash_out
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.0
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boris Staal
|
@@ -9,20 +9,20 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-02-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nori
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: 2.0.0
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 2.0.0
|
28
28
|
description: Dead simple Rails 3 SOAP server library
|
@@ -31,9 +31,9 @@ executables: []
|
|
31
31
|
extensions: []
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
|
-
- .gitignore
|
35
|
-
- .rspec
|
36
|
-
- .travis.yml
|
34
|
+
- ".gitignore"
|
35
|
+
- ".rspec"
|
36
|
+
- ".travis.yml"
|
37
37
|
- Appraisals
|
38
38
|
- CHANGELOG.md
|
39
39
|
- Gemfile
|
@@ -42,22 +42,28 @@ files:
|
|
42
42
|
- README.md
|
43
43
|
- Rakefile
|
44
44
|
- app/helpers/wash_out_helper.rb
|
45
|
-
- app/views/
|
46
|
-
- app/views/
|
47
|
-
- app/views/
|
48
|
-
- app/views/
|
49
|
-
- app/views/
|
50
|
-
- app/views/
|
45
|
+
- app/views/wash_out/document/error.builder
|
46
|
+
- app/views/wash_out/document/response.builder
|
47
|
+
- app/views/wash_out/document/wsdl.builder
|
48
|
+
- app/views/wash_out/rpc/error.builder
|
49
|
+
- app/views/wash_out/rpc/response.builder
|
50
|
+
- app/views/wash_out/rpc/wsdl.builder
|
51
|
+
- gemfiles/rails_3.1.3.gemfile
|
52
|
+
- gemfiles/rails_3.2.12.gemfile
|
53
|
+
- gemfiles/rails_4.0.0.gemfile
|
54
|
+
- gemfiles/rails_4.1.0.gemfile
|
55
|
+
- gemfiles/rails_4.2.0.gemfile
|
51
56
|
- init.rb
|
52
57
|
- lib/wash_out.rb
|
53
|
-
- lib/wash_out/
|
54
|
-
- lib/wash_out/
|
55
|
-
- lib/wash_out/
|
56
|
-
- lib/wash_out/
|
58
|
+
- lib/wash_out/configurable.rb
|
59
|
+
- lib/wash_out/dispatcher.rb
|
60
|
+
- lib/wash_out/engine.rb
|
61
|
+
- lib/wash_out/middleware.rb
|
62
|
+
- lib/wash_out/model.rb
|
57
63
|
- lib/wash_out/param.rb
|
58
|
-
- lib/wash_out/
|
59
|
-
- lib/wash_out/
|
60
|
-
- lib/wash_out/
|
64
|
+
- lib/wash_out/router.rb
|
65
|
+
- lib/wash_out/soap.rb
|
66
|
+
- lib/wash_out/soap_config.rb
|
61
67
|
- lib/wash_out/type.rb
|
62
68
|
- lib/wash_out/version.rb
|
63
69
|
- lib/wash_out/wsse.rb
|
@@ -85,8 +91,9 @@ files:
|
|
85
91
|
- spec/dummy/public/stylesheets/.gitkeep
|
86
92
|
- spec/dummy/script/rails
|
87
93
|
- spec/lib/wash_out/dispatcher_spec.rb
|
94
|
+
- spec/lib/wash_out/middleware_spec.rb
|
88
95
|
- spec/lib/wash_out/param_spec.rb
|
89
|
-
- spec/lib/wash_out/
|
96
|
+
- spec/lib/wash_out/router_spec.rb
|
90
97
|
- spec/lib/wash_out/type_spec.rb
|
91
98
|
- spec/lib/wash_out_spec.rb
|
92
99
|
- spec/spec_helper.rb
|
@@ -102,17 +109,17 @@ require_paths:
|
|
102
109
|
- lib
|
103
110
|
required_ruby_version: !ruby/object:Gem::Requirement
|
104
111
|
requirements:
|
105
|
-
- -
|
112
|
+
- - ">="
|
106
113
|
- !ruby/object:Gem::Version
|
107
114
|
version: '0'
|
108
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
116
|
requirements:
|
110
|
-
- -
|
117
|
+
- - ">="
|
111
118
|
- !ruby/object:Gem::Version
|
112
|
-
version:
|
119
|
+
version: '0'
|
113
120
|
requirements: []
|
114
121
|
rubyforge_project:
|
115
|
-
rubygems_version: 2.
|
122
|
+
rubygems_version: 2.2.5
|
116
123
|
signing_key:
|
117
124
|
specification_version: 4
|
118
125
|
summary: Dead simple Rails 3 SOAP server library
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module WashOut
|
2
|
-
#
|
3
|
-
# An exception reflecting expected logical error
|
4
|
-
#
|
5
|
-
# Such exception (or its descendants) will be intercepted and rendered
|
6
|
-
# into proper SOAP error XML response.
|
7
|
-
#
|
8
|
-
class SOAPError < Exception
|
9
|
-
attr_accessor :code
|
10
|
-
|
11
|
-
def initialize(message, code=nil)
|
12
|
-
super(message)
|
13
|
-
@code = code
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# Backward compatibility hack
|
19
|
-
class SOAPError < WashOut::SOAPError; end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module WashOut
|
2
|
-
module Middlewares
|
3
|
-
class Catcher
|
4
|
-
def initialize(app)
|
5
|
-
@app = app
|
6
|
-
end
|
7
|
-
|
8
|
-
def call(env)
|
9
|
-
@app.call env
|
10
|
-
rescue REXML::ParseException => e
|
11
|
-
raise e unless env.has_key?('HTTP_SOAPACTION')
|
12
|
-
|
13
|
-
input = env['rack.input'].respond_to?(:string) ? env['rack.input'].string
|
14
|
-
: env['rack.input'].read
|
15
|
-
|
16
|
-
env['rack.errors'].puts <<-TEXT
|
17
|
-
WashOut::Exception: #{e.continued_exception} for:
|
18
|
-
#{input}
|
19
|
-
TEXT
|
20
|
-
|
21
|
-
[
|
22
|
-
400,
|
23
|
-
{'Content-Type' => 'text/xml'},
|
24
|
-
[self.class.render_client_soap_fault("Error parsing SOAP Request XML")]
|
25
|
-
]
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.render_client_soap_fault(msg)
|
29
|
-
xml = Builder::XmlMarkup.new
|
30
|
-
xml.tag! 'soap:Envelope', 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
31
|
-
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' do
|
32
|
-
xml.tag! 'soap:Body' do
|
33
|
-
xml.tag! 'soap:Fault', :encodingStyle => 'http://schemas.xmlsoap.org/soap/encoding/' do
|
34
|
-
xml.faultcode 'Client'
|
35
|
-
xml.faultstring msg
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,132 +0,0 @@
|
|
1
|
-
require 'nori'
|
2
|
-
|
3
|
-
module WashOut
|
4
|
-
module Middlewares
|
5
|
-
#
|
6
|
-
# This class is a Rack middleware used to route SOAP requests to a proper
|
7
|
-
# action of a given SOAP controller.
|
8
|
-
#
|
9
|
-
# WashOut engine adds routing helper `wash_out` that registeres this middleware
|
10
|
-
# as a main responder internally.
|
11
|
-
#
|
12
|
-
# @see WashOut::Rails::Engine
|
13
|
-
#
|
14
|
-
class Router
|
15
|
-
def initialize(controller_name)
|
16
|
-
@controller_name = "#{controller_name.to_s}_controller".camelize
|
17
|
-
end
|
18
|
-
|
19
|
-
def parse_soap_action(env)
|
20
|
-
return env['wash_out.soap_action'] if env['wash_out.soap_action']
|
21
|
-
|
22
|
-
# SOAPACTION is expected to come in quotes that have to be stripped
|
23
|
-
soap_action = env['HTTP_SOAPACTION'].to_s.gsub(/^"(.*)"$/, '\1')
|
24
|
-
|
25
|
-
# Clients can sometimes send empty SOAPACTION to avoid duplication
|
26
|
-
# In this cases we have to get it from the body
|
27
|
-
if soap_action.blank?
|
28
|
-
soap_action = nori.parse(soap_body env)[:Envelope][:Body].keys.first.to_s
|
29
|
-
end
|
30
|
-
|
31
|
-
# RUBY18
|
32
|
-
soap_action.force_encoding('UTF-8') if soap_action.respond_to? :force_encoding
|
33
|
-
|
34
|
-
# And finally we have to strip namespace from the action name
|
35
|
-
if @controller.soap_config.namespace
|
36
|
-
namespace = Regexp.escape @controller.soap_config.namespace.to_s
|
37
|
-
soap_action.gsub!(/^(#{namespace}(\/|#)?)?([^"]*)$/, '\3')
|
38
|
-
end
|
39
|
-
|
40
|
-
env['wash_out.soap_action'] = soap_action
|
41
|
-
end
|
42
|
-
|
43
|
-
def parse_soap_parameters(env)
|
44
|
-
return env['wash_out.soap_data'] if env['wash_out.soap_data']
|
45
|
-
|
46
|
-
env['wash_out.soap_data'] = nori(@controller.soap_config.snakecase_input).parse(soap_body env)
|
47
|
-
|
48
|
-
# Seeking for in-XML substitutions marked by attribute `id`
|
49
|
-
references = self.class.deep_select(env['wash_out.soap_data']) do |k,v|
|
50
|
-
v.is_a?(Hash) && v.has_key?(:@id)
|
51
|
-
end
|
52
|
-
|
53
|
-
# Replacing the found substitutions with nodes having proper `href` attribute
|
54
|
-
unless references.blank?
|
55
|
-
replaces = {}
|
56
|
-
references.each { |r| replaces['#'+r[:@id]] = r }
|
57
|
-
|
58
|
-
env['wash_out.soap_data'] = self.class.deep_replace_href(env['wash_out.soap_data'], replaces)
|
59
|
-
end
|
60
|
-
|
61
|
-
env['wash_out.soap_data']
|
62
|
-
end
|
63
|
-
|
64
|
-
#
|
65
|
-
# Nori parser builder
|
66
|
-
#
|
67
|
-
def nori(snakecase=false)
|
68
|
-
Nori.new(
|
69
|
-
parser: @controller.soap_config.parser,
|
70
|
-
strip_namespaces: true,
|
71
|
-
advanced_typecasting: true,
|
72
|
-
convert_tags_to: (
|
73
|
-
snakecase ? lambda { |tag| tag.snakecase.to_sym }
|
74
|
-
: lambda { |tag| tag.to_sym }
|
75
|
-
)
|
76
|
-
)
|
77
|
-
end
|
78
|
-
|
79
|
-
#
|
80
|
-
# Universal body accessor working with any Rack server
|
81
|
-
#
|
82
|
-
def soap_body(env)
|
83
|
-
env['rack.input'].respond_to?(:string) ? env['rack.input'].string
|
84
|
-
: env['rack.input'].read
|
85
|
-
end
|
86
|
-
|
87
|
-
def call(env)
|
88
|
-
@controller = @controller_name.constantize
|
89
|
-
|
90
|
-
parse_soap_action(env)
|
91
|
-
parse_soap_parameters(env)
|
92
|
-
|
93
|
-
action_spec = @controller.soap_actions[env['wash_out.soap_action']]
|
94
|
-
|
95
|
-
if action_spec
|
96
|
-
action = action_spec[:to]
|
97
|
-
else
|
98
|
-
action = '_invalid_action'
|
99
|
-
end
|
100
|
-
|
101
|
-
@controller.action(action).call(env)
|
102
|
-
end
|
103
|
-
|
104
|
-
#
|
105
|
-
# Recursively seeks XML tree for nodes matching given block
|
106
|
-
#
|
107
|
-
def self.deep_select(hash, result=[], &blk)
|
108
|
-
result += Hash[hash.select(&blk)].values
|
109
|
-
|
110
|
-
hash.each do |key, value|
|
111
|
-
result = deep_select(value, result, &blk) if value.is_a? Hash
|
112
|
-
end
|
113
|
-
|
114
|
-
result
|
115
|
-
end
|
116
|
-
|
117
|
-
#
|
118
|
-
# Recursively replaces nodes in the tree matching the given
|
119
|
-
# map of `href` attributes
|
120
|
-
#
|
121
|
-
def self.deep_replace_href(hash, replace)
|
122
|
-
return replace[hash[:@href]] if hash.has_key?(:@href)
|
123
|
-
|
124
|
-
hash.keys.each do |key, value|
|
125
|
-
hash[key] = deep_replace_href(hash[key], replace) if hash[key].is_a?(Hash)
|
126
|
-
end
|
127
|
-
|
128
|
-
hash
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module WashOut
|
2
|
-
module Rails
|
3
|
-
module ActiveRecord
|
4
|
-
def wash_out_param_map
|
5
|
-
types = {
|
6
|
-
text: :string,
|
7
|
-
float: :double,
|
8
|
-
decimal: :double,
|
9
|
-
timestamp: :string
|
10
|
-
}
|
11
|
-
map = {}
|
12
|
-
|
13
|
-
columns_hash.each do |key, column|
|
14
|
-
type = column.type
|
15
|
-
type = types[type] if types.has_key?(type)
|
16
|
-
map[key] = type
|
17
|
-
end
|
18
|
-
|
19
|
-
map
|
20
|
-
end
|
21
|
-
|
22
|
-
def wash_out_param_name(soap_config = nil)
|
23
|
-
WashOut.normalize(name.underscore.gsub('/', '.'), soap_config)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,201 +0,0 @@
|
|
1
|
-
module WashOut
|
2
|
-
module Rails
|
3
|
-
# The WashOut::Rails::Controller module should be included in a controller acting
|
4
|
-
# as a SOAP endpoint. It includes actions for generating WSDL and handling
|
5
|
-
# SOAP requests.
|
6
|
-
module Controller extend ActiveSupport::Concern
|
7
|
-
|
8
|
-
included do
|
9
|
-
helper :wash_out
|
10
|
-
|
11
|
-
around_filter :_catch_soap_errors
|
12
|
-
before_filter :_authenticate_wsse, :except => [ :_generate_wsdl, :_invalid_action ]
|
13
|
-
before_filter :_map_soap_parameters, :except => [ :_generate_wsdl, :_invalid_action ]
|
14
|
-
|
15
|
-
skip_before_filter :verify_authenticity_token
|
16
|
-
|
17
|
-
cattr_reader :soap_config
|
18
|
-
cattr_accessor :soap_actions
|
19
|
-
|
20
|
-
self.soap_actions = {}
|
21
|
-
end
|
22
|
-
|
23
|
-
module ClassMethods
|
24
|
-
#
|
25
|
-
# Overrides WashOut settings on a controller level
|
26
|
-
#
|
27
|
-
def soap_config=(options)
|
28
|
-
class_variable_set :@@soap_config, OpenStruct.new(
|
29
|
-
WashOut::Rails::Engine.config.wash_out.merge(options)
|
30
|
-
)
|
31
|
-
end
|
32
|
-
|
33
|
-
#
|
34
|
-
# Define a SOAP action +action+. The function has two required +options+:
|
35
|
-
# :args and :return. Each is a type +definition+ of format described in
|
36
|
-
# WashOut::Param#parse_def.
|
37
|
-
#
|
38
|
-
# An optional option :to can be passed to allow for names of SOAP actions
|
39
|
-
# which are not valid Ruby function names.
|
40
|
-
#
|
41
|
-
def soap_action(action, options={})
|
42
|
-
exposed_name = if action.is_a?(Symbol)
|
43
|
-
WashOut.normalize(action, soap_config)
|
44
|
-
else
|
45
|
-
action.to_s
|
46
|
-
end
|
47
|
-
|
48
|
-
self.soap_actions[exposed_name] = options.merge(
|
49
|
-
in: WashOut::Param.parse_def(soap_config, options[:args]),
|
50
|
-
out: WashOut::Param.parse_def(soap_config, options[:return]),
|
51
|
-
to: options[:to] || action.to_s
|
52
|
-
)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
#
|
57
|
-
# Render a SOAP error response.
|
58
|
-
#
|
59
|
-
def render_soap_error(message, code=nil)
|
60
|
-
render :template => "wash_with_soap/#{soap_config.wsdl_style}/error", :status => 500,
|
61
|
-
:layout => false,
|
62
|
-
:locals => { :error_message => message, :error_code => (code || 'Server') },
|
63
|
-
:content_type => 'text/xml'
|
64
|
-
end
|
65
|
-
|
66
|
-
def _authenticate_wsse
|
67
|
-
begin
|
68
|
-
xml_security = env['wash_out.soap_data'].values_at(:envelope, :Envelope).compact.first
|
69
|
-
xml_security = xml_security.values_at(:header, :Header).compact.first
|
70
|
-
xml_security = xml_security.values_at(:security, :Security).compact.first
|
71
|
-
username_token = xml_security.values_at(:username_token, :UsernameToken).compact.first
|
72
|
-
rescue
|
73
|
-
username_token = nil
|
74
|
-
end
|
75
|
-
|
76
|
-
WashOut::Wsse.authenticate(soap_config, username_token)
|
77
|
-
|
78
|
-
request.env['WSSE_TOKEN'] = username_token.with_indifferent_access unless username_token.blank?
|
79
|
-
end
|
80
|
-
|
81
|
-
def _map_soap_parameters
|
82
|
-
soap_action = request.env['wash_out.soap_action']
|
83
|
-
action_spec = self.class.soap_actions[soap_action]
|
84
|
-
|
85
|
-
xml_data = env['wash_out.soap_data'].values_at(:envelope, :Envelope).compact.first
|
86
|
-
xml_data = xml_data.values_at(:body, :Body).compact.first
|
87
|
-
xml_data = xml_data.values_at(soap_action.underscore.to_sym,
|
88
|
-
soap_action.to_sym).compact.first || {}
|
89
|
-
|
90
|
-
strip_empty_nodes = lambda{|hash|
|
91
|
-
hash.keys.each do |key|
|
92
|
-
if hash[key].is_a? Hash
|
93
|
-
value = hash[key].delete_if{|k, v| key.to_s[0] == '@'}
|
94
|
-
|
95
|
-
if value.length > 0
|
96
|
-
hash[key] = strip_empty_nodes.call(value)
|
97
|
-
else
|
98
|
-
hash[key] = nil
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
hash
|
104
|
-
}
|
105
|
-
xml_data = strip_empty_nodes.call(xml_data)
|
106
|
-
@_params = _load_params(action_spec[:in], xml_data)
|
107
|
-
end
|
108
|
-
|
109
|
-
# Creates the final parameter hash based on the request spec and xml_data from the request
|
110
|
-
def _load_params(spec, xml_data)
|
111
|
-
params = HashWithIndifferentAccess.new
|
112
|
-
spec.each do |param|
|
113
|
-
key = param.raw_name.to_sym
|
114
|
-
if xml_data.has_key? key
|
115
|
-
params[param.raw_name] = param.load(xml_data, key)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
params
|
119
|
-
end
|
120
|
-
|
121
|
-
# This action generates the WSDL for defined SOAP methods.
|
122
|
-
def _generate_wsdl
|
123
|
-
|
124
|
-
@map = self.class.soap_actions
|
125
|
-
@namespace = soap_config.namespace
|
126
|
-
@name = controller_path.gsub('/', '_')
|
127
|
-
|
128
|
-
render :template => "wash_with_soap/#{soap_config.wsdl_style}/wsdl", :layout => false,
|
129
|
-
:content_type => 'text/xml'
|
130
|
-
end
|
131
|
-
|
132
|
-
# Render a SOAP response.
|
133
|
-
def _render_soap(result, options)
|
134
|
-
@namespace = soap_config.namespace
|
135
|
-
@operation = soap_action = request.env['wash_out.soap_action']
|
136
|
-
@action_spec = self.class.soap_actions[soap_action]
|
137
|
-
|
138
|
-
result = { 'value' => result } unless result.is_a? Hash
|
139
|
-
result = HashWithIndifferentAccess.new(result)
|
140
|
-
|
141
|
-
inject = lambda {|data, map|
|
142
|
-
result_spec = []
|
143
|
-
return result_spec if data.nil?
|
144
|
-
|
145
|
-
map.each_with_index do |param, i|
|
146
|
-
result_spec[i] = param.flat_copy
|
147
|
-
|
148
|
-
unless data.is_a?(Hash)
|
149
|
-
raise WashOut::ProgrammerError,
|
150
|
-
"SOAP response used #{data.inspect} (which is #{data.class.name}), " +
|
151
|
-
"in the context where a Hash with key of '#{param.raw_name}' " +
|
152
|
-
"was expected."
|
153
|
-
end
|
154
|
-
|
155
|
-
value = data[param.raw_name]
|
156
|
-
|
157
|
-
unless value.nil?
|
158
|
-
if param.multiplied && !value.is_a?(Array)
|
159
|
-
raise WashOut::ProgrammerError,
|
160
|
-
"SOAP response tried to use '#{value.inspect}' " +
|
161
|
-
"(which is of type #{value.class.name}), as the value for " +
|
162
|
-
"'#{param.raw_name}' (which expects an Array)."
|
163
|
-
end
|
164
|
-
|
165
|
-
# Inline complex structure {:foo => {bar: ...}}
|
166
|
-
if param.struct? && !param.multiplied
|
167
|
-
result_spec[i].map = inject.call(value, param.map)
|
168
|
-
|
169
|
-
# Inline array of complex structures {:foo => [{bar: ...}]}
|
170
|
-
elsif param.struct? && param.multiplied
|
171
|
-
result_spec[i].map = value.map{|e| inject.call(e, param.map)}
|
172
|
-
|
173
|
-
# Inline scalar {:foo => :string}
|
174
|
-
else
|
175
|
-
result_spec[i].value = value
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
return result_spec
|
181
|
-
}
|
182
|
-
|
183
|
-
render :template => "wash_with_soap/#{soap_config.wsdl_style}/response",
|
184
|
-
:layout => false,
|
185
|
-
:locals => { :result => inject.call(result, @action_spec[:out]) },
|
186
|
-
:content_type => 'text/xml'
|
187
|
-
end
|
188
|
-
|
189
|
-
# This action is a fallback for all undefined SOAP actions.
|
190
|
-
def _invalid_action
|
191
|
-
render_soap_error("Cannot find SOAP action mapping for #{request.env['wash_out.soap_action']}")
|
192
|
-
end
|
193
|
-
|
194
|
-
def _catch_soap_errors
|
195
|
-
yield
|
196
|
-
rescue WashOut::SOAPError => error
|
197
|
-
render_soap_error(error.message, error.code)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|