bodhi-slam 0.2.5 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4c3c82642a103662a2881ac8e07c236853d2e812
4
- data.tar.gz: ac2ebf8f9226eb5395ace0a7a8d4da99a3159b24
3
+ metadata.gz: 918cd6ede8d2d5cd62621b10fa6c80db870ef708
4
+ data.tar.gz: 26cbbadd0c463339016f7b60d4e87993373aaf5a
5
5
  SHA512:
6
- metadata.gz: fcccae214b0272c9fed879dc74e49980521db7f8bc27fb5cda37350b63c795f40c852902b59c95e64788ab8edf8d8d97c8f7c1e95eb144d88857e75c83a0c472
7
- data.tar.gz: 799f5e418a7ce569b70543002dd9dcbccc897c6658f088f2fc2622e530e75b2d708b6262445747fe37c1ba0d5393f8f04ad96ff1675b4f0acd40c12f4a1fe5bd
6
+ metadata.gz: 0d8e3134e705a6aeafe8fbea15831e1e3aefe5dca26e466c6484420531e5da67bb7436761c1c80db6077441cc8b3437726ad1d99250ec8fab3b72f055590b197
7
+ data.tar.gz: 3db2df8a8b36503709c1c9589a574977024d19b2bb8ac78eb9780001e592269d1be7f8c197867514d50644220fad3d5a89d35fc77a547b1d08d0dad1b00b9658
@@ -4,13 +4,16 @@ require "json"
4
4
  require "time"
5
5
  require "SecureRandom"
6
6
 
7
- require 'bodhi-slam/context'
8
- require 'bodhi-slam/errors'
9
- require 'bodhi-slam/resource'
10
- require 'bodhi-slam/types'
11
7
  require 'bodhi-slam/validations'
8
+ require 'bodhi-slam/errors'
9
+
10
+ require 'bodhi-slam/batches'
11
+ require 'bodhi-slam/context'
12
12
  require 'bodhi-slam/enumerations'
13
13
  require 'bodhi-slam/factory'
14
+ require 'bodhi-slam/resource'
15
+ require 'bodhi-slam/types'
16
+ require 'bodhi-slam/users'
14
17
 
15
18
  class BodhiSlam
16
19
  # Defines a context to interact with the Bodhi API
@@ -0,0 +1,19 @@
1
+ module Bodhi
2
+ class Batch
3
+ attr_accessor :records
4
+ attr_reader :created, :failed
5
+
6
+ def initialize(records=[])
7
+ @records = records
8
+ @created = []
9
+ @failed = []
10
+ end
11
+
12
+ # Saves the batch of records to the Bodhi cloud.
13
+ def save!(context)
14
+ raise NotImplementedError, "Subclasses must implement a save!(context) method."
15
+ end
16
+ end
17
+ end
18
+
19
+ Dir[File.dirname(__FILE__) + "/batches/*.rb"].each { |file| require file }
@@ -0,0 +1,49 @@
1
+ module Bodhi
2
+ class ResourceBatch < Batch
3
+ include Bodhi::Validations
4
+
5
+ attr_accessor :type
6
+
7
+ validates :type, type: "String", required: true, is_not_blank: true
8
+ validates :records, type: "Bodhi::Resource", required: true, multi: true
9
+
10
+ def initialize(type, resources=[])
11
+ super(resources)
12
+ @type = type
13
+ end
14
+
15
+ # Saves all records in the batch to the cloud
16
+ # and populates the +created+ and +failed+ arrays with the results
17
+ def save!(context)
18
+ if context.invalid?
19
+ raise Bodhi::ContextErrors.new(context.errors.messages), context.errors.to_a.to_s
20
+ end
21
+
22
+ records.each{ |record| record.validate! }
23
+
24
+ response = context.connection.post do |request|
25
+ request.url "/#{context.namespace}/resources/#{type}"
26
+ request.headers['Content-Type'] = 'application/json'
27
+ request.headers[context.credentials_header] = context.credentials
28
+ request.body = records.to_json
29
+ end
30
+
31
+ if response.status != 200
32
+ raise Bodhi::ApiErrors.new(body: response.body, status: response.status), "status: #{response.status}, body: #{response.body}"
33
+ end
34
+
35
+ # Parse the result body and update records with their sys_id
36
+ response_body = JSON.parse(response.body)
37
+ results = response_body.zip(records)
38
+ results.each do |response, record|
39
+ if response["location"]
40
+ record.sys_id = response["location"].match(/(?<id>[a-zA-Z0-9]{24})/)[:id]
41
+ @created.push record
42
+ else
43
+ @failed.push record
44
+ end
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -69,21 +69,11 @@ module Bodhi
69
69
  end
