nurego 1.0.1

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