Skip to content

Commit efb718b

Browse files
rupal-bqjoshuali925opensearch-trigger-bot[bot]opensearch-ci-bot
authored
[Backport 1.0.0] Use front-end report generation instead of chromium (#607)
* Use front-end report generation instead of chromium (#586) * Increment version to 2.4.1-SNAPSHOT (#540) Signed-off-by: opensearch-ci-bot <[email protected]> Signed-off-by: opensearch-ci-bot <[email protected]> Co-authored-by: opensearch-ci-bot <[email protected]> * --wip-- Signed-off-by: Joshua Li <[email protected]> * Add initial implementation of client reporting generation Signed-off-by: Joshua Li <[email protected]> * Fix url with basepath Signed-off-by: Joshua Li <[email protected]> * Update header footer height Signed-off-by: Joshua Li <[email protected]> * Update dialog text to not close dialog Signed-off-by: Joshua Li <[email protected]> * Remove console.log Signed-off-by: Joshua Li <[email protected]> * Remove unused components Signed-off-by: Joshua Li <[email protected]> * Remove chromium references Signed-off-by: Joshua Li <[email protected]> * Add report generation error handling Signed-off-by: Joshua Li <[email protected]> * Minor refactors Signed-off-by: Joshua Li <[email protected]> * Add postinstall patch to support safari for html2canvas Signed-off-by: Joshua Li <[email protected]> * Add dompurify Signed-off-by: Joshua Li <[email protected]> * Fix build error Signed-off-by: Joshua Li <[email protected]> * Remove chromium from CI Signed-off-by: Joshua Li <[email protected]> * Update CI artifact name Signed-off-by: Joshua Li <[email protected]> Signed-off-by: opensearch-ci-bot <[email protected]> Signed-off-by: Joshua Li <[email protected]> Co-authored-by: opensearch-trigger-bot[bot] <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com> Co-authored-by: opensearch-ci-bot <[email protected]> * Fix osd bootstrap error Signed-off-by: Rupal Mahajan <[email protected]> * Fix build Signed-off-by: Rupal Mahajan <[email protected]> Signed-off-by: opensearch-ci-bot <[email protected]> Signed-off-by: Joshua Li <[email protected]> Signed-off-by: Rupal Mahajan <[email protected]> Co-authored-by: Joshua Li <[email protected]> Co-authored-by: opensearch-trigger-bot[bot] <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com> Co-authored-by: opensearch-ci-bot <[email protected]>
1 parent d2b2cb8 commit efb718b

28 files changed

+675
-1200
lines changed

.github/workflows/dashboards-reports-test-and-build-workflow.yml

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,6 @@ jobs:
3030
- name: Move Dashboards Reports to Plugins Dir
3131
run: mv dashboards-reports ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}
3232

33-
- name: Add Chromium Binary to Reporting for Testing
34-
run: |
35-
sudo apt install -y libnss3-dev fonts-liberation libfontconfig1
36-
cd ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}
37-
wget https://github.com/opendistro-for-elasticsearch/kibana-reports/releases/download/chromium-1.12.0.0/chromium-linux-x64.zip
38-
unzip chromium-linux-x64.zip
39-
rm chromium-linux-x64.zip
40-
4133
- name: OpenSearch Dashboards Plugin Bootstrap
4234
uses: nick-invision/retry@v1
4335
with:
@@ -63,48 +55,10 @@ jobs:
6355
run: |
6456
cd ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}
6557
yarn build
66-
67-
cd build
68-
mkdir -p ./{linux-x64,linux-arm64,windows-x64}/opensearch-dashboards/${{ env.PLUGIN_NAME }}
69-
cp ./${{ env.PLUGIN_NAME }}-*.zip ./linux-x64/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-linux-x64.zip
70-
cp ./${{ env.PLUGIN_NAME }}-*.zip ./linux-arm64/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-linux-arm64.zip
71-
mv ./${{ env.PLUGIN_NAME }}-*.zip ./windows-x64/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-windows-x64.zip
72-
73-
cd linux-x64
74-
wget https://github.com/opensearch-project/dashboards-reports/releases/download/chromium-1.12.0.0/chromium-linux-x64.zip
75-
unzip chromium-linux-x64.zip -d ./opensearch-dashboards/${{ env.PLUGIN_NAME }}
76-
zip -ur ./${{ env.ARTIFACT_NAME }}-*.zip ./opensearch-dashboards
77-
mv ./${{ env.ARTIFACT_NAME }}-*.zip ..
78-
cd ..
79-
80-
cd linux-arm64
81-
wget https://github.com/opensearch-project/dashboards-reports/releases/download/chromium-1.12.0.0/chromium-linux-arm64.zip
82-
unzip chromium-linux-arm64.zip -d ./opensearch-dashboards/${{ env.PLUGIN_NAME }}
83-
zip -ur ./${{ env.ARTIFACT_NAME }}-*.zip ./opensearch-dashboards
84-
mv ./${{ env.ARTIFACT_NAME }}-*.zip ..
85-
cd ..
86-
87-
cd windows-x64
88-
wget https://github.com/opensearch-project/dashboards-reports/releases/download/chromium-1.12.0.0/chromium-windows-x64.zip
89-
unzip chromium-windows-x64.zip -d ./opensearch-dashboards/${{ env.PLUGIN_NAME }}
90-
zip -ur ./${{ env.ARTIFACT_NAME }}-*.zip ./opensearch-dashboards
91-
mv ./${{ env.ARTIFACT_NAME }}-*.zip ..
92-
cd ..
58+
mv ./build/*.zip ./build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}.zip
9359
9460
- name: Upload Artifact For Linux x64
9561
uses: actions/upload-artifact@v1
9662
with:
9763
name: dashboards-reports-linux-x64
98-
path: ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-linux-x64.zip
99-
100-
- name: Upload Artifact For Linux arm64
101-
uses: actions/upload-artifact@v1
102-
with:
103-
name: dashboards-reports-linux-arm64
104-
path: ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-linux-arm64.zip
105-
106-
- name: Upload Artifact For Windows
107-
uses: actions/upload-artifact@v1
108-
with:
109-
name: dashboards-reports-windows-x64
110-
path: ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-windows-x64.zip
64+
path: ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}.zip

README.md

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
- [Contributing](#contributing)
1111
- [Setup](#setup-&-build)
1212
- [Notifications Integration](#notifications-integration)
13-
- [Troubleshooting](#troubleshooting)
1413
- [Code of Conduct](#code-of-conduct)
1514
- [Security](#security)
1615
- [License](#license)
@@ -35,15 +34,6 @@ Complete OpenSearch Dashboards Report feature is composed of 2 plugins. Refer to
3534

3635
OpenSearch Dashboards Reports integration with [Notifications](https://github.com/opensearch-project/notifications) is currently in progress, tracking for the 8/30 OpenSearch 1.1 release.
3736

38-
## Troubleshooting
39-
40-
#### Fail to launch Chromium
41-
42-
There could be two reasons for this problem
43-
44-
1. You are not having the correct version of headless-chrome matching to the OS that your OpenSearch Dashboards is running. Different versions of headless-chrome can be found [here](https://github.com/opensearch-project/dashboards-reports/releases/tag/chromium-1.12.0.0)
45-
46-
2. Missing additional dependencies. Please refer to [additional dependencies section](./dashboards-reports/rendering-engine/headless-chrome/README.md#additional-libaries) to install required dependencies according to your operating system.
4737
## Code of Conduct
4838

4939
This project has adopted the [Amazon Open Source Code of Conduct](CODE_OF_CONDUCT.md). For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq), or contact [[email protected]](mailto:[email protected]) with any additional questions or comments.

dashboards-reports/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,3 @@ yarn-error.log
1010
.eslintcache
1111
package-lock.json
1212
/target/
13-
.chromium/

dashboards-reports/opensearch-dashboards-plugin-helpers.dev.json renamed to dashboards-reports/.opensearch_dashboards-plugin-helpers.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"yarn.lock",
66
".i18nrc.json",
77
"common/**/*",
8+
"scripts/**/*",
89
"public/**/*",
910
"server/**/*",
1011
"translations/**/*"

