fix(v0.11): 第二轮走查 P1/P2(按模块优先级)

- davinci:DavinciResult.fail/success;FileManager Feign Fallback 结构化降级;FileStorageManagerImpl 对空 Result/Response 防御
- cwos-resource:RestPortalUserServiceImpl 消除静默 null,统一 CloudwalkResult.fail 与 getDefaultPwd 空串语义
- device-manager:DeviceConstant 改为 final 工具类
- aks:AksRespCodeConstant final + 私有构造
- ninca-crk:启动入口 SLF4J、显式 Feign 扫描包、SpringApplication 写法
- ninca-qk-alarm:main 简化、收窄 @EnableFeignClients(保持 netflix 注解以兼容当前 BOM)

Made-with: Cursor
This commit is contained in:
反编译工作区
2026-04-24 23:59:05 +08:00
parent 0a34c76a82
commit 470103bfdd
8 changed files with 179 additions and 135 deletions
@@ -1,38 +1,12 @@
package cn.cloudwalk.common.device.constant; package cn.cloudwalk.common.device.constant;
/**
* 设备域公共常量(工具类,禁止实例化)。
*/
public final class DeviceConstant {
private DeviceConstant() {}
public interface DeviceConstant
{
public static final String OCEAN_DEFAULT_APPLICATIONID = "10000000"; public static final String OCEAN_DEFAULT_APPLICATIONID = "10000000";
public static final String OCEAN_DEFAULT_BUSINESSID = "10000000"; public static final String OCEAN_DEFAULT_BUSINESSID = "10000000";
public static final String OCEAN_DEFAULT_SERVICECODE = "10000000"; public static final String OCEAN_DEFAULT_SERVICECODE = "10000000";
@@ -40,5 +14,3 @@ public static final String OCEAN_DEFAULT_CUST_ID = "10000000";
public static final String OCEAN_DEFAULT_CROWSERVICEID = "10000000"; public static final String OCEAN_DEFAULT_CROWSERVICEID = "10000000";
public static final Long DEFAULT_DEVICE_HEART_TIME = Long.valueOf(1262275200000L); public static final Long DEFAULT_DEVICE_HEART_TIME = Long.valueOf(1262275200000L);
} }
@@ -42,4 +42,22 @@ public class DavinciResult<T> implements Serializable {
public void setData(T data) { public void setData(T data) {
this.data = data; this.data = data;
} }
/** Feign 降级或本地失败路径使用的结构化失败体(不走异常控制流)。 */
public static <T> DavinciResult<T> fail(String code, String message) {
DavinciResult<T> r = new DavinciResult<>();
r.setSuccess(false);
r.setCode(code);
r.setMessage(message);
return r;
}
public static <T> DavinciResult<T> success(T data) {
DavinciResult<T> r = new DavinciResult<>();
r.setSuccess(true);
r.setCode("0");
r.setMessage("ok");
r.setData(data);
return r;
}
} }
@@ -2,7 +2,10 @@ package cn.cloudwalk.intelligent.davinci.storage.feign;
import cn.cloudwalk.intelligent.davinci.common.result.DavinciResult; import cn.cloudwalk.intelligent.davinci.common.result.DavinciResult;
import cn.cloudwalk.intelligent.davinci.storage.bean.file.dto.FileRemoveDTO; import cn.cloudwalk.intelligent.davinci.storage.bean.file.dto.FileRemoveDTO;
import feign.Request;
import feign.Response; import feign.Response;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@@ -43,39 +46,46 @@ public interface FileManagerFeign {
@Component @Component
class FileManagerFeignClientFallback implements FileManagerFeign { class FileManagerFeignClientFallback implements FileManagerFeign {
private static final String FEIGN_DOWN = "DAVINCI_FEIGN_DOWN";
@Override @Override
public DavinciResult<String> fileUpload(MultipartFile file) { public DavinciResult<String> fileUpload(MultipartFile file) {
throw new RuntimeException("调用Davinci-portal服务,模块文件上传接口异常"); return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,模块文件上传接口降级");
} }
@Override @Override
public DavinciResult<String> fileUpload(String moduleCategory, MultipartFile file) { public DavinciResult<String> fileUpload(String moduleCategory, MultipartFile file) {
throw new RuntimeException("调用Davinci-portal服务,模块文件上传接口异常"); return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,模块文件上传接口降级");
} }
@Override @Override
public DavinciResult<String> bigFileUpload(MultipartFile file) { public DavinciResult<String> bigFileUpload(MultipartFile file) {
throw new RuntimeException("调用Davinci-portal服务,大文件上传接口异常"); return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,大文件上传接口降级");
} }
@Override @Override
public DavinciResult<String> bigFileUpload(String moduleCategory, MultipartFile file) { public DavinciResult<String> bigFileUpload(String moduleCategory, MultipartFile file) {
throw new RuntimeException("调用Davinci-portal服务,大文件上传接口异常"); return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,大文件上传接口降级");
} }
@Override @Override
public Response fileDownload(String path) { public Response fileDownload(String path) {
throw new RuntimeException("调用Davinci-portal服务,获取文件流接口异常"); return Response.builder()
.status(503)
.reason("Feign fallback")
.request(Request.create(Request.HttpMethod.GET, "/", Collections.emptyMap(), null, StandardCharsets.UTF_8))
.body("{}", StandardCharsets.UTF_8)
.build();
} }
@Override @Override
public DavinciResult<String> getFileData(String path) { public DavinciResult<String> getFileData(String path) {
throw new RuntimeException("调用Davinci-portal服务,获取获取文件Base64内容接口异常"); return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,获取文件Base64内容接口降级");
} }
@Override @Override
public DavinciResult<List<String>> remove(FileRemoveDTO dto) { public DavinciResult<List<String>> remove(FileRemoveDTO dto) {
throw new RuntimeException("调用Davinci-portal服务,删除文件接口异常"); return DavinciResult.fail(FEIGN_DOWN, "调用Davinci-portal服务,删除文件接口降级");
} }
} }
} }
@@ -107,6 +107,12 @@ public class FileStorageManagerImpl implements FileStorageManager {
} }
} }
private static void requireDavinciResult(DavinciResult<?> result, String op) throws DavinciServiceException {
if (result == null) {
throw new DavinciServiceException("NULL_RESULT", "Davinci-portal 返回空结果: " + op);
}
}
private static InputStream attachResponseClose(InputStream bodyStream, Response response) { private static InputStream attachResponseClose(InputStream bodyStream, Response response) {
return new FilterInputStream(bodyStream) { return new FilterInputStream(bodyStream) {
@Override @Override
@@ -123,6 +129,7 @@ public class FileStorageManagerImpl implements FileStorageManager {
@Override @Override
public String fileUpload(MultipartFile file) throws DavinciServiceException { public String fileUpload(MultipartFile file) throws DavinciServiceException {
DavinciResult<String> result = this.fileManagerFeign.fileUpload(file); DavinciResult<String> result = this.fileManagerFeign.fileUpload(file);
requireDavinciResult(result, "fileUpload");
if (result.isSuccess()) { if (result.isSuccess()) {
return result.getData(); return result.getData();
} }
@@ -132,6 +139,7 @@ public class FileStorageManagerImpl implements FileStorageManager {
@Override @Override
public String fileUpload(String moduleCategory, MultipartFile file) throws DavinciServiceException { public String fileUpload(String moduleCategory, MultipartFile file) throws DavinciServiceException {
DavinciResult<String> result = this.fileManagerFeign.fileUpload(moduleCategory, file); DavinciResult<String> result = this.fileManagerFeign.fileUpload(moduleCategory, file);
requireDavinciResult(result, "fileUpload(module)");
if (result.isSuccess()) { if (result.isSuccess()) {
return result.getData(); return result.getData();
} }
@@ -141,6 +149,7 @@ public class FileStorageManagerImpl implements FileStorageManager {
@Override @Override
public String bigFileUpload(MultipartFile file) throws DavinciServiceException { public String bigFileUpload(MultipartFile file) throws DavinciServiceException {
DavinciResult<String> result = this.fileManagerFeign.bigFileUpload(file); DavinciResult<String> result = this.fileManagerFeign.bigFileUpload(file);
requireDavinciResult(result, "bigFileUpload");
if (result.isSuccess()) { if (result.isSuccess()) {
return result.getData(); return result.getData();
} }
@@ -150,6 +159,7 @@ public class FileStorageManagerImpl implements FileStorageManager {
@Override @Override
public String bigFileUpload(String moduleCategory, MultipartFile file) throws DavinciServiceException { public String bigFileUpload(String moduleCategory, MultipartFile file) throws DavinciServiceException {
DavinciResult<String> result = this.fileManagerFeign.bigFileUpload(moduleCategory, file); DavinciResult<String> result = this.fileManagerFeign.bigFileUpload(moduleCategory, file);
requireDavinciResult(result, "bigFileUpload(module)");
if (result.isSuccess()) { if (result.isSuccess()) {
return result.getData(); return result.getData();
} }
@@ -159,6 +169,9 @@ public class FileStorageManagerImpl implements FileStorageManager {
@Override @Override
public byte[] fileDownload(String path) throws DavinciServiceException { public byte[] fileDownload(String path) throws DavinciServiceException {
try (Response response = this.fileManagerFeign.fileDownload(path)) { try (Response response = this.fileManagerFeign.fileDownload(path)) {
if (response == null) {
return null;
}
if (response.body() == null) { if (response.body() == null) {
return null; return null;
} }
@@ -174,13 +187,18 @@ public class FileStorageManagerImpl implements FileStorageManager {
public InputStream fileDownloadStream(String path) throws DavinciServiceException { public InputStream fileDownloadStream(String path) throws DavinciServiceException {
Response response = this.fileManagerFeign.fileDownload(path); Response response = this.fileManagerFeign.fileDownload(path);
try { try {
if (response == null) {
return null;
}
if (response.body() == null) { if (response.body() == null) {
response.close(); response.close();
return null; return null;
} }
return attachResponseClose(response.body().asInputStream(), response); return attachResponseClose(response.body().asInputStream(), response);
} catch (IOException e) { } catch (IOException e) {
if (response != null) {
response.close(); response.close();
}
throw new DavinciServiceException("FILE_DOWNLOAD_IO", "调用Davinci-portal服务,获取文件流接口异常"); throw new DavinciServiceException("FILE_DOWNLOAD_IO", "调用Davinci-portal服务,获取文件流接口异常");
} }
} }
@@ -191,6 +209,7 @@ public class FileStorageManagerImpl implements FileStorageManager {
return ""; return "";
} }
DavinciResult<String> result = this.fileManagerFeign.getFileData(path); DavinciResult<String> result = this.fileManagerFeign.getFileData(path);
requireDavinciResult(result, "getFileData");
if (result.isSuccess()) { if (result.isSuccess()) {
return result.getData(); return result.getData();
} }
@@ -200,6 +219,7 @@ public class FileStorageManagerImpl implements FileStorageManager {
@Override @Override
public List<String> remove(FileRemoveDTO dto) throws DavinciServiceException { public List<String> remove(FileRemoveDTO dto) throws DavinciServiceException {
DavinciResult<List<String>> result = this.fileManagerRestFeign.remove(dto); DavinciResult<List<String>> result = this.fileManagerRestFeign.remove(dto);
requireDavinciResult(result, "remove");
if (result.isSuccess()) { if (result.isSuccess()) {
return result.getData(); return result.getData();
} }
@@ -1,6 +1,9 @@
package cn.cloudwalk.client.aks.common.constant; package cn.cloudwalk.client.aks.common.constant;
public class AksRespCodeConstant { public final class AksRespCodeConstant {
private AksRespCodeConstant() {}
public static final String RESPONSE_SUCCESS = "00000000"; public static final String RESPONSE_SUCCESS = "00000000";
public static final String REQUEST_PARAM_ILLEGAL = "56001001"; public static final String REQUEST_PARAM_ILLEGAL = "56001001";
@@ -17,90 +17,107 @@ import cn.cloudwalk.cwos.client.resource.user.feign.PortalUserFeignClient;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
/**
* SDK 侧占位实现:原反编译桩大量 {@code return null},易导致调用方 NPE。
* 生产环境应替换为接入 davinci-portal 的完整实现或仅保留 Feign 委托路径。
*/
@Deprecated
public class RestPortalUserServiceImpl implements PortalUserService {
private static final String SDK_STUB = "76260996";
private static final String SDK_STUB_MSG = "cwos-java-sdk-resource 占位实现未接入 Portal,请使用服务端实现或扩展 Feign";
public class RestPortalUserServiceImpl
implements PortalUserService
{
@Autowired @Autowired
private PortalUserFeignClient portalUserFeignClient; private PortalUserFeignClient portalUserFeignClient;
public CloudwalkResult<String> add(UserAddParam userAddParam, CloudwalkCallContext cloudwalkCallContext) throws ServiceException { @Override
/* 32 */ return null; public CloudwalkResult<String> add(UserAddParam userAddParam, CloudwalkCallContext cloudwalkCallContext)
throws ServiceException {
return CloudwalkResult.fail(SDK_STUB, SDK_STUB_MSG);
} }
@Override
public CloudwalkResult<Boolean> checkPassword(PortalUserCheckPwdParam portalUserCheckPwdParam, CloudwalkCallContext cloudwalkCallContext, HttpServletRequest httpServletRequest) throws ServiceException { public CloudwalkResult<Boolean> checkPassword(PortalUserCheckPwdParam portalUserCheckPwdParam,
/* 37 */ return null; CloudwalkCallContext cloudwalkCallContext, HttpServletRequest httpServletRequest) throws ServiceException {
return CloudwalkResult.fail(SDK_STUB, SDK_STUB_MSG);
} }
@Override
public CloudwalkResult<Boolean> changePassword(PortalUserChangePwdParam portalUserChangePwdParam, CloudwalkCallContext cloudwalkCallContext, HttpServletRequest httpServletRequest) throws ServiceException { public CloudwalkResult<Boolean> changePassword(PortalUserChangePwdParam portalUserChangePwdParam,
/* 42 */ return null; CloudwalkCallContext cloudwalkCallContext, HttpServletRequest httpServletRequest) throws ServiceException {
return CloudwalkResult.fail(SDK_STUB, SDK_STUB_MSG);
} }
@Override
public CloudwalkResult<Boolean> changePwdFromDefault(PortalUserChangePwdParam portalUserChangePwdParam, CloudwalkCallContext cloudwalkCallContext, HttpServletRequest httpServletRequest) throws ServiceException { public CloudwalkResult<Boolean> changePwdFromDefault(PortalUserChangePwdParam portalUserChangePwdParam,
/* 47 */ return null; CloudwalkCallContext cloudwalkCallContext, HttpServletRequest httpServletRequest) throws ServiceException {
return CloudwalkResult.fail(SDK_STUB, SDK_STUB_MSG);
} }
@Override
public CloudwalkResult<Boolean> sendEmail(String s, CloudwalkCallContext cloudwalkCallContext) throws ServiceException { public CloudwalkResult<Boolean> sendEmail(String s, CloudwalkCallContext cloudwalkCallContext)
/* 52 */ return null; throws ServiceException {
return CloudwalkResult.fail(SDK_STUB, SDK_STUB_MSG);
} }
@Override
public CloudwalkResult<Boolean> changePwdBySign(PortalUserGetBacKPwdParam portalUserGetBacKPwdParam, CloudwalkCallContext cloudwalkCallContext, HttpServletRequest httpServletRequest) throws ServiceException { public CloudwalkResult<Boolean> changePwdBySign(PortalUserGetBacKPwdParam portalUserGetBacKPwdParam,
/* 57 */ return null; CloudwalkCallContext cloudwalkCallContext, HttpServletRequest httpServletRequest) throws ServiceException {
return CloudwalkResult.fail(SDK_STUB, SDK_STUB_MSG);
} }
@Override
public CloudwalkResult<PortalUserDetailResult> getCurrentUserDetail(CloudwalkCallContext cloudwalkCallContext) throws ServiceException { public CloudwalkResult<PortalUserDetailResult> getCurrentUserDetail(CloudwalkCallContext cloudwalkCallContext)
/* 62 */ return this.portalUserFeignClient.getCurrentUserDetail(); throws ServiceException {
CloudwalkResult<PortalUserDetailResult> result = this.portalUserFeignClient.getCurrentUserDetail();
if (result == null) {
return CloudwalkResult.fail(SDK_STUB, "Portal Feign 返回空结果");
}
return result;
} }
@Override
public CloudwalkResult<Boolean> changePhoto(String s, CloudwalkCallContext cloudwalkCallContext) throws ServiceException { public CloudwalkResult<Boolean> changePhoto(String s, CloudwalkCallContext cloudwalkCallContext)
/* 67 */ return null; throws ServiceException {
return CloudwalkResult.fail(SDK_STUB, SDK_STUB_MSG);
} }
@Override
public CloudwalkResult<Boolean> resetPassword(String s, CloudwalkCallContext cloudwalkCallContext, HttpServletRequest httpServletRequest) throws ServiceException { public CloudwalkResult<Boolean> resetPassword(String s, CloudwalkCallContext cloudwalkCallContext,
/* 72 */ return null; HttpServletRequest httpServletRequest) throws ServiceException {
return CloudwalkResult.fail(SDK_STUB, SDK_STUB_MSG);
} }
@Override
public void pwdExpireCall() {} public void pwdExpireCall() {}
/**
* 与「默认密码」语义一致:无配置时返回空串,避免调用方 NPE。
*/
@Override
public String getDefaultPwd() { public String getDefaultPwd() {
/* 82 */ return null; return "";
} }
@Override
public CloudwalkResult<Boolean> apiAuth(String s, CloudwalkCallContext cloudwalkCallContext) { public CloudwalkResult<Boolean> apiAuth(String s, CloudwalkCallContext cloudwalkCallContext) {
/* 87 */ return null; return CloudwalkResult.fail(SDK_STUB, SDK_STUB_MSG);
} }
@Override
public CloudwalkResult<Boolean> update(PortalUserEditParam portalUserEditParam, CloudwalkCallContext cloudwalkCallContext) { public CloudwalkResult<Boolean> update(PortalUserEditParam portalUserEditParam,
/* 92 */ return null; CloudwalkCallContext cloudwalkCallContext) {
return CloudwalkResult.fail(SDK_STUB, SDK_STUB_MSG);
} }
@Override
public CloudwalkResult<CloudwalkPageAble<PortalUserQueryResult>> page(UserAccountQueryParam userAccountQueryParam, CloudwalkCallContext cloudwalkCallContext) { public CloudwalkResult<CloudwalkPageAble<PortalUserQueryResult>> page(UserAccountQueryParam userAccountQueryParam,
/* 97 */ return null; CloudwalkCallContext cloudwalkCallContext) {
return CloudwalkResult.fail(SDK_STUB, SDK_STUB_MSG);
} }
@Override
public CloudwalkResult<PortalUserDetailResult> detail(String s, CloudwalkCallContext cloudwalkCallContext) { public CloudwalkResult<PortalUserDetailResult> detail(String s, CloudwalkCallContext cloudwalkCallContext) {
return null; return CloudwalkResult.fail(SDK_STUB, SDK_STUB_MSG);
} }
} }
@@ -5,6 +5,8 @@ import com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration;
import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.spring.autoconfigure.MeterRegistryCustomizer; import io.micrometer.spring.autoconfigure.MeterRegistryCustomizer;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.Banner; import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
@@ -18,18 +20,21 @@ import org.springframework.scheduling.annotation.EnableAsync;
* 轻舟标准 GPU 出入口聚合后端启动类。 * 轻舟标准 GPU 出入口聚合后端启动类。
*/ */
@SpringBootApplication(exclude = {PageHelperAutoConfiguration.class}) @SpringBootApplication(exclude = {PageHelperAutoConfiguration.class})
@EnableFeignClients @EnableFeignClients(basePackages = {"cn.cloudwalk"})
@MapperScan({"cn.cloudwalk.data.**.mapper", "cn.cloudwalk.task.data.mapper"}) @MapperScan({"cn.cloudwalk.data.**.mapper", "cn.cloudwalk.task.data.mapper"})
@EnableAsync @EnableAsync
@EnableCloudwalkEvent @EnableCloudwalkEvent
@EnableAspectJAutoProxy(exposeProxy = true) @EnableAspectJAutoProxy(exposeProxy = true)
public class Application { public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("[标准GPU服务器-出入口版]- 开始启动..."); log.info("[标准GPU服务器-出入口版] 开始启动");
SpringApplication app = new SpringApplication(new Object[] {Application.class}); SpringApplication app = new SpringApplication(Application.class);
app.setBannerMode(Banner.Mode.OFF); app.setBannerMode(Banner.Mode.OFF);
app.run(args); app.run(args);
System.out.println("[标准GPU服务器-出入口版]- 启动完成..."); log.info("[标准GPU服务器-出入口版] 启动完成(进程将持续运行直至关闭)");
} }
@Bean @Bean
@@ -11,13 +11,12 @@ import org.springframework.scheduling.annotation.EnableScheduling;
* 区域告警应用入口:启用 Feign、服务发现、调度与 MyBatis 扫描。 * 区域告警应用入口:启用 Feign、服务发现、调度与 MyBatis 扫描。
*/ */
@MapperScan({"cn.cloudwalk.data.alarm.**.mapper"}) @MapperScan({"cn.cloudwalk.data.alarm.**.mapper"})
@EnableFeignClients(basePackages = {"cn.cloudwalk"}) @EnableFeignClients(basePackages = {"cn.cloudwalk.data.alarm", "cn.cloudwalk.ninca"})
@EnableDiscoveryClient @EnableDiscoveryClient
@SpringBootApplication @SpringBootApplication
@EnableScheduling @EnableScheduling
public class AlarmApplication { public class AlarmApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication application = new SpringApplication(new Object[] {cn.cloudwalk.AlarmApplication.class}); SpringApplication.run(AlarmApplication.class, args);
application.run(args);
} }
} }