Skip to content
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

[Backport 1.0.0] Use front-end report generation instead of chromium #607

Merged
merged 3 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 2 additions & 48 deletions .github/workflows/dashboards-reports-test-and-build-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +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 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 @@ -63,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
10 changes: 0 additions & 10 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,15 +34,6 @@ Complete OpenSearch Dashboards Report feature is composed of 2 plugins. Refer to

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.

## Troubleshooting

#### Fail to launch Chromium

There could be two reasons for this problem

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)

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.
## 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 [[email protected]](mailto:[email protected]) with any additional questions or comments.
Expand Down
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
15 changes: 9 additions & 6 deletions dashboards-reports/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,22 @@
"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",
"cheerio": "0.22.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 @@ -43,14 +44,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 @@ -66,6 +67,7 @@
"identity-obj-proxy": "^3.0.0",
"jest-dom": "^4.0.0",
"react-test-renderer": "^16.12.0",
"replace-in-file": "^6.3.5",
"ts-jest": "^26.1.0"
},
"resolutions": {
Expand All @@ -75,6 +77,7 @@
"lodash": "^4.17.21",
"path-parse": "^1.0.7",
"glob-parent": "^5.1.2",
"css-what": "^5.0.1"
"css-what": "^5.0.1",
"yargs": "16.2.0"
}
}
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 @@ -25,27 +25,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 @@ -126,23 +129,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 @@ -239,9 +247,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 @@ -266,7 +266,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 @@ -297,7 +297,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 @@ -339,7 +339,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 @@ -366,7 +366,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 @@ -397,17 +397,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 @@ -80,7 +80,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 @@ -93,15 +93,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