Skip to content

Commit

Permalink
[Reporting] Fix reporting for non-default spaces (elastic#62226)
Browse files Browse the repository at this point in the history
* [Reporting] Fix URLs in job params when basePath includes namespace suffix

* canvas fix

* cleanup

* update snapshots in tests

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
tsullivan and elasticmachine committed Apr 4, 2020
1 parent e4bdc69 commit a3d41cc
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const WorkpadExport = compose<ComponentProps, {}>(
({ workpad, pageCount, kibana }: Props & WithKibanaProps): ComponentProps => ({
getExportUrl: type => {
if (type === 'pdf') {
const pdfUrl = getPdfUrl(workpad, { pageCount }, kibana.services.http.basePath.prepend);
const pdfUrl = getPdfUrl(workpad, { pageCount }, kibana.services.http.basePath);
return getAbsoluteUrl(pdfUrl);
}

Expand All @@ -78,7 +78,7 @@ export const WorkpadExport = compose<ComponentProps, {}>(
onExport: type => {
switch (type) {
case 'pdf':
return createPdf(workpad, { pageCount }, kibana.services.http.basePath.prepend)
return createPdf(workpad, { pageCount }, kibana.services.http.basePath)
.then(({ data }: { data: { job: { id: string } } }) => {
notify.info(strings.getExportPDFMessage(), {
title: strings.getExportPDFTitle(workpad.name),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,34 @@ jest.mock('../../../../common/lib/fetch');
import { getPdfUrl, createPdf } from './utils';
import { workpads } from '../../../../__tests__/fixtures/workpads';
import { fetch } from '../../../../common/lib/fetch';
import { IBasePath } from 'kibana/public';

const addBasePath = jest.fn().mockImplementation(s => `basepath/${s}`);
const basePath = ({
prepend: jest.fn().mockImplementation(s => `basepath/s/spacey/${s}`),
get: () => 'basepath/s/spacey',
serverBasePath: `basepath`,
} as unknown) as IBasePath;
const workpad = workpads[0];

test('getPdfUrl returns the correct url', () => {
const url = getPdfUrl(workpad, { pageCount: 2 }, addBasePath);
const url = getPdfUrl(workpad, { pageCount: 2 }, basePath);

expect(url).toMatchInlineSnapshot(
`"basepath//api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FPhoenix,layout:(dimensions:(height:0,width:0),id:preserve_layout),objectType:'canvas%20workpad',relativeUrls:!(%2Fapp%2Fcanvas%23%2Fexport%2Fworkpad%2Fpdf%2Fbase-workpad%2Fpage%2F1,%2Fapp%2Fcanvas%23%2Fexport%2Fworkpad%2Fpdf%2Fbase-workpad%2Fpage%2F2),title:'base%20workpad')"`
`"basepath/s/spacey//api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FPhoenix,layout:(dimensions:(height:0,width:0),id:preserve_layout),objectType:'canvas%20workpad',relativeUrls:!(%2Fs%2Fspacey%2Fapp%2Fcanvas%23%2Fexport%2Fworkpad%2Fpdf%2Fbase-workpad%2Fpage%2F1,%2Fs%2Fspacey%2Fapp%2Fcanvas%23%2Fexport%2Fworkpad%2Fpdf%2Fbase-workpad%2Fpage%2F2),title:'base%20workpad')"`
);
});

test('createPdf posts to create the pdf', () => {
createPdf(workpad, { pageCount: 2 }, addBasePath);
createPdf(workpad, { pageCount: 2 }, basePath);

expect(fetch.post).toBeCalled();

const args = (fetch.post as jest.MockedFunction<typeof fetch.post>).mock.calls[0];

expect(args[0]).toMatchInlineSnapshot(`"basepath//api/reporting/generate/printablePdf"`);
expect(args[0]).toMatchInlineSnapshot(`"basepath/s/spacey//api/reporting/generate/printablePdf"`);
expect(args[1]).toMatchInlineSnapshot(`
Object {
"jobParams": "(browserTimezone:America/Phoenix,layout:(dimensions:(height:0,width:0),id:preserve_layout),objectType:'canvas workpad',relativeUrls:!(/app/canvas#/export/workpad/pdf/base-workpad/page/1,/app/canvas#/export/workpad/pdf/base-workpad/page/2),title:'base workpad')",
"jobParams": "(browserTimezone:America/Phoenix,layout:(dimensions:(height:0,width:0),id:preserve_layout),objectType:'canvas workpad',relativeUrls:!(/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/1,/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/2),title:'base workpad')",
}
`);
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import rison from 'rison-node';
// @ts-ignore Untyped local.
import { IBasePath } from 'kibana/public';
import { fetch } from '../../../../common/lib/fetch';
import { CanvasWorkpad } from '../../../../types';
import { url } from '../../../../../../../../src/plugins/kibana_utils/public';
Expand All @@ -17,9 +18,7 @@ interface PageCount {
pageCount: number;
}

type AddBasePath = (url: string) => string;

type Arguments = [CanvasWorkpad, PageCount, AddBasePath];
type Arguments = [CanvasWorkpad, PageCount, IBasePath];

interface PdfUrlData {
createPdfUri: string;
Expand All @@ -29,10 +28,11 @@ interface PdfUrlData {
function getPdfUrlParts(
{ id, name: title, width, height }: CanvasWorkpad,
{ pageCount }: PageCount,
addBasePath: (path: string) => string
basePath: IBasePath
): PdfUrlData {
const reportingEntry = addBasePath('/api/reporting/generate');
const canvasEntry = '/app/canvas#';
const reportingEntry = basePath.prepend('/api/reporting/generate');
const urlPrefix = basePath.get().replace(basePath.serverBasePath, ''); // for Spaces prefix, which is included in basePath.get()
const canvasEntry = `${urlPrefix}/app/canvas#`;

// The viewport in Reporting by specifying the dimensions. In order for things to work,
// we need a viewport that will include all of the pages in the workpad. The viewport
Expand Down
21 changes: 12 additions & 9 deletions x-pack/plugins/reporting/public/lib/reporting_api_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ import rison from 'rison-node';

import { HttpSetup } from 'src/core/public';
import { add } from './job_completion_notifications';
import {
API_LIST_URL,
API_BASE_URL,
API_BASE_GENERATE,
REPORTING_MANAGEMENT_HOME,
} from '../../constants';
import { API_LIST_URL, API_BASE_GENERATE, REPORTING_MANAGEMENT_HOME } from '../../constants';
import { JobId, SourceJob } from '../..';

export interface JobQueueEntry {
Expand Down Expand Up @@ -129,12 +124,17 @@ export class ReportingAPIClient {
});
};

/*
* Return a URL to queue a job, with the job params encoded in the query string of the URL. Used for copying POST URL
*/
public getReportingJobPath = (exportType: string, jobParams: JobParams) => {
const params = stringify({ jobParams: rison.encode(jobParams) });

return `${this.http.basePath.prepend(API_BASE_URL)}/${exportType}?${params}`;
return `${this.http.basePath.prepend(API_BASE_GENERATE)}/${exportType}?${params}`;
};

/*
* Sends a request to queue a job, with the job params in the POST body
*/
public createReportingJob = async (exportType: string, jobParams: any) => {
const jobParamsRison = rison.encode(jobParams);
const resp = await this.http.post(`${API_BASE_GENERATE}/${exportType}`, {
Expand All @@ -154,5 +154,8 @@ export class ReportingAPIClient {
public getDownloadLink = (jobId: JobId) =>
this.http.basePath.prepend(`${API_LIST_URL}/download/${jobId}`);

public getBasePath = () => this.http.basePath.get();
/*
* provides the raw server basePath to allow it to be stripped out from relativeUrls in job params
*/
public getServerBasePath = () => this.http.basePath.serverBasePath;
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ export const reportingPDFPNGProvider = ({
}

const getReportingJobParams = () => {
// Relative URL must have URL prefix (Spaces ID prefix), but not server basePath
// Replace hashes with original RISON values.
const relativeUrl = shareableUrl.replace(
window.location.origin + apiClient.getBasePath(),
window.location.origin + apiClient.getServerBasePath(),
''
);

Expand All @@ -80,7 +81,7 @@ export const reportingPDFPNGProvider = ({
const getPngJobParams = () => {
// Replace hashes with original RISON values.
const relativeUrl = shareableUrl.replace(
window.location.origin + apiClient.getBasePath(),
window.location.origin + apiClient.getServerBasePath(),
''
);

Expand Down

0 comments on commit a3d41cc

Please sign in to comment.