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 82276c636 [INLONG-7238][Dashboard] Support cascading of redis cluster 
/ data-type and format configuration (#7239)
82276c636 is described below

commit 82276c636d9b627d8b97dbbfb6305766deed747e
Author: feat <[email protected]>
AuthorDate: Wed Jan 18 01:11:04 2023 +0800

    [INLONG-7238][Dashboard] Support cascading of redis cluster / data-type and 
format configuration (#7239)
    
    Co-authored-by: Charles Zhang <[email protected]>
---
 inlong-dashboard/src/locales/cn.json               |  34 ++-
 inlong-dashboard/src/locales/en.json               |  20 ++
 inlong-dashboard/src/metas/sinks/defaults/Redis.ts | 326 +++++++++++++++++----
 3 files changed, 311 insertions(+), 69 deletions(-)

diff --git a/inlong-dashboard/src/locales/cn.json 
b/inlong-dashboard/src/locales/cn.json
index 575769d1a..5640a53cb 100644
--- a/inlong-dashboard/src/locales/cn.json
+++ b/inlong-dashboard/src/locales/cn.json
@@ -311,19 +311,39 @@
   "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.ClusterMode": "集群模式",
+  "meta.Sinks.Redis.Database": "DatabaseID",
+  "meta.Sinks.Redis.Password": "密码",
+  "meta.Sinks.Redis.Ttl": "TTL",
+  "meta.Sinks.Redis.TtlUnit": "秒",
   "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.Sinks.Redis.MaxRetries": "最大重试次数",
+  "meta.Sinks.Redis.DataType": "数据类型",
+  "meta.Sinks.Redis.SchemaMapMode": "Schema 映射模式",
+  "meta.Sinks.Redis.Host": "Host",
+  "meta.Sinks.Redis.Port": "端口",
+  "meta.Sinks.Redis.SentinelMasterName": "主节点名称",
+  "meta.Sinks.Redis.SentinelsInfo": "哨兵信息",
+  "meta.Sinks.Redis.ClusterNodes": "集群节点",
+  "meta.Sinks.Redis.TimeoutUnit": "秒",
+  "meta.Sinks.Redis.SoTimeoutUnit": "秒",
+  "meta.Sinks.Redis.ClusterModeHelper": "请选择 Redis 集群模式",
+  "meta.Sinks.Redis.PortHelper": "请设置Redis服务器的端口, 默认: 6379",
+  "meta.Sinks.Redis.FormatDataType": "数据格式",
+  "meta.Sinks.Redis.FormatIgnoreParseError": "忽略数据解析错误",
+  "meta.Sinks.Redis.FormatDataEncoding": "数据编码",
+  "meta.Sinks.Redis.DataSeparator.Space": "空格",
+  "meta.Sinks.Redis.DataSeparator.VerticalLine": "竖线(|)",
+  "meta.Sinks.Redis.DataSeparator.Comma": "逗号(,)",
+  "meta.Sinks.Redis.DataSeparator.Semicolon": "分号(;)",
+  "meta.Sinks.Redis.DataSeparator.Asterisk": "星号(*)",
+  "meta.Sinks.Redis.DataSeparator.DoubleQuotes": "双引号(\")",
+  "meta.Sinks.Redis.FormatDataSeparator": "数据字段分隔符",
   "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 8e8fb2046..116fbb94a 100644
--- a/inlong-dashboard/src/locales/en.json
+++ b/inlong-dashboard/src/locales/en.json
@@ -315,6 +315,7 @@
   "meta.Sinks.Redis.database": "DatabaseID",
   "meta.Sinks.Redis.password": "Password",
   "meta.Sinks.Redis.ttl": "TTL",
+  "meta.Sinks.Redis.TtlUnit": "s",
   "meta.Sinks.Redis.ExtList": "ExtList",
   "meta.Sinks.Redis.Timeout": "TimeOut",
   "meta.Sinks.Redis.SoTimeout": "SoTimeout",
@@ -324,6 +325,25 @@
   "meta.Sinks.Redis.maxRetries": "Max Retries",
   "meta.Sinks.Redis.dataType": "Data Type",
   "meta.Sinks.Redis.schemaMapMode": "Schema Map Mode",
+  "meta.Sinks.Redis.Host": "Host",
+  "meta.Sinks.Redis.Port": "port",
+  "meta.Sinks.Redis.SentinelMasterName": "Sentinel Master",
+  "meta.Sinks.Redis.SentinelsInfo": "Sentinels Info",
+  "meta.Sinks.Redis.ClusterNodes": "Cluster Nodes",
+  "meta.Sinks.Redis.TimeoutUnit": "s",
+  "meta.Sinks.Redis.SoTimeoutUnit": "s",
+  "meta.Sinks.Redis.ClusterModeHelper": "Please select Cluster Mode",
+  "meta.Sinks.Redis.PortHelper": "Please select Redis server port, default: 
6379",
+  "meta.Sinks.Redis.FormatDataType": "Format data type",
+  "meta.Sinks.Redis.FormatIgnoreParseError": "Ignore parse error",
+  "meta.Sinks.Redis.FormatDataEncoding": "Data encoding",
+  "meta.Sinks.Redis.DataSeparator.Space": "Space",
+  "meta.Sinks.Redis.DataSeparator.VerticalLine": "Vertical line (|)",
+  "meta.Sinks.Redis.DataSeparator.Comma": "Comma(,)",
+  "meta.Sinks.Redis.DataSeparator.Semicolon": "Semicolon(;)",
+  "meta.Sinks.Redis.DataSeparator.Asterisk": "Asterisk(*)",
+  "meta.Sinks.Redis.DataSeparator.DoubleQuotes": "Double quotes(\")",
+  "meta.Sinks.Redis.FormatDataSeparator": "Data separator",
   "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
index 1fe911331..1394170eb 100644
--- a/inlong-dashboard/src/metas/sinks/defaults/Redis.ts
+++ b/inlong-dashboard/src/metas/sinks/defaults/Redis.ts
@@ -30,26 +30,48 @@ const { FieldDecorator } = RenderRow;
 const { ColumnDecorator } = RenderList;
 
 const redisTargetTypes = [
-  'BOOLEAN',
-  'INT',
-  'BIGINT',
-  'FLOAT',
-  'DOUBLE',
-  'DATE',
-  'DATETIME',
-  'CHAR',
-  'TIME',
+  'int',
+  'long',
+  'string',
+  'float',
+  'double',
+  'date',
+  'timestamp',
+  'time',
+  'boolean',
+  'timestamptz',
+  'binary',
 ].map(item => ({
   label: item,
   value: item,
 }));
 
+const schemaMappingModeStrategies = dataType => {
+  const data = [
+    {
+      label: 'STATIC_PREFIX_MATCH',
+      value: 'STATIC_PREFIX_MATCH',
+      enable: !['BITMAP'].includes(dataType),
+    },
+    {
+      label: 'STATIC_KV_PAIR',
+      value: 'STATIC_KV_PAIR',
+      enable: !['BITMAP', 'PLAIN'].includes(dataType),
+    },
+    {
+      label: 'DYNAMIC',
+      value: 'DYNAMIC',
+      enable: !['PLAIN'].includes(dataType),
+    },
+  ];
+  return data.filter(item => item.enable);
+};
+
 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'),
+    tooltip: i18n.t('meta.Sinks.Redis.ClusterNameHelper'),
     props: values => ({
       disabled: [110, 130].includes(values?.status),
       options: [
@@ -66,27 +88,87 @@ export default class RedisSink extends SinkInfo implements 
DataWithBackend, Rend
           value: 'standalone',
         },
       ],
+      placeholder: i18n.t('meta.Sinks.Redis.ClusterModeHelper'),
     }),
   })
