[ 
https://issues.apache.org/jira/browse/SPARK-60204?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Sowmya Sundar updated SPARK-60204:
----------------------------------
    Description: 
On the SQL execution page, "Download → SVG" produces a `{{{}plan.svg`{}}} in 
which every node is a solid black box (Attached file) when the Spark UI or 
History Server is served under a path prefix ({{{}spark.ui.proxyBase{}}} / 
{{{}X-Forwarded-Context{}}}, e.g. behind a reverse proxy or a hosted History 
Server such as Amazon EMR's). The on-screen DAG and the DOT/TXT downloads are 
unaffected, and the same download is correctly coloured on a UI served at the 
root (e.g. {{{}localhost:4040{}}}). It affects every plan, not just a 
particular query type.

Reproduce:
 # On any Spark 4.1 cluster, open the Spark UI or History Server through its 
proxied URL (for example an Amazon EMR cluster's History Server from the EMR 
console, served under {{{}/shs/{}}}), and go to the SQL execution page of any 
query.
 # Under the DAG, choose SVG and click Download.
 # Open the downloaded {{{}plan.svg{}}}: every node is a solid black box.
 # For contrast, open the same UI directly on its own port (or a local 
{{spark-shell}} at {{{}localhost:4040{}}}) and repeat: the SVG is correctly 
coloured.

Root cause:

the download handler, added by SPARK-51629 (4.1.0), inlines 
{{spark-sql-viz.css}} into the SVG so the file is self-contained, but fetches 
it from an absolute root path:
 {{{}{code:js}{}}}// 
sql/core/src/main/resources/org/apache/spark/sql/execution/ui/static/spark-sql-viz.js
css = await fetch("/static/sql/spark-sql-viz.css").then((resp) => 
resp.text());{{{}{code}{}}}
Under a prefix the request goes to the proxy host's root and is not routed to 
Spark (on the proxied page {{GET /static/sql/spark-sql-viz.css}} returns the 
proxy host's 404 page, while {{GET <prefix>/static/sql/spark-sql-viz.css}} 
returns the stylesheet). {{fetch}} does not reject on a 404, so the proxy's 
error page is inlined as the {{<style>}} content; with no {{fill}} rules the 
nodes render with SVG's default fill, black. Every other asset reference in the 
same file goes through {{{}uiRoot{}}}.

Fix: prefix the fetch with {{{}uiRoot{}}}, which is already in scope in this 
file:
css = await fetch(uiRoot + "/static/sql/spark-sql-viz.css").then((resp) => 
resp.text());
Observed on Apache Spark 4.1.1 (Amazon EMR {{{}emr-spark-8.1.0{}}}, both the 
on-cluster History Server and the persistent application UI, under 
{{{}/shs/{}}}); the code is unchanged on {{branch-4.1}} and {{{}master{}}}. Not 
applicable to 3.5.x / 4.0.x (no download button).

  was:
On the SQL execution page, "Download → SVG" produces a `{{{}plan.svg`{}}} in 
which every node is a solid black box (Attached file) when the Spark UI or 
History Server is served under a path prefix ({{{}spark.ui.proxyBase{}}} / 
{{{}X-Forwarded-Context{}}}, e.g. behind a reverse proxy or a hosted History 
Server such as Amazon EMR's). The on-screen DAG and the DOT/TXT downloads are 
unaffected, and the same download is correctly coloured on a UI served at the 
root (e.g. {{{}localhost:4040{}}}). It affects every plan, not just a 
particular query type.

Reproduce:
 # On any Spark 4.1 cluster, open the Spark UI or History Server through its 
proxied URL (for example an Amazon EMR cluster's History Server from the EMR 
console, served under {{{}/shs/{}}}), and go to the SQL execution page of any 
query.
 # Under the DAG, choose SVG and click Download.
 # Open the downloaded {{{}plan.svg{}}}: every node is a solid black box.
 # For contrast, open the same UI directly on its own port (or a local 
{{spark-shell}} at {{{}localhost:4040{}}}) and repeat: the SVG is correctly 
coloured.

Root cause:

the download handler, added by SPARK-51629 (4.1.0), inlines 
{{spark-sql-viz.css}} into the SVG so the file is self-contained, but fetches 
it from an absolute root path:
 
