nurego 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/Gemfile +3 -0
  2. data/Gemfile.lock +59 -0
  3. data/LICENSE +32 -0
  4. data/README.md +25 -0
  5. data/Rakefile +41 -0
  6. data/VERSION +1 -0
  7. data/examples/enumerate_plans.rb +17 -0
  8. data/lib/data/ca-certificates.crt +53 -0
  9. data/lib/nurego.rb +287 -0
  10. data/lib/nurego/api_operations/create.rb +16 -0
  11. data/lib/nurego/api_operations/delete.rb +11 -0
  12. data/lib/nurego/api_operations/list.rb +16 -0
  13. data/lib/nurego/api_operations/update.rb +37 -0
  14. data/lib/nurego/api_resource.rb +33 -0
  15. data/lib/nurego/auth.rb +112 -0
  16. data/lib/nurego/bill.rb +6 -0
  17. data/lib/nurego/connector.rb +7 -0
  18. data/lib/nurego/customer.rb +29 -0
  19. data/lib/nurego/entitlement.rb +27 -0
  20. data/lib/nurego/errors/api_connection_error.rb +4 -0
  21. data/lib/nurego/errors/api_error.rb +4 -0
  22. data/lib/nurego/errors/authentication_error.rb +4 -0
  23. data/lib/nurego/errors/card_error.rb +10 -0
  24. data/lib/nurego/errors/invalid_request_error.rb +10 -0
  25. data/lib/nurego/errors/nurego_error.rb +24 -0
  26. data/lib/nurego/errors/user_not_found_error.rb +4 -0
  27. data/lib/nurego/feature.rb +5 -0
  28. data/lib/nurego/instance.rb +9 -0
  29. data/lib/nurego/json.rb +21 -0
  30. data/lib/nurego/list_object.rb +35 -0
  31. data/lib/nurego/nurego_object.rb +167 -0
  32. data/lib/nurego/offering.rb +17 -0
  33. data/lib/nurego/organization.rb +23 -0
  34. data/lib/nurego/password_reset.rb +14 -0
  35. data/lib/nurego/payment_method.rb +16 -0
  36. data/lib/nurego/plan.rb +9 -0
  37. data/lib/nurego/registration.rb +18 -0
  38. data/lib/nurego/util.rb +109 -0
  39. data/lib/nurego/version.rb +3 -0
  40. data/nurego.gemspec +31 -0
  41. data/spec/unit/nurego/api_resource_spec.rb +326 -0
  42. data/spec/unit/nurego/customer_spec.rb +75 -0
  43. data/spec/unit/nurego/list_object_spec.rb +14 -0
  44. data/spec/unit/nurego/util_spec.rb +27 -0
  45. data/spec/unit/test_helper.rb +94 -0
  46. metadata +279 -0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,59 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ nurego (1.0.0)