-  @I18n('meta.Sinks.Redis.clusterMode')
+  @I18n('meta.Sinks.Redis.ClusterMode')
   clusterMode: string;
 
+  @FieldDecorator({
+    type: 'input',
+    initialValue: '127.0.0.1',
+    rules: [{ required: false }],
+    props: values => ({
+      disabled: [110, 130].includes(values?.status),
+      placeholder: '127.0.0.1',
+    }),
+    visible: values => values!.clusterMode == 'standalone',
+  })
+  @ColumnDecorator()
+  @I18n('meta.Sinks.Redis.Host')
+  host: String;
+
   @FieldDecorator({
     type: 'inputnumber',
     rules: [{ required: false }],
+    initialValue: 6379,
     props: values => ({
       disabled: [110, 130].includes(values?.status),
-      min: 0,
+      min: 1,
+      max: 65535,
+      placeholder: i18n.t('meta.Sinks.Redis.PortHelper'),
     }),
+    visible: values => values!.clusterMode == 'standalone',
   })
   @ColumnDecorator()
-  @I18n('meta.Sinks.Redis.database')
-  database: number;
+  @I18n('meta.Sinks.Redis.Port')
+  port: number;
 
   @FieldDecorator({
-    type: 'select',
+    type: 'input',
+    initialValue: '',
+    rules: [{ required: false }],
+    props: values => ({
+      disabled: [110, 130].includes(values?.status),
+    }),
+    visible: values => values!.clusterMode == 'sentinel',
+  })
+  @ColumnDecorator()
+  @I18n('meta.Sinks.Redis.SentinelMasterName')
+  sentinelMasterName: String;
+
+  @FieldDecorator({
+    type: 'input',
+    initialValue: '',
+    rules: [{ required: false }],
+    props: values => ({
+      disabled: [110, 130].includes(values?.status),
+      placeholder: '127.0.0.1:6379,127.0.0.1:6378',
+    }),
+    visible: values => values!.clusterMode == 'sentinel',
+  })
+  @ColumnDecorator()
+  @I18n('meta.Sinks.Redis.SentinelsInfo')
+  sentinelsInfo: String;
+
+  @FieldDecorator({
+    type: 'input',
+    initialValue: '',
     rules: [{ required: false }],
-    initialValue: 'PLAIN',
+    props: values => ({
+      disabled: [110, 130].includes(values?.status),
+      placeholder: '127.0.0.1:6379,127.0.0.1:6378',
+    }),
+    visible: values => values!.clusterMode == 'cluster',
+  })
+  @ColumnDecorator()
+  @I18n('meta.Sinks.Redis.ClusterNodes')
+  clusterNodes: String;
+
+  @FieldDecorator({
+    type: 'select',
+    rules: [{ required: true }],
+    initialValue: '',
     props: values => ({
       disabled: [110, 130].includes(values?.status),
       options: [
@@ -106,34 +188,159 @@ export default class RedisSink extends SinkInfo 
implements DataWithBackend, Rend
     }),
   })
   @ColumnDecorator()
-  @I18n('meta.Sinks.Redis.dataType')
+  @I18n('meta.Sinks.Redis.DataType')
   dataType: string;
 
   @FieldDecorator({
     type: 'select',
-    rules: [{ required: false }],
-    initialValue: 'STATIC_PREFIX_MATCH',
+    rules: [{ required: true }],
+    props: values => ({
+      disabled: [110, 130].includes(values?.status),
+      options: schemaMappingModeStrategies(values!.dataType),
+    }),
+  })
+  @ColumnDecorator()
+  @I18n('meta.Sinks.Redis.SchemaMapMode')
+  schemaMapMode: string;
+
+  @FieldDecorator({
+    type: 'select',
+    initialValue: 'CSV',
+    visible: values => values!.schemaMapMode == 'STATIC_PREFIX_MATCH',
+    props: values => ({
+      disabled: [110, 130].includes(values?.status),
+      options: [
+        {
+          label: 'CSV',
+          value: 'CSV',
+        },
+        {
+          label: 'KV',
+          value: 'KV',
+        },
+        {
+          label: 'AVRO',
+          value: 'AVRO',
+        },
+        {
+          label: 'JSON',
+          value: 'JSON',
+        },
+      ],
+    }),
+    rules: [{ required: true }],
+  })
+  @I18n('meta.Sinks.Redis.FormatDataType')
+  formatDataType: string;
+
+  @FieldDecorator({
+    type: 'radio',
+    rules: [{ required: true }],
+    initialValue: true,
+    visible: values => values!.schemaMapMode == 'STATIC_PREFIX_MATCH',
     props: values => ({
       disabled: [110, 130].includes(values?.status),
       options: [
         {
-          label: 'STATIC_PREFIX_MATCH',
-          value: 'STATIC_PREFIX_MATCH',
+          label: i18n.t('basic.Yes'),
+          value: true,
         },
         {
-          label: 'STATIC_KV_PAIR',
-          value: 'STATIC_KV_PAIR',
+          label: i18n.t('basic.No'),
+          value: false,
+        },
+      ],
+    }),
+  })
+  @I18n('meta.Sinks.Redis.FormatIgnoreParseError')
+  formatIgnoreParseError: boolean;
+
+  @FieldDecorator({
+    type: 'radio',
+    initialValue: 'UTF-8',
+    visible: values => values!.schemaMapMode == 'STATIC_PREFIX_MATCH',
+    props: values => ({
+      disabled: [110, 130].includes(values?.status),
+      options: [
+        {
+          label: 'UTF-8',
+          value: 'UTF-8',
         },
         {
-          label: 'DYNAMIC',
-          value: 'DYNAMIC',
+          label: 'GBK',
+          value: 'GBK',
         },
       ],
     }),
+    rules: [{ required: true }],
+  })
+  @I18n('meta.Sinks.Redis.FormatDataEncoding')
+  formatDataEncoding: string;
+
+  @FieldDecorator({
+    type: 'select',
+    initialValue: '124',
+    visible: values => values!.schemaMapMode == 'STATIC_PREFIX_MATCH',
+    props: values => ({
+      disabled: [110, 130].includes(values?.status),
+      dropdownMatchSelectWidth: false,
+      options: [
+        {
+          label: i18n.t('meta.Sinks.Redis.DataSeparator.Space'),
+          value: '32',
+        },
+        {
+          label: i18n.t('meta.Sinks.Redis.DataSeparator.VerticalLine'),
+          value: '124',
+        },
+        {
+          label: i18n.t('meta.Sinks.Redis.DataSeparator.Comma'),
+          value: '44',
+        },
+        {
+          label: i18n.t('meta.Sinks.Redis.DataSeparator.Semicolon'),
+          value: '59',
+        },
+        {
+          label: i18n.t('meta.Sinks.Redis.DataSeparator.Asterisk'),
+          value: '42',
+        },
+        {
+          label: i18n.t('meta.Sinks.Redis.DataSeparator.DoubleQuotes'),
+          value: '34',
+        },
+      ],
+      useInput: true,
+      useInputProps: {
+        placeholder: 'ASCII',
+      },
+      style: { width: 100 },
+    }),
+    rules: [
+      {
+        required: true,
+        type: 'number',
+        transform: val => +val,
+        min: 0,
+        max: 127,
+      },
+    ],
+  })
+  @I18n('meta.Sinks.Redis.FormatDataSeparator')
+  formatDataSeparator: string;
+
+  @FieldDecorator({
+    type: 'inputnumber',
+    rules: [{ required: false }],
+    props: values => ({
+      disabled: [110, 130].includes(values?.status),
+      min: 0,
+      placholder: '0',
+    }),
   })
   @ColumnDecorator()
-  @I18n('meta.Sinks.Redis.schemaMapMode')
-  schemaMapMode: string;
+  @I18n('meta.Sinks.Redis.Database')
+  database: number;
 
   @FieldDecorator({
     type: 'password',
@@ -144,7 +351,7 @@ export default class RedisSink extends SinkInfo implements 
DataWithBackend, Rend
     }),
   })
   @ColumnDecorator()
