vigiles 0.1.0.pre.beta7 → 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: 8ce9b4330b1d4ad0334d37f23d154149d01580c47f3f3c32d012f4b094244fac
4
- data.tar.gz: 11aa9a2571cf62454937a3e61b01b7de70bb702255b952d46f533d8831572ccd
3
+ metadata.gz: 9ae2f2c7a8b3a0642d0fb228264821c882b9b98cf7a59380dcf139e1a514221c
4
+ data.tar.gz: 7ca651c0579f55907094ade6d43825cae72627fef6c8e995fd621d7f94e9acc4
5
5
  SHA512:
6
- metadata.gz: 07be4f5abcbfae46edd0c480a6b3766924979990c065b7833c41c50ff6ff6401ab8b0798a643d5da339cb3a71e885be62af6034d774a2d400befb6cdf9db3e61
7
- data.tar.gz: dfe33dbe27d11e5ac0604538c803158315e5fcdd61726ef0107734dc61aa53eff04f7e6e769c2dae6d1fa5d534682d0d8895eec90ef1cd5d8e8d926157474a56
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]] }
@@ -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-beta7"
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.beta7
4
+ version: 0.1.0.pre.beta8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yaw Boakye