Skip to content

Commit

Permalink
Webhook class is implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
takeshi-uchitane committed Dec 25, 2019
1 parent 7010da9 commit 91e8ead
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 132 deletions.
82 changes: 6 additions & 76 deletions app/models/simulator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,18 @@ class Simulator
include Mongoid::Timestamps
include Executable

WEBHOOK_CONDITION = {0=>:all_finished, 1=>:each_ps_finished}

field :name, type: String
field :description, type: String
field :sequential_seed, type: Boolean, default: false
field :position, type: Integer # position in the table. start from zero
field :to_be_destroyed, type: Boolean, default: false
field :webhook_url, type: String, default: ""
field :webhook_condition, type: Symbol , default: WEBHOOK_CONDITION[1]
field :webhook_triggered, type: Hash, default: {} # save conditios: {ps_id => {created: 0, submitted: 0, running: 0, finished: 0, failed: 0}}
embeds_many :parameter_definitions
has_many :parameter_sets, dependent: :destroy
has_many :runs
has_many :parameter_set_filters, dependent: :destroy
has_many :analyzers, dependent: :destroy, autosave: true #enable autosave to copy analyzers
has_many :save_tasks, dependent: :destroy
has_one :webhook, dependent: :destroy

default_scope ->{ where(to_be_destroyed: false) }

Expand All @@ -29,6 +25,7 @@ class Simulator

before_create :set_position
after_create :create_simulator_dir
after_create :create_a_webhook
before_destroy :delete_simulator_dir

public
Expand Down Expand Up @@ -391,76 +388,9 @@ def runs_csv(runs = self.runs)
end
end

def http_post(url, data)
req = Net::HTTP::Post.new(url.path)
req.set_form_data(data)
res = http.request(req)
return res
end

def webhook
trigger_condition = {}
ParameterSet.runs_status_count_batch(self.parameter_sets).each do |key, val|
trigger_condition[key.to_s] = val
end
return if trigger_condition == self.webhook_triggered
return if self.webhook_url.length == 0

ps_ids = trigger_condition.keys
ps_status = ps_ids.map do |ps_id|
[:created, :submitted, :running].map do |sym|
trigger_condition[ps_id][sym]
end.inject(:+)
end

# when the condition is all_finished
if self.webhook_condition == WEBHOOK_CONDITION[0] and ps_status.inject(:+) == 0
url = "/" + self.id.to_s
sim_name = self.name
payload={
"username": "oacis bot",
"icon_url": "https://slack.com/img/icons/app-57.png"
}
payload["text"] = <<~EOS
This is posted by #oacis.
EOS
payload["text"] += <<~EOS
Info: All run on <a href="#{url}">Simulator("#{self.id.to_s}")</a> was finished.
EOS
res = http_post(self.webhook_url, "payload=#{payload.to_json}")
end

# when the condition is each_ps_finished
if self.webhook_condition == WEBHOOK_CONDITION[1]
triggered_ps_ids = ps_ids.map.with_index do |ps_id, i|
id = ps_id
if self.webhook_triggered[ps_id]
old_status = [:created, :submitted, :running].map do |sym| self.webhook_triggered[ps_id][sym] end.inject(:+)
id = nil unless ps_status[i] == 0 and old_status > 0
else
id = nil unless ps_status[i] == 0
end
id
end.compact
payload={
"username": "oacis bot",
"icon_url": "https://slack.com/img/icons/app-57.png"
}
payload["text"] = <<~EOS
This is posted by #oacis.
EOS
triggered_ps_ids.each do |ps_id|
url = "/" + self.id.to_s + "/" + ps_id
payload["text"] += <<~EOS
Info: All run on <a href="#{url}">ParameterSet("#{ps_id}")</a> was finished.
EOS
end
if triggered_ps_ids.size > 0
res = http_post(self.webhook_url, "payload=#{payload.to_json}")
end
end

# save the trigger_condition
self.timeless.update_attribute(:webhook_triggered, trigger_condition)
private
def create_a_webhook
wh = self.build_webhook
wh.save
end
end
87 changes: 87 additions & 0 deletions app/models/webhook.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
class Webhook
include Mongoid::Document

WEBHOOK_CONDITION = {0=>:all_finished, 1=>:each_ps_finished}

field :webhook_url, type: String, default: ""
field :webhook_condition, type: Symbol , default: WEBHOOK_CONDITION[1]
field :webhook_triggered, type: Hash, default: {} # save conditios: {ps_id => {created: 0, submitted: 0, running: 0, finished: 0, failed: 0}}

belongs_to :simulator

private
def http_post(url, data)
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Post.new(url)
req.set_form_data(data)
res = http.request(req)
return res
end

private
def run
trigger_condition = {}
ParameterSet.runs_status_count_batch(simulator.parameter_sets).each do |key, val|
trigger_condition[key.to_s] = val
end
return if trigger_condition == self.webhook_triggered
return if self.webhook_url.length == 0

ps_ids = trigger_condition.keys
ps_status = ps_ids.map do |ps_id|
[:created, :submitted, :running].map do |sym|
trigger_condition[ps_id][sym]
end.inject(:+)
end
# when the condition is all_finished
if self.webhook_condition == WEBHOOK_CONDITION[0] and ps_status.inject(:+) == 0
url = "/" + simulator.id.to_s
sim_name = simulator.name
payload={
"username": "oacis bot",
"icon_url": "https://slack.com/img/icons/app-57.png"
}
payload["text"] = <<~EOS
This is posted by #oacis.
EOS
payload["text"] += <<~EOS
Info: All run on <a href="#{url}">Simulator("#{simulator.id.to_s}")</a> was finished.
EOS
res = http_post(self.webhook_url, {"payload"=>payload})
end

