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

[Rollups] Rollup support in Kibana, phase 1 #21117

Merged
merged 52 commits into from
Oct 25, 2018
Merged

[Rollups] Rollup support in Kibana, phase 1 #21117

merged 52 commits into from
Oct 25, 2018

Conversation

cjcenizal
Copy link
Contributor

@cjcenizal cjcenizal commented Jul 23, 2018

Meta issue: #20004

Overview

This PR introduces rollup support to Kibana. Specifically, the ability to:

  1. View/Manage/Create rollup jobs
  2. Create a rollup index pattern
  3. Create rollup visualizations
  4. Add rollup visualizations to dashboards
  5. View raw rollup documents in Discover

Testing plan

Please refer to this document for detailed information and testing strategy for each aspect of rollup support: Rollups testing plan

Rollup job management

image

image

image

@cjcenizal
Copy link
Contributor Author

@maryia-lapata I've localized the copy in x-pack/plugins/rollup/public/crud_app. When you have time could you please review and let me know if I missed any copy or made any mistakes? Thank you!

@cjcenizal cjcenizal force-pushed the feature/rollups branch 2 times, most recently from 81480f2 to 0743e30 Compare September 19, 2018 00:13
@@ -245,12 +252,15 @@ export class StepIndexPatternComponent extends Component {
const errorMessage = intl.formatMessage(
{
id: 'kbn.management.createIndexPattern.step.invalidCharactersErrorMessage',
defaultMessage: 'An index pattern cannot contain spaces or the characters: {characterList}'
defaultMessage: 'A ${indexPatternName} cannot contain spaces or the characters: {characterList}'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove $ sign. Placeholders should be presented just in curly braces.

const label = intl.formatMessage({

const infoLabel = intl.formatMessage({
id: 'kbn.management.editIndexPattern.fields.table.additionalInfo',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a description of label type to the id. Since it's a label for aria-label attribute, id should end with AriaLabel.
kbn.management.editIndexPattern.fields.table.additionalInfoAriaLabel

id: 'kbn.management.editIndexPattern.fields.table.additionalInfo',
defaultMessage: 'Additional field information'
});
const timeLabel = intl.formatMessage({
id: 'kbn.management.editIndexPattern.fields.table.primaryTimeAria',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Please update the id according to Guideline: kbn.management.editIndexPattern.fields.table.primaryTimeAriaLabel

</a>
</li>
</ul>
<div id="indexPatternListReact" role="region" aria-label="Index patterns"></div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, this aria-label attribute should be translated as well.

indexPatternCreationOptions
}) => (
<CreateButton options={indexPatternCreationOptions}>
Create index pattern
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose that Create index pattern should be translated as well.

renderJobs() {
const { jobs } = this.props;
const jobItems = jobs.map(({ id, status }) => {
const statusText = status === 'started' ? ' (started)' : null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(started) should be translated.

<EuiButton
data-test-subj="jobActionMenuButton"
iconSide={iconSide}
aria-label={`${entity} options`}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please translate aria-label attribute.


const columns = [{
field: 'name',
name: 'Field',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please translate this label.


const columns = [{
field: 'name',
name: 'Field',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please translate this field.

truncateText: true,
sortable: true,
}, {
name: 'Types',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and this one

Copy link
Contributor

@maryia-lapata maryia-lapata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some more comments

@@ -36,22 +36,36 @@ function addJsonFieldToIndexPattern(target, sourceString, fieldName, indexName)
try {
target[fieldName] = JSON.parse(sourceString);
} catch (error) {
throw new Error(`Error encountered parsing ${fieldName} for index pattern ${indexName}: ${error.message}`);
throw new Error(
`Error encountered parsing ${fieldName} for index pattern ${indexName}: ${error.message}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if a user can see this message, it should be translated as well.

);
};

export const TabJson = injectI18n(TabJsonUi);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no translated labels, so it's no reason to wrap the component with injectI18n

<EuiFlexItem>
<EuiDescriptionListTitle>
<FormattedMessage
id="xpack.rollupJobs.jobDetails.tabSummary.itemDocumentsProcessed.label"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: To be consistent with other code, please follow to naming convention described in Guideline. Please use camelcase for the message type: xpack.rollupJobs.jobDetails.tabSummary.itemDocumentsProcessedLabel

<EuiFlexItem>
<EuiDescriptionListTitle>
<FormattedMessage
id="xpack.rollupJobs.jobDetails.tabSummary.itemPagesProcessed.label"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: xpack.rollupJobs.jobDetails.tabSummary.itemPagesProcessedLabel

@yaronp68
Copy link

@cjcenizal
In the last phase consider adding a checkbox / button to allow all stats to be ticked per metric row. currently user need to tick each stat

image

@yaronp68
Copy link

@cjcenizal in the last phase consider adding a user friendly version to the cron pattern. the field should be named like in the wizard: Schedule (or we can use frequency)
image

@elastic elastic deleted a comment from elasticmachine Sep 26, 2018
@elastic elastic deleted a comment from elasticmachine Sep 26, 2018
@elastic elastic deleted a comment from elasticmachine Sep 26, 2018
@elastic elastic deleted a comment from elasticmachine Sep 27, 2018
@elastic elastic deleted a comment from elasticmachine Sep 27, 2018
@elastic elastic deleted a comment from elasticmachine Sep 27, 2018
@elastic elastic deleted a comment from elasticmachine Sep 27, 2018
@cjcenizal cjcenizal removed the WIP Work in progress label Oct 22, 2018
@elasticmachine

This comment has been minimized.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Copy link
Contributor

@spalger spalger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went digging around in some of the places that @cjcenizal pointed out and found somethings that I think should be addressed, but nothing earth shattering.

I'm a little shocked to not find a single test in the rollup UI. Thankfully there are tests for the server libs, but there should absolutely be more unit tests in the UI and some functional tests to verify baseline functionality end-to-end.

I know we're trying to get this in for 6.5, and since most of this logic is out of the critical path it shouldn't be too problematic, I'm fine if y'all merge this and work to address testing/feedback in follow up PRs, but I'm going to have to trust that you follow through with that as I won't be able to verify everything is taken care of.

let _http;

export function setHttp(http) {
_http = http;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, why not use kfetch?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're blocked by #22594 (interceptor parity between kfetch and $http). We originally used kfetch and then switched to $http for this reason.

};

export function getOrdinalValue(number) {
// TODO: This is breaking reporting pdf generation. Possibly due to phantom not setting locale,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an issue for this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created #24770


function removeEmptyValues(object) {
Object.keys(object).forEach(key => {
if (object[key] == null || object[key].trim() === '') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think relying on the values in object to be either undefined, null, or a string is slightly risky. String(object[key]).trim() === '' would probably be a bit safer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you clarify what you meant by "safer"? Are you concerned about object being of type Object or number?

}

const extractedQueryParams = {};
const queryParamPairs = queryString.split('?')[1].split('&').map(paramString => paramString.split('='));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please use require('query_string').parse() instead of reimplementing query string parsing without tests?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try {
await sendStartJobsRequest(jobIds);
} catch (error) {
return toastNotifications.addDanger(error.data.message);
Copy link
Contributor

@spalger spalger Oct 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not confident that errors will always have a data.message property, we should probably use a helper of some sort that uses that when available, and defaults to something like error.stack when it isn't...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[ newJob ] = await Promise.all([
sendCreateJobRequest(serializeJob(jobConfig)),
// Wait at least half a second to avoid a weird flicker of the saving feedback.
new Promise(resolve => setTimeout(resolve, 500)),

This comment was marked as resolved.

new Promise(resolve => setTimeout(resolve, 500)),
]);
} catch (error) {
const { statusCode, data } = error;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are lots of situations where error here is not coming from the API, so I think we should handle those errors differently rather than assuming every error will be an HTTP response.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const { statusCode, data } = error;

// Some errors have statusCode directly available but some are under a data property.
switch (statusCode || data.statusCode) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes more sense as a if ((statusCode || data.statusCode) === 409) block with an early return, followed by the default case and an early return, rather than a switch statement with a floating return after it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const { isLoading, jobs, jobLoadError } = this.props;

let content;
if (jobLoadError && jobLoadError.status === 403) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have a jobLoadError and it's not because of a permission error, we should probably do something besides load an empty screen, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import dateMath from '@kbn/datemath';

import { InvalidEsCalendarIntervalError } from './invalid_es_calendar_interval_error';
import { InvalidEsIntervalFormatError } from './invalid_es_interval_format_error';

const ES_INTERVAL_STRING_REGEX = new RegExp(
'^([1-9][0-9]*)\\s*(' + dateMath.units.join('|') + ')$'
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to https://github.com/elastic/kibana/blob/master/packages/kbn-datemath/src/index.js#L25 m is a mixed type unit, meaning a single minute is a "calendar" unit type, right? Does that mean that the datemath module is wrong or this module is wrong?

Also why is this not part of the datemath module? Feels like it's pretty closely related.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we either hashed this out or it is being addressed in #24671? Let me know if this is actually a separate issue.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

cjcenizal and others added 4 commits October 24, 2018 14:18
…to allow rollups to avoid normalizing ES interval units (#24428)
* add rollups link to Kibana home

* copy change

* copy edit

* Making rollup jobs empty message match home page copy

* copy edit

* copy edit
Copy link
Contributor

@bmcconaghy bmcconaghy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting out works to prevent creation of rollup index pattern. Code LGTM.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@cjcenizal cjcenizal merged commit f74f633 into master Oct 25, 2018
@cjcenizal cjcenizal removed the review label Oct 25, 2018
cjcenizal added a commit to cjcenizal/kibana that referenced this pull request Oct 25, 2018
Enabled:
- View/Manage/Create rollup jobs

Disabled:
- Create a rollup index pattern
- Create rollup visualizations
- Add rollup visualizations to dashboards
- View raw rollup documents in Discover
cjcenizal added a commit that referenced this pull request Oct 25, 2018
Enabled:
- View/Manage/Create rollup jobs

Disabled:
- Create a rollup index pattern
- Create rollup visualizations
- Add rollup visualizations to dashboards
- View raw rollup documents in Discover
@cjcenizal cjcenizal deleted the feature/rollups branch November 1, 2018 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants