shapewear 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1
4
+ * Added support for SOAP 1.2 Faults;
5
+ * Refactored the request handling into its own class.
6
+
3
7
  ## 0.1.0
4
8
  * Added specs and fixed basic support for SOAP:Fault.
5
9
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shapewear (0.1.0)
4
+ shapewear (0.1.1)
5
5
  builder (>= 2.1.2)
6
6
  nokogiri (>= 1.5.0)
7
7
 
data/lib/shapewear/dsl.rb CHANGED
@@ -21,7 +21,8 @@ module Shapewear::DSL
21
21
  'soap' => 'http://schemas.xmlsoap.org/wsdl/soap/',
22
22
  'soap12' => 'http://schemas.xmlsoap.org/wsdl/soap12/',
23
23
  'xsd' => 'http://www.w3.org/2001/XMLSchema',
24
- 'env' => 'http://schemas.xmlsoap.org/soap/envelope/'
24
+ 'env' => 'http://schemas.xmlsoap.org/soap/envelope/',
25
+ 'env12' => 'http://www.w3.org/2001/12/soap-envelope'
25
26
  end
26
27
 
27
28
  protected
@@ -1,81 +1,130 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'forwardable'
4
+
3
5
  module Shapewear::Request
4
6
  # @param request [Rack::Request, Hash]
5
7
  def serve(request)
6
- op_node = find_soap_operation_node(request)
7
-
8
- begin
9
- call_soap_operation(op_node)
10
- rescue => e
11
- serialize_soap_fault e
12
- end
8
+ RequestHandler.new(self, request).serve
13
9
  end
14
10
 
15
- private
11
+ class RequestHandler
12
+ extend Forwardable
16
13
 
17
- def find_soap_operation_node(request)
18
- body ||= request.body if request.respond_to? :body
19
- body ||= request[:body] if request.is_a?(Hash)
20
- body ||= request.to_s
14
+ attr_reader :soap_version, :op_node, :clazz
15
+ def_delegators :@clazz, :namespaces, :operations, :logger
21
16
 
22
- raise "Request body could not be found" if body.nil?
17
+ def initialize(clazz, request)
18
+ @clazz = clazz
23
19
 
24
- doc = Nokogiri::XML(body) { |c| c.strict } rescue raise("Request body is not a valid XML")
20
+ body ||= request.body if request.respond_to? :body
21
+ body ||= request[:body] if request.is_a?(Hash)
22
+ body ||= request.to_s
25
23
 
26
- raise "Request is not a SOAP::Envelope: #{body}" if doc.at('/env:Envelope', namespaces).nil?
24
+ raise "Request body could not be found" if body.nil?
27
25
 
28
- # find the operation element, or raise if not found
29
- doc.at("/env:Envelope/env:Body/tns:*", namespaces) or raise "Operation not found"
30
- end
26
+ doc = Nokogiri::XML(body) { |c| c.strict } rescue raise("Request body is not a valid XML")
31
27
 
32
- def call_soap_operation(node)
33
- operations.each do |k, v|
34
- if v[:public_name] == node.name
35
- params = extract_parameters(node)
36
- logger.debug "Calling #{k} with args: #{params.map(&:inspect) * ', '}"
37
- r = self.new.send(k, *params)
38
- logger.debug "Result: #{r.inspect}"
39
- return serialize_soap_result v, r
28
+ # detect the SOAP version from the envelope, and find the operation element, or raise if not found
29
+ if doc.at('/env:Envelope', namespaces)
30
+ @soap_version = :soap11
31
+ @op_node = doc.at("/env:Envelope/env:Body/tns:*", namespaces)
32
+ elsif doc.at('/env12:Envelope', namespaces)
33
+ @soap_version = :soap12
34
+ @op_node = doc.at("/env12:Envelope/env12:Body/tns:*", namespaces)
35
+ else
36
+ raise "Request is not a SOAP 1.1 nor SOAP 1.2 Envelope: #{body}"
40
37
  end
41
38
  end
42
39
 
43
- raise "Operation not found: #{node.name}"
44
- end
45
-
46
- def extract_parameters(node)
47
- # TODO: use the metadata collected from the DSL to reoder the parameters and perform the appropriate conversions
48
- node.children.map { |n| n.text }
49
- end
50
-
51
- #noinspection RubyArgCount
52
- def serialize_soap_result(op_options, r)
53
- xb = Builder::XmlMarkup.new
54
- xb.instruct!
40
+ def serve
41
+ call_soap_operation
42
+ end
55
43
 
