jfoundry 0.1.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/LICENSE +746 -0
  2. data/Rakefile +10 -0
  3. data/lib/cc_api_stub/applications.rb +53 -0
  4. data/lib/cc_api_stub/domains.rb +32 -0
  5. data/lib/cc_api_stub/frameworks.rb +22 -0
  6. data/lib/cc_api_stub/helper.rb +139 -0
  7. data/lib/cc_api_stub/login.rb +21 -0
  8. data/lib/cc_api_stub/organization_users.rb +21 -0
  9. data/lib/cc_api_stub/organizations.rb +70 -0
  10. data/lib/cc_api_stub/routes.rb +26 -0
  11. data/lib/cc_api_stub/runtimes.rb +22 -0
  12. data/lib/cc_api_stub/service_bindings.rb +22 -0
  13. data/lib/cc_api_stub/service_instances.rb +22 -0
  14. data/lib/cc_api_stub/services.rb +21 -0
  15. data/lib/cc_api_stub/spaces.rb +49 -0
  16. data/lib/cc_api_stub/users.rb +85 -0
  17. data/lib/cc_api_stub.rb +16 -0
  18. data/lib/jfoundry/auth_token.rb +63 -0
  19. data/lib/jfoundry/baseclient.rb +177 -0
  20. data/lib/jfoundry/chatty_hash.rb +46 -0
  21. data/lib/jfoundry/client.rb +39 -0
  22. data/lib/jfoundry/concerns/proxy_options.rb +17 -0
  23. data/lib/jfoundry/errors.rb +163 -0
  24. data/lib/jfoundry/rest_client.rb +331 -0
  25. data/lib/jfoundry/signature/version.rb +27 -0
  26. data/lib/jfoundry/signer.rb +13 -0
  27. data/lib/jfoundry/test_support.rb +3 -0
  28. data/lib/jfoundry/timer.rb +13 -0
  29. data/lib/jfoundry/trace_helpers.rb +64 -0
  30. data/lib/jfoundry/upload_helpers.rb +222 -0
  31. data/lib/jfoundry/v2/app.rb +357 -0
  32. data/lib/jfoundry/v2/app_event.rb +13 -0
  33. data/lib/jfoundry/v2/base.rb +92 -0
  34. data/lib/jfoundry/v2/client.rb +78 -0
  35. data/lib/jfoundry/v2/domain.rb +20 -0
  36. data/lib/jfoundry/v2/managed_service_instance.rb +13 -0
  37. data/lib/jfoundry/v2/model.rb +209 -0
  38. data/lib/jfoundry/v2/model_magic/attribute.rb +49 -0
  39. data/lib/jfoundry/v2/model_magic/client_extensions.rb +170 -0
  40. data/lib/jfoundry/v2/model_magic/has_summary.rb +49 -0
  41. data/lib/jfoundry/v2/model_magic/queryable_by.rb +39 -0
  42. data/lib/jfoundry/v2/model_magic/to_many.rb +138 -0
  43. data/lib/jfoundry/v2/model_magic/to_one.rb +81 -0
  44. data/lib/jfoundry/v2/model_magic.rb +93 -0
  45. data/lib/jfoundry/v2/organization.rb +22 -0
  46. data/lib/jfoundry/v2/quota_definition.rb +12 -0
  47. data/lib/jfoundry/v2/route.rb +25 -0
  48. data/lib/jfoundry/v2/service.rb +20 -0
  49. data/lib/jfoundry/v2/service_auth_token.rb +10 -0
  50. data/lib/jfoundry/v2/service_binding.rb +10 -0
  51. data/lib/jfoundry/v2/service_broker.rb +11 -0
  52. data/lib/jfoundry/v2/service_instance.rb +13 -0
  53. data/lib/jfoundry/v2/service_plan.rb +13 -0
  54. data/lib/jfoundry/v2/space.rb +18 -0
  55. data/lib/jfoundry/v2/stack.rb +10 -0
  56. data/lib/jfoundry/v2/user.rb +104 -0
  57. data/lib/jfoundry/v2/user_provided_service_instance.rb +7 -0
  58. data/lib/jfoundry/validator.rb +41 -0
  59. data/lib/jfoundry/version.rb +4 -0
  60. data/lib/jfoundry/zip.rb +56 -0
  61. data/lib/jfoundry.rb +5 -0
  62. data/lib/tasks/gem_release.rake +42 -0
  63. data/vendor/errors/README.md +3 -0
  64. data/vendor/errors/v1.yml +189 -0
  65. data/vendor/errors/v2.yml +470 -0
  66. metadata +269 -0
