correlation_id 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6266047a4e8c34208e1fa280278cc356e3c36521
4
+ data.tar.gz: a1d7e3b675b127b9ddd499b9cec20dfa96060fbe
5
+ SHA512:
6
+ metadata.gz: 13a310538fcf3892aca406a97ebae211994375c0a7493a1cad30d217f17468ead75fc76314e7fcb5d4eb497cf86c50b80b4e41d9295a64f96ba88c6177518f09
7
+ data.tar.gz: ea0ffa171d5c879a6c43b97c41773e5e2877d6f34a1e6fe19f117df96252704b0194dd5c9e566c713f5a4028988440367b05a4cfc3334bbea75c2e2e6c3039fa
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # CorrelationId (System:MES,Squad:publisher,Type:Component)
2
+ Provides correllation id implementation.
3
+
4
+ ## Technology
5
+ * ruby
6
+
7
+ ## Build
8
+ [![Build Status](https://travis-ci.com/glomex/correlation_id.svg?token=mwYidZuSA2BCP1MMZkGB&branch=master)](https://travis-ci.com/glomex/correlation_id)
9
+
10
+ Allows correlation tracking from request down the network stack
11
+
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'correlation_id'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install correlation_id
28
+
29
+
30
+ ## Usage
31
+
32
+ ### Rails
33
+
34
+ You need just add gem to your Gemfile somewhere after `rails`.
35
+
36
+ ### Rack
37
+
38
+ You need to add our middleware to the top of your middlewares `config.ru`.
39
+
40
+ ```ruby
41
+ use CorrelationId::Middleware::Rack
42
+ ```
43
+
44
+ ### Airbrake
45
+
46
+ You need to add our Airbrake filter after configuring Airbrake
47
+
48
+ ```ruby
49
+ Airbrake.configure do |c|
50
+ c.project_id = ENV['AIRBRAKE_PROJECT_ID']
51
+ c.project_key = ENV['AIRBRAKE_PROJECT_KEY']
52
+ end
53
+
54
+ Airbrake.add_filter(CorrelationId::Middleware::Airbrake)
55
+ ```
56
+
57
+ ### Faraday
58
+
59
+ You need to add gem after faraday and add middleware when you create Faraday connection.
60
+
61
+ **Example:**
62
+
63
+ ```ruby
64
+ conn = Faraday.new 'http://example.com' do |faraday|
65
+ faraday.request :correlation_id
66
+ faraday.adapter Faraday.default_adapter
67
+ end
68
+ conn.get('/page')
69
+ ```
70
+
71
+ ## Development
72
+
73
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run
74
+ the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
75
+
76
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version,
77
+ update the version number in `version.rb`, and then run `bundle exec rake release`, which will
78
+ create a git tag for the version, push git commits and tags, and push the `.gem` file to
79
+ [rubygems.org](https://rubygems.org).
80
+
81
+
82
+ ## Contributing
83
+
84
+ Bug reports and pull requests are welcome on GitHub at https://github.com/glomex/correlation_id.
85
+ This project is intended to be a safe, welcoming space for collaboration, and contributors are
86
+ expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
87
+
88
+
89
+ ## License
90
+
91
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
92
+
@@ -0,0 +1,47 @@
1
+ require 'securerandom'
2
+
3
+ require 'correlation_id/version'
4
+
5
+ require 'correlation_id/middleware/airbrake' if defined?(Airbrake)
6
+ require 'correlation_id/middleware/faraday' if defined?(Faraday)
7
+ require 'correlation_id/middleware/rack' if defined?(Rack)
8
+ require 'correlation_id/middleware/railtie' if defined?(Rails)
9
+
10
+ module CorrelationId
11
+ HEADER_KEY = 'X-Correlation-ID'.freeze
12
+ THREAD_KEY = 'CORRELATION_UUID'.freeze
13
+
14
+ class << self
15
+ def uuid
16
+ Thread.current[THREAD_KEY] ||= _uuid
17
+ end
18
+
19
+ def uuid!
20
+ Thread.current[THREAD_KEY] = _uuid
21
+ end
22
+
23
+ def uuid=(value)
24
+ Thread.current[THREAD_KEY] = value
25
+ end
26
+
27
+ def disable
28
+ using_uuid(_uuid) { yield }
29
+ end
30
+
31
+ def using_uuid(new_uuid)
32
+ old_uuid = uuid
33
+
34
+ self.uuid = new_uuid
35
+ result = yield
36
+ self.uuid = old_uuid
37
+
38
+ result
39
+ end
40
+
41
+ private
42
+
43
+ def _uuid
44
+ SecureRandom.uuid
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,9 @@
1
+ module CorrelationId
2
+ module Middleware
3
+ class Airbrake
4
+ def self.call(notice)
5
+ notice[:context][:correlation_id] = CorrelationId.uuid
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module CorrelationId
2
+ module Middleware
3
+ class Faraday < ::Faraday::Middleware
4
+ def call(env)
5
+ env.request_headers[HEADER_KEY] = CorrelationId.uuid
6
+ @app.call(env)
7
+ end
8
+ end
9
+
10
+ ::Faraday::Request.register_middleware correlation_id: -> { Faraday }
11
+ end
12
+ end
@@ -0,0 +1,24 @@
1
+ module CorrelationId
2
+ module Middleware
3
+ class Rack
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ CorrelationId.uuid = header_from_env(env)
10
+
11
+ status, headers, body = @app.call(env)
12
+
13
+ headers = headers.merge(HEADER_KEY => CorrelationId.uuid)
14
+ [status, headers, body]
15
+ end
16
+
17
+ private
18
+
19
+ def header_from_env(env)
20
+ env["HTTP_#{HEADER_KEY.upcase.tr('-', '_')}"]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ module CorrelationId
2
+ module Middleware
3
+ class Railtie < ::Rails::Railtie
4
+ initializer('correlation_id.middleware') do |app|
5
+ app.config.middleware.insert(
6
+ 0,
7
+ CorrelationId::Middleware::Rack
8
+ )
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module CorrelationId
2
+ VERSION = '0.2.1'.freeze
3
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe CorrelationId::Middleware::Airbrake do
4
+ let(:project_id) { 123_456 }
5
+ let(:project_key) { 'project_key' }
6
+ let(:airbrake_endpoint) do
7
+ "https://airbrake.io/api/v3/projects/#{project_id}/notices"
8
+ end
9
+
10
+ before do
11
+ Airbrake.configure do |c|
12
+ c.project_id = project_id
13
+ c.project_key = project_key
14
+ end
15
+
16
+ Airbrake.add_filter(CorrelationId::Middleware::Airbrake)
17
+ end
18
+
19
+ describe 'X-Correlation-ID' do
20
+ before do
21
+ stub_request(:post, airbrake_endpoint).to_return(status: 201)
22
+ Airbrake.notify_sync('my error')
23
+ end
24
+
25
+ it 'sets header' do
26
+ body = /"correlation_id":"#{CorrelationId.uuid}"/
27
+ expect(a_request(:post, airbrake_endpoint).with(body: body)).to have_been_made.once
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe CorrelationId::Middleware::Faraday do
4
+ let(:conn) do
5
+ Faraday.new 'http://example.com' do |faraday|
6
+ faraday.request :correlation_id
7
+ faraday.adapter Faraday.default_adapter
8
+ end
9
+ end
10
+
11
+ describe 'X-Correlation-ID' do
12
+ let(:request) do
13
+ a_request(:get, 'http://example.com/').with(headers: { 'X-Correlation-ID' => uuid })
14
+ end
15
+
16
+ let!(:response) do
17
+ CorrelationId.uuid = uuid
18
+
19
+ stub_request(:get, 'http://example.com/')
20
+ .with(headers: { 'X-Correlation-ID' => uuid })
21
+ .to_return(status: 200, headers: { 'X-Correlation-ID' => uuid })
22
+
23
+ conn.get('/')
24
+ end
25
+
26
+ it 'sets header' do
27
+ expect(request).to have_been_made.once
28
+ expect(response.headers['X-Correlation-ID']).to eq(uuid)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe CorrelationId::Middleware::Rack do
4
+ let(:app) do
5
+ Rack::Builder.app do
6
+ use CorrelationId::Middleware::Rack
7
+ use Rack::Heartbeat
8
+ run(proc {})
9
+ end
10
+ end
11
+
12
+ it_behaves_like 'rack app'
13
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe CorrelationId::Middleware::Railtie do
4
+ let(:app) do
5
+ Rack::Builder.app do
6
+ run DummyApp
7
+ end
8
+ end
9
+
10
+ it_behaves_like 'rack app'
11
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe CorrelationId do
4
+ it 'has a version number' do
5
+ expect(described_class::VERSION).not_to be nil
6
+ end
7
+
8
+ describe '.uuid' do
9
+ def subject
10
+ described_class.uuid
11
+ end
12
+
13
+ it 'generates uuid' do
14
+ expect(subject).to be
15
+ end
16
+
17
+ it 'generates same id for one request' do
18
+ expect(Array.new(5) { subject }.uniq).to be_one
19
+ end
20
+ end
21
+
22
+ describe '.uuid!' do
23
+ def subject
24
+ described_class.uuid!
25
+ end
26
+
27
+ it 'generates uuid' do
28
+ expect(subject).to be
29
+ end
30
+
31
+ it 'generates new id for each request' do
32
+ expect(Array.new(5) { subject }.uniq.length).to eq(5)
33
+ end
34
+
35
+ it 'stores uuid' do
36
+ generated = subject
37
+ retrieved = described_class.uuid
38
+
39
+ expect(generated).to eq(retrieved)
40
+ end
41
+ end
42
+
43
+ describe '.uuid=' do
44
+ let(:uuid) { SecureRandom.uuid }
45
+
46
+ before { described_class.uuid = uuid }
47
+
48
+ it 'sets uuid' do
49
+ expect(described_class.uuid).to eq(uuid)
50
+ end
51
+ end
52
+
53
+ describe '.disable' do
54
+ let(:uuid) { SecureRandom.uuid }
55
+
56
+ before { described_class.uuid = uuid }
57
+
58
+ it 'can be temporarily disable' do
59
+ expect(described_class.uuid).to eq(uuid)
60
+
61
+ described_class.disable do
62
+ expect(described_class.uuid).to be
63
+ expect(described_class.uuid).not_to eq(uuid)
64
+ end
65
+
66
+ expect(described_class.uuid).to eq(uuid)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,27 @@
1
+ require 'bundler/setup'
2
+
3
+ require 'airbrake'
4
+ require 'net/http'
5
+ require 'faraday'
6
+ require 'rack/test'
7
+ require 'rack-heartbeat'
8
+ require 'webmock/rspec'
9
+ require 'rails'
10
+ require 'correlation_id'
11
+
12
+ Dir['./spec/support/**/*'].sort.each(&method(:require))
13
+
14
+ Rack::Heartbeat.heartbeat_path = ''
15
+
16
+ RSpec.configure do |config|
17
+ # Enable flags like --only-failures and --next-failure
18
+ config.example_status_persistence_file_path = '.rspec_status'
19
+
20
+ config.expect_with :rspec do |c|
21
+ c.syntax = :expect
22
+ end
23
+
24
+ config.include Rack::Test::Methods
25
+
26
+ config.include SpecHelpers
27
+ end
@@ -0,0 +1,21 @@
1
+ require 'action_controller/railtie'
2
+
3
+ class DummyApp < Rails::Application
4
+ config.session_store :cookie_store, key: 'd9cb0a8a7e5a2dd295fcb51ae81a2187'
5
+ config.secret_token = '94e56772b226b2b9fe20f9fd882e7f35'
6
+ config.secret_key_base = '80a0c6d167742a32428ec7a75edeea48'
7
+
8
+ config.eager_load = false
9
+
10
+ routes.draw do
11
+ get '/' => 'dummy#index'
12
+ end
13
+
14
+ class DummyController < ActionController::API
15
+ def index
16
+ render json: { hello: :world }
17
+ end
18
+ end
19
+ end
20
+
21
+ DummyApp.initialize!
@@ -0,0 +1,22 @@
1
+ RSpec.shared_examples 'rack app' do
2
+ describe 'X-Correlation-ID' do
3
+ context 'without header' do
4
+ before { get '/' }
5
+
6
+ it 'is set' do
7
+ expect(last_response.headers).to have_key('X-Correlation-ID')
8
+ end
9
+ end
10
+
11
+ context 'with header' do
12
+ before do
13
+ header 'X-Correlation-ID', uuid
14
+ get '/'
15
+ end
16
+
17
+ it 'is proxied' do
18
+ expect(last_response.headers['X-Correlation-ID']).to eq(uuid)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ module SpecHelpers
2
+ extend RSpec::SharedContext
3
+
4
+ let(:uuid) { SecureRandom.uuid }
5
+ end
metadata ADDED
@@ -0,0 +1,224 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: correlation_id
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Alex Tonkonozhenko
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-07-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: airbrake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '6'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: faraday
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rack-heartbeat
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rack-test
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rails
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: webmock
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ description: Allows correlation tracking from request down the network stack
168
+ email:
169
+ - alex@tonkonozhenko.com
170
+ executables: []
171
+ extensions: []
172
+ extra_rdoc_files: []
173
+ files:
174
+ - README.md
175
+ - lib/correlation_id.rb
176
+ - lib/correlation_id/middleware/airbrake.rb
177
+ - lib/correlation_id/middleware/faraday.rb
178
+ - lib/correlation_id/middleware/rack.rb
179
+ - lib/correlation_id/middleware/railtie.rb
180
+ - lib/correlation_id/version.rb
181
+ - spec/correlation_id/middleware/airbrake_spec.rb
182
+ - spec/correlation_id/middleware/faraday_spec.rb
183
+ - spec/correlation_id/middleware/rack_spec.rb
184
+ - spec/correlation_id/middleware/railtie_spec.rb
185
+ - spec/correlation_id_spec.rb
186
+ - spec/spec_helper.rb
187
+ - spec/support/dummy_app.rb
188
+ - spec/support/rack_app_behaviour.rb
189
+ - spec/support/spec_helpers.rb
190
+ homepage: https://github.com/glomex/correlation_id
191
+ licenses:
192
+ - MIT
193
+ metadata:
194
+ allowed_push_host: https://rubygems.org
195
+ post_install_message:
196
+ rdoc_options: []
197
+ require_paths:
198
+ - lib
199
+ required_ruby_version: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - ">="
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
204
+ required_rubygems_version: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ requirements: []
210
+ rubyforge_project:
211
+ rubygems_version: 2.6.11
212
+ signing_key:
213
+ specification_version: 4
214
+ summary: Allows correlation tracking from request down the network stack
215
+ test_files:
216
+ - spec/correlation_id/middleware/airbrake_spec.rb
217
+ - spec/correlation_id/middleware/faraday_spec.rb
218
+ - spec/correlation_id/middleware/rack_spec.rb
219
+ - spec/correlation_id/middleware/railtie_spec.rb
220
+ - spec/correlation_id_spec.rb
221
+ - spec/spec_helper.rb
222
+ - spec/support/dummy_app.rb
223
+ - spec/support/rack_app_behaviour.rb
224
+ - spec/support/spec_helpers.rb