dashboards-reports/package.json

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,22 @@
1717
"test": "../../node_modules/.bin/jest --config ./test/jest.config.js",
1818
"cypress:run": "cypress run",
1919
"cypress:open": "cypress open",
20-
"plugin_helpers": "node ../../scripts/plugin_helpers"
20+
"plugin_helpers": "node ../../scripts/plugin_helpers",
21+
"postinstall": "node ./scripts/patch-html2canvas.js"
2122
},
2223
"dependencies": {
23-
"async-mutex": "^0.2.6",
2424
"babel-polyfill": "^6.26.0",
2525
"cheerio": "0.22.0",
2626
"cron-validator": "^1.1.1",
27-
"dompurify": "^2.3.8",
27+
"dompurify": "^2.4.1",
2828
"elastic-builder": "^2.7.1",
2929
"enzyme-adapter-react-16": "^1.15.2",
30+
"html2canvas": "1.4.1",
3031
"jest-fetch-mock": "^3.0.3",
3132
"jquery": "^3.5.0",
3233
"jsdom": "13.1.0",
3334
"json-2-csv": "^3.7.6",
34-
"puppeteer-core": "^13.7.0",
35+
"jspdf": "^2.5.1",
3536
"react-addons-test-utils": "^15.6.2",
3637
"react-id-generator": "^3.0.1",
3738
"react-markdown": "^4.3.1",
@@ -43,14 +44,14 @@
4344
"react-toast-notifications": "^2.4.0",
4445
"set-interval-async": "1.0.33",
4546
"showdown": "^1.9.1",
47+
"svg-pathdata": "5.0.5",
4648
"ws": "^7.4.6"
4749
},
4850
"devDependencies": {
4951
"@elastic/eslint-import-resolver-kibana": "link:../../packages/osd-eslint-import-resolver-opensearch-dashboards",
5052
"@types/dompurify": "^2.3.3",
5153
"@types/enzyme-adapter-react-16": "^1.0.6",
5254
"@types/jsdom": "^16.2.3",
53-
"@types/puppeteer-core": "^5.4.0",
5455
"@types/react": "^16.9.36",
5556
"@types/react-addons-test-utils": "^0.14.25",
5657
"@types/react-dom": "^16.9.8",
@@ -66,6 +67,7 @@
6667
"identity-obj-proxy": "^3.0.0",
6768
"jest-dom": "^4.0.0",
6869
"react-test-renderer": "^16.12.0",
70+
"replace-in-file": "^6.3.5",
6971
"ts-jest": "^26.1.0"
7072
},
7173
"resolutions": {
@@ -75,6 +77,7 @@
7577
"lodash": "^4.17.21",
7678
"path-parse": "^1.0.7",
7779
"glob-parent": "^5.1.2",
78-
"css-what": "^5.0.1"
80+
"css-what": "^5.0.1",
81+
"yargs": "16.2.0"
7982
}
8083
}

