Skip to content

Commit

Permalink
feature(frontend): adding enable switch for ingestor for Otel DataSto…
Browse files Browse the repository at this point in the history
…res (#2715)

* feature(frontend): adding enable switch for ingestor for Otel DataStores

* feature(frontend): adding missing url

* feature(frontend): updating enabled ingestor check logic
  • Loading branch information
xoscar committed Jun 13, 2023
1 parent 7b98216 commit da41f03
Show file tree
Hide file tree
Showing 25 changed files with 270 additions and 139 deletions.
2 changes: 1 addition & 1 deletion web/src/components/AnalyzerResult/AnalyzerResult.styled.ts
Expand Up @@ -50,7 +50,7 @@ export const RuleContainer = styled.div`
border-bottom: ${({theme}) => `1px dashed ${theme.color.borderLight}`};
padding-bottom: 16px;
margin-bottom: 16px;
margin-left: 32px;
margin-left: 43px;
`;

export const RuleHeader = styled.div`
Expand Down
@@ -1,7 +1,7 @@
import { Typography } from 'antd';
import styled from 'styled-components';

export const DataStoreDocsBannerContainer = styled.div`
export const DocsBannerContainer = styled.div`
display: flex;
gap: 8px;
align-items: center;
Expand Down
13 changes: 13 additions & 0 deletions web/src/components/DocsBanner/DocsBanner.tsx
@@ -0,0 +1,13 @@
import {ReadOutlined} from '@ant-design/icons';
import * as S from './DocsBanner.styled';

const DocsBanner: React.FC = ({children}) => {
return (
<S.DocsBannerContainer>
<ReadOutlined />
<S.Text>{children}</S.Text>
</S.DocsBannerContainer>
);
};

export default DocsBanner;
2 changes: 2 additions & 0 deletions web/src/components/DocsBanner/index.ts
@@ -0,0 +1,2 @@
// eslint-disable-next-line no-restricted-exports
export {default} from './DocsBanner';
@@ -1,23 +1,19 @@
import {ReadOutlined} from '@ant-design/icons';
import {SupportedDataStoresToDocsLink, SupportedDataStoresToName} from 'constants/DataStore.constants';
import {SupportedDataStores} from 'types/DataStore.types';
import * as S from './DataStoreDocsBanner.styled';
import DocsBanner from 'components/DocsBanner/DocsBanner';

interface IProps {
dataStoreType: SupportedDataStores;
}

const DataStoreDocsBanner = ({dataStoreType}: IProps) => {
return (
<S.DataStoreDocsBannerContainer>
<ReadOutlined />
<S.Text>
Need more information about setting up {SupportedDataStoresToName[dataStoreType]}?{' '}
<a href={SupportedDataStoresToDocsLink[dataStoreType]} target="_blank">
Go to our docs
</a>
</S.Text>
</S.DataStoreDocsBannerContainer>
<DocsBanner>
Need more information about setting up {SupportedDataStoresToName[dataStoreType]}?{' '}
<a href={SupportedDataStoresToDocsLink[dataStoreType]} target="_blank">
Go to our docs
</a>
</DocsBanner>
);
};

Expand Down
Expand Up @@ -78,13 +78,6 @@ export const Title = styled(Typography.Title)`
}
`;

export const Explanation = styled(Typography.Text)`
&& {
color: ${({theme}) => theme.color.textSecondary};
font-size: ${({theme}) => theme.size.md};
}
`;

export const Description = styled(Typography.Text)`
&& {
color: ${({theme}) => theme.color.textSecondary};
Expand Down
22 changes: 10 additions & 12 deletions web/src/components/Settings/DataStoreForm/DataStoreForm.tsx
Expand Up @@ -2,9 +2,8 @@ import {Button, Form} from 'antd';
import {useCallback, useEffect, useMemo} from 'react';
import DataStoreService from 'services/DataStore.service';
import {TDraftDataStore, TDataStoreForm, SupportedDataStores} from 'types/DataStore.types';
import {SupportedDataStoresToExplanation, SupportedDataStoresToName} from 'constants/DataStore.constants';
import {SupportedDataStoresToName} from 'constants/DataStore.constants';
import DataStoreConfig from 'models/DataStoreConfig.model';
import DataStoreDocsBanner from '../DataStoreDocsBanner/DataStoreDocsBanner';
import DataStoreComponentFactory from '../DataStorePlugin/DataStoreComponentFactory';
import * as S from './DataStoreForm.styled';
import DataStoreSelectionInput from './DataStoreSelectionInput';
Expand Down Expand Up @@ -36,11 +35,17 @@ const DataStoreForm = ({
isLoading,
isFormValid,
}: IProps) => {
const initialValues = useMemo(() => DataStoreService.getInitialValues(dataStoreConfig), [dataStoreConfig]);
const configuredDataStoreType = dataStoreConfig.defaultDataStore.type as SupportedDataStores;
const initialValues = useMemo(
() => DataStoreService.getInitialValues(dataStoreConfig, configuredDataStoreType),
[configuredDataStoreType, dataStoreConfig]
);
const dataStoreType = Form.useWatch('dataStoreType', form);

useEffect(() => {
form.setFieldsValue({dataStore: {name: '', type: SupportedDataStores.JAEGER, ...initialValues.dataStore}});
form.setFieldsValue({
dataStore: {name: '', type: SupportedDataStores.JAEGER, ...initialValues.dataStore},
});
}, [dataStoreType, form, initialValues.dataStore]);

const onValidation = useCallback(
Expand All @@ -50,7 +55,6 @@ const DataStoreForm = ({
},
[onIsFormValid]
);
const explanation = SupportedDataStoresToExplanation[dataStoreType!];

return (
<Form<TDraftDataStore>
Expand All @@ -72,12 +76,6 @@ const DataStoreForm = ({
Tracetest needs configuration information to be able to retrieve your trace from your distributed tracing
solution. Select your tracing data store and enter the configuration info.
</S.Description>
{explanation ? (
<S.Explanation>{explanation}</S.Explanation>
) : (
<S.Title>Provide the connection info for {SupportedDataStoresToName[dataStoreType!]}</S.Title>
)}
<DataStoreDocsBanner dataStoreType={dataStoreType!} />
{dataStoreType && <DataStoreComponentFactory dataStoreType={dataStoreType} />}
</S.TopContainer>
<S.ButtonsContainer>
Expand All @@ -93,7 +91,7 @@ const DataStoreForm = ({
Test Connection
</Button>
<Button disabled={!isFormValid} loading={isLoading} type="primary" onClick={() => form.submit()}>
Save
Save and Set as DataStore
</Button>
</S.SaveContainer>
</S.ButtonsContainer>
Expand Down
@@ -1,5 +1,8 @@
import {Checkbox, Col, Form, Input, Row} from 'antd';
import {SupportedDataStores, TDraftDataStore} from 'types/DataStore.types';
import DataStoreDocsBanner from '../../../DataStoreDocsBanner/DataStoreDocsBanner';
import * as S from '../../DataStorePluginForm.styled';
import { SupportedDataStoresToName } from '../../../../../constants/DataStore.constants';

const AwsXRay = () => {
const baseName = ['dataStore', SupportedDataStores.AWSXRay];
Expand All @@ -8,6 +11,8 @@ const AwsXRay = () => {

return (
<>
<S.Title>Provide the connection info for {SupportedDataStoresToName[SupportedDataStores.AWSXRay]}</S.Title>
<DataStoreDocsBanner dataStoreType={SupportedDataStores.AWSXRay} />
<Row gutter={[16, 16]}>
<Col span={12}>
<Form.Item name={[...baseName, 'useDefaultAuth']} valuePropName="checked">
Expand Down
@@ -1,8 +1,9 @@
import {Checkbox, Col, Form, Input, Radio, Row} from 'antd';
import {ConnectionTypes, SupportedDataStores, TDraftDataStore} from 'types/DataStore.types';
import * as S from 'components/Settings/DataStoreForm/DataStoreForm.styled';
import {collectorExplanation} from 'constants/DataStore.constants';
import {SupportedDataStoresToName} from 'constants/DataStore.constants';
import OpenTelemetryCollector from '../OpenTelemetryCollector/OpenTelemetryCollector';
import * as S from '../../DataStorePluginForm.styled';
import DataStoreDocsBanner from '../../../DataStoreDocsBanner/DataStoreDocsBanner';

const AzureAppInsights = () => {
const baseName = ['dataStore', SupportedDataStores.AzureAppInsights];
Expand All @@ -23,8 +24,12 @@ const AzureAppInsights = () => {
</Form.Item>
</Col>
</Row>
{(connectionType === ConnectionTypes.Direct && (
{(connectionType === ConnectionTypes.Collector && <OpenTelemetryCollector />) || (
<>
<S.Title>
Provide the connection info for {SupportedDataStoresToName[SupportedDataStores.AzureAppInsights]}
</S.Title>
<DataStoreDocsBanner dataStoreType={SupportedDataStores.AzureAppInsights} />
<Row gutter={[16, 16]}>
<Col span={16}>
<Form.Item
Expand Down Expand Up @@ -55,20 +60,6 @@ const AzureAppInsights = () => {
</Col>
</Row>
</>
)) || (
<>
<Row gutter={[16, 16]}>
<Col span={16}>
<S.Explanation>{collectorExplanation}</S.Explanation>
</Col>
</Row>

<Row gutter={[16, 16]}>
<Col span={16}>
<OpenTelemetryCollector />
</Col>
</Row>
</>
)}
</>
);
Expand Down
@@ -1,5 +1,5 @@
import {Col, Form, Radio, Row} from 'antd';
import {SupportedClientTypes, TDraftDataStore} from 'types/DataStore.types';
import {SupportedClientTypes, SupportedDataStores, TDraftDataStore} from 'types/DataStore.types';
import GrpcClient from '../GrpcClient';
import HttpClient from '../HttpClient';

Expand All @@ -10,7 +10,7 @@ const FieldsFormMap = {

const BaseClient = () => {
const form = Form.useFormInstance<TDraftDataStore>();
const dataStoreType = form.getFieldValue('dataStoreType');
const dataStoreType = form.getFieldValue('dataStoreType') as SupportedDataStores;
const baseName = ['dataStore', dataStoreType];
const type = (Form.useWatch([...baseName, 'type'], form) || SupportedClientTypes.GRPC) as SupportedClientTypes;
const Component = FieldsFormMap[type];
Expand Down
@@ -1,10 +1,11 @@
import {Checkbox, Col, Form, Input, Row} from 'antd';

import RequestDetailsFileInput from 'components/CreateTestPlugins/Grpc/steps/RequestDetails/RequestDetailsFileInput';
import {SupportedDataStoresToDefaultEndpoint} from 'constants/DataStore.constants';
import {SupportedDataStoresToDefaultEndpoint, SupportedDataStoresToName} from 'constants/DataStore.constants';
import {SupportedDataStores, TDraftDataStore} from 'types/DataStore.types';
import * as S from '../../DataStorePluginForm.styled';
import AddressesList from './AddressesList';
import DataStoreDocsBanner from '../../../DataStoreDocsBanner/DataStoreDocsBanner';

const OpenSearch = () => {
const form = Form.useFormInstance<TDraftDataStore>();
Expand All @@ -14,6 +15,8 @@ const OpenSearch = () => {

return (
<>
<S.Title>Provide the connection info for {SupportedDataStoresToName[dataStoreType]}</S.Title>
<DataStoreDocsBanner dataStoreType={dataStoreType} />
<Row gutter={[16, 16]}>
<Col span={12}>
<Form.Item
Expand Down
@@ -1,12 +1,13 @@
import {Checkbox, Col, Form, Input, Row, Select, Space, Switch} from 'antd';
import {useCallback} from 'react';
import {SupportedDataStoresToDefaultEndpoint} from 'constants/DataStore.constants';
import {SupportedDataStoresToDefaultEndpoint, SupportedDataStoresToName} from 'constants/DataStore.constants';
import {useDataStore} from 'providers/DataStore/DataStore.provider';
import DataStoreService from 'services/DataStore.service';
import {SupportedDataStores, TDraftDataStore} from 'types/DataStore.types';
import * as FS from '../../DataStorePluginForm.styled';
import * as S from './GrcpClient.styled';
import GrpcClientSecure from './GrpcClientSecure';
import DataStoreDocsBanner from '../../../DataStoreDocsBanner/DataStoreDocsBanner';

const COMPRESSION_LIST = [
{name: 'none', value: 'none'},
Expand Down Expand Up @@ -36,6 +37,8 @@ const GrpcClient = () => {

return (
<>
<FS.Title>Provide the connection info for {SupportedDataStoresToName[dataStoreType]}</FS.Title>
<DataStoreDocsBanner dataStoreType={dataStoreType} />
<Row gutter={[16, 16]}>
<Col span={12}>
<Form.Item
Expand Down
@@ -1,18 +1,22 @@
import {Checkbox, Col, Form, Input, Row, Space, Switch} from 'antd';
import {TDraftDataStore} from 'types/DataStore.types';
import {SupportedDataStores, TDraftDataStore} from 'types/DataStore.types';
import {SupportedDataStoresToName} from 'constants/DataStore.constants';
import GrpcClientSecure from '../GrpcClient/GrpcClientSecure';
import * as S from '../../DataStorePluginForm.styled';
import DataStoreDocsBanner from '../../../DataStoreDocsBanner/DataStoreDocsBanner';

const HEADER_DEFAULT_VALUES = [{key: '', value: ''}];

const HttpClient = () => {
const form = Form.useFormInstance<TDraftDataStore>();
const dataStoreType = form.getFieldValue('dataStoreType');
const dataStoreType = form.getFieldValue('dataStoreType') as SupportedDataStores;
const baseName = ['dataStore', dataStoreType, 'http'];
const insecureValue = Form.useWatch([...baseName, 'tls', 'insecure'], form) ?? true;

return (
<>
<S.Title>Provide the connection info for {SupportedDataStoresToName[dataStoreType]}</S.Title>
<DataStoreDocsBanner dataStoreType={dataStoreType} />
<Row gutter={[16, 16]}>
<Col span={12}>
<Form.Item label="URL" name={[...baseName, 'url']} rules={[{required: true, message: 'URL is required'}]}>
Expand Down
@@ -0,0 +1,44 @@
import {Form} from 'antd';
import SyntaxHighlighter from 'react-syntax-highlighter';
import {arduinoLight} from 'react-syntax-highlighter/dist/cjs/styles/hljs';
import useCopy from 'hooks/useCopy';
import {CollectorConfigMap} from 'constants/CollectorConfig.constants';
import {TCollectorDataStores, TDraftDataStore} from 'types/DataStore.types';
import * as S from '../../DataStorePluginForm.styled';
import * as OtelCollectorStyles from './OpenTelemetryCollector.styled';
import DataStoreDocsBanner from '../../../DataStoreDocsBanner/DataStoreDocsBanner';

const Configuration = () => {
const copy = useCopy();
const form = Form.useFormInstance<TDraftDataStore>();
const dataStoreType = Form.useWatch('dataStoreType', form) as TCollectorDataStores;
const example = CollectorConfigMap[dataStoreType!];

return (
<>
<OtelCollectorStyles.SubtitleContainer>
<OtelCollectorStyles.Title>OpenTelemetry Collector Configuration</OtelCollectorStyles.Title>
<OtelCollectorStyles.Description>
The OpenTelemetry Collector configuration below is a sample. Your config file layout should look the same.
Make sure to use your own API keys or tokens as explained. Copy the config sample below, paste it into your
own OpenTelemetry Collector config and apply it.
</OtelCollectorStyles.Description>
</OtelCollectorStyles.SubtitleContainer>
<S.FormContainer>
<S.FormColumn>
<OtelCollectorStyles.CodeContainer data-cy="file-viewer-code-container">
<OtelCollectorStyles.CopyIconContainer onClick={() => copy(example)}>
<OtelCollectorStyles.CopyIcon />
</OtelCollectorStyles.CopyIconContainer>
<SyntaxHighlighter language="yaml" style={arduinoLight}>
{example}
</SyntaxHighlighter>
</OtelCollectorStyles.CodeContainer>
</S.FormColumn>
</S.FormContainer>
<DataStoreDocsBanner dataStoreType={dataStoreType} />
</>
);
};

export default Configuration;
@@ -0,0 +1,40 @@
import {Form, Switch} from 'antd';
import DocsBanner from 'components/DocsBanner/DocsBanner';
import {INGESTOR_ENDPOINT_URL} from 'constants/Common.constants';
import {TCollectorDataStores, TDraftDataStore} from 'types/DataStore.types';
import * as S from './OpenTelemetryCollector.styled';

const Ingestor = () => {
const form = Form.useFormInstance<TDraftDataStore>();
const dataStoreType = Form.useWatch('dataStoreType', form) as TCollectorDataStores;
const baseName = ['dataStore', dataStoreType];

return (
<S.Container>
<S.Description>
Tracetest easily integrates with any distributed tracing solution via the OpenTelemetry Collector. It allows
your current tracing system to send only Tracetest spans while the rest go to your chosen backend.
</S.Description>
<S.Title>Ingestor Endpoint</S.Title>
<S.Description>
Tracetest exposes trace ingestion endpoints on ports 4317 for gRPC and 4318 for HTTP. Turn on the Tracetest
ingestion endpoint to start sending traces. Use the Tracetest Server’s hostname and port to connect.For example,
with Docker use tracetest:4317 for gRPC.
</S.Description>
<S.SwitchContainer>
<Form.Item name={[...baseName, 'isIngestorEnabled']} valuePropName="checked">
<Switch />
</Form.Item>
Enable Tracetest ingestion endpoint
</S.SwitchContainer>
<DocsBanner>
Need more information about setting up ingestion endpoint?{' '}
<a target="_blank" href={INGESTOR_ENDPOINT_URL}>
Go to our docs
</a>
</DocsBanner>
</S.Container>
);
};

export default Ingestor;

0 comments on commit da41f03

Please sign in to comment.