dev_suite 0.2.7 → 0.2.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +12 -0
- data/.github/workflows/ci.yml +1 -1
- data/.sonarcloud.properties +23 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +17 -33
- data/README.md +216 -0
- data/dev_suite.gemspec +1 -0
- data/examples/helpers/api_helper.rb +51 -0
- data/examples/helpers/data_helper.rb +72 -0
- data/examples/helpers/helpers.rb +4 -0
- data/examples/workflow/basic_workflow.rb +15 -0
- data/examples/workflow/composite_workflow.rb +21 -0
- data/examples/workflow/conditional_workflow.rb +17 -0
- data/examples/workflow/full_workflow.rb +79 -0
- data/examples/workflow/loop_workflow.rb +17 -0
- data/examples/workflow/order_processing_workflow.rb +163 -0
- data/examples/workflow/parallel_workflow.rb +17 -0
- data/lib/dev_suite/dev_suite.rb +3 -0
- data/lib/dev_suite/method_tracer/config/config.rb +11 -0
- data/lib/dev_suite/method_tracer/config/configuration.rb +16 -0
- data/lib/dev_suite/method_tracer/config.rb +9 -0
- data/lib/dev_suite/method_tracer/helpers.rb +41 -0
- data/lib/dev_suite/method_tracer/logger.rb +46 -0
- data/lib/dev_suite/method_tracer/method_tracer.rb +20 -0
- data/lib/dev_suite/method_tracer/tracer.rb +65 -0
- data/lib/dev_suite/method_tracer.rb +7 -0
- data/lib/dev_suite/request_builder/builder/base.rb +27 -0
- data/lib/dev_suite/request_builder/builder/builder.rb +10 -0
- data/lib/dev_suite/request_builder/builder/http.rb +32 -0
- data/lib/dev_suite/request_builder/builder.rb +9 -0
- data/lib/dev_suite/request_builder/config/config.rb +11 -0
- data/lib/dev_suite/request_builder/config/configuration.rb +24 -0
- data/lib/dev_suite/request_builder/config.rb +9 -0
- data/lib/dev_suite/request_builder/formatter/base.rb +13 -0
- data/lib/dev_suite/request_builder/formatter/formatter.rb +10 -0
- data/lib/dev_suite/request_builder/formatter/graphql.rb +19 -0
- data/lib/dev_suite/request_builder/formatter.rb +9 -0
- data/lib/dev_suite/request_builder/request_builder.rb +21 -0
- data/lib/dev_suite/request_builder/tool/base.rb +19 -0
- data/lib/dev_suite/request_builder/tool/curl.rb +91 -0
- data/lib/dev_suite/request_builder/tool/tool.rb +11 -0
- data/lib/dev_suite/request_builder/tool/validator/curl.rb +38 -0
- data/lib/dev_suite/request_builder/tool/validator/validator.rb +11 -0
- data/lib/dev_suite/request_builder/tool/validator.rb +11 -0
- data/lib/dev_suite/request_builder/tool.rb +9 -0
- data/lib/dev_suite/request_builder.rb +7 -0
- data/lib/dev_suite/request_logger/adapter/adapter.rb +11 -9
- data/lib/dev_suite/request_logger/adapter/faraday.rb +12 -1
- data/lib/dev_suite/request_logger/adapter/middleware/faraday.rb +3 -3
- data/lib/dev_suite/request_logger/adapter/net_http.rb +15 -6
- data/lib/dev_suite/request_logger/config/configuration.rb +1 -0
- data/lib/dev_suite/request_logger/extractor/base.rb +8 -2
- data/lib/dev_suite/request_logger/extractor/extractor.rb +5 -6
- data/lib/dev_suite/request_logger/extractor/faraday.rb +32 -14
- data/lib/dev_suite/request_logger/extractor/net_http.rb +53 -12
- data/lib/dev_suite/request_logger/logger.rb +9 -3
- data/lib/dev_suite/request_logger/request.rb +12 -0
- data/lib/dev_suite/request_logger/response.rb +34 -9
- data/lib/dev_suite/utils/construct/component/base.rb +13 -0
- data/lib/dev_suite/utils/construct/component/component.rb +1 -0
- data/lib/dev_suite/utils/construct/component/manager.rb +27 -10
- data/lib/dev_suite/utils/construct/component/validator/base.rb +25 -0
- data/lib/dev_suite/utils/construct/component/validator/validation_error.rb +21 -0
- data/lib/dev_suite/utils/construct/component/validator/validation_rule.rb +68 -0
- data/lib/dev_suite/utils/construct/component/validator/validator.rb +15 -0
- data/lib/dev_suite/utils/construct/component/validator.rb +13 -0
- data/lib/dev_suite/utils/construct/config/dependency_handler.rb +25 -34
- data/lib/dev_suite/utils/construct/config/settings/base.rb +43 -26
- data/lib/dev_suite/utils/data/base_operations.rb +61 -0
- data/lib/dev_suite/utils/data/data.rb +19 -0
- data/lib/dev_suite/utils/data/path_access.rb +172 -0
- data/lib/dev_suite/utils/data/search_filter.rb +60 -0
- data/lib/dev_suite/utils/data/serialization.rb +29 -0
- data/lib/dev_suite/utils/data/transformations.rb +45 -0
- data/lib/dev_suite/utils/data.rb +9 -0
- data/lib/dev_suite/utils/dependency_loader.rb +2 -2
- data/lib/dev_suite/utils/emoji.rb +19 -0
- data/lib/dev_suite/utils/file_loader/file_loader.rb +1 -5
- data/lib/dev_suite/utils/file_loader/loader/json.rb +4 -1
- data/lib/dev_suite/utils/file_loader/loader/loader.rb +23 -19
- data/lib/dev_suite/utils/file_loader/loader.rb +0 -2
- data/lib/dev_suite/utils/file_writer/atomic_writer.rb +53 -0
- data/lib/dev_suite/utils/file_writer/backup_manager.rb +21 -0
- data/lib/dev_suite/utils/file_writer/file_writer.rb +24 -0
- data/lib/dev_suite/utils/file_writer/writer/base.rb +43 -0
- data/lib/dev_suite/utils/file_writer/writer/json.rb +24 -0
- data/lib/dev_suite/utils/file_writer/writer/text.rb +27 -0
- data/lib/dev_suite/utils/file_writer/writer/writer.rb +14 -0
- data/lib/dev_suite/utils/file_writer/writer/yaml.rb +44 -0
- data/lib/dev_suite/utils/file_writer/writer.rb +11 -0
- data/lib/dev_suite/utils/file_writer/writer_manager.rb +32 -0
- data/lib/dev_suite/utils/file_writer.rb +9 -0
- data/lib/dev_suite/utils/logger.rb +7 -5
- data/lib/dev_suite/utils/store/config/config.rb +13 -0
- data/lib/dev_suite/utils/store/config/configuration.rb +30 -0
- data/lib/dev_suite/utils/store/config.rb +11 -0
- data/lib/dev_suite/utils/store/driver/base.rb +35 -0
- data/lib/dev_suite/utils/store/driver/driver.rb +18 -0
- data/lib/dev_suite/utils/store/driver/file.rb +61 -0
- data/lib/dev_suite/utils/store/driver/memory.rb +42 -0
- data/lib/dev_suite/utils/store/driver.rb +11 -0
- data/lib/dev_suite/utils/store/store.rb +69 -0
- data/lib/dev_suite/utils/store.rb +9 -0
- data/lib/dev_suite/utils/utils.rb +17 -5
- data/lib/dev_suite/utils/warning_handler.rb +25 -0
- data/lib/dev_suite/version.rb +1 -1
- data/lib/dev_suite/workflow/engine.rb +27 -0
- data/lib/dev_suite/workflow/step/base.rb +56 -0
- data/lib/dev_suite/workflow/step/composite.rb +27 -0
- data/lib/dev_suite/workflow/step/conditional.rb +23 -0
- data/lib/dev_suite/workflow/step/loop.rb +21 -0
- data/lib/dev_suite/workflow/step/parallel.rb +18 -0
- data/lib/dev_suite/workflow/step/step.rb +21 -0
- data/lib/dev_suite/workflow/step.rb +9 -0
- data/lib/dev_suite/workflow/step_context.rb +46 -0
- data/lib/dev_suite/workflow/workflow.rb +39 -0
- data/lib/dev_suite/workflow.rb +7 -0
- metadata +101 -3
- data/lib/dev_suite/utils/construct/component/initializer.rb +0 -28
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module RequestBuilder
|
5
|
+
module Tool
|
6
|
+
class Curl < Base
|
7
|
+
def build_command(http_method:, url:, headers:, body: nil)
|
8
|
+
validate_parameters(http_method, url, headers, body)
|
9
|
+
|
10
|
+
command = build_base_command(http_method, url)
|
11
|
+
|
12
|
+
add_headers(command, headers)
|
13
|
+
add_body(command, body)
|
14
|
+
add_insecure_option(command)
|
15
|
+
add_verbose_option(command)
|
16
|
+
add_follow_redirects_option(command)
|
17
|
+
add_cookie_option(command)
|
18
|
+
add_user_agent_option(command)
|
19
|
+
add_max_time_option(command)
|
20
|
+
add_connect_timeout_option(command)
|
21
|
+
|
22
|
+
command.join(" ").strip
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def validate_parameters(http_method, url, headers, body)
|
28
|
+
validator = Validator::Curl.new
|
29
|
+
validator.validate!(
|
30
|
+
http_method: http_method,
|
31
|
+
url: url,
|
32
|
+
headers: headers,
|
33
|
+
body: body,
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_base_command(http_method, url)
|
38
|
+
["curl", "-X #{http_method}", "'#{url}'"]
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_headers(command, headers)
|
42
|
+
headers.each do |key, value|
|
43
|
+
command << "-H '#{key}: #{value}'"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_body(command, body)
|
48
|
+
return unless body
|
49
|
+
|
50
|
+
command << (raw_data? ? "--data-raw '#{body}'" : "-d '#{body}'")
|
51
|
+
end
|
52
|
+
|
53
|
+
def add_insecure_option(command)
|
54
|
+
command << "--insecure" if fetch_setting("tool.curl.use_insecure", default: false)
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_verbose_option(command)
|
58
|
+
command << "-v" if fetch_setting("tool.curl.verbose", default: false)
|
59
|
+
end
|
60
|
+
|
61
|
+
def add_follow_redirects_option(command)
|
62
|
+
command << "-L" if fetch_setting("tool.curl.follow_redirects", default: true)
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_cookie_option(command)
|
66
|
+
cookie = fetch_setting("tool.curl.cookie")
|
67
|
+
command << "-b '#{cookie}'" if cookie
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_user_agent_option(command)
|
71
|
+
user_agent = fetch_setting("tool.curl.user_agent")
|
72
|
+
command << "-A '#{user_agent}'" if user_agent
|
73
|
+
end
|
74
|
+
|
75
|
+
def add_max_time_option(command)
|
76
|
+
max_time = fetch_setting("tool.curl.max_time")
|
77
|
+
command << "--max-time #{max_time}" if max_time
|
78
|
+
end
|
79
|
+
|
80
|
+
def add_connect_timeout_option(command)
|
81
|
+
connect_timeout = fetch_setting("tool.curl.connect_timeout")
|
82
|
+
command << "--connect-timeout #{connect_timeout}" if connect_timeout
|
83
|
+
end
|
84
|
+
|
85
|
+
def raw_data?
|
86
|
+
fetch_setting("tool.curl.raw_data", default: false)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DevSuite
|
4
|
+
module RequestBuilder
|
5
|
+
module Tool
|
6
|
+
module Validator
|
7
|
+
class Curl < Utils::Construct::Component::Validator::Base
|
8
|
+
VALID_HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"].freeze
|
9
|
+
|
10
|
+
def validate!(http_method:, url:, headers:, body: nil)
|
11
|
+
validate_http_method(http_method)
|
12
|
+
validate_url(url)
|
13
|
+
validate_headers(headers)
|
14
|
+
validate_body(body)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def validate_http_method(http_method)
|
20
|
+
validate_inclusion!(http_method, VALID_HTTP_METHODS, field_name: "HTTP Method")
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate_url(url)
|
24
|
+
validate_url!(url, field_name: "URL")
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate_headers(headers)
|
28
|
+
validate_hash!(headers, field_name: "Headers")
|
29
|
+
end
|
30
|
+
|
31
|
+
def validate_body(body)
|
32
|
+
validate_type!(body, [String, NilClass], field_name: "Body")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -8,21 +8,23 @@ module DevSuite
|
|
8
8
|
require_relative "base"
|
9
9
|
|
10
10
|
class << self
|
11
|
-
def
|
12
|
-
Config.configuration.
|
11
|
+
def handle_missing_nethttp(missing_dependencies)
|
12
|
+
Config.configuration.remove_failed_dependency(:adapters, :net_http, *missing_dependencies)
|
13
|
+
end
|
14
|
+
|
15
|
+
def handle_missing_faraday(missing_dependencies)
|
16
|
+
Config.configuration.remove_failed_dependency(:adapters, :faraday, *missing_dependencies)
|
13
17
|
end
|
14
18
|
end
|
15
19
|
|
16
20
|
# Load and register `net/http` adapter
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
load_dependency(["net/http"], on_failure: method(:handle_missing_nethttp)) do
|
22
|
+
require_relative "net_http"
|
23
|
+
register_component(NetHttp)
|
24
|
+
end
|
20
25
|
|
21
26
|
# Load and register `faraday` adapter
|
22
|
-
|
23
|
-
"faraday",
|
24
|
-
on_failure: method(:handle_missing_dependencies),
|
25
|
-
) do
|
27
|
+
load_dependency(["faraday"], on_failure: method(:handle_missing_faraday)) do
|
26
28
|
require_relative "faraday"
|
27
29
|
register_component(Faraday)
|
28
30
|
end
|
@@ -7,6 +7,8 @@ module DevSuite
|
|
7
7
|
|
8
8
|
class Faraday < Base
|
9
9
|
def enable
|
10
|
+
return unless faraday_defined?
|
11
|
+
|
10
12
|
::Faraday::Connection.class_eval do
|
11
13
|
alias_method(:_original_run_request, :run_request)
|
12
14
|
|
@@ -20,17 +22,26 @@ module DevSuite
|
|
20
22
|
|
21
23
|
Middleware::Faraday.new(lambda do |e|
|
22
24
|
_original_run_request(e.method, e.url, e.body, e.request_headers, &block)
|
23
|
-
end).call(env)
|
25
|
+
end).call(env, self)
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
30
|
def disable
|
31
|
+
return unless faraday_defined?
|
32
|
+
|
29
33
|
::Faraday::Connection.class_eval do
|
30
34
|
alias_method(:run_request, :_original_run_request)
|
31
35
|
remove_method(:_original_run_request)
|
32
36
|
end
|
33
37
|
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Check if Faraday is defined
|
42
|
+
def faraday_defined?
|
43
|
+
defined?(::Faraday::Connection) && defined?(::Faraday::Env)
|
44
|
+
end
|
34
45
|
end
|
35
46
|
end
|
36
47
|
end
|
@@ -5,14 +5,14 @@ module DevSuite
|
|
5
5
|
module Adapter
|
6
6
|
module Middleware
|
7
7
|
class Faraday < ::Faraday::Middleware
|
8
|
-
def call(env)
|
8
|
+
def call(env, instance = nil)
|
9
9
|
# Log the request details
|
10
|
-
Logger.log_request(
|
10
|
+
Logger.log_request(instance, env)
|
11
11
|
|
12
12
|
# Perform the actual request
|
13
13
|
@app.call(env).on_complete do |response_env|
|
14
14
|
# Log the response details
|
15
|
-
Logger.log_response(
|
15
|
+
Logger.log_response(instance, response_env)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -13,16 +13,25 @@ module DevSuite
|
|
13
13
|
|
14
14
|
# Override the request method to add logging functionality
|
15
15
|
def request(request, body = nil, &block)
|
16
|
-
|
16
|
+
start_time = Time.now
|
17
|
+
|
17
18
|
Logger.log_request(self, request)
|
18
19
|
|
19
|
-
|
20
|
-
|
20
|
+
response = nil
|
21
|
+
begin
|
22
|
+
# Call the original request method (now aliased as _original_request) to perform the actual HTTP request
|
23
|
+
response = _original_request(request, body, &block)
|
24
|
+
ensure
|
25
|
+
end_time = Time.now
|
26
|
+
response ||= Net::HTTPResponse.new("1.1", "500", "Internal Server Error")
|
27
|
+
response.instance_variable_set(:@start_time, start_time)
|
28
|
+
response.instance_variable_set(:@end_time, end_time)
|
29
|
+
response.define_singleton_method(:start_time) { @start_time }
|
30
|
+
response.define_singleton_method(:end_time) { @end_time }
|
21
31
|
|
22
|
-
|
23
|
-
|
32
|
+
Logger.log_response(self, response)
|
33
|
+
end
|
24
34
|
|
25
|
-
# Return the response object so that the calling code receives the expected result
|
26
35
|
response
|
27
36
|
end
|
28
37
|
end
|
@@ -4,11 +4,17 @@ module DevSuite
|
|
4
4
|
module RequestLogger
|
5
5
|
module Extractor
|
6
6
|
class Base < Utils::Construct::Component::Base
|
7
|
-
|
7
|
+
# Extracts the request details from an HTTP request object
|
8
|
+
# @param instance [Object] The instance of the HTTP client that is making the request
|
9
|
+
# @param request [Object] The request object that is being made
|
10
|
+
def extract_request(_instance, _request)
|
8
11
|
raise NotImplementedError
|
9
12
|
end
|
10
13
|
|
11
|
-
|
14
|
+
# Extracts the response details from an HTTP response object
|
15
|
+
# @param instance [Object] The instance of the HTTP client that is making the request
|
16
|
+
# @param response [Object] The response object that is being returned
|
17
|
+
def extract_response(_instance, _response)
|
12
18
|
raise NotImplementedError
|
13
19
|
end
|
14
20
|
end
|
@@ -6,14 +6,13 @@ module DevSuite
|
|
6
6
|
include Utils::Construct::Component::Manager
|
7
7
|
|
8
8
|
require_relative "base"
|
9
|
-
require_relative "net_http"
|
10
9
|
|
11
|
-
|
10
|
+
load_dependency(["net/http"], on_failure: ->(_) {}) do
|
11
|
+
require_relative "net_http"
|
12
|
+
register_component(NetHttp)
|
13
|
+
end
|
12
14
|
|
13
|
-
|
14
|
-
"faraday",
|
15
|
-
on_failure: ->(_) {}, # Empty lambda to do nothing on failure
|
16
|
-
) do
|
15
|
+
load_dependency(["faraday"], on_failure: ->(_) {}) do
|
17
16
|
require_relative "faraday"
|
18
17
|
register_component(Faraday)
|
19
18
|
end
|
@@ -4,31 +4,49 @@ module DevSuite
|
|
4
4
|
module RequestLogger
|
5
5
|
module Extractor
|
6
6
|
class Faraday < Base
|
7
|
-
COMPONENT_KEY = ::Faraday::
|
7
|
+
COMPONENT_KEY = ::Faraday::Connection
|
8
8
|
|
9
|
-
|
9
|
+
# Extracts the request details from a Faraday request object
|
10
|
+
# @param _instance [Faraday::Connection] The instance of the Faraday client that is making the request
|
11
|
+
# @param request [Faraday::Env] The request object that is being made
|
12
|
+
def extract_request(connection, request)
|
10
13
|
Request.new(
|
11
|
-
method:
|
12
|
-
url:
|
13
|
-
headers:
|
14
|
-
cookies:
|
15
|
-
body:
|
14
|
+
method: request.method.to_s.upcase,
|
15
|
+
url: build_url(connection),
|
16
|
+
headers: build_headers_from_request(request),
|
17
|
+
cookies: build_cookies(request),
|
18
|
+
body: request.body,
|
16
19
|
)
|
17
20
|
end
|
18
21
|
|
19
|
-
|
22
|
+
# Extracts the response details from a Faraday response object
|
23
|
+
# @param _instance [Faraday::Connection] The instance of the Faraday client that received the response
|
24
|
+
# @param response [Faraday::Env] The response object received
|
25
|
+
def extract_response(_connection, response)
|
20
26
|
Response.new(
|
21
|
-
status:
|
22
|
-
message:
|
23
|
-
headers:
|
24
|
-
body:
|
27
|
+
status: response.status,
|
28
|
+
message: response.reason_phrase || "",
|
29
|
+
headers: build_headers_from_response(response),
|
30
|
+
body: response.body,
|
25
31
|
)
|
26
32
|
end
|
27
33
|
|
28
34
|
private
|
29
35
|
|
30
|
-
def
|
31
|
-
|
36
|
+
def build_url(connection)
|
37
|
+
connection.url_prefix.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
def build_headers_from_request(request)
|
41
|
+
request.request_headers.to_h
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_headers_from_response(response)
|
45
|
+
response.response_headers.to_h
|
46
|
+
end
|
47
|
+
|
48
|
+
def build_cookies(request)
|
49
|
+
headers = build_headers_from_request(request)
|
32
50
|
headers["Cookie"] ? [headers["Cookie"]] : []
|
33
51
|
end
|
34
52
|
end
|
@@ -6,30 +6,71 @@ module DevSuite
|
|
6
6
|
class NetHttp < Base
|
7
7
|
COMPONENT_KEY = ::Net::HTTP
|
8
8
|
|
9
|
-
|
9
|
+
# Extracts the request details from a Net::HTTP request object
|
10
|
+
# @param http [Net::HTTP] The Net::HTTP object that is making the request
|
11
|
+
# @param request [Net::HTTP::Request] The request object that is being made
|
12
|
+
def extract_request(http, request)
|
10
13
|
Request.new(
|
11
|
-
method:
|
12
|
-
url:
|
13
|
-
headers:
|
14
|
-
cookies:
|
15
|
-
body:
|
14
|
+
method: request.method,
|
15
|
+
url: build_url(http, request),
|
16
|
+
headers: request.each_header.to_h,
|
17
|
+
cookies: build_cookies(request),
|
18
|
+
body: request.body,
|
16
19
|
)
|
17
20
|
end
|
18
21
|
|
19
|
-
|
22
|
+
# Extracts the response details from a Net::HTTP response object
|
23
|
+
# @param http [Net::HTTP] The Net::HTTP object that received the response
|
24
|
+
# @param response [Net::HTTPResponse] The response object received
|
25
|
+
# @return [Response] The extracted response details
|
26
|
+
def extract_response(_http, response)
|
20
27
|
Response.new(
|
21
|
-
status:
|
22
|
-
message:
|
23
|
-
headers:
|
24
|
-
body:
|
28
|
+
status: response.code.to_i,
|
29
|
+
message: response.message,
|
30
|
+
headers: response.each_header.to_h,
|
31
|
+
body: response.body,
|
32
|
+
response_time: calculate_response_time(response),
|
25
33
|
)
|
26
34
|
end
|
27
35
|
|
28
36
|
private
|
29
37
|
|
30
|
-
|
38
|
+
# Builds the full URL for the request
|
39
|
+
# @param http [Net::HTTP] The Net::HTTP object
|
40
|
+
# @param request [Net::HTTP::Request] The request object
|
41
|
+
# @return [String] The fully constructed URL
|
42
|
+
def build_url(http, request)
|
43
|
+
scheme = determine_scheme(http)
|
44
|
+
host = http.address
|
45
|
+
port_part = determine_port(http, scheme)
|
46
|
+
path = request.path
|
47
|
+
|
48
|
+
"#{scheme}://#{host}#{port_part}#{path}"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Extracts cookies from the request headers
|
52
|
+
# @param request [Net::HTTP::Request] The request object
|
53
|
+
# @return [Array<String>] Array of cookie strings
|
54
|
+
def build_cookies(request)
|
31
55
|
request.to_hash["cookie"] || []
|
32
56
|
end
|
57
|
+
|
58
|
+
# Calculates the response time (if available)
|
59
|
+
# This example assumes response time is tracked separately and stored in the `http` object
|
60
|
+
def calculate_response_time(response)
|
61
|
+
if response.respond_to?(:start_time) && response.respond_to?(:end_time)
|
62
|
+
response.end_time - response.start_time
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def determine_scheme(http)
|
67
|
+
http.use_ssl? ? "https" : "http"
|
68
|
+
end
|
69
|
+
|
70
|
+
def determine_port(http, scheme)
|
71
|
+
default_port = (scheme == "https" ? 443 : 80)
|
72
|
+
http.port == default_port ? nil : ":#{http.port}"
|
73
|
+
end
|
33
74
|
end
|
34
75
|
end
|
35
76
|
end
|
@@ -20,6 +20,7 @@ module DevSuite
|
|
20
20
|
log_entry(format_response_line(instance, response), status_emoji, log_level)
|
21
21
|
log_headers(response) if settings.get(:log_headers)
|
22
22
|
log_body(response.body, "Response") if settings.get(:log_body)
|
23
|
+
log_response_time(response) if settings.get(:log_response_time)
|
23
24
|
end
|
24
25
|
|
25
26
|
private
|
@@ -34,12 +35,12 @@ module DevSuite
|
|
34
35
|
|
35
36
|
def extract_request(instance, request)
|
36
37
|
extractor = Extractor.build_component_from_instance(instance)
|
37
|
-
extractor.extract_request(request)
|
38
|
+
extractor.extract_request(instance, request)
|
38
39
|
end
|
39
40
|
|
40
41
|
def extract_response(instance, response)
|
41
42
|
extractor = Extractor.build_component_from_instance(instance)
|
42
|
-
extractor.extract_response(response)
|
43
|
+
extractor.extract_response(instance, response)
|
43
44
|
end
|
44
45
|
|
45
46
|
def log_entry(message, emoji, level = settings.get(:log_level))
|
@@ -64,7 +65,7 @@ module DevSuite
|
|
64
65
|
|
65
66
|
def log_headers(request)
|
66
67
|
headers = request.headers
|
67
|
-
log_entry("Headers: #{headers}", :document)
|
68
|
+
log_entry("Headers: #{headers}", :document)
|
68
69
|
end
|
69
70
|
|
70
71
|
def log_cookies(request)
|
@@ -81,6 +82,11 @@ module DevSuite
|
|
81
82
|
|
82
83
|
log_entry("#{type} Body: #{body}", :code)
|
83
84
|
end
|
85
|
+
|
86
|
+
def log_response_time(response)
|
87
|
+
response_time = response.response_time
|
88
|
+
log_entry("Response Time: #{response_time} seconds", :stop) if response_time
|
89
|
+
end
|
84
90
|
end
|
85
91
|
end
|
86
92
|
end
|
@@ -5,6 +5,8 @@
|
|
5
5
|
module DevSuite
|
6
6
|
module RequestLogger
|
7
7
|
class Request
|
8
|
+
include Utils::WarningHandler
|
9
|
+
|
8
10
|
attr_reader :method, :url, :headers, :cookies, :body
|
9
11
|
|
10
12
|
def initialize(method:, url:, headers:, cookies:, body:)
|
@@ -13,6 +15,16 @@ module DevSuite
|
|
13
15
|
@headers = headers
|
14
16
|
@cookies = cookies
|
15
17
|
@body = body
|
18
|
+
|
19
|
+
validate_presence
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def validate_presence
|
25
|
+
warn_if_missing("Request URL", @url)
|
26
|
+
warn_if_missing("Request Method", @method)
|
27
|
+
warn_if_missing("Request Headers", @headers)
|
16
28
|
end
|
17
29
|
end
|
18
30
|
end
|
@@ -1,28 +1,53 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# request_logger/response.rb
|
4
|
-
|
5
3
|
module DevSuite
|
6
4
|
module RequestLogger
|
7
5
|
class Response
|
8
|
-
|
6
|
+
include Utils::WarningHandler
|
7
|
+
|
8
|
+
attr_reader :status, :message, :headers, :body, :content_type, :content_length, :response_time
|
9
9
|
|
10
|
-
def initialize(
|
11
|
-
|
10
|
+
def initialize(
|
11
|
+
status:,
|
12
|
+
message:,
|
13
|
+
headers:,
|
14
|
+
body:,
|
15
|
+
response_time: nil
|
16
|
+
)
|
17
|
+
@status = status.to_i
|
12
18
|
@message = message
|
13
|
-
@headers = headers
|
14
|
-
@body = body
|
19
|
+
@headers = headers
|
20
|
+
@body = body
|
21
|
+
@content_type = extract_content_type
|
22
|
+
@content_length = extract_content_length
|
23
|
+
@response_time = response_time
|
24
|
+
|
25
|
+
validate_presence
|
15
26
|
end
|
16
27
|
|
17
|
-
# Check if the response is successful (2xx status codes)
|
18
28
|
def success?
|
19
29
|
status.between?(200, 299)
|
20
30
|
end
|
21
31
|
|
22
|
-
# Helper method to fetch specific headers in a case-insensitive way
|
23
32
|
def header(key)
|
24
33
|
headers[key.to_s.downcase] || headers[key.to_s]
|
25
34
|
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def extract_content_type
|
39
|
+
header("Content-Type") || "unknown"
|
40
|
+
end
|
41
|
+
|
42
|
+
def extract_content_length
|
43
|
+
length = header("Content-Length")
|
44
|
+
length ? length.to_i : 0
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate_presence
|
48
|
+
warn_if_missing("Response Status", @status)
|
49
|
+
warn_if_missing("Response Headers", @headers)
|
50
|
+
end
|
26
51
|
end
|
27
52
|
end
|
28
53
|
end
|
@@ -23,6 +23,19 @@ module DevSuite
|
|
23
23
|
snake_case_class_name.to_sym
|
24
24
|
end
|
25
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Fetches a setting based on the provided key.
|
30
|
+
# This method should be overridden by subclasses to provide specific behavior.
|
31
|
+
#
|
32
|
+
# @param key [String] The key for the setting.
|
33
|
+
# @param default [Object] The default value to return if the key is not found.
|
34
|
+
def fetch_setting(_key, _default = nil)
|
35
|
+
# Example implementation
|
36
|
+
# Config.configuration.settings.get(key, default)
|
37
|
+
raise NotImplementedError
|
38
|
+
end
|
26
39
|
end
|
27
40
|
end
|
28
41
|
end
|