dashboards-reports/public/components/context_menu/context_menu.js

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,30 @@
2525
*/
2626

2727
/* eslint-disable no-restricted-globals */
28-
import $ from 'jquery';
29-
import dateMath from '@elastic/datemath';
28+
//@ts-check
3029
import { i18n } from '@osd/i18n';
30+
import $ from 'jquery';
31+
import { parse } from 'url';
3132
import { readStreamToFile } from '../main/main_utils';
33+
import { uiSettingsService } from '../utils/settings_service';
34+
import {
35+
GENERATE_REPORT_PARAM,
36+
GENERATE_REPORT_PARAM_REGEX,
37+
} from '../visual_report/constants';
38+
import { generateReport } from '../visual_report/generate_report';
3239
import {
33-
contextMenuCreateReportDefinition,
34-
getTimeFieldsFromUrl,
35-
displayLoadingModal,
3640
addSuccessOrFailureToast,
41+
contextMenuCreateReportDefinition,
3742
contextMenuViewReports,
43+
displayLoadingModal,
44+
getTimeFieldsFromUrl,
3845
replaceQueryURL,
3946
} from './context_menu_helpers';
4047
import {
48+
getMenuItem,
4149
popoverMenu,
4250
popoverMenuDiscover,
43-
getMenuItem,
4451
} from './context_menu_ui';
45-
import { timeRangeMatcher } from '../utils/utils';
46-
import { parse } from 'url';
47-
import { unhashUrl } from '../../../../../src/plugins/opensearch_dashboards_utils/public';
48-
import { uiSettingsService } from '../utils/settings_service';
4952