56
- xb.Envelope :xmlns => namespaces['env'] do |xenv|
57
- xenv.Body do |xbody|
58
- xbody.tag! "#{op_options[:public_name]}Response", :xmlns => namespaces['tns'] do |xres|
59
- xres.body r
44
+ private
45
+
46
+ def call_soap_operation
47
+ raise "Operation node not found" if op_node.nil?
48
+
49
+ operations.each do |k, v|
50
+ if v[:public_name] == op_node.name
51
+ logger.debug "Extracting parameters from operation node..."
52
+ params = extract_parameters(@op_node)
53
+ logger.debug "Creating new instance of #{clazz}..."
54
+ obj = clazz.new
55
+ logger.debug "Calling #{k} with args: #{params.map(&:inspect) * ', '}"
56
+ begin
57
+ r = obj.send(k, *params)
58
+ logger.debug "Result: #{r.inspect}"
59
+ return serialize_soap_result v, r
60
+ rescue => e
61
+ logger.debug "Exception: #{e.inspect}"
62
+ return serialize_soap_fault e
63
+ end
60
64
  end
61
65
  end
66
+
67
+ raise "Operation not found: #{@op_node.name}"
62
68
  end
63
- end
64
69
 
65
- #noinspection RubyArgCount
66
- def serialize_soap_fault(ex)
67
- logger.debug "Serializing SOAP Fault: #{ex.inspect}"
70
+ def extract_parameters(node)
71
+ # TODO: use the metadata collected from the DSL to reoder the parameters and perform the appropriate conversions
72
+ node.children.map { |n| n.text }
73
+ end
68
74
 
69
- xb = Builder::XmlMarkup.new
70
- xb.instruct!
75
+ #noinspection RubyArgCount
76
+ def serialize_soap_result(op_options, r)
77
+ xb = Builder::XmlMarkup.new
78
+ xb.instruct!
71
79
 
72
- xb.Envelope :xmlns => namespaces['env'] do |xenv|
73
- xenv.Body do |xbody|
74
- xbody.Fault do |xf|
75
- xf.faultcode ex.class.name
76
- xf.faultstring ex.message
80
+ xb.Envelope :xmlns => soap_env_ns do |xenv|
81
+ xenv.Body do |xbody|
82
+ xbody.tag! "#{op_options[:public_name]}Response", :xmlns => namespaces['tns'] do |xres|
83
+ xres.body r
84
+ end
77
85
  end
78
86
  end
79
87
  end
88
+
89
+ #noinspection RubyArgCount
90
+ def serialize_soap_fault(ex)
91
+ logger.debug "Serializing SOAP Fault: #{ex.inspect}"
92
+
93
+ xb = Builder::XmlMarkup.new
94
+ xb.instruct!
95
+
96
+ xb.Envelope 'xmlns:e' => soap_env_ns do |xenv|
97
+ xenv.tag! 'e:Body' do |xbody|
98
+ xbody.tag! 'e:Fault' do |xf|
99
+ case soap_version
100
+ when :soap11
101
+ xf.faultcode "e:Server.#{ex.class.name}"
102
+ xf.faultstring ex.message
103
+ when :soap12
104
+ xf.tag! 'e:Code' do |xcode|
105
+ xcode.tag! 'e:Value', 'e:Receiver'
106
+ xcode.tag! 'e:Subcode' do |xsubcode|
107
+ xsubcode.tag! 'e:Value', ex.class.name
108
+ end
109
+ end
110
+ xf.tag! 'e:Reason', ex.message
111
+ else
112
+ raise "Unsupported SOAP version: #{soap_version}"
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ def soap_env_ns
120
+ case soap_version
121
+ when :soap11
122
+ namespaces['env']
123
+ when :soap12
124
+ namespaces['env12']
125
+ else
126
+ raise "Unrecognized SOAP version: #{soap_version}"
127
+ end
128
+ end
80
129
  end
81
130
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Shapewear
4
4
 
5
- Version = "0.1.0"
5
+ Version = "0.1.1"
6
6
 
7
7
  end
@@ -25,14 +25,25 @@ describe Shapewear do
25
25
  response.body[:echo_in_uppercase_response][:body].should == 'UPPERCASE TEXT'
26
26
  end
27
27
 
28
- it "should raise SOAP:Faults" do
28
+ it "should raise SOAP 1.1 Faults" do
29
29
  client = Savon::Client.new 'http://services.example.com/complete/soap/wsdl'
30
30
 
31
31
  expect {
32
32
  client.request :get_structured_data, :xmlns => 'http://services.example.com/v1' do
33
33
  soap.body = { :id => 55 }
34
34
  end
35
- }.to raise_error Savon::SOAP::Fault, "(RuntimeError) ID must be 0 or 1"
35
+ }.to raise_error Savon::SOAP::Fault, "(e:Server.RuntimeError) ID must be 0 or 1"
36
+ end
37
+
38
+ it "should raise SOAP 1.2 Faults" do
39
+ client = Savon::Client.new 'http://services.example.com/complete/soap/wsdl'
40
+
41
+ expect {
42
+ client.request :get_structured_data, :xmlns => 'http://services.example.com/v1' do
43
+ soap.version = 2
44
+ soap.body = { :id => 55 }
45
+ end
46
+ }.to raise_error Savon::SOAP::Fault, "(e:Server.RuntimeError) ID must be 0 or 1"
36
47
  end
37
48
  end
38
49
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shapewear
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 0
10
- version: 0.1.0
9
+ - 1
10
+ version: 0.1.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - "F\xC3\xA1bio Batista"