Skip to content

Commit 04d5607

Browse files
authored
Feat: modify Q dev connection (#8592)
* feat:modify q dev connection ui * feat:modify q dev connection ui * fix:test * fix: scopedata
1 parent 84fee8a commit 04d5607

File tree

8 files changed

+297
-200
lines changed

8 files changed

+297
-200
lines changed

backend/plugins/q_dev/api/connection.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,12 @@ func validateConnection(connection *models.QDevConnection) error {
122122
return errors.Default.New("Bucket is required")
123123
}
124124

125-
// Validate Identity Store fields (now required)
126-
if connection.IdentityStoreId == "" {
127-
return errors.Default.New("IdentityStoreId is required")
125+
// Identity Store fields are optional, but must be provided together if used
126+
if connection.IdentityStoreId == "" && connection.IdentityStoreRegion != "" {
127+
return errors.Default.New("IdentityStoreRegion provided but IdentityStoreId is empty")
128128
}
129-
if connection.IdentityStoreRegion == "" {
130-
return errors.Default.New("IdentityStoreRegion is required")
129+
if connection.IdentityStoreId != "" && connection.IdentityStoreRegion == "" {
130+
return errors.Default.New("IdentityStoreId provided but IdentityStoreRegion is empty")
131131
}
132132

133133
// Validate rate limit

backend/plugins/q_dev/api/connection_test.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,38 +111,54 @@ func TestValidateConnection_MissingBucket(t *testing.T) {
111111
assert.Contains(t, err.Error(), "Bucket is required")
112112
}
113113

114-
func TestValidateConnection_MissingIdentityStoreId(t *testing.T) {
114+
func TestValidateConnection_EmptyIdentityStoreOk(t *testing.T) {
115115
connection := &models.QDevConnection{
116116
QDevConn: models.QDevConn{
117117
AccessKeyId: "AKIAIOSFODNN7EXAMPLE",
118118
SecretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
119119
Region: "us-east-1",
120120
Bucket: "my-q-dev-bucket",
121-
IdentityStoreId: "", // Missing
122-
IdentityStoreRegion: "us-west-2",
121+
IdentityStoreId: "",
122+
IdentityStoreRegion: "",
123+
},
124+
}
125+
126+
err := validateConnection(connection)
127+
assert.NoError(t, err)
128+
}
129+
130+
func TestValidateConnection_IdentityStoreRegionWithoutId(t *testing.T) {
131+
connection := &models.QDevConnection{
132+
QDevConn: models.QDevConn{
133+
AccessKeyId: "AKIAIOSFODNN7EXAMPLE",
134+
SecretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
135+
Region: "us-east-1",
136+
Bucket: "my-q-dev-bucket",
137+
IdentityStoreId: "",
138+
IdentityStoreRegion: "us-east-1",
123139
},
124140
}
125141

126142
err := validateConnection(connection)
127143
assert.Error(t, err)
128-
assert.Contains(t, err.Error(), "IdentityStoreId is required")
144+
assert.Contains(t, err.Error(), "IdentityStoreRegion")
129145
}
130146

131-
func TestValidateConnection_MissingIdentityStoreRegion(t *testing.T) {
147+
func TestValidateConnection_IdentityStoreIdWithoutRegion(t *testing.T) {
132148
connection := &models.QDevConnection{
133149
QDevConn: models.QDevConn{
134150
AccessKeyId: "AKIAIOSFODNN7EXAMPLE",
135151
SecretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
136152
Region: "us-east-1",
137153
Bucket: "my-q-dev-bucket",
138154
IdentityStoreId: "d-1234567890",
139-
IdentityStoreRegion: "", // Missing
155+
IdentityStoreRegion: "",
140156
},
141157
}
142158

143159
err := validateConnection(connection)
144160
assert.Error(t, err)
145-
assert.Contains(t, err.Error(), "IdentityStoreRegion is required")
161+
assert.Contains(t, err.Error(), "IdentityStoreId provided but IdentityStoreRegion is empty")
146162
}
147163

148164
func TestValidateConnection_InvalidRateLimit(t *testing.T) {

config-ui/src/plugins/components/connection-form/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ export const ConnectionForm = ({ plugin, connectionId, onSuccess }: Props) => {
7777
})
7878
: API.connection.testOld(
7979
plugin,
80-
pick(values, [
80+
pick({ ...initialValues, ...values }, [
81+
'name',
8182
'endpoint',
8283
'token',
8384
'username',
@@ -86,6 +87,13 @@ export const ConnectionForm = ({ plugin, connectionId, onSuccess }: Props) => {
8687
'authMethod',
8788
'appId',
8889
'secretKey',
90+
'accessKeyId',
91+
'secretAccessKey',
92+
'region',
93+
'bucket',
94+
'identityStoreId',
95+
'identityStoreRegion',
96+
'rateLimitPerHour',
8997
'tenantId',
9098
'tenantType',
9199
'dbUrl',

config-ui/src/plugins/register/q-dev/config.tsx

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -19,64 +19,68 @@
1919
import { IPluginConfig } from '@/types';
2020

2121
import Icon from './assets/icon.svg?react';
22+
import { AwsCredentials, IdentityCenterConfig, S3Config } from './connection-fields';
2223

2324
export const QDevConfig: IPluginConfig = {
2425
plugin: 'q_dev',
2526
name: 'Q Developer',
2627
icon: ({ color }) => <Icon fill={color} />,
2728
sort: 20,
2829
connection: {
29-
docLink: '', // TODO: 添加文档链接
30+
docLink: 'https://devlake.apache.org/docs/UserManual/plugins/qdev',
3031
initialValues: {
32+
name: '',
3133
accessKeyId: '',
3234
secretAccessKey: '',
3335
region: 'us-east-1',
3436
bucket: '',
3537
identityStoreId: '',
36-
identityStoreRegion: 'us-east-1',
38+
identityStoreRegion: '',
3739
rateLimitPerHour: 20000,
3840
},
3941
fields: [
4042
'name',
41-
{
42-
key: 'accessKeyId',
43-
label: 'AWS Access Key ID',
44-
subLabel: '请输入您的AWS Access Key ID',
45-
},
46-
{
47-
key: 'secretAccessKey',
48-
label: 'AWS Secret Access Key',
49-
subLabel: '请输入您的AWS Secret Access Key',
50-
},
51-
{
52-
key: 'region',
53-
label: 'AWS区域',
54-
subLabel: '请输入AWS区域,例如:us-east-1',
55-
},
56-
{
57-
key: 'bucket',
58-
label: 'S3存储桶名称',
59-
subLabel: '请输入存储Q Developer数据的S3存储桶名称',
60-
},
61-
{
62-
key: 'identityStoreId',
63-
label: 'IAM Identity Store ID',
64-
subLabel: '请输入Identity Store ID,格式:d-xxxxxxxxxx',
65-
},
66-
{
67-
key: 'identityStoreRegion',
68-
label: 'IAM Identity Center区域',
69-
subLabel: '请输入IAM Identity Center所在的AWS区域',
70-
},
43+
({ type, initialValues, values, setValues, setErrors }: any) => (
44+
<AwsCredentials
45+
key="qdev-aws"
46+
type={type}
47+
initialValues={initialValues}
48+
values={values}
49+
setValues={setValues}
50+
setErrors={setErrors}
51+
/>
52+
),
53+
({ initialValues, values, setValues, setErrors }: any) => (
54+
<S3Config
55+
key="qdev-s3"
56+
initialValues={initialValues}
57+
values={values}
58+
setValues={setValues}
59+
setErrors={setErrors}
60+
/>
61+
),
62+
({ initialValues, values, setValues, setErrors }: any) => (
63+
<IdentityCenterConfig
64+
key="qdev-identity"
65+
initialValues={initialValues}
66+
values={values}
67+
setValues={setValues}
68+
setErrors={setErrors}
69+
/>
70+
),
7171
'proxy',
7272
{
7373
key: 'rateLimitPerHour',
74-
subLabel: '设置每小时的API请求限制,用于控制数据收集速度',
74+
subLabel: 'Set a fixed hourly rate limit if you need to throttle collection speed (default 20,000).',
7575
defaultValue: 20000,
7676
},
7777
],
7878
},
7979
dataScope: {
80-
title: 'Data Sources',
80+
title: 'S3 Prefixes',
81+
},
82+
scopeConfig: {
83+
entities: ['CROSS'],
84+
transformation: {},
8185
},
82-
};
86+
};

0 commit comments

Comments
 (0)