-  @I18n('meta.Sinks.Redis.password')
+  @I18n('meta.Sinks.Redis.Password')
   password: string;
 
   @FieldDecorator({
@@ -152,14 +359,24 @@ export default class RedisSink extends SinkInfo 
implements DataWithBackend, Rend
     initialValue: 0,
     props: values => ({
       disabled: [110, 130].includes(values?.status),
-      min: 1,
+      min: 0,
     }),
-    rules: [{ required: true }],
-    suffix: i18n.t('meta.Sinks.Redis.ttlUnit'),
+    rules: [{ required: false }],
+    suffix: i18n.t('meta.Sinks.Redis.TtlUnit'),
   })
-  @I18n('meta.Sinks.Redis.ttl')
+  @I18n('meta.Sinks.Redis.Ttl')
   ttl: number;
 
+  @FieldDecorator({
+    type: EditableTable,
+    props: values => ({
+      size: 'small',
+      editing: ![110, 130].includes(values?.status),
+      columns: getFieldListColumns(values),
+    }),
+  })
+  sinkFieldList: Record<string, unknown>[];
+
   @FieldDecorator({
     type: EditableTable,
     rules: [{ required: false }],
@@ -188,38 +405,36 @@ export default class RedisSink extends SinkInfo 
implements DataWithBackend, Rend
   @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',
+    isPro: true,
+    initialValue: 2000,
     rules: [{ required: true }],
     props: values => ({
       disabled: values?.status === 101,
     }),
+    suffix: i18n.t('meta.Sinks.Redis.TimeoutUnit'),
   })
   @I18n('meta.Sinks.Redis.Timeout')
   timeout: number;
 
   @FieldDecorator({
     type: 'inputnumber',
+    isPro: true,
+    initialValue: 2000,
     rules: [{ required: true }],
     props: values => ({
       disabled: values?.status === 101,
     }),
+    suffix: i18n.t('meta.Sinks.Redis.SoTimeoutUnit'),
   })
   @I18n('meta.Sinks.Redis.SoTimeout')
   soTimeout: number;
 
   @FieldDecorator({
     type: 'inputnumber',
+    isPro: true,
+    initialValue: 2,
     rules: [{ required: true }],
     props: values => ({
       disabled: values?.status === 101,
@@ -230,6 +445,8 @@ export default class RedisSink extends SinkInfo implements 
DataWithBackend, Rend
 
   @FieldDecorator({
     type: 'inputnumber',
+    isPro: true,
+    initialValue: 8,
     rules: [{ required: true }],
     props: values => ({
       disabled: values?.status === 101,
@@ -240,6 +457,8 @@ export default class RedisSink extends SinkInfo implements 
DataWithBackend, Rend
 
   @FieldDecorator({
     type: 'inputnumber',
+    isPro: true,
+    initialValue: 1,
     rules: [{ required: true }],
     props: values => ({
       disabled: values?.status === 101,
@@ -250,6 +469,7 @@ export default class RedisSink extends SinkInfo implements 
DataWithBackend, Rend
 
   @FieldDecorator({
     type: 'inputnumber',
+    isPro: true,
     rules: [{ required: true }],
     initialValue: 1,
     props: values => ({
@@ -257,7 +477,7 @@ export default class RedisSink extends SinkInfo implements 
DataWithBackend, Rend
       min: 1,
     }),
   })
-  @I18n('meta.Sinks.Redis.maxRetries')
+  @I18n('meta.Sinks.Redis.MaxRetries')
   maxRetries: number;
 }
 
@@ -290,24 +510,6 @@ const getFieldListColumns = sinkValues => {
       }),
       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',

Reply via email to