vigiles 0.1.0.pre.beta6 → 0.1.0.pre.beta8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ad47542ac3fa029cef8be2b99b104eb7995abf67765c8e0582426249f2d5a5a
4
- data.tar.gz: a468738d5ef0ad815be016420198ef939b254997509b25228f5b3779fa51976f
3
+ metadata.gz: 9ae2f2c7a8b3a0642d0fb228264821c882b9b98cf7a59380dcf139e1a514221c
4
+ data.tar.gz: 7ca651c0579f55907094ade6d43825cae72627fef6c8e995fd621d7f94e9acc4
5
5
  SHA512:
6
- metadata.gz: df8d3f3c5361e26b23b6a8cce014c4c55f3b15cc09f754a5ed3c34f15250360e09d6a0964ed23df5b1eb81cb87bec575198f71237fd24e1ce5f3ff201b279dc6
7
- data.tar.gz: fe0759a9e54c564ee235f421dbd8c7d8cfe34378777c1c3737fb29fa152a7f277c4a94808e138ec4fb61c0ef7a619bed8b60a9d14d3059299772a3ef4c2dbcda
6
+ metadata.gz: a942ca1c61aefdb02f843b7d3defd046ebce9935b47d406e8193c2c54b7befd360b19f974618f24f42c23278e8c313be513d25b68fece32985d2272f504b8c2e
7
+ data.tar.gz: 2a70d2be56a5c86fa4f30f881b6b9002e6967cfe6cd04339f1bb4f70f1a6f8bd28b6ae34281a19b5504ad82a594fa8b0660591ff0ab28e9ad3fdd94214c26d78
@@ -37,7 +37,7 @@ module Vigiles
37
37
 
38
38
  sig { params(request: ActionDispatch::Request).returns(Request) }
39
39
  def self.from(request)
40
- preferred_headers = Vigiles.specification.request_headers
40
+ preferred_headers = Vigiles.spec.request_headers
41
41
  available_headers = request.original_headers
42
42
  recorded_headers = (available_headers if preferred_headers.empty?)
43
43
  recorded_headers ||= preferred_headers.to_h { |h| [h, available_headers[h]] }
@@ -16,14 +16,17 @@ module Vigiles
16
16
  when Array
17
17
  return { body: :empty_no_content } if body.empty?
18
18
 
19
- { body: :not_empty_handle_later }
19
+ { __false_body: :not_empty_handle_later }
20
20
  when Rack::BodyProxy
21
21
  body_proxy = body
22
22
  body_proxy = body_proxy.instance_variable_get(:@body) until body_proxy.is_a?(Array)
23
- JSON.parse(body_proxy[0])
23
+ begin
24
+ JSON.parse(body_proxy[0])
25
+ rescue StandardError
26
+ { __false_body: body_proxy[0] }
27
+ end
24
28
  else
25
- debugger
26
- { body: :unknown_response_payload_type }
29
+ { __false_body: :unknown_response_payload_type }
27
30
  end
28
31
  end
29
32
 
@@ -18,23 +18,14 @@ module Vigiles
18
18
 
19
19
  sig { params(req: ActionDispatch::Request, res: Rack::Response).returns(T.nilable(Conversation)) }
20
20
  def self.record_conversation(req:, res:)
21
- # preferring to call `response.request` instead of preparing a new
22
- # request (via `ActionDispatch::Request.new(env)` and passing it
23
- # as an argument to this method because we can always recover the
24
- # specific request that elicited a given response, according to
25
- # https://github.com/rails/rails/blob/cacb8475a9d4373c0db437e7be4905685f03cefa/actionpack/lib/action_dispatch/http/response.rb#L53
26
- response = Response.from(res)
27
- metadata = Metadata.from(req.env)
28
- request = Request.from(req)
29
- extras = Extras.from(req.env)
30
-
31
- case (content_type = request.content_type)
32
- when ContentType::ApplicationJson.serialize then record_json_conversation(request:, response:, metadata:, extras:)
33
- when ContentType::TextHtml.serialize then record_html_conversation(request:, response:, metadata:, extras:)
34
- else record_conversation_with_unknown_content_type(request:, response:, metadata:, extras:)
21
+ content_type = req.content_type
22
+ if (recorder = Vigiles.spec.recorders[content_type]).nil?
23
+ raise \
24
+ UnrecordableRequestError,
25
+ "no recorder configured for content type: #{content_type}"
35
26
  end
36
- rescue Request::InvalidParameterError => e
37
- raise UnrecordableRequestError, "#{e.parameter} considered invalid"
27
+
28
+ recorder.record(req:, res:)
38
29
  end
39
30
 
40
31
  sig do
@@ -3,9 +3,24 @@
3
3
 
4
4
  module Vigiles
5
5
  class ConversationRecorder
6
+ class MisconfiguredRecorderError < StandardError
7
+ sig { returns(String) }
8
+ attr_reader :expected
9
+
10
+ sig { returns(String) }
11
+ attr_reader :actual
12
+
13
+ sig { params(expected: String, actual: String).void }
14
+ def initialize(expected:, actual:)
15
+ @expected = expected
16
+ @actual = actual
17
+ super
18
+ end
19
+ end
20
+
6
21
  abstract!
7
22
 
8
- sig { abstract.params(response: ActionDispatch::Response).returns(Archive::Conversation) }
9
- def record(response); end
23
+ sig { abstract.params(req: ActionDispatch::Request, res: Rack::Response).returns(Archive::Conversation) }
24
+ def record(req:, res:); end
10
25
  end
11
26
  end
