diff --git a/src/apps/clients/notifications.clj b/src/apps/clients/notifications.clj index 80373614..b53a59fc 100644 --- a/src/apps/clients/notifications.clj +++ b/src/apps/clients/notifications.clj @@ -106,11 +106,18 @@ (send-job-status-update username email-address job-info))) (defn send-interactive-job-status-update - "Sends notification of an interactive job status update to the user." - ([username email-address {status :status user-id :user_id :as job-info} {external-id :external_id}] - (if-not (jp/completed? status) - (let [access-url (str (interapps-url (curl/url (config/interapps-base)) user-id external-id))] - (send-job-status-update username email-address (assoc job-info :access_url access-url))) + "Sends notification of an interactive job status update to the user, attaching + the analysis access URL so the cluster running it is reachable from the + notification. job-info is the formatted job, whose :interactive_urls were + already built against the correct per-operator base URL." + ([username email-address {status :status :as job-info} _job-step-info] + ;; Attach :access_url only for a still-running job that actually has an + ;; interactive URL. Completed jobs get no URL (the analysis is gone), and a + ;; job with no :interactive_urls (no interactive steps) simply has none to + ;; attach -- in both cases the plain status update is sent. + (if-let [access-url (and (not (jp/completed? status)) + (first (:interactive_urls job-info)))] + (send-job-status-update username email-address (assoc job-info :access_url access-url)) (send-job-status-update username email-address job-info))) ([{username :shortUsername email-address :email} job-info job-step-info] (send-interactive-job-status-update username email-address job-info job-step-info))) diff --git a/src/apps/persistence/jobs.clj b/src/apps/persistence/jobs.clj index a52e1c36..dbea8ff7 100644 --- a/src/apps/persistence/jobs.clj +++ b/src/apps/persistence/jobs.clj @@ -356,7 +356,8 @@ :j.job_type :j.parent_id :j.is_batch - :j.notify))) + :j.notify + :j.operator_base_url))) (defn- hsql-job-base-query "The HoneySQL version of the base query used for retrieving job information from the database." @@ -379,7 +380,8 @@ :j.job_type :j.parent_id :j.is_batch - :j.notify) + :j.notify + :j.operator_base_url) (h/from [:job_listings :j]))) (defn- job-step-base-query @@ -474,7 +476,8 @@ :j.job_type :j.parent_id :j.is_batch - :j.notify) + :j.notify + :j.operator_base_url) (sql/where (exists (sql/subselect :job_steps (sql/where {:job_id :j.id :external_id [:in external-ids]})))) (sql/select))) diff --git a/src/apps/service/apps/job_listings.clj b/src/apps/service/apps/job_listings.clj index 681a1ebc..dd94923f 100644 --- a/src/apps/service/apps/job_listings.clj +++ b/src/apps/service/apps/job_listings.clj @@ -66,9 +66,14 @@ :batch_status (when (:is_batch job) (format-batch-status id))})) (defn- interactive-urls - [{user-id :user_id :as job} rep-steps] - (let [interactive? (fn [step] (= (:job_type step) jp/interactive-job-type)) - get-url (fn [step] (str (interapps-url (url (config/interapps-base)) user-id (:external_id step))))] + [{user-id :user_id operator-base-url :operator_base_url :as job} rep-steps] + ;; Use the base URL of the operator the job was launched on so the URL + ;; points at the cluster actually running the analysis. Jobs with no + ;; operator_id (legacy / pre-operator launches) fall back to the static + ;; interactive-apps base URL. + (let [base (url (or operator-base-url (config/interapps-base))) + interactive? (fn [step] (= (:job_type step) jp/interactive-job-type)) + get-url (fn [step] (str (interapps-url base user-id (:external_id step))))] (when-not (:is_batch job) (seq (map get-url (filter interactive? (rep-steps (:id job))))))))