diesel-api-dsl 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/Rakefile +5 -0
- data/diesel.gemspec +4 -0
- data/lib/diesel.rb +13 -5
- data/lib/diesel/api_base.rb +27 -0
- data/lib/diesel/api_builder.rb +98 -34
- data/lib/diesel/api_error.rb +3 -0
- data/lib/diesel/api_group.rb +27 -0
- data/lib/diesel/data_model.rb +24 -0
- data/lib/diesel/endpoint.rb +15 -33
- data/lib/diesel/middleware/auth/api_key.rb +27 -0
- data/lib/diesel/middleware/debug.rb +20 -0
- data/lib/diesel/middleware/set_body_parameter.rb +11 -0
- data/lib/diesel/middleware/set_header.rb +15 -0
- data/lib/diesel/middleware/set_parameter_base.rb +33 -0
- data/lib/diesel/middleware/set_path_parameter.rb +17 -0
- data/lib/diesel/middleware/set_query_parameter.rb +13 -0
- data/lib/diesel/middleware_builder.rb +15 -0
- data/lib/diesel/middleware_stack.rb +21 -0
- data/lib/diesel/request_context.rb +40 -15
- data/lib/diesel/swagger/data_type_field.rb +25 -0
- data/lib/diesel/swagger/definition.rb +12 -0
- data/lib/diesel/swagger/external_docs.rb +10 -0
- data/lib/diesel/swagger/info.rb +14 -0
- data/lib/diesel/swagger/node.rb +140 -0
- data/lib/diesel/swagger/operation.rb +22 -0
- data/lib/diesel/swagger/parameter.rb +32 -0
- data/lib/diesel/swagger/parser.rb +70 -0
- data/lib/diesel/swagger/path.rb +27 -0
- data/lib/diesel/swagger/property.rb +8 -0
- data/lib/diesel/swagger/security_definition.rb +15 -0
- data/lib/diesel/swagger/specification.rb +30 -0
- data/lib/diesel/utils/inflections.rb +46 -0
- data/lib/diesel/version.rb +1 -1
- data/spec/diesel/api_builder_spec.rb +14 -0
- data/spec/diesel/swagger/parser_spec.rb +80 -0
- data/spec/diesel_spec.rb +43 -0
- data/spec/files/honeybadger.json +80 -0
- data/spec/files/pivotal_tracker.json +94 -0
- data/spec/fixtures/vcr_cassettes/honeybadger.yml +98 -0
- data/spec/fixtures/vcr_cassettes/pivotal_tracker_create_story.yml +61 -0
- data/spec/spec_helper.rb +10 -0
- metadata +110 -25
- data/apis/pivotal_tracker.rb +0 -55
- data/examples/create_pivotal_task.rb +0 -13
- data/lib/diesel/action/http.rb +0 -92
- data/lib/diesel/api.rb +0 -33
- data/lib/diesel/auth/api_key.rb +0 -39
- data/lib/diesel/auth/base.rb +0 -8
- data/lib/diesel/auth/oauth2.rb +0 -13
- data/lib/diesel/authenticator.rb +0 -35
- data/lib/diesel/complex_type_builder.rb +0 -24
- data/lib/diesel/container_builder.rb +0 -6
- data/lib/diesel/dsl.rb +0 -239
- data/lib/diesel/model_builder.rb +0 -9
- data/lib/diesel/profile.rb +0 -112
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ODhkYmQ4ZDFjMTBjZjZiMTUxMDU4NTI4NjhkMzQ5NTUzODg5OGQxNA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4c09f2251953d171164fa4883b9aad83e9a1d7d9
|
4
|
+
data.tar.gz: 7c885dc69abd71c3e3c897e20bfcbf5ca141c166
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
OWZlZjExOTA4NjRiN2E0MjZiZmE5N2JiYzJjMjFkMGQ1NWI5ZTQ0OGM0YTZk
|
11
|
-
M2M5MTk3ZWRiYzk1YTIxNTQ3ZDU2NzQ3MjQ2YjNmNDYyYWQ1ZmQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NjhlOGZkZTg2ODhiYmNkYjQ5MmYwZjVjYTRjOWZkNjhhZTI5NjZlMTUyYzhj
|
14
|
-
NjlhMzkyNTljZDQ1Y2IzZWM1YmRmODVlNzdlNDBkMmNjZWYyZmJlNjdhMzU1
|
15
|
-
MDJiYjk2NDFhNThhNTkzZTIwODRkYjE1Nzc4MTJhODgyZjQ4Yzc=
|
6
|
+
metadata.gz: 8347d51bde9ca019c77d813ce453199603736228b00e69294bc4af670959101b978218d39bf18ef1f7b04afdfe2483d7b2fae19eb9bde26f51c528592d442496
|
7
|
+
data.tar.gz: b67551247eab1cde0aa09fb14f34f60e1d6e4824d1d4016eae690d3f34d92662b1d2e738e032a81b33295151a59613e021ba43d5ae0d7135c857093f9d86f1ba
|
data/Rakefile
CHANGED
data/diesel.gemspec
CHANGED
@@ -20,6 +20,10 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
22
|
spec.add_development_dependency "rake", "~> 10.1"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.0.0"
|
24
|
+
spec.add_development_dependency "vcr", "~> 2.9.0"
|
25
|
+
spec.add_development_dependency "webmock", "~> 1.20.0"
|
23
26
|
|
24
27
|
spec.add_dependency "httparty", "~> 0.12"
|
28
|
+
spec.add_dependency "multi_json", "~> 1.10.1"
|
25
29
|
end
|
data/lib/diesel.rb
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
-
require
|
2
|
-
require 'diesel/
|
1
|
+
require 'diesel/version'
|
2
|
+
require 'diesel/swagger/parser'
|
3
3
|
require 'diesel/api_builder'
|
4
4
|
|
5
|
+
|
5
6
|
module Diesel
|
6
|
-
def self.
|
7
|
-
|
8
|
-
|
7
|
+
def self.parse_specification(path)
|
8
|
+
Diesel::Swagger::Parser.new.parse(File.read(path))
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.build_api(specification)
|
12
|
+
Diesel::APIBuilder.new(specification).build
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.load_api(path)
|
16
|
+
build_api(parse_specification(path))
|
9
17
|
end
|
10
18
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'diesel/api_group'
|
2
|
+
|
3
|
+
module Diesel
|
4
|
+
class APIError < Exception; end
|
5
|
+
end
|
6
|
+
|
7
|
+
module Diesel
|
8
|
+
class APIBase
|
9
|
+
attr_accessor :logger, :options
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def logger=(logger)
|
16
|
+
@logger = logger
|
17
|
+
self.class.api_groups.each { |g| g.logger = logger }
|
18
|
+
end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def api_groups; @api_groups ||= []; end
|
22
|
+
def api_groups=(api_groups)
|
23
|
+
@api_groups = api_groups
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/diesel/api_builder.rb
CHANGED
@@ -1,61 +1,125 @@
|
|
1
|
-
require 'diesel/
|
2
|
-
require 'diesel/
|
3
|
-
require 'diesel/
|
1
|
+
require 'diesel/api_error'
|
2
|
+
require 'diesel/utils/inflections'
|
3
|
+
require 'diesel/api_base'
|
4
|
+
require 'diesel/data_model'
|
5
|
+
|
6
|
+
require 'diesel/middleware/debug'
|
7
|
+
require 'diesel/middleware/set_header'
|
4
8
|
|
5
9
|
module Diesel
|
6
10
|
class APIBuilder
|
7
|
-
|
11
|
+
include Diesel::Utils::Inflections
|
12
|
+
|
13
|
+
attr_reader :specification
|
8
14
|
|
9
|
-
def initialize(
|
10
|
-
@
|
15
|
+
def initialize(specification)
|
16
|
+
@specification = specification
|
11
17
|
end
|
12
18
|
|
13
19
|
def build
|
20
|
+
validate!
|
21
|
+
|
14
22
|
create_api_class.tap do |klass|
|
15
|
-
klass.
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
23
|
+
klass.api_groups = [
|
24
|
+
APIGroup.new.tap do |group|
|
25
|
+
group.endpoints = build_endpoints
|
26
|
+
group.endpoints.each do |endpoint|
|
27
|
+
klass.send(:define_method, endpoint.name.to_sym) do |parameters|
|
28
|
+
group.execute(self.options, endpoint, parameters)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
]
|
33
|
+
|
21
34
|
#Diesel.const_set create_class_name(name), klass
|
22
35
|
end
|
23
36
|
end
|
24
37
|
|
25
38
|
protected
|
26
|
-
|
27
|
-
|
39
|
+
|
40
|
+
def validate!
|
41
|
+
api_errors = specification.collect_errors
|
42
|
+
if api_errors.any?
|
43
|
+
raise APIError, "API specification is invalid: \n #{api_errors.join("\n")}"
|
44
|
+
end
|
28
45
|
end
|
29
46
|
|
30
47
|
def create_api_class
|
31
|
-
Class.new(Diesel::
|
48
|
+
Class.new(Diesel::APIBase)
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_endpoint_url(specification, path)
|
52
|
+
base_path = specification.base_path.chomp('/')
|
53
|
+
resource_path = path.sub(/^([^\/])/, '/\1').chomp('/')
|
54
|
+
[
|
55
|
+
specification.schemes.first,
|
56
|
+
'://',
|
57
|
+
specification.host,
|
58
|
+
base_path,
|
59
|
+
resource_path
|
60
|
+
].join('')
|
32
61
|
end
|
33
62
|
|
34
|
-
def build_endpoints
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
63
|
+
def build_endpoints
|
64
|
+
spec = specification
|
65
|
+
data_models = self.data_models
|
66
|
+
|
67
|
+
spec.paths.map do |path, path_model|
|
68
|
+
path_model.operations_map.map do |(method, operation)|
|
69
|
+
endpoint_name = underscore(operation.operation_id)
|
70
|
+
endpoint_url = build_endpoint_url(spec, path)
|
71
|
+
|
72
|
+
Diesel::Endpoint.new(endpoint_name, endpoint_url, method).tap do |endpoint|
|
73
|
+
endpoint.config_middleware do
|
74
|
+
use Diesel::Middleware::Debug
|
75
|
+
|
76
|
+
if spec.produces.any?
|
77
|
+
use Diesel::Middleware::SetHeader, 'Content-Type' => spec.produces.first
|
78
|
+
end
|
79
|
+
|
80
|
+
spec.security_definitions.each_pair do |name, security_def|
|
81
|
+
case security_def.type
|
82
|
+
when 'apiKey'
|
83
|
+
require 'diesel/middleware/auth/api_key'
|
84
|
+
use Diesel::Middleware::Auth::APIKey,
|
85
|
+
id: Diesel::Utils::Inflections.underscore(name).to_sym,
|
86
|
+
in: security_def.in,
|
87
|
+
name: security_def.name
|
88
|
+
else
|
89
|
+
raise APIError, "Unsupported security definition: #{security_def.type}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
operation.parameters.each do |parameter|
|
94
|
+
param_class_path = "diesel/middleware/set_#{parameter.in}_parameter"
|
95
|
+
require param_class_path
|
96
|
+
param_class_name = Diesel::Utils::Inflections.camelize(param_class_path)
|
97
|
+
param_class = Diesel::Utils::Inflections.constantize(param_class_name)
|
98
|
+
middleware_opts = {name: parameter.name}
|
99
|
+
if parameter.schema?
|
100
|
+
unless schema = data_models[parameter.schema]
|
101
|
+
raise APIError, "Unspecified schema: #{parameter.schema}"
|
102
|
+
end
|
103
|
+
middleware_opts[:schema] = schema
|
104
|
+
end
|
105
|
+
use param_class, middleware_opts
|
106
|
+
end
|
107
|
+
|
45
108
|
end
|
46
109
|
end
|
47
110
|
end
|
48
111
|
end.flatten.compact
|
49
112
|
end
|
50
113
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
114
|
+
def data_models
|
115
|
+
@data_models ||= build_data_models
|
116
|
+
end
|
117
|
+
|
118
|
+
def build_data_models
|
119
|
+
specification.definitions.reduce({}) do |m, (name, definition)|
|
120
|
+
m[name] = DataModel.new(definition)
|
121
|
+
m
|
122
|
+
end
|
59
123
|
end
|
60
124
|
|
61
125
|
def create_class_name(name)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'diesel/request_context'
|
2
|
+
require 'diesel/endpoint'
|
3
|
+
|
4
|
+
module Diesel
|
5
|
+
class APIGroup
|
6
|
+
attr_accessor :logger
|
7
|
+
|
8
|
+
def endpoints; @endpoints ||= []; end
|
9
|
+
def endpoints=(endpoints)
|
10
|
+
@endpoints = endpoints
|
11
|
+
end
|
12
|
+
|
13
|
+
def authenticators; @authenticators; end
|
14
|
+
def authenticators=(auth)
|
15
|
+
@authenticators = auth
|
16
|
+
end
|
17
|
+
|
18
|
+
def data_models; @data_models ||= {}; end
|
19
|
+
def data_models=(data_models)
|
20
|
+
@data_models = data_models
|
21
|
+
end
|
22
|
+
|
23
|
+
def execute(options, endpoint, parameters)
|
24
|
+
RequestContext.new(options, self, endpoint, parameters).perform
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
|
3
|
+
module Diesel
|
4
|
+
class DataModel
|
5
|
+
attr_reader :definition
|
6
|
+
|
7
|
+
def initialize(definition)
|
8
|
+
@definition = definition
|
9
|
+
end
|
10
|
+
|
11
|
+
def build(parameter_name, env)
|
12
|
+
context = env[:context]
|
13
|
+
h = context.get_attribute(parameter_name)
|
14
|
+
return nil unless h
|
15
|
+
|
16
|
+
json = definition.properties.reduce({}) do |m, (name, property)|
|
17
|
+
name = name.to_sym
|
18
|
+
m[name] = h[name] if h[name]; m
|
19
|
+
end
|
20
|
+
|
21
|
+
MultiJson.dump(json)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/diesel/endpoint.rb
CHANGED
@@ -1,43 +1,25 @@
|
|
1
|
+
require 'diesel/middleware_builder'
|
2
|
+
require 'diesel/middleware_stack'
|
3
|
+
|
1
4
|
module Diesel
|
2
5
|
class Endpoint
|
3
|
-
attr_reader :
|
4
|
-
attr_accessor :action
|
6
|
+
attr_reader :name, :url, :request_method
|
5
7
|
|
6
|
-
def initialize(
|
7
|
-
@
|
8
|
+
def initialize(name, url, request_method)
|
9
|
+
@name, @url, @request_method = name, url, request_method
|
8
10
|
end
|
9
11
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
13
|
-
assert_attributes(context)
|
14
|
-
|
15
|
-
#unless action.accept? context
|
16
|
-
# raise 'endpoint does not support this context'
|
17
|
-
#end
|
18
|
-
|
19
|
-
action.perform(context)
|
12
|
+
def middlewares
|
13
|
+
@middlewares ||= []
|
20
14
|
end
|
21
15
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
# unless context.attributes.empty?
|
26
|
-
# raise ArgumentError, "invalid attributes #{atts.keys.join(', ')}"
|
27
|
-
# end
|
28
|
-
# return
|
29
|
-
#end
|
30
|
-
|
31
|
-
#invalid_atts = context.attributes.keys.map!(&:intern) - attributes.keys
|
32
|
-
#unless invalid_atts.empty?
|
33
|
-
# raise ArgumentError, "invalid attributes #{invalid_atts.join(', ')}"
|
34
|
-
#end
|
16
|
+
def middleware_stack
|
17
|
+
@middleware_stack ||= MiddlewareStack.new(middlewares)
|
18
|
+
end
|
35
19
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
#end
|
41
|
-
end
|
20
|
+
def config_middleware(&block)
|
21
|
+
builder = MiddlewareBuilder.new(middlewares)
|
22
|
+
builder.build(&block)
|
23
|
+
end
|
42
24
|
end
|
43
25
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Diesel
|
2
|
+
module Middleware
|
3
|
+
module Auth
|
4
|
+
class APIKey
|
5
|
+
|
6
|
+
def initialize(app, options)
|
7
|
+
@app = app
|
8
|
+
@id = options[:id]
|
9
|
+
@in = options[:in]
|
10
|
+
@name = options[:name]
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
context = env[:context]
|
15
|
+
value = context.options[@id]
|
16
|
+
if @in == :header
|
17
|
+
env[:request_headers][@name] = value
|
18
|
+
elsif @in == :query
|
19
|
+
env[:params][@name] = value
|
20
|
+
end
|
21
|
+
@app.call(env)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Diesel
|
2
|
+
module Middleware
|
3
|
+
class Debug
|
4
|
+
def initialize(app)
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
def call(env)
|
8
|
+
@app.call(env)
|
9
|
+
logger = env[:logger]
|
10
|
+
if logger && logger.debug?
|
11
|
+
logger.debug("Request Method: #{env[:method]}")
|
12
|
+
logger.debug("URL: #{env[:url]}")
|
13
|
+
logger.debug("Request Headers: #{env[:request_headers].inspect}")
|
14
|
+
logger.debug("Params: #{env[:params].inspect}")
|
15
|
+
logger.debug("Body: #{env[:body]}")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|