diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/constant/CommonConstant.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/constant/CommonConstant.java new file mode 100644 index 00000000..0f0b91f3 --- /dev/null +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/constant/CommonConstant.java @@ -0,0 +1,133 @@ +package cd.casic.ci.process.engine.constant; + +import lombok.Data; + +/** + * @author HopeLi + * @version v1.0 + * @ClassName CommonConstant + * @Date: 2025/5/22 9:58 + * @Description: + */ +public interface CommonConstant { + /** + * id + */ + String ID = "id"; + + /** + * 名称 + */ + String NAME = "name"; + + /** + * 编码 + */ + String CODE = "code"; + + /** + * 值 + */ + String VALUE = "value"; + + /** + * 默认标识状态的字段名称 + */ + String STATUS = "status"; + + /** + * 默认逻辑删除的状态值 + */ + String DEFAULT_LOGIC_DELETE_VALUE = "2"; + + /** + * 用户代理 + */ + String USER_AGENT = "User-Agent"; + + /** + * 请求头token表示 + */ + String AUTHORIZATION = "Authorization"; + + /** + * token名称 + */ + String TOKEN_NAME = "token"; + + /** + * token类型 + */ + String TOKEN_TYPE_BEARER = "Bearer"; + + /** + * 首页提示语 + */ + String INDEX_TIPS = "Welcome To Ops"; + + /** + * 未知标识 + */ + String UNKNOWN = "Unknown"; + + /** + * 默认包名 + */ + String DEFAULT_PACKAGE_NAME = "cd.casic"; + + /** + * 默认密码 + */ + String DEFAULT_PASSWORD = "123456"; + + /** + * 请求号在header中的唯一标识 + */ + String REQUEST_NO_HEADER_NAME = "Request-No"; + + /** + * 数据库链接URL标识 + */ + String DATABASE_URL_NAME = "DATABASE_URL_NAME"; + + /** + * 数据库链接驱动标识 + */ + String DATABASE_DRIVER_NAME = "DATABASE_DRIVER_NAME"; + + /** + * 数据库用户标识 + */ + String DATABASE_USER_NAME = "DATABASE_USER_NAME"; + + /** + * 点选验证码 + */ + String IMAGE_CODE_TYPE = "clickWord"; + + /** + * undefined未知 + */ + String UNDEFINED = "undefined"; + + /** + * 数据库配置文件地址 + */ + String DB_PROPERTIES_PATH = "resources/db.properties"; + /** + * resources路径 + */ + String RESOURCES_DIR = "resources"; + + /** + * 开发资源路径 + */ + String DEV_RESOURCES_PATH = "classpath:"; + /* integration*/ + String VERSION_TYPE_INTEGRATION = "integrationTest"; + /* 單元測試 */ + String VERSION_TYPE_UNIT = "unitTest"; + String VERSION_TYPE_STATIC = "staticTest"; + String TASK4_TEST_TYPE = "task4"; + String SONAR_TEST_TYPE = "sonarqube"; +} diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/constant/SymbolConstant.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/constant/SymbolConstant.java new file mode 100644 index 00000000..b64963f1 --- /dev/null +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/constant/SymbolConstant.java @@ -0,0 +1,73 @@ +package cd.casic.ci.process.engine.constant; + +/** + * @author HopeLi + * @version v1.0 + * @ClassName SymbolConstant + * @Date: 2025/5/22 9:53 + * @Description: + */ +public interface SymbolConstant { + + String PERIOD = "."; + + String COMMA = ","; + + String COLON = ":"; + + String SEMICOLON = ";"; + + String EXCLAMATION_MARK = "!"; + + String QUESTION_MARK = "?"; + + String HYPHEN = "-"; + + String ASTERISK = "*"; + + String APOSTROPHE = "`"; + + String DASH = "-"; + + String UNDER_SCORE = "_"; + + String SINGLE_QUOTATION_MARK = "'"; + + String DOUBLE_QUOTATION_MARK = "\""; + + String LEFT_ROUND_BRACKETS = "("; + + String RIGHT_ROUND_BRACKETS = ")"; + + String LEFT_SQUARE_BRACKETS = "["; + + String RIGHT_SQUARE_BRACKETS = "]"; + + String LEFT_ANGLE_BRACKETS = "<"; + + String RIGHT_ANGLE_BRACKETS = ">"; + + String LEFT_CURLY_BRACKETS = "{"; + + String RIGHT_CURLY_BRACKETS = "}"; + + String DOLLAR = "$"; + + String PERCENT = "%"; + + String LEFT_DIVIDE = "/"; + + String RIGHT_DIVIDE = "\\"; + + String LEFT_DOUBLE_DIVIDE = "//"; + + String RIGHT_DOUBLE_DIVIDE = "\\\\"; + + String EQUAL = "="; + + String LF = "\n"; + + String SPACE_4 = " "; + + Long N_N_1_L = -1L; +} diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/constant/SysConfigConstant.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/constant/SysConfigConstant.java new file mode 100644 index 00000000..0ce0135b --- /dev/null +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/constant/SysConfigConstant.java @@ -0,0 +1,15 @@ +package cd.casic.ci.process.engine.constant; + +/** + * @author HopeLi + * @version v1.0 + * @ClassName SysConfigConstant + * @Date: 2025/5/22 9:53 + * @Description: + */ +public interface SysConfigConstant { + /** + * 不需要xss过滤的接口 + */ + String OPS_UN_XSS_FILTER_URL = "OPS_UN_XSS_FILTER_URL"; +} diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/context/ConstantContext.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/context/ConstantContext.java new file mode 100644 index 00000000..45363884 --- /dev/null +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/context/ConstantContext.java @@ -0,0 +1,54 @@ +package cd.casic.ci.process.engine.context; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; + +/** + * @author HopeLi + * @version v1.0 + * @ClassName ConstantContext + * @Date: 2025/5/22 10:03 + * @Description: + */ +public class ConstantContext { + /** + * 所有的常量,可以增删改查 + */ + private static final Dict CONSTANTS_HOLDER = Dict.create(); + + /** + * 添加系统常量 + * + * @author yubaoshan + * @date 2020/6/20 22:32 + */ + public static void putConstant(String code, Object value) { + if (ObjectUtil.hasEmpty(code, value)) { + return; + } + CONSTANTS_HOLDER.put(code, value); + } + + /** + * 删除常量,系统常量无法删除,在sysConfig已判断 + * + * @author yubaoshan + * @date 2020/6/20 22:32 + */ + public static void deleteConstant(String code) { + if (ObjectUtil.hasEmpty(code)) { + return; + } + CONSTANTS_HOLDER.remove(code); + } + + /** + * 获取系统常量本身 + * + * @author yubaoshan + * @date 2020/6/20 22:32 + */ + public static Dict me() { + return CONSTANTS_HOLDER; + } +} diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/context/ConstantContextHolder.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/context/ConstantContextHolder.java new file mode 100644 index 00000000..7bf44ee8 --- /dev/null +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/context/ConstantContextHolder.java @@ -0,0 +1,435 @@ +package cd.casic.ci.process.engine.context; + + +import cd.casic.ci.process.engine.constant.CommonConstant; +import cd.casic.ci.process.engine.constant.SymbolConstant; +import cd.casic.ci.process.engine.constant.SysConfigConstant; +import cd.casic.ci.process.engine.druid.DruidProperties; +import cd.casic.ci.process.engine.oauth.OauthConfigs; +import cd.casic.ci.process.engine.pojo.CryptogramConfigs; +import cd.casic.framework.commons.exception.ServiceException; +import cd.casic.framework.commons.exception.enums.GlobalErrorCodeConstants; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.log.Log; + +import java.util.List; + +/** + * 系统参数配置获取 + * + * @author xuyuxiang + * @date 2020/4/14 15:34 + */ +public class ConstantContextHolder { + + private static final Log log = Log.get(); + + /** + * 获取租户功能是否开启 + * + * @author xuyuxiang + * @date 2020/9/3 + */ + public static Boolean getTenantOpenFlag() { + return getSysConfigWithDefault("OPS_TENANT_OPEN", Boolean.class, false); + } + + /** + * 获取放开xss过滤的接口 + * + * @author yubaoshan + * @date 2020/6/20 22:13 + */ + public static List getUnXssFilterUrl() { + String snowyUnXssFilterUrl = getSysConfigWithDefault(SysConfigConstant.OPS_UN_XSS_FILTER_URL, String.class, null); + if (ObjectUtil.isEmpty(snowyUnXssFilterUrl)) { + return CollectionUtil.newArrayList(); + } else { + return CollectionUtil.toList(snowyUnXssFilterUrl.split(SymbolConstant.COMMA)); + } + } + + /** + * 获取演示环境开关是否开启,默认为false + * + * @author yubaoshan + * @date 2020/6/20 22:13 + */ + public static Boolean getDemoEnvFlag() { + return getSysConfigWithDefault("OPS_DEMO_ENV_FLAG", Boolean.class, false); + } + + + /** + * 获取Druid默认用户名密码 + * + * @author yubaoshan + * @date 2022/5/16 + */ + public static DruidProperties getDruidLoginConfigs() { + String snowyDruidLoginUsername = getSysConfigWithDefault("OPS_DRUID_LOGIN_USERNAME", String.class, RandomUtil.randomString(10)); + String snowyDruidLoginPassword = getSysConfigWithDefault("OPS_DRUID_LOGIN_PASSWORD", String.class, RandomUtil.randomString(10)); + + DruidProperties druidProperties = new DruidProperties(); + druidProperties.setLoginUsername(snowyDruidLoginUsername); + druidProperties.setLoginPassword(snowyDruidLoginPassword); + return druidProperties; + } + + + /** + * 获取jwt密钥,默认是32位随机字符串 + * + * @author yubaoshan + * @date 2020/6/19 18:08 + */ + public static String getJwtSecret() { + return getSysConfigWithDefault("OPS_JWT_SECRET", String.class, RandomUtil.randomString(32)); + } + + /** + * 获取默认密码 + * + * @author yubaoshan + * @date 2020/6/19 18:08 + */ + public static String getDefaultPassWord() { + return getSysConfigWithDefault("OPS_DEFAULT_PASSWORD", String.class, CommonConstant.DEFAULT_PASSWORD); + } + + /** + * 获取会话过期时间,默认2小时 + * + * @author yubaoshan + * @date 2020/7/9 16:18 + */ + public static Long getSessionTokenExpireSec() { + return getSysConfigWithDefault("OPS_SESSION_EXPIRE", Long.class, 2 * 60 * 60L); + } + + /** + * 获取token过期时间(单位:秒) + *

+ * 默认时间1天 + * + * @author xuyuxiang + * @date 2020/6/19 18:08 + */ + public static Long getTokenExpireSec() { + return getSysConfigWithDefault("OPS_TOKEN_EXPIRE", Long.class, 86400L); + } + + /** + * 获取自定义的windows环境本地文件上传路径 + * + * @author xuyuxiang + * @date 2020/6/19 18:09 + */ + public static String getDefaultFileUploadPathForWindows() { + return getSysConfigWithDefault("OPS_FILE_UPLOAD_PATH_FOR_WINDOWS", String.class, ""); + } + + /** + * 获取自定义的linux环境本地文件上传路径 + * + * @author xuyuxiang + * @date 2020/6/19 18:09 + */ + public static String getDefaultFileUploadPathForLinux() { + return getSysConfigWithDefault("OPS_FILE_UPLOAD_PATH_FOR_LINUX", String.class, ""); + } + + /** + * 获取是否允许单用户登陆的开关, 默认为false + * + * @author xuyuxiang + * @date 2020/6/19 18:09 + */ + public static Boolean getEnableSingleLogin() { + return getSysConfigWithDefault("OPS_ENABLE_SINGLE_LOGIN", Boolean.class, false); + } + + /** + * 获取阿里云定位接口 + * + * @author xuyuxiang + * @date 2020/7/20 9:20 + **/ + public static String getIpGeoApi() { + return getSysConfig("OPS_IP_GEO_API", String.class, false); + } + + /** + * 获取阿里云定位appCode + * + * @author xuyuxiang + * @date 2020/7/20 10:33 + **/ + public static String getIpGeoAppCode() { + return getSysConfig("OPS_IP_GEO_APP_CODE", String.class, false); + } + + /** + * 获取Oauth码云第三方登录的配置 + * + * @author xuyuxiang + * @date 2020/7/28 17:16 + **/ + public static OauthConfigs getGiteeOauthConfigs() { + String snowyClientId = getSysConfig("OPS_OAUTH_GITEE_CLIENT_ID", String.class, true); + String snowyClientSecret = getSysConfig("OPS_OAUTH_GITEE_CLIENT_SECRET", String.class, true); + String snowyRedirectUri = getSysConfig("OPS_OAUTH_GITEE_REDIRECT_URI", String.class, true); + + OauthConfigs oauthConfigs = new OauthConfigs(); + oauthConfigs.setClientId(snowyClientId); + oauthConfigs.setClientSecret(snowyClientSecret); + oauthConfigs.setRedirectUri(snowyRedirectUri); + return oauthConfigs; + } + + /** + * 获取OauthGithub第三方登录的配置 + * + * @author xuyuxiang + * @date 2020/7/28 17:16 + **/ + public static OauthConfigs getGithubOauthConfigs() { + String snowyClientId = getSysConfig("OPS_OAUTH_GITHUB_CLIENT_ID", String.class, true); + String snowyClientSecret = getSysConfig("OPS_OAUTH_GITHUB_CLIENT_SECRET", String.class, true); + String snowyRedirectUri = getSysConfig("OPS_OAUTH_GITHUB_REDIRECT_URI", String.class, true); + + OauthConfigs oauthConfigs = new OauthConfigs(); + oauthConfigs.setClientId(snowyClientId); + oauthConfigs.setClientSecret(snowyClientSecret); + oauthConfigs.setRedirectUri(snowyRedirectUri); + return oauthConfigs; + } + + /** + * 获取是否允许Oauth用户登陆的开关, 默认为false + * + * @author xuyuxiang + * @date 2020/7/28 16:37 + **/ + public static Boolean getEnableOauthLogin() { + return getSysConfigWithDefault("OPS_ENABLE_OAUTH_LOGIN", Boolean.class, false); + } + + /** + * 获取前端项目的地址 + * + * @author xuyuxiang + * @date 2020/7/29 14:08 + **/ + public static String getWebUrl() { + return getSysConfig("OPS_WEB_URL", String.class, true); + } + + /** + * 获取支付宝支付成功转发地址 + * + * @author xuyuxiang + * @date 2020/7/29 14:08 + **/ + public static String getAlipayReturnUrl() { + return getSysConfig("OPS_ALIPAY_RETURN_URL", String.class, true); + } + + /** + * 获取OnlyOffice地址 + * + * @author xuyuxiang + * @date 2020/7/29 14:08 + **/ + public static String getOnlyOfficeUrl() { + return getSysConfig("OPS_ONLY_OFFICE_SERVICE_URL", String.class, true); + } + + /** + * 获取config表中的配置,如果为空返回默认值 + * + * @param configCode 变量名称,对应sys_config表中的code + * @param clazz 返回变量值的类型 + * @param defaultValue 如果结果为空返回此默认值 + * @author yubaoshan + * @date 2020/6/20 22:03 + */ + public static T getSysConfigWithDefault(String configCode, Class clazz, T defaultValue) { + String configValue = ConstantContext.me().getStr(configCode); + if (ObjectUtil.isEmpty(configValue)) { + // 将默认值加入到缓存常量 + log.warn(">>> 系统配置sys_config表中存在空项,configCode为:{},系统采用默认值:{}", configCode, defaultValue); + ConstantContext.me().put(configCode, defaultValue); + return defaultValue; + } else { + try { + return Convert.convert(clazz, configValue); + } catch (Exception e) { + return defaultValue; + } + } + } + + /** + * 获取config表中的配置,如果为空,是否抛出异常 + * + * @param configCode 变量名称,对应sys_config表中的code + * @param clazz 返回变量值的类型 + * @param nullThrowExp 若为空是否抛出异常 + * @author yubaoshan + * @date 2020/6/20 22:03 + */ + public static T getSysConfig(String configCode, Class clazz, Boolean nullThrowExp) { + String configValue = ConstantContext.me().getStr(configCode); + if (ObjectUtil.isEmpty(configValue)) { + if (nullThrowExp) { + String format = StrUtil.format(">>> 系统配置sys_config表中存在空项,configCode为:{}", configCode); + log.error(format); + throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), format); + } else { + return null; + } + } else { + try { + return Convert.convert(clazz, configValue); + } catch (Exception e) { + if (nullThrowExp) { + String format = StrUtil.format(">>> 系统配置sys_config表中存在格式错误的值,configCode={},configValue={}", configCode, configValue); + log.error(format); + throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), format); + } else { + return null; + } + } + } + } + + /** + * 获取验证码 开关标识 + * + * @author Jax + * @Date 2021/1/21 15:22 + */ + public static Boolean getCaptchaOpenFlag() { + return getSysConfigWithDefault("OPS_CAPTCHA_OPEN", Boolean.class, true); + } + + /** + * 获取加解密的配置 + * + * @author yubaoshan + */ + public static CryptogramConfigs getCryptogramConfigs() { + boolean snowyTokenEncDec = getSysConfigWithDefault("OPS_TOKEN_ENCRYPTION_OPEN", Boolean.class, true); + boolean snowyVisLogEnc = getSysConfigWithDefault("OPS_VISLOG_ENCRYPTION_OPEN", Boolean.class, true); + boolean snowyOpLogEnc = getSysConfigWithDefault("OPS_OPLOG_ENCRYPTION_OPEN", Boolean.class, true); + boolean snowyFieldEncDec = getSysConfigWithDefault("OPS_FIELD_ENC_DEC_OPEN", Boolean.class, true); + + CryptogramConfigs cryptogramConfigs = new CryptogramConfigs(); + cryptogramConfigs.setTokenEncDec(snowyTokenEncDec); + cryptogramConfigs.setVisLogEnc(snowyVisLogEnc); + cryptogramConfigs.setOpLogEnc(snowyOpLogEnc); + cryptogramConfigs.setFieldEncDec(snowyFieldEncDec); + return cryptogramConfigs; + } + + /** + * 获取代码仓存储路径配置 + * + * @author herenbin + */ + public static String getGitRepositoryFilePath() { + return getSysConfigWithDefault("OPS_VCS_PATH", String.class, "vcs"); + } + + /** + * 获取OnRoad系统账户配置账号 + * + * @author herenbin + */ + public static String getSystemOnRoad() { + return getSysConfigWithDefault("OPS_SYSTEM_ONROAD", String.class, "onroad"); + } + + /** + * 获取 + * + * @author herenbin + */ + public static String getToperaReport() { + return getSysConfigWithDefault("OPS_URL_TOPERA_REPORT", String.class, "http://127.0.0.1:8785"); + } + + /** + * 获取代码扫描服务器地址 + * + * @author herenbin + */ + public static String getScan() { + return getSysConfigWithDefault("OPS_URL_SCAN", String.class, "http://127.0.0.1:8086"); + } + + /** + * 获取OnRoad服务器地址 + * + * @author herenbin + */ + public static String getOnRoadIp() { + return getSysConfigWithDefault("OPS_URL_ON_ROAD", String.class, "http://127.0.0.1:8766"); + } + + /** + * 获取任务四的ip信息 + * + * @author liuyuchao + */ + public static String getSmartRocketIp() { + return getSysConfigWithDefault("OPS_URL_SMART_ROCKET", String.class, "http://192.168.0.158"); + } + + /** + * 获取sonarqube的ip信息 + * + * @author liuyuchao + */ + public static String getSonarqubeIp() { + return getSysConfigWithDefault("SONARQUBE", String.class, "http://192.168.0.17:9002"); + } + + /** + * 获取安世客户端地址 + * + * @author pangrongan + */ + public static String getModelClient() { + return getSysConfigWithDefault("OPS_MODEL_CLIENT", String.class, "http://192.168.0.121:9856"); + } + + /** + * 获取onsim报告 + * + * @author pangrongan + */ + public static String getOnsimReport() { + return getSysConfigWithDefault("OPS_ONSIM_REPORT", String.class, "http://127.0.0.1:8090/providers/onsim/-sim_dsp-a-b-c-result-test_elf-index.html/onsimCoverRate"); + } + + /** + * SCA地址 + */ + public static String getScaIp() { + return getSysConfigWithDefault("OPS_URL_SCA", String.class, "https://175.6.27.252:30002"); + } + + /** + * SCA token + * SCA默认写死 + */ + public static String getScaToken() { + return getSysConfigWithDefault("OPS_TOKEN_SCA", String.class, "6b906a14493644af801efbcdee7cd390"); + } +} diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/druid/DruidProperties.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/druid/DruidProperties.java new file mode 100644 index 00000000..e892ae12 --- /dev/null +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/druid/DruidProperties.java @@ -0,0 +1,167 @@ +package cd.casic.ci.process.engine.druid; + +import cd.casic.ci.process.engine.enums.DbIdEnum; +import cn.hutool.log.Log; +import com.alibaba.druid.pool.DruidDataSource; +import lombok.Data; + +import java.sql.SQLException; +import java.util.Properties; + +/** + * @author HopeLi + * @version v1.0 + * @ClassName DruidProperties + * @Date: 2025/5/22 9:55 + * @Description: + */ +@Data +public class DruidProperties { + + private static final Log log = Log.get(); + + /** + * mysql校验语句 + */ + private final String MYSQL_VALIDATE_QUERY_SQL = "select 1"; + + /** + * oracle校验语句 + */ + private final String ORACLE_VALIDATE_QUERY_SQL = "select 1 from dual"; + + /** + * postgresql校验语句 + */ + private final String POSTGRESQL_VALIDATE_QUERY_SQL = "select version()"; + + /** + * sqlserver校验语句 + */ + private final String SQLSERVER_VALIDATE_QUERY_SQL = "select 1"; + + /** + * 达梦数据库校验语句 + */ + private final String DM_VALIDATE_QUERY_SQL = "select 1"; + + /** + * 人大金仓数据库校验语句 + */ + private final String KINGBASEES_VALIDATE_QUERY_SQL = "select 1"; + + private String loginUsername; + + private String loginPassword; + + private String url; + + private String username; + + private String password; + + private String driverClassName; + + private Integer initialSize = 2; + + private Integer minIdle = 1; + + private Integer maxActive = 20; + + private Integer maxWait = 60000; + + private Integer timeBetweenEvictionRunsMillis = 60000; + + private Integer minEvictableIdleTimeMillis = 300000; + + private String validationQuery; + + private Boolean testWhileIdle = true; + + private Boolean testOnBorrow = true; + + private Boolean testOnReturn = true; + + private Boolean poolPreparedStatements = true; + + private Integer maxPoolPreparedStatementPerConnectionSize = 20; + + private String filters = "stat,slf4j"; + + private String dataSourceName; + + public void config(DruidDataSource dataSource) { + + dataSource.setUrl(url); + dataSource.setUsername(username); + dataSource.setPassword(password); + + dataSource.setDriverClassName(driverClassName); + //定义初始连接数 + dataSource.setInitialSize(initialSize); + //最小空闲 + dataSource.setMinIdle(minIdle); + //定义最大连接数 + dataSource.setMaxActive(maxActive); + //最长等待时间 + dataSource.setMaxWait(maxWait); + + //配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + + //配置一个连接在池中最小生存的时间,单位是毫秒 + dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + dataSource.setValidationQuery(getValidateQueryByUrl(url)); + dataSource.setTestWhileIdle(testWhileIdle); + dataSource.setTestOnBorrow(testOnBorrow); + dataSource.setTestOnReturn(testOnReturn); + + //打开PSCache,并且指定每个连接上PSCache的大小 + dataSource.setPoolPreparedStatements(poolPreparedStatements); + dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); + + try { + dataSource.setFilters(filters); + } catch (SQLException e) { + log.error(">>> 数据库连接池初始化异常:{}", e.getMessage()); + } + } + + public Properties createProperties() { + Properties properties = new Properties(); + properties.put("url", this.url); + properties.put("username", this.username); + properties.put("password", this.password); + properties.put("driverClassName", this.driverClassName); + properties.put("initialSize", this.initialSize); + properties.put("maxActive", this.maxActive); + properties.put("minIdle", this.minIdle); + properties.put("maxWait", this.maxWait); + properties.put("poolPreparedStatements", this.poolPreparedStatements); + properties.put("maxPoolPreparedStatementPerConnectionSize", this.maxPoolPreparedStatementPerConnectionSize); + properties.put("validationQuery", getValidateQueryByUrl(this.url)); + properties.put("testOnBorrow", this.testOnBorrow); + properties.put("testOnReturn", this.testOnReturn); + properties.put("testWhileIdle", this.testWhileIdle); + properties.put("timeBetweenEvictionRunsMillis", this.timeBetweenEvictionRunsMillis); + properties.put("minEvictableIdleTimeMillis", this.minEvictableIdleTimeMillis); + properties.put("filters", this.filters); + return properties; + } + + private String getValidateQueryByUrl(String url) { + if (url.contains(DbIdEnum.ORACLE.getName())) { + return ORACLE_VALIDATE_QUERY_SQL; + } else if (url.contains(DbIdEnum.PG_SQL.getName())) { + return POSTGRESQL_VALIDATE_QUERY_SQL; + } else if (url.contains(DbIdEnum.MS_SQL.getName())) { + return SQLSERVER_VALIDATE_QUERY_SQL; + } else if (url.contains(DbIdEnum.DM_SQL.getName())) { + return DM_VALIDATE_QUERY_SQL; + } else if (url.contains(DbIdEnum.KINGBASE_ES.getName())) { + return KINGBASEES_VALIDATE_QUERY_SQL; + } else { + return MYSQL_VALIDATE_QUERY_SQL; + } + } +} diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/enums/DbIdEnum.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/enums/DbIdEnum.java new file mode 100644 index 00000000..ec9bcd21 --- /dev/null +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/enums/DbIdEnum.java @@ -0,0 +1,53 @@ +package cd.casic.ci.process.engine.enums; + +import lombok.Getter; + +/** + * @author HopeLi + * @version v1.0 + * @ClassName DbIdEnum + * @Date: 2025/5/22 9:56 + * @Description: + */ +@Getter +public enum DbIdEnum { + /** + * mysql + */ + MYSQL("mysql", "mysql"), + + /** + * pgsql + */ + PG_SQL("pgsql", "postgresql"), + + /** + * oracle + */ + ORACLE("oracle", "oracle"), + + /** + * mssql + */ + MS_SQL("mssql", "sqlserver"), + + /** + * 达梦数据库 + */ + DM_SQL("dm", "dm"), + + /** + * 人大金仓数据库 + */ + KINGBASE_ES("kingbase", "kingbasees"); + + private final String code; + + private final String name; + + DbIdEnum(String code, String name) { + this.code = code; + this.name = name; + } + +} diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/oauth/OauthConfigs.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/oauth/OauthConfigs.java new file mode 100644 index 00000000..49b146e7 --- /dev/null +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/oauth/OauthConfigs.java @@ -0,0 +1,29 @@ +package cd.casic.ci.process.engine.oauth; + +import lombok.Data; + +/** + * @author HopeLi + * @version v1.0 + * @ClassName OauthConfigs + * @Date: 2025/5/22 10:02 + * @Description: + */ +@Data +public class OauthConfigs { + + /** + * clientId + */ + private String clientId; + + /** + * clientSecret + */ + private String clientSecret; + + /** + * 回调地址 + */ + private String redirectUri; +} diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/pojo/CryptogramConfigs.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/pojo/CryptogramConfigs.java new file mode 100644 index 00000000..796137fe --- /dev/null +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/pojo/CryptogramConfigs.java @@ -0,0 +1,33 @@ +package cd.casic.ci.process.engine.pojo; + +import lombok.Data; + +/** + * @author HopeLi + * @version v1.0 + * @ClassName CryptogramConfigs + * @Date: 2025/5/22 10:05 + * @Description: + */ +@Data +public class CryptogramConfigs { + /** + * token是否加解密 + */ + private Boolean tokenEncDec; + + /** + * 操作日志是否加密 + */ + private Boolean opLogEnc; + + /** + * 登录登出日志是否加密 + */ + private Boolean visLogEnc; + + /** + * 铭感字段值是否加解密 + */ + private Boolean fieldEncDec; +} diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/worker/ScaSbomWorker.java b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/worker/ScaSbomWorker.java index d504f6f0..19fd61ff 100644 --- a/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/worker/ScaSbomWorker.java +++ b/modules/module-ci-process-biz/src/main/java/cd/casic/ci/process/engine/worker/ScaSbomWorker.java @@ -1,253 +1,236 @@ -//package cd.casic.ci.process.engine.worker; -// -//import cd.casic.ci.common.pipeline.annotation.Plugin; -//import cd.casic.ci.process.engine.configinfo.ScaSbomConfigInfo; -//import cd.casic.ci.process.engine.runContext.BaseRunContext; -//import cd.casic.ci.process.engine.runContext.TaskRunContext; -//import cd.casic.ci.process.process.dataObject.base.PipBaseElement; -//import cd.casic.ci.process.process.dataObject.pipeline.PipPipeline; -//import cd.casic.ci.process.process.dataObject.target.TargetVersion; -//import cd.casic.ci.process.process.dataObject.task.PipTask; -//import cd.casic.ci.process.process.service.pipeline.PipelineService; -//import cd.casic.ci.process.process.service.target.impl.TargetVersionServiceImpl; -//import cd.casic.ci.process.process.service.task.impl.TaskServiceImpl; -//import cd.casic.framework.commons.exception.ServiceException; -//import cd.casic.framework.commons.exception.enums.GlobalErrorCodeConstants; -//import cn.hutool.core.util.ObjectUtil; -//import com.alibaba.fastjson.JSON; -//import com.alibaba.fastjson.JSONObject; -//import jakarta.annotation.Resource; -//import lombok.extern.slf4j.Slf4j; -//import org.apache.commons.lang3.StringUtils; -//import org.springframework.beans.BeanUtils; -//import org.springframework.core.io.FileSystemResource; -//import org.springframework.http.*; -//import org.springframework.util.LinkedMultiValueMap; -//import org.springframework.util.MultiValueMap; -//import org.springframework.web.client.RestTemplate; -// -//import java.io.File; -//import java.security.KeyManagementException; -//import java.security.KeyStoreException; -//import java.security.NoSuchAlgorithmException; -//import java.util.*; -// -///** -// * @author HopeLi -// * @version v1.0 -// * @ClassName ScaSbomWorker -// * @Date: 2025/5/21 9:30 -// * @Description: -// */ -//@Slf4j -//@Plugin(taskType = "ScaSbom") -//public class ScaSbomWorker extends HttpWorker{ -// -// private static final int POLLING_INTERVAL = 5000; // 轮询间隔,单位:毫秒 -// private static final int MAX_POLLING_TIMES = 100; // 最大退出次数 -// -// @Resource -// private PipelineService pipelineService; -// -// @Resource -// private TargetVersionServiceImpl targetVersionService; -// -// @Resource -// private TaskServiceImpl pipelineNodeInfoService; -// -// -// public String work(BaseRunContext workerParam) { -// int statusCode = 0; -// -// PipBaseElement contextDef = workerParam.getContextDef(); -// log.info("================SCA-SBOM节点执行==================="); -// if (ObjectUtil.isEmpty(contextDef)) { -// log.error("未查询到节点[{}]配置,taskType = ScaSbom"); -// return "-1"; -// } -// if (ObjectUtil.isEmpty(contextDef)) { -// log.error("未查询到节点[{}]配置,taskType = ScaSbom"); -// return "-1"; -// } -// -// String filePath = ""; -// if (contextDef instanceof PipTask pipTask){ -// // 查询并下载目标文件 -// String pipelineId = pipTask.getPipelineId(); -// //根据流水线id查询流水线信息 -// PipPipeline pipeline = pipelineService.getById(pipelineId); -// //根据目标id查询目标信息 -// if (StringUtils.isEmpty(pipeline.getTargetVersionId())){ -// throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"目标文件不存在"); -// } -// TargetVersion targetVersion = targetVersionService.getById(pipeline.getTargetVersionId()); -// filePath = targetVersion.getFilePath(); -// -// try { -// -// -// File file = new File(filePath); -// if (!file.exists() || !file.canRead()) { -// log.error("目标文件不存在或不可读"); -//// nodeLogger.appendErrorNow("目标文件不存在或不可读"); -// return "-1"; -// } -// -// handleUpload(workerParam, contextDef, pipTask.getTaskProperties(), file); -// }catch (Exception e){ -// throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"SCA-SBOM节点执行失败"); -// } -// } -// -// -// return statusCode + ""; -// } -// -// private void handleUpload(BaseRunContext workerParam, PipBaseElement pipelineNodeConfigInfo, -// Map scaSbomConfigInfo, File file) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { -// RestTemplate restTemplate = getRestTemplateWithoutSANCheck(); -// String scaUploadUrl = ConstantContextHolder.getScaIp() + "/openapi/v1/sbom/detect-file"; -// MultiValueMap body = buildRequestBody(scaSbomConfigInfo, file); -// HttpHeaders headers = createHeaders(); -// headers.setContentType(MediaType.MULTIPART_FORM_DATA); -// headers.add("OpenApiUserToken", ConstantContextHolder.getScaToken()); -// HttpEntity> requestEntity = new HttpEntity<>(body, headers); -// -// log.info("SCA上传接口:" + scaUploadUrl); -// JSONObject response = restTemplate.postForObject(scaUploadUrl, requestEntity, JSONObject.class); -// String message = response.getString("message"); -// -// if (message.equals("success")) { -// nodeLogger.appendNow("==================SCA上传成功================="); -// JSONObject data = response.getJSONObject("data"); -// Integer scaTaskId = data.getInteger("scaTaskId"); -// Integer applicationId = data.getInteger("applicationId"); -// -// scaSbomConfigInfo.setScaTaskId(scaTaskId); -// scaSbomConfigInfo.setApplicationId(applicationId); -// //更新到节点json数据 -// String nodeJson = JSON.toJSONString(scaSbomConfigInfo); -// pipelineNodeConfigInfo.setInfo(nodeJson); -// PipelineNodeInfoParam pipelineNodeInfoParam = new PipelineNodeInfoParam(); -// BeanUtils.copyProperties(pipelineNodeConfigInfo, pipelineNodeInfoParam); -// pipelineNodeInfoService.update(pipelineNodeInfoParam); -// workerParam.getPipelineNodeConfigInfo().setInfo(nodeJson); -// -// pollTaskStatus(restTemplate, scaTaskId); -// } else if (message.equals("应用已经存在")) { -// Integer oldScaTaskId = scaSbomConfigInfo.getScaTaskId(); -// Integer oldApplicationId = scaSbomConfigInfo.getApplicationId(); -// int restartResult = reStartTask(restTemplate, oldApplicationId); -// if (restartResult != 0) { -// return; -// } -// pollTaskStatus(restTemplate, oldScaTaskId); -// } else { -// nodeLogger.appendNow("==================SCA接口异常,调用失败================="); -// } -// } -// -// private MultiValueMap buildRequestBody(ScaSbomConfigInfo scaSbomConfigInfo, File file) { -// MultiValueMap body = new LinkedMultiValueMap<>(); -// body.add("file", new FileSystemResource(file)); -// body.add("projectName", scaSbomConfigInfo.getProjectName()); -// body.add("applicationName", scaSbomConfigInfo.getApplicationName()); -// body.add("applicationVersion", scaSbomConfigInfo.getApplicationVersion()); -// body.add("applicationDescription", scaSbomConfigInfo.getApplicationDescription()); -// return body; -// } -// -// /** -// * 创建请求头 -// * -// * @return HttpHeaders -// */ -// private HttpHeaders createHeaders() { -// HttpHeaders headers = new HttpHeaders(); -// headers.add("OpenApiUserToken", ConstantContextHolder.getScaToken()); -// return headers; -// } -// -// /** -// * 轮询请求任务状态 -// * -// * @param restTemplate -// * @param scaTaskId -// */ -// public void pollTaskStatus(RestTemplate restTemplate, Integer scaTaskId) { -// int currentPollingTimes = 0; -// while (currentPollingTimes < MAX_POLLING_TIMES) { -// try { -// HttpHeaders headers = new HttpHeaders(); -// headers.add("OpenApiUserToken", ConstantContextHolder.getScaToken()); -// HttpEntity requestEntity = new HttpEntity<>(null, headers); -// String scaStatusUrl = ConstantContextHolder.getScaIp() + "/openapi/v1/task/" + scaTaskId; -// ResponseEntity response = restTemplate.exchange(scaStatusUrl, HttpMethod.GET, requestEntity, JSONObject.class); -// -// if (Objects.requireNonNull(response.getBody()).getString("message").equals("success")) { -// //"status": 5, //状态 0-未审计 1-未检测 2-排队中 3-检测中 4-检测暂停 5-检测完成 6-检测超时 7-手动停止 8-检测异常 9-已删除 10-拉取中 11-停止中 12-下载中 -// int status = response.getBody().getJSONObject("data").getInteger("status"); -// log.info("当前任务状态: " + status); -// if (status == 5) { -// System.out.println("任务已完成,停止轮询。"); -// log.info("任务已完成,停止轮询。"); -// break; -// } -// } else { -// log.error("获取任务状态失败: " + response.getBody().getString("message")); -// break; -// } -// } catch (Exception e) { -// log.error("获取任务状态时发生错误: " + e.getMessage()); -// } -// try { -// // 轮询间隔 5 秒 -// Thread.sleep(POLLING_INTERVAL); -// } catch (InterruptedException e) { -// Thread.currentThread().interrupt(); -// log.error("轮询被中断: " + e.getMessage()); -// } -// currentPollingTimes++; -// } -// System.out.println("停止轮询"); -// } -// -// /** -// * 重新检测接口 -// * -// * @param restTemplate -// * @param applicationId -// */ -// public int reStartTask(RestTemplate restTemplate, Integer applicationId) { -// try { -// String url = ConstantContextHolder.getScaIp() + "/openapi/v1/task/batch/detect"; -// HttpHeaders headers = new HttpHeaders(); -// headers.add("OpenApiUserToken", ConstantContextHolder.getScaToken()); -// headers.setContentType(MediaType.APPLICATION_JSON); -// headers.add("Accept", MediaType.APPLICATION_JSON.toString()); -// Map> param = new HashMap<>(); -// param.put("applicationIds", Arrays.asList(applicationId)); -// String s = JSON.toJSONString(param); -// HttpEntity formEntry = new HttpEntity<>(s, headers); -// -// JSONObject res = restTemplate.postForObject(url, formEntry, JSONObject.class); -// if (res.getString("message").equals("success")) { -// log.info("重新检测成功"); -// return 0; -// } else { -// log.error("重新检测失败"); -// log.error(res.getString("message")); -// return -1; -// } -// } catch (Exception e) { -// log.error("重新检测失败"); -// log.error(e.getMessage()); -// } -// return 0; -// } -// -// @Override -// public void execute(TaskRunContext context) { -// -// } -//} +package cd.casic.ci.process.engine.worker; + +import cd.casic.ci.common.pipeline.annotation.Plugin; +import cd.casic.ci.process.engine.context.ConstantContextHolder; +import cd.casic.ci.process.engine.runContext.BaseRunContext; +import cd.casic.ci.process.engine.runContext.TaskRunContext; +import cd.casic.ci.process.process.dataObject.base.PipBaseElement; +import cd.casic.ci.process.process.dataObject.pipeline.PipPipeline; +import cd.casic.ci.process.process.dataObject.target.TargetVersion; +import cd.casic.ci.process.process.dataObject.task.PipTask; +import cd.casic.ci.process.process.service.pipeline.PipelineService; +import cd.casic.ci.process.process.service.target.impl.TargetVersionServiceImpl; +import cd.casic.framework.commons.exception.ServiceException; +import cd.casic.framework.commons.exception.enums.GlobalErrorCodeConstants; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.io.File; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.util.*; + +/** + * @author HopeLi + * @version v1.0 + * @ClassName ScaSbomWorker + * @Date: 2025/5/21 9:30 + * @Description: + */ +@Slf4j +@Plugin(taskType = "ScaSbom") +public class ScaSbomWorker extends HttpWorker{ + + private static final int POLLING_INTERVAL = 5000; // 轮询间隔,单位:毫秒 + private static final int MAX_POLLING_TIMES = 100; // 最大退出次数 + + @Resource + private PipelineService pipelineService; + + @Resource + private TargetVersionServiceImpl targetVersionService; + + + public String work(BaseRunContext workerParam) { + int statusCode = 0; + + PipBaseElement contextDef = workerParam.getContextDef(); + log.info("================SCA-SBOM节点执行==================="); + if (ObjectUtil.isEmpty(contextDef)) { + log.error("未查询到节点[{}]配置,taskType = ScaSbom"); + return "-1"; + } + if (ObjectUtil.isEmpty(contextDef)) { + log.error("未查询到节点[{}]配置,taskType = ScaSbom"); + return "-1"; + } + + String filePath = ""; + if (contextDef instanceof PipTask pipTask){ + // 查询并下载目标文件 + String pipelineId = pipTask.getPipelineId(); + //根据流水线id查询流水线信息 + PipPipeline pipeline = pipelineService.getById(pipelineId); + //根据目标id查询目标信息 + if (StringUtils.isEmpty(pipeline.getTargetVersionId())){ + throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"目标文件不存在"); + } + TargetVersion targetVersion = targetVersionService.getById(pipeline.getTargetVersionId()); + filePath = targetVersion.getFilePath(); + + try { + + + File file = new File(filePath); + if (!file.exists() || !file.canRead()) { + log.error("目标文件不存在或不可读"); +// nodeLogger.appendErrorNow("目标文件不存在或不可读"); + return "-1"; + } + + handleUpload(workerParam, contextDef, pipTask.getTaskProperties(), file); + }catch (Exception e){ + throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"SCA-SBOM节点执行失败"); + } + } + + + return statusCode + ""; + } + + private void handleUpload(BaseRunContext workerParam, PipBaseElement pipelineNodeConfigInfo, + Map scaSbomConfigInfo, File file) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { + RestTemplate restTemplate = getRestTemplateWithoutSANCheck(); + String scaUploadUrl = ConstantContextHolder.getScaIp() + "/openapi/v1/sbom/detect-file"; + MultiValueMap body = buildRequestBody(scaSbomConfigInfo, file); + HttpHeaders headers = createHeaders(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + headers.add("OpenApiUserToken", ConstantContextHolder.getScaToken()); + HttpEntity> requestEntity = new HttpEntity<>(body, headers); + + log.info("SCA上传接口:" + scaUploadUrl); + JSONObject response = restTemplate.postForObject(scaUploadUrl, requestEntity, JSONObject.class); + String message = response.getString("message"); + + if (message.equals("success")) { + JSONObject data = response.getJSONObject("data"); + Integer scaTaskId = data.getInteger("scaTaskId"); + + pollTaskStatus(restTemplate, scaTaskId); + } else if (message.equals("应用已经存在")) { + Integer oldScaTaskId = (Integer) scaSbomConfigInfo.get("taskId"); + Integer oldApplicationId = (Integer) scaSbomConfigInfo.get("applicationId"); + int restartResult = reStartTask(restTemplate, oldApplicationId); + if (restartResult != 0) { + return; + } + pollTaskStatus(restTemplate, oldScaTaskId); + } else { + throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"SCA-SBOM节点执行失败"); + } + } + + private MultiValueMap buildRequestBody(Map scaSbomConfigInfo, File file) { + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("file", new FileSystemResource(file)); + body.add("projectName", scaSbomConfigInfo.get("projectName")); + body.add("applicationName", scaSbomConfigInfo.get("applicationName")); + body.add("applicationVersion", scaSbomConfigInfo.get("applicationVersion")); + body.add("applicationDescription", scaSbomConfigInfo.get("applicationDescription")); + return body; + } + + /** + * 创建请求头 + * + * @return HttpHeaders + */ + private HttpHeaders createHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.add("OpenApiUserToken", ConstantContextHolder.getScaToken()); + return headers; + } + + /** + * 轮询请求任务状态 + * + * @param restTemplate + * @param scaTaskId + */ + public void pollTaskStatus(RestTemplate restTemplate, Integer scaTaskId) { + int currentPollingTimes = 0; + while (currentPollingTimes < MAX_POLLING_TIMES) { + try { + HttpHeaders headers = new HttpHeaders(); + headers.add("OpenApiUserToken", ConstantContextHolder.getScaToken()); + HttpEntity requestEntity = new HttpEntity<>(null, headers); + String scaStatusUrl = ConstantContextHolder.getScaIp() + "/openapi/v1/task/" + scaTaskId; + ResponseEntity response = restTemplate.exchange(scaStatusUrl, HttpMethod.GET, requestEntity, JSONObject.class); + + if (Objects.requireNonNull(response.getBody()).getString("message").equals("success")) { + //"status": 5, //状态 0-未审计 1-未检测 2-排队中 3-检测中 4-检测暂停 5-检测完成 6-检测超时 7-手动停止 8-检测异常 9-已删除 10-拉取中 11-停止中 12-下载中 + int status = response.getBody().getJSONObject("data").getInteger("status"); + log.info("当前任务状态: " + status); + if (status == 5) { + System.out.println("任务已完成,停止轮询。"); + log.info("任务已完成,停止轮询。"); + break; + } + } else { + log.error("获取任务状态失败: " + response.getBody().getString("message")); + break; + } + } catch (Exception e) { + log.error("获取任务状态时发生错误: " + e.getMessage()); + } + try { + // 轮询间隔 5 秒 + Thread.sleep(POLLING_INTERVAL); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.error("轮询被中断: " + e.getMessage()); + } + currentPollingTimes++; + } + System.out.println("停止轮询"); + } + + /** + * 重新检测接口 + * + * @param restTemplate + * @param applicationId + */ + public int reStartTask(RestTemplate restTemplate, Integer applicationId) { + try { + String url = ConstantContextHolder.getScaIp() + "/openapi/v1/task/batch/detect"; + HttpHeaders headers = new HttpHeaders(); + headers.add("OpenApiUserToken", ConstantContextHolder.getScaToken()); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.add("Accept", MediaType.APPLICATION_JSON.toString()); + Map> param = new HashMap<>(); + param.put("applicationIds", Arrays.asList(applicationId)); + String s = JSON.toJSONString(param); + HttpEntity formEntry = new HttpEntity<>(s, headers); + + JSONObject res = restTemplate.postForObject(url, formEntry, JSONObject.class); + if (res.getString("message").equals("success")) { + log.info("重新检测成功"); + return 0; + } else { + log.error("重新检测失败"); + log.error(res.getString("message")); + return -1; + } + } catch (Exception e) { + log.error("重新检测失败"); + log.error(e.getMessage()); + } + return 0; + } + + @Override + public void execute(TaskRunContext context) { + + } +}