jfoundry 0.1.0.pre

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.
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