bodhi-slam 0.0.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.
- checksums.yaml +7 -0
- data/lib/bodhi-slam.rb +243 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a5847a2624bbebdcca10694961184c705fe2a291
|
4
|
+
data.tar.gz: 2cc55276b1d0d2f56334ed704e638655c8c10715
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9a42e6cb3c52fec9c87d124bd7f45c81ec3111a58ed2d64579167cb471db55681f3501d4276590f83c639f08c203505052a2447093f73c9814979bdcf7a59575
|
7
|
+
data.tar.gz: 1374f972b39667ccf2d56b21c346cd5c7cbed9dfa073828d822d6501febd1ccf09ee2a8ec6277acca86d54f2734a7b119277248ec434ec0a0a48e6010ec1bb44
|
data/lib/bodhi-slam.rb
ADDED
@@ -0,0 +1,243 @@
|
|
1
|
+
require "faraday"
|
2
|
+
require "factory_girl"
|
3
|
+
require "json"
|
4
|
+
require "time"
|
5
|
+
|
6
|
+
class BodhiSlam
|
7
|
+
def self.context(params, &block)
|
8
|
+
bodhi_context = BodhiContext.new params
|
9
|
+
bodhi_context.validate!
|
10
|
+
|
11
|
+
puts "Switching context to: #{bodhi_context.attributes}"
|
12
|
+
|
13
|
+
yield bodhi_context
|
14
|
+
|
15
|
+
puts "Exiting context: #{bodhi_context.attributes}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.analyze(context)
|
19
|
+
context.validate!
|
20
|
+
|
21
|
+
#Get the types for this namespace
|
22
|
+
result = context.connection.get do |request|
|
23
|
+
request.url "/#{context.namespace}/types"
|
24
|
+
request.headers[context.credentials_header] = context.credentials
|
25
|
+
end
|
26
|
+
|
27
|
+
if result.status != 200
|
28
|
+
errors = JSON.parse result.body
|
29
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
30
|
+
errors["status"] = result.status if errors.is_a? Hash
|
31
|
+
raise errors.to_s
|
32
|
+
end
|
33
|
+
types = JSON.parse(result.body)
|
34
|
+
|
35
|
+
#Get the enumerations for this namespace
|
36
|
+
result = context.connection.get do |request|
|
37
|
+
request.url "/#{context.namespace}/enums"
|
38
|
+
request.headers[context.credentials_header] = context.credentials
|
39
|
+
end
|
40
|
+
|
41
|
+
if result.status != 200
|
42
|
+
errors = JSON.parse result.body
|
43
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
44
|
+
errors["status"] = result.status if errors.is_a? Hash
|
45
|
+
raise errors.to_s
|
46
|
+
end
|
47
|
+
enumerations = JSON.parse(result.body)
|
48
|
+
|
49
|
+
#Create a class & factory for each type
|
50
|
+
setup_factory = lambda do |name, properties|
|
51
|
+
FactoryGirl.define do
|
52
|
+
factory name.to_sym do
|
53
|
+
properties.each_pair do |k,v|
|
54
|
+
unless v["system"]
|
55
|
+
|
56
|
+
case v["type"]
|
57
|
+
when "GeoJSON"
|
58
|
+
send(k) { {type: "Point", coordinates: [10,20]} } if v["multi"].nil?
|
59
|
+
send(k) { [*0..5].sample.times.collect{ {type: "Point", coordinates: [10,20]} } } if v["multi"]
|
60
|
+
when "Boolean"
|
61
|
+
send(k) { [true, false].sample } if v["multi"].nil?
|
62
|
+
send(k) { [*0..5].sample.times.collect{ [true, false].sample } } if v["multi"]
|
63
|
+
when "Enumerated"
|
64
|
+
enum = enumerations.select{ |enumeration| enumeration["name"] == v["ref"].split('.')[0] }[0]
|
65
|
+
send(k) { enum["values"].sample[v["ref"].split('.')[1]] } if v["multi"].nil?
|
66
|
+
send(k) { [*0..5].sample.times.collect{ enum["values"].sample[v["ref"].split('.')[1]] } } if v["multi"]
|
67
|
+
when "Object"
|
68
|
+
send(k) { {"foo" => SecureRandom.hex} } if v["multi"].nil?
|
69
|
+
send(k) { [*0..5].sample.times.collect{ {"foo" => SecureRandom.hex} } } if v["multi"]
|
70
|
+
when "String"
|
71
|
+
send(k) { SecureRandom.hex } if v["multi"].nil?
|
72
|
+
send(k) { [*0..5].sample.times.collect{ SecureRandom.hex } } if v["multi"]
|
73
|
+
when "DateTime"
|
74
|
+
send(k) { Time.at(rand * Time.now.to_i).iso8601 } if v["multi"].nil?
|
75
|
+
send(k) { [*0..5].sample.times.collect{ Time.at(rand * Time.now.to_i).iso8601 } } if v["multi"]
|
76
|
+
when "Integer"
|
77
|
+
send(k) { SecureRandom.random_number(100) } if v["multi"].nil?
|
78
|
+
send(k) { [*0..5].sample.times.collect{ SecureRandom.random_number(100) } } if v["multi"]
|
79
|
+
when "Real"
|
80
|
+
send(k) { SecureRandom.random_number } if v["multi"].nil?
|
81
|
+
send(k) { [*0..5].sample.times.collect{ SecureRandom.random_number } } if v["multi"]
|
82
|
+
else # Its an embedded type
|
83
|
+
send(k) { FactoryGirl.build(v["type"]).attributes } if v["multi"].nil?
|
84
|
+
send(k) { [*0..5].sample.times.collect{ FactoryGirl.build(v["type"]).attributes } } if v["multi"]
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
create_type = lambda do |type|
|
94
|
+
if type["package"] != "system"
|
95
|
+
properties = type["properties"].keys.collect{ |key| key.to_sym }
|
96
|
+
klass = Object.const_set(type["name"], Class.new {
|
97
|
+
include BodhiResource
|
98
|
+
attr_accessor *properties
|
99
|
+
})
|
100
|
+
klass.define_singleton_method(:find) do |id, context|
|
101
|
+
result = context.connection.get do |request|
|
102
|
+
request.url "/#{context.namespace}/resources/#{klass.name}/#{id}"
|
103
|
+
request.headers[context.credentials_header] = context.credentials
|
104
|
+
end
|
105
|
+
|
106
|
+
if result.status != 200
|
107
|
+
errors = JSON.parse result.body
|
108
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
109
|
+
errors["status"] = result.status if errors.is_a? Hash
|
110
|
+
raise errors.to_s
|
111
|
+
end
|
112
|
+
|
113
|
+
object_hash = JSON.parse(result.body)
|
114
|
+
object_hash["bodhi_context"] = context
|
115
|
+
return FactoryGirl.build(klass.name, object_hash)
|
116
|
+
end
|
117
|
+
|
118
|
+
setup_factory.call(klass.name, type["properties"]) unless FactoryGirl.factories.registered?(klass.name)
|
119
|
+
puts "Created Class & Factory for: #{klass.name}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
embedded_types = types.select{ |type| type["embedded"] }
|
124
|
+
normal_types = types.select{ |type| !type["embedded"] }
|
125
|
+
|
126
|
+
embedded_types.each{ |type| create_type.call(type) }
|
127
|
+
normal_types.each{ |type| create_type.call(type) }
|
128
|
+
|
129
|
+
#Party!
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
class BodhiContext
|
135
|
+
attr_reader :connection, :server, :namespace,
|
136
|
+
:credentials, :credentials_type, :credentials_header
|
137
|
+
|
138
|
+
def initialize(params)
|
139
|
+
params.symbolize_keys!
|
140
|
+
|
141
|
+
@connection = Faraday.new(url: params[:server]) do |faraday|
|
142
|
+
faraday.request :url_encoded # form-encode POST params
|
143
|
+
#faraday.response :logger # log requests to STDOUT
|
144
|
+
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
145
|
+
end
|
146
|
+
@server = params[:server]
|
147
|
+
@namespace = params[:namespace]
|
148
|
+
|
149
|
+
if params[:cookie]
|
150
|
+
@credentials = params[:cookie]
|
151
|
+
@credentials_header = "Cookie"
|
152
|
+
@credentials_type = "HTTP_COOKIE"
|
153
|
+
else
|
154
|
+
@credentials = @connection.basic_auth params[:username], params[:password]
|
155
|
+
@credentials_header = "Authorization"
|
156
|
+
@credentials_type = "HTTP_BASIC"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def attributes
|
161
|
+
attributes = Hash.new
|
162
|
+
self.instance_variables.each do |variable|
|
163
|
+
attribute_name = variable.to_s.delete('@').to_sym
|
164
|
+
attributes[attribute_name] = send(attribute_name) unless [:connection, :credentials_header].include?(attribute_name)
|
165
|
+
end
|
166
|
+
attributes
|
167
|
+
end
|
168
|
+
|
169
|
+
def validate!
|
170
|
+
raise ArgumentError, "Server URL must be a String" unless server.is_a?(String)
|
171
|
+
raise ArgumentError, "Namespace name must be a String" unless namespace.is_a?(String)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
module BodhiResource
|
177
|
+
SYSTEM_ATTRIBUTES = [:bodhi_context, :sys_created_at, :sys_version, :sys_modified_at, :sys_modified_by,
|
178
|
+
:sys_namespace, :sys_created_by, :sys_type_version, :sys_id]
|
179
|
+
attr_accessor *SYSTEM_ATTRIBUTES
|
180
|
+
|
181
|
+
# - Returns a Hash of the objects attributes
|
182
|
+
def attributes
|
183
|
+
attributes = Hash.new
|
184
|
+
self.instance_variables.each do |variable|
|
185
|
+
#Convert :@variable to :variable
|
186
|
+
attribute_name = variable.to_s.delete('@').to_sym
|
187
|
+
#Get the value of :attribute_name and add it to the Hash
|
188
|
+
#Unless the attribute is one of the BASE_ATTRIBUTES
|
189
|
+
attributes[attribute_name] = send(attribute_name) unless SYSTEM_ATTRIBUTES.include?(attribute_name)
|
190
|
+
end
|
191
|
+
attributes
|
192
|
+
end
|
193
|
+
|
194
|
+
def save!
|
195
|
+
result = bodhi_context.connection.post do |request|
|
196
|
+
request.url "/#{bodhi_context.namespace}/resources/#{self.class}"
|
197
|
+
request.headers['Content-Type'] = 'application/json'
|
198
|
+
request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
|
199
|
+
request.body = attributes.to_json
|
200
|
+
end
|
201
|
+
|
202
|
+
if result.status != 201
|
203
|
+
errors = JSON.parse result.body
|
204
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
205
|
+
errors["status"] = result.status if errors.is_a? Hash
|
206
|
+
raise errors.to_s
|
207
|
+
end
|
208
|
+
|
209
|
+
if result.headers['location']
|
210
|
+
@sys_id = result.headers['location'].match(/(?<id>[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12})/)[:id]
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def delete!
|
215
|
+
result = bodhi_context.connection.delete do |request|
|
216
|
+
request.url "/#{bodhi_context.namespace}/resources/#{self.class}/#{sys_id}"
|
217
|
+
request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
|
218
|
+
end
|
219
|
+
|
220
|
+
if result.status != 204
|
221
|
+
errors = JSON.parse result.body
|
222
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
223
|
+
errors["status"] = result.status if errors.is_a? Hash
|
224
|
+
raise errors.to_s
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def patch!(params)
|
229
|
+
result = bodhi_context.connection.patch do |request|
|
230
|
+
request.url "/#{bodhi_context.namespace}/resources/#{self.class}/#{sys_id}"
|
231
|
+
request.headers['Content-Type'] = 'application/json'
|
232
|
+
request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
|
233
|
+
request.body = params
|
234
|
+
end
|
235
|
+
|
236
|
+
if result.status != 204
|
237
|
+
errors = JSON.parse result.body
|
238
|
+
errors.each{|error| error['status'] = result.status } if errors.is_a? Array
|
239
|
+
errors["status"] = result.status if errors.is_a? Hash
|
240
|
+
raise errors.to_s
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bodhi-slam
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Will Davis
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: factory_girl
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.9'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.7'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.7'
|
55
|
+
description: Generate data in serial or parallel
|
56
|
+
email: will.davis@hotschedules.com
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- lib/bodhi-slam.rb
|
62
|
+
homepage:
|
63
|
+
licenses:
|
64
|
+
- MIT
|
65
|
+
metadata: {}
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 2.4.5
|
83
|
+
signing_key:
|
84
|
+
specification_version: 4
|
85
|
+
summary: Generate data and push to the Bodhi API
|
86
|
+
test_files: []
|