hoodoo 1.15.1 → 1.16.0

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
  SHA1:
3
- metadata.gz: 1074a01d7b0b249400765334f2991cd5c00b9e85
4
- data.tar.gz: 2e2473fbe2031ea3433a660e4a7bdc80a5012e03
3
+ metadata.gz: ab07823823bf92d1cfdd5070eb71585b95d7adbe
4
+ data.tar.gz: a9249d7aa4765ca5979eee0cf58d6919fc6f8a27
5
5
  SHA512:
6
- metadata.gz: 89f72453d4d3ba63e7d22676864171272fb2a8fb6caf5c38704ca3993fbde88a3993f7e1f6cd70b6fa880ba2e439171b975cf33db6a27a91e81dd382de45092a
7
- data.tar.gz: 3c1e9c6dc2e6f00955869055cee8f431364b3891fa72f68d2f7ca9dc6cfd6886d1501228d53aa2e95d4a7886362f193f96c2d4f77b7de8d3ba2c71fb30a57f6d
6
+ metadata.gz: 8fe35486b496e980d15d58cb2c353b86692833612a89cee9349b00bfac3fe5e54ae6cdb2fcd2591dd99454d66034e13b7fce01c6234c05ef0f5bcb7ea9dd0da1
7
+ data.tar.gz: 7101a2bc7914f19ab92fc338a74c16cb3f045b8d39985137dc177aae2bc1eb256a9f9af812be3eecd6eab78c2654302f853033c8bbf2bb88f7ab23e3767192fd
@@ -122,6 +122,7 @@ module Hoodoo
122
122
  #
123
123
  # * Hoodoo::Monkey
124
124
  # * Hoodoo::Monkey::Patch::NewRelicTracedAMQP
125
+ # * Hoodoo::Monkey::Patch::DatadogTracedAMQP
125
126
  #
126
127
  # +http_message+:: Hash describing the message to send.
127
128
  # +full_uri+:: Equivalent full URI of the request (information
data/lib/hoodoo/monkey.rb CHANGED
@@ -12,3 +12,4 @@
12
12
  require 'hoodoo/monkey/monkey'
13
13
  require 'hoodoo/monkey/patch/newrelic_middleware_analytics'
14
14
  require 'hoodoo/monkey/patch/newrelic_traced_amqp'