@@ -6,8 +6,45 @@ module Vigiles
6
6
  class ApplicationJson < ConversationRecorder
7
7
  include Singleton
8
8
 
9
- sig { override.params(_response: ActionDispatch::Response).returns(Archive::Conversation) }
10
- def record(_response) = Archive::Conversation.new
9
+ ConversationRecorder = Vigiles::ConversationRecorder
10
+ ContentType = Vigiles::Types::ContentType
11
+ Conversation = Vigiles::Archive::Conversation
12
+ Response = Vigiles::Archive::Response
13
+ Metadata = Vigiles::Archive::Metadata
14
+ Request = Vigiles::Archive::Request
15
+ Extras = Vigiles::Archive::Extras
16
+
17
+ sig { override.params(req: ActionDispatch::Request, res: Rack::Response).returns(Archive::Conversation) }
18
+ def record(req:, res:)
19
+ unless req.content_type == ContentType::ApplicationJson.serialize
20
+ raise ConversationRecorder::MisconfiguredRecorderError.new(
21
+ expected: ContentType::ApplicationJson.serialize,
22
+ actual: req.content_type
23
+ )
24
+ end
25
+
26
+ response = Response.from(res)
27
+ request = Request.from(req)
28
+
29
+ Conversation.create!(
30
+ request_content_type: request.content_type,
31
+ request_user_agent: request.user_agent,
32
+ request_timestamp: request.timestamp,
33
+ request_remote_ip: request.remote_ip,
34
+ request_protocol: request.protocol,
35
+ request_headers: request.headers,
36
+ request_origin: request.origin,
37
+ request_payload: request.payload,
38
+ request_method: request.http_method.serialize,
39
+ request_path: request.path,
40
+ request_url: request.url,
41
+ request_id: request.id,
42
+ response_content_type: response.content_type,
43
+ response_headers: response.headers,
44
+ response_payload: response.payload,
45
+ response_status: response.status
46
+ )
47
+ end
11
48
  end
12
49
  end
13
50
  end
@@ -4,8 +4,10 @@
4
4
  module Vigiles
5
5
  module ConversationRecorders
6
6
  class Unknown < ConversationRecorder
7
- sig { override.params(_response: ActionDispatch::Response).returns(Archive::Conversation) }
8
- def record(_response) = Archive::Conversation.new
7
+ include Singleton
8
+
9
+ sig { override.params(req: ActionDispatch::Request, res: Rack::Response).returns(Archive::Conversation) }
10
+ def record(req:, res:) = Archive::Conversation.new
9
11
  end
10
12
  end
11
13
  end
data/lib/vigiles/spec.rb CHANGED
@@ -3,16 +3,16 @@
3
3
 
4
4
  module Vigiles
5
5
  class Spec < T::Struct
6
- const :content_type_recorders, T::Hash[String, ConversationRecorder]
7
6
  const :request_content_types, T::Set[String]
8
7
  const :request_headers, T::Set[String]
8
+ const :recorders, T::Hash[String, ConversationRecorder]
9
9
 
10
10
  sig { returns(Spec) }
11
11
  def self.make_default_spec
12
12
  Spec.new(
13
- content_type_recorders: Constants::DEFAULT_CONTENT_TYPE_RECORDERS,
14
13
  request_content_types: Constants::DEFAULT_CONTENT_TYPES,
15
- request_headers: Set[]
14
+ request_headers: Set[].freeze,
15
+ recorders: Constants::DEFAULT_CONTENT_TYPE_RECORDERS
16
16
  )
17
17
  end
18
18
  end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Vigiles
5
- VERSION = "0.1.0-beta6"
5
+ VERSION = "0.1.0-beta8"
6
6
  end
data/lib/vigiles.rb CHANGED
@@ -17,16 +17,16 @@ module Vigiles
17
17
  extend T::Sig
18
18
 
19
19
  sig { returns(Vigiles::Spec) }
20
- def self.specification
21
- @specification ||= T.let(
20
+ def self.spec
21
+ @spec ||= T.let(
22
22
  Vigiles::Spec.make_default_spec,
23
23
  T.nilable(Vigiles::Spec)
24
24
  )
25
25
  end
26
26
 
27
27
  sig { params(spec: Vigiles::Spec).returns(Vigiles::Spec) }
28
- def self.specification=(spec)
29
- @specification = spec
28
+ def self.spec=(spec)
29
+ @spec = spec
30
30
  end
31
31
 
32
32
  sig { params(req: ActionDispatch::Request, res: Rack::Response).returns(T.nilable(Archive::Conversation)) }
@@ -40,9 +40,9 @@ module Vigiles
40
40
 
41
41
  sig { params(blk: T.untyped).void }
42
42
  def self.configure(&blk)
43
- blk.call(specification)
43
+ blk.call(spec)
44
44
 
45
- # TODO(yaw, 2024-06-15): ensure that the specification is valid.
45
+ # TODO(yaw, 2024-06-15): ensure that the spec is valid.
46
46
  # ensure that for every content type a recorder is configured. otherwise
47
47
  # assign the general recorder for unknown content types.
48
48
  end
@@ -3,10 +3,10 @@
3
3
 
4
4
  require "action_dispatch"
5
5
  require "active_record"
6
+ require "logger"
6
7
  require "minitest/autorun"
7
8
  require "rails/generators"
8
9
  require "rails/generators/active_record"
9
10
  require "securerandom"
10
11
  require "sorbet-runtime"
11
- require "uri"
12
12
  require "zeitwerk"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vigiles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.beta6
4
+ version: 0.1.0.pre.beta8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yaw Boakye