Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c020977
[ML] Adds number of transform nodes to stats bar.
walterra Mar 8, 2021
6808b08
[ML] Fix typo.
walterra Mar 8, 2021
0231ef4
Merge branch 'master' into ml-transform-nodes
walterra Mar 9, 2021
bbe793a
[ML] Add callout when no transform nodes available.
walterra Mar 9, 2021
8afc547
Merge branch 'master' into ml-transform-nodes
walterra Mar 10, 2021
bc3e236
[ML] Functional Tests. Loading behavior improvements. Server side cod…
walterra Mar 10, 2021
3bede65
[ML] Rename endpoint to /_nodes.
walterra Mar 10, 2021
c09dbf7
Merge branch 'master' into ml-transform-nodes
walterra Mar 10, 2021
f7ff1e7
[ML] Update jest test.
walterra Mar 10, 2021
d0a448f
Merge branch 'master' into ml-transform-nodes
walterra Mar 10, 2021
7ad9b57
[ML] Reenable tests.
walterra Mar 10, 2021
c47595c
[ML] Tweak callout text.
walterra Mar 10, 2021
7fc4d8f
[ML] Disable all actions except delete if no transform nodes are avai…
walterra Mar 10, 2021
aaef8c4
Merge branch 'master' into ml-transform-nodes
walterra Mar 11, 2021
cf88faa
[ML] Fix jest tests.
walterra Mar 11, 2021
d30e9e4
[ML] Fix types.
walterra Mar 11, 2021
e919f30
Merge branch 'master' into ml-transform-nodes
walterra Mar 11, 2021
e5d918c
[ML] Fix type guard.
walterra Mar 11, 2021
e970178
[ML] Disable create transform button when no transform nodes available.
walterra Mar 11, 2021
9cc9719
[ML] Fix jest test.
walterra Mar 11, 2021
cf49a77
[ML] Fix type guard and add jest tests.
walterra Mar 11, 2021
a0637d6
Merge branch 'master' into ml-transform-nodes
kibanamachine Mar 15, 2021
4675a88
Merge branch 'master' into ml-transform-nodes
kibanamachine Mar 15, 2021
22553c6
Merge branch 'master' into ml-transform-nodes
walterra Mar 16, 2021
9a471ee
[ML] Get number of transform nodes using roles instead of attributes.
walterra Mar 16, 2021
f8dbbab
Merge branch 'ml-transform-nodes' of github.com:walterra/kibana into …
walterra Mar 16, 2021
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
1 change: 1 addition & 0 deletions src/core/public/doc_links/doc_links_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ export class DocLinksService {
elasticsearch: {
indexModules: `${ELASTICSEARCH_DOCS}index-modules.html`,
mapping: `${ELASTICSEARCH_DOCS}mapping.html`,
nodeRoles: `${ELASTICSEARCH_DOCS}modules-node.html#node-roles`,
remoteClusters: `${ELASTICSEARCH_DOCS}modules-remote-clusters.html`,
remoteClustersProxy: `${ELASTICSEARCH_DOCS}modules-remote-clusters.html#proxy-mode`,
remoteClusersProxySettings: `${ELASTICSEARCH_DOCS}modules-remote-clusters.html#remote-cluster-proxy-settings`,
Expand Down
5 changes: 5 additions & 0 deletions x-pack/plugins/transform/common/api_schemas/transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ import type { TransformId, TransformPivotConfig } from '../types/transform';

import { transformStateSchema, runtimeMappingsSchema } from './common';

// GET transform nodes
export interface GetTransformNodesResponseSchema {
count: number;
}

// GET transforms
export const getTransformsRequestSchema = schema.arrayOf(
schema.object({
Expand Down
9 changes: 9 additions & 0 deletions x-pack/plugins/transform/common/api_schemas/type_guards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type { DeleteTransformsResponseSchema } from './delete_transforms';
import type { StartTransformsResponseSchema } from './start_transforms';
import type { StopTransformsResponseSchema } from './stop_transforms';
import type {
GetTransformNodesResponseSchema,
GetTransformsResponseSchema,
PostTransformsPreviewResponseSchema,
PutTransformsResponseSchema,
Expand All @@ -35,6 +36,14 @@ const isGenericResponseSchema = <T>(arg: any): arg is T => {
);
};

export const isGetTransformNodesResponseSchema = (
arg: unknown
): arg is GetTransformNodesResponseSchema => {
return (
isPopulatedObject(arg) && {}.hasOwnProperty.call(arg, 'count') && typeof arg.count === 'number'
);
};

export const isGetTransformsResponseSchema = (arg: unknown): arg is GetTransformsResponseSchema => {
return isGenericResponseSchema<GetTransformsResponseSchema>(arg);
};
Expand Down
8 changes: 8 additions & 0 deletions x-pack/plugins/transform/public/app/hooks/use_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import type {
StopTransformsResponseSchema,
} from '../../../common/api_schemas/stop_transforms';
import type {
GetTransformNodesResponseSchema,
GetTransformsResponseSchema,
PostTransformsPreviewRequestSchema,
PostTransformsPreviewResponseSchema,
Expand Down Expand Up @@ -66,6 +67,13 @@ export const useApi = () => {

return useMemo(
() => ({
async getTransformNodes(): Promise<GetTransformNodesResponseSchema | HttpFetchError> {
try {
return await http.get(`${API_BASE_PATH}transforms/_nodes`);
} catch (e) {
return e;
}
},
async getTransform(
transformId: TransformId
): Promise<GetTransformsResponseSchema | HttpFetchError> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const useDocumentationLinks = () => {
return {
esAggsCompositeMissingBucket: deps.docLinks.links.aggs.composite_missing_bucket,
esIndicesCreateIndex: deps.docLinks.links.apis.createIndex,
esNodeRoles: deps.docLinks.links.elasticsearch.nodeRoles,
esPluginDocBasePath: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/plugins/${DOC_LINK_VERSION}/`,
esQueryDsl: deps.docLinks.links.query.queryDsl,
esTransform: deps.docLinks.links.transforms.guide,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { HttpFetchError } from 'src/core/public';

import {
isGetTransformNodesResponseSchema,
isGetTransformsResponseSchema,
isGetTransformsStatsResponseSchema,
} from '../../../common/api_schemas/type_guards';
Expand All @@ -22,6 +23,7 @@ export type GetTransforms = (forceRefresh?: boolean) => void;

export const useGetTransforms = (
setTransforms: React.Dispatch<React.SetStateAction<TransformListRow[]>>,
setTransformNodes: React.Dispatch<React.SetStateAction<number>>,
setErrorMessage: React.Dispatch<React.SetStateAction<HttpFetchError | undefined>>,
setIsInitialized: React.Dispatch<React.SetStateAction<boolean>>,
blockRefresh: boolean
Expand All @@ -40,17 +42,20 @@ export const useGetTransforms = (
}

const fetchOptions = { asSystemRequest: true };
const transformNodes = await api.getTransformNodes();
const transformConfigs = await api.getTransforms(fetchOptions);
const transformStats = await api.getTransformsStats(fetchOptions);

if (
!isGetTransformsResponseSchema(transformConfigs) ||
!isGetTransformsStatsResponseSchema(transformStats)
!isGetTransformsStatsResponseSchema(transformStats) ||
!isGetTransformNodesResponseSchema(transformNodes)
) {
// An error is followed immediately by setting the state to idle.
// This way we're able to treat ERROR as a one-time-event like REFRESH.
refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.ERROR);
refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.IDLE);
setTransformNodes(0);
setTransforms([]);

setIsInitialized(true);
Expand Down Expand Up @@ -86,6 +91,7 @@ export const useGetTransforms = (
return reducedtableRows;
}, [] as TransformListRow[]);

setTransformNodes(transformNodes.count);
setTransforms(tableRows);
setErrorMessage(undefined);
setIsInitialized(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ export const hasPrivilegeFactory = (privileges: Privileges | undefined | null) =

// create the text for button's tooltips if the user
// doesn't have the permission to press that button
export function createCapabilityFailureMessage(capability: keyof Capabilities) {
export function createCapabilityFailureMessage(
capability: keyof Capabilities | 'noTransformNodes'
) {
let message = '';

switch (capability) {
Expand All @@ -80,6 +82,12 @@ export function createCapabilityFailureMessage(capability: keyof Capabilities) {
defaultMessage: 'You do not have permission to delete transforms.',
});
break;

case 'noTransformNodes':
message = i18n.translate('xpack.transform.capability.noPermission.noTransformNodesTooltip', {
defaultMessage: 'There are no transform nodes available.',
});
break;
}

return i18n.translate('xpack.transform.capability.pleaseContactAdministratorTooltip', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,7 @@ export const StepDefineForm: FC<StepDefineFormProps> = React.memo((props) => {
stepDefineForm.advancedPivotEditor.actions.setAdvancedPivotEditorApplyButtonEnabled(false);
};

const { esQueryDsl } = useDocumentationLinks();
const { esTransformPivot } = useDocumentationLinks();
const { esQueryDsl, esTransformPivot } = useDocumentationLinks();

const advancedEditorsSidebarWidth = '220px';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { useAppDependencies, useToastNotifications } from '../../../../app_depen
import { cloneActionNameText, CloneActionName } from './clone_action_name';

export type CloneAction = ReturnType<typeof useCloneAction>;
export const useCloneAction = (forceDisable: boolean) => {
export const useCloneAction = (forceDisable: boolean, transformNodes: number) => {
const history = useHistory();
const appDeps = useAppDependencies();
const savedObjectsClient = appDeps.savedObjects.client;
Expand Down Expand Up @@ -72,14 +72,14 @@ export const useCloneAction = (forceDisable: boolean) => {
const action: TransformListAction = useMemo(
() => ({
name: (item: TransformListRow) => <CloneActionName disabled={!canCreateTransform} />,
enabled: () => canCreateTransform && !forceDisable,
enabled: () => canCreateTransform && !forceDisable && transformNodes > 0,
description: cloneActionNameText,
icon: 'copy',
type: 'icon',
onClick: clickHandler,
'data-test-subj': 'transformActionClone',
}),
[canCreateTransform, forceDisable, clickHandler]
[canCreateTransform, forceDisable, clickHandler, transformNodes]
);

return { action };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { AuthorizationContext } from '../../../../lib/authorization';

import { editActionNameText, EditActionName } from './edit_action_name';

export const useEditAction = (forceDisable: boolean) => {
export const useEditAction = (forceDisable: boolean, transformNodes: number) => {
const { canCreateTransform } = useContext(AuthorizationContext).capabilities;

const [config, setConfig] = useState<TransformConfigUnion>();
Expand All @@ -28,14 +28,14 @@ export const useEditAction = (forceDisable: boolean) => {
const action: TransformListAction = useMemo(
() => ({
name: () => <EditActionName />,
enabled: () => canCreateTransform || !forceDisable,
enabled: () => canCreateTransform && !forceDisable && transformNodes > 0,
description: editActionNameText,
icon: 'pencil',
type: 'icon',
onClick: (item: TransformListRow) => showFlyout(item.config),
'data-test-subj': 'transformActionEdit',
}),
[canCreateTransform, forceDisable]
[canCreateTransform, forceDisable, transformNodes]
);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ describe('Transform: Transform List Actions <StartAction />', () => {
const props: StartActionNameProps = {
forceDisable: false,
items: [item],
transformNodes: 1,
};

const wrapper = shallow(<StartActionName {...props} />);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ export const startActionNameText = i18n.translate(

export const isStartActionDisabled = (
items: TransformListRow[],
canStartStopTransform: boolean
canStartStopTransform: boolean,
transformNodes: number
) => {
// Disable start for batch transforms which have completed.
const completedBatchTransform = items.some((i: TransformListRow) => isCompletedBatchTransform(i));
Expand All @@ -36,15 +37,24 @@ export const isStartActionDisabled = (
);

return (
!canStartStopTransform || completedBatchTransform || startedTransform || items.length === 0
!canStartStopTransform ||
completedBatchTransform ||
startedTransform ||
items.length === 0 ||
transformNodes === 0
);
};

export interface StartActionNameProps {
items: TransformListRow[];
forceDisable?: boolean;
transformNodes: number;
}
export const StartActionName: FC<StartActionNameProps> = ({ items, forceDisable }) => {
export const StartActionName: FC<StartActionNameProps> = ({
items,
forceDisable,
transformNodes,
}) => {
const { canStartStopTransform } = useContext(AuthorizationContext).capabilities;
const isBulkAction = items.length > 1;

Expand Down Expand Up @@ -89,7 +99,7 @@ export const StartActionName: FC<StartActionNameProps> = ({ items, forceDisable
);
}

const actionIsDisabled = isStartActionDisabled(items, canStartStopTransform);
const actionIsDisabled = isStartActionDisabled(items, canStartStopTransform, transformNodes);

let content: string | undefined;
if (actionIsDisabled && items.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { useStartTransforms } from '../../../../hooks';
import { isStartActionDisabled, startActionNameText, StartActionName } from './start_action_name';

export type StartAction = ReturnType<typeof useStartAction>;
export const useStartAction = (forceDisable: boolean) => {
export const useStartAction = (forceDisable: boolean, transformNodes: number) => {
const { canStartStopTransform } = useContext(AuthorizationContext).capabilities;

const startTransforms = useStartTransforms();
Expand All @@ -43,17 +43,22 @@ export const useStartAction = (forceDisable: boolean) => {
const action: TransformListAction = useMemo(
() => ({
name: (item: TransformListRow) => (
<StartActionName items={[item]} forceDisable={forceDisable} />
<StartActionName
items={[item]}
forceDisable={forceDisable}
transformNodes={transformNodes}
/>
),
available: (item: TransformListRow) => item.stats.state === TRANSFORM_STATE.STOPPED,
enabled: (item: TransformListRow) => !isStartActionDisabled([item], canStartStopTransform),
enabled: (item: TransformListRow) =>
!isStartActionDisabled([item], canStartStopTransform, transformNodes),
description: startActionNameText,
icon: 'play',
type: 'icon',
onClick: (item: TransformListRow) => openModal([item]),
'data-test-subj': 'transformActionStart',
}),
[canStartStopTransform, forceDisable]
[canStartStopTransform, forceDisable, transformNodes]
);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jest.mock('../../../../../shared_imports');

describe('Transform: Transform List <CreateTransformButton />', () => {
test('Minimal initialization', () => {
const wrapper = shallow(<CreateTransformButton onClick={jest.fn()} />);
const wrapper = shallow(<CreateTransformButton onClick={jest.fn()} transformNodes={1} />);

expect(wrapper).toMatchSnapshot();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,20 @@ import {

interface CreateTransformButtonProps {
onClick: MouseEventHandler<HTMLButtonElement>;
transformNodes: number;
}

export const CreateTransformButton: FC<CreateTransformButtonProps> = ({ onClick }) => {
export const CreateTransformButton: FC<CreateTransformButtonProps> = ({
onClick,
transformNodes,
}) => {
const { capabilities } = useContext(AuthorizationContext);

const disabled =
!capabilities.canCreateTransform ||
!capabilities.canPreviewTransform ||
!capabilities.canStartStopTransform;
!capabilities.canStartStopTransform ||
transformNodes === 0;

const createTransformButton = (
<EuiButton
Expand All @@ -45,7 +50,12 @@ export const CreateTransformButton: FC<CreateTransformButtonProps> = ({ onClick

if (disabled) {
return (
<EuiToolTip position="top" content={createCapabilityFailureMessage('canCreateTransform')}>
<EuiToolTip
position="top"
content={createCapabilityFailureMessage(
transformNodes > 0 ? 'canCreateTransform' : 'noTransformNodes'
)}
>
{createTransformButton}
</EuiToolTip>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ describe('Transform: Transform List <TransformList />', () => {
test('Minimal initialization', () => {
const wrapper = shallow(
<TransformList
errorMessage={undefined}
isInitialized={true}
onCreateTransform={jest.fn()}
transformNodes={1}
transforms={[]}
transformsLoading={false}
/>
Expand Down
Loading