5053
const generateInContextReport = async (
5154
timeRanges,
@@ -126,23 +129,28 @@ const generateInContextReport = async (
126129
credentials: 'include',
127130
}
128131
)
129-
.then((response) => {
130-
if (response.status === 200) {
131-
$('#reportGenerationProgressModal').remove();
132-
addSuccessOrFailureToast('success');
133-
} else {
134-
if (response.status === 403) {
132+
.then(async (response) => [response.status, await response.json()])
133+
.then(async ([status, data]) => {
134+
if (status !== 200) {
135+
if (status === 403) {
135136
addSuccessOrFailureToast('permissionsFailure');
136-
} else if (response.status === 503) {
137+
} else if (status === 503) {
137138
addSuccessOrFailureToast('timeoutFailure', reportSource);
138139
} else {
139140
addSuccessOrFailureToast('failure');
140141
}
142+
} else if (fileFormat === 'pdf' || fileFormat === 'png') {
143+
try {
144+
await generateReport(data.reportId);
145+
addSuccessOrFailureToast('success');
146+
} catch (error) {
147+
console.error(error);
148+
addSuccessOrFailureToast('failure');
149+
}
150+
} else if (data.data) {
151+
await readStreamToFile(data.data, fileFormat, data.filename);
141152
}
142-
return response.json();
143-
})
144-
.then(async (data) => {
145-
await readStreamToFile(data.data, fileFormat, data.filename);
153+
$('#reportGenerationProgressModal').remove();
146154
});
147155
};
148156

@@ -239,9 +247,34 @@ $(function () {
239247
});
240248
});
241249

250+
checkURLParams();
242251
locationHashChanged();
243252
});
244253

