diff --git a/app/models/simulator.rb b/app/models/simulator.rb
index 102c712c..3b9a6dd0 100644
--- a/app/models/simulator.rb
+++ b/app/models/simulator.rb
@@ -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) }
@@ -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
@@ -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 Simulator("#{self.id.to_s}") 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 ParameterSet("#{ps_id}") 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
diff --git a/app/models/webhook.rb b/app/models/webhook.rb
new file mode 100644
index 00000000..7616c7ee
--- /dev/null
+++ b/app/models/webhook.rb
@@ -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 Simulator("#{simulator.id.to_s}") 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 ParameterSet("#{ps_id}") 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
diff --git a/spec/models/simulator_spec.rb b/spec/models/simulator_spec.rb
index 5ea928f0..e188d057 100644
--- a/spec/models/simulator_spec.rb
+++ b/spec/models/simulator_spec.rb
@@ -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
diff --git a/spec/models/webhook_spec.rb b/spec/models/webhook_spec.rb
new file mode 100644
index 00000000..f68c7994
--- /dev/null
+++ b/spec/models/webhook_spec.rb
@@ -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
\ No newline at end of file