Skip to content

Commit

Permalink
[Backport 1.2] Use front-end report generation instead of chromium (#610
Browse files Browse the repository at this point in the history
)

* Use front-end report generation instead of chromium (#586)

* Increment version to 2.4.1-SNAPSHOT (#540)

Signed-off-by: opensearch-ci-bot <opensearch-infra@amazon.com>

Signed-off-by: opensearch-ci-bot <opensearch-infra@amazon.com>
Co-authored-by: opensearch-ci-bot <opensearch-infra@amazon.com>

* --wip--

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Add initial implementation of client reporting generation

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Fix url with basepath

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Update header footer height

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Update dialog text to not close dialog

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Remove console.log

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Remove unused components

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Remove chromium references

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Add report generation error handling

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Minor refactors

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Add postinstall patch to support safari for html2canvas

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Add dompurify

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Fix build error

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Remove chromium from CI

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Update CI artifact name

Signed-off-by: Joshua Li <joshuali925@gmail.com>

Signed-off-by: opensearch-ci-bot <opensearch-infra@amazon.com>
Signed-off-by: Joshua Li <joshuali925@gmail.com>
Co-authored-by: opensearch-trigger-bot[bot] <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com>
Co-authored-by: opensearch-ci-bot <opensearch-infra@amazon.com>

* Update yarn.lock

Signed-off-by: Rupal Mahajan <maharup@amazon.com>

* Fix build failure

Signed-off-by: Rupal Mahajan <maharup@amazon.com>

* Fix workflow

Signed-off-by: Rupal Mahajan <maharup@amazon.com>

* Update yarn.lock

Signed-off-by: Rupal Mahajan <maharup@amazon.com>

Signed-off-by: opensearch-ci-bot <opensearch-infra@amazon.com>
Signed-off-by: Joshua Li <joshuali925@gmail.com>
Signed-off-by: Rupal Mahajan <maharup@amazon.com>
Co-authored-by: Joshua Li <joshuali925@gmail.com>
Co-authored-by: opensearch-trigger-bot[bot] <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com>
Co-authored-by: opensearch-ci-bot <opensearch-infra@amazon.com>
  • Loading branch information
4 people authored Jan 3, 2023
1 parent 3182b86 commit 976265a
Show file tree
Hide file tree
Showing 28 changed files with 587 additions and 1,049 deletions.
51 changes: 2 additions & 49 deletions .github/workflows/dashboards-reports-test-and-build-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,6 @@ jobs:
- name: Move Dashboards Reports to Plugins Dir
run: mv dashboards-reports ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}

- name: Add Chromium Binary to Reporting for Testing
run: |
sudo apt update
sudo apt install -y libnss3-dev fonts-liberation libfontconfig1
cd ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}
wget https://github.com/opendistro-for-elasticsearch/kibana-reports/releases/download/chromium-1.12.0.0/chromium-linux-x64.zip
unzip chromium-linux-x64.zip
rm chromium-linux-x64.zip
- name: OpenSearch Dashboards Plugin Bootstrap
uses: nick-invision/retry@v1
with:
Expand All @@ -64,48 +55,10 @@ jobs:
run: |
cd ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}
yarn build
cd build
mkdir -p ./{linux-x64,linux-arm64,windows-x64}/opensearch-dashboards/${{ env.PLUGIN_NAME }}
cp ./${{ env.PLUGIN_NAME }}-*.zip ./linux-x64/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-linux-x64.zip
cp ./${{ env.PLUGIN_NAME }}-*.zip ./linux-arm64/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-linux-arm64.zip
mv ./${{ env.PLUGIN_NAME }}-*.zip ./windows-x64/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-windows-x64.zip
cd linux-x64
wget https://github.com/opensearch-project/dashboards-reports/releases/download/chromium-1.12.0.0/chromium-linux-x64.zip
unzip chromium-linux-x64.zip -d ./opensearch-dashboards/${{ env.PLUGIN_NAME }}
zip -ur ./${{ env.ARTIFACT_NAME }}-*.zip ./opensearch-dashboards
mv ./${{ env.ARTIFACT_NAME }}-*.zip ..
cd ..
cd linux-arm64
wget https://github.com/opensearch-project/dashboards-reports/releases/download/chromium-1.12.0.0/chromium-linux-arm64.zip
unzip chromium-linux-arm64.zip -d ./opensearch-dashboards/${{ env.PLUGIN_NAME }}
zip -ur ./${{ env.ARTIFACT_NAME }}-*.zip ./opensearch-dashboards
mv ./${{ env.ARTIFACT_NAME }}-*.zip ..
cd ..
cd windows-x64
wget https://github.com/opensearch-project/dashboards-reports/releases/download/chromium-1.12.0.0/chromium-windows-x64.zip
unzip chromium-windows-x64.zip -d ./opensearch-dashboards/${{ env.PLUGIN_NAME }}
zip -ur ./${{ env.ARTIFACT_NAME }}-*.zip ./opensearch-dashboards
mv ./${{ env.ARTIFACT_NAME }}-*.zip ..
cd ..
mv ./build/*.zip ./build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}.zip
- name: Upload Artifact For Linux x64
uses: actions/upload-artifact@v1
with:
name: dashboards-reports-linux-x64
path: ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-linux-x64.zip

- name: Upload Artifact For Linux arm64
uses: actions/upload-artifact@v1
with:
name: dashboards-reports-linux-arm64
path: ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-linux-arm64.zip

- name: Upload Artifact For Windows
uses: actions/upload-artifact@v1
with:
name: dashboards-reports-windows-x64
path: ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-windows-x64.zip
path: ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}.zip
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
- [Contributing](#contributing)
- [Setup](#setup-&-build)
- [Notifications Integration](#notifications-integration)
- [Troubleshooting](#troubleshooting)
- [Code of Conduct](#code-of-conduct)
- [Security](#security)
- [License](#license)
Expand All @@ -35,6 +34,7 @@ Complete OpenSearch Dashboards Report feature is composed of 2 plugins.

OpenSearch Dashboards Reports integration with [Notifications](https://github.com/opensearch-project/notifications) is currently in progress. Tracking [here](https://github.com/opensearch-project/dashboards-reports/issues/72)

<<<<<<< HEAD
## Troubleshooting

### Fail to launch Chromium
Expand Down Expand Up @@ -66,6 +66,8 @@ If you are using a Ubuntu/Debian system, install the following packages:

The installation command for both systems can be found [here](./dashboards-reports/rendering-engine/headless-chrome/README.md).

=======
>>>>>>> 71d843a... Use front-end report generation instead of chromium (#586)
## Code of Conduct

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 [opensource-codeofconduct@amazon.com](mailto:opensource-codeofconduct@amazon.com) with any additional questions or comments.
Expand All @@ -80,4 +82,3 @@ See the [LICENSE](./LICENSE) file for our project's licensing. We will ask you t

## Copyright

Copyright OpenSearch Contributors. See [NOTICE](NOTICE.txt) for details.
1 change: 0 additions & 1 deletion dashboards-reports/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@ yarn-error.log
.eslintcache
package-lock.json
/target/
.chromium/
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"yarn.lock",
".i18nrc.json",
"common/**/*",
"scripts/**/*",
"public/**/*",
"server/**/*",
"translations/**/*"
Expand Down
12 changes: 7 additions & 5 deletions dashboards-reports/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,21 @@
"test": "../../node_modules/.bin/jest --config ./test/jest.config.js",
"cypress:run": "cypress run",
"cypress:open": "cypress open",
"plugin_helpers": "node ../../scripts/plugin_helpers"
"plugin_helpers": "node ../../scripts/plugin_helpers",
"postinstall": "node ./scripts/patch-html2canvas.js"
},
"dependencies": {
"async-mutex": "^0.2.6",
"babel-polyfill": "^6.26.0",
"cron-validator": "^1.1.1",
"dompurify": "^2.3.8",
"dompurify": "^2.4.1",
"elastic-builder": "^2.7.1",
"enzyme-adapter-react-16": "^1.15.2",
"html2canvas": "1.4.1",
"jest-fetch-mock": "^3.0.3",
"jquery": "^3.5.0",
"jsdom": "13.1.0",
"json-2-csv": "^3.7.6",
"puppeteer-core": "^13.7.0",
"jspdf": "^2.5.1",
"react-addons-test-utils": "^15.6.2",
"react-id-generator": "^3.0.1",
"react-markdown": "^4.3.1",
Expand All @@ -42,14 +43,14 @@
"react-toast-notifications": "^2.4.0",
"set-interval-async": "1.0.33",
"showdown": "^1.9.1",
"svg-pathdata": "^5.0.5",
"ws": "^7.4.6"
},
"devDependencies": {
"@elastic/eslint-import-resolver-kibana": "link:../../packages/osd-eslint-import-resolver-opensearch-dashboards",
"@types/dompurify": "^2.3.3",
"@types/enzyme-adapter-react-16": "^1.0.6",
"@types/jsdom": "^16.2.3",
"@types/puppeteer-core": "^5.4.0",
"@types/react": "^16.9.36",
"@types/react-addons-test-utils": "^0.14.25",
"@types/react-dom": "^16.9.8",
Expand All @@ -65,6 +66,7 @@
"identity-obj-proxy": "^3.0.0",
"jest-dom": "^4.0.0",
"react-test-renderer": "^16.12.0",
"replace-in-file": "^5.0.2",
"ts-jest": "^26.1.0"
},
"resolutions": {
Expand Down
75 changes: 54 additions & 21 deletions dashboards-reports/public/components/context_menu/context_menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,30 @@
*/

/* eslint-disable no-restricted-globals */
import $ from 'jquery';
import dateMath from '@elastic/datemath';
//@ts-check
import { i18n } from '@osd/i18n';
import $ from 'jquery';
import { parse } from 'url';
import { readStreamToFile } from '../main/main_utils';
import { uiSettingsService } from '../utils/settings_service';
import {
GENERATE_REPORT_PARAM,
GENERATE_REPORT_PARAM_REGEX,
} from '../visual_report/constants';
import { generateReport } from '../visual_report/generate_report';
import {
contextMenuCreateReportDefinition,
getTimeFieldsFromUrl,
displayLoadingModal,
addSuccessOrFailureToast,
contextMenuCreateReportDefinition,
contextMenuViewReports,
displayLoadingModal,
getTimeFieldsFromUrl,
replaceQueryURL,
} from './context_menu_helpers';
import {
getMenuItem,
popoverMenu,
popoverMenuDiscover,
getMenuItem,
} from './context_menu_ui';
import { timeRangeMatcher } from '../utils/utils';
import { parse } from 'url';
import { unhashUrl } from '../../../../../src/plugins/opensearch_dashboards_utils/public';
import { uiSettingsService } from '../utils/settings_service';

const generateInContextReport = async (
timeRanges,
Expand Down Expand Up @@ -105,23 +108,28 @@ const generateInContextReport = async (
credentials: 'include',
}
)
.then((response) => {
if (response.status === 200) {
$('#reportGenerationProgressModal').remove();
addSuccessOrFailureToast('success');
} else {
if (response.status === 403) {
.then(async (response) => [response.status, await response.json()])
.then(async ([status, data]) => {
if (status !== 200) {
if (status === 403) {
addSuccessOrFailureToast('permissionsFailure');
} else if (response.status === 503) {
} else if (status === 503) {
addSuccessOrFailureToast('timeoutFailure', reportSource);
} else {
addSuccessOrFailureToast('failure');
}
} else if (fileFormat === 'pdf' || fileFormat === 'png') {
try {
await generateReport(data.reportId);
addSuccessOrFailureToast('success');
} catch (error) {
console.error(error);
addSuccessOrFailureToast('failure');
}
} else if (data.data) {
await readStreamToFile(data.data, fileFormat, data.filename);
}
return response.json();
})
.then(async (data) => {
await readStreamToFile(data.data, fileFormat, data.filename);
$('#reportGenerationProgressModal').remove();
});
};

Expand Down Expand Up @@ -218,9 +226,34 @@ $(function () {
});
});

checkURLParams();
locationHashChanged();
});