5
+ cf-uaa-lib (= 1.3.10)
6
+ mime-types (~> 1.25)
7
+ multi_json (>= 1.0.4, < 2)
8
+ rest-client (~> 1.4)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ builder (3.2.2)
14
+ cf-uaa-lib (1.3.10)
15
+ multi_json
16
+ ci_reporter (1.9.2)
17
+ builder (>= 2.1.2)
18
+ diff-lcs (1.2.5)
19
+ docile (1.1.3)
20
+ mime-types (1.25.1)
21
+ multi_json (1.10.0)
22
+ rack (1.5.2)
23
+ rack-test (0.6.2)
24
+ rack (>= 1.0)
25
+ rake (10.3.1)
26
+ rest-client (1.6.7)
27
+ mime-types (>= 1.16)
28
+ rspec (2.14.1)
29
+ rspec-core (~> 2.14.0)
30
+ rspec-expectations (~> 2.14.0)
31
+ rspec-mocks (~> 2.14.0)
32
+ rspec-core (2.14.8)
33
+ rspec-expectations (2.14.5)
34
+ diff-lcs (>= 1.1.3, < 2.0)
35
+ rspec-mocks (2.14.6)
36
+ simplecov (0.8.2)
37
+ docile (~> 1.1.0)
38
+ multi_json
39
+ simplecov-html (~> 0.8.0)
40
+ simplecov-csv (0.1.3)
41
+ simplecov
42
+ simplecov-html (0.8.0)
43
+ simplecov-rcov (0.2.3)
44
+ simplecov (>= 0.4.1)
45
+ uuidtools (2.1.4)
46
+
47
+ PLATFORMS
48
+ ruby
49
+
50
+ DEPENDENCIES
51
+ ci_reporter
52
+ nurego!
53
+ rack-test
54
+ rake
55
+ rspec
56
+ simplecov
57
+ simplecov-csv
58
+ simplecov-rcov
59
+ uuidtools
data/LICENSE ADDED
@@ -0,0 +1,32 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2013- Nurego, Inc. (http://www.nurego.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
22
+
23
+
24
+ Copyright (c) 2011- Stripe, Inc. (https://stripe.com)
25
+
26
+ Permission is hereby granted, free of charge, to any person obtaining a copy
27
+ of this software and associated documentation files (the "Software"), to deal
28
+ in the Software without restriction, including without limitation the rights
29
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30
+ copies of the Software, and to permit persons to whom the Software is
31
+ furnished to do so, subject to the following conditions:
32
+
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ nurego-ruby
2
+ ===========
3
+
4
+ Ruby bindings for Nurego API
5
+
6
+ == Installation
7
+
8
+ You don't need this source code unless you want to modify the gem. If
9
+ you just want to use the Nurego Ruby bindings, you should run:
10
+
11
+ gem install nurego
12
+
13
+ If you want to build the gem from source:
14
+
15
+ gem build nurego.gemspec
16
+
17
+ == Requirements
18
+
19
+ * Ruby 1.8.7 or above.
20
+
21
+ == Development
22
+
23
+ Test cases can be run with: `bundle exec rake spec:unit`
24
+
25
+ Examples can be run with: `bundle install; ruby -I./lib examples/<example_name>.rb`
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require 'rspec'
2
+ require "rspec/core/rake_task"
3
+ require "rack/test"
4
+ require "ci/reporter/rake/rspec"
5
+
6
+
7
+ namespace "spec" do
8
+ RSpec::Core::RakeTask.new("unit") do |t|
9
+ t.rspec_opts = ["--format", "documentation", "--colour"]
10
+ t.pattern = "**/unit/**/*_spec.rb"
11
+ end
12
+
13
+ RSpec::Core::RakeTask.new("integration") do |t|
14
+ t.rspec_opts = ["--format", "documentation", "--colour"]
15
+ t.pattern = "**/integration/**/*_spec.rb"
16
+ end
17
+
18
+ desc "Run specs with code coverage"
19
+ task :rcov => ["ci:setup:rspec"] do
20
+ require 'simplecov'
21
+ require 'simplecov-rcov'
22
+ require 'simplecov-csv'
23
+
24
+ FileUtils.rm_rf File.join('.', "coverage")
25
+
26
+ SimpleCov.start do
27
+ formatter SimpleCov::Formatter::CSVFormatter
28
+ coverage_dir ENV["COVERAGE_REPORTS"]
29
+ root '.'
30
+
31
+ add_filter "/spec/"
32
+
33
+ RSpec::Core::Runner.disable_autorun!
34
+ exit 1 unless RSpec::Core::Runner.run(['spec/unit'], STDERR, STDOUT) == 0
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ task :default => [:spec]
41
+ task :spec => ['spec:unit']
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.1
@@ -0,0 +1,17 @@
1
+ require "nurego"
2
+
3
+ Nurego.api_base = "https://api.nurego.com"
4
+ Nurego.api_key = "YOUR INSTANCE KEY" #login to nurego.com and check Settings/Organization for api keys
5
+
6
+ begin
7
+ offering = Nurego::Offering.current
8
+ offering.plans.each do |plan|
9
+ puts plan.inspect
10
+ plan.features.each do |feature|
11
+ puts feature.inspect
12
+ end
13
+ end
14
+ rescue Nurego::NuregoError => e
15
+ puts "ERROR #{e.error_code}"
16
+ end
17
+
@@ -0,0 +1,53 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
3
+ ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
4
+ RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
5
+ MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH
6
+ QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
7
+ b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
8
+ b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj
9
+ YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN
10
+ AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H
11
+ KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm
12
+ VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR
13
+ SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT
14
+ cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ
15
+ 6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu
16
+ MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS
17
+ kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB
18
+ BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
19
+ BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
20
+ c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH
21
+ AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO
22
+ BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG
23
+ OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU
24
+ A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o
25
+ 0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
26
+ RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
27
+ qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
28
+ U+4=
29
+ -----END CERTIFICATE-----
30
+ -----BEGIN CERTIFICATE-----
31
+ MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
32
+ MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
33
+ YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
34
+ MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
35
+ ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
36
+ MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
37
+ ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
38
+ PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
39
+ wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
40
+ EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
41
+ avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
42
+ YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
43
+ sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
44
+ /t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
45
+ IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
46
+ YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
47
+ ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
48
+ OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
49
+ TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
50
+ HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
51
+ dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
52
+ ReYNnyicsbkqWletNw+vHX/bvZ8=
53
+ -----END CERTIFICATE-----
data/lib/nurego.rb ADDED
@@ -0,0 +1,287 @@
1
+ # Nurego Ruby bindings
2
+ # API spec at http://www.nurego.com/docs/api
3
+ require 'cgi'
4
+ require 'set'
5
+ require 'openssl'
6
+ require 'rest_client'
7
+ require 'multi_json'
8
+
9
+ # Version
10
+ require 'nurego/version'
11
+
12
+ # API operations
13
+ require 'nurego/api_operations/create'
14
+ require 'nurego/api_operations/update'
15
+ require 'nurego/api_operations/delete'
16
+ require 'nurego/api_operations/list'
17
+
18
+ # Resources
19
+ require 'nurego/util'
20
+ require 'nurego/json'
21
+ require 'nurego/auth'
22
+ require 'nurego/nurego_object'
23
+ require 'nurego/api_resource'
24
+ require 'nurego/list_object'
25
+ require 'nurego/registration'
26
+ require 'nurego/customer'
27
+ require 'nurego/organization'
28
+ require 'nurego/instance'
29
+ require 'nurego/connector'
30
+ require 'nurego/password_reset'
31
+ require 'nurego/offering'
32
+ require 'nurego/plan'
33
+ require 'nurego/feature'
34
+ require 'nurego/bill'
35
+ require 'nurego/payment_method'
36
+ require 'nurego/entitlement'
37
+
38
+
39
+ # Errors
40
+ require 'nurego/errors/nurego_error'
41
+ require 'nurego/errors/api_error'
42
+ require 'nurego/errors/api_connection_error'
43
+ require 'nurego/errors/invalid_request_error'
44
+ require 'nurego/errors/card_error'
45
+ require 'nurego/errors/authentication_error'
46
+ require 'nurego/errors/user_not_found_error'
47
+
48
+ module Nurego
49
+ @api_base = 'https://api.nurego.com'
50
+
51
+ @ssl_bundle_path = File.dirname(__FILE__) + '/data/ca-certificates.crt'
52
+ @verify_ssl_certs = true
53
+
54
+ @logger = nil
55
+
56
+ class << self
57
+ attr_accessor :api_key, :api_base, :verify_ssl_certs, :api_version, :logger
58
+ end
59
+
60
+ def self.api_url(url='')
61
+ @api_base + url
62
+ end
63
+
64
+ def self.request(method, url, api_key, params={}, headers={})
65
+ unless api_key ||= @api_key
66
+ raise AuthenticationError.new('No API key provided. ' +
67
+ 'Set your API key using "Nurego.api_key = <API-KEY>". ' +
68
+ 'You can generate API keys from the Nurego web interface. ' +
69
+ 'See https://www.nurego.com/api for details, or email support@nurego.com ' +
70
+ 'if you have any questions.')
71
+ end
72
+
73
+ if api_key =~ /\s/
74
+ raise AuthenticationError.new('Your API key is invalid, as it contains ' +
75
+ 'whitespace. (HINT: You can double-check your API key from the ' +
76
+ 'Nurego web interface. See https://www.nurego.com/api for details, or ' +
77
+ 'email support@nurego.com if you have any questions.)')
78
+ end
79
+
80
+ request_opts = { :verify_ssl => false }
81
+
82
+ if ssl_preflight_passed?
83
+ request_opts.update(:verify_ssl => OpenSSL::SSL::VERIFY_PEER,
84
+ :ssl_ca_file => @ssl_bundle_path)
85
+ end
86
+
87
+ params = Util.objects_to_ids(params)
88
+ url = api_url(url)
89
+
90
+ case method.to_s.downcase.to_sym
91
+ when :get, :head, :delete
92
+ # Make params into GET parameters
93
+ url += "#{URI.parse(url).query ? '&' : '?'}#{uri_encode(params)}" if params && params.any?
94
+ payload = nil
95
+ else
96
+ payload = uri_encode(params)
97
+ end
98
+ request_opts.update(:headers => request_headers(api_key).update(headers),
99
+ :method => method, :open_timeout => 30,
100
+ :payload => payload, :url => url, :timeout => 80)
101
+
102
+ begin
103
+ response = execute_request(request_opts)
104
+ rescue SocketError => e
105
+ handle_restclient_error(e)
106
+ rescue NoMethodError => e
107
+ # Work around RestClient bug
108
+ if e.message =~ /\WRequestFailed\W/
109
+ e = APIConnectionError.new('Unexpected HTTP response code')
110
+ handle_restclient_error(e)
111
+ else
112
+ raise
113
+ end
114
+ rescue RestClient::ExceptionWithResponse => e
115
+ if rcode = e.http_code and rbody = e.http_body
116
+ handle_api_error(rcode, rbody)
117
+ else
118
+ handle_restclient_error(e)
119
+ end
120
+ rescue RestClient::Exception, Errno::ECONNREFUSED => e
121
+ handle_restclient_error(e)
122
+ end
123
+
124
+ [parse(response), api_key]
125
+ end
126
+
127
+ private
128
+
129
+ def self.ssl_preflight_passed?
130
+ if !verify_ssl_certs && !@no_verify
131
+ $stderr.puts "WARNING: Running without SSL cert verification. " +
132
+ "Execute 'Nurego.verify_ssl_certs = true' to enable verification."
133
+
134
+ @no_verify = true
135
+
136
+ elsif !Util.file_readable(@ssl_bundle_path) && !@no_bundle
137
+ $stderr.puts "WARNING: Running without SSL cert verification " +
138
+ "because #{@ssl_bundle_path} isn't readable"
139
+
140
+ @no_bundle = true
141
+ end
142
+
143
+ !(@no_verify || @no_bundle)
144
+ end
145
+
146
+ def self.user_agent
147
+ @uname ||= get_uname
148
+ lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
149
+
150
+ {
151
+ :bindings_version => Nurego::VERSION,
152
+ :lang => 'ruby',
153
+ :lang_version => lang_version,
154
+ :platform => RUBY_PLATFORM,
155
+ :publisher => 'nurego',
156
+ :uname => @uname
157
+ }
158
+
159
+ end
160
+
161
+ def self.get_uname
162
+ `uname -a 2>/dev/null`.strip if RUBY_PLATFORM =~ /linux|darwin/i
163
+ rescue Errno::ENOMEM => ex # couldn't create subprocess
164
+ "uname lookup failed"
165
+ end
166
+
167
+ def self.uri_encode(params)
168
+ Util.flatten_params(params).
169
+ map { |k,v| "#{k}=#{Util.url_encode(v)}" }.join('&')
170
+ end
171
+
172
+ def self.request_headers(api_key)
173
+ headers = {
174
+ :user_agent => "Nurego/v1 RubyBindings/#{Nurego::VERSION}",
175
+ :x_nurego_authorization => "Bearer #{api_key}",
176
+ :content_type => 'application/x-www-form-urlencoded'
177
+ }
178
+
179
+ headers[:nurego_version] = api_version if api_version
180
+ headers[:authorization] = Nurego::Auth.header_token[:token] if Nurego::Auth.header_token
181
+
182
+ begin
183
+ headers.update(:x_nurego_client_user_agent => Nurego::JSON.dump(user_agent))
184
+ rescue => e
185
+ headers.update(:x_nurego_client_raw_user_agent => user_agent.inspect,
186
+ :error => "#{e} (#{e.class})")
187
+ end
188
+ end
189
+
190
+ def self.execute_request(opts)
191
+ opts[:headers][:x_request_id] = SecureRandom.uuid
192
+
193
+ if @logger
194
+ @logger.info("nurego-ruby execute_request")
195
+ @logger.info(opts.inspect)
196
+ end
197
+
198
+ RestClient::Request.execute(opts)
199
+ end
200
+
201
+ def self.parse(response)
202
+ begin
203
+ # Would use :symbolize_names => true, but apparently there is
204
+ # some library out there that makes symbolize_names not work.
205
+ response = Nurego::JSON.load(response.body)
206
+ rescue MultiJson::DecodeError
207
+ raise general_api_error(response.code, response.body)
208
+ end
209
+
210
+ Util.symbolize_names(response)
211
+ end
212
+
213
+ def self.general_api_error(rcode, rbody)
214
+ APIError.new("Invalid response object from API: #{rbody.inspect} " +
215
+ "(HTTP response code was #{rcode})", rcode, rbody)
216
+ end
217
+
218
+ def self.handle_api_error(rcode, rbody)
219
+ begin
220
+ error_obj = Nurego::JSON.load(rbody)
221
+ error_obj = Util.symbolize_names(error_obj)
222
+ error = (error_obj && error_obj[:error]) or raise NuregoError.new # escape from parsing
223
+
224
+ rescue MultiJson::DecodeError, NuregoError
225
+ raise general_api_error(rcode, rbody)
226
+ end
227
+
228
+ case rcode
229
+ when 402
230
+ raise card_error error, rcode, rbody, error_obj
231
+ when 400, 404
232
+ raise invalid_request_error error, rcode, rbody, error_obj
233
+ when 401
234
+ raise authentication_error error, rcode, rbody, error_obj
235
+ else
236
+ raise api_error error, rcode, rbody, error_obj
237
+ end
238
+
239
+ end
240
+
241
+
242
+
243
+ def self.invalid_request_error(error, rcode, rbody, error_obj)
244
+ InvalidRequestError.new(error[:message], error[:param], rcode,
245
+ rbody, error_obj)
246
+ end
247
+
248
+ def self.card_error(error, rcode, rbody, error_obj)
249
+ CardError.new(error[:message], error[:param], rcode, rbody, error_obj)
250
+ end
251
+
252
+ def self.authentication_error(error, rcode, rbody, error_obj)
253
+ AuthenticationError.new(error[:message], rcode, rbody, error_obj)
254
+ end
255
+
256
+ def self.api_error(error, rcode, rbody, error_obj)
257
+ APIError.new(error[:message], rcode, rbody, error_obj)
258
+ end
259
+
260
+ def self.handle_restclient_error(e)
261
+ case e
262
+ when RestClient::ServerBrokeConnection, RestClient::RequestTimeout
263
+ message = "Could not connect to Nurego (#{@api_base}). " +
264
+ "Please check your internet connection and try again. " +
265
+ "If this problem persists, you should check Nurego's service status at " +
266
+ "https://twitter.com/nuregostatus, or let us know at support@nurego.com."
267
+
268
+ when RestClient::SSLCertificateNotVerified
269
+ message = "Could not verify Nurego's SSL certificate. " +
270
+ "Please make sure that your network is not intercepting certificates. " +
271
+ "(Try going to https://api.nurego.com/v1 in your browser.) " +
272
+ "If this problem persists, let us know at support@nurego.com."
273
+
274
+ when SocketError
275
+ message = "Unexpected error communicating when trying to connect to Nurego. " +
276
+ "You may be seeing this message because your DNS is not working. " +
277
+ "To check, try running 'host nurego.com' from the command line."
278
+
279
+ else
280
+ message = "Unexpected error communicating with Nurego. " +
281
+ "If this problem persists, let us know at support@nurego.com."
282
+
283
+ end
284
+
285
+ raise APIConnectionError.new(message + "\n\n(Network error: #{e.message})")
286
+ end
287
+ end