quiz_api_client 3.1.0 → 4.2.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 +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +35 -0
- data/Dockerfile +3 -2
- data/Jenkinsfile +5 -5
- data/README.md +8 -0
- data/lib/quiz_api_client/config.rb +64 -0
- data/lib/quiz_api_client/http_client.rb +38 -10
- data/lib/quiz_api_client/http_request/failure.rb +65 -0
- data/lib/quiz_api_client/http_request/metrics.rb +67 -0
- data/lib/quiz_api_client/services/base_api_service.rb +5 -11
- data/lib/quiz_api_client/services/jwt_service.rb +7 -8
- data/lib/quiz_api_client/services/qti_imports_service.rb +11 -10
- data/lib/quiz_api_client/version.rb +1 -1
- data/lib/quiz_api_client.rb +35 -36
- data/quiz_api_client.gemspec +5 -1
- metadata +43 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9191c8a80cb0e2a654139c30e5e6ad3662e7589f6bf34a5b9f00b4517de22f99
|
4
|
+
data.tar.gz: 875e4bc7336dac500bbf699438ce9ad457680d6d3ce736b6aff3077efc495dfd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf91a4c19851e9c1e4569f25be567ffae06bb91666da2d56cfc28fea0569cf55ce2706e18ebbb5ad38ce1ea9246eb348806f2fd05243250baa8573379ac9a843
|
7
|
+
data.tar.gz: aa366eff458ec1045bab8abae45d5a99bc374327a2d085a70fce32963e730b31d7a1f58ad5150f8978326b0b7608bb27c74b4a4ddde5e5bf3cbd25717ed463ff
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
CHANGELOG
|
2
|
+
=========
|
3
|
+
|
4
|
+
All notable changes to this project will be documented in this file. This
|
5
|
+
project adheres to [Semantic Versioning](http://semver.org/).
|
6
|
+
|
7
|
+
[TOC]
|
8
|
+
|
9
|
+
#TODO: Enter the date
|
10
|
+
## 4.2.0 ()
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
* Internal refactor of request error handling
|
14
|
+
* Added `metric_handler` and `metrics_namespace` to work with InstStatsd gem
|
15
|
+
|
16
|
+
## 4.1.0 (2021-10-27)
|
17
|
+
|
18
|
+
### Breaking changes (potentially)
|
19
|
+
|
20
|
+
* All non-successful (2xx) responses will raise `QuizApiClient::HttpClient::RequestFailed` error except for 401 and 422
|
21
|
+
* Can be overridden in `allowable_response_codes` config
|
22
|
+
|
23
|
+
## 4.0.0 (2021-10-18)
|
24
|
+
|
25
|
+
### Breaking changes
|
26
|
+
|
27
|
+
* Ruby 2.4.x is no longer supported
|
28
|
+
* Ruby 2.5.x is no longer supported
|
29
|
+
|
30
|
+
### Changed
|
31
|
+
* Minimum Ruby version to 2.6.x
|
32
|
+
* Internal classes use a configuration object instead parameters on instantiation
|
33
|
+
* Instantiating `QuizApiClient::Client` remains the same
|
34
|
+
* Added `error_handler` configuration to work with Sentry Raven gem
|
35
|
+
|
data/Dockerfile
CHANGED
@@ -4,8 +4,9 @@ RUN mkdir -p coverage log pacts
|
|
4
4
|
|
5
5
|
COPY --chown=docker:docker quiz_api_client.gemspec Gemfile ./
|
6
6
|
COPY --chown=docker:docker lib/quiz_api_client/version.rb lib/quiz_api_client/version.rb
|
7
|
-
RUN /bin/bash -l -c "rvm-exec 2.
|
7
|
+
RUN /bin/bash -l -c "rvm-exec 2.6 gem install bundler -v 2.1.4"
|
8
|
+
RUN /bin/bash -l -c "rvm-exec 2.6 bundle install --jobs 5"
|
8
9
|
|
9
10
|
COPY --chown=docker:docker . .
|
10
11
|
|
11
|
-
CMD /bin/bash -l -c "rvm-exec 2.
|
12
|
+
CMD /bin/bash -l -c "rvm-exec 2.6 bundle exec rspec"
|
data/Jenkinsfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
def buildMatrix = ['2.
|
1
|
+
def buildMatrix = ['2.6', '2.7'].collectEntries { ruby ->
|
2
2
|
["Ruby ${ruby}": {
|
3
3
|
sh """
|
4
4
|
docker-compose run --name "${env.BUILD_ID}-ruby-${ruby}" \
|
@@ -25,7 +25,7 @@ pipeline {
|
|
25
25
|
steps {
|
26
26
|
sh '''
|
27
27
|
docker-compose run --rm app /bin/bash -lc \
|
28
|
-
"rvm-exec 2.
|
28
|
+
"rvm-exec 2.6 bundle exec rubocop --fail-level autocorrect"
|
29
29
|
'''
|
30
30
|
}
|
31
31
|
}
|
@@ -34,7 +34,7 @@ pipeline {
|
|
34
34
|
}
|
35
35
|
stage('Contract Tests') {
|
36
36
|
steps {
|
37
|
-
sh 'docker-compose run app /bin/bash -l -c "rvm-exec 2.
|
37
|
+
sh 'docker-compose run app /bin/bash -l -c "rvm-exec 2.6 bundle exec rspec -t pact"'
|
38
38
|
}
|
39
39
|
}
|
40
40
|
stage ('Publish') {
|
@@ -58,7 +58,7 @@ pipeline {
|
|
58
58
|
-e PACT_BROKER_PASSWORD="${PACT_BROKER_PASSWORD}" \
|
59
59
|
-e PACT_CONSUMER_TAG="${PACT_CONSUMER_TAG}" \
|
60
60
|
-e SHA="${sha}" \
|
61
|
-
app /bin/bash -l -c "rvm-exec 2.
|
61
|
+
app /bin/bash -l -c "rvm-exec 2.6 bundle exec rake broker:pact:publish:jenkins_post_merge"
|
62
62
|
'''
|
63
63
|
}
|
64
64
|
}
|
@@ -67,7 +67,7 @@ pipeline {
|
|
67
67
|
|
68
68
|
post {
|
69
69
|
success {
|
70
|
-
sh "docker cp \"${env.BUILD_ID}-ruby-2.
|
70
|
+
sh "docker cp \"${env.BUILD_ID}-ruby-2.6:/usr/src/app/coverage\" ."
|
71
71
|
publishHTML target: [
|
72
72
|
allowMissing: false,
|
73
73
|
alwaysLinkToLastBuild: false,
|
data/README.md
CHANGED
@@ -37,6 +37,14 @@ client = QuizApiClient::Client.new(
|
|
37
37
|
)
|
38
38
|
```
|
39
39
|
|
40
|
+
### Error Handler
|
41
|
+
|
42
|
+
In order to set addition error information in your error handling system, you can set the `error_hander` property of the config. The list of valid values can be found in the `QuizApiClient::Config::ERROR_HANDLERS` constant.
|
43
|
+
|
44
|
+
### Metrics
|
45
|
+
|
46
|
+
HTTP Request metrics will now be provided if the `setup_metrics` method is called. The list of valid values can be found in the `QuizApiClient::Config::METRICS_HANDLERS` constant. The count and duration metrics will be provided under the namespace provided.
|
47
|
+
|
40
48
|
### Creation of Tokens
|
41
49
|
|
42
50
|
JWTs are created without hitting quiz_api and and they are validated on quiz_api. Tokens are created for a given scope, expiration, and an optional resource_id.
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module QuizApiClient
|
2
|
+
class Config
|
3
|
+
DEFAULT_ALLOWABLE_RESPONSE_CODES = [401, 422].freeze
|
4
|
+
DEFAULT_PROTOCOL = 'https'.freeze
|
5
|
+
ERROR_HANDLERS = %i[sentry_raven].freeze
|
6
|
+
METRICS_HANDLERS = %i[inststatsd].freeze
|
7
|
+
|
8
|
+
class InvalidErrorHandler < StandardError; end
|
9
|
+
class InvalidMetricsHandler < StandardError; end
|
10
|
+
class InvalidMetricsNamespace < StandardError; end
|
11
|
+
|
12
|
+
attr_reader :error_handler, :metrics_handler, :metrics_namespace
|
13
|
+
attr_writer :protocol, :allowable_response_codes
|
14
|
+
attr_accessor :consumer_key, :consumer_request_id, :host, :shared_secret
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
yield(self) if block_given?
|
18
|
+
end
|
19
|
+
|
20
|
+
def protocol
|
21
|
+
@protocol || DEFAULT_PROTOCOL
|
22
|
+
end
|
23
|
+
|
24
|
+
def error_handler=(handler)
|
25
|
+
validate_error_handler!(handler)
|
26
|
+
|
27
|
+
@error_handler = handler.to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup_metrics(handler, namespace)
|
31
|
+
validate_metrics_handler!(handler)
|
32
|
+
validate_metrics_namespace!(namespace)
|
33
|
+
|
34
|
+
@metrics_handler = handler.to_sym
|
35
|
+
@metrics_namespace = namespace.to_s.strip
|
36
|
+
end
|
37
|
+
|
38
|
+
def allowable_response_codes
|
39
|
+
@allowable_response_codes || DEFAULT_ALLOWABLE_RESPONSE_CODES
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def validate_error_handler!(handler)
|
45
|
+
return unless handler
|
46
|
+
return if ERROR_HANDLERS.include?(handler)
|
47
|
+
|
48
|
+
raise InvalidErrorHandler, "It must be one of the following: #{ERROR_HANDLERS.inspect}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def validate_metrics_handler!(handler)
|
52
|
+
return unless handler
|
53
|
+
return if METRICS_HANDLERS.include?(handler)
|
54
|
+
|
55
|
+
raise InvalidMetricsHandler, "It must be one of the following: #{METRICS_HANDLERS.inspect}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def validate_metrics_namespace!(namespace)
|
59
|
+
return unless namespace.nil? || namespace.to_s.strip == ''
|
60
|
+
|
61
|
+
raise InvalidMetricsNamespace, 'It must be present'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -4,14 +4,21 @@ module QuizApiClient
|
|
4
4
|
class HttpClient
|
5
5
|
include HTTParty
|
6
6
|
|
7
|
-
class RequestFailed < StandardError
|
7
|
+
class RequestFailed < StandardError
|
8
|
+
attr_reader :context
|
8
9
|
|
9
|
-
|
10
|
+
def initialize(context)
|
11
|
+
@context = context
|
12
|
+
super(context)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :jwt, :uri, :config
|
10
17
|
|
11
|
-
def initialize(uri:, jwt:,
|
18
|
+
def initialize(uri:, jwt:, config:, logging: true, log_level: :info)
|
12
19
|
@uri = uri
|
13
20
|
@jwt = jwt
|
14
|
-
@
|
21
|
+
@config = config
|
15
22
|
initialize_logger(log_level) if logging
|
16
23
|
end
|
17
24
|
|
@@ -49,7 +56,7 @@ module QuizApiClient
|
|
49
56
|
HTTParty::Logger.add_formatter('quiz_api_client_json_formatter', QuizApiClient::JSONFormatter)
|
50
57
|
@logger = ::Logger.new(
|
51
58
|
STDOUT,
|
52
|
-
formatter: proc { |_, _, _, msg| msg.merge(consumer_request_id:
|
59
|
+
formatter: proc { |_, _, _, msg| msg.merge(consumer_request_id: config.consumer_request_id).to_json },
|
53
60
|
level: unfriendly_logger_level(log_level)
|
54
61
|
)
|
55
62
|
@logger_config = {
|
@@ -75,13 +82,18 @@ module QuizApiClient
|
|
75
82
|
end
|
76
83
|
|
77
84
|
def make_request(method, url, request_options = {})
|
78
|
-
|
85
|
+
start_time = Time.now
|
86
|
+
resp = self.class.send(
|
79
87
|
method,
|
80
88
|
url,
|
81
89
|
default_request_data.merge(request_options)
|
82
90
|
)
|
91
|
+
raise_error(method, url, response: resp) unless successful_response?(resp)
|
92
|
+
resp
|
83
93
|
rescue HTTParty::Error, Errno::ECONNREFUSED, Net::ReadTimeout => e
|
84
|
-
|
94
|
+
raise_error(method, url, current_error: e)
|
95
|
+
ensure
|
96
|
+
record_metrics(method, url, resp, start_time, Time.now)
|
85
97
|
end
|
86
98
|
|
87
99
|
def make_paginated_request(method, url, options)
|
@@ -91,8 +103,6 @@ module QuizApiClient
|
|
91
103
|
|
92
104
|
until request_url.nil?
|
93
105
|
resp = make_request(method, request_url, request_options)
|
94
|
-
raise RequestFailed, "#{url} responded #{resp.body} (#{resp.code})" unless resp.code == 200
|
95
|
-
|
96
106
|
entities.concat(resp.parsed_response)
|
97
107
|
request_url, request_options = next_page(resp, url, options)
|
98
108
|
end
|
@@ -109,7 +119,7 @@ module QuizApiClient
|
|
109
119
|
}
|
110
120
|
}
|
111
121
|
|
112
|
-
initial_hash[:headers]['X-Consumer-Request-Id'] =
|
122
|
+
initial_hash[:headers]['X-Consumer-Request-Id'] = config.consumer_request_id if config.consumer_request_id
|
113
123
|
|
114
124
|
initial_hash.merge!(@logger_config) if @logger_config
|
115
125
|
initial_hash
|
@@ -138,5 +148,23 @@ module QuizApiClient
|
|
138
148
|
)
|
139
149
|
[url, options.merge(query: query)]
|
140
150
|
end
|
151
|
+
|
152
|
+
def raise_error(method, url, response: nil, current_error: nil)
|
153
|
+
failure = QuizApiClient::HttpRequest::Failure.new(config)
|
154
|
+
|
155
|
+
failure.raise_error(method, url, response: response, current_error: current_error)
|
156
|
+
end
|
157
|
+
|
158
|
+
def record_metrics(method, url, resp, start_time, end_time)
|
159
|
+
code = resp&.code || 0
|
160
|
+
metrics = QuizApiClient::HttpRequest::Metrics.new(config, method, url, code)
|
161
|
+
|
162
|
+
metrics.increment
|
163
|
+
metrics.duration(start_time, end_time)
|
164
|
+
end
|
165
|
+
|
166
|
+
def successful_response?(resp)
|
167
|
+
resp.success? || config.allowable_response_codes.include?(resp.code)
|
168
|
+
end
|
141
169
|
end
|
142
170
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module QuizApiClient
|
2
|
+
module HttpRequest
|
3
|
+
class Failure
|
4
|
+
attr_reader :config
|
5
|
+
|
6
|
+
def initialize(config)
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
def raise_error(
|
11
|
+
method,
|
12
|
+
url,
|
13
|
+
response: nil,
|
14
|
+
current_error: nil,
|
15
|
+
error_class: QuizApiClient::HttpClient::RequestFailed
|
16
|
+
)
|
17
|
+
context = generate_error_context(method, url, response)
|
18
|
+
|
19
|
+
record_error_context(context)
|
20
|
+
|
21
|
+
raise error_class.new(context), error_message(current_error, url, response)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def generate_error_context(method, url, response = nil)
|
27
|
+
context = {
|
28
|
+
quiz_api_client: {
|
29
|
+
request: {
|
30
|
+
method: method,
|
31
|
+
url: url
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
if response
|
37
|
+
context[:quiz_api_client][:response] = {
|
38
|
+
body: response.body,
|
39
|
+
code: response.code
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
context
|
44
|
+
end
|
45
|
+
|
46
|
+
def record_error_context(context)
|
47
|
+
case config.error_handler
|
48
|
+
when :sentry_raven
|
49
|
+
require 'sentry-raven'
|
50
|
+
Raven.extra_context(context)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def error_message(current_error, url, response)
|
55
|
+
if current_error && response
|
56
|
+
"#{current_error.message}: #{url} responded #{response.body} (#{response.code})"
|
57
|
+
elsif current_error
|
58
|
+
current_error.message
|
59
|
+
elsif response
|
60
|
+
"#{url} responded #{response.body} (#{response.code})"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module QuizApiClient
|
2
|
+
module HttpRequest
|
3
|
+
class Metrics
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
attr_reader :config, :method, :url, :code
|
7
|
+
def_delegators :config, :metrics_handler, :metrics_namespace
|
8
|
+
|
9
|
+
def initialize(config, method, url, code)
|
10
|
+
@config = config
|
11
|
+
@method = method
|
12
|
+
@url = url
|
13
|
+
@code = code
|
14
|
+
end
|
15
|
+
|
16
|
+
def increment
|
17
|
+
return unless configured?
|
18
|
+
|
19
|
+
case metrics_handler
|
20
|
+
when :inststatsd
|
21
|
+
InstStatsd::Statsd.increment count_metric_name, tags: tags
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def duration(start_time, end_time)
|
26
|
+
return unless configured?
|
27
|
+
|
28
|
+
duration_ms = ((end_time - start_time) * 1_000).round
|
29
|
+
|
30
|
+
case metrics_handler
|
31
|
+
when :inststatsd
|
32
|
+
InstStatsd::Statsd.timing duration_metric_name, duration_ms, tags: tags
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def configured?
|
39
|
+
metrics_handler_present? && metrics_namespace_present?
|
40
|
+
end
|
41
|
+
|
42
|
+
def count_metric_name
|
43
|
+
"#{metrics_namespace}.quiz_api_client.request.count"
|
44
|
+
end
|
45
|
+
|
46
|
+
def duration_metric_name
|
47
|
+
"#{metrics_namespace}.quiz_api_client.request.duration_ms"
|
48
|
+
end
|
49
|
+
|
50
|
+
def metrics_handler_present?
|
51
|
+
!metrics_handler.nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
def metrics_namespace_present?
|
55
|
+
!metrics_namespace.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
def tags
|
59
|
+
{
|
60
|
+
method: method,
|
61
|
+
status: code,
|
62
|
+
url: url
|
63
|
+
}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -1,29 +1,23 @@
|
|
1
1
|
module QuizApiClient::Services
|
2
2
|
class BaseApiService
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :config
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
|
7
|
-
)
|
8
|
-
@consumer_key = consumer_key
|
9
|
-
@consumer_request_id = consumer_request_id
|
10
|
-
@host = host
|
11
|
-
@protocol = protocol
|
12
|
-
@shared_secret = shared_secret
|
5
|
+
def initialize(config)
|
6
|
+
@config = config
|
13
7
|
@errors = []
|
14
8
|
end
|
15
9
|
|
16
10
|
private
|
17
11
|
|
18
12
|
def uri
|
19
|
-
URI.parse("#{protocol}://#{host}").to_s
|
13
|
+
URI.parse("#{config.protocol}://#{config.host}").to_s
|
20
14
|
end
|
21
15
|
|
22
16
|
def client(token:)
|
23
17
|
QuizApiClient::HttpClient.new(
|
24
18
|
uri: uri,
|
25
19
|
jwt: token,
|
26
|
-
|
20
|
+
config: config
|
27
21
|
)
|
28
22
|
end
|
29
23
|
end
|
@@ -1,15 +1,14 @@
|
|
1
1
|
module QuizApiClient::Services
|
2
2
|
class JwtService
|
3
|
+
extend Forwardable
|
4
|
+
|
3
5
|
HASHING_ALGORITHM = 'HS512'.freeze
|
4
6
|
|
5
|
-
attr_reader :
|
7
|
+
attr_reader :config
|
8
|
+
def_delegators :config, :host, :protocol, :consumer_key
|
6
9
|
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
@host = host
|
10
|
-
@shared_secret = shared_secret
|
11
|
-
@protocol = protocol
|
12
|
-
@consumer_request_id = consumer_request_id
|
10
|
+
def initialize(config)
|
11
|
+
@config = config
|
13
12
|
end
|
14
13
|
|
15
14
|
def grant_permission(scope:, exp: nil, uuid: nil, **additional_fields)
|
@@ -26,7 +25,7 @@ module QuizApiClient::Services
|
|
26
25
|
payload[:user][:uuid] = uuid
|
27
26
|
end
|
28
27
|
|
29
|
-
JWT.encode(payload, shared_secret, HASHING_ALGORITHM)
|
28
|
+
JWT.encode(payload, config.shared_secret, HASHING_ALGORITHM)
|
30
29
|
end
|
31
30
|
end
|
32
31
|
end
|
@@ -3,7 +3,17 @@ module QuizApiClient::Services
|
|
3
3
|
def create(params:, token: nil)
|
4
4
|
raise 'Quiz Id Required' unless params && params[:quiz_id]
|
5
5
|
|
6
|
-
|
6
|
+
client(token: token).post(
|
7
|
+
"/api/quizzes/#{params[:quiz_id]}/qti_imports",
|
8
|
+
qti_import: params
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
def banks(params:, token: nil)
|
13
|
+
client(token: token).post(
|
14
|
+
'/api/qti_imports/banks',
|
15
|
+
qti_import: params
|
16
|
+
)
|
7
17
|
end
|
8
18
|
|
9
19
|
def get_imported_consumer_settings(params:, token: nil)
|
@@ -13,14 +23,5 @@ module QuizApiClient::Services
|
|
13
23
|
"/api/quizzes/#{params[:quiz_id]}/qti_imports/imported_consumer_settings"
|
14
24
|
)
|
15
25
|
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def post_to_quiz_api(params:, token:)
|
20
|
-
client(token: token).post(
|
21
|
-
"/api/quizzes/#{params[:quiz_id]}/qti_imports",
|
22
|
-
qti_import: params
|
23
|
-
)
|
24
|
-
end
|
25
26
|
end
|
26
27
|
end
|
data/lib/quiz_api_client.rb
CHANGED
@@ -4,106 +4,105 @@ require 'link_header'
|
|
4
4
|
|
5
5
|
module QuizApiClient
|
6
6
|
class Client
|
7
|
-
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def_delegators :config, :consumer_key, :consumer_request_id, :host, :protocol, :shared_secret
|
8
10
|
|
9
11
|
def initialize(consumer_key:, host:, shared_secret:, protocol: 'https', consumer_request_id: nil)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
config.consumer_key = consumer_key
|
13
|
+
config.host = host
|
14
|
+
config.shared_secret = shared_secret
|
15
|
+
config.protocol = protocol
|
16
|
+
config.consumer_request_id = consumer_request_id
|
17
|
+
|
18
|
+
yield(config) if block_given?
|
19
|
+
end
|
20
|
+
|
21
|
+
def config
|
22
|
+
@_config ||= QuizApiClient::Config.new
|
15
23
|
end
|
16
24
|
|
17
25
|
def jwt_service
|
18
|
-
@_jwt_service ||= QuizApiClient::Services::JwtService.new(
|
26
|
+
@_jwt_service ||= QuizApiClient::Services::JwtService.new(config)
|
19
27
|
end
|
20
28
|
|
21
29
|
def quiz_service
|
22
|
-
@_quiz_service ||= Services::QuizService.new(
|
30
|
+
@_quiz_service ||= Services::QuizService.new(config)
|
23
31
|
end
|
24
32
|
|
25
33
|
def quizzes_service
|
26
|
-
@_quizzes_service ||= Services::QuizzesService.new(
|
34
|
+
@_quizzes_service ||= Services::QuizzesService.new(config)
|
27
35
|
end
|
28
36
|
|
29
37
|
def quiz_session_service
|
30
|
-
@_quiz_session_service ||= Services::QuizSessionService.new(
|
38
|
+
@_quiz_session_service ||= Services::QuizSessionService.new(config)
|
31
39
|
end
|
32
40
|
|
33
41
|
def quiz_sessions_service
|
34
|
-
@_quiz_sessions_service ||= Services::QuizSessionsService.new(
|
42
|
+
@_quiz_sessions_service ||= Services::QuizSessionsService.new(config)
|
35
43
|
end
|
36
44
|
|
37
45
|
def quiz_clone_job_service
|
38
|
-
@_quiz_clone_job_service ||= Services::QuizCloneJobService.new(
|
46
|
+
@_quiz_clone_job_service ||= Services::QuizCloneJobService.new(config)
|
39
47
|
end
|
40
48
|
|
41
49
|
def quiz_clone_jobs_service
|
42
|
-
@_quiz_clone_jobs_service ||= Services::QuizCloneJobsService.new(
|
50
|
+
@_quiz_clone_jobs_service ||= Services::QuizCloneJobsService.new(config)
|
43
51
|
end
|
44
52
|
|
45
53
|
def qti_imports_service
|
46
|
-
@_qti_imports_service ||= Services::QtiImportsService.new(
|
54
|
+
@_qti_imports_service ||= Services::QtiImportsService.new(config)
|
47
55
|
end
|
48
56
|
|
49
57
|
def item_analyses_service
|
50
|
-
@_item_analyses_service ||= Services::ItemAnalysesService.new(
|
58
|
+
@_item_analyses_service ||= Services::ItemAnalysesService.new(config)
|
51
59
|
end
|
52
60
|
|
53
61
|
def quiz_analyses_service
|
54
|
-
@_quiz_analyses_service ||= Services::QuizAnalysesService.new(
|
62
|
+
@_quiz_analyses_service ||= Services::QuizAnalysesService.new(config)
|
55
63
|
end
|
56
64
|
|
57
65
|
def quiz_session_events_service
|
58
|
-
@_quiz_session_events_service ||= Services::QuizSessionEventsService.new(
|
66
|
+
@_quiz_session_events_service ||= Services::QuizSessionEventsService.new(config)
|
59
67
|
end
|
60
68
|
|
61
69
|
def quiz_session_result_service
|
62
|
-
@_quiz_session_result_service ||= Services::QuizSessionResultService.new(
|
70
|
+
@_quiz_session_result_service ||= Services::QuizSessionResultService.new(config)
|
63
71
|
end
|
64
72
|
|
65
73
|
def quiz_entries_service
|
66
|
-
@_quiz_entries_service ||= Services::QuizEntriesService.new(
|
74
|
+
@_quiz_entries_service ||= Services::QuizEntriesService.new(config)
|
67
75
|
end
|
68
76
|
|
69
77
|
def session_items_service
|
70
|
-
@_session_items_service ||= Services::SessionItemsService.new(
|
78
|
+
@_session_items_service ||= Services::SessionItemsService.new(config)
|
71
79
|
end
|
72
80
|
|
73
81
|
def session_item_results_service
|
74
|
-
@_session_item_results_service ||= Services::SessionItemResultsService.new(
|
82
|
+
@_session_item_results_service ||= Services::SessionItemResultsService.new(config)
|
75
83
|
end
|
76
84
|
|
77
85
|
def items_service
|
78
|
-
@_items_service ||= QuizApiClient::Services::ItemsService.new(
|
86
|
+
@_items_service ||= QuizApiClient::Services::ItemsService.new(config)
|
79
87
|
end
|
80
88
|
|
81
89
|
def interaction_types_service
|
82
|
-
@_interaction_types_service ||= QuizApiClient::Services::InteractionTypesService.new(
|
90
|
+
@_interaction_types_service ||= QuizApiClient::Services::InteractionTypesService.new(config)
|
83
91
|
end
|
84
92
|
|
85
93
|
def shared_banks
|
86
|
-
@_shared_banks ||= QuizApiClient::Services::SharedBanks.new(
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
def service_params
|
92
|
-
{
|
93
|
-
consumer_key: consumer_key,
|
94
|
-
consumer_request_id: consumer_request_id,
|
95
|
-
host: host,
|
96
|
-
protocol: protocol,
|
97
|
-
shared_secret: shared_secret
|
98
|
-
}
|
94
|
+
@_shared_banks ||= QuizApiClient::Services::SharedBanks.new(config)
|
99
95
|
end
|
100
96
|
end
|
101
97
|
end
|
102
98
|
|
103
99
|
require 'quiz_api_client/version'
|
104
100
|
|
101
|
+
require 'quiz_api_client/config'
|
105
102
|
require 'quiz_api_client/http_client'
|
106
103
|
require 'quiz_api_client/json_formatter'
|
104
|
+
require 'quiz_api_client/http_request/failure'
|
105
|
+
require 'quiz_api_client/http_request/metrics'
|
107
106
|
require 'quiz_api_client/services/jwt_service'
|
108
107
|
require 'quiz_api_client/services/base_api_service'
|
109
108
|
|
data/quiz_api_client.gemspec
CHANGED
@@ -13,6 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
'Han Yan',
|
14
14
|
'Jayce Higgins',
|
15
15
|
'Marc Alan Phillips',
|
16
|
+
'Mark Starkman',
|
16
17
|
'Michael Brewer-Davis',
|
17
18
|
'Michael Hargiss',
|
18
19
|
'Omar Khan',
|
@@ -26,6 +27,7 @@ Gem::Specification.new do |spec|
|
|
26
27
|
'hyan@instructure.com',
|
27
28
|
'jhiggins@instructure.com',
|
28
29
|
'mphillips@instructure.com',
|
30
|
+
'mark.starkman@instructure.com',
|
29
31
|
'mbd@instructure.com',
|
30
32
|
'mhargiss@instructure.com',
|
31
33
|
'okhan@instructure.com',
|
@@ -40,17 +42,19 @@ Gem::Specification.new do |spec|
|
|
40
42
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
41
43
|
spec.require_paths = ['lib']
|
42
44
|
|
43
|
-
spec.required_ruby_version = '>= 2.
|
45
|
+
spec.required_ruby_version = '>= 2.6'
|
44
46
|
|
45
47
|
spec.add_dependency 'httparty', '~> 0.17'
|
46
48
|
spec.add_dependency 'jwt', '~> 2.2'
|
47
49
|
spec.add_dependency 'link_header', '~> 0.0'
|
48
50
|
|
51
|
+
spec.add_development_dependency 'inst_statsd'
|
49
52
|
spec.add_development_dependency 'pact', '~> 1.41'
|
50
53
|
spec.add_development_dependency 'pact_broker-client', '~> 1.19'
|
51
54
|
spec.add_development_dependency 'rake', '~> 12.3'
|
52
55
|
spec.add_development_dependency 'rspec', '~> 3.8'
|
53
56
|
spec.add_development_dependency 'rubocop', '~> 0.74.0'
|
57
|
+
spec.add_development_dependency 'sentry-raven', '~> 3.1'
|
54
58
|
spec.add_development_dependency 'simplecov'
|
55
59
|
spec.add_development_dependency 'webmock'
|
56
60
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quiz_api_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Wang
|
@@ -11,15 +11,16 @@ authors:
|
|
11
11
|
- Han Yan
|
12
12
|
- Jayce Higgins
|
13
13
|
- Marc Alan Phillips
|
14
|
+
- Mark Starkman
|
14
15
|
- Michael Brewer-Davis
|
15
16
|
- Michael Hargiss
|
16
17
|
- Omar Khan
|
17
18
|
- Robin Kuss
|
18
19
|
- Ryan Taylor
|
19
|
-
autorequire:
|
20
|
+
autorequire:
|
20
21
|
bindir: exe
|
21
22
|
cert_chain: []
|
22
|
-
date:
|
23
|
+
date: 2021-11-19 00:00:00.000000000 Z
|
23
24
|
dependencies:
|
24
25
|
- !ruby/object:Gem::Dependency
|
25
26
|
name: httparty
|
@@ -63,6 +64,20 @@ dependencies:
|
|
63
64
|
- - "~>"
|
64
65
|
- !ruby/object:Gem::Version
|
65
66
|
version: '0.0'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: inst_statsd
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
type: :development
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
66
81
|
- !ruby/object:Gem::Dependency
|
67
82
|
name: pact
|
68
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,6 +148,20 @@ dependencies:
|
|
133
148
|
- - "~>"
|
134
149
|
- !ruby/object:Gem::Version
|
135
150
|
version: 0.74.0
|
151
|
+
- !ruby/object:Gem::Dependency
|
152
|
+
name: sentry-raven
|
153
|
+
requirement: !ruby/object:Gem::Requirement
|
154
|
+
requirements:
|
155
|
+
- - "~>"
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '3.1'
|
158
|
+
type: :development
|
159
|
+
prerelease: false
|
160
|
+
version_requirements: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - "~>"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '3.1'
|
136
165
|
- !ruby/object:Gem::Dependency
|
137
166
|
name: simplecov
|
138
167
|
requirement: !ruby/object:Gem::Requirement
|
@@ -161,7 +190,7 @@ dependencies:
|
|
161
190
|
- - ">="
|
162
191
|
- !ruby/object:Gem::Version
|
163
192
|
version: '0'
|
164
|
-
description:
|
193
|
+
description:
|
165
194
|
email:
|
166
195
|
- acallejas@instructure.com
|
167
196
|
- bpetty@instructure.com
|
@@ -169,6 +198,7 @@ email:
|
|
169
198
|
- hyan@instructure.com
|
170
199
|
- jhiggins@instructure.com
|
171
200
|
- mphillips@instructure.com
|
201
|
+
- mark.starkman@instructure.com
|
172
202
|
- mbd@instructure.com
|
173
203
|
- mhargiss@instructure.com
|
174
204
|
- okhan@instructure.com
|
@@ -184,6 +214,7 @@ files:
|
|
184
214
|
- ".gitignore"
|
185
215
|
- ".rspec"
|
186
216
|
- ".rubocop.yml"
|
217
|
+
- CHANGELOG.md
|
187
218
|
- Dockerfile
|
188
219
|
- Gemfile
|
189
220
|
- Jenkinsfile
|
@@ -195,7 +226,10 @@ files:
|
|
195
226
|
- docker-compose.dev.override.yml
|
196
227
|
- docker-compose.yml
|
197
228
|
- lib/quiz_api_client.rb
|
229
|
+
- lib/quiz_api_client/config.rb
|
198
230
|
- lib/quiz_api_client/http_client.rb
|
231
|
+
- lib/quiz_api_client/http_request/failure.rb
|
232
|
+
- lib/quiz_api_client/http_request/metrics.rb
|
199
233
|
- lib/quiz_api_client/json_formatter.rb
|
200
234
|
- lib/quiz_api_client/services/base_api_service.rb
|
201
235
|
- lib/quiz_api_client/services/interaction_types_service.rb
|
@@ -218,10 +252,10 @@ files:
|
|
218
252
|
- lib/quiz_api_client/services/shared_banks.rb
|
219
253
|
- lib/quiz_api_client/version.rb
|
220
254
|
- quiz_api_client.gemspec
|
221
|
-
homepage:
|
255
|
+
homepage:
|
222
256
|
licenses: []
|
223
257
|
metadata: {}
|
224
|
-
post_install_message:
|
258
|
+
post_install_message:
|
225
259
|
rdoc_options: []
|
226
260
|
require_paths:
|
227
261
|
- lib
|
@@ -229,15 +263,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
229
263
|
requirements:
|
230
264
|
- - ">="
|
231
265
|
- !ruby/object:Gem::Version
|
232
|
-
version: '2.
|
266
|
+
version: '2.6'
|
233
267
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
234
268
|
requirements:
|
235
269
|
- - ">="
|
236
270
|
- !ruby/object:Gem::Version
|
237
271
|
version: '0'
|
238
272
|
requirements: []
|
239
|
-
rubygems_version: 3.
|
240
|
-
signing_key:
|
273
|
+
rubygems_version: 3.1.6
|
274
|
+
signing_key:
|
241
275
|
specification_version: 4
|
242
276
|
summary: Ruby client for quiz_api
|
243
277
|
test_files: []
|