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 <featzh...@outlook.com>
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'),
+  },
 ];

Reply via email to