This is an automated email from the ASF dual-hosted git repository.
dockerzhang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/inlong.git
The following commit(s) were added to refs/heads/master by this push:
new 45cd578a7 [INLONG-7211][Dashboard] Support Redis sink (#7212)
45cd578a7 is described below
commit 45cd578a7c2cddda933714cac939051db6a740ee
Author: feat <[email protected]>
AuthorDate: Wed Jan 11 15:37:42 2023 +0800
[INLONG-7211][Dashboard] Support Redis sink (#7212)
---
inlong-dashboard/src/locales/cn.json | 21 ++
inlong-dashboard/src/locales/en.json | 21 ++
inlong-dashboard/src/metas/sinks/defaults/Redis.ts | 330 +++++++++++++++++++++
inlong-dashboard/src/metas/sinks/defaults/index.ts | 5 +
4 files changed, 377 insertions(+)
diff --git a/inlong-dashboard/src/locales/cn.json
b/inlong-dashboard/src/locales/cn.json
index d9a47c92e..cd390a65b 100644
--- a/inlong-dashboard/src/locales/cn.json
+++ b/inlong-dashboard/src/locales/cn.json
@@ -303,6 +303,27 @@
"meta.Sinks.StarRocks.IsMetaField": "是否为元字段",
"meta.Sinks.StarRocks.FieldFormat": "字段格式",
"meta.Sinks.StarRocks.FieldDescription": "字段描述",
+ "meta.Sinks.Redis.clusterModeHelp": "Redis 集群模式, 可为
[cluster|sentinel|standalone]",
+ "meta.Sinks.Redis.ttlUnit": "秒",
+ "meta.Sinks.Redis.FieldName": "字段名",
+ "meta.Sinks.Redis.FieldNameRule": "以英文字母或下划线开头,只能包含英文字母、数字、下划线",
+ "meta.Sinks.Redis.FieldType": "字段类型",
+ "meta.Sinks.Redis.IsMetaField": "是否为元字段",
+ "meta.Sinks.Redis.FieldFormat": "字段格式",
+ "meta.Sinks.Redis.FieldDescription": "字段描述",
+ "meta.Sinks.Redis.clusterMode": "集群模式",
+ "meta.Sinks.Redis.database": "DatabaseID",
+ "meta.Sinks.Redis.password": "密码",
+ "meta.Sinks.Redis.ttl": "TTL",
+ "meta.Sinks.Redis.ExtList": "高级参数",
+ "meta.Sinks.Redis.Timeout": "超时时间",
+ "meta.Sinks.Redis.SoTimeout": "读取超时时间",
+ "meta.Sinks.Redis.MaxTotal": "最大连接数",
+ "meta.Sinks.Redis.MaxIdle": "最大空闲连接数",
+ "meta.Sinks.Redis.MinIdle": "最小空闲连接数",
+ "meta.Sinks.Redis.maxRetries": "最大重试次数",
+ "meta.Sinks.Redis.dataType": "数据类型",
+ "meta.Sinks.Redis.schemaMapMode": "Schema映射模式",
"meta.Group.InlongGroupId": "数据流组 ID",
"meta.Group.InlongGroupIdRules": "只能包含小写字母、数字、中划线、下划线",
"meta.Group.InlongGroupName": "数据流组名称",
diff --git a/inlong-dashboard/src/locales/en.json
b/inlong-dashboard/src/locales/en.json
index 4279632fd..a9a1883e5 100644
--- a/inlong-dashboard/src/locales/en.json
+++ b/inlong-dashboard/src/locales/en.json
@@ -303,6 +303,27 @@
"meta.Sinks.StarRocks.IsMetaField": "IsMetaField",
"meta.Sinks.StarRocks.FieldFormat": "FieldFormat",
"meta.Sinks.StarRocks.FieldDescription": "FieldDescription",
+ "meta.Sinks.Redis.clusterModeHelp": "Redis cluster mode, contains
[cluster|sentinel|standalone]",
+ "meta.Sinks.Redis.ttlUnit": "s",
+ "meta.Sinks.Redis.FieldName": "FieldName",
+ "meta.Sinks.Redis.FieldNameRule": "At the beginning of English letters, only
English letters, numbers, and underscores",
+ "meta.Sinks.Redis.FieldType": "FieldType",
+ "meta.Sinks.Redis.IsMetaField": "IsMetaField",
+ "meta.Sinks.Redis.FieldFormat": "FieldFormat",
+ "meta.Sinks.Redis.FieldDescription": "FieldDescription",
+ "meta.Sinks.Redis.clusterMode": "ClusterMode",
+ "meta.Sinks.Redis.database": "DatabaseID",
+ "meta.Sinks.Redis.password": "Password",
+ "meta.Sinks.Redis.ttl": "TTL",
+ "meta.Sinks.Redis.ExtList": "ExtList",
+ "meta.Sinks.Redis.Timeout": "TimeOut",
+ "meta.Sinks.Redis.SoTimeout": "SoTimeout",
+ "meta.Sinks.Redis.MaxTotal": "Max Total",
+ "meta.Sinks.Redis.MaxIdle": "Max Idle",
+ "meta.Sinks.Redis.MinIdle": "Min Idle",
+ "meta.Sinks.Redis.maxRetries": "Max Retries",
+ "meta.Sinks.Redis.dataType": "Data Type",
+ "meta.Sinks.Redis.schemaMapMode": "Schema Map Mode",
"meta.Group.InlongGroupId": "Inlong Group ID",
"meta.Group.InlongGroupIdRules": "Only lowercase letters, numbers, minus,
and underscores",
"meta.Group.InlongGroupName": "Inlong Group Name",
diff --git a/inlong-dashboard/src/metas/sinks/defaults/Redis.ts
b/inlong-dashboard/src/metas/sinks/defaults/Redis.ts
new file mode 100644
index 000000000..1fe911331
--- /dev/null
+++ b/inlong-dashboard/src/metas/sinks/defaults/Redis.ts
@@ -0,0 +1,330 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { DataWithBackend } from '@/metas/DataWithBackend';
+import { RenderRow } from '@/metas/RenderRow';
+import { RenderList } from '@/metas/RenderList';
+import i18n from '@/i18n';
+import EditableTable from '@/components/EditableTable';
+import { sourceFields } from '../common/sourceFields';
+import { SinkInfo } from '../common/SinkInfo';
+
+const { I18n } = DataWithBackend;
+const { FieldDecorator } = RenderRow;
+const { ColumnDecorator } = RenderList;
+
+const redisTargetTypes = [
+ 'BOOLEAN',
+ 'INT',
+ 'BIGINT',
+ 'FLOAT',
+ 'DOUBLE',
+ 'DATE',
+ 'DATETIME',
+ 'CHAR',
+ 'TIME',
+].map(item => ({
+ label: item,
+ value: item,
+}));
+
+export default class RedisSink extends SinkInfo implements DataWithBackend,
RenderRow, RenderList {
+ @FieldDecorator({
+ type: 'select',
+ rules: [{ required: true }],
+ initialValue: 0,
+ tooltip: i18n.t('meta.Sinks.Redis.clusterModeHelp'),
+ props: values => ({
+ disabled: [110, 130].includes(values?.status),
+ options: [
+ {
+ label: 'cluster',
+ value: 'cluster',
+ },
+ {
+ label: 'sentinel',
+ value: 'sentinel',
+ },
+ {
+ label: 'standalone',
+ value: 'standalone',
+ },
+ ],
+ }),
+ })
+ @I18n('meta.Sinks.Redis.clusterMode')
+ clusterMode: string;
+
+ @FieldDecorator({
+ type: 'inputnumber',
+ rules: [{ required: false }],
+ props: values => ({
+ disabled: [110, 130].includes(values?.status),
+ min: 0,
+ }),
+ })
+ @ColumnDecorator()
+ @I18n('meta.Sinks.Redis.database')
+ database: number;
+
+ @FieldDecorator({
+ type: 'select',
+ rules: [{ required: false }],
+ initialValue: 'PLAIN',
+ props: values => ({
+ disabled: [110, 130].includes(values?.status),
+ options: [
+ {
+ label: 'PLAIN',
+ value: 'PLAIN',
+ },
+ {
+ label: 'HASH',
+ value: 'HASH',
+ },
+ {
+ label: 'BITMAP',
+ value: 'BITMAP',
+ },
+ ],
+ }),
+ })
+ @ColumnDecorator()
+ @I18n('meta.Sinks.Redis.dataType')
+ dataType: string;
+
+ @FieldDecorator({
+ type: 'select',
+ rules: [{ required: false }],
+ initialValue: 'STATIC_PREFIX_MATCH',
+ props: values => ({
+ disabled: [110, 130].includes(values?.status),
+ options: [
+ {
+ label: 'STATIC_PREFIX_MATCH',
+ value: 'STATIC_PREFIX_MATCH',
+ },
+ {
+ label: 'STATIC_KV_PAIR',
+ value: 'STATIC_KV_PAIR',
+ },
+ {
+ label: 'DYNAMIC',
+ value: 'DYNAMIC',
+ },
+ ],
+ }),
+ })
+ @ColumnDecorator()
+ @I18n('meta.Sinks.Redis.schemaMapMode')
+ schemaMapMode: string;
+
+ @FieldDecorator({
+ type: 'password',
+ rules: [{ required: false }],
+ initialValue: '',
+ props: values => ({
+ disabled: [110, 130].includes(values?.status),
+ }),
+ })
+ @ColumnDecorator()
+ @I18n('meta.Sinks.Redis.password')
+ password: string;
+
+ @FieldDecorator({
+ type: 'inputnumber',
+ initialValue: 0,
+ props: values => ({
+ disabled: [110, 130].includes(values?.status),
+ min: 1,
+ }),
+ rules: [{ required: true }],
+ suffix: i18n.t('meta.Sinks.Redis.ttlUnit'),
+ })
+ @I18n('meta.Sinks.Redis.ttl')
+ ttl: number;
+
+ @FieldDecorator({
+ type: EditableTable,
+ rules: [{ required: false }],
+ initialValue: [],
+ props: values => ({
+ size: 'small',
+ columns: [
+ {
+ title: 'Key',
+ dataIndex: 'keyName',
+ props: {
+ disabled: [110, 130].includes(values?.status),
+ },
+ },
+ {
+ title: 'Value',
+ dataIndex: 'keyValue',
+ props: {
+ disabled: [110, 130].includes(values?.status),
+ },
+ },
+ ],
+ }),
+ })
+ @ColumnDecorator()
+ @I18n('meta.Sinks.Redis.ExtList')
+ extList: string;
+
+ @FieldDecorator({
+ type: EditableTable,
+ props: values => ({
+ size: 'small',
+ editing: ![110, 130].includes(values?.status),
+ columns: getFieldListColumns(values),
+ }),
+ })
+ sinkFieldList: Record<string, unknown>[];
+
+ @FieldDecorator({
+ type: 'inputnumber',
+ rules: [{ required: true }],
+ props: values => ({
+ disabled: values?.status === 101,
+ }),
+ })
+ @I18n('meta.Sinks.Redis.Timeout')
+ timeout: number;
+
+ @FieldDecorator({
+ type: 'inputnumber',
+ rules: [{ required: true }],
+ props: values => ({
+ disabled: values?.status === 101,
+ }),
+ })
+ @I18n('meta.Sinks.Redis.SoTimeout')
+ soTimeout: number;
+
+ @FieldDecorator({
+ type: 'inputnumber',
+ rules: [{ required: true }],
+ props: values => ({
+ disabled: values?.status === 101,
+ }),
+ })
+ @I18n('meta.Sinks.Redis.MaxTotal')
+ maxTotal: number;
+
+ @FieldDecorator({
+ type: 'inputnumber',
+ rules: [{ required: true }],
+ props: values => ({
+ disabled: values?.status === 101,
+ }),
+ })
+ @I18n('meta.Sinks.Redis.MaxIdle')
+ maxIdle: number;
+
+ @FieldDecorator({
+ type: 'inputnumber',
+ rules: [{ required: true }],
+ props: values => ({
+ disabled: values?.status === 101,
+ }),
+ })
+ @I18n('meta.Sinks.Redis.MinIdle')
+ minIdle: number;
+
+ @FieldDecorator({
+ type: 'inputnumber',
+ rules: [{ required: true }],
+ initialValue: 1,
+ props: values => ({
+ disabled: values?.status === 101,
+ min: 1,
+ }),
+ })
+ @I18n('meta.Sinks.Redis.maxRetries')
+ maxRetries: number;
+}
+
+const getFieldListColumns = sinkValues => {
+ return [
+ ...sourceFields,
+ {
+ title: `Redis${i18n.t('meta.Sinks.Redis.FieldName')}`,
+ dataIndex: 'fieldName',
+ initialValue: '',
+ rules: [
+ { required: true },
+ {
+ pattern: /^[a-z][0-9a-z_]*$/,
+ message: i18n.t('meta.Sinks.Redis.FieldNameRule'),
+ },
+ ],
+ props: (text, record, idx, isNew) => ({
+ disabled: [110, 130].includes(sinkValues?.status as number) && !isNew,
+ }),
+ },
+ {
+ title: `Redis${i18n.t('meta.Sinks.Redis.FieldType')}`,
+ dataIndex: 'fieldType',
+ initialValue: redisTargetTypes[0].value,
+ type: 'select',
+ props: (text, record, idx, isNew) => ({
+ options: redisTargetTypes,
+ disabled: [110, 130].includes(sinkValues?.status as number) && !isNew,
+ }),
+ rules: [{ required: true }],
+ },
+ {
+ title: i18n.t('meta.Sinks.Redis.IsMetaField'),
+ dataIndex: 'isMetaField',
+ initialValue: 0,
+ type: 'select',
+ props: (text, record, idx, isNew) => ({
+ options: [
+ {
+ label: i18n.t('basic.Yes'),
+ value: 1,
+ },
+ {
+ label: i18n.t('basic.No'),
+ value: 0,
+ },
+ ],
+ }),
+ },
+ {
+ title: i18n.t('meta.Sinks.Redis.FieldFormat'),
+ dataIndex: 'fieldFormat',
+ initialValue: 0,
+ type: 'autocomplete',
+ props: (text, record, idx, isNew) => ({
+ options: ['MICROSECONDS', 'MILLISECONDS', 'SECONDS', 'SQL',
'ISO_8601'].map(item => ({
+ label: item,
+ value: item,
+ })),
+ }),
+ visible: (text, record) => ['BIGINT', 'DATE'].includes(record.fieldType
as string),
+ },
+ {
+ title: i18n.t('meta.Sinks.Redis.FieldDescription'),
+ dataIndex: 'fieldComment',
+ initialValue: '',
+ },
+ ];
+};
diff --git a/inlong-dashboard/src/metas/sinks/defaults/index.ts
b/inlong-dashboard/src/metas/sinks/defaults/index.ts
index a19d2d4bb..cb83240d4 100644
--- a/inlong-dashboard/src/metas/sinks/defaults/index.ts
+++ b/inlong-dashboard/src/metas/sinks/defaults/index.ts
@@ -101,4 +101,9 @@ export const allDefaultSinks:
MetaExportWithBackendList<SinkMetaType> = [
value: 'TDSQLPOSTGRESQL',
LoadEntity: () => import('./TDSQLPostgreSQL'),
},
+ {
+ label: 'Redis',
+ value: 'REDIS',
+ LoadEntity: () => import('./Redis'),
+ },
];