15
+ require 'hoodoo/monkey/patch/datadog_traced_amqp'
@@ -0,0 +1,89 @@
1
+ ########################################################################
2
+ # File:: datadog_traced_amqp.rb
3
+ # (C):: Loyalty New Zealand 2017
4
+ #
5
+ # Purpose:: Extend the AMQP endpoint to support Datadog cross-app
6
+ # transaction tracing. Only defined and registered if the
7
+ # Datadog gem is available and Hoodooo Client is in scope.
8
+ #
9
+ # See Hoodoo::Monkey::Patch::DatadogTracedAMQP for more.
10
+ # ----------------------------------------------------------------------
11
+ # 22-June-2017 (JRW): Created.
12
+ ########################################################################
13
+
14
+ module Hoodoo
15
+ module Monkey
16
+ module Patch
17
+
18
+ begin
19
+ require 'ddtrace' # Raises LoadError if Datadog is absent
20
+
21
+ # Wrap Hoodoo::Client::Endpoint::AMQP using Datadog transaction
22
+ # tracing so that over-queue inter-resource calls get connected
23
+ # together in Datadogs's view of the world.
24
+ #
25
+ # This module self-registers with Hooodoo::Monkey and, provided
26
+ # that Hoodoo::Services::Middleware is defined at parse-time,
27
+ # will be enabled by default.
28
+ #
29
+ module DatadogTracedAMQP
30
+
31
+ # Instance methods to patch over Hoodoo::Client::Endpoint::AMQP.
32
+ #
33
+ module InstanceExtensions
34
+
35
+ # Wrap the request with Datadog's distributed tracing.
36
+ # This adds headers to the request and extracts header data from
37
+ # the response. It calls the original implementation via +super+.
38
+ #
39
+ # +http_message+:: Hash describing the message to send.
40
+ #
41
+ # +full_uri+:: URI being sent to. This is somewhat meaningless
42
+ # when using AMQP but NewRelic requires it.
43
+ #
44
+ def monkey_send_request( http_message, full_uri )
45
+ amqp_response = nil
46
+
47
+ Datadog.tracer.trace( 'alchemy.request' ) do |span|
48
+ span.service = 'alchemy'
49
+ span.span_type = 'alchemy'
50
+ span.resource = http_message[ 'verb' ]
51
+ span.set_tag( 'target.path', http_message[ 'path'] )
52
+
53
+ # Add Datadog trace IDs to the HTTP message
54
+ http_message[ 'headers' ][ 'X_DDTRACE_PARENT_TRACE_ID' ] = span.trace_id.to_s
55
+ http_message[ 'headers' ][ 'X_DDTRACE_PARENT_SPAN_ID' ] = span.span_id.to_s
56
+
57
+ amqp_response = super( http_message, full_uri )
58
+ end
59
+
60
+ return amqp_response
61
+ end
62
+ end
63
+ end
64
+
65
+ # Register this class with the Hoodoo monkey patch engine.
66
+ #
67
+ if defined?( Hoodoo::Client ) &&
68
+ defined?( Hoodoo::Client::Endpoint ) &&
69
+ defined?( Hoodoo::Client::Endpoint::AMQP )
70
+
71
+ Hoodoo::Monkey.register(
72
+ target_unit: Hoodoo::Client::Endpoint::AMQP,
73
+ extension_module: Hoodoo::Monkey::Patch::DatadogTracedAMQP
74
+ )
75
+
76
+ if defined?( Hoodoo::Services ) &&
77
+ defined?( Hoodoo::Services::Middleware )
78
+
79
+ Hoodoo::Monkey.enable( extension_module: Hoodoo::Monkey::Patch::DatadogTracedAMQP )
80
+ end
81
+ end
82
+
83
+ rescue LoadError
84
+ # No Datadog => do nothing
85
+ end
86
+
87
+ end # module Patch
88
+ end # module Monkey
89
+ end # module Hoodoo
@@ -12,6 +12,6 @@ module Hoodoo
12
12
  # The Hoodoo gem version. If this changes, ensure that the date in
13
13
  # "hoodoo.gemspec" is correct and run "bundle install" (or "update").
14
14
  #
15
- VERSION = '1.15.1'
15
+ VERSION = '1.16.0'
16
16
 
17
17
  end
