pingdom_client_v3 0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ad56c767c43aa546a4cde464b65c52e9796fb3a31fb5a8a2e6c93e831389012c
4
+ data.tar.gz: 0f044f192dc6620dfb75c92f9e96783a269b845724ebac083e857a39c0c187ab
5
+ SHA512:
6
+ metadata.gz: 1e2a33899942e06db747fa24502dbf3cc6152d8cb0f62d9f1ee23d15a28bcf854ae0162e078bf20e6b105124615537355344b1a4f7fa88fc9bac18391fffbf07
7
+ data.tar.gz: 6a3b347d3368fce6a5a0cf538e302a5cfa18f6e1cfeeb4caaad3d9fb1341e5c562f5d4dc0827e8abbfe8b849d8ca7e030c0c4eea027b1d7644ffe0c38a303b06
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # PingdomClientV3
2
+
3
+ Lightweight ruby gem for connecting to Pingdom's API V3.
4
+
5
+ ## About Pingdom
6
+
7
+ [https://www.pingdom.com/](https://www.pingdom.com/)
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'pingdom_client_v3'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install pingdom_client_v3
24
+
25
+ ## Usage
26
+
27
+ ```
28
+ client = PingdomClientV3::Client.new('api-key');
29
+
30
+
31
+ # test connection
32
+
33
+ response = client.checks #=> PingdomClientV3::Response
34
+ response.success? #=> Boolean
35
+ checks = response.response_object['checks'] #=> Array
36
+ checks.first.name #=> 'you check name'
37
+ ```
38
+
39
+ ## Development
40
+
41
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "pingdom_client_v3"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/client.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'rest-client'
2
+
3
+ module PingdomClientV3
4
+ class Client
5
+ def initialize(api_url='https://api.pingdom.com/api/3.1', api_token)
6
+ @api_url = api_url
7
+ @api_token = api_token
8
+ end
9
+
10
+ def check
11
+ @pool ||= PingdomClientV3::Resources::Check.new(self)
12
+ end
13
+
14
+ def resource_caller
15
+ PingdomClientV3::ResourceCaller.new(http_resource)
16
+ end
17
+
18
+ private
19
+
20
+ def http_resource
21
+ RestClient::Resource.new(@api_url, headers: { 'Authorization' => "Bearer #{@api_token}" })
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'rest-client'
2
+
3
+ module PingdomClientV3
4
+ class Client
5
+ def initialize(api_token, api_url='https://api.pingdom.com/api/3.1')
6
+ @api_token = api_token
7
+ @api_url = api_url
8
+ end
9
+
10
+ def check
11
+ @check ||= PingdomClientV3::Resources::Check.new(self)
12
+ end
13
+
14
+ def resource_caller
15
+ PingdomClientV3::ResourceCaller.new(http_resource)
16
+ end
17
+
18
+ private
19
+
20
+ def http_resource
21
+ RestClient::Resource.new(@api_url, headers: { 'Authorization' => "Bearer #{@api_token}" })
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ require 'json'
2
+
3
+ module PingdomClientV3
4
+ class CustomException < StandardError
5
+ attr_reader :http_response, :original_exception, :error_message
6
+
7
+ def initialize(original_exception)
8
+ @original_exception = original_exception
9
+ @http_response = @original_exception.response if @original_exception.respond_to?(:response)
10
+ @error_message = parsed_response if @http_response
11
+ super(@original_exception.to_s)
12
+ end
13
+
14
+ private
15
+
16
+ def parsed_response
17
+ @json_error_parser ||= parse_json_body
18
+ end
19
+
20
+ def parse_json_body
21
+ JSON.load(@http_response.body)
22
+ rescue
23
+ ''
24
+ end
25
+ end
26
+
27
+ class ConnectionError < CustomException; end
28
+ class StandardError < CustomException; end
29
+ class BadResponse < CustomException; end
30
+ end
@@ -0,0 +1,53 @@
1
+ require 'json'
2
+
3
+ module PingdomClientV3
4
+ class ResourceCaller
5
+ def initialize(resource)
6
+ @resource = resource
7
+ end
8
+
9
+ def get(path)
10
+ wrap_exception { @resource[path].get }
11
+ end
12
+
13
+ def post(path, payload = {})
14
+ send_payload(:post, path, payload)
15
+ end
16
+
17
+ def put(path, payload = {})
18
+ send_payload(:put, path, payload)
19
+ end
20
+
21
+ def patch(path, payload = {})
22
+ send_payload(:patch, path, payload)
23
+ end
24
+
25
+ def delete(path)
26
+ wrap_exception { @resource[path].delete }
27
+ end
28
+
29
+ private
30
+
31
+ def send_payload(method, path, payload)
32
+ wrap_exception { @resource[path].send(method, hash_to_json(payload), json_headers) }
33
+ end
34
+
35
+ def hash_to_json(hash)
36
+ JSON.dump(hash)
37
+ end
38
+
39
+ def json_headers
40
+ { 'Content-Type' => 'application/json' }
41
+ end
42
+
43
+ def wrap_exception
44
+ PingdomClientV3::Response.new(yield)
45
+ rescue RestClient::ExceptionWithResponse => e
46
+ raise PingdomClientV3::BadResponse.new(e)
47
+ rescue RestClient::Exception, SocketError => e
48
+ raise PingdomClientV3::ConnectionError.new(e)
49
+ rescue => e
50
+ raise PingdomClientV3::StandardError.new(e)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,14 @@
1
+ module PingdomClientV3
2
+ module Resources
3
+ class BaseResource
4
+ extend Forwardable
5
+
6
+ def_delegators :@resource_caller, :get, :post, :put, :delete, :patch
7
+
8
+ def initialize(client)
9
+ @resource_caller = client.resource_caller
10
+ end
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,21 @@
1
+ module PingdomClientV3
2
+ module Resources
3
+ class Check < BaseResource
4
+ def index(params = {})
5
+ get("/checks?#{URI.encode_www_form(params)}")
6
+ end
7
+
8
+ def show(check_id)
9
+ get("/checks/#{check_id}")
10
+ end
11
+
12
+ def create(payload)
13
+ post("/checks", payload)
14
+ end
15
+
16
+ def destroy(check_id)
17
+ delete("/checks/#{check_id}")
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,54 @@
1
+ require 'json'
2
+ require 'forwardable'
3
+
4
+ module PingdomClientV3
5
+ class Response
6
+ extend Forwardable
7
+
8
+ def_delegators :@original_response, :code, :request, :headers
9
+
10
+ def initialize(original_response)
11
+ @original_response = original_response
12
+ end
13
+
14
+ def success?
15
+ success_codes.include?(code)
16
+ end
17
+
18
+ def failure?
19
+ !success?
20
+ end
21
+
22
+ def body
23
+ @body ||= parse_json_safe(original_body)
24
+ end
25
+
26
+ def original_body
27
+ @original_response.body
28
+ end
29
+
30
+ def response_object
31
+ @response_object ||= initialize_object(body)
32
+ end
33
+
34
+ private
35
+
36
+ def initialize_object(body)
37
+ if body.is_a?(Array)
38
+ body.map do |item|
39
+ PingdomClientV3::ResponseObject.new(item)
40
+ end
41
+ else
42
+ PingdomClientV3::ResponseObject.new(body)
43
+ end
44
+ end
45
+
46
+ def success_codes
47
+ 200..226
48
+ end
49
+
50
+ def parse_json_safe(json)
51
+ JSON.load(json)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,9 @@
1
+ require 'delegate'
2
+
3
+ module PingdomClientV3
4
+ class ResponseObject < SimpleDelegator
5
+ def initialize(attributes)
6
+ __setobj__(attributes)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module PingdomClientV3
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,11 @@
1
+ require 'pingdom_client_v3/version'
2
+ require 'pingdom_client_v3/custom_exception'
3
+ require 'pingdom_client_v3/response_object'
4
+ require 'pingdom_client_v3/response'
5
+ require 'pingdom_client_v3/resource_caller'
6
+ require 'pingdom_client_v3/resources/base_resource'
7
+ require 'pingdom_client_v3/resources/check'
8
+ require 'pingdom_client_v3/client'
9
+
10
+ module PingdomClientV3
11
+ end
@@ -0,0 +1,31 @@
1
+ require_relative '../spec_helper'
2
+
3
+ module PingdomClientV3
4
+ RSpec.describe Client do
5
+ include_context :pingdom_client
6
+
7
+ subject { pingdom_client }
8
+
9
+ describe '#check' do
10
+ specify { expect(subject.check).to be_a PingdomClientV3::Resources::Check }
11
+
12
+ specify do
13
+ expect(PingdomClientV3::Resources::Check).to receive(:new).with(subject)
14
+ subject.check
15
+ end
16
+ end
17
+
18
+ describe '#resource_caller' do
19
+ let(:resource) { double(:resource) }
20
+
21
+ before do
22
+ allow(RestClient::Resource).to receive(:new).with(pingdom_api_url, headers: { 'Authorization' => "Bearer #{pingdom_api_key}" }).and_return(resource)
23
+ end
24
+
25
+ specify do
26
+ expect(PingdomClientV3::ResourceCaller).to receive(:new).with(resource).and_call_original
27
+ expect(subject.resource_caller).to be_a PingdomClientV3::ResourceCaller
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,37 @@
1
+ require_relative '../spec_helper'
2
+ require 'json'
3
+
4
+ module PingdomClientV3
5
+ RSpec.describe CustomException do
6
+ it 'inherits from StandardError' do
7
+ expect(described_class.superclass).to be ::StandardError
8
+ end
9
+
10
+ subject { described_class.new(original_exception) }
11
+
12
+ describe '#original_exception' do
13
+ let(:original_exception) { double }
14
+
15
+ specify { expect(subject.original_exception).to eq original_exception }
16
+ end
17
+
18
+ describe '#http_response' do
19
+ let(:original_exception) { double(:response => 'a response object') }
20
+
21
+ specify { expect(subject.http_response).to eq 'a response object' }
22
+ end
23
+
24
+ describe '#error_message' do
25
+ let(:original_exception) { double }
26
+ let(:response) { double }
27
+ let(:body) { JSON.dump({ :some => 'response' }) }
28
+
29
+ before do
30
+ expect(original_exception).to receive(:response).and_return(response)
31
+ expect(response).to receive(:body).and_return(body)
32
+ end
33
+
34
+ specify { expect(subject.error_message).to eq({ 'some' => 'response' }) }
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,271 @@
1
+ require_relative '../spec_helper'
2
+
3
+ module PingdomClientV3
4
+ RSpec.describe ResourceCaller do
5
+ let(:resource) { double(:resource) }
6
+
7
+ subject { described_class.new(resource) }
8
+
9
+ describe '#post' do
10
+ let(:payload) { { :name => 'John' } }
11
+ let(:json_payload) { JSON.dump(payload) }
12
+ let(:result) { subject.post('some_path', payload) }
13
+ let(:post_resource) { double(:post_resource) }
14
+ let(:headers) { { 'Content-Type' => 'application/json' } }
15
+
16
+ context 'when request is successful' do
17
+ let(:fake_response) { double(:fake_response) }
18
+
19
+ before do
20
+ allow(resource).to receive(:[]).with('some_path').and_return(post_resource)
21
+ allow(post_resource).to receive(:post).with(json_payload, headers).and_return(fake_response)
22
+ end
23
+
24
+ it 'returns a PingdomClientV3::Response' do
25
+ expect(result).to be_a PingdomClientV3::Response
26
+ end
27
+ end
28
+
29
+ context 'when resource raises a RestClient::ExceptionWithResponse' do
30
+ let(:http_code) { 422 }
31
+ let(:exception) { RestClient::ExceptionWithResponse.new }
32
+
33
+ before do
34
+ allow(exception).to receive(:http_code).and_return(http_code)
35
+ allow(resource).to receive(:[]).with('some_path').and_return(post_resource)
36
+ allow(post_resource).to receive(:post).with(json_payload, headers).and_raise(exception)
37
+ end
38
+
39
+ it 'raises a PingdomClientV3::BadResponse' do
40
+ expect { result }.to raise_error PingdomClientV3::BadResponse
41
+ end
42
+ end
43
+
44
+ context 'when resource raises a RestClient::Exception' do
45
+ before do
46
+ allow(resource).to receive(:[]).with('some_path').and_return(post_resource)
47
+ allow(post_resource).to receive(:post).with(json_payload, headers).and_raise(RestClient::Exception.new)
48
+ end
49
+
50
+ it 'raises a PingdomClientV3::ConnectionError' do
51
+ expect { result }.to raise_error PingdomClientV3::ConnectionError
52
+ end
53
+ end
54
+
55
+ context 'when resource raises a SocketError' do
56
+ before do
57
+ allow(resource).to receive(:[]).with('some_path').and_return(post_resource)
58
+ allow(post_resource).to receive(:post).with(json_payload, headers).and_raise(SocketError.new)
59
+ end
60
+
61
+ it 'raises a PingdomClientV3::ConnectionError' do
62
+ expect { result }.to raise_error PingdomClientV3::ConnectionError
63
+ end
64
+ end
65
+
66
+ context 'when resource raises any other error' do
67
+ before do
68
+ allow(resource).to receive(:[]).with('some_path').and_return(post_resource)
69
+ allow(post_resource).to receive(:post).with(json_payload, headers).and_raise(StandardError.new('some_error'))
70
+ end
71
+
72
+ it 'raises a PingdomClientV3::ConnectionError' do
73
+ expect { result }.to raise_error PingdomClientV3::StandardError
74
+ end
75
+ end
76
+ end
77
+
78
+ describe '#put' do
79
+ let(:payload) { { :name => 'John' } }
80
+ let(:json_payload) { JSON.dump(payload) }
81
+ let(:result) { subject.put('some_path', payload) }
82
+ let(:post_resource) { double(:post_resource) }
83
+ let(:headers) { { 'Content-Type' => 'application/json' } }
84
+
85
+ context 'when request is successful' do
86
+ let(:fake_response) { double(:fake_response) }
87
+
88
+ before do
89
+ allow(resource).to receive(:[]).with('some_path').and_return(post_resource)
90
+ allow(post_resource).to receive(:put).with(json_payload, headers).and_return(fake_response)
91
+ end
92
+
93
+ it 'returns a PingdomClientV3::Response' do
94
+ expect(result).to be_a PingdomClientV3::Response
95
+ end
96
+ end
97
+
98
+ context 'when resource raises a RestClient::ExceptionWithResponse' do
99
+ let(:http_code) { 422 }
100
+ let(:exception) { RestClient::ExceptionWithResponse.new }
101
+
102
+ before do
103
+ allow(exception).to receive(:http_code).and_return(http_code)
104
+ allow(resource).to receive(:[]).with('some_path').and_return(post_resource)
105
+ allow(post_resource).to receive(:put).with(json_payload, headers).and_raise(exception)
106
+ end
107
+
108
+ it 'raises a PingdomClientV3::BadResponse' do
109
+ expect { result }.to raise_error PingdomClientV3::BadResponse
110
+ end
111
+ end
112
+
113
+ context 'when resource raises a RestClient::Exception' do
114
+ before do
115
+ allow(resource).to receive(:[]).with('some_path').and_return(post_resource)
116
+ allow(post_resource).to receive(:put).with(json_payload, headers).and_raise(RestClient::Exception.new)
117
+ end
118
+
119
+ it 'raises a PingdomClientV3::ConnectionError' do
120
+ expect { result }.to raise_error PingdomClientV3::ConnectionError
121
+ end
122
+ end
123
+
124
+ context 'when resource raises a SocketError' do
125
+ before do
126
+ allow(resource).to receive(:[]).with('some_path').and_return(post_resource)
127
+ allow(post_resource).to receive(:put).with(json_payload, headers).and_raise(SocketError.new)
128
+ end
129
+
130
+ it 'raises a PingdomClientV3::ConnectionError' do
131
+ expect { result }.to raise_error PingdomClientV3::ConnectionError
132
+ end
133
+ end
134
+
135
+ context 'when resource raises any other error' do
136
+ before do
137
+ allow(resource).to receive(:[]).with('some_path').and_return(post_resource)
138
+ allow(post_resource).to receive(:put).with(json_payload, headers).and_raise(StandardError.new('some_error'))
139
+ end
140
+
141
+ it 'raises a PingdomClientV3::ConnectionError' do
142
+ expect { result }.to raise_error PingdomClientV3::StandardError
143
+ end
144
+ end
145
+ end
146
+
147
+ describe '#get' do
148
+ let(:result) { subject.get('some_path') }
149
+ let(:get_resource) { double(:get_resource) }
150
+
151
+ context 'when request is successful' do
152
+ let(:fake_response) { double(:fake_response) }
153
+
154
+ before do
155
+ allow(resource).to receive(:[]).with('some_path').and_return(get_resource)
156
+ allow(get_resource).to receive(:get).and_return(fake_response)
157
+ end
158
+
159
+ it 'returns a PingdomClientV3::Response' do
160
+ expect(result).to be_a PingdomClientV3::Response
161
+ end
162
+ end
163
+
164
+ context 'when resource raises a RestClient::ExceptionWithResponse' do
165
+ before do
166
+ allow(resource).to receive(:[]).with('some_path').and_return(get_resource)
167
+ allow(get_resource).to receive(:get).and_raise(RestClient::ExceptionWithResponse.new)
168
+ end
169
+
170
+ it 'raises a PingdomClientV3::BadResponse' do
171
+ expect { result }.to raise_error PingdomClientV3::BadResponse
172
+ end
173
+ end
174
+
175
+ context 'when resource raises a RestClient::Exception' do
176
+ before do
177
+ allow(resource).to receive(:[]).with('some_path').and_return(get_resource)
178
+ allow(get_resource).to receive(:get).and_raise(RestClient::Exception.new)
179
+ end
180
+
181
+ it 'raises a PingdomClientV3::ConnectionError' do
182
+ expect { result }.to raise_error PingdomClientV3::ConnectionError
183
+ end
184
+ end
185
+
186
+ context 'when resource raises a SocketError' do
187
+ before do
188
+ allow(resource).to receive(:[]).with('some_path').and_return(get_resource)
189
+ allow(get_resource).to receive(:get).and_raise(SocketError.new)
190
+ end
191
+
192
+ it 'raises a PingdomClientV3::ConnectionError' do
193
+ expect { result }.to raise_error PingdomClientV3::ConnectionError
194
+ end
195
+ end
196
+
197
+ context 'when resource raises any other error' do
198
+ before do
199
+ allow(resource).to receive(:[]).with('some_path').and_return(get_resource)
200
+ allow(get_resource).to receive(:get).and_raise(StandardError.new('some_error'))
201
+ end
202
+
203
+ it 'raises a PingdomClientV3::ConnectionError' do
204
+ expect { result }.to raise_error PingdomClientV3::StandardError
205
+ end
206
+ end
207
+ end
208
+
209
+ describe '#delete' do
210
+ let(:result) { subject.delete('some_path') }
211
+ let(:get_resource) { double(:get_resource) }
212
+
213
+ context 'when request is successful' do
214
+ let(:fake_response) { double(:fake_response) }
215
+
216
+ before do
217
+ allow(resource).to receive(:[]).with('some_path').and_return(get_resource)
218
+ allow(get_resource).to receive(:delete).and_return(fake_response)
219
+ end
220
+
221
+ it 'returns a PingdomClientV3::Response' do
222
+ expect(result).to be_a PingdomClientV3::Response
223
+ end
224
+ end
225
+
226
+ context 'when resource raises a RestClient::ExceptionWithResponse' do
227
+ before do
228
+ allow(resource).to receive(:[]).with('some_path').and_return(get_resource)
229
+ allow(get_resource).to receive(:delete).and_raise(RestClient::ExceptionWithResponse.new)
230
+ end
231
+
232
+ it 'raises a PingdomClientV3::BadResponse' do
233
+ expect { result }.to raise_error PingdomClientV3::BadResponse
234
+ end
235
+ end
236
+
237
+ context 'when resource raises a RestClient::Exception' do
238
+ before do
239
+ allow(resource).to receive(:[]).with('some_path').and_return(get_resource)
240
+ allow(get_resource).to receive(:delete).and_raise(RestClient::Exception.new)
241
+ end
242
+
243
+ it 'raises a PingdomClientV3::ConnectionError' do
244
+ expect { result }.to raise_error PingdomClientV3::ConnectionError
245
+ end
246
+ end
247
+
248
+ context 'when resource raises a SocketError' do
249
+ before do
250
+ allow(resource).to receive(:[]).with('some_path').and_return(get_resource)
251
+ allow(get_resource).to receive(:delete).and_raise(SocketError.new)
252
+ end
253
+
254
+ it 'raises a PingdomClientV3::ConnectionError' do
255
+ expect { result }.to raise_error PingdomClientV3::ConnectionError
256
+ end
257
+ end
258
+
259
+ context 'when resource raises any other error' do
260
+ before do
261
+ allow(resource).to receive(:[]).with('some_path').and_return(get_resource)
262
+ allow(get_resource).to receive(:delete).and_raise(StandardError.new('some_error'))
263
+ end
264
+
265
+ it 'raises a PingdomClientV3::ConnectionError' do
266
+ expect { result }.to raise_error PingdomClientV3::StandardError
267
+ end
268
+ end
269
+ end
270
+ end
271
+ end