mirror of
https://github.com/Fishwaldo/huginn.git
synced 2025-03-16 03:41:41 +00:00
Merge pull request #1209 from darrencauthon/ping_agent
Http Status agent
This commit is contained in:
commit
1aaad3b7ef
4 changed files with 355 additions and 1 deletions
|
@ -110,7 +110,9 @@ module WebRequestConcern
|
|||
|
||||
builder.headers[:user_agent] = user_agent
|
||||
|
||||
builder.use FaradayMiddleware::FollowRedirects
|
||||
unless boolify(interpolated['disable_redirect_follow'])
|
||||
builder.use FaradayMiddleware::FollowRedirects
|
||||
end
|
||||
builder.request :url_encoded
|
||||
|
||||
if boolify(interpolated['disable_url_encoding'])
|
||||
|
|
81
app/models/agents/http_status_agent.rb
Normal file
81
app/models/agents/http_status_agent.rb
Normal file
|
@ -0,0 +1,81 @@
|
|||
module Agents
|
||||
|
||||
class HttpStatusAgent < Agent
|
||||
|
||||
include WebRequestConcern
|
||||
include FormConfigurable
|
||||
|
||||
can_dry_run!
|
||||
can_order_created_events!
|
||||
|
||||
default_schedule "every_12h"
|
||||
|
||||
form_configurable :url
|
||||
form_configurable :disable_redirect_follow, type: :array, values: ['true', 'false']
|
||||
|
||||
description <<-MD
|
||||
The HttpStatusAgent will check a url and emit the resulting HTTP status code.
|
||||
|
||||
Specify a `Url` and the Http Status Agent will produce an event with the http status code.
|
||||
|
||||
The `disable redirect follow` option causes the Agent to not follow HTTP redirects. For example, setting this to `true` will cause an agent that receives a 301 redirect to `http://yahoo.com` to return a status of 301 instead of following the redirect and returning 200.
|
||||
MD
|
||||
|
||||
event_description <<-MD
|
||||
Events will have the following fields:
|
||||
|
||||
{
|
||||
"url": "...",
|
||||
"status": "..."
|
||||
}
|
||||
MD
|
||||
|
||||
def working?
|
||||
memory['last_status'].to_i > 0
|
||||
end
|
||||
|
||||
def default_options
|
||||
{
|
||||
'url' => "http://google.com",
|
||||
'disable_redirect_follow' => "true",
|
||||
}
|
||||
end
|
||||
|
||||
def validate_options
|
||||
errors.add(:base, "a url must be specified") unless options['url'].present?
|
||||
end
|
||||
|
||||
def check
|
||||
check_this_url interpolated[:url]
|
||||
end
|
||||
|
||||
def receive(incoming_events)
|
||||
incoming_events.each do |event|
|
||||
interpolate_with(event) do
|
||||
check_this_url interpolated[:url]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_this_url(url)
|
||||
if result = ping(url)
|
||||
create_event payload: { 'url' => url, 'status' => result.status.to_s, 'response_received' => true }
|
||||
memory['last_status'] = result.status.to_s
|
||||
else
|
||||
create_event payload: { 'url' => url, 'response_received' => false }
|
||||
memory['last_status'] = nil
|
||||
end
|
||||
end
|
||||
|
||||
def ping(url)
|
||||
result = faraday.get url
|
||||
result.status > 0 ? result : nil
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
260
spec/controllers/http_status_agent_spec.rb
Normal file
260
spec/controllers/http_status_agent_spec.rb
Normal file
|
@ -0,0 +1,260 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe 'HttpStatusAgent' do
|
||||
|
||||
let(:agent) do
|
||||
Agents::HttpStatusAgent.new(:name => SecureRandom.uuid, :options => valid_params).tap do |a|
|
||||
a.service = services(:generic)
|
||||
a.user = users(:jane)
|
||||
a.options['url'] = 'http://google.com'
|
||||
a.save!
|
||||
|
||||
def a.interpolate_with(e, &block)
|
||||
@the_event = e
|
||||
block.call
|
||||
end
|
||||
|
||||
def a.interpolated
|
||||
@the_event.payload
|
||||
end
|
||||
|
||||
def a.create_event event
|
||||
@the_created_events ||= []
|
||||
@the_created_events << event
|
||||
end
|
||||
|
||||
def a.the_created_events
|
||||
@the_created_events || []
|
||||
end
|
||||
|
||||
def a.faraday
|
||||
@faraday ||= Struct.new(:programmed_responses).new({}).tap do |f|
|
||||
def f.get url
|
||||
programmed_responses[url] || raise('invalid url')
|
||||
end
|
||||
|
||||
def f.set url, response, time = nil
|
||||
sleep(time/1000) if time
|
||||
programmed_responses[url] = response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:valid_params) { {} }
|
||||
|
||||
describe "working" do
|
||||
it "should be working when the last status is 200" do
|
||||
agent.memory['last_status'] = '200'
|
||||
expect(agent.working?).to eq(true)
|
||||
end
|
||||
|
||||
it "should be working when the last status is 304" do
|
||||
agent.memory['last_status'] = '304'
|
||||
expect(agent.working?).to eq(true)
|
||||
end
|
||||
|
||||
it "should not be working if the status is 0" do
|
||||
agent.memory['last_status'] = '0'
|
||||
expect(agent.working?).to eq(false)
|
||||
end
|
||||
|
||||
it "should not be working if the status is missing" do
|
||||
agent.memory['last_status'] = nil
|
||||
expect(agent.working?).to eq(false)
|
||||
end
|
||||
|
||||
it "should not be working if the status is -1" do
|
||||
agent.memory['last_status'] = '-1'
|
||||
expect(agent.working?).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe "check" do
|
||||
|
||||
before do
|
||||
|
||||
def agent.interpolated
|
||||
@interpolated ||= { :url => SecureRandom.uuid }
|
||||
end
|
||||
|
||||
def agent.check_this_url url
|
||||
@url = url
|
||||
end
|
||||
|
||||
def agent.checked_url
|
||||
@url
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
it "should check the url" do
|
||||
agent.check
|
||||
expect(agent.checked_url).to eq(agent.interpolated[:url])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "receive" do
|
||||
|
||||
describe "with an event with a successful ping" do
|
||||
|
||||
let(:successful_url) { SecureRandom.uuid }
|
||||
|
||||
let(:status_code) { 200 }
|
||||
|
||||
let(:event_with_a_successful_ping) do
|
||||
agent.faraday.set(successful_url, Struct.new(:status).new(status_code))
|
||||
Event.new.tap { |e| e.payload = { url: successful_url } }
|
||||
end
|
||||
|
||||
let(:events) do
|
||||
[event_with_a_successful_ping]
|
||||
end
|
||||
|
||||
it "should create one event" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events.count).to eq(1)
|
||||
end
|
||||
|
||||
it "should note that the successful response succeeded" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events[0][:payload]['response_received']).to eq(true)
|
||||
end
|
||||
|
||||
it "should return the status code" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events[0][:payload]['status']).to eq('200')
|
||||
end
|
||||
|
||||
it "should remember the status" do
|
||||
agent.receive events
|
||||
expect(agent.memory['last_status']).to eq('200')
|
||||
end
|
||||
|
||||
describe "but the status code is not 200" do
|
||||
let(:status_code) { 500 }
|
||||
|
||||
it "should return the status code" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events[0][:payload]['status']).to eq('500')
|
||||
end
|
||||
|
||||
it "should remember the status" do
|
||||
agent.receive events
|
||||
expect(agent.memory['last_status']).to eq('500')
|
||||
end
|
||||
end
|
||||
|
||||
it "should return the original url" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events[0][:payload]['url']).to eq(successful_url)
|
||||
end
|
||||
|
||||
describe "but the ping returns a status code of 0" do
|
||||
|
||||
let(:event_with_a_successful_ping) do
|
||||
agent.faraday.set(successful_url, Struct.new(:status).new(0))
|
||||
Event.new.tap { |e| e.payload = { url: successful_url } }
|
||||
end
|
||||
|
||||
it "should create one event" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events.count).to eq(1)
|
||||
end
|
||||
|
||||
it "should note that no response was received" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events[0][:payload]['response_received']).to eq(false)
|
||||
end
|
||||
|
||||
it "should return the original url" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events[0][:payload]['url']).to eq(successful_url)
|
||||
end
|
||||
|
||||
it "should remember no status" do
|
||||
agent.memory['last_status'] = '200'
|
||||
agent.receive events
|
||||
expect(agent.memory['last_status']).to be_nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "but the ping returns a status code of -1" do
|
||||
|
||||
let(:event_with_a_successful_ping) do
|
||||
agent.faraday.set(successful_url, Struct.new(:status).new(-1))
|
||||
Event.new.tap { |e| e.payload = { url: successful_url } }
|
||||
end
|
||||
|
||||
it "should create one event" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events.count).to eq(1)
|
||||
end
|
||||
|
||||
it "should note that no response was received" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events[0][:payload]['response_received']).to eq(false)
|
||||
end
|
||||
|
||||
it "should return the original url" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events[0][:payload]['url']).to eq(successful_url)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "and with one event with a failing ping" do
|
||||
|
||||
let(:failing_url) { SecureRandom.uuid }
|
||||
let(:event_with_a_failing_ping) { Event.new.tap { |e| e.payload = { url: failing_url } } }
|
||||
|
||||
let(:events) do
|
||||
[event_with_a_successful_ping, event_with_a_failing_ping]
|
||||
end
|
||||
|
||||
it "should create two events" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events.count).to eq(2)
|
||||
end
|
||||
|
||||
it "should note that the failed response failed" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events[1][:payload]['response_received']).to eq(false)
|
||||
end
|
||||
|
||||
it "should note that the successful response succeeded" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events[0][:payload]['response_received']).to eq(true)
|
||||
end
|
||||
|
||||
it "should return the original url on both events" do
|
||||
agent.receive events
|
||||
expect(agent.the_created_events[0][:payload]['url']).to eq(successful_url)
|
||||
expect(agent.the_created_events[1][:payload]['url']).to eq(failing_url)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
before do
|
||||
expect(agent).to be_valid
|
||||
end
|
||||
|
||||
it "should validate url" do
|
||||
agent.options['url'] = ""
|
||||
expect(agent).not_to be_valid
|
||||
|
||||
agent.options['url'] = "http://www.google.com"
|
||||
expect(agent).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
|
@ -156,6 +156,17 @@ shared_examples_for WebRequestConcern do
|
|||
agent.options['disable_url_encoding'] = 'true'
|
||||
expect(agent.faraday.options.params_encoder).to eq(WebRequestConcern::DoNotEncoder)
|
||||
end
|
||||
|
||||
describe "redirect follow" do
|
||||
it "should use FollowRedirects by default" do
|
||||
expect(agent.faraday.builder.handlers).to include(FaradayMiddleware::FollowRedirects)
|
||||
end
|
||||
|
||||
it "should not use FollowRedirects when disabled" do
|
||||
agent.options['disable_redirect_follow'] = true
|
||||
expect(agent.faraday.builder.handlers).not_to include(FaradayMiddleware::FollowRedirects)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe WebRequestConcern::DoNotEncoder do
|
||||
|
|
Loading…
Add table
Reference in a new issue