This is an automated email from the ASF dual-hosted git repository.
klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new 7e6723d4 feat: add connection rate limit setting (#2783)
7e6723d4 is described below
commit 7e6723d4d0c5fb37e7858638782cf598c926e1f3
Author: Julien Chinapen <[email protected]>
AuthorDate: Sun Aug 21 22:29:08 2022 -0400
feat: add connection rate limit setting (#2783)
* feat: add connection rate limit setting
* fix: apply linting cleanups
* fix: enable rate-limit for jenkins provider
* fix: change payload prop name to rateLimitPerHour
* fix: switch value prop and add tapd config
Co-authored-by: Klesh Wong <[email protected]>
---
.../src/components/blueprints/ConnectionDialog.jsx | 4 +
config-ui/src/data/NullConnection.js | 1 +
config-ui/src/data/Providers.js | 39 ++++++---
config-ui/src/hooks/useConnectionManager.jsx | 20 +++++
config-ui/src/hooks/useConnectionValidation.jsx | 3 +
.../src/pages/blueprints/create-blueprint.jsx | 5 ++
.../pages/configure/connections/AddConnection.jsx | 5 ++
.../configure/connections/ConfigureConnection.jsx | 5 ++
.../pages/configure/connections/ConnectionForm.jsx | 99 +++++++++++++++-------
9 files changed, 138 insertions(+), 43 deletions(-)
diff --git a/config-ui/src/components/blueprints/ConnectionDialog.jsx
b/config-ui/src/components/blueprints/ConnectionDialog.jsx
index 9857b91f..f428951b 100644
--- a/config-ui/src/components/blueprints/ConnectionDialog.jsx
+++ b/config-ui/src/components/blueprints/ConnectionDialog.jsx
@@ -95,6 +95,7 @@ const ConnectionDialog = (props) => {
name,
endpointUrl,
proxy,
+ rateLimit = 0,
token,
initialTokenStore = {},
username,
@@ -116,6 +117,7 @@ const ConnectionDialog = (props) => {
onNameChange = () => {},
onEndpointChange = () => {},
onProxyChange = () => {},
+ onRateLimitChange = () => {},
onTokenChange = () => {},
onUsernameChange = () => {},
onPasswordChange = () => {},
@@ -287,6 +289,7 @@ const ConnectionDialog = (props) => {
name={name}
endpointUrl={endpointUrl}
proxy={proxy}
+ rateLimit={rateLimit}
token={token}
initialTokenStore={initialTokenStore}
username={username}
@@ -298,6 +301,7 @@ const ConnectionDialog = (props) => {
onNameChange={onNameChange}
onEndpointChange={onEndpointChange}
onProxyChange={onProxyChange}
+ onRateLimitChange={onRateLimitChange}
onTokenChange={onTokenChange}
onUsernameChange={onUsernameChange}
onPasswordChange={onPasswordChange}
diff --git a/config-ui/src/data/NullConnection.js
b/config-ui/src/data/NullConnection.js
index f10daa02..70207389 100644
--- a/config-ui/src/data/NullConnection.js
+++ b/config-ui/src/data/NullConnection.js
@@ -21,6 +21,7 @@ const NullConnection = {
name: null,
endpoint: null,
proxy: null,
+ rateLimit: 0,
token: null,
username: null,
password: null,
diff --git a/config-ui/src/data/Providers.js b/config-ui/src/data/Providers.js
index caa94c93..7a33b798 100644
--- a/config-ui/src/data/Providers.js
+++ b/config-ui/src/data/Providers.js
@@ -81,7 +81,8 @@ const ProviderFormLabels = {
proxy: 'Proxy URL',
token: 'Basic Auth Token',
username: 'Username',
- password: 'Password'
+ password: 'Password',
+ rateLimit: 'Rate Limit'
},
gitlab: {
name: 'Connection Name',
@@ -89,7 +90,8 @@ const ProviderFormLabels = {
proxy: 'Proxy URL',
token: 'Access Token',
username: 'Username',
- password: 'Password'
+ password: 'Password',
+ rateLimit: <>Rate Limit <sup>(per hour)</sup></>
},
jenkins: {
name: 'Connection Name',
@@ -97,7 +99,8 @@ const ProviderFormLabels = {
proxy: 'Proxy URL',
token: 'Basic Auth Token',
username: 'Username',
- password: 'Password'
+ password: 'Password',
+ rateLimit: <>Rate Limit <sup>(per hour)</sup></>
},
tapd: {
name: 'Connection Name',
@@ -106,13 +109,14 @@ const ProviderFormLabels = {
token: 'Basic Auth Token',
username: 'Username',
password: 'Password',
+ rateLimit: <>Rate Limit <sup>(per hour)</sup></>
},
jira: {
name: 'Connection Name',
endpoint: 'Endpoint URL',
token: 'Basic Auth Token',
username: 'Username / E-mail',
- // password; 'Password',
+ proxy: 'Proxy URL',
password: (
<>
Password
@@ -134,17 +138,17 @@ const ProviderFormLabels = {
/>
</Tooltip>
</>),
+ rateLimit: <>Rate Limit <sup>(per hour)</sup></>
},
github: {
name: 'Connection Name',
endpoint: 'Endpoint URL',
proxy: 'Proxy URL',
- // token: 'Auth Token(s)',
token: (
<>
Auth Token(s)
<Tooltip
- content={(<span>Due to Github’s rate limit, input more tokens, <br
/>comma separated, to accelerate data collection.</span>)}
+ content={(<span>Due to Github's rate limit, input more tokens, <br
/>comma separated, to accelerate data collection.</span>)}
intent='primary'
>
<Icon
@@ -162,8 +166,9 @@ const ProviderFormLabels = {
</Tooltip>
</>),
username: 'Username',
- password: 'Password'
- },
+ password: 'Password',
+ rateLimit: <>Rate Limit <sup>(per hour)</sup></>
+ }
}
const ProviderFormPlaceholders = {
@@ -173,7 +178,8 @@ const ProviderFormPlaceholders = {
proxy: 'eg. http://proxy.localhost:8080',
token: 'eg. 3f5cda2a23ff410792e0',
username: 'Enter Username / E-mail',
- password: 'Enter Password'
+ password: 'Enter Password',
+ rateLimit: '1000'
},
gitlab: {
name: 'eg. GitLab',
@@ -181,7 +187,8 @@ const ProviderFormPlaceholders = {
proxy: 'eg. http://proxy.localhost:8080',
token: 'eg. ff9d1ad0e5c04f1f98fa',
username: 'Enter Username / E-mail',
- password: 'Enter Password'
+ password: 'Enter Password',
+ rateLimit: '1000'
},
jenkins: {
name: 'eg. Jenkins',
@@ -189,7 +196,8 @@ const ProviderFormPlaceholders = {
proxy: 'eg. http://proxy.localhost:8080',
token: 'eg. 6b057ffe68464c93a057',
username: 'eg. admin',
- password: 'eg. ************'
+ password: 'eg. ************',
+ rateLimit: '1000'
},
tapd: {
name: 'eg. Tapd',
@@ -197,7 +205,8 @@ const ProviderFormPlaceholders = {
proxy: 'eg. http://proxy.localhost:8080',
token: 'eg. 6b057ffe68464c93a057',
username: 'eg. admin',
- password: 'eg. ************'
+ password: 'eg. ************',
+ rateLimit: '1000'
},
jira: {
name: 'eg. JIRA',
@@ -205,7 +214,8 @@ const ProviderFormPlaceholders = {
proxy: 'eg. http://proxy.localhost:8080',
token: 'eg. 8c06a7cc50b746bfab30',
username: 'eg. admin',
- password: 'eg. ************'
+ password: 'eg. ************',
+ rateLimit: '1000'
},
github: {
name: 'eg. GitHub',
@@ -213,7 +223,8 @@ const ProviderFormPlaceholders = {
proxy: 'eg. http://proxy.localhost:8080',
token: 'eg. 4c5cbdb62c165e2b3d18, 40008ebccff9837bb8d2',
username: 'eg. admin',
- password: 'eg. ************'
+ password: 'eg. ************',
+ rateLimit: '1000'
}
}
diff --git a/config-ui/src/hooks/useConnectionManager.jsx
b/config-ui/src/hooks/useConnectionManager.jsx
index b7ad258e..ce5d0f48 100644
--- a/config-ui/src/hooks/useConnectionManager.jsx
+++ b/config-ui/src/hooks/useConnectionManager.jsx
@@ -44,6 +44,7 @@ function useConnectionManager (
const [name, setName] = useState()
const [endpointUrl, setEndpointUrl] = useState()
const [proxy, setProxy] = useState()
+ const [rateLimit, setRateLimit] = useState(0)
const [token, setToken] = useState()
const [initialTokenStore, setInitialTokenStore] = useState({
0: '',
@@ -148,6 +149,7 @@ function useConnectionManager (
username: username,
password: password,
proxy: proxy,
+ rateLimitPerHour: rateLimit,
...connectionPayload,
}
break
@@ -158,6 +160,7 @@ function useConnectionManager (
username: username,
password: password,
proxy: proxy,
+ rateLimitPerHour: rateLimit,
...connectionPayload,
}
break
@@ -167,6 +170,7 @@ function useConnectionManager (
endpoint: endpointUrl,
token: token,
proxy: proxy,
+ rateLimitPerHour: rateLimit,
...connectionPayload,
}
break
@@ -177,6 +181,7 @@ function useConnectionManager (
endpoint: endpointUrl,
username: username,
password: password,
+ rateLimitPerHour: rateLimit,
...connectionPayload,
}
break
@@ -186,6 +191,7 @@ function useConnectionManager (
endpoint: endpointUrl,
token: token,
proxy: proxy,
+ rateLimitPerHour: rateLimit,
...connectionPayload,
}
break
@@ -321,6 +327,7 @@ function useConnectionManager (
name: connectionData.name || connectionData.Name,
endpoint: connectionData.endpoint || connectionData.Endpoint,
proxy: connectionData.proxy || connectionData.Proxy,
+ rateLimit: connectionData.rateLimit,
username: connectionData.username || connectionData.Username,
password: connectionData.password || connectionData.Password,
token: connectionData.token || connectionData.auth
@@ -544,6 +551,7 @@ function useConnectionManager (
2: ''
})
setProxy('')
+ setRateLimit(0)
}, [])
useEffect(() => {
@@ -555,22 +563,32 @@ function useConnectionManager (
case Providers.JENKINS:
setUsername(activeConnection.username)
setPassword(activeConnection.password)
+ setRateLimit(activeConnection.rateLimit)
break
case Providers.GITLAB:
setToken(activeConnection.basicAuthEncoded || activeConnection.token
|| activeConnection.auth)
setProxy(activeConnection.Proxy || activeConnection.proxy)
+ setRateLimit(activeConnection.rateLimit)
break
case Providers.GITHUB:
setToken(connectionToken)
setInitialTokenStore(connectionToken?.split(',')?.reduce((tS, cT,
id) => ({ ...tS, [id]: cT }), {}))
setProxy(activeConnection.Proxy || activeConnection.proxy)
+ setRateLimit(activeConnection.rateLimit)
break
case Providers.JIRA:
// setToken(activeConnection.basicAuthEncoded ||
activeConnection.token)
setUsername(activeConnection.username)
setPassword(activeConnection.password)
setProxy(activeConnection.Proxy || activeConnection.proxy)
+ setRateLimit(activeConnection.rateLimit)
break
+ case Providers.TAPD:
+ setUsername(activeConnection.username)
+ setPassword(activeConnection.password)
+ setProxy(activeConnection.Proxy || activeConnection.proxy)
+ setRateLimit(activeConnection.rateLimit)
+ break
}
ToastNotification.clear()
// ToastNotification.show({ message: `Fetched settings for
${activeConnection.name}.`, intent: 'success', icon: 'small-tick' })
@@ -657,6 +675,7 @@ function useConnectionManager (
name,
endpointUrl,
proxy,
+ rateLimit,
username,
password,
token,
@@ -667,6 +686,7 @@ function useConnectionManager (
setName,
setEndpointUrl,
setProxy,
+ setRateLimit,
setToken,
setInitialTokenStore,
setUsername,
diff --git a/config-ui/src/hooks/useConnectionValidation.jsx
b/config-ui/src/hooks/useConnectionValidation.jsx
index 20c300b8..0af438d5 100644
--- a/config-ui/src/hooks/useConnectionValidation.jsx
+++ b/config-ui/src/hooks/useConnectionValidation.jsx
@@ -25,6 +25,7 @@ function useConnectionValidation ({
name,
endpointUrl,
proxy,
+ rateLimit,
token,
username,
password
@@ -48,6 +49,7 @@ function useConnectionValidation ({
'NAME', name,
'ENDPOINT URL', endpointUrl,
'PROXY URL', proxy,
+ 'RATE LIMIT', rateLimit,
'TOKEN', token,
'USERNAME', username,
'PASSWORD', password
@@ -100,6 +102,7 @@ function useConnectionValidation ({
name,
endpointUrl,
proxy,
+ rateLimit,
token,
username,
password,
diff --git a/config-ui/src/pages/blueprints/create-blueprint.jsx
b/config-ui/src/pages/blueprints/create-blueprint.jsx
index b6b6aa8d..6c632c74 100644
--- a/config-ui/src/pages/blueprints/create-blueprint.jsx
+++ b/config-ui/src/pages/blueprints/create-blueprint.jsx
@@ -268,6 +268,7 @@ const CreateBlueprint = (props) => {
name: connectionName,
endpointUrl,
proxy,
+ rateLimit,
token,
initialTokenStore,
username,
@@ -278,6 +279,7 @@ const CreateBlueprint = (props) => {
setName,
setEndpointUrl,
setProxy,
+ setRateLimit,
setUsername,
setPassword,
setToken,
@@ -333,6 +335,7 @@ const CreateBlueprint = (props) => {
name: connectionName,
endpointUrl,
proxy,
+ rateLimit,
token,
username,
password,
@@ -1129,6 +1132,7 @@ const CreateBlueprint = (props) => {
endpointUrl={endpointUrl}
name={connectionName}
proxy={proxy}
+ rateLimit={rateLimit}
token={token}
initialTokenStore={initialTokenStore}
username={username}
@@ -1145,6 +1149,7 @@ const CreateBlueprint = (props) => {
onNameChange={setName}
onEndpointChange={setEndpointUrl}
onProxyChange={setProxy}
+ onRateLimitChange={setRateLimit}
onTokenChange={setToken}
onUsernameChange={setUsername}
onPasswordChange={setPassword}
diff --git a/config-ui/src/pages/configure/connections/AddConnection.jsx
b/config-ui/src/pages/configure/connections/AddConnection.jsx
index 4ad749bf..4cf69f9f 100644
--- a/config-ui/src/pages/configure/connections/AddConnection.jsx
+++ b/config-ui/src/pages/configure/connections/AddConnection.jsx
@@ -57,6 +57,7 @@ export default function AddConnection () {
name,
endpointUrl,
proxy,
+ rateLimit,
token,
initialTokenStore,
username,
@@ -64,6 +65,7 @@ export default function AddConnection () {
setName,
setEndpointUrl,
setProxy,
+ setRateLimit,
setUsername,
setPassword,
setToken,
@@ -84,6 +86,7 @@ export default function AddConnection () {
name,
endpointUrl,
proxy,
+ rateLimit,
token,
username,
password
@@ -164,6 +167,7 @@ export default function AddConnection () {
name={name}
endpointUrl={endpointUrl}
proxy={proxy}
+ rateLimit={rateLimit}
token={token}
initialTokenStore={initialTokenStore}
username={username}
@@ -175,6 +179,7 @@ export default function AddConnection () {
onNameChange={setName}
onEndpointChange={setEndpointUrl}
onProxyChange={setProxy}
+ onRateLimitChange={setRateLimit}
onTokenChange={setToken}
onUsernameChange={setUsername}
onPasswordChange={setPassword}
diff --git a/config-ui/src/pages/configure/connections/ConfigureConnection.jsx
b/config-ui/src/pages/configure/connections/ConfigureConnection.jsx
index f6607597..ce62c221 100644
--- a/config-ui/src/pages/configure/connections/ConfigureConnection.jsx
+++ b/config-ui/src/pages/configure/connections/ConfigureConnection.jsx
@@ -57,6 +57,7 @@ export default function ConfigureConnection () {
name,
endpointUrl,
proxy,
+ rateLimit = 0,
username,
password,
token,
@@ -71,6 +72,7 @@ export default function ConfigureConnection () {
setName,
setEndpointUrl,
setProxy,
+ setRateLimit,
setUsername,
setPassword,
setToken,
@@ -106,6 +108,7 @@ export default function ConfigureConnection () {
name,
endpointUrl,
proxy,
+ rateLimit,
token,
username,
password
@@ -250,6 +253,7 @@ export default function ConfigureConnection () {
name={name}
endpointUrl={endpointUrl}
proxy={proxy}
+ rateLimit={rateLimit}
token={token}
initialTokenStore={initialTokenStore}
username={username}
@@ -262,6 +266,7 @@ export default function ConfigureConnection () {
onNameChange={setName}
onEndpointChange={setEndpointUrl}
onProxyChange={setProxy}
+ onRateLimitChange={setRateLimit}
onTokenChange={setToken}
onUsernameChange={setUsername}
onPasswordChange={setPassword}
diff --git a/config-ui/src/pages/configure/connections/ConnectionForm.jsx
b/config-ui/src/pages/configure/connections/ConnectionForm.jsx
index c929fa54..46c1f3b2 100644
--- a/config-ui/src/pages/configure/connections/ConnectionForm.jsx
+++ b/config-ui/src/pages/configure/connections/ConnectionForm.jsx
@@ -31,6 +31,7 @@ import {
// PopoverInteractionKind,
Intent,
PopoverInteractionKind,
+ NumericInput
} from '@blueprintjs/core'
import { Providers } from '@/data/Providers'
import FormValidationErrors from '@/components/messages/FormValidationErrors'
@@ -56,6 +57,7 @@ export default function ConnectionForm (props) {
username,
password,
proxy = '',
+ rateLimit = 0,
isSaving,
isTesting,
showError,
@@ -72,6 +74,7 @@ export default function ConnectionForm (props) {
onUsernameChange = () => {},
onPasswordChange = () => {},
onProxyChange = () => {},
+ onRateLimitChange = () => {},
onValidate = () => {},
authType = 'token',
sourceLimits = {},
@@ -89,6 +92,7 @@ export default function ConnectionForm (props) {
const connectionUsernameRef = useRef()
const connectionPasswordRef = useRef()
const connectionProxyRef = useRef()
+ const connectionRateLimitRef = useRef()
// const [isValidForm, setIsValidForm] = useState(true)
const [allowedAuthTypes, setAllowedAuthTypes] = useState(['token', 'plain'])
@@ -123,8 +127,9 @@ export default function ConnectionForm (props) {
token,
username,
password,
+ rateLimit,
})
- }, [name, endpointUrl, token, username, password, onValidate])
+ }, [name, endpointUrl, token, username, password, rateLimit, onValidate])
const fieldHasError = (fieldId) => {
return validationErrors.some((e) => e.includes(fieldId))
}
@@ -702,39 +707,75 @@ export default function ConnectionForm (props) {
</div>
</>
)}
- {[Providers.GITHUB, Providers.GITLAB, Providers.JIRA,
Providers.TAPD].includes(
+ {[Providers.GITHUB, Providers.GITLAB, Providers.JIRA,
Providers.JENKINS, Providers.TAPD].includes(
activeProvider.id
) && (
- <div className='formContainer'>
- <FormGroup
- disabled={isTesting || isSaving || isLocked}
- inline={true}
- labelFor='connection-proxy'
- className={formGroupClassName}
- contentClassName='formGroupContent'
- >
- <Label>{labels ? labels.proxy : <>Proxy URL</>}</Label>
- <InputGroup
- id='connection-proxy'
- inputRef={connectionProxyRef}
- tabIndex={3}
- placeholder={
- placeholders.proxy
- ? placeholders.proxy
- : 'http://proxy.localhost:8080'
- }
- defaultValue={proxy}
- onChange={(e) => onProxyChange(e.target.value)}
+ <>
+ <div className='formContainer'>
+ <FormGroup
disabled={isTesting || isSaving || isLocked}
- className={`input input-proxy ${
- fieldHasError('Proxy') ? 'invalid-field' : ''
+ inline={true}
+ labelFor='connection-proxy'
+ className={formGroupClassName}
+ contentClassName='formGroupContent'
+ >
+ <Label>{labels ? labels.proxy : <>Proxy URL</>}</Label>
+ <InputGroup
+ id='connection-proxy'
+ inputRef={connectionProxyRef}
+ tabIndex={3}
+ placeholder={
+ placeholders.proxy
+ ? placeholders.proxy
+ : 'http://proxy.localhost:8080'
+ }
+ defaultValue={proxy}
+ onChange={(e) => onProxyChange(e.target.value)}
+ disabled={isTesting || isSaving || isLocked}
+ className={`input input-proxy ${
+ fieldHasError('Proxy') ? 'invalid-field' : ''
+ }`}
+ rightElement={
+ <InputValidationError error={getFieldError('Proxy')} />
+ }
+ />
+ </FormGroup>
+ </div>
+ <div className='formContainer'>
+ <FormGroup
+ disabled={isTesting || isSaving || isLocked}
+ inline={true}
+ labelFor='connection-ratelimit'
+ className={formGroupClassName}
+ contentClassName='formGroupContent'
+ >
+ <Label>{labels ? labels.rateLimit :
<>Rate Limit</>}</Label>
+ <NumericInput
+ id='connection-ratelimit'
+ ref={connectionRateLimitRef}
+ disabled={isTesting || isSaving || isLocked}
+ min={0}
+ max={1000000000}
+ clampValueOnBlur={true}
+ className={`input input-ratelimit ${
+ fieldHasError('RateLimit') ? 'invalid-field' : ''
}`}
- rightElement={
- <InputValidationError error={getFieldError('Proxy')} />
+ fill={false}
+ placeholder={
+ placeholders.rateLimit
+ ? placeholders.rateLimit
+ : '1000'
}
- />
- </FormGroup>
- </div>
+ allowNumericCharactersOnly={true}
+ onValueChange={(rateLimitPerHour) => {
onRateLimitChange(rateLimitPerHour) }}
+ value={rateLimit}
+ rightElement={
+ <InputValidationError error={getFieldError('RateLimit')} />
+ }
+ />
+ </FormGroup>
+ </div>
+ </>
)}
{enableActions && (
<div