sinatra-soap-current 0.1.8
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 +7 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +120 -0
- data/Rakefile +6 -0
- data/examples/Gemfile +4 -0
- data/examples/app.rb +26 -0
- data/examples/client.rb +16 -0
- data/lib/sinatra/soap.rb +38 -0
- data/lib/sinatra/soap/dsl_methods.rb +11 -0
- data/lib/sinatra/soap/error.rb +5 -0
- data/lib/sinatra/soap/helper_methods.rb +68 -0
- data/lib/sinatra/soap/param.rb +181 -0
- data/lib/sinatra/soap/request.rb +63 -0
- data/lib/sinatra/soap/response.rb +13 -0
- data/lib/sinatra/soap/version.rb +5 -0
- data/lib/sinatra/soap/wsdl.rb +39 -0
- data/lib/sinatra/views/error.builder +10 -0
- data/lib/sinatra/views/response.builder +11 -0
- data/lib/sinatra/views/wsdl.builder +77 -0
- data/sinatra-soap.gemspec +32 -0
- data/spec/request_spec.rb +30 -0
- data/spec/soap_spec.rb +62 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/views/error.builder +10 -0
- data/spec/views/response.builder +11 -0
- data/spec/views/wsdl.builder +73 -0
- data/spec/wsdl_spec.rb +26 -0
- metadata +209 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 38b98a95ec28ca97366c1bd815ed35b50a2b0546
|
4
|
+
data.tar.gz: 145e978d20e525cef7887fb3bf45c7c0f5f3daa6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 17fe741df3d1bfbc0810f930b3b60c1001b9b4f9f5be032592b1729b217a4fd0795048fa7380198a406b2402f3f98869be06ce79603a0a5799f794aef092c912
|
7
|
+
data.tar.gz: 5db6d0bef29b7f61a33f33c1acb30f1c66295f43a59f8590214598a6bbf49bade640e62ff3b9692e38dad2ba745d89c597d1127807fb6efd61c2208e52f2c433
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Ivan Shamatov
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
# Sinatra::Soap
|
2
|
+
|
3
|
+
[](https://travis-ci.org/ejhayes/sinatra-soap) [](https://codeclimate.com/github/ejhayes/sinatra-soap/maintainability) [](http://badge.fury.io/rb/sinatra-soap-current)
|
4
|
+
|
5
|
+
Sinatra-soap gem makes task to create SOAP API really simple. Inspired by WashOut gem for Rails. But remember, the only reason why you should use SOAP is legacy code.
|
6
|
+
|
7
|
+
|
8
|
+
## Overview
|
9
|
+
|
10
|
+
In case of simplicity and quick first working release:
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
Add the following to your gemfile:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem 'sinatra-soap-current'
|
18
|
+
```
|
19
|
+
|
20
|
+
A classic application would work like that:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
require 'sinatra'
|
24
|
+
require 'sinatra/soap'
|
25
|
+
|
26
|
+
soap "SomeAction" do
|
27
|
+
do_something_with_params # hash to be returned
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
A modular application would look like that:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
require 'sinatra/base'
|
35
|
+
require 'sinatra/soap'
|
36
|
+
|
37
|
+
class SoapAPI < Sinatra::Base
|
38
|
+
|
39
|
+
#remember to register extenstion if you are using modular style
|
40
|
+
register Sinatra::Soap
|
41
|
+
|
42
|
+
soap "SomeAction" do
|
43
|
+
params # hash to be returned
|
44
|
+
end
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
|
49
|
+
## Settings
|
50
|
+
|
51
|
+
* **:wsdl_route** — url for getting wsdl, either static or dynamically generated file
|
52
|
+
```ruby
|
53
|
+
set :wsdl_route, '/wsdl'
|
54
|
+
```
|
55
|
+
Defines route for app to response with wsdl. Default is '/wsdl'
|
56
|
+
|
57
|
+
|
58
|
+
* **:endpoint** — url for sending SOAP Requests
|
59
|
+
```ruby
|
60
|
+
set :endpoint, '/action'
|
61
|
+
```
|
62
|
+
Defines route for SOAP Requests. Default is '/action'
|
63
|
+
|
64
|
+
|
65
|
+
* **:wsdl_file** — app will send static file, if this setting specified
|
66
|
+
```ruby
|
67
|
+
set :wsdl_file, "wsdl.xml"
|
68
|
+
```
|
69
|
+
If wsdl_file is set, app will try to read wsdl file from ```:public_folder``` (by default ./public directory). If file does not exist, app will raise an error. You also don't need to specify ```:namespace``` or ```:service``` if you want to serve static wsdl.
|
70
|
+
|
71
|
+
|
72
|
+
* **:namespace** — wsdl setting, required for generating wsdl
|
73
|
+
```ruby
|
74
|
+
set :namespace, "http://schemas.xmlsoap.org/wsdl/"
|
75
|
+
```
|
76
|
+
Namespace is taking it's place in ```xmlns:tns``` and ```targetNamespace``` definitions of SOAP Envelope
|
77
|
+
|
78
|
+
* **:service** — wsdl setting, required for generating wsdl
|
79
|
+
```ruby
|
80
|
+
set :service, "sinatra"
|
81
|
+
```
|
82
|
+
Service involved in ```portType```, ```binding``` and ```service``` definitions as a prefix for name attribute.
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
## Soap Arguments
|
88
|
+
|
89
|
+
If you want to be able to generate wsdl on a fly, you need to specify incoming and outgoing nodes with their types.
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
soap :test, in: {circle: {center: {x: :integer,
|
93
|
+
y: :integer},
|
94
|
+
radius: :double}
|
95
|
+
},
|
96
|
+
out: nil do
|
97
|
+
params #=> {circle: {center: {x: 3, y: 2}, radius: 12.0} }
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
The code above will respond to request like this:
|
103
|
+
```xml
|
104
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
105
|
+
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="anynamespacehere" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
|
106
|
+
<env:Body>
|
107
|
+
<wsdl:test>
|
108
|
+
<circle>
|
109
|
+
<center>
|
110
|
+
<x>3</x>
|
111
|
+
<y>2</y>
|
112
|
+
</center>
|
113
|
+
<radius>12.0</radius>
|
114
|
+
</circle>
|
115
|
+
</wsdl:test>
|
116
|
+
</env:Body>
|
117
|
+
</env:Envelope>
|
118
|
+
```
|
119
|
+
|
120
|
+
|
data/Rakefile
ADDED
data/examples/Gemfile
ADDED
data/examples/app.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'sinatra/soap'
|
3
|
+
|
4
|
+
class App < Sinatra::Base
|
5
|
+
register Sinatra::Soap
|
6
|
+
|
7
|
+
set :service, "sinatra"
|
8
|
+
set :namespace, "http://schemas.xmlsoap.org/wsdl/"
|
9
|
+
set :endpoint, '/action'
|
10
|
+
set :wsdl_route, '/wsdl'
|
11
|
+
|
12
|
+
#soap :test do
|
13
|
+
# params
|
14
|
+
#end
|
15
|
+
|
16
|
+
soap :test, in: { hello: :string }, out: nil do
|
17
|
+
params
|
18
|
+
end
|
19
|
+
|
20
|
+
soap :ObjectTest, in: { TestObject: { a: :string, b: :string }}, out: { hello: :string } do
|
21
|
+
params
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
end
|
26
|
+
App.run!
|
data/examples/client.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "savon"
|
2
|
+
|
3
|
+
#client = Savon.client do
|
4
|
+
# endpoint "http://127.0.0.1:4567/action"
|
5
|
+
# namespace "http://schemas.xmlsoap.org/wsdl/"
|
6
|
+
#end
|
7
|
+
|
8
|
+
|
9
|
+
client = Savon.client(wsdl: "http://127.0.0.1:4567/wsdl")
|
10
|
+
|
11
|
+
puts client.operations
|
12
|
+
|
13
|
+
puts client.call(:test, message: { :hello => :world })
|
14
|
+
puts client.call(:test, message: { :should => :fail })
|
15
|
+
|
16
|
+
|
data/lib/sinatra/soap.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require "sinatra/base"
|
2
|
+
require "sinatra/soap/version"
|
3
|
+
require "sinatra/soap/wsdl"
|
4
|
+
require "sinatra/soap/error"
|
5
|
+
require "sinatra/soap/dsl_methods"
|
6
|
+
require "sinatra/soap/helper_methods"
|
7
|
+
require "sinatra/soap/request"
|
8
|
+
require "sinatra/soap/response"
|
9
|
+
require "builder"
|
10
|
+
|
11
|
+
|
12
|
+
module Sinatra
|
13
|
+
module Soap
|
14
|
+
|
15
|
+
include DslMethods
|
16
|
+
|
17
|
+
def self.registered(app)
|
18
|
+
app.helpers Soap::HelperMethods
|
19
|
+
|
20
|
+
app.set :wsdl_route, '/wsdl' unless defined?(app.settings.wsdl_path)
|
21
|
+
app.set :namespace, 'http://schemas.xmlsoap.org/wsdl/' unless defined?(app.settings.namespace)
|
22
|
+
app.set :endpoint, '/action' unless defined?(app.settings.endpoint)
|
23
|
+
app.set :service, 'Sinatra' unless defined?(app.settings.service)
|
24
|
+
|
25
|
+
app.post(app.settings.endpoint) do
|
26
|
+
content_type 'text/xml'
|
27
|
+
call_action_block
|
28
|
+
end
|
29
|
+
|
30
|
+
app.get(app.settings.wsdl_route) do
|
31
|
+
content_type 'text/xml'
|
32
|
+
get_wsdl
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
Delegator.delegate :soap
|
37
|
+
register Soap
|
38
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative 'param'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module Soap
|
5
|
+
module HelperMethods
|
6
|
+
|
7
|
+
# Return the location where we can find our views
|
8
|
+
def soap_views()
|
9
|
+
File.join(File.dirname(__FILE__), "..", "views")
|
10
|
+
end
|
11
|
+
|
12
|
+
def call_action_block
|
13
|
+
request = Soap::Request.new(env, request, params)
|
14
|
+
response = request.execute
|
15
|
+
builder :response, locals: {wsdl: response.wsdl, params: response.params}, :views => self.soap_views
|
16
|
+
rescue Soap::Error => e
|
17
|
+
builder :error, locals: {e: e}, :views => self.soap_views
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_wsdl
|
21
|
+
if defined?(settings.wsdl_path)
|
22
|
+
path = File.join(settings.public_folder, settings.wsdl_path)
|
23
|
+
if File.exist?(path)
|
24
|
+
File.read(path)
|
25
|
+
else
|
26
|
+
raise "No wsdl file"
|
27
|
+
end
|
28
|
+
else
|
29
|
+
builder :wsdl, locals: {wsdl: Soap::Wsdl.actions}, :views => self.soap_views
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def wsdl_occurence(param, inject, extend_with = {})
|
34
|
+
param=Param.new(param[0], param[1])
|
35
|
+
extend_with = { :name => param.name, :type => param.namespaced_type }
|
36
|
+
data = !param.multiplied ? {} : {
|
37
|
+
"#{'xsi:' if inject}minOccurs" => 0,
|
38
|
+
"#{'xsi:' if inject}maxOccurs" => 'unbounded'
|
39
|
+
}
|
40
|
+
extend_with.merge(data)
|
41
|
+
end
|
42
|
+
|
43
|
+
def wsdl_type(xml, param, defined=[])
|
44
|
+
param = Param.new(param[0], param[1])
|
45
|
+
more = []
|
46
|
+
if param.struct?
|
47
|
+
if !defined.include?(param.basic_type)
|
48
|
+
xml.tag! "xsd:complexType", :name => param.basic_type do
|
49
|
+
xml.tag! "xsd:sequence" do
|
50
|
+
param.map.each do |value|
|
51
|
+
param_value = Param.new(value[0], value[1])
|
52
|
+
more << value if param_value.struct?
|
53
|
+
xml.tag! "xsd:element", wsdl_occurence(value, false)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
defined << param.basic_type
|
58
|
+
elsif !param.classified?
|
59
|
+
raise RuntimeError, "Duplicate use of `#{param.basic_type}` type name. Consider using classified types."
|
60
|
+
end
|
61
|
+
end
|
62
|
+
more.each do |p|
|
63
|
+
wsdl_type xml, p, defined
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module Soap
|
3
|
+
class Param
|
4
|
+
attr_accessor :raw_name
|
5
|
+
attr_accessor :name
|
6
|
+
attr_accessor :map
|
7
|
+
attr_accessor :type
|
8
|
+
attr_accessor :multiplied
|
9
|
+
attr_accessor :value
|
10
|
+
attr_accessor :source_class
|
11
|
+
|
12
|
+
def initialize(name, type, multiplied = false)
|
13
|
+
type ||= {}
|
14
|
+
@name = name.to_s
|
15
|
+
@raw_name = name.to_s
|
16
|
+
@map = {}
|
17
|
+
@multiplied = multiplied
|
18
|
+
|
19
|
+
if type.is_a?(Symbol)
|
20
|
+
@type = type.to_s
|
21
|
+
elsif type.is_a?(Class)
|
22
|
+
@type = 'struct'
|
23
|
+
@source_class = type
|
24
|
+
@map = type
|
25
|
+
else
|
26
|
+
@type = 'struct'
|
27
|
+
@map = type
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Converts a generic externally derived Ruby value, such as String or
|
32
|
+
# Hash, to a native Ruby object according to the definition of this type.
|
33
|
+
def load(data, key)
|
34
|
+
if !data.has_key? key
|
35
|
+
raise Error, "Required SOAP parameter '#{key}' is missing"
|
36
|
+
end
|
37
|
+
|
38
|
+
data = data[key]
|
39
|
+
data = [data] if @multiplied && !data.is_a?(Array)
|
40
|
+
|
41
|
+
if struct?
|
42
|
+
data ||= {}
|
43
|
+
if @multiplied
|
44
|
+
data.map do |x|
|
45
|
+
map_struct x do |param, dat, elem|
|
46
|
+
param.load(dat, elem)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
else
|
50
|
+
map_struct data do |param, dat, elem|
|
51
|
+
param.load(dat, elem)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
else
|
55
|
+
operation = case type
|
56
|
+
when 'string'; :to_s
|
57
|
+
when 'integer'; :to_i
|
58
|
+
when 'double'; :to_f
|
59
|
+
when 'boolean'; lambda{|dat| dat === "0" ? false : !!dat}
|
60
|
+
when 'date'; :to_date
|
61
|
+
when 'datetime'; :to_datetime
|
62
|
+
when 'time'; :to_time
|
63
|
+
when 'base64Binary'; lambda{|dat| Base64.decode64(dat)}
|
64
|
+
else raise RuntimeError, "Invalid WashOut simple type: #{type}"
|
65
|
+
end
|
66
|
+
|
67
|
+
begin
|
68
|
+
if data.nil?
|
69
|
+
data
|
70
|
+
elsif @multiplied
|
71
|
+
return data.map{|x| x.send(operation)} if operation.is_a?(Symbol)
|
72
|
+
return data.map{|x| operation.call(x)} if operation.is_a?(Proc)
|
73
|
+
elsif operation.is_a? Symbol
|
74
|
+
data.send(operation)
|
75
|
+
else
|
76
|
+
operation.call(data)
|
77
|
+
end
|
78
|
+
rescue
|
79
|
+
raise Error, "Invalid SOAP parameter '#{key}' format"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Checks if this Param defines a complex type.
|
85
|
+
def struct?
|
86
|
+
type == 'struct'
|
87
|
+
end
|
88
|
+
|
89
|
+
def classified?
|
90
|
+
!source_class.nil?
|
91
|
+
end
|
92
|
+
|
93
|
+
def basic_type
|
94
|
+
return name unless classified?
|
95
|
+
return source_class.wash_out_param_name(@soap_config)
|
96
|
+
end
|
97
|
+
|
98
|
+
def xsd_type
|
99
|
+
return 'int' if type.to_s == 'integer'
|
100
|
+
return 'dateTime' if type.to_s == 'datetime'
|
101
|
+
return type
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns a WSDL namespaced identifier for this type.
|
105
|
+
def namespaced_type
|
106
|
+
struct? ? "tns:#{basic_type}" : "xsd:#{xsd_type}"
|
107
|
+
end
|
108
|
+
|
109
|
+
# Parses a +definition+. The format of the definition is best described
|
110
|
+
# by the following BNF-like grammar.
|
111
|
+
#
|
112
|
+
# simple_type := :string | :integer | :double | :boolean
|
113
|
+
# nested_type := type_hash | simple_type | WashOut::Param instance
|
114
|
+
# type_hash := { :parameter_name => nested_type, ... }
|
115
|
+
# definition := [ WashOut::Param, ... ] |
|
116
|
+
# type_hash |
|
117
|
+
# simple_type
|
118
|
+
#
|
119
|
+
# If a simple type is passed as the +definition+, a single Param is returned
|
120
|
+
# with the +name+ set to "value".
|
121
|
+
# If a WashOut::Param instance is passed as a +nested_type+, the corresponding
|
122
|
+
# +:parameter_name+ is ignored.
|
123
|
+
#
|
124
|
+
# This function returns an array of WashOut::Param objects.
|
125
|
+
def self.parse_def(soap_config, definition)
|
126
|
+
raise RuntimeError, "[] should not be used in your params. Use nil if you want to mark empty set." if definition == []
|
127
|
+
return [] if definition == nil
|
128
|
+
|
129
|
+
if definition.is_a?(Class) && definition.ancestors.include?(WashOut::Type)
|
130
|
+
definition = definition.wash_out_param_map
|
131
|
+
end
|
132
|
+
|
133
|
+
if [Array, Symbol].include?(definition.class)
|
134
|
+
definition = { :value => definition }
|
135
|
+
end
|
136
|
+
|
137
|
+
if definition.is_a? Hash
|
138
|
+
definition.map do |name, opt|
|
139
|
+
if opt.is_a? WashOut::Param
|
140
|
+
opt
|
141
|
+
elsif opt.is_a? Array
|
142
|
+
WashOut::Param.new(soap_config, name, opt[0], true)
|
143
|
+
else
|
144
|
+
WashOut::Param.new(soap_config, name, opt)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
else
|
148
|
+
raise RuntimeError, "Wrong definition: #{definition.inspect}"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def flat_copy
|
153
|
+
copy = self.class.new(@soap_config, @name, @type.to_sym, @multiplied)
|
154
|
+
copy.raw_name = raw_name
|
155
|
+
copy.source_class = copy.source_class
|
156
|
+
copy
|
157
|
+
end
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
# Used to load an entire structure.
|
162
|
+
def map_struct(data)
|
163
|
+
unless data.is_a?(Hash)
|
164
|
+
raise Error, "SOAP message structure is broken"
|
165
|
+
end
|
166
|
+
|
167
|
+
data = data.with_indifferent_access
|
168
|
+
struct = {}.with_indifferent_access
|
169
|
+
|
170
|
+
# RUBY18 Enumerable#each_with_object is better, but 1.9 only.
|
171
|
+
@map.map do |param|
|
172
|
+
if data.has_key? param.raw_name
|
173
|
+
struct[param.raw_name] = yield param, data, param.raw_name
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
struct
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "nori"
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module Soap
|
5
|
+
class Request
|
6
|
+
|
7
|
+
attr_reader :wsdl, :action, :env, :request, :params
|
8
|
+
|
9
|
+
def initialize(env, request, params)
|
10
|
+
@env = env
|
11
|
+
@request = request
|
12
|
+
@params = params
|
13
|
+
parse_request
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def execute
|
18
|
+
request_block = wsdl.block
|
19
|
+
response_hash = self.instance_eval(&request_block)
|
20
|
+
Soap::Response.new(wsdl, response_hash)
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :orig_params, :params
|
24
|
+
|
25
|
+
def action
|
26
|
+
return orig_params[:action] unless orig_params[:action].nil?
|
27
|
+
orig_params[:action] = env['HTTP_SOAPACTION'].to_s.gsub(/^"(.*)"$/, '\1').to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def params
|
32
|
+
return orig_params[:soap] unless orig_params[:soap].nil?
|
33
|
+
rack_input = env["rack.input"].read
|
34
|
+
env["rack.input"].rewind
|
35
|
+
orig_params[:soap] = nori.parse(rack_input)[:Envelope][:Body][action]
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def wsdl
|
40
|
+
@wsdl = Soap::Wsdl.new(action)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def parse_request
|
46
|
+
action
|
47
|
+
params
|
48
|
+
end
|
49
|
+
|
50
|
+
def nori(snakecase=false)
|
51
|
+
Nori.new(
|
52
|
+
:strip_namespaces => true,
|
53
|
+
:advanced_typecasting => true,
|
54
|
+
:convert_tags_to => (
|
55
|
+
snakecase ? lambda { |tag| tag.snakecase.to_sym }
|
56
|
+
: lambda { |tag| tag.to_sym }
|
57
|
+
)
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module Soap
|
3
|
+
class Wsdl
|
4
|
+
|
5
|
+
@@actions = {}
|
6
|
+
|
7
|
+
def self.actions
|
8
|
+
@@actions
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.register(name, *args, &block)
|
12
|
+
@@actions[name] = {}
|
13
|
+
args = args.pop || {}
|
14
|
+
args.each do |key, value|
|
15
|
+
@@actions[name][key] = value || {}
|
16
|
+
end
|
17
|
+
@@actions[name][:block] = block if block_given?
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.generate
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_accessor :action, :block, :arguments
|
24
|
+
|
25
|
+
def initialize(action)
|
26
|
+
data = all[action]
|
27
|
+
raise Soap::Error, "Undefined Soap Action" if data.nil?
|
28
|
+
@action = action
|
29
|
+
@block = data[:block]
|
30
|
+
@arguments = data.select {|k,v| k != :block}
|
31
|
+
end
|
32
|
+
|
33
|
+
def all
|
34
|
+
@@actions
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
xml.instruct!
|
2
|
+
xml.tag! 'soap:Envelope', 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
3
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' do
|
4
|
+
xml.tag! 'soap:Body' do
|
5
|
+
xml.tag! 'soap:Fault', :encodingStyle => 'http://schemas.xmlsoap.org/soap/encoding/' do
|
6
|
+
xml.faultcode 'Client'
|
7
|
+
xml.faultstring e.message
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
xml.instruct!
|
2
|
+
xml.tag! 'soap:Envelope', 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
3
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' do
|
4
|
+
xml.tag! 'soap:Body' do
|
5
|
+
xml.tag! "soap:#{wsdl.action}Response" do
|
6
|
+
params.each do |key, value|
|
7
|
+
xml.tag! key, value
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
xml.instruct!
|
2
|
+
xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
|
3
|
+
'xmlns:tns' => settings.namespace,
|
4
|
+
'xmlns:soap' => 'http://schemas.xmlsoap.org/wsdl/soap/',
|
5
|
+
'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
|
6
|
+
'xmlns:soap-enc' => 'http://schemas.xmlsoap.org/soap/encoding/',
|
7
|
+
'xmlns:wsdl' => 'http://schemas.xmlsoap.org/wsdl/',
|
8
|
+
'name' => settings.service,
|
9
|
+
'targetNamespace' => settings.namespace do
|
10
|
+
|
11
|
+
xml.types do
|
12
|
+
xml.tag! "schema", :targetNamespace => settings.namespace, :xmlns => 'http://www.w3.org/2001/XMLSchema' do
|
13
|
+
defined = []
|
14
|
+
wsdl.each do |operation, formats|
|
15
|
+
formats[:in]||={}
|
16
|
+
formats[:out]||={}
|
17
|
+
formats[:in].each do |p|
|
18
|
+
wsdl_type xml, p, defined
|
19
|
+
end
|
20
|
+
formats[:out].each do |p|
|
21
|
+
wsdl_type xml, p, defined
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
xml.portType :name => "#{settings.service}_port" do
|
28
|
+
wsdl.keys.each do |operation|
|
29
|
+
xml.operation :name => operation do
|
30
|
+
xml.input :message => "tns:#{operation}"
|
31
|
+
xml.output :message => "tns:#{operation}Response"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
xml.binding :name => "#{settings.service}_binding", :type => "tns:#{settings.service}_port" do
|
37
|
+
xml.tag! "soap:binding", :style => 'document', :transport => 'http://schemas.xmlsoap.org/soap/http'
|
38
|
+
wsdl.keys.each do |operation|
|
39
|
+
xml.operation :name => operation do
|
40
|
+
xml.tag! "soap:operation", :soapAction => operation
|
41
|
+
xml.input do
|
42
|
+
xml.tag! "soap:body",
|
43
|
+
:use => "literal",
|
44
|
+
:namespace => settings.namespace
|
45
|
+
end
|
46
|
+
xml.output do
|
47
|
+
xml.tag! "soap:body",
|
48
|
+
:use => "literal",
|
49
|
+
:namespace => settings.namespace
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
xml.service :name => "service" do
|
56
|
+
xml.port :name => "#{settings.service}_port", :binding => "tns:#{settings.service}_binding" do
|
57
|
+
xml.tag! "soap:address", :location => "http://#{request.host_with_port}#{settings.endpoint}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
wsdl.each do |operation, formats|
|
62
|
+
xml.message :name => "#{operation}" do
|
63
|
+
formats[:in] ||= []
|
64
|
+
formats[:in].each do |p|
|
65
|
+
xml.part wsdl_occurence(p, false)
|
66
|
+
#, :name => param.name, :type => param.namespaced_type)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
xml.message :name => "#{operation}Response" do
|
70
|
+
formats[:out] ||= []
|
71
|
+
formats[:out].each do |p|
|
72
|
+
xml.part wsdl_occurence(p, false)
|
73
|
+
#, :name => param.name, :type => param.namespaced_type)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sinatra/soap/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sinatra-soap-current"
|
8
|
+
spec.version = Sinatra::Soap::VERSION
|
9
|
+
spec.authors = ["Ivan Shamatov"]
|
10
|
+
spec.email = ["eric@deployfx.com"]
|
11
|
+
spec.description = %q{Sinatra-soap gem makes task to create SOAP API really simple. Inspired by WashOut gem for Rails. But remember, the only reason why you should use SOAP is legacy code.}
|
12
|
+
spec.summary = %q{Handling SOAP requests for sinatra inspired by washout}
|
13
|
+
spec.homepage = "https://github.com/IvanShamatov/sinatra-soap"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rspec"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "rack-test"
|
25
|
+
spec.add_development_dependency "byebug"
|
26
|
+
|
27
|
+
|
28
|
+
spec.add_runtime_dependency "builder"
|
29
|
+
spec.add_runtime_dependency "sinatra"
|
30
|
+
spec.add_runtime_dependency "nori", ">= 2.0.0"
|
31
|
+
spec.add_runtime_dependency "nokogiri"
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Request" do
|
4
|
+
def app
|
5
|
+
SoapApp
|
6
|
+
end
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
headers = {"HTTP_SOAPACTION" => 'test'}
|
10
|
+
message = '<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="any" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Body><wsdl:test><par>one</par><par2>bar</par2><foo>wat</foo></wsdl:test></env:Body></env:Envelope>'
|
11
|
+
post '/action', message, headers
|
12
|
+
@request = Sinatra::Soap::Request.new(last_request.env, last_request, last_request.params)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should get soap_action" do
|
16
|
+
expect(@request.action).to eq(:test)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should get soap arguments" do
|
20
|
+
expect(@request.params).to eq({par: "one", par2: "bar", foo: "wat"})
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should build response" do
|
24
|
+
expect(@request.execute).to be_an_instance_of(Sinatra::Soap::Response)
|
25
|
+
end
|
26
|
+
|
27
|
+
#it "should validate input with WSDL" do
|
28
|
+
# pending
|
29
|
+
#end
|
30
|
+
end
|
data/spec/soap_spec.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe 'A default soap sinatra application' do
|
5
|
+
def app
|
6
|
+
SoapApp
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should parse soap request and send response" do
|
10
|
+
headers = {"HTTP_SOAPACTION" => 'test'}
|
11
|
+
message = '<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="any" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Body><wsdl:test><par>one</par><par2>bar</par2><foo>wat</foo></wsdl:test></env:Body></env:Envelope>'
|
12
|
+
post '/action', message, headers
|
13
|
+
response =<<-XML
|
14
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
15
|
+
<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">
|
16
|
+
<soap:Body>
|
17
|
+
<soap:testResponse>
|
18
|
+
<par>one</par>
|
19
|
+
<par2>bar</par2>
|
20
|
+
<foo>wat</foo>
|
21
|
+
</soap:testResponse>
|
22
|
+
</soap:Body>
|
23
|
+
</soap:Envelope>
|
24
|
+
XML
|
25
|
+
expect(last_response.body).to eq(response)
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
it "should raise soap fault on unknown action" do
|
30
|
+
headers = {"HTTP_SOAPACTION" => 'test2'}
|
31
|
+
message = '<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="any" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Body><wsdl:test><par>one</par><par2>bar</par2><foo>wat</foo></wsdl:test></env:Body></env:Envelope>'
|
32
|
+
post '/action', message, headers
|
33
|
+
response =<<-XML
|
34
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
35
|
+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
36
|
+
<soap:Body>
|
37
|
+
<soap:Fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
38
|
+
<faultcode>Client</faultcode>
|
39
|
+
<faultstring>Undefined Soap Action</faultstring>
|
40
|
+
</soap:Fault>
|
41
|
+
</soap:Body>
|
42
|
+
</soap:Envelope>
|
43
|
+
XML
|
44
|
+
expect(last_response.body).to eq(response)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should have endpoint for soap actions" do
|
48
|
+
endpoint = app.routes["POST"].select {|k| k[0].to_s.match('action')}.count
|
49
|
+
expect(endpoint).to eq 1
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should have route for wsdl" do
|
53
|
+
wsdl = app.routes["GET"].select {|k| k[0].to_s.match('wsdl')}.count
|
54
|
+
expect(wsdl).to eq(1)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return a usable soap views directory" do
|
58
|
+
view_search = File.join(app.views, "*.builder")
|
59
|
+
expect(Dir.glob(view_search).count).to be > 0
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
ENV['RACK_ENV'] = 'test'
|
2
|
+
require File.join(File.join(File.expand_path(File.dirname(__FILE__))), '..', 'lib', 'sinatra', 'soap')
|
3
|
+
require 'rspec'
|
4
|
+
require 'rack/test'
|
5
|
+
|
6
|
+
class SoapApp < Sinatra::Base
|
7
|
+
register Sinatra::Soap
|
8
|
+
soap :test do
|
9
|
+
params
|
10
|
+
end
|
11
|
+
|
12
|
+
soap :add_circle, in: {circle: {center: {x: :integer, y: :integer},
|
13
|
+
radius: :double}},
|
14
|
+
out: nil do
|
15
|
+
params #=> {circle: {center: {x: 3, y: 2}, radius: 12.0} }
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module RSpecMixin
|
21
|
+
include Rack::Test::Methods
|
22
|
+
end
|
23
|
+
|
24
|
+
RSpec.configure { |c| c.include RSpecMixin }
|
@@ -0,0 +1,10 @@
|
|
1
|
+
xml.instruct!
|
2
|
+
xml.tag! 'soap:Envelope', 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
3
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' do
|
4
|
+
xml.tag! 'soap:Body' do
|
5
|
+
xml.tag! 'soap:Fault', :encodingStyle => 'http://schemas.xmlsoap.org/soap/encoding/' do
|
6
|
+
xml.faultcode 'Client'
|
7
|
+
xml.faultstring e.message
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
xml.instruct!
|
2
|
+
xml.tag! 'soap:Envelope', 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
3
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' do
|
4
|
+
xml.tag! 'soap:Body' do
|
5
|
+
xml.tag! "soap:#{wsdl.action}Response" do
|
6
|
+
params.each do |key, value|
|
7
|
+
xml.tag! key, value
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
xml.instruct!
|
2
|
+
xml.definitions 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
|
3
|
+
'xmlns:tns' => settings.namespace,
|
4
|
+
'xmlns:soap' => 'http://schemas.xmlsoap.org/wsdl/soap/',
|
5
|
+
'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
|
6
|
+
'xmlns:soap-enc' => 'http://schemas.xmlsoap.org/soap/encoding/',
|
7
|
+
'xmlns:wsdl' => 'http://schemas.xmlsoap.org/wsdl/',
|
8
|
+
'name' => settings.service,
|
9
|
+
'targetNamespace' => settings.namespace do
|
10
|
+
|
11
|
+
xml.types do
|
12
|
+
xml.tag! "schema", :targetNamespace => settings.namespace, :xmlns => 'http://www.w3.org/2001/XMLSchema' do
|
13
|
+
defined = []
|
14
|
+
wsdl.each do |operation, formats|
|
15
|
+
formats[:in]||={}
|
16
|
+
formats[:out]||={}
|
17
|
+
formats[:in].each do |p|
|
18
|
+
wsdl_type xml, p, defined
|
19
|
+
end
|
20
|
+
formats[:out].each do |p|
|
21
|
+
wsdl_type xml, p, defined
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
xml.portType :name => "#{settings.service}_port" do
|
28
|
+
wsdl.keys.each do |operation|
|
29
|
+
xml.operation :name => operation do
|
30
|
+
xml.input :message => "tns:#{operation}"
|
31
|
+
xml.output :message => "tns:#{operation}Response"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
xml.binding :name => "#{settings.service}_binding", :type => "tns:#{settings.service}_port" do
|
37
|
+
xml.tag! "soap:binding", :style => 'document', :transport => 'http://schemas.xmlsoap.org/soap/http'
|
38
|
+
wsdl.keys.each do |operation|
|
39
|
+
xml.operation :name => operation do
|
40
|
+
xml.tag! "soap:operation", :soapAction => operation
|
41
|
+
xml.input do
|
42
|
+
xml.tag! "soap:body",
|
43
|
+
:use => "literal",
|
44
|
+
:namespace => settings.namespace
|
45
|
+
end
|
46
|
+
xml.output do
|
47
|
+
xml.tag! "soap:body",
|
48
|
+
:use => "literal",
|
49
|
+
:namespace => settings.namespace
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
xml.service :name => "service" do
|
56
|
+
xml.port :name => "#{settings.service}_port", :binding => "tns:#{settings.service}_binding" do
|
57
|
+
xml.tag! "soap:address", :location => send("#{settings.service}_action_url")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
wsdl.each do |operation, formats|
|
62
|
+
xml.message :name => "#{operation}" do
|
63
|
+
formats[:in].each do |p|
|
64
|
+
xml.part wsdl_occurence(p, false, :name => p.name, :type => p.namespaced_type)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
xml.message :name => "#{operation}Response}" do
|
68
|
+
formats[:out].each do |p|
|
69
|
+
xml.part wsdl_occurence(p, false, :name => p.name, :type => p.namespaced_type)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/spec/wsdl_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe "WSDL" do
|
5
|
+
|
6
|
+
def wsdl
|
7
|
+
Sinatra::Soap::Wsdl
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should hold registered actions with arguments and blocks" do
|
11
|
+
[:test, :add_circle].each do |action|
|
12
|
+
expect(wsdl.actions).to include(action)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should hold blocks for registered actions" do
|
17
|
+
[:test, :add_circle].each do |action|
|
18
|
+
expect(wsdl.actions[action]).to include(:block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should hould arguments types" do
|
23
|
+
expect(wsdl.actions[:add_circle]).to include(:in)
|
24
|
+
expect(wsdl.actions[:add_circle]).to include(:out)
|
25
|
+
end
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,209 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-soap-current
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.8
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ivan Shamatov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-10-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rack-test
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: builder
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: sinatra
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: nori
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 2.0.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 2.0.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: nokogiri
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: Sinatra-soap gem makes task to create SOAP API really simple. Inspired
|
140
|
+
by WashOut gem for Rails. But remember, the only reason why you should use SOAP
|
141
|
+
is legacy code.
|
142
|
+
email:
|
143
|
+
- eric@deployfx.com
|
144
|
+
executables: []
|
145
|
+
extensions: []
|
146
|
+
extra_rdoc_files: []
|
147
|
+
files:
|
148
|
+
- ".gitignore"
|
149
|
+
- ".rspec"
|
150
|
+
- ".travis.yml"
|
151
|
+
- Gemfile
|
152
|
+
- LICENSE.txt
|
153
|
+
- README.md
|
154
|
+
- Rakefile
|
155
|
+
- examples/Gemfile
|
156
|
+
- examples/app.rb
|
157
|
+
- examples/client.rb
|
158
|
+
- lib/sinatra/soap.rb
|
159
|
+
- lib/sinatra/soap/dsl_methods.rb
|
160
|
+
- lib/sinatra/soap/error.rb
|
161
|
+
- lib/sinatra/soap/helper_methods.rb
|
162
|
+
- lib/sinatra/soap/param.rb
|
163
|
+
- lib/sinatra/soap/request.rb
|
164
|
+
- lib/sinatra/soap/response.rb
|
165
|
+
- lib/sinatra/soap/version.rb
|
166
|
+
- lib/sinatra/soap/wsdl.rb
|
167
|
+
- lib/sinatra/views/error.builder
|
168
|
+
- lib/sinatra/views/response.builder
|
169
|
+
- lib/sinatra/views/wsdl.builder
|
170
|
+
- sinatra-soap.gemspec
|
171
|
+
- spec/request_spec.rb
|
172
|
+
- spec/soap_spec.rb
|
173
|
+
- spec/spec_helper.rb
|
174
|
+
- spec/views/error.builder
|
175
|
+
- spec/views/response.builder
|
176
|
+
- spec/views/wsdl.builder
|
177
|
+
- spec/wsdl_spec.rb
|
178
|
+
homepage: https://github.com/IvanShamatov/sinatra-soap
|
179
|
+
licenses:
|
180
|
+
- MIT
|
181
|
+
metadata: {}
|
182
|
+
post_install_message:
|
183
|
+
rdoc_options: []
|
184
|
+
require_paths:
|
185
|
+
- lib
|
186
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
187
|
+
requirements:
|
188
|
+
- - ">="
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: '0'
|
191
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - ">="
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: '0'
|
196
|
+
requirements: []
|
197
|
+
rubyforge_project:
|
198
|
+
rubygems_version: 2.5.2
|
199
|
+
signing_key:
|
200
|
+
specification_version: 4
|
201
|
+
summary: Handling SOAP requests for sinatra inspired by washout
|
202
|
+
test_files:
|
203
|
+
- spec/request_spec.rb
|
204
|
+
- spec/soap_spec.rb
|
205
|
+
- spec/spec_helper.rb
|
206
|
+
- spec/views/error.builder
|
207
|
+
- spec/views/response.builder
|
208
|
+
- spec/views/wsdl.builder
|
209
|
+
- spec/wsdl_spec.rb
|