254+
/* generate a report if flagged in URL params */
255+
const checkURLParams = async () => {
256+
const [hash, query] = location.href.split('#')[1].split('?');
257+
const params = new URLSearchParams(query);
258+
const id = params.get(GENERATE_REPORT_PARAM);
259+
if (!id) return;
260+
await new Promise((resolve) => setTimeout(resolve, 1000));
261+
displayLoadingModal();
262+
try {
263+
await generateReport(id, 30000);
264+
window.history.replaceState(
265+
{},
266+
'',
267+
`#${hash}?${query.replace(GENERATE_REPORT_PARAM_REGEX, '')}`
268+
);
269+
addSuccessOrFailureToast('success');
270+
} catch (error) {
271+
console.error(error);
272+
addSuccessOrFailureToast('failure');
273+
} finally {
274+
$('#reportGenerationProgressModal').remove();
275+
}
276+
};
277+
245278
const isDiscoverNavMenu = (navMenu) => {
246279
return (
247280
navMenu[0].children.length === 5 &&

dashboards-reports/public/components/context_menu/context_menu_ui.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ export const popoverMenuDiscover = (savedObjectAvailable) => {
266266

267267
export const permissionsMissingOnGeneration = () => {
268268
return `
269-
<div class="euiToast euiToast--danger" id="permissionsMissingErrorToast">
269+
<div class="euiToast euiToast--danger" id="permissionsMissingErrorToast" data-html2canvas-ignore>
270270
<p class="euiScreenReaderOnly">${i18n.translate(
271271
'opensearch.reports.menu.newNotificationAppears',
272272
{ defaultMessage: 'A new notification appears' }
@@ -297,7 +297,7 @@ export const permissionsMissingOnGeneration = () => {
297297

298298
export const reportGenerationSuccess = () => {
299299
return `
300-
<div class="euiToast euiToast--success" id="reportSuccessToast">
300+
<div class="euiToast euiToast--success" id="reportSuccessToast" data-html2canvas-ignore>
301301
<p class="euiScreenReaderOnly">A new notification appears</p>
302302
<div class="euiToastHeader euiToastHeader--withBody"
303303
aria-label="Notification" data-test-subj="euiToastHeader">
@@ -339,7 +339,7 @@ export const reportGenerationFailure = (
339339
})
340340
) => {
341341
return `
342-
<div class="euiToast euiToast--danger" id="reportFailureToast">
342+
<div class="euiToast euiToast--danger" id="reportFailureToast" data-html2canvas-ignore>
343343
<p class="euiScreenReaderOnly">A new notification appears</p>
344344
<div class="euiToastHeader euiToastHeader--withBody"
345345
aria-label="Notification" data-test-subj="euiToastHeader">
@@ -366,7 +366,7 @@ export const reportGenerationFailure = (
366366

367367
export const reportGenerationInProgressModal = () => {
368368
return `
369-
<div class="euiOverlayMask" id="reportGenerationProgressModal">
369+
<div class="euiOverlayMask" id="reportGenerationProgressModal" data-html2canvas-ignore>
370370
<div data-focus-guard="true" tabindex="0" style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"></div>
371371
<div data-focus-guard="true" tabindex="1" style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"></div>
372372
<div data-focus-lock-disabled="false">
@@ -397,17 +397,14 @@ export const reportGenerationInProgressModal = () => {
397397
'opensearch.reports.menu.progress.youCanClose',
398398
{
399399
defaultMessage:
400-
'You can close this dialog while we continue in the background.',
400+
'Please keep this dialog open while report is being generated.',
401401
}
402402
)}</div>
403403
<div class="euiSpacer euiSpacer--l"></div>
404404
<div class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentCenter euiFlexGroup--directionRow euiFlexGroup--responsive">
405405
<div class="euiFlexItem euiFlexItem--flexGrowZero"><span class="euiLoadingSpinner euiLoadingSpinner--xLarge" style="min-width: 75px; min-height: 75px;"></span></div>
406406
</div>
407407
<div class="euiSpacer euiSpacer--l"></div>
408-
<div class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsFlexEnd euiFlexGroup--justifyContentFlexEnd euiFlexGroup--directionRow euiFlexGroup--responsive">
409-
<div class="euiFlexItem euiFlexItem--flexGrowZero"><button class="euiButton euiButton--primary" type="button" id="closeReportGenerationModalButton"><span class="euiButton__content"><span class="euiButton__text">Close</span></span></button></div>
410-
</div>
411408
</div>
412409
</div>
413410
</div>

dashboards-reports/public/components/main/loading_modal/loading_modal.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export function GenerateReportLoadingModal(props: { setShowLoading: any }) {
8080
<EuiText>
8181
{i18n.translate('opensearch.reports.loading.youCanClose', {
8282
defaultMessage:
83-
'You can close this dialog while we continue in the background.',
83+
'Please keep this dialog open while report is being generated.',
8484
})}
8585
</EuiText>
8686
<EuiSpacer />
@@ -93,15 +93,6 @@ export function GenerateReportLoadingModal(props: { setShowLoading: any }) {
9393
</EuiFlexItem>
9494
</EuiFlexGroup>
9595
<EuiSpacer size="l" />
96-
<EuiFlexGroup alignItems="flexEnd" justifyContent="flexEnd">
97-
<EuiFlexItem grow={false}>
98-
<EuiButton onClick={closeModal}>
99-
{i18n.translate('opensearch.reports.loading.close', {
100-
defaultMessage: 'Close',
101-
})}
102-
</EuiButton>
103-
</EuiFlexItem>
104-
</EuiFlexGroup>
10596
</EuiModalBody>
10697
</EuiModal>
10798
</EuiOverlayMask>

0 commit comments

Comments
 (0)