Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
15 changes: 6 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,13 @@ pom.xml.versionsBackup
gen

# buildTools
package/buildTools/gradle/
package/buildTools/.gradle/
package/buildTools/gradlew
package/buildTools/gradlew.bat
/package/build/

# run data dir.
/logs
/data
/install_upgrade.log
/backend/logs
/backend/data
/backend/install_upgrade.log

# web
node_modules
dist
frontend/node_modules
frontend/dist
8 changes: 6 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,17 @@ cd frontend && npm run check-i18n
- 避免长条件和层层 `if` 堆叠导致代码难读;如果必须校验,优先让边界、契约和数据结构保持清晰。
- 代码要干净直接,好读优先,不要为了抽象而抽象。
- 尽量不写三元表达式,能用 `if` 表达清楚的逻辑,优先使用 `if`。
- 不写没必要的小 helper,只有复用明显且能降低理解成本时才抽。
- 连续条件判断的三元表达式只有在完整表达式能控制在 100 个字符以内时才允许使用;超过后必须退化为显式 `if`,避免嵌套三元和换行三元影响阅读。
- 不写没必要的小 helper,只有复用明显且能降低理解成本时才抽。拆小方法的规则是:
- 2~3 行的代码在 3~5 处以上重复出现,那么适合拆小方法,但是优先考虑使用 JDK 自带工具及 utils 包的工具方法。
- 一个独立的业务逻辑具有 20行以上的代码量那么适合拆小方法。否则优先 在代码中使用注释分段执行并标记注释。
- 一个方法超过 40 行就适合评估拆方法。
- 大段 `if/else` 分支承载独立业务流程时,即使只有一个调用点,也可以抽成有业务含义的小方法。
- 不为了测试扩大生产代码的 public API。
- 不要增加只为测试存在的生产方法。
- 没用到的字段、方法、分支、返回值要删掉。
- 方法、字段可见性要明确,能 `private` 就不要保留为默认或 `public`。
- 默认不要写内部类;能提成独立类就提成独立类。
- 类不要声明为 `final`,统一使用 `public`。
- 不要使用 `@SneakyThrows`;需要 `try/catch` 异常时,用简短 `msg` 描述错误,并通过 `log.error(msg, e)` 打印异常。
- Java 中能用 Lombok 解决 getter / setter 模板代码的地方,优先使用 Lombok。
- 重复胶水代码要适度收敛,但收敛方式不能比原逻辑更难懂。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public enum ConfigI18nKey {
CONFIG_DS_DEPLOY_ALIYUN_INSTANCE_ID_DESCRIPTION,
CONFIG_RDB_CONFIG_VERSION_DESCRIPTION,
CONFIG_RDB_STORE_PASSWORD_DESCRIPTION,
CONFIG_DS_SSH_PROXY_ENABLED,
CONFIG_DS_SSH_CONFIG_ID,

// ---------------------------------------------------------------------------------------------------
// for Type :com.clougence.clouddm.base.metadata.dsconfig.rdb.RdbConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,12 @@ public class DataSourceConfig implements DeserializeAble, ConfigKeys {
// ------------------------------------------------------------------------------------------------------------------------ basic
@ConfigDef(name = "instanceId", descKey = ConfigI18nKey.CONFIG_DS_INSTANCE_ID_DESCRIPTION)
private String instanceId;

/** DataSourceType */
@ConfigDef(name = DM_DS_KEY_DS_TYPE, descKey = ConfigI18nKey.CONFIG_DS_TYPE_DESCRIPTION)
private DataSourceType dataSourceType;

@ConfigDef(name = DM_DS_KEY_VERSION, descKey = ConfigI18nKey.CONFIG_RDB_VERSION_DESCRIPTION)
private String version;

@ConfigDef(name = DM_DS_KEY_DRIVER_VERSION, descKey = ConfigI18nKey.CONFIG_RDB_VERSION_DESCRIPTION, readOnly = false)
private String driverVersion;

@ConfigDef(name = DM_DS_KEY_SEC_TYPE, descKey = ConfigI18nKey.CONFIG_DS_SECURITY_TYPE_DESCRIPTION, readOnly = false, valueAdvance = "NONE / USER_PASSWD / ONLY_PASSWD / ONLY_USER / USER_PASSWD_WITH_TLS / KERBEROS")
private SecurityType securityType;

Expand Down Expand Up @@ -77,26 +72,18 @@ public class DataSourceConfig implements DeserializeAble, ConfigKeys {

@ConfigDef(name = DM_DS_KEY_USERNAME, descKey = ConfigI18nKey.CONFIG_RDB_USERNAME_DESCRIPTION, readOnly = false)
private String userName;

@ConfigDef(name = DM_DS_KEY_PASSWORD, descKey = ConfigI18nKey.CONFIG_RDB_PASSWORD_DESCRIPTION, isSecret = true, readOnly = false)
private String password;

@ConfigDef(name = "defaultDataBase", valueRequire = false, descKey = ConfigI18nKey.CONFIG_RDB_DEFAULT_DB_DESCRIPTION, readOnly = false)
private String defaultDataBase;

@ConfigDef(name = "defaultSchema", valueRequire = false, descKey = ConfigI18nKey.CONFIG_RDB_DEFAULT_SCHEMA_DESCRIPTION, readOnly = false)
private String defaultSchema;

/** ip:port */
@ConfigDef(name = DM_DS_KEY_HOST, descKey = ConfigI18nKey.CONFIG_RDB_CONN_HOST_DESCRIPTION, readOnly = false)
private String host;

@ConfigDef(name = "connectTimeoutMs", defaultValue = "5000", valueRequire = false, descKey = ConfigI18nKey.CONFIG_RDB_CONN_TIMEOUT_MS_DESCRIPTION, readOnly = false, valueAdvance = "2000 - 100000", group = DsConfigGroup.OPTIONS)
private Long connectTimeoutMs;

@ConfigDef(name = "isolation", defaultValue = "DEFAULT", valueAdvance = "DEFAULT/READ_UNCOMMITTED/READ_COMMITTED/REPEATABLE_READ/SERIALIZABLE", descKey = ConfigI18nKey.CONFIG_RDB_ISOLATION_DESCRIPTION, readOnly = false)
private String isolation;

@ConfigDef(name = "autoCommit", defaultValue = "true", valueAdvance = "true or false", descKey = ConfigI18nKey.CONFIG_RDB_TRANSACTION_DESCRIPTION, readOnly = false)
private Boolean autoCommit;

Expand All @@ -109,6 +96,10 @@ public class DataSourceConfig implements DeserializeAble, ConfigKeys {
// ----------------------------------------------------------------------------------------------- config version UUID,for ssl file update
@ConfigDef(name = "configVersion", descKey = ConfigI18nKey.CONFIG_RDB_CONFIG_VERSION_DESCRIPTION, defaultValue = "1")
private Long configVersion;
@ConfigDef(name = "sshProxyEnabled", defaultValue = "false", valueAdvance = "true or false", descKey = ConfigI18nKey.CONFIG_DS_SSH_PROXY_ENABLED, readOnly = false, group = DsConfigGroup.OPTIONS)
private Boolean sshProxyEnabled;
@ConfigDef(name = "sshConfigId", valueRequire = false, descKey = ConfigI18nKey.CONFIG_DS_SSH_CONFIG_ID, readOnly = false, group = DsConfigGroup.OPTIONS)
private Long sshConfigId;

// aliyun config
// ---------------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2026 杭州开云集致科技有限公司
*
* Licensed 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.
*/
package com.clougence.clouddm.base.metadata.ds;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SecretField {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2026 杭州开云集致科技有限公司
*
* Licensed 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.
*/
package com.clougence.clouddm.base.metadata.ds;

public enum SshAuthType {

PASSWORD,
PRIVATE_KEY;

public static SshAuthType valueOfCode(String code) {
if (code == null || code.isEmpty()) {
return null;
}
for (SshAuthType authType : values()) {
if (authType.name().equalsIgnoreCase(code)) {
return authType;
}
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2026 杭州开云集致科技有限公司
*
* Licensed 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.
*/
package com.clougence.clouddm.base.metadata.ds;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class SshConFeatures implements Serializable {

private Boolean keepAliveEnabled;
private Integer serverAliveIntervalMs;
private Integer connectTimeoutMs;
private SshHostKey hostKey;
private boolean strictHostKeyChecking;
private List<SshKnownHost> knownHosts = new ArrayList<>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2026 杭州开云集致科技有限公司
*
* Licensed 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.
*/
package com.clougence.clouddm.base.metadata.ds;

import java.io.Serializable;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class SshConfig implements Serializable {

private String name;
private String host;
private Integer port;
private String username;
private SshAuthType authType;
@SecretField
private String password;
@SecretField
private String privateKeyData;
@SecretField
private String privateKeyPassphrase;
private SshConFeatures conFeatures;
private SshProxyType proxyType;
private SshProxyFeatures proxyFeatures;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2026 杭州开云集致科技有限公司
*
* Licensed 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.
*/
package com.clougence.clouddm.base.metadata.ds;

import java.io.Serializable;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class SshHostKey implements Serializable {

private boolean strictChecking;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2026 杭州开云集致科技有限公司
*
* Licensed 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.
*/
package com.clougence.clouddm.base.metadata.ds;

import java.io.Serializable;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class SshKnownHost implements Serializable {

private String host;
private Integer port;
private String type;
private String key;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2026 杭州开云集致科技有限公司
*
* Licensed 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.
*/
package com.clougence.clouddm.base.metadata.ds;

import java.io.Serializable;

import com.clougence.clouddm.base.metadata.rdp.enumeration.SecurityType;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class SshProxyFeatures implements Serializable {

private String host;
private Integer port;
private SecurityType securityType;
private String username;
@SecretField
private String password;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2026 杭州开云集致科技有限公司
*
* Licensed 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.
*/
package com.clougence.clouddm.base.metadata.ds;

public enum SshProxyType {

NO_PROXY,
HTTP,
SOCKS4,
SOCKS5;

public static SshProxyType valueOfCode(String code) {
if (code == null || code.isEmpty()) {
return null;
}
for (SshProxyType proxyType : values()) {
if (proxyType.name().equalsIgnoreCase(code)) {
return proxyType;
}
}
return null;
}
}
Loading