post_agent.rb 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. module Agents
  2. class PostAgent < Agent
  3. cannot_create_events!
  4. default_schedule "never"
  5. description <<-MD
  6. A PostAgent receives events from other agents (or runs periodically), merges those events with the contents of `payload`, and sends the results as POST (or GET) requests to a specified url.
  7. The `post_url` field must specify where you would like to send requests. Please include the URI scheme (`http` or `https`).
  8. The `headers` field is optional. When present, it should be a hash of headers to send with the request.
  9. MD
  10. event_description "Does not produce events."
  11. def default_options
  12. {
  13. 'post_url' => "http://www.example.com",
  14. 'expected_receive_period_in_days' => 1,
  15. 'method' => 'post',
  16. 'payload' => {
  17. 'key' => 'value'
  18. },
  19. 'headers' => {}
  20. }
  21. end
  22. def working?
  23. last_receive_at && last_receive_at > interpolated['expected_receive_period_in_days'].to_i.days.ago && !recent_error_logs?
  24. end
  25. def method
  26. (interpolated['method'].presence || 'post').to_s.downcase
  27. end
  28. def headers
  29. interpolated['headers'].presence || {}
  30. end
  31. def validate_options
  32. unless options['post_url'].present? && options['expected_receive_period_in_days'].present?
  33. errors.add(:base, "post_url and expected_receive_period_in_days are required fields")
  34. end
  35. if options['payload'].present? && !options['payload'].is_a?(Hash)
  36. errors.add(:base, "if provided, payload must be a hash")
  37. end
  38. unless %w[post get].include?(method)
  39. errors.add(:base, "method must be 'post' or 'get'")
  40. end
  41. unless headers.is_a?(Hash)
  42. errors.add(:base, "if provided, headers must be a hash")
  43. end
  44. end
  45. def receive(incoming_events)
  46. incoming_events.each do |event|
  47. handle (interpolated(event.payload)['payload'].presence || {}).merge(event.payload)
  48. end
  49. end
  50. def check
  51. handle interpolated['payload'].presence || {}
  52. end
  53. def generate_uri(params = nil)
  54. uri = URI interpolated[:post_url]
  55. uri.query = URI.encode_www_form(Hash[URI.decode_www_form(uri.query || '')].merge(params)) if params
  56. uri
  57. end
  58. private
  59. def handle(data)
  60. if method == 'post'
  61. post_data(data)
  62. elsif method == 'get'
  63. get_data(data)
  64. else
  65. error "Invalid method '#{method}'"
  66. end
  67. end
  68. def post_data(data)
  69. uri = generate_uri
  70. req = Net::HTTP::Post.new(uri.request_uri, headers)
  71. req.form_data = data
  72. Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == "https") { |http| http.request(req) }
  73. end
  74. def get_data(data)
  75. uri = generate_uri(data)
  76. req = Net::HTTP::Get.new(uri.request_uri, headers)
  77. Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == "https") { |http| http.request(req) }
  78. end
  79. end
  80. end