@@ -0,0 +1,209 @@
1
+ require "multi_json"
2
+ require "jfoundry/v2/model_magic"
3
+
4
+ module JFoundry::V2
5
+ class Model
6
+ include ActiveModel::Validations
7
+
8
+ @@objects = {}
9
+
10
+ extend ModelMagic
11
+
12
+ class << self
13
+ def objects
14
+ @@objects
15
+ end
16
+
17
+ def inherited(klass)
18
+ @@objects[klass.object_name] = klass
19
+ super
20
+ end
21
+ end
22
+
23
+ attr_accessor :guid, :cache, :changes
24
+ attr_reader :created_at, :updated_at
25
+ attr_reader :diff
26
+
27
+ def initialize(guid, client, manifest = nil, partial = false)
28
+ @guid = guid
29
+ @client = client
30
+ @manifest = manifest
31
+ @partial = partial
32
+ @cache = {}
33
+ @diff = {}
34
+ @changes = {}
35
+ end
36
+
37
+ def created_at
38
+ timestamp = @manifest.try(:[], :metadata).try(:[], :created_at)
39
+ DateTime.parse(timestamp) if timestamp.present?
40
+ end
41
+
42
+ def updated_at
43
+ timestamp = @manifest.try(:[], :metadata).try(:[], :updated_at)
44
+ DateTime.parse(timestamp) if timestamp.present?
45
+ end
46
+
47
+ def manifest
48
+ @manifest ||= @client.base.send(object_name, @guid)
49
+ end
50
+
51
+ def partial?
52
+ @partial
53
+ end
54
+
55
+ def changed?
56
+ !@changes.empty?
57
+ end
58
+
59
+ def inspect
60
+ "\#<#{self.class.name} '#@guid'>"
61
+ end
62
+
63
+ def object_name
64
+ @object_name ||= self.class.object_name
65
+ end
66
+
67
+ def plural_object_name
68
+ @plural_object_name ||= self.class.plural_object_name
69
+ end
70
+
71
+ def invalidate!
72
+ @manifest = nil
73
+ @partial = false
74
+ @cache = {}
75
+ @diff = {}
76
+ @changes = {}
77
+ end
78
+
79
+ def create
80
+ create!
81
+ true
82
+ rescue JFoundry::APIError => e
83
+ if e.instance_of? JFoundry::APIError
84
+ errors.add(:base, :cc_client)
85
+ else
86
+ errors.add(attribute_for_error(e), e.message)
87
+ end
88
+ false
89
+ end
90
+
91
+ def attribute_for_error(error)
92
+ :base
93
+ end
94
+
95
+ # this does a bit of extra processing to allow for
96
+ # `delete!' followed by `create!'
97
+ def create!
98
+ payload = {}
99
+
100
+ @manifest ||= {}
101
+ @manifest[:entity] ||= {}
102
+
103
+ @manifest[:entity].each do |k, v|
104
+ if v.is_a?(Hash) && v.key?(:metadata)
105
+ # skip; there's a _guid attribute already
106
+ elsif v.is_a?(Array) && !v.empty? && v.all? { |x|
107
+ x.is_a?(Hash) && x.key?(:metadata)
108
+ }
109
+ singular = k.to_s.sub(/s$/, "")
110
+
111
+ payload[:"#{singular}_guids"] = v.collect do |x|
112
+ if x.is_a?(Hash) && x.key?(:metadata)
113
+ x[:metadata][:guid]
114
+ else
115
+ x
116
+ end
117
+ end
118
+ else
119
+ payload[k] = v
120
+ end
121
+ end
122
+
123
+ #puts "payload: ", payload
124
+ #puts "plural_object_name: ", plural_object_name
125
+ @manifest = @client.base.post("v2", plural_object_name,
126
+ :content => :json,
127
+ :accept => :json,
128
+ :payload => payload
129
+ )
130
+
131
+ @guid = @manifest[:metadata][:guid]
132
+
133
+ @diff.clear
134
+
135
+ true
136
+ end
137
+
138
+ def update!
139
+ @manifest = @client.base.put("v2", plural_object_name, guid,
140
+ :content => :json,
141
+ :accept => :json,
142
+ :payload => @diff
143
+ )
144
+
145
+ @diff.clear
146
+
147
+ true
148
+ end
149
+
150
+ def delete(options = {})
151
+ delete!(options)
152
+ rescue JFoundry::APIError => e
153
+ if e.instance_of? JFoundry::APIError
154
+ errors.add(:base, :cc_client)
155
+ else
156
+ errors.add(attribute_for_error(e), e.message)
157
+ end
158
+ false
159
+ end
160
+
161
+ def delete!(options = {})
162
+ @client.base.delete("v2", plural_object_name, guid, :params => options)
163
+
164
+ @deleted = true
165
+
166
+ @diff.clear
167
+
168
+ if @manifest
169
+ @manifest.delete :metadata
170
+ end
171
+
172
+ true
173
+ end
174
+
175
+ def to_param
176
+ persisted? ? @guid.to_s : nil
177
+ end
178
+
179
+ def to_key
180
+ persisted? ? [@guid] : nil
181
+ end
182
+
183
+ def persisted?
184
+ @guid && !@deleted
185
+ end
186
+
187
+ def exists?
188
+ invalidate!
189
+ manifest
190
+ true
191
+ rescue JFoundry::NotFound
192
+ false
193
+ end
194
+
195
+ def query_target(klass)
196
+ self
197
+ end
198
+
199
+ def eql?(other)
200
+ other.is_a?(self.class) && @guid == other.guid
201
+ end
202
+
203
+ alias :== :eql?
204
+
205
+ def hash
206
+ @guid.hash
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,49 @@
1
+ module JFoundry::V2::ModelMagic
2
+ module Attribute
3
+ def attribute(name, type, opts = {})
4
+ attributes[name] = opts
5
+ json_name = opts[:at] || name
6
+
7
+ default = opts[:default]
8
+
9
+ if has_default = opts.key?(:default)
10
+ defaults[name] = default
11
+ end
12
+
13
+ #
14
+ # def ATTRIBUTE
15
+ #
16
+ define_method(name) do
17
+ return @cache[name] if @cache.key?(name)
18
+ return nil unless persisted?
19
+
20
+ @cache[name] =
21
+ if manifest[:entity].key?(json_name)
22
+ manifest[:entity][json_name]
23
+ else
24
+ default
25
+ end
26
+ end
27
+
28
+ #
29
+ # def ATTRIBUTE=
30
+ #
31
+ define_method(:"#{name}=") do |val|
32
+ unless has_default && val == default
33
+ JFoundry::Validator.validate_type(val, type)
34
+ end
35
+
36
+ @cache[name] = val
37
+
38
+ @manifest ||= {}
39
+ @manifest[:entity] ||= {}
40
+
41
+ old = @manifest[:entity][json_name]
42
+ @changes[name] = [old, val] if old != val
43
+ @manifest[:entity][json_name] = val
44
+
45
+ @diff[json_name] = val
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,170 @@
1
+ module JFoundry
2
+ module V2
3
+ module ModelMagic
4
+ module ClientExtensions
5
+ def add_client_methods(klass)
6
+ singular = klass.object_name
7
+ plural = klass.plural_object_name
8
+
9
+ define_base_client_methods do
10
+ #
11
+ # def client.MODEL
12
+ #
13
+ define_method(singular) do |guid, *args|
14
+ get("v2", plural, guid,
15
+ :accept => :json,
16
+ :params => ModelMagic.params_from(args)
17
+ )
18
+ end
19
+
20
+ #
21
+ # def client.MODELs
22
+ #
23
+ define_method(plural) do |*args|
24
+ all_pages(
25
+ get("v2", plural,
26
+ :accept => :json,
27
+ :params => ModelMagic.params_from(args)
28
+ )
29
+ )
30
+ end
31
+
32
+ #
33
+ # def client.MODELs_first_page
34
+ #
35
+ define_method(:"#{plural}_first_page") do |*args|
36
+ get("v2", plural,
37
+ :accept => :json,
38
+ :params => ModelMagic.params_from(args)
39
+ )
40
+ end
41
+
42
+ #
43
+ # def client.MODELs_for_each
44
+ #
45
+ define_method(:"#{plural}_for_each") do |*args, &block|
46
+ for_each(get("v2", plural,
47
+ :accept => :json,
48
+ :params => ModelMagic.params_from(args)
49
+ ),
50
+ &block
51
+ )
52
+ end
53
+ end
54
+
55
+
56
+ define_client_methods do
57
+ #
58
+ # def client.MODEL
59
+ #
60
+ define_method(singular) do |*args|
61
+ guid, partial, _ = args
62
+
63
+ x = klass.new(guid, self, nil, partial)
64
+
65
+ # when creating an object, automatically set the org/space
66
+ unless guid
67
+ if klass.scoped_organization && current_organization
68
+ x.send(:"#{klass.scoped_organization}=", current_organization)
69
+ end
70
+
71
+ if klass.scoped_space && current_space
72
+ x.send(:"#{klass.scoped_space}=", current_space)
73
+ end
74
+ end
75
+
76
+ x
77
+ end
78
+
79
+ #
80
+ # def client.MODELs
81
+ #
82
+ define_method(plural) do |*args|
83
+ # use current org/space
84
+ if klass.scoped_space && current_space
85
+ current_space.send(plural, *args)
86
+ elsif klass.scoped_organization && current_organization
87
+ current_organization.send(plural, *args)
88
+ else
89
+ @base.send(plural, *args).collect do |json|
90
+ send(:"make_#{singular}", json)
91
+ end
92
+ end
93
+ end
94
+
95
+ #
96
+ # def client.MODELs_first_page
97
+ #
98
+ define_method(:"#{plural}_first_page") do |*args|
99
+ response = @base.send(:"#{plural}_first_page", *args)
100
+ results = response[:resources].collect do |json|
101
+ send(:"make_#{singular}", json)
102
+ end
103
+ {
104
+ :next_page => !!response[:next_url],
105
+ :results => results
106
+ }
107
+ end
108
+
109
+ #
110
+ # def client.MODELs_for_each
111
+ #
112
+ define_method(:"#{plural}_for_each") do |*args, &block|
113
+ @base.send(:"#{plural}_for_each", *args) do |json|
114
+ result = send(:"make_#{singular}", json)
115
+ block.call(result)
116
+ end
117
+ end
118
+
119
+ #
120
+ # def client.MODEL_from
121
+ #
122
+ define_method(:"#{singular}_from") do |path, *args|
123
+ send(
124
+ :"make_#{singular}",
125
+ @base.get(
126
+ path,
127
+ :accept => :json,
128
+ :params => ModelMagic.params_from(args)))
129
+ end
130
+
131
+ #
132
+ # def client.MODELs_from
133
+ #
134
+ define_method(:"#{plural}_from") do |path, *args|
135
+ objs = @base.all_pages(
136
+ @base.get(
137
+ path,
138
+ :accept => :json,
139
+ :params => ModelMagic.params_from(args)))
140
+
141
+ objs.collect do |json|
142
+ send(:"make_#{singular}", json)
143
+ end
144
+ end
145
+
146
+ #
147
+ # def client.make_MODEL
148
+ #
149
+ define_method(:"make_#{singular}") do |json|
150
+ klass.new(
151
+ json[:metadata][:guid],
152
+ self,
153
+ json)
154
+ end
155
+ end
156
+ end
157
+
158
+ private
159
+
160
+ def define_client_methods(&blk)
161
+ ClientMethods.module_eval(&blk)
162
+ end
163
+
164
+ def define_base_client_methods(&blk)
165
+ BaseClientMethods.module_eval(&blk)
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,49 @@
1
+ module JFoundry::V2::ModelMagic
2
+ module HasSummary
3
+ def has_summary(actions = {})
4
+ #
5
+ # def summary
6
+ #
7
+ define_method(:summary) do
8
+ @client.base.get("v2", plural_object_name, @guid, "summary", :accept => :json)
9
+ end
10
+
11
+ #
12
+ # def summarize!
13
+ #
14
+ define_method(:summarize!) do |*args|
15
+ body, _ = args
16
+
17
+ body ||= summary
18
+
19
+ body.each do |key, val|
20
+ if act = actions[key]
21
+ instance_exec(val, &act)
22
+
23
+ elsif self.class.attributes[key]
24
+ self.send(:"#{key}=", val)
25
+
26
+ elsif self.class.to_many_relations[key]
27
+ singular = key.to_s.sub(/s$/, "").to_sym
28
+
29
+ vals = val.collect do |sub|
30
+ obj = @client.send(singular, sub[:guid], true)
31
+ obj.summarize! sub
32
+ obj
33
+ end
34
+
35
+ self.send(:"#{key}=", vals)
36
+
37
+ elsif self.class.to_one_relations[key]
38
+ obj = @client.send(key, val[:guid], true)
39
+ obj.summarize! val
40
+
41
+ self.send(:"#{key}=", obj)
42
+ end
43
+ end
44
+
45
+ nil
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,39 @@
1
+ module JFoundry::V2
2
+ module ModelMagic::QueryableBy
3
+ def queryable_by(*names)
4
+ klass = self
5
+ singular = object_name
6
+ plural = plural_object_name
7
+
8
+ query = ::JFoundry::V2::QUERIES[singular]
9
+
10
+ query.module_eval do
11
+ names.each do |name|
12
+ #
13
+ # def MODEL_by_ATTRIBUTE
14
+ #
15
+ define_method(:"#{singular}_by_#{name}") do |*args|
16
+ send(:"#{plural}_by_#{name}", *args).first
17
+ end
18
+
19
+ #
20
+ # def MODELs_by_ATTRIBUTE
21
+ #
22
+ define_method(:"#{plural}_by_#{name}") do |val, *args|
23
+ options, _ = args
24
+ options ||= {}
25
+ options[:query] = [name, val]
26
+
27
+ query_target(klass).send(plural, options)
28
+ end
29
+ end
30
+ end
31
+
32
+ const_set(:Queries, query)
33
+
34
+ ClientMethods.module_eval do
35
+ include query
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,138 @@
1
+ module JFoundry::V2::ModelMagic
2
+ module ToMany
3
+ def to_many(plural, opts = {})
4
+ to_many_relations[plural] = opts
5
+
6
+ singular = plural.to_s.sub(/s$/, "").to_sym
7
+
8
+ include ::JFoundry::V2::QUERIES[singular]
9
+
10
+ object = opts[:as] || singular
11
+
12
+ kls = object.to_s.camelcase
13
+
14
+ #
15
+ # def MODELs
16
+ #
17
+ define_method(plural) do |*args|
18
+ klass = JFoundry::V2.const_get(kls)
19
+
20
+ opts, _ = args
21
+ opts ||= {}
22
+
23
+ if opts.empty? && cache = @cache[plural]
24
+ return cache
25
+ end
26
+
27
+ if @manifest && @manifest[:entity].key?(plural) && opts.empty?
28
+ objs = @manifest[:entity][plural]
29
+
30
+ if query = opts[:query]
31
+ find_by, find_val = query
32
+ objs = objs.select { |o| o[:entity][find_by] == find_val }
33
+ end
34
+
35
+ res =
36
+ objs.collect do |json|
37
+ @client.send(:"make_#{object}", json)
38
+ end
39
+ else
40
+ res =
41
+ @client.send(
42
+ :"#{klass.plural_object_name}_from",
43
+ "/v2/#{plural_object_name}/#@guid/#{plural}",
44
+ opts)
45
+ end
46
+
47
+ if opts.empty?
48
+ @cache[plural] = res
49
+ end
50
+
51
+ res
52
+ end
53
+
54
+ #
55
+ # def MODELs_url
56
+ #
57
+ define_method(:"#{plural}_url") do
58
+ manifest[:entity][:"#{plural}_url"]
59
+ end
60
+
61
+ #
62
+ # def add_MODEL
63
+ #
64
+ define_method(:"add_#{singular}") do |x|
65
+ klass = self.class.objects[object]
66
+
67
+ JFoundry::Validator.validate_type(x, klass)
68
+
69
+ if cache = @cache[plural]
70
+ cache << x unless cache.include?(x)
71
+ end
72
+
73
+ @client.base.put("v2", plural_object_name, @guid, plural, x.guid, :accept => :json)
74
+ end
75
+
76
+ #
77
+ # def create_MODEL
78
+ #
79
+ define_method("create_#{singular}") do |*args|
80
+ associated_instance = @client.send(:"#{singular}")
81
+ args.first.each do |name, value|
82
+ associated_instance.send("#{name}=", value)
83
+ end if args.first.is_a? Hash
84
+
85
+ associated_instance.create!
86
+ self.send(:"add_#{singular}", associated_instance)
87
+ associated_instance
88
+ end
89
+
90
+ #
91
+ # def remove_MODEL
92
+ #
93
+ define_method(:"remove_#{singular}") do |x|
94
+ klass = self.class.objects[object]
95
+
96
+ JFoundry::Validator.validate_type(x, klass)
97
+
98
+ if cache = @cache[plural]
99
+ cache.delete(x)
100
+ end
101
+
102
+ @client.base.delete("v2", plural_object_name, @guid, plural, x.guid, :accept => :json)
103
+ end
104
+
105
+ #
106
+ # def MODELs=
107
+ #
108
+ define_method(:"#{plural}=") do |xs|
109
+ klass = self.class.objects[object]
110
+
111
+ JFoundry::Validator.validate_type(xs, [klass])
112
+
113
+ @manifest ||= {}
114
+ @manifest[:entity] ||= {}
115
+
116
+ old = @manifest[:entity][:"#{singular}_guids"]
117
+ if old != xs.collect(&:guid)
118
+ old_objs =
119
+ @cache[plural] ||
120
+ if all = @manifest[:entity][plural]
121
+ all.collect do |m|
122
+ klass.new(@client, m[:metadata][:guid], m)
123
+ end
124
+ elsif old
125
+ old.collect { |id| klass.new(@client, id) }
126
+ end
127
+
128
+ @changes[plural] = [old_objs, xs]
129
+ end
130
+
131
+ @cache[plural] = xs
132
+
133
+ @manifest[:entity][:"#{singular}_guids"] =
134
+ @diff[:"#{singular}_guids"] = xs.collect(&:guid)
135
+ end
136
+ end
137
+ end
138
+ end