Skip to content

Commit

Permalink
[Fleet APM Integration] static Java agent version list becomes stale …
Browse files Browse the repository at this point in the history
…quickly (#131759)

* changing version field to text input

* disable save button

* fixing storybook

* adding doc links

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
cauemarcondes and kibanamachine authored May 11, 2022
1 parent c0e03c8 commit 15ca113
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 111 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,8 @@
* 2.0.
*/

import {
htmlIdGenerator,
euiDragDropReorder,
DropResult,
EuiComboBoxOptionOption,
} from '@elastic/eui';
import React, { useState, useCallback, ReactNode } from 'react';
import { htmlIdGenerator, euiDragDropReorder, DropResult } from '@elastic/eui';
import React, { useState, useCallback, ReactNode, useEffect } from 'react';
import { RuntimeAttachment as RuntimeAttachmentStateless } from './runtime_attachment';

export const STAGED_DISCOVERY_RULE_ID = 'STAGED_DISCOVERY_RULE_ID';
Expand Down Expand Up @@ -42,8 +37,8 @@ interface Props {
initialIsEnabled?: boolean;
initialDiscoveryRules?: IDiscoveryRule[];
operationTypes: Operation[];
selectedVersion: string;
versions: string[];
version: RuntimeAttachmentSettings['version'];
invalidatePackagePolicy: () => void;
}

interface Option {
Expand All @@ -58,8 +53,11 @@ export interface Operation {
}

const versionRegex = new RegExp(/^\d+\.\d+\.\d+$/);
function validateVersion(version: string) {
return versionRegex.test(version);
export function validateVersion(version: RuntimeAttachmentSettings['version']) {
if (version) {
return versionRegex.test(version);
}
return false;
}

export function RuntimeAttachment(props: Props) {
Expand All @@ -75,10 +73,24 @@ export function RuntimeAttachment(props: Props) {
const [editDiscoveryRuleId, setEditDiscoveryRuleId] = useState<null | string>(
null
);
const [version, setVersion] = useState(props.selectedVersion);
const [versions, setVersions] = useState(props.versions);
const [version, setVersion] = useState<RuntimeAttachmentSettings['version']>(
props.version
);
const [isValidVersion, setIsValidVersion] = useState(
validateVersion(version)
validateVersion(props.version)
);

useEffect(
() => {
// Invalidates the package policy, so save button is disabled
// until a valid version is provided
if (isEnabled && !isValidVersion) {
props.invalidatePackagePolicy();
}
},
// props shouldn't be listed as dependency here
// eslint-disable-next-line react-hooks/exhaustive-deps
[isEnabled, isValidVersion]
);

const onToggleEnable = useCallback(() => {
Expand Down Expand Up @@ -250,11 +262,14 @@ export function RuntimeAttachment(props: Props) {
[isEnabled, discoveryRuleList, onChange, version]
);

function onChangeVersion(nextVersion?: string) {
if (!nextVersion) {
function onChangeVersion(nextVersion: RuntimeAttachmentSettings['version']) {
const isNextVersionValid = validateVersion(nextVersion);
setIsValidVersion(isNextVersionValid);
setVersion(nextVersion);

if (!isNextVersionValid) {
return;
}
setVersion(nextVersion);
onChange({
enabled: isEnabled,
discoveryRules: isEnabled
Expand All @@ -264,29 +279,6 @@ export function RuntimeAttachment(props: Props) {
});
}

function onCreateNewVersion(
newVersion: string,
flattenedOptions: Array<EuiComboBoxOptionOption<string>>
) {
const normalizedNewVersion = newVersion.trim().toLowerCase();
const isNextVersionValid = validateVersion(normalizedNewVersion);
setIsValidVersion(isNextVersionValid);
if (!normalizedNewVersion || !isNextVersionValid) {
return;
}

// Create the option if it doesn't exist.
if (
flattenedOptions.findIndex(
(option) => option.label.trim().toLowerCase() === normalizedNewVersion
) === -1
) {
setVersions([...versions, newVersion]);
}

onChangeVersion(newVersion);
}

return (
<RuntimeAttachmentStateless
isEnabled={isEnabled}
Expand All @@ -310,15 +302,8 @@ export function RuntimeAttachment(props: Props) {
discoveryRulesDescription={props.discoveryRulesDescription}
showUnsavedWarning={props.showUnsavedWarning}
onDragEnd={onDragEnd}
selectedVersion={version}
versions={versions}
onChangeVersion={(selectedVersions) => {
const nextVersion: string | undefined = selectedVersions[0]?.label;
const isNextVersionValid = validateVersion(nextVersion);
setIsValidVersion(isNextVersionValid);
onChangeVersion(nextVersion);
}}
onCreateNewVersion={onCreateNewVersion}
version={version}
onChangeVersion={onChangeVersion}
isValidVersion={isValidVersion}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ const excludeOptions = [
];
const includeOptions = [{ value: 'all', label: 'All' }, ...excludeOptions];

const versions = ['1.27.1', '1.27.0', '1.26.0', '1.25.0'];

export const RuntimeAttachmentExample: Story = () => {
const [runtimeAttachmentSettings, setRuntimeAttachmentSettings] = useState(
{}
);
const [isEnabled, setIsEnabled] = useState(true);
return (
<>
<RuntimeAttachment
Expand All @@ -57,7 +56,7 @@ export const RuntimeAttachmentExample: Story = () => {
toggleDescription="Attach the Java agent to running and starting Java applications."
discoveryRulesDescription="For every running JVM, the discovery rules are evaluated in the order they are provided. The first matching rule determines the outcome. Learn more in the docs"
showUnsavedWarning={true}
initialIsEnabled={true}
initialIsEnabled={isEnabled}
initialDiscoveryRules={[
{
operation: 'include',
Expand All @@ -70,8 +69,10 @@ export const RuntimeAttachmentExample: Story = () => {
probe: '10948653898867',
},
]}
versions={versions}
selectedVersion={versions[0]}
version={null}
invalidatePackagePolicy={() => {
setIsEnabled(false);
}}
/>
<hr />
<pre>{JSON.stringify(runtimeAttachmentSettings, null, 4)}</pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@ import {
EuiDraggable,
EuiIcon,
DropResult,
EuiComboBox,
EuiComboBoxProps,
EuiFormRow,
EuiFieldText,
EuiLink,
} from '@elastic/eui';
import React, { ReactNode } from 'react';
import { i18n } from '@kbn/i18n';
import { isEmpty } from 'lodash';
import { FormattedMessage } from '@kbn/i18n-react';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { DiscoveryRule } from './discovery_rule';
import { DefaultDiscoveryRule } from './default_discovery_rule';
import { EditDiscoveryRule } from './edit_discovery_rule';
import { IDiscoveryRuleList, Operation } from '.';
import { IDiscoveryRuleList, Operation, RuntimeAttachmentSettings } from '.';

interface Props {
isEnabled: boolean;
Expand All @@ -51,10 +54,8 @@ interface Props {
discoveryRulesDescription: ReactNode;
showUnsavedWarning?: boolean;
onDragEnd: (dropResult: DropResult) => void;
selectedVersion: string;
versions: string[];
onChangeVersion: EuiComboBoxProps<string>['onChange'];
onCreateNewVersion: EuiComboBoxProps<string>['onCreateOption'];
version: RuntimeAttachmentSettings['version'];
onChangeVersion: (nextVersion: RuntimeAttachmentSettings['version']) => void;
isValidVersion: boolean;
}

Expand All @@ -80,12 +81,13 @@ export function RuntimeAttachment({
discoveryRulesDescription,
showUnsavedWarning,
onDragEnd,
selectedVersion,
versions,
version,
onChangeVersion,
onCreateNewVersion,
isValidVersion,
}: Props) {
const {
services: { docLinks },
} = useKibana();
return (
<div>
{showUnsavedWarning && (
Expand Down Expand Up @@ -120,7 +122,7 @@ export function RuntimeAttachment({
<p>{toggleDescription}</p>
</EuiText>
</EuiFlexItem>
{isEnabled && versions && (
{isEnabled && (
<EuiFlexItem>
<EuiFormRow
label={i18n.translate(
Expand All @@ -132,18 +134,36 @@ export function RuntimeAttachment({
'xpack.apm.fleetIntegration.apmAgent.runtimeAttachment.version.invalid',
{ defaultMessage: 'Invalid version' }
)}
helpText={
<FormattedMessage
id="xpack.apm.fleetIntegration.apmAgent.runtimeAttachment.version.helpText"
defaultMessage="Enter the {versionLink} of the Elastic APM Java agent that should be attached."
values={{
versionLink: (
<EuiLink
href={`${docLinks?.ELASTIC_WEBSITE_URL}/guide/en/apm/agent/java/current/release-notes.html`}
target="_blank"
>
{i18n.translate(
'xpack.apm.fleetIntegration.apmAgent.runtimeAttachment.version.helpText.version',
{ defaultMessage: 'version' }
)}
</EuiLink>
),
}}
/>
}
>
<EuiComboBox
selectedOptions={[{ label: selectedVersion }]}
<EuiFieldText
value={version || ''}
onChange={(e) => {
const nextVersion = e.target.value;
onChangeVersion(isEmpty(nextVersion) ? null : nextVersion);
}}
placeholder={i18n.translate(
'xpack.apm.fleetIntegration.apmAgent.runtimeAttachment.version.placeHolder',
{ defaultMessage: 'Select or add a version' }
{ defaultMessage: 'Add a version' }
)}
options={versions.map((_version) => ({ label: _version }))}
onChange={onChangeVersion}
onCreateOption={onCreateNewVersion}
singleSelection
isClearable={false}
/>
</EuiFormRow>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
RuntimeAttachment,
RuntimeAttachmentSettings,
IDiscoveryRule,
validateVersion,
} from '..';
import type {
NewPackagePolicy,
Expand Down Expand Up @@ -85,39 +86,6 @@ const includeOptions = [
...excludeOptions,
];

const versions = [
'1.27.1',
'1.27.0',
'1.26.0',
'1.25.0',
'1.24.0',
'1.23.0',
'1.22.0',
'1.21.0',
'1.20.0',
'1.19.0',
'1.18.1',
'1.18.0',
'1.18.0.RC1',
'1.17.0',
'1.16.0',
'1.15.0',
'1.14.0',
'1.13.0',
'1.12.0',
'1.11.0',
'1.10.0',
'1.9.0',
'1.8.0',
'1.7.0',
'1.6.1',
'1.6.0',
'1.5.0',
'1.4.0',
'1.3.0',
'1.2.0',
];

function getApmVars(newPolicy: NewPackagePolicy) {
return newPolicy.inputs.find(({ type }) => type === 'apm')?.vars;
}
Expand All @@ -130,7 +98,7 @@ export function JavaRuntimeAttachment({ newPolicy, onChange }: Props) {
({ type }) => type === 'apm'
);
onChange({
isValid: true,
isValid: validateVersion(runtimeAttachmentSettings.version),
updatedPolicy: {
...newPolicy,
inputs: [
Expand Down Expand Up @@ -164,6 +132,10 @@ export function JavaRuntimeAttachment({ newPolicy, onChange }: Props) {
[newPolicy, onChange]
);

function invalidatePackagePolicy() {
onChange({ isValid: false, updatedPolicy: newPolicy });
}

const apmVars = useMemo(() => getApmVars(newPolicy), [newPolicy]);

return (
Expand Down Expand Up @@ -223,10 +195,8 @@ export function JavaRuntimeAttachment({ newPolicy, onChange }: Props) {
apmVars?.java_attacher_discovery_rules?.value ?? '[]\n',
[initialDiscoveryRule]
)}
selectedVersion={
apmVars?.java_attacher_agent_version?.value || versions[0]
}
versions={versions}
version={apmVars?.java_attacher_agent_version?.value || null}
invalidatePackagePolicy={invalidatePackagePolicy}
/>
);
}
Expand Down

0 comments on commit 15ca113

Please sign in to comment.