FIX: Handle alerts with no id label

FIX: Handle alerts with no id label

Previously they were recorded with NULL values, but null values are treated as distinct in SQL. This commit replaces null identifiers with empty strings, so that they are deduplicated correctly.

diff --git a/app/jobs/concerns/alert_post_mixin.rb b/app/jobs/concerns/alert_post_mixin.rb
index 54c6770..8587501 100644
--- a/app/jobs/concerns/alert_post_mixin.rb
+++ b/app/jobs/concerns/alert_post_mixin.rb
@@ -21,7 +21,7 @@ module AlertPostMixin
         external_url: external_url,
         alertname: raw_alert['labels']['alertname'],
         datacenter: raw_alert["labels"]["datacenter"],
-        identifier: raw_alert['labels']['id'],
+        identifier: raw_alert['labels']['id'] || '',
         status: normalize_status(raw_alert['status']),
         starts_at: raw_alert['startsAt'],
         ends_at: raw_alert['status'] == 'firing' ? nil : raw_alert['endsAt'],
diff --git a/db/migrate/20200818090001_alert_receiver_alerts_identifier_null.rb b/db/migrate/20200818090001_alert_receiver_alerts_identifier_null.rb
new file mode 100644
index 0000000..afdf137
--- /dev/null
+++ b/db/migrate/20200818090001_alert_receiver_alerts_identifier_null.rb
@@ -0,0 +1,29 @@
+
+# frozen_string_literal: true
+class AlertReceiverAlertsIdentifierNull < ActiveRecord::Migration[6.0]
+  def change
+    # Remove duplicates
+    execute <<~SQL
+      DELETE FROM alert_receiver_alerts a1
+      USING (
+        SELECT MAX(id) as id, external_url, topic_id, identifier
+        FROM alert_receiver_alerts
+        GROUP BY (external_url, topic_id, identifier)
+        HAVING COUNT(*) > 1
+      ) a2
+      WHERE
+        a1.identifier IS NULL AND
+        a1.topic_id = a2.topic_id AND
+        a1.external_url = a2.external_url AND
+        a1.id <> a2.id
+    SQL
+
+    execute <<~SQL
+      UPDATE alert_receiver_alerts
+      SET identifier = ''
+      WHERE identifier IS NULL
+    SQL
+
+    change_column_null :alert_receiver_alerts, :identifier, false
+  end
+end
diff --git a/spec/integration/discourse_prometheus_alert_receiver/receiver_controller_spec.rb b/spec/integration/discourse_prometheus_alert_receiver/receiver_controller_spec.rb
index 8b3e5ca..4bcb792 100644
--- a/spec/integration/discourse_prometheus_alert_receiver/receiver_controller_spec.rb
+++ b/spec/integration/discourse_prometheus_alert_receiver/receiver_controller_spec.rb
@@ -538,6 +538,25 @@ RSpec.describe DiscoursePrometheusAlertReceiver::ReceiverController do
         end
       end
 
+      context "an alert with no identifier" do
+        let(:topic) { Fabricate(:post).topic }
+        let(:topic_map) { { alert_name => topic.id } }
+
+        before do
+          payload["alerts"].first["labels"].delete("id")
+        end
+
+        it "should update the topic" do
+          freeze_time Time.now.utc
+
+          expect do
+            post "/prometheus/receiver/#{token}", params: payload
+          end.to change { AlertReceiverAlert.count }.by(1)
+
+          expect(topic.alert_receiver_alert.first.identifier).to eq('')
+        end
+      end
+
       context "a resolving alert for a closed alert" do
         before do
           topic.alert_receiver_alerts.create!(

GitHub sha: c8738e37

1 Like