From 0dd4013dc0bf43f508cf0c59a77295891bda202e Mon Sep 17 00:00:00 2001 From: Noah Moss <32746338+noahmoss@users.noreply.github.com> Date: Mon, 26 Aug 2024 11:27:05 -0400 Subject: [PATCH] Use more precise query contexts when recording execution of public downloads (#47201) --- src/metabase/api/public.clj | 11 ++++++- src/metabase/lib/schema/info.cljc | 3 ++ .../middleware/process_userland_query.clj | 4 +-- test/metabase/api/public_test.clj | 30 +++++++++++++++++++ 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/metabase/api/public.clj b/src/metabase/api/public.clj index 4e1bea08214..d97860262f1 100644 --- a/src/metabase/api/public.clj +++ b/src/metabase/api/public.clj @@ -15,6 +15,7 @@ [metabase.db.query :as mdb.query] [metabase.events :as events] [metabase.lib.schema.id :as lib.schema.id] + [metabase.lib.schema.info :as lib.schema.info] [metabase.lib.util.match :as lib.util.match] [metabase.models.action :as action] [metabase.models.card :as card :refer [Card]] @@ -138,6 +139,14 @@ (mw.session/as-admin (qp (update query :info merge info) rff)))))) +(mu/defn- export-format->context :- ::lib.schema.info/context + [export-format] + (case export-format + "csv" :public-csv-download + "xlsx" :public-xlsx-download + "json" :public-json-download + :public-question)) + (mu/defn process-query-for-card-with-id "Run the query belonging to Card with `card-id` with `parameters` and other query options (e.g. `:constraints`). Returns a `StreamingResponse` object that should be returned as the result of an API endpoint." @@ -155,7 +164,7 @@ (mw.session/as-admin (m/mapply qp.card/process-query-for-card card-id export-format :parameters parameters - :context :public-question + :context (export-format->context export-format) :qp qp :make-run process-query-for-card-with-id-run-fn options))) diff --git a/src/metabase/lib/schema/info.cljc b/src/metabase/lib/schema/info.cljc index 3665118c047..0d9bd7bedf4 100644 --- a/src/metabase/lib/schema/info.cljc +++ b/src/metabase/lib/schema/info.cljc @@ -25,6 +25,9 @@ :json-download :public-dashboard :public-question + :public-csv-download + :public-xlsx-download + :public-json-download :embedded-dashboard :embedded-question :embedded-csv-download diff --git a/src/metabase/query_processor/middleware/process_userland_query.clj b/src/metabase/query_processor/middleware/process_userland_query.clj index afb96ec491e..03d3f5b7b09 100644 --- a/src/metabase/query_processor/middleware/process_userland_query.clj +++ b/src/metabase/query_processor/middleware/process_userland_query.clj @@ -64,9 +64,7 @@ (defn- save-execution-metadata! "Save a `QueryExecution` row containing `execution-info`. Done asynchronously when a query is finished." [execution-info field-usages] - (let [execution-info' (sdk/include-analytics execution-info) - ;; `sdk/assoc-analytics` reads values from dynamic vars, so we need to set them here, on the same thread: - ] + (let [execution-info' (sdk/include-analytics execution-info)] (qp.util/with-execute-async ;; 1. Asynchronously save QueryExecution, update query average execution time etc. using the Agent/pooledExecutor ;; pool, which is a fixed pool of size `nthreads + 2`. This way we don't spin up a ton of threads doing unimportant diff --git a/test/metabase/api/public_test.clj b/test/metabase/api/public_test.clj index 2983cab4e13..ee0324f17f5 100644 --- a/test/metabase/api/public_test.clj +++ b/test/metabase/api/public_test.clj @@ -21,6 +21,7 @@ [metabase.models.params.chain-filter-test :as chain-filter-test] [metabase.models.permissions :as perms] [metabase.models.permissions-group :as perms-group] + [metabase.query-processor.middleware.process-userland-query-test :as process-userland-query-test] [metabase.test :as mt] [metabase.util :as u] [throttle.core :as throttle] @@ -507,6 +508,35 @@ keys set)))))) +(deftest query-execution-context test + (testing "Make sure we record the correct context for each export format (#45147)" + (mt/with-temporary-setting-values [enable-public-sharing true] + (let [query (merge (mt/mbql-query venues) + ;; Add these constraints for the API query so that the query hash matches in `with-query-execution!` + {:constraints {:max-results 10000, :max-results-bare-rows 2000}})] + (with-temp-public-card [{uuid :public_uuid} {:dataset_query query}] + (testing "Default :api response format" + (process-userland-query-test/with-query-execution! [qe query] + (client/client :get 202 (str "public/card/" uuid "/query")) + (is (= :public-question (:context (qe)))))))) + + (let [query (merge (mt/mbql-query venues))] + (with-temp-public-card [{uuid :public_uuid} {:dataset_query query}] + (testing ":json download response format" + (process-userland-query-test/with-query-execution! [qe query] + (client/client :get 200 (str "public/card/" uuid "/query/json")) + (is (= :public-json-download (:context (qe)))))) + + (testing ":xlsx download response format" + (process-userland-query-test/with-query-execution! [qe query] + (client/client :get 200 (str "public/card/" uuid "/query/xlsx")) + (is (= :public-xlsx-download (:context (qe)))))) + + (testing ":csv download response format" + (process-userland-query-test/with-query-execution! [qe query] + (client/client :get 200 (str "public/card/" uuid "/query/csv"), :format :csv) + (is (= :public-csv-download (:context (qe))))))))))) + ;;; ---------------------------------------- GET /api/public/dashboard/:uuid ----------------------------------------- (deftest get-public-dashboard-errors-test -- GitLab