bodhi-slam 0.2.5 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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