Browse Source

Add `output_mode` to PostAgent

This allows to merge the contents of the the emitted event into
the received event by setting this option to `merge`.
Christian Hein 7 years ago
parent
commit
463aba9584
2 changed files with 54 additions and 3 deletions
  1. 14 3
      app/models/agents/post_agent.rb
  2. 40 0
      spec/models/agents/post_agent_spec.rb

+ 14 - 3
app/models/agents/post_agent.rb

@@ -30,6 +30,9 @@ module Agents
         If `emit_events` is set to `true`, the server response will be emitted as an Event and can be fed to a WebsiteAgent for parsing (using its `data_from_event` and `type` options). No data processing
         will be attempted by this Agent, so the Event's "body" value will always be raw text.
         The Event will also have a "headers" hash and a "status" integer value.
+
+        If `output_mode` is set to `merge`, the emitted Event will be merged into the original contents of the received Event.
+
         Set `event_headers_style` to one of the following values to normalize the keys of "headers" for downstream agents' convenience:
 
           * `capitalized` (default) - Header names are capitalized; e.g. "Content-Type"
@@ -60,6 +63,8 @@ module Agents
           },
           "body": "<html>Some data...</html>"
         }
+
+      Original event contents will be merged when `output_mode` is set to `merge`.
     MD
 
     def default_options
@@ -74,7 +79,8 @@ module Agents
         },
         'headers' => {},
         'emit_events' => 'false',
-        'no_merge' => 'false'
+        'no_merge' => 'false',
+        'output_mode' => 'clean'
       }
     end
 
@@ -122,6 +128,10 @@ module Agents
         errors.add(:base, "if provided, no_merge must be 'true' or 'false'")
       end
 
+      if options['output_mode'].present? && !options['output_mode'].to_s.include?('{') && !%[clean merge].include?(options['output_mode'].to_s)
+        errors.add(:base, "if provided, output_mode must be 'clean' or 'merge'")
+      end
+
       unless headers.is_a?(Hash)
         errors.add(:base, "if provided, headers must be a hash")
       end
@@ -210,11 +220,12 @@ module Agents
       }
 
       if boolify(interpolated['emit_events'])
-        create_event payload: {
+        new_event = interpolated['output_mode'].to_s == 'merge' ? event.payload.dup : {}
+        create_event payload: new_event.merge(
           body: response.body,
           headers: normalize_response_headers(response.headers),
           status: response.status
-        }
+        )
       end
     end
   end

+ 40 - 0
spec/models/agents/post_agent_spec.rb

@@ -292,6 +292,20 @@ describe Agents::PostAgent do
           @checker.check
           expect(@checker.events.last.payload['headers']).to eq({ 'content_type' => 'text/html' })
         end
+
+        context "when output_mode is set to 'merge'" do
+          before do
+            @checker.options['output_mode'] = 'merge'
+            @checker.save!
+          end
+
+          it "emits the received event" do
+            @checker.receive([@event])
+            @checker.check
+            expect(@checker.events.last.payload['somekey']).to eq('somevalue')
+            expect(@checker.events.last.payload['someotherkey']).to eq({ 'somekey' => 'value' })
+          end
+        end
       end
     end
   end
@@ -430,5 +444,31 @@ describe Agents::PostAgent do
       @checker.options['emit_events'] = true
       expect(@checker).to be_valid
     end
+
+    it "requires output_mode to be 'clean' or 'merge', if present" do
+      @checker.options['output_mode'] = 'what?'
+      expect(@checker).not_to be_valid
+
+      @checker.options.delete('output_mode')
+      expect(@checker).to be_valid
+
+      @checker.options['output_mode'] = 'clean'
+      expect(@checker).to be_valid
+
+      @checker.options['output_mode'] = 'merge'
+      expect(@checker).to be_valid
+
+      @checker.options['output_mode'] = :clean
+      expect(@checker).to be_valid
+
+      @checker.options['output_mode'] = :merge
+      expect(@checker).to be_valid
+
+      @checker.options['output_mode'] = '{{somekey}}'
+      expect(@checker).to be_valid
+
+      @checker.options['output_mode'] = "{% if key == 'foo' %}merge{% else %}clean{% endif %}"
+      expect(@checker).to be_valid
+    end
   end
 end