data/spec/ddtrace.rb ADDED
@@ -0,0 +1,17 @@
1
+ ########################################################################
2
+ # File:: ddtrace.rb
3
+ # (C):: Loyalty New Zealand 2017
4
+ #
5
+ # Purpose:: Override Datadog 'require "ddtrace"'. The test suite
6
+ # cannot allow "real" Datadog to be loaded as this would hook
7
+ # into all kinds of things and interfere with test results,
8
+ # especially for tests covering variant behaviour for when
9
+ # Datadog is present or absent.
10
+ # ----------------------------------------------------------------------
11
+ # 22-June-2017 (JRW): Created.
12
+ ########################################################################
13
+
14
+ # Yes, this is empty, just comments. The whole point is to allow code to
15
+ # be able to require what it thinks is Datadog without a LoadError
16
+ # exception being raised, but not actually define any Datadog components
17
+ # until the test suite is good and ready to do so (with mock data).
@@ -0,0 +1,63 @@
1
+ require 'spec_helper.rb'
2
+
3
+ # We need to run these tests in order. First a bunch of shared examples
4
+ # run. Then we check to see if hook methods were invoked in passing. You
5
+ # can't do that in an 'after' hook as exceptions therein cause warnings
6
+ # to be printed, but don't cause test failures.
7
+ #
8
+ describe Hoodoo::Monkey::Patch::DatadogTracedAMQP, :order => :defined do
9
+
10
+ # Not every test in the 'an AMQP-based middleware/client endpoint' shared
11
+ # example group will provoke a request. We cannot expect to have the
12
+ # NewRelic hooks called for every example. We *can* expect them to be
13
+ # called several times though, so use 'allow' to track those calls and
14
+ # count them.
15
+ #
16
+ before :all do
17
+ @@endpoint_do_amqp_count = 0
18
+ @@datadog_trace_count = 0
19
+
20
+ # Stub Datadog
21
+ class Datadog
22
+ def self.tracer
23
+ Datadog.new
24
+ end
25
+ end
26
+
27
+ Hoodoo::Monkey.enable( extension_module: Hoodoo::Monkey::Patch::DatadogTracedAMQP )
28
+ end
29
+
30
+ after :all do
31
+ Hoodoo::Monkey.disable( extension_module: Hoodoo::Monkey::Patch::DatadogTracedAMQP )
32
+ Object.send( :remove_const, :Datadog )
33
+ end
34
+
35
+ before :each do
36
+ expect( Hoodoo::Client::Endpoint::AMQP.ancestors ).to include( Hoodoo::Monkey::Patch::DatadogTracedAMQP::InstanceExtensions )
37
+
38
+ original_do_amqp = Hoodoo::Client::Endpoint::AMQP.instance_method( :do_amqp )
39
+
40
+ allow_any_instance_of( Hoodoo::Client::Endpoint::AMQP ).to receive( :do_amqp ) do | instance, description_of_request |
41
+ result = original_do_amqp.bind( instance ).call( description_of_request )
42
+ @@endpoint_do_amqp_count += 1
43
+ result
44
+ end
45
+
46
+ allow_any_instance_of( Datadog ).to receive( :trace ) do | &block |
47
+ # Datadog Trace method responds with a yielded span this is here to mock tha
48
+ span = double('span', trace_id: 'trace_id', span_id: 'span_id').as_null_object
49
+ @@datadog_trace_count += 1
50
+ block.call(span)
51
+ end
52
+ end
53
+
54
+ it_behaves_like 'an AMQP-based middleware/client endpoint',
55
+ {'X_DDTRACE_PARENT_TRACE_ID'=>'trace_id', 'X_DDTRACE_PARENT_SPAN_ID' => 'span_id'}
56
+
57
+ context 'afterwards' do
58
+ it 'has non-zero NewRelic method call counts' do
59
+ expect( @@endpoint_do_amqp_count ).to be > 5
60
+ expect( @@datadog_trace_count ).to eq( @@endpoint_do_amqp_count )
61
+ end
62
+ end
63
+ end
@@ -8,6 +8,7 @@ describe Hoodoo::Services::Middleware do
8
8
 
9
9
  context 'on queue' do
10
10
  before :all do
11
+ Hoodoo::Monkey.disable( extension_module: Hoodoo::Monkey::Patch::DatadogTracedAMQP )
11
12
  Hoodoo::Monkey.disable( extension_module: Hoodoo::Monkey::Patch::NewRelicTracedAMQP )
12
13
  end
13
14
 
@@ -437,8 +437,8 @@ describe Hoodoo::Services::Middleware::InterResourceLocal do
437
437
  it 'manages ActiveRecord when implementation is called in its presence' do
438
438
  pool = ActiveRecord::Base.connection_pool
439
439
 
440
- expect( ActiveRecord::Base ).to receive( :connection_pool ).twice.and_call_original
441
- expect( pool ).to receive( :with_connection ).twice.and_call_original
440
+ expect( ActiveRecord::Base ).to receive( :connection_pool ).exactly( 3 ).times.and_call_original
441
+ expect( pool ).to receive( :with_connection ).exactly( 2 ).times.and_call_original
442
442
 
443
443
  list_things()
444
444
  end
@@ -16,8 +16,10 @@ class RSpecTestServiceExoticStub < Hoodoo::Services::Service
16
16
  comprised_of RSpecTestServiceExoticStubInterface
17
17
  end
18
18
 