# when the condition is each_ps_finished
if self.webhook_condition == WEBHOOK_CONDITION[1]
triggered_ps_ids = ps_ids.map.with_index do |ps_id, i|
id = ps_id
if self.webhook_triggered[ps_id]
old_status = [:created, :submitted, :running].map do |sym| self.webhook_triggered[ps_id][sym] end.inject(:+)
id = nil unless ps_status[i] == 0 and old_status > 0
else
id = nil unless ps_status[i] == 0
end
id
end.compact
payload={
"username": "oacis bot",
"icon_url": "https://slack.com/img/icons/app-57.png"
}
payload["text"] = <<~EOS
This is posted by #oacis.
EOS
triggered_ps_ids.each do |ps_id|
url = "/" + simulator.id.to_s + "/" + ps_id
payload["text"] += <<~EOS
Info: All run on <a href="#{url}">ParameterSet("#{ps_id}")</a> was finished.
EOS
end
if triggered_ps_ids.size > 0
res = http_post(self.webhook_url, {"payload"=>payload})
end
end

# save the trigger_condition
self.update_attribute(:webhook_triggered, trigger_condition)
end
end
56 changes: 0 additions & 56 deletions spec/models/simulator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -778,60 +778,4 @@
end
end
end

describe "webhook can be triggerd" do

before(:each) do
@sim = FactoryBot.create(:simulator, parameter_sets_count: 2, runs_count: 0)
@sim.webhook_url= "https://example.com"
@sim.save!
allow(@sim).to receive(:http_post).with(anything(), anything()).and_return("Success")
end

it "with condition: all_finished" do

@sim.webhook_condition = Simulator::WEBHOOK_CONDITION[0] # all_finished
@sim.save!
@sim.webhook #do not call http_post
@sim.parameter_sets.each do |ps|
run = ps.runs.build
run.status = :finished
run.save
end
trigger_condition = {}
ParameterSet.runs_status_count_batch(@sim.parameter_sets).map do |key, val|
trigger_condition[key.to_s] = val.map{|k,v| [k.to_s, v] }.to_h
end
# if webhook condition is satisfied
expect(@sim).to have_received(:http_post).once
@sim.webhook # call http_post
@sim.reload
# webhook_condition and webhook_triggerd are updated
expect(@sim.webhook_condition).to eq(Simulator::WEBHOOK_CONDITION[0])
expect(@sim.webhook_triggered).to eq(trigger_condition)
end

it "with condition: each_ps_finished" do

@sim.webhook_condition = Simulator::WEBHOOK_CONDITION[1] # each_ps_finished
@sim.save!
@sim.webhook #do not call http_post
@sim.parameter_sets.each do |ps|
run = ps.runs.build
run.status = :finished
run.save
end
trigger_condition = {}
ParameterSet.runs_status_count_batch(@sim.parameter_sets).map do |key, val|
trigger_condition[key.to_s] = val.map{|k,v| [k.to_s, v] }.to_h
end
# if webhook condition is satisfied
expect(@sim).to have_received(:http_post).once
@sim.webhook # call http_post
@sim.reload
# webhook_condition and webhook_triggerd are updated
expect(@sim.webhook_condition).to eq(Simulator::WEBHOOK_CONDITION[1])
expect(@sim.webhook_triggered).to eq(trigger_condition)
end
end
end
63 changes: 63 additions & 0 deletions spec/models/webhook_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
require 'spec_helper'

describe Webhook do

describe "webhook can be triggerd" do

before(:each) do
@sim = FactoryBot.create(:simulator, parameter_sets_count: 2, runs_count: 0)
@webhook = @sim.webhook
@webhook.webhook_url = "https://example.com"
@webhook.save!
http_mock = instance_double(Net::HTTP)
allow(Net::HTTP).to receive(:new).with(anything(), anything()).and_return(http_mock)
allow(http_mock).to receive(:request).with(anything()).and_return("Success")
end

it "with condition: all_finished" do

@webhook.webhook_condition = Webhook::WEBHOOK_CONDITION[0] # all_finished
@webhook.save!
@webhook.run #do not call http_post
@sim.parameter_sets.each do |ps|
run = ps.runs.build
run.status = :finished
run.save
end
trigger_condition = {}
ParameterSet.runs_status_count_batch(@sim.parameter_sets).map do |key, val|
trigger_condition[key.to_s] = val.map{|k,v| [k.to_s, v] }.to_h
end
# if webhook condition is satisfied
expect(Net::HTTP).to have_received(:new).once
@webhook.run # call http_post
@webhook.reload
# webhook_condition and webhook_triggerd are updated
expect(@webhook.webhook_condition).to eq(Webhook::WEBHOOK_CONDITION[0])
expect(@webhook.webhook_triggered).to eq(trigger_condition)
end

it "with condition: each_ps_finished" do

@webhook.webhook_condition = Webhook::WEBHOOK_CONDITION[1] # each_ps_finished
@webhook.save!
@webhook.run #do not call http_post
@sim.parameter_sets.each do |ps|
run = ps.runs.build
run.status = :finished
run.save
end
trigger_condition = {}
ParameterSet.runs_status_count_batch(@sim.parameter_sets).map do |key, val|
trigger_condition[key.to_s] = val.map{|k,v| [k.to_s, v] }.to_h
end
# if webhook condition is satisfied
expect(Net::HTTP).to have_received(:new).once
@webhook.run # call http_post
@webhook.reload
# webhook_condition and webhook_triggerd are updated
expect(@webhook.webhook_condition).to eq(Webhook::WEBHOOK_CONDITION[1])
expect(@webhook.webhook_triggered).to eq(trigger_condition)
end
end
end

0 comments on commit 91e8ead

Please sign in to comment.