clx_api 0.1.0
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 +7 -0
- data/.gitignore +13 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +55 -0
- data/Rakefile +7 -0
- data/clx_api.gemspec +26 -0
- data/doc/CLX.html +305 -0
- data/doc/CLX/API.html +1491 -0
- data/doc/CLX/CLXAPIException.html +411 -0
- data/doc/CLX/CLXException.html +134 -0
- data/doc/CLX/HTTPAdapter.html +1294 -0
- data/doc/CLX/HTTPClient.html +1058 -0
- data/doc/ClxApi.html +141 -0
- data/doc/_index.html +161 -0
- data/doc/class_list.html +58 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +339 -0
- data/doc/file.README.html +112 -0
- data/doc/file_list.html +60 -0
- data/doc/frames.html +26 -0
- data/doc/index.html +112 -0
- data/doc/js/app.js +219 -0
- data/doc/js/full_list.js +181 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +279 -0
- data/doc/top-level-namespace.html +112 -0
- data/examples/get_gateway_by_id.rb +16 -0
- data/examples/get_gateways.rb +18 -0
- data/examples/get_operator_by_id.rb +21 -0
- data/examples/get_operators.rb +23 -0
- data/examples/get_price_entries_by_gateway_id.rb +19 -0
- data/examples/get_price_entries_by_gateway_id_and_operator_id.rb +17 -0
- data/examples/get_price_entries_by_gateway_id_and_operator_id_and_date.rb +18 -0
- data/examples/readme.md +167 -0
- data/lib/clx_api.rb +35 -0
- data/lib/clx_api/api.rb +132 -0
- data/lib/clx_api/exceptions/clx_api_exception.rb +25 -0
- data/lib/clx_api/exceptions/clx_exception.rb +8 -0
- data/lib/clx_api/http_adapter.rb +129 -0
- data/lib/clx_api/http_client.rb +163 -0
- data/lib/clx_api/version.rb +4 -0
- data/test/adapter/test_adapter.rb +67 -0
- data/test/api_test.rb +306 -0
- data/test/http_adapter_test.rb +211 -0
- data/test/http_client_test.rb +173 -0
- data/test/test_helper.rb +7 -0
- metadata +168 -0
data/lib/clx_api/api.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
module CLX
|
2
|
+
|
3
|
+
# Library class for CLX Networks REST API
|
4
|
+
class API
|
5
|
+
|
6
|
+
# @!attribute [r]
|
7
|
+
# Mostly for testing
|
8
|
+
attr_accessor :http_client
|
9
|
+
|
10
|
+
# Initialize a new API client
|
11
|
+
# @param [String] username
|
12
|
+
# @param [String] password
|
13
|
+
# @param [HTTPAdapter] http_adapter
|
14
|
+
# Used for testing
|
15
|
+
# @return [CLX::API]
|
16
|
+
# @example
|
17
|
+
# CLX::API.new 'my_username', 'my_password'
|
18
|
+
def initialize(username, password, http_adapter = nil)
|
19
|
+
http_adapter = http_adapter.nil? ? HTTPAdapter.new : http_adapter
|
20
|
+
http_adapter.set_auth(username, password)
|
21
|
+
|
22
|
+
@http_client = HTTPClient.new(CLX::base_url, http_adapter)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Enables change of credentials after initialization
|
26
|
+
# @param [String] username
|
27
|
+
# @param [String] password
|
28
|
+
def set_auth(username, password)
|
29
|
+
@http_client.http_adapter.set_auth(username, password)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Enables change of base URL after initialization
|
33
|
+
# @param [String] url
|
34
|
+
def set_base_url(url)
|
35
|
+
@http_client.base_url = url
|
36
|
+
end
|
37
|
+
|
38
|
+
# Get all operators from the API
|
39
|
+
# @return [hash] operators
|
40
|
+
# list of operators as hash.
|
41
|
+
# @example
|
42
|
+
# clx_api = CLX::API.new 'my_username', 'my_password'
|
43
|
+
# operators = clx_api.get_operators
|
44
|
+
def get_operators
|
45
|
+
url = CLX.paths[:operator]
|
46
|
+
@http_client.get(url)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Get one operator based on it's operator id
|
50
|
+
# @param [Integer] operator_id Operator ID
|
51
|
+
# @return [hash] operator
|
52
|
+
# One operator as hash.
|
53
|
+
# @example
|
54
|
+
# clx_api = CLX::API.new 'my_username', 'my_password'
|
55
|
+
# operator = clx_api.get_operator(1)
|
56
|
+
def get_operator_by_id(operator_id)
|
57
|
+
valid_id?(operator_id)
|
58
|
+
url = CLX.paths[:operator] + '/' + operator_id.to_s
|
59
|
+
@http_client.get(url)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Get all gateways
|
63
|
+
# @return [hash] gateways
|
64
|
+
# list of gateways as hash.
|
65
|
+
def get_gateways
|
66
|
+
url = CLX.paths[:gateway]
|
67
|
+
@http_client.get(url)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Get one gateway based on it's gateway id
|
71
|
+
# @param [Integer] gateway_id Gateway ID
|
72
|
+
# @return [hash] gateway
|
73
|
+
# One operators as hash.
|
74
|
+
def get_gateway_by_id(gateway_id)
|
75
|
+
valid_id?(gateway_id)
|
76
|
+
url = CLX.paths[:gateway] + '/' + gateway_id.to_s
|
77
|
+
@http_client.get(url)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Get price entires based on gateway id
|
81
|
+
# @param [Integer] gateway_id Gateway ID
|
82
|
+
# @return [hash] price_entires
|
83
|
+
# list of price entries as hash.
|
84
|
+
def get_price_entires_by_gateway_id(gateway_id)
|
85
|
+
valid_id?(gateway_id)
|
86
|
+
url = CLX.paths[:gateway] + '/' + gateway_id.to_s + '/price'
|
87
|
+
@http_client.get(url)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Get price entiry based on gateway id and operator id
|
91
|
+
# @param [Integer] gateway_id Gateway ID
|
92
|
+
# @param [Integer] operator_id Operator ID
|
93
|
+
# @return [hash] price_entry
|
94
|
+
# one price entry as hash.
|
95
|
+
def get_price_entries_by_gateway_id_and_operator_id(gateway_id, operator_id)
|
96
|
+
valid_id?(gateway_id)
|
97
|
+
valid_id?(operator_id)
|
98
|
+
url = CLX.paths[:gateway] + '/' + gateway_id.to_s + '/price/' + operator_id.to_s
|
99
|
+
@http_client.get(url)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Get price entiry based on gateway id, operator id and a date
|
103
|
+
# @param [Integer] gateway_id Gateway ID
|
104
|
+
# @param [Integer] operator_id Operator ID
|
105
|
+
# @param [DateTime] date DateTime
|
106
|
+
# @return [hash] price_entry
|
107
|
+
# one price entry as hash.
|
108
|
+
def get_price_entries_by_gateway_id_and_operator_id_and_date(gateway_id, operator_id, date)
|
109
|
+
valid_id?(gateway_id)
|
110
|
+
valid_id?(operator_id)
|
111
|
+
valid_date?(date)
|
112
|
+
date_query = "?date=#{date.year}-#{date.month}-#{date.day}"
|
113
|
+
url = CLX.paths[:gateway] + '/' + gateway_id.to_s + '/price/' + operator_id.to_s + '/' + date_query
|
114
|
+
@http_client.get(url)
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
# Validates that in is of type integer and is grater than zero
|
120
|
+
def valid_id?(id)
|
121
|
+
raise CLXException, 'Id must be integer' unless id.is_a? Integer
|
122
|
+
raise CLXException, 'Id must be greater than zero' unless id > 0
|
123
|
+
end
|
124
|
+
|
125
|
+
#Validates that date is of type DateTime
|
126
|
+
def valid_date?(date)
|
127
|
+
raise CLXException, 'Date must be of type DateTime' unless date.is_a? DateTime
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module CLX
|
2
|
+
|
3
|
+
# CLX Exception Class for API request errors
|
4
|
+
class CLXAPIException < Exception
|
5
|
+
|
6
|
+
# @!attribute [r]
|
7
|
+
attr_reader :clx_error_code
|
8
|
+
|
9
|
+
# @!attribute [r]
|
10
|
+
attr_reader :clx_error_message
|
11
|
+
|
12
|
+
# Initialize CLX Exception
|
13
|
+
# @param [String] clx_error_message
|
14
|
+
# @param [Integer] clx_error_code
|
15
|
+
# @example
|
16
|
+
# response = http_adapter.get('operator/99999999') #results in error from api
|
17
|
+
# raise CLXException(response.error.message, response.error.body), ""
|
18
|
+
def initialize(clx_error_message = nil, clx_error_code = nil)
|
19
|
+
@clx_error_message = clx_error_message
|
20
|
+
@clx_error_code = clx_error_code
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module CLX
|
4
|
+
|
5
|
+
#HTTP Adapter class for making RESTful HTTP-requests
|
6
|
+
class HTTPAdapter
|
7
|
+
|
8
|
+
# Contains the username used for Basic Auth requests
|
9
|
+
# @!attribute [r]
|
10
|
+
attr_reader :username
|
11
|
+
|
12
|
+
# Contains the password used for Basic Auth requests
|
13
|
+
# @!attribute [r]
|
14
|
+
attr_reader :password
|
15
|
+
|
16
|
+
# Set credentials for basic auth
|
17
|
+
# @param [String] username
|
18
|
+
# @param [String] password
|
19
|
+
def set_auth(username, password)
|
20
|
+
raise CLXException, 'Username must be a string' unless username.is_a? String
|
21
|
+
raise CLXException, 'Password must be a string' unless password.is_a? String
|
22
|
+
raise CLXException, 'Username can not be an empty string' unless username.length > 0
|
23
|
+
raise CLXException, 'Password can not be an empty string' unless password.length > 0
|
24
|
+
|
25
|
+
@username = username
|
26
|
+
@password = password
|
27
|
+
end
|
28
|
+
|
29
|
+
# GET-request
|
30
|
+
# @param [URI] uri
|
31
|
+
# Ruby URI object with full API URL
|
32
|
+
# @return [HTTP::Response]
|
33
|
+
def get(uri)
|
34
|
+
return execute('get', uri)
|
35
|
+
end
|
36
|
+
|
37
|
+
# POST-request
|
38
|
+
# (Not implemented)
|
39
|
+
# @param [URI] uri
|
40
|
+
# Ruby URI object with full API URL
|
41
|
+
# @param [Hash] data
|
42
|
+
# POST-data
|
43
|
+
# @return [HTTP::Response]
|
44
|
+
def post(uri, data)
|
45
|
+
return execute('post', uri, data)
|
46
|
+
end
|
47
|
+
|
48
|
+
# PUT-request
|
49
|
+
# (Not implemented)
|
50
|
+
# @param [URI] uri
|
51
|
+
# Ruby URI object with full API URL
|
52
|
+
# @param [Hash] data
|
53
|
+
# PUT-data
|
54
|
+
# @return [HTTP::Response]
|
55
|
+
def put(uri, data)
|
56
|
+
return execute('put', uri, data)
|
57
|
+
end
|
58
|
+
|
59
|
+
# DELETE-request
|
60
|
+
# (Not implemented)
|
61
|
+
# @param [URI] uri
|
62
|
+
# Ruby URI object with full API URL
|
63
|
+
# @return [HTTP::Response]
|
64
|
+
def delete(uri)
|
65
|
+
return execute('delete', uri)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# Execute request
|
71
|
+
# @param [String] method
|
72
|
+
# @param [String] uri
|
73
|
+
# Full API-path
|
74
|
+
# @param [Hash] data
|
75
|
+
# @return [HTTP::Response] result
|
76
|
+
# @raise [CLXException] if he request fails
|
77
|
+
def execute(method, uri, data = nil)
|
78
|
+
raise CLXException, 'uri must be instance of URI' unless uri.instance_of?(URI::HTTPS) || uri.instance_of?(URI::HTTP)
|
79
|
+
request = create_request(method, uri, data)
|
80
|
+
request.basic_auth(@username, @password)
|
81
|
+
http = create_http(uri);
|
82
|
+
|
83
|
+
return http.request(request)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Create Request object by method and uri
|
87
|
+
# @param [String] method
|
88
|
+
# HTTP
|
89
|
+
# @param [URI] uri
|
90
|
+
# @param [Hash] data
|
91
|
+
# @return [Mixed] request
|
92
|
+
# Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Put, Net::HTTP::Delete
|
93
|
+
# @example
|
94
|
+
# request = create_request("GET", 'http://some.url')
|
95
|
+
# @raise [CLXException] If an invalid HTTP-method was passed
|
96
|
+
def create_request(method, uri, data = nil)
|
97
|
+
method = method.upcase
|
98
|
+
if(method == 'GET')
|
99
|
+
return Net::HTTP::Get.new(uri)
|
100
|
+
elsif(method == 'POST')
|
101
|
+
request = Net::HTTP::Post.new(uri)
|
102
|
+
request.body = data.to_json
|
103
|
+
return request
|
104
|
+
elsif(method == 'PUT')
|
105
|
+
request = Net::HTTP::Put.new(uri)
|
106
|
+
request.body = data.to_json
|
107
|
+
return request
|
108
|
+
elsif(method == 'DELETE')
|
109
|
+
return Net::HTTP::Delete.new(uri)
|
110
|
+
else
|
111
|
+
raise CLXException, 'Unknown HTTP method'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Creates a Net:HTTP instance with ssl activated with URI-object
|
116
|
+
# @param [URI] uri
|
117
|
+
# @return [Net::HTTP] http
|
118
|
+
def create_http(uri)
|
119
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
120
|
+
if uri.instance_of? URI::HTTPS
|
121
|
+
http.use_ssl = true
|
122
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
123
|
+
end
|
124
|
+
return http
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
module CLX
|
2
|
+
|
3
|
+
#HTTP Client class for making RESTful HTTP-requests
|
4
|
+
class HTTPClient
|
5
|
+
|
6
|
+
# Gives access to base_url so this can be modified
|
7
|
+
# @!attribute [rw]
|
8
|
+
attr_accessor :base_url
|
9
|
+
|
10
|
+
# Gives access to the adapter so Auth credentials can be monipulated
|
11
|
+
# @!attribute [rw]
|
12
|
+
attr_accessor :http_adapter
|
13
|
+
|
14
|
+
# Initializer
|
15
|
+
# @param [String] base_url
|
16
|
+
# @param [HTTPAdapter] http_adapter
|
17
|
+
def initialize(base_url, http_adapter)
|
18
|
+
@base_url = base_url
|
19
|
+
@http_adapter = http_adapter
|
20
|
+
end
|
21
|
+
|
22
|
+
# Make a GET-request to specified API-path
|
23
|
+
# @param [String] url
|
24
|
+
# API-path
|
25
|
+
# @return [hash] result
|
26
|
+
def get(url)
|
27
|
+
uri = get_full_url(url)
|
28
|
+
response = @http_adapter.get(uri)
|
29
|
+
return parseResponse(response)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Make a POST-request to specified API-path
|
33
|
+
# (Not implemented)
|
34
|
+
# @param [String] url
|
35
|
+
# API-path
|
36
|
+
# @param [Hash] data
|
37
|
+
# POST data
|
38
|
+
def post(url, data = nil)
|
39
|
+
uri = get_full_url(url)
|
40
|
+
response = @http_adapter.post(uri, data)
|
41
|
+
return parseResponse(response)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Make a PUT-request to specified API-path
|
45
|
+
# (Not implemented)
|
46
|
+
# @param [String] url
|
47
|
+
# API-path
|
48
|
+
# @param [Hash] data
|
49
|
+
# PUT-data
|
50
|
+
def put(url, data = nil)
|
51
|
+
uri = get_full_url(url)
|
52
|
+
response = @http_adapter.put(uri, data)
|
53
|
+
return parseResponse(response)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Make a DELETE-request to specified API-path
|
57
|
+
# (Not implemented)
|
58
|
+
# @param [String] url
|
59
|
+
# API-path
|
60
|
+
def delete(url)
|
61
|
+
uri = get_full_url(url)
|
62
|
+
response = @http_adapter.delete(uri)
|
63
|
+
return parseResponse(response)
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# Build the full API request URL
|
69
|
+
# @param [string] url
|
70
|
+
# API-path
|
71
|
+
# @return [Mixed] uri
|
72
|
+
# URI::HTTP or URI::HTTPS
|
73
|
+
# @example
|
74
|
+
# uri = get_full_url('/gateway/1/operator/')
|
75
|
+
def get_full_url(url)
|
76
|
+
full_url = @base_url + url
|
77
|
+
return URI(URI.encode(full_url))
|
78
|
+
end
|
79
|
+
|
80
|
+
# Parse response from a request and return body content as JSON
|
81
|
+
# @param [NET::HTTP::response] response
|
82
|
+
# @return [JSON] json
|
83
|
+
def parseResponse(response)
|
84
|
+
|
85
|
+
begin
|
86
|
+
result = JSON.parse(response.body, object_class: OpenStruct)
|
87
|
+
rescue
|
88
|
+
raise CLXException, 'Unable to parse JSON response'
|
89
|
+
end
|
90
|
+
|
91
|
+
if(response.code.to_i > 399)
|
92
|
+
error_message = (result.error && result.error.message) ? result.error.message : 'No error message available'
|
93
|
+
code = (result.error && result.error.code) ? result.error.code : 'No error code available'
|
94
|
+
raise CLXAPIException.new(error_message, code), '400: Bad request' if response.code == 400
|
95
|
+
raise CLXAPIException.new(error_message, code), '401: Unauthorized' if response.code == 401
|
96
|
+
raise CLXAPIException.new(error_message, code), '403: Forbidden' if response.code == 403
|
97
|
+
raise CLXAPIException.new(error_message, code), '404: Not Found' if response.code == 404
|
98
|
+
raise CLXAPIException.new(error_message, code), 'Unknown error'
|
99
|
+
end
|
100
|
+
|
101
|
+
return result
|
102
|
+
end
|
103
|
+
|
104
|
+
#################################
|
105
|
+
# Currently unused helper methods
|
106
|
+
#################################
|
107
|
+
|
108
|
+
# # Method for validating URL's
|
109
|
+
# # @param [String] url
|
110
|
+
# # @return [Boolean]
|
111
|
+
# # @raise [CLXException]
|
112
|
+
# def valid_url?(url)
|
113
|
+
# raise CLXException, 'url can not be an empty string' if url.to_s.strip.length == 0
|
114
|
+
# # Seems to accept any string as a valid url, might need some work
|
115
|
+
# !!URI.parse(url)
|
116
|
+
# rescue URI::InvalidURIError
|
117
|
+
# raise CLXException, format('URL: "%s" is not a valid url', url)
|
118
|
+
# end
|
119
|
+
|
120
|
+
# # Encodes passed mixed variable to a URL-encoded query string
|
121
|
+
# # @param [Mixed] params
|
122
|
+
# # String, Hash or Array
|
123
|
+
# # @return [String] query_string
|
124
|
+
# # @example
|
125
|
+
# # date = 'date=2014-01-01'
|
126
|
+
# # encoded_date = url_encode(date)
|
127
|
+
# # @example
|
128
|
+
# # param_hash = {my_date: '2014-01-01', my_string: 'a string', my_int: 1}
|
129
|
+
# # encoded_params = url_encode(param_hash)
|
130
|
+
# def url_encode(params)
|
131
|
+
# return URI.encode(params) if params.instance_of? String
|
132
|
+
|
133
|
+
# if params.instance_of?(Hash) || params.instance_of?(Array)
|
134
|
+
# return '' if params.size == 0
|
135
|
+
|
136
|
+
# ret = ''
|
137
|
+
# params.each do | key, value |
|
138
|
+
# ret += format('&%s=%s', key, value)
|
139
|
+
# end
|
140
|
+
|
141
|
+
# return ret[1..-1]
|
142
|
+
# end
|
143
|
+
|
144
|
+
# return ''
|
145
|
+
# end
|
146
|
+
|
147
|
+
# # Tries to validate that parameter argument is in the correct format: String, Array or Hash
|
148
|
+
# # @param [Mixed] params
|
149
|
+
# # @return [Boolean]
|
150
|
+
# # @raise [CLXException]
|
151
|
+
# def valid_params?(params)
|
152
|
+
# if params != nil
|
153
|
+
# if params.is_a?(String) || params.is_a?(Hash) || params.is_a?(Array)
|
154
|
+
# return true
|
155
|
+
# else
|
156
|
+
# raise CLXException, 'params must be String, Hash or Array'
|
157
|
+
# end
|
158
|
+
# end
|
159
|
+
# end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|