70
70
 
71
71
  resources = build_list(size, params)
72
- result = context.connection.post do |request|
73
- request.url "/#{context.namespace}/resources/#{klass}"
74
- request.headers['Content-Type'] = 'application/json'
75
- request.headers[context.credentials_header] = context.credentials
76
- request.body = resources.to_json
72
+ resources.each do |resource|
73
+ resource.bodhi_context = context
74
+ resource.save!
77
75
  end
78
76
 
79
- #puts "\033[33mResult Body\033[0m: \033[36m#{result.body}\033[0m"
80
-
81
- if result.status != 200
82
- raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
83
- end
84
-
85
- #puts "\033[33mRecords\033[0m: \033[36m#{records.map(&:attributes)}\033[0m"
86
-
87
77
  resources
88
78
  end
89
79
 
@@ -1,8 +1,10 @@
1
1
  module Bodhi
2
2
  module Resource
3
- SYSTEM_ATTRIBUTES = [:bodhi_context, :sys_created_at, :sys_version, :sys_modified_at, :sys_modified_by,
3
+ SYSTEM_ATTRIBUTES = [:sys_created_at, :sys_version, :sys_modified_at, :sys_modified_by,
4
4
  :sys_namespace, :sys_created_by, :sys_type_version, :sys_id, :sys_embeddedType]
5
+ SUPPORT_ATTRIBUTES = [:bodhi_context, :errors]
5
6
  attr_accessor *SYSTEM_ATTRIBUTES
7
+ attr_accessor *SUPPORT_ATTRIBUTES
6
8
 
7
9
  module ClassMethods
8
10
  def factory; @factory; end
@@ -14,22 +16,9 @@ module Bodhi
14
16
  # list = Resource.factory.build_list(10)
15
17
  # Resource.save_batch(context, list)
16
18
  def save_batch(context, objects)
17
- if context.invalid?
18
- raise Bodhi::ContextErrors.new(context.errors.messages), context.errors.to_a.to_s
19
- end
20
-
21
- result = context.connection.post do |request|
22
- request.url "/#{context.namespace}/resources/#{name}"
23
- request.headers['Content-Type'] = 'application/json'
24
- request.headers[context.credentials_header] = context.credentials
25
- request.body = objects.to_json
26
- end
27
-
28
- if result.status != 200
29
- raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
30
- end
31
-
32
- objects
19
+ batch = Bodhi::ResourceBatch.new(name, objects)
20
+ batch.save!(context)
21
+ batch
33
22
  end
34
23
 
35
24
  # Returns a single resource from the Bodhi Cloud that matches the given +id+
@@ -168,7 +157,9 @@ module Bodhi
168
157
  attributes = Hash.new
169
158
  self.instance_variables.each do |variable|
170
159
  attribute_name = variable.to_s.delete('@').to_sym
171
- attributes[attribute_name] = send(attribute_name) unless SYSTEM_ATTRIBUTES.include?(attribute_name)
160
+ unless SYSTEM_ATTRIBUTES.include?(attribute_name) || SUPPORT_ATTRIBUTES.include?(attribute_name)
161
+ attributes[attribute_name] = send(attribute_name)
162
+ end
172
163
  end
173
164
  attributes
174
165
  end
@@ -2,18 +2,31 @@ module Bodhi
2
2
  class Type
3
3
  include Bodhi::Validations
4
4
 
5
- BODHI_SYSTEM_ATTRIBUTES = [:sys_created_at, :sys_version, :sys_modified_at, :sys_modified_by,
5
+ SYSTEM_ATTRIBUTES = [:sys_created_at, :sys_version, :sys_modified_at, :sys_modified_by,
6
6
  :sys_namespace, :sys_created_by, :sys_type_version, :sys_id, :sys_embeddedType]
7
- BODHI_TYPE_ATTRIBUTES = [:name, :namespace, :package, :embedded, :properties]
7
+ ATTRIBUTES = [:name, :namespace, :package, :embedded, :properties, :version]
8
8
 
9
- attr_accessor *BODHI_TYPE_ATTRIBUTES
10
- attr_reader *BODHI_SYSTEM_ATTRIBUTES
9
+ attr_accessor *ATTRIBUTES
10
+ attr_reader *SYSTEM_ATTRIBUTES
11
11
  attr_reader :validations
12
+ attr_accessor :bodhi_context
12
13
 
13
14
  validates :name, required: true, is_not_blank: true
14
15
  validates :namespace, required: true
15
16
  validates :properties, required: true
16
17
 
18
+ # Returns a factory for the Bodhi::Type class
19
+ def self.factory
20
+ @factory ||= Bodhi::Factory.new(Bodhi::Type).tap do |factory|
21
+ factory.add_generator(:name, type: "String", required: true, is_not_blank: true)
22
+ factory.add_generator(:namespace, type: "String", required: true)
23
+ factory.add_generator(:properties, type: "Object", required: true)
24
+ factory.add_generator(:package, type: "String")
25
+ factory.add_generator(:embedded, type: "Boolean")
26
+ factory.add_generator(:version, type: "String")
27
+ end
28
+ end
29
+
17
30
  def initialize(params={})
18
31
  # same as symbolize_keys!
19
32
  params = params.reduce({}) do |memo, (k, v)|
@@ -21,7 +34,7 @@ module Bodhi
21
34
  end
22
35
 
23
36
  # set attributes
24
- BODHI_TYPE_ATTRIBUTES.each do |attribute|
37
+ ATTRIBUTES.each do |attribute|
25
38
  send("#{attribute}=", params[attribute])
26
39
  end
27
40
 
@@ -52,8 +65,84 @@ module Bodhi
52
65
  end
53
66
  end
54
67
 
55
- # Queries the Bodhi API for all types within the given +context+
56
- # Returns an array of Bodhi::Type objects
68
+ # Returns a Hash of the Objects form attributes
69
+ #
70
+ # s = SomeResource.factory.build({foo:"test", bar:12345})
71
+ # s.attributes # => { foo: "test", bar: 12345 }
72
+ def attributes
73
+ result = Hash.new
74
+ ATTRIBUTES.each do |attribute|
75
+ result[attribute] = send(attribute)
76
+ end
77
+ result
78
+ end
79
+
80
+ # Returns all the Objects attributes as JSON.
81
+ # It converts any nested Objects to JSON if they respond to +to_json+
82
+ #
83
+ # s = SomeResource.factory.build({foo:"test", bar:12345})
84
+ # s.to_json # => "{ 'foo':'test', 'bar':12345 }"
85
+ def to_json(base=nil)
86
+ super if base
87
+ attributes.to_json
88
+ end
89
+
90
+ # Saves the resource to the Bodhi Cloud. Raises ArgumentError if record could not be saved.
91
+ #
92
+ # obj = Resouce.new
93
+ # obj.save!
94
+ # obj.persisted? # => true
95
+ def save!
96
+ result = bodhi_context.connection.post do |request|
97
+ request.url "/#{bodhi_context.namespace}/types"
98
+ request.headers['Content-Type'] = 'application/json'
99
+ request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
100
+ request.body = attributes.to_json
101
+ end
102
+
103
+ if result.status != 201
104
+ raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
105
+ end
106
+ end
107
+
108
+ def delete!
109
+ result = bodhi_context.connection.delete do |request|
110
+ request.url "/#{bodhi_context.namespace}/types/#{name}"
111
+ request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
112
+ end
113
+
114
+ if result.status != 204
115
+ raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
116
+ end
117
+ end
118
+
119
+ # Queries the Bodhi API for the given +type_name+ and
120
+ # returns a Bodhi::Type
121
+ #
122
+ # context = BodhiContext.new(valid_params)
123
+ # type = Bodhi::Type.find(context, "MyTypeName")
124
+ # type # => #<Bodhi::Type:0x007fbff403e808 @name="MyTypeName">
125
+ def self.find(context, type_name)
126
+ if context.invalid?
127
+ raise context.errors, context.errors.to_a.to_s
128
+ end
129
+
130
+ result = context.connection.get do |request|
131
+ request.url "/#{context.namespace}/types/#{type_name}"
132
+ request.headers[context.credentials_header] = context.credentials
133
+ end
134
+
135
+ if result.status != 200
136
+ raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
137
+ end
138
+
139
+ type = Bodhi::Type.new(result)
140
+ type.bodhi_context = context
141
+ type
142
+ end
143
+
144
+ # Queries the Bodhi API for all types within the given +context+ and
145
+ # returns an array of Bodhi::Type objects
57
146
  #
58
147
  # context = BodhiContext.new(valid_params)
59
148
  # types = Bodhi::Type.find_all(context)
@@ -70,10 +159,7 @@ module Bodhi
70
159
  end
71
160
 
72
161
  if result.status != 200
73
- errors = JSON.parse result.body
74
- errors.each{|error| error['status'] = result.status } if errors.is_a? Array
75
- errors["status"] = result.status if errors.is_a? Hash
76
- raise errors.to_s
162
+ raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
77
163
  end
78
164
 
79
165
  page += 1
@@ -81,7 +167,11 @@ module Bodhi
81
167
  all_records << records
82
168
  end while records.size == 100
83
169
 
84
- all_records.flatten.collect{ |type| Bodhi::Type.new(type) }
170
+ all_records.flatten.collect do |type|
171
+ record = Bodhi::Type.new(type)
172
+ record.bodhi_context = context
173
+ record
174
+ end
85
175
  end
86
176
 
87
177
  # Dynamically defines a new Ruby class for the given +type+
@@ -0,0 +1,139 @@
1
+ module Bodhi
2
+ class User
3
+ include Bodhi::Validations
4
+
5
+ ATTRIBUTES = [:username, :password, :profiles, :email, :firstName, :lastName, :phone]
6
+ attr_accessor *ATTRIBUTES
7
+ attr_accessor :bodhi_context
8
+
9
+ validates :username, type: "String", required: true, is_not_blank: true
10
+ validates :password, type: "String", required: true, is_not_blank: true
11
+ validates :profiles, type: "String", required: true, multi: true
12
+ validates :email, type: "String", is_email: true
13
+ validates :firstName, type: "String"
14
+ validates :lastName, type: "String"
15
+ validates :phone, type: "String"
16
+
17
+ def initialize(params={})
18
+ # same as symbolize_keys!
19
+ params = params.reduce({}) do |memo, (k, v)|
20
+ memo.merge({ k.to_sym => v})
21
+ end
22
+
23
+ # set attributes
24
+ ATTRIBUTES.each do |attribute|
25
+ send("#{attribute}=", params[attribute])
26
+ end
27
+ end
28
+
29
+ # Returns a Hash of the Objects form attributes
30
+ #
31
+ # s = SomeResource.factory.build({foo:"test", bar:12345})
32
+ # s.attributes # => { foo: "test", bar: 12345 }
33
+ def attributes
34
+ result = Hash.new
35
+ ATTRIBUTES.each do |attribute|
36
+ result[attribute] = send(attribute)
37
+ end
38
+ result
39
+ end
40
+
41
+ # Returns all the Objects attributes as JSON.
42
+ # It converts any nested Objects to JSON if they respond to +to_json+
43
+ #
44
+ # s = SomeResource.factory.build({foo:"test", bar:12345})
45
+ # s.to_json # => "{ 'foo':'test', 'bar':12345 }"
46
+ def to_json(base=nil)
47
+ super if base
48
+ attributes.to_json
49
+ end
50
+
51
+ # Saves the resource to the Bodhi Cloud. Raises ArgumentError if record could not be saved.
52
+ #
53
+ # obj = Resouce.new
54
+ # obj.save!
55
+ # obj.persisted? # => true
56
+ def save!
57
+ result = bodhi_context.connection.post do |request|
58
+ request.url "/#{bodhi_context.namespace}/users"
59
+ request.headers['Content-Type'] = 'application/json'
60
+ request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
61
+ request.body = attributes.to_json
62
+ end
63
+
64
+ if result.status != 201
65
+ raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
66
+ end
67
+ end
68
+
69
+ def delete!
70
+ result = bodhi_context.connection.delete do |request|
71
+ request.url "/#{bodhi_context.namespace}/users/#{username}"
72
+ request.headers[bodhi_context.credentials_header] = bodhi_context.credentials
73
+ end
74
+
75
+ if result.status != 204
76
+ raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
77
+ end
78
+ end
79
+
80
+ # Returns a factory for the Bodhi::User class
81
+ def self.factory
82
+ @factory ||= Bodhi::Factory.new(Bodhi::User).tap do |factory|
83
+ factory.add_generator(:username, type: "String", required: true, is_not_blank: true)
84
+ factory.add_generator(:password, type: "String", required: true, is_not_blank: true)
85
+ factory.add_generator(:profiles, type: "String", required: true, multi: true)
86
+ factory.add_generator(:email, type: "String", is_email: true)
87
+ factory.add_generator(:firstName, type: "String")
88
+ factory.add_generator(:lastName, type: "String")
89
+ factory.add_generator(:phone, type: "String")
90
+ end
91
+ end
92
+
93
+ # Queries the Bodhi API for the given +user_name+ and
94
+ # returns a Bodhi::User
95
+ #
96
+ # context = BodhiContext.new(valid_params)
97
+ # user = Bodhi::User.find(context, "User1")
98
+ # user # => #<Bodhi::User:0x007fbff403e808 @username="User1">
99
+ def self.find(context, user_name)
100
+ if context.invalid?
101
+ raise context.errors, context.errors.to_a.to_s
102
+ end
103
+
104
+ result = context.connection.get do |request|
105
+ request.url "/#{context.namespace}/users/#{user_name}"
106
+ request.headers[context.credentials_header] = context.credentials
107
+ end
108
+
109
+ if result.status != 200
110
+ raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
111
+ end
112
+
113
+ user = Bodhi::User.new(result)
114
+ user.bodhi_context = context
115
+ user
116
+ end
117
+
118
+ # Queries the Bodhi API for the users account info
119
+ #
120
+ # context = BodhiContext.new(valid_params)
121
+ # user_properties = Bodhi::User.find_me(context)
122
+ def self.find_me(context)
123
+ if context.invalid?
124
+ raise context.errors, context.errors.to_a.to_s
125
+ end
126
+
127
+ result = context.connection.get do |request|
128
+ request.url "/me"
129
+ request.headers[context.credentials_header] = context.credentials
130
+ end
131
+
132
+ if result.status != 200
133
+ raise Bodhi::ApiErrors.new(body: result.body, status: result.status), "status: #{result.status}, body: #{result.body}"
134
+ end
135
+
136
+ result
137
+ end
138
+ end
139
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bodhi-slam
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - willdavis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-20 00:00:00.000000000 Z
11
+ date: 2015-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-http-persistent
@@ -101,6 +101,8 @@ extensions: []
101
101
  extra_rdoc_files: []
102
102
  files:
103
103
  - lib/bodhi-slam.rb
104
+ - lib/bodhi-slam/batches.rb
105
+ - lib/bodhi-slam/batches/resource.rb
104
106
  - lib/bodhi-slam/context.rb
105
107
  - lib/bodhi-slam/enumerations.rb
106
108
  - lib/bodhi-slam/errors.rb
@@ -109,6 +111,7 @@ files:
109
111
  - lib/bodhi-slam/factory.rb
110
112
  - lib/bodhi-slam/resource.rb
111
113
  - lib/bodhi-slam/types.rb
114
+ - lib/bodhi-slam/users.rb
112
115
  - lib/bodhi-slam/validations.rb
113
116
  - lib/bodhi-slam/validators.rb
114
117
  - lib/bodhi-slam/validators/blank.rb