// 
sql/core/src/main/resources/org/apache/spark/sql/execution/ui/static/spark-sql-viz.js
css = await fetch("/static/sql/spark-sql-viz.css").then((resp) => resp.text());
Under a prefix the request goes to the proxy host's root and is not routed to 
Spark (on the proxied page {{GET /static/sql/spark-sql-viz.css}} returns the 
proxy host's 404 page, while {{GET <prefix>/static/sql/spark-sql-viz.css}} 
returns the stylesheet). {{fetch}} does not reject on a 404, so the proxy's 
error page is inlined as the {{<style>}} content; with no {{fill}} rules the 
nodes render with SVG's default fill, black. Every other asset reference in the 
same file goes through {{{}uiRoot{}}}.

Fix: prefix the fetch with {{{}uiRoot{}}}, which is already in scope in this 
file:
css = await fetch(uiRoot + "/static/sql/spark-sql-viz.css").then((resp) => 
resp.text());
Observed on Apache Spark 4.1.1 (Amazon EMR {{{}emr-spark-8.1.0{}}}, both the 
on-cluster History Server and the persistent application UI, under 
{{{}/shs/{}}}); the code is unchanged on {{branch-4.1}} and {{{}master{}}}. Not 
applicable to 3.5.x / 4.0.x (no download button).


> SQL execution page "Download SVG" produces an unstyled (black-box) plan
> -----------------------------------------------------------------------
>
>                 Key: SPARK-60204
>                 URL: https://issues.apache.org/jira/browse/SPARK-60204
>             Project: Spark
>          Issue Type: Bug
>          Components: Web UI
>    Affects Versions: 4.1.0, 4.1.1
>            Reporter: Sowmya Sundar
>            Priority: Major
>         Attachments: plan (2).svg
>
>
> On the SQL execution page, "Download → SVG" produces a `{{{}plan.svg`{}}} in 
> which every node is a solid black box (Attached file) when the Spark UI or 
> History Server is served under a path prefix ({{{}spark.ui.proxyBase{}}} / 
> {{{}X-Forwarded-Context{}}}, e.g. behind a reverse proxy or a hosted History 
> Server such as Amazon EMR's). The on-screen DAG and the DOT/TXT downloads are 
> unaffected, and the same download is correctly coloured on a UI served at the 
> root (e.g. {{{}localhost:4040{}}}). It affects every plan, not just a 
> particular query type.
> Reproduce:
>  # On any Spark 4.1 cluster, open the Spark UI or History Server through its 
> proxied URL (for example an Amazon EMR cluster's History Server from the EMR 
> console, served under {{{}/shs/{}}}), and go to the SQL execution page of any 
> query.
>  # Under the DAG, choose SVG and click Download.
>  # Open the downloaded {{{}plan.svg{}}}: every node is a solid black box.
>  # For contrast, open the same UI directly on its own port (or a local 
> {{spark-shell}} at {{{}localhost:4040{}}}) and repeat: the SVG is correctly 
> coloured.
> Root cause:
> the download handler, added by SPARK-51629 (4.1.0), inlines 
> {{spark-sql-viz.css}} into the SVG so the file is self-contained, but fetches 
> it from an absolute root path:
>  {{{}{code:js}{}}}// 
> sql/core/src/main/resources/org/apache/spark/sql/execution/ui/static/spark-sql-viz.js
> css = await fetch("/static/sql/spark-sql-viz.css").then((resp) => 
> resp.text());{{{}{code}{}}}
> Under a prefix the request goes to the proxy host's root and is not routed to 
> Spark (on the proxied page {{GET /static/sql/spark-sql-viz.css}} returns the 
> proxy host's 404 page, while {{GET <prefix>/static/sql/spark-sql-viz.css}} 
> returns the stylesheet). {{fetch}} does not reject on a 404, so the proxy's 
> error page is inlined as the {{<style>}} content; with no {{fill}} rules the 
> nodes render with SVG's default fill, black. Every other asset reference in 
> the same file goes through {{{}uiRoot{}}}.
> Fix: prefix the fetch with {{{}uiRoot{}}}, which is already in scope in this 
> file:
> css = await fetch(uiRoot + "/static/sql/spark-sql-viz.css").then((resp) => 
> resp.text());
> Observed on Apache Spark 4.1.1 (Amazon EMR {{{}emr-spark-8.1.0{}}}, both the 
> on-cluster History Server and the persistent application UI, under 
> {{{}/shs/{}}}); the code is unchanged on {{branch-4.1}} and {{{}master{}}}. 
> Not applicable to 3.5.x / 4.0.x (no download button).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to