/* generate a report if flagged in URL params */
const checkURLParams = async () => {
const [hash, query] = location.href.split('#')[1].split('?');
const params = new URLSearchParams(query);
const id = params.get(GENERATE_REPORT_PARAM);
if (!id) return;
await new Promise((resolve) => setTimeout(resolve, 1000));
displayLoadingModal();
try {
await generateReport(id, 30000);
window.history.replaceState(
{},
'',
`#${hash}?${query.replace(GENERATE_REPORT_PARAM_REGEX, '')}`
);
addSuccessOrFailureToast('success');
} catch (error) {
console.error(error);
addSuccessOrFailureToast('failure');
} finally {
$('#reportGenerationProgressModal').remove();
}
};

const isDiscoverNavMenu = (navMenu) => {
return (
navMenu[0].children.length === 5 &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ export const popoverMenuDiscover = (savedObjectAvailable) => {

export const permissionsMissingOnGeneration = () => {
return `
<div class="euiToast euiToast--danger" id="permissionsMissingErrorToast">
<div class="euiToast euiToast--danger" id="permissionsMissingErrorToast" data-html2canvas-ignore>
<p class="euiScreenReaderOnly">${i18n.translate(
'opensearch.reports.menu.newNotificationAppears',
{ defaultMessage: 'A new notification appears' }
Expand Down Expand Up @@ -277,7 +277,7 @@ export const permissionsMissingOnGeneration = () => {

export const reportGenerationSuccess = () => {
return `
<div class="euiToast euiToast--success" id="reportSuccessToast">
<div class="euiToast euiToast--success" id="reportSuccessToast" data-html2canvas-ignore>
<p class="euiScreenReaderOnly">A new notification appears</p>
<div class="euiToastHeader euiToastHeader--withBody"
aria-label="Notification" data-test-subj="euiToastHeader">
Expand Down Expand Up @@ -319,7 +319,7 @@ export const reportGenerationFailure = (
})
) => {
return `
<div class="euiToast euiToast--danger" id="reportFailureToast">
<div class="euiToast euiToast--danger" id="reportFailureToast" data-html2canvas-ignore>
<p class="euiScreenReaderOnly">A new notification appears</p>
<div class="euiToastHeader euiToastHeader--withBody"
aria-label="Notification" data-test-subj="euiToastHeader">
Expand All @@ -346,7 +346,7 @@ export const reportGenerationFailure = (

export const reportGenerationInProgressModal = () => {
return `
<div class="euiOverlayMask" id="reportGenerationProgressModal">
<div class="euiOverlayMask" id="reportGenerationProgressModal" data-html2canvas-ignore>
<div data-focus-guard="true" tabindex="0" style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"></div>
<div data-focus-guard="true" tabindex="1" style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"></div>
<div data-focus-lock-disabled="false">
Expand Down Expand Up @@ -377,17 +377,14 @@ export const reportGenerationInProgressModal = () => {
'opensearch.reports.menu.progress.youCanClose',
{
defaultMessage:
'You can close this dialog while we continue in the background.',
'Please keep this dialog open while report is being generated.',
}
)}</div>
<div class="euiSpacer euiSpacer--l"></div>
<div class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentCenter euiFlexGroup--directionRow euiFlexGroup--responsive">
<div class="euiFlexItem euiFlexItem--flexGrowZero"><span class="euiLoadingSpinner euiLoadingSpinner--xLarge" style="min-width: 75px; min-height: 75px;"></span></div>
</div>
<div class="euiSpacer euiSpacer--l"></div>
<div class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsFlexEnd euiFlexGroup--justifyContentFlexEnd euiFlexGroup--directionRow euiFlexGroup--responsive">
<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>
</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function GenerateReportLoadingModal(props: { setShowLoading: any }) {
<EuiText>
{i18n.translate('opensearch.reports.loading.youCanClose', {
defaultMessage:
'You can close this dialog while we continue in the background.',
'Please keep this dialog open while report is being generated.',
})}
</EuiText>
<EuiSpacer />
Expand All @@ -72,15 +72,6 @@ export function GenerateReportLoadingModal(props: { setShowLoading: any }) {
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="l" />
<EuiFlexGroup alignItems="flexEnd" justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiButton onClick={closeModal}>
{i18n.translate('opensearch.reports.loading.close', {
defaultMessage: 'Close',
})}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiModalBody>
</EuiModal>
</EuiOverlayMask>
Expand Down
Loading

0 comments on commit 976265a

Please sign in to comment.