moesif_api 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,72 @@
1
+
2
+
3
+ require 'date'
4
+ module MoesifApi
5
+ class ResponseModel < BaseModel
6
+ # Time when response received
7
+ # @return [DateTime]
8
+ attr_accessor :time
9
+
10
+ # HTTP Status code such as 200
11
+ # @return [Integer]
12
+ attr_accessor :status
13
+
14
+ # Key/Value map of response headers
15
+ # @return [Object]
16
+ attr_accessor :headers
17
+
18
+ # Response body
19
+ # @return [Object]
20
+ attr_accessor :body
21
+
22
+ # IP Address from the response, such as the server IP Address
23
+ # @return [String]
24
+ attr_accessor :ip_address
25
+
26
+ # A mapping from model property names to API property names
27
+ def self.names
28
+ if @hash.nil?
29
+ @hash = {}
30
+ @hash["time"] = "time"
31
+ @hash["status"] = "status"
32
+ @hash["headers"] = "headers"
33
+ @hash["body"] = "body"
34
+ @hash["ip_address"] = "ip_address"
35
+ end
36
+ @hash
37
+ end
38
+
39
+ def initialize(time = nil,
40
+ status = nil,
41
+ headers = nil,
42
+ body = nil,
43
+ ip_address = nil)
44
+ @time = time
45
+ @status = status
46
+ @headers = headers
47
+ @body = body
48
+ @ip_address = ip_address
49
+ end
50
+
51
+ # Creates an instance of the object from a hash
52
+ def self.from_hash(hash)
53
+ if hash == nil
54
+ nil
55
+ else
56
+ # Extract variables from the hash
57
+ time = DateTime.iso8601(hash["time"]) if hash["time"]
58
+ status = hash["status"]
59
+ headers = hash["headers"]
60
+ body = hash["body"]
61
+ ip_address = hash["ip_address"]
62
+
63
+ # Create object from extracted values
64
+ ResponseModel.new(time,
65
+ status,
66
+ headers,
67
+ body,
68
+ ip_address)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,44 @@
1
+
2
+
3
+ module MoesifApi
4
+ class StatusModel < BaseModel
5
+ # Status of Call
6
+ # @return [Boolean]
7
+ attr_accessor :status
8
+
9
+ # Location
10
+ # @return [String]
11
+ attr_accessor :region
12
+
13
+ # A mapping from model property names to API property names
14
+ def self.names
15
+ if @hash.nil?
16
+ @hash = {}
17
+ @hash["status"] = "status"
18
+ @hash["region"] = "region"
19
+ end
20
+ @hash
21
+ end
22
+
23
+ def initialize(status = nil,
24
+ region = nil)
25
+ @status = status
26
+ @region = region
27
+ end
28
+
29
+ # Creates an instance of the object from a hash
30
+ def self.from_hash(hash)
31
+ if hash == nil
32
+ nil
33
+ else
34
+ # Extract variables from the hash
35
+ status = hash["status"]
36
+ region = hash["region"]
37
+
38
+ # Create object from extracted values
39
+ StatusModel.new(status,
40
+ region)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,22 @@
1
+
2
+
3
+ module MoesifApi
4
+ class MoesifAPIClient
5
+ # Singleton access to api controller
6
+ # @return [ApiController] Returns the controller instance
7
+ def api
8
+ ApiController.instance
9
+ end
10
+
11
+ # Singleton access to health controller
12
+ # @return [HealthController] Returns the controller instance
13
+ def health
14
+ HealthController.instance
15
+ end
16
+
17
+ # Initializer with authentication and configuration parameters
18
+ def initialize(application_id: nil)
19
+ Configuration.application_id = application_id
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+
2
+
3
+ require 'json'
4
+ require 'test/unit'
5
+ require 'moesif_api.rb'
6
+ require_relative '../test_helper.rb'
7
+ require_relative '../http_response_catcher.rb'
8
+
9
+ class ControllerTestBase < Test::Unit::TestCase
10
+ include MoesifApi
11
+
12
+ class << self
13
+ attr_accessor :controller
14
+ end
15
+
16
+ # Called only once for a test class before any test has executed.
17
+ def self.startup
18
+ @@api_client = MoesifAPIClient.new
19
+ @@request_timeout = 30
20
+ @@assert_precision = 0.01
21
+ Configuration.application_id = "eyJhcHAiOiIzNjU6NiIsInZlciI6IjIuMCIsIm9yZyI6IjM1OTo0IiwiaWF0IjoxNDczMzc5MjAwfQ.9WOx3D357PGMxrXzFm3pV3IzJSYNsO4oRudiMI8mQ3Q"
22
+ end
23
+
24
+ # Called once before every test case.
25
+ def setup
26
+ @response_catcher = HttpResponseCatcher.new
27
+ self.class.controller.http_call_back = @response_catcher
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+
2
+
3
+ require_relative 'controller_test_base'
4
+
5
+ class ApiControllerTests < ControllerTestBase
6
+ # Called only once for the class before any test has executed
7
+ def self.startup
8
+ self.controller = @@api_client.api
9
+ end
10
+
11
+ # Add Single Event via Injestion API
12
+ def test_add_event()
13
+ # Parameters for the API call
14
+ body = EventModel.from_hash(JSON.parse('{ "request": { "time": "2016-09-09T04:45:42.914", "uri": "https://api.acmeinc.com/items/reviews/", "verb": "PATCH", "api_version": "1.1.0", "ip_address": "61.48.220.123", "headers": { "Host": "api.acmeinc.com", "Accept": "*/*", "Connection": "Keep-Alive", "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 5.0.2; C6906 Build/14.5.A.0.242)", "Content-Type": "application/json", "Content-Length": "126", "Accept-Encoding": "gzip" }, "body": { "items": [ { "direction_type": 1, "discovery_id": "fwfrf", "liked": false }, { "direction_type": 2, "discovery_id": "d43d3f", "liked": true } ] } }, "response": { "time": "2016-09-09T04:45:42.914", "status": 500, "headers": { "Date": "Tue, 23 Aug 2016 23:46:49 GMT", "Vary": "Accept-Encoding", "Pragma": "no-cache", "Expires": "-1", "Content-Type": "application/json; charset=utf-8", "X-Powered-By": "ARR/3.0", "Cache-Control": "no-cache", "Arr-Disable-Session-Affinity": "true" }, "body": { "Error": "InvalidArgumentException", "Message": "Missing field field_a" } }, "user_id": "mndug437f43", "session_token": "23jdf0owekfmcn4u3qypxg09w4d8ayrcdx8nu2ng]s98y18cx98q3yhwmnhcfx43f" }'))
15
+
16
+ # Perform the API call through the SDK function
17
+ self.class.controller.create_event(body)
18
+
19
+ # Test response code
20
+ assert_equal(@response_catcher.response.status_code, 201)
21
+ end
22
+
23
+ # Add Batched Events via Ingestion API
24
+ def test_add_batched_events()
25
+ # Parameters for the API call
26
+ body = JSON.parse('[{ "request": { "time": "2016-09-09T04:45:42.914", "uri": "https://api.acmeinc.com/items/reviews/", "verb": "PATCH", "api_version": "1.1.0", "ip_address": "61.48.220.123", "headers": { "Host": "api.acmeinc.com", "Accept": "*/*", "Connection": "Keep-Alive", "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 5.0.2; C6906 Build/14.5.A.0.242)", "Content-Type": "application/json", "Content-Length": "126", "Accept-Encoding": "gzip" }, "body": { "items": [ { "direction_type": 1, "discovery_id": "fwfrf", "liked": false }, { "direction_type": 2, "discovery_id": "d43d3f", "liked": true } ] } }, "response": { "time": "2016-09-09T04:45:42.914", "status": 500, "headers": { "Date": "Tue, 23 Aug 2016 23:46:49 GMT", "Vary": "Accept-Encoding", "Pragma": "no-cache", "Expires": "-1", "Content-Type": "application/json; charset=utf-8", "X-Powered-By": "ARR/3.0", "Cache-Control": "no-cache", "Arr-Disable-Session-Affinity": "true" }, "body": { "Error": "InvalidArgumentException", "Message": "Missing field field_a" } }, "user_id": "mndug437f43", "session_token": "23jdf0owekfmcn4u3qypxg09w4d8ayrcdx8nu2ng]s98y18cx98q3yhwmnhcfx43f" }, { "request": { "time": "2016-09-09T04:46:42.914", "uri": "https://api.acmeinc.com/items/reviews/", "verb": "PATCH", "api_version": "1.1.0", "ip_address": "61.48.220.123", "headers": { "Host": "api.acmeinc.com", "Accept": "*/*", "Connection": "Keep-Alive", "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 5.0.2; C6906 Build/14.5.A.0.242)", "Content-Type": "application/json", "Content-Length": "126", "Accept-Encoding": "gzip" }, "body": { "items": [ { "direction_type": 1, "discovery_id": "fwfrf", "liked": false }, { "direction_type": 2, "discovery_id": "d43d3f", "liked": true } ] } }, "response": { "time": "2016-09-09T04:46:42.914", "status": 500, "headers": { "Date": "Tue, 23 Aug 2016 23:46:49 GMT", "Vary": "Accept-Encoding", "Pragma": "no-cache", "Expires": "-1", "Content-Type": "application/json; charset=utf-8", "X-Powered-By": "ARR/3.0", "Cache-Control": "no-cache", "Arr-Disable-Session-Affinity": "true" }, "body": { "Error": "InvalidArgumentException", "Message": "Missing field field_a" } }, "user_id": "mndug437f43", "session_token": "23jdf0owekfmcn4u3qypxg09w4d8ayrcdx8nu2ng]s98y18cx98q3yhwmnhcfx43f" }, { "request": { "time": "2016-09-09T04:47:42.914", "uri": "https://api.acmeinc.com/items/reviews/", "verb": "PATCH", "api_version": "1.1.0", "ip_address": "61.48.220.123", "headers": { "Host": "api.acmeinc.com", "Accept": "*/*", "Connection": "Keep-Alive", "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 5.0.2; C6906 Build/14.5.A.0.242)", "Content-Type": "application/json", "Content-Length": "126", "Accept-Encoding": "gzip" }, "body": { "items": [ { "direction_type": 1, "discovery_id": "fwfrf", "liked": false }, { "direction_type": 2, "discovery_id": "d43d3f", "liked": true } ] } }, "response": { "time": "2016-09-09T04:47:42.914", "status": 500, "headers": { "Date": "Tue, 23 Aug 2016 23:46:49 GMT", "Vary": "Accept-Encoding", "Pragma": "no-cache", "Expires": "-1", "Content-Type": "application/json; charset=utf-8", "X-Powered-By": "ARR/3.0", "Cache-Control": "no-cache", "Arr-Disable-Session-Affinity": "true" }, "body": { "Error": "InvalidArgumentException", "Message": "Missing field field_a" } }, "user_id": "mndug437f43", "session_token": "23jdf0owekfmcn4u3qypxg09w4d8ayrcdx8nu2ng]s98y18cx98q3yhwmnhcfx43f" }, { "request": { "time": "2016-09-09T04:48:42.914", "uri": "https://api.acmeinc.com/items/reviews/", "verb": "PATCH", "api_version": "1.1.0", "ip_address": "61.48.220.123", "headers": { "Host": "api.acmeinc.com", "Accept": "*/*", "Connection": "Keep-Alive", "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 5.0.2; C6906 Build/14.5.A.0.242)", "Content-Type": "application/json", "Content-Length": "126", "Accept-Encoding": "gzip" }, "body": { "items": [ { "direction_type": 1, "discovery_id": "fwfrf", "liked": false }, { "direction_type": 2, "discovery_id": "d43d3f", "liked": true } ] } }, "response": { "time": "2016-09-09T04:48:42.914", "status": 500, "headers": { "Date": "Tue, 23 Aug 2016 23:46:49 GMT", "Vary": "Accept-Encoding", "Pragma": "no-cache", "Expires": "-1", "Content-Type": "application/json; charset=utf-8", "X-Powered-By": "ARR/3.0", "Cache-Control": "no-cache", "Arr-Disable-Session-Affinity": "true" }, "body": { "Error": "InvalidArgumentException", "Message": "Missing field field_a" } }, "user_id": "mndug437f43", "session_token": "exfzweachxjgznvKUYrxFcxv]s98y18cx98q3yhwmnhcfx43f" }, { "request": { "time": "2016-09-09T04:49:42.914", "uri": "https://api.acmeinc.com/items/reviews/", "verb": "PATCH", "api_version": "1.1.0", "ip_address": "61.48.220.123", "headers": { "Host": "api.acmeinc.com", "Accept": "*/*", "Connection": "Keep-Alive", "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 5.0.2; C6906 Build/14.5.A.0.242)", "Content-Type": "application/json", "Content-Length": "126", "Accept-Encoding": "gzip" }, "body": { "items": [ { "direction_type": 1, "discovery_id": "fwfrf", "liked": false }, { "direction_type": 2, "discovery_id": "d43d3f", "liked": true } ] } }, "response": { "time": "2016-09-09T04:49:42.914", "status": 500, "headers": { "Date": "Tue, 23 Aug 2016 23:46:49 GMT", "Vary": "Accept-Encoding", "Pragma": "no-cache", "Expires": "-1", "Content-Type": "application/json; charset=utf-8", "X-Powered-By": "ARR/3.0", "Cache-Control": "no-cache", "Arr-Disable-Session-Affinity": "true" }, "body": { "Error": "InvalidArgumentException", "Message": "Missing field field_a" } }, "user_id": "mndug437f43", "session_token": "23jdf0owekfmcn4u3qypxg09w4d8ayrcdx8nu2ng]s98y18cx98q3yhwmnhcfx43f" }, { "request": { "time": "2016-09-09T04:50:42.914", "uri": "https://api.acmeinc.com/items/reviews/", "verb": "PATCH", "api_version": "1.1.0", "ip_address": "61.48.220.123", "headers": { "Host": "api.acmeinc.com", "Accept": "*/*", "Connection": "Keep-Alive", "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 5.0.2; C6906 Build/14.5.A.0.242)", "Content-Type": "application/json", "Content-Length": "126", "Accept-Encoding": "gzip" }, "body": { "items": [ { "direction_type": 1, "discovery_id": "fwfrf", "liked": false }, { "direction_type": 2, "discovery_id": "d43d3f", "liked": true } ] } }, "response": { "time": "2016-09-09T04:50:42.914", "status": 500, "headers": { "Date": "Tue, 23 Aug 2016 23:46:49 GMT", "Vary": "Accept-Encoding", "Pragma": "no-cache", "Expires": "-1", "Content-Type": "application/json; charset=utf-8", "X-Powered-By": "ARR/3.0", "Cache-Control": "no-cache", "Arr-Disable-Session-Affinity": "true" }, "body": { "Error": "InvalidArgumentException", "Message": "Missing field field_a" } }, "user_id": "recvreedfef", "session_token": "xcvkrjmcfghwuignrmcmhxdhaaezse4w]s98y18cx98q3yhwmnhcfx43f" } ]').map{|element| EventModel.from_hash(element)}
27
+
28
+ # Perform the API call through the SDK function
29
+ self.class.controller.create_events_batch(body)
30
+
31
+ # Test response code
32
+ assert_equal(@response_catcher.response.status_code, 201)
33
+ end
34
+
35
+ end
@@ -0,0 +1,16 @@
1
+
2
+
3
+ class HttpResponseCatcher < MoesifApi::HttpCallBack
4
+ attr_accessor :response
5
+
6
+ def on_before_request(request)
7
+ end
8
+
9
+ # Catching the response
10
+ def on_after_response(context)
11
+ @response = context.response
12
+ end
13
+ end
14
+
15
+
16
+
@@ -0,0 +1,94 @@
1
+
2
+
3
+ require 'tempfile'
4
+ require 'open-uri'
5
+
6
+ class TestHelper
7
+
8
+ @cache = Hash.new
9
+
10
+ # Class method to compare the received headers with the expected headers.
11
+ # @param [Hash] A hash of expected headers (keys in lower case).
12
+ # @param [Hash] A hash of received headers.
13
+ # @param [Boolean, optional] A flag which determines if we allow extra headers.
14
+ def self.match_headers(expected_headers,
15
+ received_headers,
16
+ allow_extra: true)
17
+ return false if ((received_headers.length < expected_headers.length) ||
18
+ ((allow_extra == false) && (received_headers.length > expected_headers.length)))
19
+
20
+ received_headers = Hash[received_headers.map{|k, v| [k.to_s.downcase, v]}]
21
+ expected_headers.each do |e_key, e_value|
22
+ return false unless received_headers.key?(e_key)
23
+ return false if ((e_value != nil) &&
24
+ (e_value != received_headers[e_key]))
25
+ end
26
+
27
+ return true
28
+ end
29
+
30
+ # Class method to compare the received body with the expected body.
31
+ # @param [Dynamic] The expected body.
32
+ # @param [Dynamic] The received body.
33
+ # @param [Boolean, optional] A flag which determines if we check values in dictionaries.
34
+ # @param [Boolean, optional] A flag which determines if we check the order of array elements.
35
+ # @param [Boolean, optional] A flag which determines if we check the count of array elements.
36
+ def self.match_body(expected_body,
37
+ received_body,
38
+ check_values: false,
39
+ check_order: false,
40
+ check_count: false)
41
+ if expected_body.instance_of? Hash
42
+ return False if not received_body.instance_of? Hash
43
+ for key in expected_body.keys
44
+ return false if not received_body.keys.include? key
45
+ if check_values or expected_body[key].instance_of? Hash
46
+ return false if not TestHelper.match_body(expected_body[key],
47
+ received_body[key],
48
+ check_values: check_values,
49
+ check_order: check_order,
50
+ check_count: check_count)
51
+ end
52
+ end
53
+ elsif expected_body.instance_of? Array
54
+ return False if not received_body.instance_of? Array
55
+ if check_count == true && (expected_body.length != received_body.length)
56
+ return false
57
+ else
58
+ previous_matches = Array.new
59
+ expected_body.each.with_index do |expected_element, i|
60
+ matches = (received_body.map.with_index do |received_element, j|
61
+ j if TestHelper.match_body(expected_element,
62
+ received_element,
63
+ check_values: check_values,
64
+ check_order: check_order,
65
+ check_count: check_count)
66
+ end).compact
67
+ return false if matches.length == 0
68
+ if check_order == true
69
+ return false if (i != 0 && matches.map{|x| previous_matches.map{|y| y > x}.all?}.all?)
70
+ previous_matches = matches
71
+ end
72
+ end
73
+ end
74
+ elsif expected_body != received_body
75
+ return false
76
+ end
77
+ return true
78
+ end
79
+
80
+ # Class method which takes a URL, downloads the file (if not already downloaded
81
+ # for this test session) and returns a file object for the file in read-binary mode.
82
+ # @param [String] The URL of the required file.
83
+ def self.get_file(url)
84
+ if not @cache.keys.include? url
85
+ @cache[url] = Tempfile.new('APIMatic')
86
+ @cache[url].binmode
87
+ @cache[url].write(open(url, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE}).read)
88
+ else
89
+ @cache[url].open
90
+ @cache[url].binmode
91
+ end
92
+ return @cache[url]
93
+ end
94
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: moesif_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Moesif, Inc
8
+ - Derric Gilling
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-09-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 3.1.5
20
+ name: test-unit
21
+ prerelease: false
22
+ type: :runtime
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: 3.1.5
28
+ - !ruby/object:Gem::Dependency
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.2
34
+ name: unirest
35
+ prerelease: false
36
+ type: :runtime
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: 1.1.2
42
+ - !ruby/object:Gem::Dependency
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.2.1
48
+ name: json_mapper
49
+ prerelease: false
50
+ type: :runtime
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 0.2.1
56
+ description: Collection/Data Ingestion API
57
+ email: derric@moesif.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - LICENSE
63
+ - README.md
64
+ - lib/moesif_api.rb
65
+ - lib/moesif_api/api_helper.rb
66
+ - lib/moesif_api/configuration.rb
67
+ - lib/moesif_api/controllers/api_controller.rb
68
+ - lib/moesif_api/controllers/base_controller.rb
69
+ - lib/moesif_api/controllers/health_controller.rb
70
+ - lib/moesif_api/exceptions/api_exception.rb
71
+ - lib/moesif_api/http/http_call_back.rb
72
+ - lib/moesif_api/http/http_client.rb
73
+ - lib/moesif_api/http/http_context.rb
74
+ - lib/moesif_api/http/http_method_enum.rb
75
+ - lib/moesif_api/http/http_request.rb
76
+ - lib/moesif_api/http/http_response.rb
77
+ - lib/moesif_api/http/unirest_client.rb
78
+ - lib/moesif_api/models/base_model.rb
79
+ - lib/moesif_api/models/event_model.rb
80
+ - lib/moesif_api/models/event_request_model.rb
81
+ - lib/moesif_api/models/event_response_model.rb
82
+ - lib/moesif_api/models/status_model.rb
83
+ - lib/moesif_api/moesif_api_client.rb
84
+ - test/controllers/controller_test_base.rb
85
+ - test/controllers/test_api_controller.rb
86
+ - test/http_response_catcher.rb
87
+ - test/test_helper.rb
88
+ homepage: https://moesif.com
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ~>
99
+ - !ruby/object:Gem::Version
100
+ version: '2.0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.4.5
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: moesif_api
112
+ test_files: []