mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-07-25 18:30:00 +00:00
This commit is contained in:
parent
2730d13bcc
commit
ae51a49ce1
@ -8,7 +8,7 @@
|
|||||||
"javaType": "org.openmetadata.catalog.services.connections.database.ConnectionOptions",
|
"javaType": "org.openmetadata.catalog.services.connections.database.ConnectionOptions",
|
||||||
"description": "Additional connection options that can be sent to service during the connection.",
|
"description": "Additional connection options that can be sent to service during the connection.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"patternProperties": {
|
"additionalProperties": {
|
||||||
".{1,}": { "type": "string" }
|
".{1,}": { "type": "string" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -16,7 +16,7 @@
|
|||||||
"javaType": "org.openmetadata.catalog.services.connections.database.ConnectionArguments",
|
"javaType": "org.openmetadata.catalog.services.connections.database.ConnectionArguments",
|
||||||
"description": "Additional connection arguments such as security or protocol configs that can be sent to service during connection.",
|
"description": "Additional connection arguments such as security or protocol configs that can be sent to service during connection.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"patternProperties": {
|
"additionalProperties": {
|
||||||
".{1,}": { "type": "string" }
|
".{1,}": { "type": "string" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -125,7 +125,6 @@ database:
|
|||||||
migrationConfiguration:
|
migrationConfiguration:
|
||||||
path: "./bootstrap/sql"
|
path: "./bootstrap/sql"
|
||||||
|
|
||||||
# Authorizer Configuration
|
|
||||||
# Authorizer Configuration
|
# Authorizer Configuration
|
||||||
authorizerConfiguration:
|
authorizerConfiguration:
|
||||||
className: ${AUTHORIZER_CLASS_NAME:-org.openmetadata.catalog.security.NoopAuthorizer}
|
className: ${AUTHORIZER_CLASS_NAME:-org.openmetadata.catalog.security.NoopAuthorizer}
|
||||||
|
@ -35,7 +35,7 @@ import { ConfigData } from '../../interface/service.interface';
|
|||||||
import jsonData from '../../jsons/en';
|
import jsonData from '../../jsons/en';
|
||||||
import { getDashboardConfig } from '../../utils/DashboardServiceUtils';
|
import { getDashboardConfig } from '../../utils/DashboardServiceUtils';
|
||||||
import { getDatabaseConfig } from '../../utils/DatabaseServiceUtils';
|
import { getDatabaseConfig } from '../../utils/DatabaseServiceUtils';
|
||||||
import { escapeBackwardSlashChar } from '../../utils/JSONSchemaFormUtils';
|
import { formatFormDataForSubmit } from '../../utils/JSONSchemaFormUtils';
|
||||||
import { getMessagingConfig } from '../../utils/MessagingServiceUtils';
|
import { getMessagingConfig } from '../../utils/MessagingServiceUtils';
|
||||||
import { getPipelineConfig } from '../../utils/PipelineServiceUtils';
|
import { getPipelineConfig } from '../../utils/PipelineServiceUtils';
|
||||||
import { showErrorToast } from '../../utils/ToastUtils';
|
import { showErrorToast } from '../../utils/ToastUtils';
|
||||||
@ -71,12 +71,12 @@ const ConnectionConfigForm: FunctionComponent<Props> = ({
|
|||||||
: ({} as ConfigData);
|
: ({} as ConfigData);
|
||||||
|
|
||||||
const handleSave = (data: ISubmitEvent<ConfigData>) => {
|
const handleSave = (data: ISubmitEvent<ConfigData>) => {
|
||||||
const updatedFormData = escapeBackwardSlashChar(data.formData);
|
const updatedFormData = formatFormDataForSubmit(data.formData);
|
||||||
onSave({ ...data, formData: updatedFormData });
|
onSave({ ...data, formData: updatedFormData });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTestConnection = (formData: ConfigData) => {
|
const handleTestConnection = (formData: ConfigData) => {
|
||||||
const updatedFormData = escapeBackwardSlashChar(formData);
|
const updatedFormData = formatFormDataForSubmit(formData);
|
||||||
|
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
TestConnection(updatedFormData, 'Database')
|
TestConnection(updatedFormData, 'Database')
|
||||||
|
@ -18,6 +18,7 @@ import { debounce, isEmpty } from 'lodash';
|
|||||||
import { LoadingState } from 'Models';
|
import { LoadingState } from 'Models';
|
||||||
import React, { FunctionComponent, useCallback, useState } from 'react';
|
import React, { FunctionComponent, useCallback, useState } from 'react';
|
||||||
import { ConfigData } from '../../../interface/service.interface';
|
import { ConfigData } from '../../../interface/service.interface';
|
||||||
|
import { formatFormDataForRender } from '../../../utils/JSONSchemaFormUtils';
|
||||||
import SVGIcons, { Icons } from '../../../utils/SvgUtils';
|
import SVGIcons, { Icons } from '../../../utils/SvgUtils';
|
||||||
import { Button } from '../../buttons/Button/Button';
|
import { Button } from '../../buttons/Button/Button';
|
||||||
import { ArrayFieldTemplate } from '../../JSONSchemaTemplate/ArrayFieldTemplate';
|
import { ArrayFieldTemplate } from '../../JSONSchemaTemplate/ArrayFieldTemplate';
|
||||||
@ -43,18 +44,19 @@ const FormBuilder: FunctionComponent<Props> = ({
|
|||||||
onCancel,
|
onCancel,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onTestConnection,
|
onTestConnection,
|
||||||
|
uiSchema,
|
||||||
...props
|
...props
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
let oForm: Form<ConfigData> | null;
|
let oForm: Form<ConfigData> | null;
|
||||||
const [localFormData, setLocalFormData] = useState<ConfigData | undefined>(
|
const [localFormData, setLocalFormData] = useState<ConfigData | undefined>(
|
||||||
formData
|
formatFormDataForRender(formData)
|
||||||
);
|
);
|
||||||
const [connectionTesting, setConnectionTesting] = useState<boolean>(false);
|
const [connectionTesting, setConnectionTesting] = useState<boolean>(false);
|
||||||
const [connectionTestingState, setConnectionTestingState] =
|
const [connectionTestingState, setConnectionTestingState] =
|
||||||
useState<LoadingState>('initial');
|
useState<LoadingState>('initial');
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setLocalFormData(formData);
|
setLocalFormData(formatFormDataForRender(formData));
|
||||||
if (onCancel) {
|
if (onCancel) {
|
||||||
onCancel();
|
onCancel();
|
||||||
}
|
}
|
||||||
@ -137,6 +139,7 @@ const FormBuilder: FunctionComponent<Props> = ({
|
|||||||
oForm = form;
|
oForm = form;
|
||||||
}}
|
}}
|
||||||
schema={schema}
|
schema={schema}
|
||||||
|
uiSchema={uiSchema}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
handleChange(e.formData);
|
handleChange(e.formData);
|
||||||
props.onChange && props.onChange(e);
|
props.onChange && props.onChange(e);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { isString } from 'lodash';
|
import { cloneDeep, isString } from 'lodash';
|
||||||
|
|
||||||
export function escapeBackwardSlashChar<T>(formData: T): T {
|
export function escapeBackwardSlashChar<T>(formData: T): T {
|
||||||
for (const key in formData) {
|
for (const key in formData) {
|
||||||
@ -30,3 +30,79 @@ export function escapeBackwardSlashChar<T>(formData: T): T {
|
|||||||
|
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatConnectionFields<T>(formData: T, field: string): T {
|
||||||
|
if (formData && formData[field as keyof T]) {
|
||||||
|
// Since connection options support value of type string or object
|
||||||
|
// try to parse the string value as object
|
||||||
|
const options = formData[field as keyof T];
|
||||||
|
|
||||||
|
for (const key in options) {
|
||||||
|
const value = options[key];
|
||||||
|
try {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
||||||
|
// @ts-ignore
|
||||||
|
formData[field as keyof T][key] = JSON.parse(value);
|
||||||
|
} catch (_) {
|
||||||
|
// ignore exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatAdditionalProperties<T>(formData: T): T {
|
||||||
|
for (const key in formData) {
|
||||||
|
if (typeof formData[key as keyof T] === 'object') {
|
||||||
|
formatAdditionalProperties(formData[key as keyof T]);
|
||||||
|
} else {
|
||||||
|
const data = formData[key as keyof T];
|
||||||
|
if (
|
||||||
|
key.startsWith('newKey') &&
|
||||||
|
data === ('New Value' as unknown as T[keyof T])
|
||||||
|
) {
|
||||||
|
delete formData[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatFormDataForSubmit<T>(formData: T): T {
|
||||||
|
formData = cloneDeep(formData);
|
||||||
|
formData = escapeBackwardSlashChar(formData);
|
||||||
|
formData = formatAdditionalProperties(formData);
|
||||||
|
formData = formatConnectionFields(formData, 'connectionOptions');
|
||||||
|
formData = formatConnectionFields(formData, 'connectionArguments');
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatConnectionFieldsForRender<T>(formData: T, field: string): T {
|
||||||
|
if (formData && formData[field as keyof T]) {
|
||||||
|
// Since connection options support value of type string or object
|
||||||
|
// convert object into string
|
||||||
|
const options = formData[field as keyof T];
|
||||||
|
|
||||||
|
for (const key in options) {
|
||||||
|
const value = options[key];
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
||||||
|
// @ts-ignore
|
||||||
|
formData[field as keyof T][key] = JSON.stringify(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatFormDataForRender<T>(formData: T): T {
|
||||||
|
formData = cloneDeep(formData);
|
||||||
|
formData = formatConnectionFieldsForRender(formData, 'connectionOptions');
|
||||||
|
formData = formatConnectionFieldsForRender(formData, 'connectionArguments');
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user