19
- shared_examples 'an AMQP-based middleware/client endpoint' do
19
+ # Optional extra header hash is for middleware that intentionally adds headers
20
+ shared_examples 'an AMQP-based middleware/client endpoint' do |optional_extra_header_hash|
20
21
  before :each do
22
+ @optional_extra_header_hash = optional_extra_header_hash || {}
21
23
  @old_queue = ENV[ 'AMQ_URI' ]
22
24
  ENV[ 'AMQ_URI' ] = 'amqp://test:test@127.0.0.1'
23
25
  @mw = Hoodoo::Services::Middleware.new( RSpecTestServiceExoticStub.new )
@@ -103,7 +105,7 @@ shared_examples 'an AMQP-based middleware/client endpoint' do
103
105
  'Accept-Language' => 'fr',
104
106
  'X-Interaction-ID' => @interaction.interaction_id,
105
107
  'X-Session-ID' => @interaction.context.session.session_id
106
- },
108
+ }.merge!( @optional_extra_header_hash ),
107
109
  } )
108
110
  end.and_return( mock_response )
109
111
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hoodoo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.15.1
4
+ version: 1.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Loyalty New Zealand
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-18 00:00:00.000000000 Z
11
+ date: 2017-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dalli
@@ -156,14 +156,14 @@ dependencies:
156
156
  requirements:
157
157
  - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: 1.4.0
159
+ version: '1.6'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: 1.4.0
166
+ version: '1.6'
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: pg
169
169
  requirement: !ruby/object:Gem::Requirement
@@ -317,6 +317,7 @@ files:
317
317
  - lib/hoodoo/middleware.rb
318
318
  - lib/hoodoo/monkey.rb
319
319
  - lib/hoodoo/monkey/monkey.rb
320
+ - lib/hoodoo/monkey/patch/datadog_traced_amqp.rb
320
321
  - lib/hoodoo/monkey/patch/newrelic_middleware_analytics.rb
321
322
  - lib/hoodoo/monkey/patch/newrelic_traced_amqp.rb
322
323
  - lib/hoodoo/presenters.rb
@@ -417,6 +418,7 @@ files:
417
418
  - spec/data/types/permissions_full_spec.rb
418
419
  - spec/data/types/permissions_resources_spec.rb
419
420
  - spec/data/types/permissions_spec.rb
421
+ - spec/ddtrace.rb
420
422
  - spec/errors/error_descriptions_spec.rb
421
423
  - spec/errors/errors_spec.rb
422
424
  - spec/files/regenerate.rb
@@ -428,6 +430,7 @@ files:
428
430
  - spec/logger/writers/log_entries_dot_com_writer_spec.rb
429
431
  - spec/logger/writers/stream_writer_spec.rb
430
432
  - spec/monkey/monkey_spec.rb
433
+ - spec/monkey/patch/datadog_traced_amqp_spec.rb
431
434
  - spec/monkey/patch/newrelic_middleware_analytics_spec.rb
432
435
  - spec/monkey/patch/newrelic_traced_amqp_spec.rb
433
436
  - spec/new_relic/agent/method_tracer.rb
@@ -560,6 +563,7 @@ test_files:
560
563
  - spec/data/types/permissions_full_spec.rb
561
564
  - spec/data/types/permissions_resources_spec.rb
562
565
  - spec/data/types/permissions_spec.rb
566
+ - spec/ddtrace.rb
563
567
  - spec/errors/error_descriptions_spec.rb
564
568
  - spec/errors/errors_spec.rb
565
569
  - spec/files/regenerate.rb
@@ -571,6 +575,7 @@ test_files:
571
575
  - spec/logger/writers/log_entries_dot_com_writer_spec.rb
572
576
  - spec/logger/writers/stream_writer_spec.rb
573
577
  - spec/monkey/monkey_spec.rb
578
+ - spec/monkey/patch/datadog_traced_amqp_spec.rb
574
579
  - spec/monkey/patch/newrelic_middleware_analytics_spec.rb
575
580
  - spec/monkey/patch/newrelic_traced_amqp_spec.rb
576
581
  - spec/new_relic/agent/method_tracer.rb