bodhi-slam 0.0.5 → 0.1.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/lib/bodhi-slam.rb +13 -109
- data/lib/bodhi-slam/context.rb +37 -51
- data/lib/bodhi-slam/enumerations.rb +35 -0
- data/lib/bodhi-slam/errors.rb +81 -4
- data/lib/bodhi-slam/resource.rb +201 -64
- data/lib/bodhi-slam/types.rb +191 -0
- data/lib/bodhi-slam/validations.rb +141 -0
- data/lib/bodhi-slam/validators.rb +60 -0
- data/lib/bodhi-slam/validators/blank.rb +24 -0
- data/lib/bodhi-slam/validators/email.rb +24 -0
- data/lib/bodhi-slam/validators/matches.rb +27 -0
- data/lib/bodhi-slam/validators/max.rb +27 -0
- data/lib/bodhi-slam/validators/min.rb +27 -0
- data/lib/bodhi-slam/validators/multi.rb +14 -0
- data/lib/bodhi-slam/validators/not_empty.rb +20 -0
- data/lib/bodhi-slam/validators/required.rb +14 -0
- data/lib/bodhi-slam/validators/type.rb +123 -0
- data/lib/bodhi-slam/validators/url.rb +24 -0
- metadata +61 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ca91de0d49a0aa3ff8e084024cdc6114444814e
|
4
|
+
data.tar.gz: a7d550040d2b4e705ab10c7a0a6a8929aff7b967
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e9231701b099974ee34f0708740e3882743677861153b82a0c996e218b9be6b66fbb638248af82a204abc1b2ffd7bbaa1a8b7055c78b62dc208203f2d8fe058
|
7
|
+
data.tar.gz: a4cc9b671833cf91bb0524d5bc4bd608a33d276f8f7aaa5e93eb00c86f853595675bfd366380704bb59f80a195829358458e7e9a482924d1aed6c7d6fc7be420
|
data/lib/bodhi-slam.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "faraday"
|
2
|
+
require 'net/http/persistent'
|
2
3
|
require "factory_girl"
|
3
4
|
require "json"
|
4
5
|
require "time"
|
@@ -6,10 +7,13 @@ require "time"
|
|
6
7
|
require 'bodhi-slam/context'
|
7
8
|
require 'bodhi-slam/errors'
|
8
9
|
require 'bodhi-slam/resource'
|
10
|
+
require 'bodhi-slam/types'
|
11
|
+
require 'bodhi-slam/validations'
|
12
|
+
require 'bodhi-slam/enumerations'
|
9
13
|
|
10
14
|
class BodhiSlam
|
11
15
|
def self.context(params, &block)
|
12
|
-
bodhi_context =
|
16
|
+
bodhi_context = Bodhi::Context.new params
|
13
17
|
raise bodhi_context.errors unless bodhi_context.valid?
|
14
18
|
|
15
19
|
#puts "Switching context to: #{bodhi_context.attributes}"
|
@@ -19,116 +23,16 @@ class BodhiSlam
|
|
19
23
|
|
20
24
|
def self.analyze(context)
|
21
25
|
raise context.errors unless context.valid?
|
22
|
-
|
23
|
-
#Get the types for this namespace
|
24
|
-
result = context.connection.get do |request|
|
25
|
-
request.url "/#{context.namespace}/types"
|
26
|
-
request.headers[context.credentials_header] = context.credentials
|
27
|
-
end
|
28
|
-
|
29
|
-
if result.status != 200
|
30
|
-
errors = JSON.parse result.body
|
31
|
-
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
32
|
-
errors["status"] = result.status if errors.is_a? Hash
|
33
|
-
raise errors.to_s
|
34
|
-
end
|
35
|
-
types = JSON.parse(result.body)
|
36
|
-
|
37
|
-
#Get the enumerations for this namespace
|
38
|
-
result = context.connection.get do |request|
|
39
|
-
request.url "/#{context.namespace}/enums"
|
40
|
-
request.headers[context.credentials_header] = context.credentials
|
41
|
-
end
|
42
|
-
|
43
|
-
if result.status != 200
|
44
|
-
errors = JSON.parse result.body
|
45
|
-
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
46
|
-
errors["status"] = result.status if errors.is_a? Hash
|
47
|
-
raise errors.to_s
|
48
|
-
end
|
49
|
-
enumerations = JSON.parse(result.body)
|
50
|
-
|
51
|
-
embedded_types = types.select{ |type| type["embedded"] }
|
52
|
-
normal_types = types.select{ |type| !type["embedded"] }
|
53
|
-
|
54
|
-
embedded_types.each{ |type| create_type(type, enumerations) }
|
55
|
-
normal_types.each{ |type| create_type(type, enumerations) }
|
56
26
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
# - Create a BodhiResource from the given type definition and enumerations
|
61
|
-
def self.create_type(type, enumerations)
|
62
|
-
if type["package"] != "system"
|
63
|
-
properties = type["properties"].keys.collect{ |key| key.to_sym }
|
64
|
-
klass = Object.const_set(type["name"], Class.new {
|
65
|
-
include BodhiResource
|
66
|
-
attr_accessor *properties
|
67
|
-
})
|
68
|
-
klass.define_singleton_method(:find) do |id, context|
|
69
|
-
result = context.connection.get do |request|
|
70
|
-
request.url "/#{context.namespace}/resources/#{klass.name}/#{id}"
|
71
|
-
request.headers[context.credentials_header] = context.credentials
|
72
|
-
end
|
73
|
-
|
74
|
-
if result.status != 200
|
75
|
-
errors = JSON.parse result.body
|
76
|
-
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
77
|
-
errors["status"] = result.status if errors.is_a? Hash
|
78
|
-
raise errors.to_s
|
79
|
-
end
|
27
|
+
all_types = Bodhi::Type.find_all(context)
|
28
|
+
all_enums = Bodhi::Enumeration.find_all(context)
|
29
|
+
klasses = all_types.collect{ |type| Bodhi::Type.create_class_with(type) }
|
80
30
|
|
81
|
-
|
82
|
-
|
83
|
-
return FactoryGirl.build(klass.name, object_hash)
|
84
|
-
end
|
31
|
+
embedded_types = all_types.select{ |type| type.embedded }
|
32
|
+
normal_types = all_types.select{ |type| !type.embedded }
|
85
33
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
90
|
-
|
91
|
-
# - Create a Factory with the given name, properties, and available enumerations
|
92
|
-
def self.create_factory(name, properties, enumerations)
|
93
|
-
FactoryGirl.define do
|
94
|
-
factory name.to_sym do
|
95
|
-
properties.each_pair do |k,v|
|
96
|
-
unless v["system"]
|
97
|
-
|
98
|
-
case v["type"]
|
99
|
-
when "GeoJSON"
|
100
|
-
send(k) { {type: "Point", coordinates: [10,20]} } if v["multi"].nil?
|
101
|
-
send(k) { [*0..5].sample.times.collect{ {type: "Point", coordinates: [10,20]} } } if v["multi"]
|
102
|
-
when "Boolean"
|
103
|
-
send(k) { [true, false].sample } if v["multi"].nil?
|
104
|
-
send(k) { [*0..5].sample.times.collect{ [true, false].sample } } if v["multi"]
|
105
|
-
when "Enumerated"
|
106
|
-
enum = enumerations.select{ |enumeration| enumeration["name"] == v["ref"].split('.')[0] }[0]
|
107
|
-
send(k) { enum["values"].sample[v["ref"].split('.')[1]] } if v["multi"].nil?
|
108
|
-
send(k) { [*0..5].sample.times.collect{ enum["values"].sample[v["ref"].split('.')[1]] } } if v["multi"]
|
109
|
-
when "Object"
|
110
|
-
send(k) { {"foo" => SecureRandom.hex} } if v["multi"].nil?
|
111
|
-
send(k) { [*0..5].sample.times.collect{ {"foo" => SecureRandom.hex} } } if v["multi"]
|
112
|
-
when "String"
|
113
|
-
send(k) { SecureRandom.hex } if v["multi"].nil?
|
114
|
-
send(k) { [*0..5].sample.times.collect{ SecureRandom.hex } } if v["multi"]
|
115
|
-
when "DateTime"
|
116
|
-
send(k) { Time.at(rand * Time.now.to_i).iso8601 } if v["multi"].nil?
|
117
|
-
send(k) { [*0..5].sample.times.collect{ Time.at(rand * Time.now.to_i).iso8601 } } if v["multi"]
|
118
|
-
when "Integer"
|
119
|
-
send(k) { SecureRandom.random_number(100) } if v["multi"].nil?
|
120
|
-
send(k) { [*0..5].sample.times.collect{ SecureRandom.random_number(100) } } if v["multi"]
|
121
|
-
when "Real"
|
122
|
-
send(k) { SecureRandom.random_number } if v["multi"].nil?
|
123
|
-
send(k) { [*0..5].sample.times.collect{ SecureRandom.random_number } } if v["multi"]
|
124
|
-
else # Its an embedded type
|
125
|
-
send(k) { FactoryGirl.build(v["type"]).attributes } if v["multi"].nil?
|
126
|
-
send(k) { [*0..5].sample.times.collect{ FactoryGirl.build(v["type"]).attributes } } if v["multi"]
|
127
|
-
end
|
128
|
-
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
34
|
+
embedded_factories = embedded_types.each{ |type| Bodhi::Type.create_factory_with(type) }
|
35
|
+
normal_factories = normal_types.each{ |type| Bodhi::Type.create_factory_with(type) }
|
36
|
+
klasses
|
133
37
|
end
|
134
38
|
end
|
data/lib/bodhi-slam/context.rb
CHANGED
@@ -1,59 +1,45 @@
|
|
1
|
-
|
2
|
-
attr_reader :errors, :connection, :server, :namespace,
|
3
|
-
:credentials, :credentials_type, :credentials_header
|
1
|
+
require 'bodhi-slam/validations'
|
4
2
|
|
5
|
-
|
6
|
-
|
3
|
+
module Bodhi
|
4
|
+
class Context
|
5
|
+
include Bodhi::Validations
|
6
|
+
attr_reader :connection, :server, :namespace,
|
7
|
+
:credentials, :credentials_type, :credentials_header
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
#faraday.response :logger # log requests to STDOUT
|
11
|
-
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
12
|
-
end
|
13
|
-
@server = params[:server]
|
14
|
-
@namespace = params[:namespace]
|
15
|
-
|
16
|
-
if params[:cookie]
|
17
|
-
@credentials = params[:cookie]
|
18
|
-
@credentials_header = "Cookie"
|
19
|
-
@credentials_type = "HTTP_COOKIE"
|
20
|
-
else
|
21
|
-
@credentials = @connection.basic_auth params[:username], params[:password]
|
22
|
-
@credentials_header = "Authorization"
|
23
|
-
@credentials_type = "HTTP_BASIC"
|
24
|
-
end
|
9
|
+
validates :server, required: true, is_not_blank: true, url: true
|
10
|
+
validates :namespace, required: true, is_not_blank: true
|
25
11
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def attributes
|
30
|
-
attributes = Hash.new
|
31
|
-
self.instance_variables.each do |variable|
|
32
|
-
attribute_name = variable.to_s.delete('@').to_sym
|
33
|
-
attributes[attribute_name] = send(attribute_name)
|
34
|
-
end
|
35
|
-
attributes
|
36
|
-
end
|
37
|
-
|
38
|
-
# - Runs all the specified validations and returns true if no errors were added otherwise false.
|
39
|
-
def valid?
|
40
|
-
errors.add(:server, "must be present") if server.nil?
|
41
|
-
errors.add(:server, "must be a string") unless server.is_a? String
|
12
|
+
def initialize(params)
|
13
|
+
params.symbolize_keys!
|
42
14
|
|
43
|
-
|
44
|
-
|
15
|
+
@connection = Faraday.new(url: params[:server]) do |faraday|
|
16
|
+
faraday.request :url_encoded # form-encode POST params
|
17
|
+
#faraday.response :logger # log requests to STDOUT
|
18
|
+
#faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
19
|
+
faraday.adapter :net_http_persistent
|
20
|
+
end
|
21
|
+
@server = params[:server]
|
22
|
+
@namespace = params[:namespace]
|
45
23
|
|
46
|
-
|
47
|
-
|
24
|
+
if params[:cookie]
|
25
|
+
@credentials = params[:cookie]
|
26
|
+
@credentials_header = "Cookie"
|
27
|
+
@credentials_type = "HTTP_COOKIE"
|
28
|
+
else
|
29
|
+
@credentials = @connection.basic_auth params[:username], params[:password]
|
30
|
+
@credentials_header = "Authorization"
|
31
|
+
@credentials_type = "HTTP_BASIC"
|
32
|
+
end
|
33
|
+
end
|
48
34
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
35
|
+
def attributes
|
36
|
+
attributes = Hash.new
|
37
|
+
self.instance_variables.each do |variable|
|
38
|
+
attribute_name = variable.to_s.delete('@').to_sym
|
39
|
+
attributes[attribute_name] = send(attribute_name)
|
40
|
+
end
|
41
|
+
attributes
|
42
|
+
end
|
43
|
+
|
58
44
|
end
|
59
45
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Bodhi
|
2
|
+
class Enumeration
|
3
|
+
attr_reader :name, :values
|
4
|
+
|
5
|
+
def initialize(params={})
|
6
|
+
params.symbolize_keys!
|
7
|
+
|
8
|
+
@name = params[:name]
|
9
|
+
@values = params[:values]
|
10
|
+
self.class.cache[@name.to_sym] = self
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find_all(context)
|
14
|
+
raise context.errors unless context.valid?
|
15
|
+
|
16
|
+
result = context.connection.get do |request|
|
17
|
+
request.url "/#{context.namespace}/enums"
|
18
|
+
request.headers[context.credentials_header] = context.credentials
|
19
|
+
end
|
20
|
+
|
21
|
+
if result.status != 200
|
22
|
+
errors = JSON.parse result.body
|
23
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
24
|
+
errors["status"] = result.status if errors.is_a? Hash
|
25
|
+
raise errors.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
JSON.parse(result.body).collect{ |enum| Bodhi::Enumeration.new(enum) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.cache
|
32
|
+
@cache ||= Hash.new
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/bodhi-slam/errors.rb
CHANGED
@@ -1,24 +1,101 @@
|
|
1
1
|
module Bodhi
|
2
2
|
class Errors < Exception
|
3
|
+
include Enumerable
|
3
4
|
attr_accessor :messages
|
4
5
|
|
5
6
|
def initialize(errors={})
|
6
7
|
@messages = errors
|
7
8
|
end
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
|
10
|
+
# Adds the given +message+ to the errors hash under the +name+ key
|
11
|
+
#
|
12
|
+
# user.errors.add(:test, "has bad value")
|
13
|
+
# user.errors.any? # => true
|
14
|
+
def add(name, message)
|
15
|
+
@messages.has_key?(name) ? @messages[name].push(message) : @messages[name] = [message]
|
12
16
|
end
|
13
17
|
|
18
|
+
# Clears all error messages
|
19
|
+
#
|
20
|
+
# user.errors.add(:name, "is wrong")
|
21
|
+
# user.errors.clear # => nil
|
22
|
+
# user.errors.any? # => false
|
14
23
|
def clear
|
15
24
|
@messages.clear
|
16
25
|
end
|
17
26
|
|
27
|
+
# Returns an array of all error messages
|
18
28
|
def full_messages
|
19
29
|
results = []
|
20
30
|
@messages.each{ |key, values| values.each{ |value| results.push("#{key} #{value}") }}
|
21
31
|
results
|
22
32
|
end
|
33
|
+
alias :to_a :full_messages
|
34
|
+
|
35
|
+
# Converts the messages hash to json
|
36
|
+
def to_json
|
37
|
+
@messages.to_json
|
38
|
+
end
|
39
|
+
|
40
|
+
# Iterates through each error key, value pair in the error messages hash.
|
41
|
+
# Yields the attribute and the error for that attribute. If the attribute
|
42
|
+
# has more than one error message, yields once for each error message.
|
43
|
+
#
|
44
|
+
# user.errors.add(:test, "is required")
|
45
|
+
# user.errors.each do |attribute, error|
|
46
|
+
# # yields :test and "is required"
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# user.errors.add(:foo, "is awesome!")
|
50
|
+
# user.errors.each do |attribute, error|
|
51
|
+
# # yields :test and "is required"
|
52
|
+
# # then yields :foo and "is awesome!"
|
53
|
+
# end
|
54
|
+
def each
|
55
|
+
@messages.each_key do |attribute|
|
56
|
+
@messages[attribute].each{ |error| yield attribute, error }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns +true+ if the error messages include an error for the given key
|
61
|
+
# +attribute+, +false+ otherwise.
|
62
|
+
#
|
63
|
+
# user.errors.messages # => {:name=>["is required"]}
|
64
|
+
# user.errors.include?(:name) # => true
|
65
|
+
# user.errors.include?(:foo) # => false
|
66
|
+
def include?(attribute)
|
67
|
+
!@messages[attribute].nil?
|
68
|
+
end
|
69
|
+
alias :has_key? :include?
|
70
|
+
alias :key? :include?
|
71
|
+
|
72
|
+
# When passed a symbol or a name of a method, returns an array of errors
|
73
|
+
# for the method.
|
74
|
+
#
|
75
|
+
# user.errors[:name] # => ["is required"]
|
76
|
+
# user.errors['name'] # => ["is required"]
|
77
|
+
def [](attribute)
|
78
|
+
@messages[attribute.to_sym]
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns the number of error messages.
|
82
|
+
#
|
83
|
+
# user.errors.add(:name, "is required")
|
84
|
+
# user.errors.size # => 1
|
85
|
+
# user.errors.add(:name, "can not be blank")
|
86
|
+
# user.errors.size # => 2
|
87
|
+
def size
|
88
|
+
full_messages.size
|
89
|
+
end
|
90
|
+
alias :count :size
|
91
|
+
|
92
|
+
# Returns +true+ if no errors are present, +false+ otherwise.
|
93
|
+
#
|
94
|
+
# user.errors.add(:name, "test error")
|
95
|
+
# user.errors.empty? # => false
|
96
|
+
def empty?
|
97
|
+
size == 0
|
98
|
+
end
|
99
|
+
alias :blank? :empty?
|
23
100
|
end
|
24
101
|
end
|
data/lib/bodhi-slam/resource.rb
CHANGED
@@ -1,75 +1,212 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
module Bodhi
|
2
|
+
module Resource
|
3
|
+
SYSTEM_ATTRIBUTES = [:bodhi_context, :sys_created_at, :sys_version, :sys_modified_at, :sys_modified_by,
|
4
|
+
:sys_namespace, :sys_created_by, :sys_type_version, :sys_id]
|
5
|
+
attr_accessor *SYSTEM_ATTRIBUTES
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def build(context, params={})
|
9
|
+
params.merge!({bodhi_context: context})
|
10
|
+
FactoryGirl.build(name, params)
|
11
|
+
end
|
12
|
+
|
13
|
+
def build_list(context, amount, params={})
|
14
|
+
params.merge!({bodhi_context: context})
|
15
|
+
FactoryGirl.build_list(name, amount, params)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create(context, params={})
|
19
|
+
params.merge!({bodhi_context: context})
|
20
|
+
FactoryGirl.create(name, params)
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_list(context, amount, params={})
|
24
|
+
params.merge!({bodhi_context: context})
|
25
|
+
records = FactoryGirl.build_list(name, amount, params)
|
26
|
+
result = context.connection.post do |request|
|
27
|
+
request.url "/#{context.namespace}/resources/#{name}"
|
28
|
+
request.headers['Content-Type'] = 'application/json'
|
29
|
+
request.headers[context.credentials_header] = context.credentials
|
30
|
+
request.body = records.to_json
|
31
|
+
end
|
32
|
+
|
33
|
+
#puts "\033[33mResult Body\033[0m: \033[36m#{result.body}\033[0m"
|
34
|
+
|
35
|
+
if result.status != 200
|
36
|
+
errors = JSON.parse result.body
|
37
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
38
|
+
errors["status"] = result.status if errors.is_a? Hash
|
39
|
+
raise errors.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
#puts "\033[33mRecords\033[0m: \033[36m#{records.map(&:attributes)}\033[0m"
|
43
|
+
|
44
|
+
records
|
45
|
+
end
|
46
|
+
|
47
|
+
def find(context, id)
|
48
|
+
raise context.errors unless context.valid?
|
49
|
+
|
50
|
+
unless id.is_a? String
|
51
|
+
raise ArgumentError.new("Expected 'id' to be a String. 'id' #=> #{id.class}")
|
52
|
+
end
|
53
|
+
|
54
|
+
result = context.connection.get do |request|
|
55
|
+
request.url "/#{context.namespace}/resources/#{name}/#{id}"
|
56
|
+
request.headers[context.credentials_header] = context.credentials
|
57
|
+
end
|
58
|
+
|
59
|
+
if result.status != 200
|
60
|
+
errors = JSON.parse result.body
|
61
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
62
|
+
errors["status"] = result.status if errors.is_a? Hash
|
63
|
+
raise errors.to_s
|
64
|
+
end
|
65
|
+
|
66
|
+
resource_attributes = JSON.parse(result.body)
|
67
|
+
self.build(context, resource_attributes)
|
68
|
+
end
|
69
|
+
|
70
|
+
def aggregate(context, pipeline)
|
71
|
+
raise context.errors unless context.valid?
|
72
|
+
|
73
|
+
unless pipeline.is_a? String
|
74
|
+
raise ArgumentError.new("Expected 'pipeline' to be a String. 'pipeline' #=> #{pipeline.class}")
|
75
|
+
end
|
76
|
+
|
77
|
+
result = context.connection.get do |request|
|
78
|
+
request.url "/#{context.namespace}/resources/#{name}/aggregate?pipeline=#{pipeline}"
|
79
|
+
request.headers[context.credentials_header] = context.credentials
|
80
|
+
end
|
81
|
+
|
82
|
+
if result.status != 200
|
83
|
+
errors = JSON.parse result.body
|
84
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
85
|
+
errors["status"] = result.status if errors.is_a? Hash
|
86
|
+
raise errors.to_s
|
87
|
+
end
|
88
|
+
|
89
|
+
JSON.parse(result.body)
|
90
|
+
end
|
91
|
+
|
92
|
+
def where(context, query)
|
93
|
+
raise context.errors unless context.valid?
|
94
|
+
|
95
|
+
unless query.is_a? String
|
96
|
+
raise ArgumentError.new("Expected 'query' to be a String. 'query' #=> #{query.class}")
|
97
|
+
end
|
98
|
+
|
99
|
+
result = context.connection.get do |request|
|
100
|
+
request.url "/#{context.namespace}/resources/#{name}?where=#{query}"
|
101
|
+
request.headers[context.credentials_header] = context.credentials
|
102
|
+
end
|
103
|
+
|
104
|
+
if result.status != 200
|
105
|
+
errors = JSON.parse result.body
|
106
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
107
|
+
errors["status"] = result.status if errors.is_a? Hash
|
108
|
+
raise errors.to_s
|
109
|
+
end
|
110
|
+
|
111
|
+
resources = JSON.parse(result.body)
|
112
|
+
resources.map{ |attributes| self.build(context, attributes) }
|
113
|
+
end
|
114
|
+
|
115
|
+
def delete_all(context)
|
116
|
+
raise context.errors unless context.valid?
|
117
|
+
|
118
|
+
result = context.connection.delete do |request|
|
119
|
+
request.url "/#{context.namespace}/resources/#{name}"
|
120
|
+
request.headers[context.credentials_header] = context.credentials
|
121
|
+
end
|
122
|
+
|
123
|
+
if result.status != 204
|
124
|
+
errors = JSON.parse result.body
|
125
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
126
|
+
errors["status"] = result.status if errors.is_a? Hash
|
127
|
+
raise errors.to_s
|
128
|
+
end
|
129
|
+
end
|
12
130
|
end
|
13
|
-
|
14
|
-
|
131
|
+
|
132
|
+
module InstanceMethods
|
133
|
+
# Returns a Hash of the Objects form attributes
|
134
|
+
#
|
135
|
+
# s = SomeResource.build({foo:"test", bar:12345})
|
136
|
+
# s.attributes # => { foo: "test", bar: 12345 }
|
137
|
+
def attributes
|
138
|
+
attributes = Hash.new
|
139
|
+
self.instance_variables.each do |variable|
|
140
|
+
attribute_name = variable.to_s.delete('@').to_sym
|
141
|
+
attributes[attribute_name] = send(attribute_name) unless SYSTEM_ATTRIBUTES.include?(attribute_name)
|
142
|
+
end
|
143
|
+
attributes
|
144
|
+
end
|
15
145
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
146
|
+
# Returns all the Objects attributes as JSON.
|
147
|
+
# Will convert any nested Objects to JSON if they respond to :to_json
|
148
|
+
#
|
149
|
+
# s = SomeResource.build({foo:"test", bar:12345})
|
150
|
+
# s.to_json # => { "foo":"test", "bar":12345 }
|
151
|
+
def to_json(base=nil)
|
152
|
+
super if base
|
153
|
+
attributes.to_json
|
154
|
+
end
|
25
155
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
156
|
+
def save!
|
157
|
+
result = bodhi_context.connection.post do |request|
|
158
|
+
request.url "/#{bodhi_context.namespace}/resources/#{self.class}"
|
159
|
+
request.headers['Content-Type'] = 'application/json'
|
160
|
+
request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
|
161
|
+
request.body = attributes.to_json
|
162
|
+
end
|
33
163
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
164
|
+
if result.status != 201
|
165
|
+
errors = JSON.parse result.body
|
166
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
167
|
+
errors["status"] = result.status if errors.is_a? Hash
|
168
|
+
raise errors.to_s
|
169
|
+
end
|
170
|
+
|
171
|
+
if result.headers['location']
|
172
|
+
@sys_id = result.headers['location'].match(/(?<id>[a-zA-Z0-9]{24})/)[:id]
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def delete!
|
177
|
+
result = bodhi_context.connection.delete do |request|
|
178
|
+
request.url "/#{bodhi_context.namespace}/resources/#{self.class}/#{sys_id}"
|
179
|
+
request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
|
180
|
+
end
|
40
181
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
182
|
+
if result.status != 204
|
183
|
+
errors = JSON.parse result.body
|
184
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
185
|
+
errors["status"] = result.status if errors.is_a? Hash
|
186
|
+
raise errors.to_s
|
187
|
+
end
|
188
|
+
end
|
45
189
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
190
|
+
def patch!(params)
|
191
|
+
result = bodhi_context.connection.patch do |request|
|
192
|
+
request.url "/#{bodhi_context.namespace}/resources/#{self.class}/#{sys_id}"
|
193
|
+
request.headers['Content-Type'] = 'application/json'
|
194
|
+
request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
|
195
|
+
request.body = params
|
196
|
+
end
|
51
197
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
198
|
+
if result.status != 204
|
199
|
+
errors = JSON.parse result.body
|
200
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
201
|
+
errors["status"] = result.status if errors.is_a? Hash
|
202
|
+
raise errors.to_s
|
203
|
+
end
|
204
|
+
end
|
57
205
|
end
|
58
|
-
end
|
59
206
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
request.headers['Content-Type'] = 'application/json'
|
64
|
-
request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
|
65
|
-
request.body = params
|
207
|
+
def self.included(base)
|
208
|
+
base.extend(ClassMethods)
|
209
|
+
base.include(InstanceMethods, Bodhi::Validations)
|
66
210
|
end
|
67
|
-
|
68
|
-
if result.status != 204
|
69
|
-
errors = JSON.parse result.body
|
70
|
-
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
71
|
-
errors["status"] = result.status if errors.is_a? Hash
|
72
|
-
raise errors.to_s
|
73
|
-
end
|
74
|
-
end
|
211
|
+
end
|
75
212
|
end
|