-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Reporting] Separate internal and public API endpoints in Reporting #162288
Changes from all commits
51b049a
8a859d8
27ae018
f09c9b7
d59f0d8
d1710b5
01c6b5d
8ef4e04
a6950af
9379f44
0594845
264b644
99ba556
6d46174
fc30dee
664aaa4
167bc55
61c611e
40f4721
7d22b64
457b9f9
7539cef
24ffa4d
64d4352
8c9dda0
543af19
8ce821d
1b146db
5ccabec
a4dd40b
e1c2d87
0eb8a75
1438f06
d361170
73500d4
4688106
7e6a4d5
a98eb76
3f16fd7
4273309
55c1751
80ae40a
8c0371b
d0794d1
848417d
5cfda74
540a74b
53ac996
ceff224
4031a4d
5122ed6
760bceb
0f68a4c
5afefd4
0400bc7
9bbc650
44c9f03
248219d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
const prefixInternalPath = '/internal/reporting'; | ||
export const INTERNAL_ROUTES = { | ||
MIGRATE: { | ||
MIGRATE_ILM_POLICY: prefixInternalPath + '/deprecations/migrate_ilm_policy', | ||
GET_ILM_POLICY_STATUS: prefixInternalPath + '/ilm_policy_status', | ||
}, | ||
DIAGNOSE: { | ||
BROWSER: prefixInternalPath + '/diagnose/browser', | ||
SCREENSHOT: prefixInternalPath + '/diagnose/screenshot', | ||
}, | ||
JOBS: { | ||
COUNT: prefixInternalPath + '/jobs/count', | ||
LIST: prefixInternalPath + '/jobs/list', | ||
INFO_PREFIX: prefixInternalPath + '/jobs/info', // docId is added to the final path | ||
DELETE_PREFIX: prefixInternalPath + '/jobs/delete', // docId is added to the final path | ||
DOWNLOAD_PREFIX: prefixInternalPath + '/jobs/download', // docId is added to the final path | ||
}, | ||
DOWNLOAD_CSV: prefixInternalPath + '/generate/immediate/csv_searchsource', | ||
GENERATE_PREFIX: prefixInternalPath + '/generate', // exportTypeId is added to the final path | ||
}; | ||
|
||
const prefixPublicPath = '/api/reporting'; | ||
export const PUBLIC_ROUTES = { | ||
/** | ||
* Public endpoint for POST URL strings and automated report generation | ||
* exportTypeId is added to the final path | ||
*/ | ||
GENERATE_PREFIX: prefixPublicPath + `/generate`, | ||
JOBS: { | ||
/** | ||
* Public endpoint used by Watcher and automated report downloads | ||
* jobId is added to the final path | ||
*/ | ||
DOWNLOAD_PREFIX: prefixPublicPath + `/jobs/download`, | ||
/** | ||
* Public endpoint potentially used to delete a report after download in automation | ||
* jobId is added to the final path | ||
*/ | ||
DELETE_PREFIX: prefixPublicPath + `/jobs/delete`, | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,20 +4,17 @@ | |
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
import type { HttpFetchQuery } from '@kbn/core/public'; | ||
import { HttpSetup, IUiSettingsClient } from '@kbn/core/public'; | ||
import { i18n } from '@kbn/i18n'; | ||
import rison from '@kbn/rison'; | ||
import moment from 'moment'; | ||
import { stringify } from 'query-string'; | ||
import rison from '@kbn/rison'; | ||
import type { HttpFetchQuery } from '@kbn/core/public'; | ||
import { HttpSetup, IUiSettingsClient } from '@kbn/core/public'; | ||
import { buildKibanaPath } from '../../../common/build_kibana_path'; | ||
import { | ||
API_BASE_GENERATE, | ||
API_BASE_URL, | ||
API_GENERATE_IMMEDIATE, | ||
API_LIST_URL, | ||
API_MIGRATE_ILM_POLICY_URL, | ||
getRedirectAppPath, | ||
INTERNAL_ROUTES, | ||
PUBLIC_ROUTES, | ||
REPORTING_MANAGEMENT_HOME, | ||
} from '../../../common/constants'; | ||
import { | ||
|
@@ -46,7 +43,7 @@ export interface DiagnoseResponse { | |
interface IReportingAPI { | ||
// Helpers | ||
getReportURL(jobId: string): string; | ||
getReportingJobPath<T>(exportType: string, jobParams: BaseParams & T): string; // Return a URL to queue a job, with the job params encoded in the query string of the URL. Used for copying POST URL | ||
getReportingPublicJobPath<T>(exportType: string, jobParams: BaseParams & T): string; // Return a URL to queue a job, with the job params encoded in the query string of the URL. Used for copying POST URL | ||
createReportingJob<T>(exportType: string, jobParams: BaseParams & T): Promise<Job>; // Sends a request to queue a job, with the job params in the POST body | ||
getServerBasePath(): string; // Provides the raw server basePath to allow it to be stripped out from relativeUrls in job params | ||
|
||
|
@@ -96,9 +93,13 @@ export class ReportingAPIClient implements IReportingAPI { | |
return href; | ||
} | ||
|
||
/** | ||
* Get the internal URL | ||
*/ | ||
public getReportURL(jobId: string) { | ||
const apiBaseUrl = this.http.basePath.prepend(API_LIST_URL); | ||
const downloadLink = `${apiBaseUrl}/download/${jobId}`; | ||
const downloadLink = this.http.basePath.prepend( | ||
`${INTERNAL_ROUTES.JOBS.DOWNLOAD_PREFIX}/${jobId}` | ||
); | ||
|
||
return downloadLink; | ||
} | ||
|
@@ -110,9 +111,7 @@ export class ReportingAPIClient implements IReportingAPI { | |
} | ||
|
||
public async deleteReport(jobId: string) { | ||
return await this.http.delete<void>(`${API_LIST_URL}/delete/${jobId}`, { | ||
asSystemRequest: true, | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. deleting a report is manually done by the user: not a system request |
||
return await this.http.delete<void>(`${INTERNAL_ROUTES.JOBS.DELETE_PREFIX}/${jobId}`); | ||
} | ||
|
||
public async list(page = 0, jobIds: string[] = []) { | ||
|
@@ -122,7 +121,7 @@ export class ReportingAPIClient implements IReportingAPI { | |
query.ids = jobIds.slice(0, 10).join(','); | ||
} | ||
|
||
const jobQueueEntries: ReportApiJSON[] = await this.http.get(`${API_LIST_URL}/list`, { | ||
const jobQueueEntries: ReportApiJSON[] = await this.http.get(INTERNAL_ROUTES.JOBS.LIST, { | ||
query, | ||
asSystemRequest: true, | ||
}); | ||
|
@@ -131,7 +130,7 @@ export class ReportingAPIClient implements IReportingAPI { | |
} | ||
|
||
public async total() { | ||
return await this.http.get<number>(`${API_LIST_URL}/count`, { | ||
return await this.http.get<number>(INTERNAL_ROUTES.JOBS.COUNT, { | ||
asSystemRequest: true, | ||
}); | ||
} | ||
|
@@ -151,47 +150,50 @@ export class ReportingAPIClient implements IReportingAPI { | |
} | ||
|
||
public async getInfo(jobId: string) { | ||
const report: ReportApiJSON = await this.http.get(`${API_LIST_URL}/info/${jobId}`, { | ||
asSystemRequest: true, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. getting report info is manually done by the user: not a system request |
||
}); | ||
const report: ReportApiJSON = await this.http.get( | ||
`${INTERNAL_ROUTES.JOBS.INFO_PREFIX}/${jobId}` | ||
); | ||
return new Job(report); | ||
} | ||
|
||
public async findForJobIds(jobIds: JobId[]) { | ||
const reports: ReportApiJSON[] = await this.http.fetch(`${API_LIST_URL}/list`, { | ||
const reports: ReportApiJSON[] = await this.http.fetch(INTERNAL_ROUTES.JOBS.LIST, { | ||
query: { page: 0, ids: jobIds.join(',') }, | ||
method: 'GET', | ||
}); | ||
return reports.map((report) => new Job(report)); | ||
} | ||
|
||
public getReportingJobPath(exportType: string, jobParams: BaseParams) { | ||
/** | ||
* Returns a string for the public API endpoint used to automate the generation of reports | ||
* This string must be shown when the user selects the option to view/copy the POST URL | ||
*/ | ||
public getReportingPublicJobPath(exportType: string, jobParams: BaseParams) { | ||
const params = stringify({ | ||
jobParams: rison.encode(jobParams), | ||
}); | ||
return `${this.http.basePath.prepend(API_BASE_GENERATE)}/${exportType}?${params}`; | ||
return `${this.http.basePath.prepend(PUBLIC_ROUTES.GENERATE_PREFIX)}/${exportType}?${params}`; | ||
} | ||
|
||
/** | ||
* Calls the internal API to generate a report job on-demand | ||
*/ | ||
public async createReportingJob(exportType: string, jobParams: BaseParams) { | ||
const jobParamsRison = rison.encode(jobParams); | ||
const resp: { job: ReportApiJSON } = await this.http.post( | ||
`${API_BASE_GENERATE}/${exportType}`, | ||
`${INTERNAL_ROUTES.GENERATE_PREFIX}/${exportType}`, | ||
{ | ||
method: 'POST', | ||
body: JSON.stringify({ | ||
jobParams: jobParamsRison, | ||
}), | ||
body: JSON.stringify({ jobParams: jobParamsRison }), | ||
} | ||
); | ||
|
||
add(resp.job.id); | ||
|
||
return new Job(resp.job); | ||
} | ||
|
||
public async createImmediateReport(baseParams: BaseParams) { | ||
const { objectType: _objectType, ...params } = baseParams; // objectType is not needed for immediate download api | ||
return this.http.post(`${API_GENERATE_IMMEDIATE}`, { | ||
return this.http.post(INTERNAL_ROUTES.DOWNLOAD_CSV, { | ||
asResponse: true, | ||
body: JSON.stringify(params), | ||
}); | ||
|
@@ -217,23 +219,19 @@ export class ReportingAPIClient implements IReportingAPI { | |
this.http.basePath.prepend(REPORTING_MANAGEMENT_HOME); | ||
|
||
public getDownloadLink: DownloadReportFn = (jobId: JobId) => | ||
this.http.basePath.prepend(`${API_LIST_URL}/download/${jobId}`); | ||
this.http.basePath.prepend(`${INTERNAL_ROUTES.JOBS.DOWNLOAD_PREFIX}/${jobId}`); | ||
|
||
public getServerBasePath = () => this.http.basePath.serverBasePath; | ||
|
||
public verifyBrowser() { | ||
return this.http.post<DiagnoseResponse>(`${API_BASE_URL}/diagnose/browser`, { | ||
asSystemRequest: true, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. using the diagnostic tool is manually done by the user: not a system request |
||
}); | ||
return this.http.post<DiagnoseResponse>(INTERNAL_ROUTES.DIAGNOSE.BROWSER); | ||
} | ||
|
||
public verifyScreenCapture() { | ||
return this.http.post<DiagnoseResponse>(`${API_BASE_URL}/diagnose/screenshot`, { | ||
asSystemRequest: true, | ||
}); | ||
return this.http.post<DiagnoseResponse>(INTERNAL_ROUTES.DIAGNOSE.SCREENSHOT); | ||
} | ||
|
||
public migrateReportingIndicesIlmPolicy() { | ||
return this.http.put(`${API_MIGRATE_ILM_POLICY_URL}`); | ||
return this.http.put(INTERNAL_ROUTES.MIGRATE.MIGRATE_ILM_POLICY); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,11 +84,11 @@ class ReportingPanelContentUi extends Component<Props, State> { | |
} | ||
|
||
private getAbsoluteReportGenerationUrl = (props: Props) => { | ||
const relativePath = this.props.apiClient.getReportingJobPath( | ||
const relativePath = this.props.apiClient.getReportingPublicJobPath( | ||
props.reportType, | ||
this.props.apiClient.getDecoratedJobParams(this.props.getJobParams(true)) | ||
); | ||
return url.resolve(window.location.href, relativePath); // FIXME: '(from: string, to: string): string' is deprecated | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't figure out why my editor says this line uses a deprecated signature, so the comment isn't valid There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice I'm also not seeing any issues in my editor 👍🏻 |
||
return url.resolve(window.location.href, relativePath); | ||
}; | ||
|
||
public componentDidUpdate(_prevProps: Props, prevState: State) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the options object was removed from the API calls for many of these, since they mistakenly were used to send the
asSystemRequest
field