shapewear 0.1.0 → 0.1.1

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/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"