請教下有沒有在 slb 或者 nginx 層面實施 mock 的開源框架,最好是 java 的
公司用的 nacos 做服務管理,還是 1.4 的老版本,同時還有一些老專案沒接 nacos 直接走 http 請求,測試目前有一套自研的 mock 工具,但是對程式碼有一些侵入,而且有些專案存在依賴不相容問題。
所以現在想一步到位在 ng 層面做 mock 解決所有問題,請教下各位大佬有沒有開源的 mock 框架,或者有沒有其他好的解決方案。
順便就分享下現用的 mock 工具,原理就是在被 mock 類上加註解,然後透過反射替換返回值或者請求到 mock 服務上。
主要實現 2 個功能:
- 根據配置中心的配置直接返回被 mock 方法返回值
- 根據環境將請求轉發到對應環境的 mock 服務,然後在 mock 服務裡面處理邏輯。
領導覺得太 low 了讓在 ng 層實現,所以希望有能在 ng 層實現上面倆功能的工具,求大佬們推薦。
@Aspect
public class ConfMockAspect {
@Autowired
SpelExcetor spelExcetor;
private final static Logger logger = LoggerFactory.getLogger(ConfMockAspect.class);
private static String mock_system_test_url = "http://xxxx";
private static String mock_system_dev_url = "http://xxxx";
@Pointcut("@within(com.mock.ConfMock)")
private void aspect() {}
@Around("aspect()")
public Object around(JoinPoint joinPoint) throws Throwable {
Object target = joinPoint.getTarget();
Class<?> targetClass = target.getClass();
Class<?>[] interfaces = targetClass.getInterfaces();
String sName = targetClass.getSimpleName();
MethodSignature sig = (MethodSignature)joinPoint.getSignature();
Method method = sig.getMethod();
String methodName = method.getName();
Type type = method.getGenericReturnType();
String key = "ConfMock." + sName + "." + methodName;
// 走mock系統
String sysKey1 = "system.ConfMock." + sName;
String sysKey2 = "system.ConfMock." + sName + "." + methodName;
String value = null;
if (LocalCacheRepository.getInstance().get(sysKey1) != null
|| LocalCacheRepository.getInstance().get(sysKey2) != null) {
String url = null;
if (PropertyConstant.CONF_PROD_DEV.equals(AppInstance.getEnv())) {
url = mock_system_dev_url + String.format("/api?className=%s&method=%s¶mClass=%s",
interfaces[0].getName(), methodName, method.getParameterTypes()[0].getName());
} else if (PropertyConstant.CONF_PROD_TEST.equals(AppInstance.getEnv())){
url = mock_system_test_url + String.format("/api?className=%s&method=%s¶mClass=%s",
interfaces[0].getName(), methodName, method.getParameterTypes()[0].getName());
} else {
url = mock_system_uat_url + String.format("/api?className=%s&method=%s¶mClass=%s",
interfaces[0].getName(), methodName, method.getParameterTypes()[0].getName());
}
String param = JSON.toJSONString(joinPoint.getArgs()[0], new LengthFilter());
value = HttpUtil.doPost(param, new HashMap<>(), url);
if (value != null) {
return JSON.parseObject(value, type);
}
} else {
value = getValue(joinPoint, key);
if (value != null) {
Object result = parseReturn(value, type, joinPoint.getArgs());
return result;
}
}
return ((ProceedingJoinPoint)joinPoint).proceed();
}
private String getValue(JoinPoint joinPoint, String key) {
try {
Properties properties = LocalCacheRepository.getInstance().getProperties();
Set<Object> set = properties.keySet();
for (Object srt : set) {
String keyStr = srt.toString();
if (keyStr.startsWith(key)) {
String s = org.apache.commons.lang3.StringUtils.removeStart(keyStr, key);
if (!StringUtils.isEmpty(s)) {
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setRootObject(joinPoint.getArgs());
Boolean result =
(Boolean)parser.parseExpression(org.apache.commons.lang3.StringUtils.removeStart(s, "."))
.getValue(context);
if (result) {
return properties.getProperty(keyStr);
}
}
}
}
if (properties.containsKey(key)) {
return properties.getProperty(key);
}
} catch (Exception e) {
logger.warn("解析key失敗", e);
}
return null;
}
private Object parseReturn(String value, Type type, Object[] args) {
if (String.class.getTypeName().equals(type.getTypeName())) {
return value;
}
Object object = JSON.parse(value);
if (object instanceof JSONArray) {
JSONArray array = (JSONArray)object;
parseValue(array, args);
return array.toJavaObject(type);
} else if (object instanceof JSONObject) {
JSONObject jsonObject = (JSONObject)object;
parseValue(jsonObject, args);
return jsonObject.toJavaObject(type);
}
return object;
}
private void parseValue(JSONArray array, Object rootObject) {
if (array != null && !array.isEmpty()) {
for (int i = 0; i < array.size(); i++) {
Object value = array.get(i);
if (value != null) {
if (value instanceof String) {
Object newValue = doneInSpringContext((String)value, rootObject);
if (newValue != null) {
array.set(i, newValue);
}
} else if (value instanceof JSONObject) {
parseValue((JSONObject)value, rootObject);
} else if (value instanceof JSONArray) {
parseValue((JSONArray)value, rootObject);
}
}
}
}
}
private void parseValue(JSONObject object, Object rootObject) {
Set<String> set = object.keySet();
if (!set.isEmpty()) {
for (String key : set) {
Object value = object.get(key);
if (value != null) {
if (value instanceof String) {
if (isSpel((String)value)) {
Object newValue = doneInSpringContext(spelValue((String)value), rootObject);
if (newValue != null) {
object.put(key, newValue);
}
}
} else if (value instanceof JSONObject) {
parseValue((JSONObject)value, rootObject);
} else if (value instanceof JSONArray) {
parseValue((JSONArray)value, rootObject);
}
}
}
}
}
private static boolean isSpel(String value) {
// ${}
if (value != null && value.startsWith("${") && value.endsWith("}")) {
return true;
}
return false;
}
public static String spelValue(String value) {
if (isSpel(value)) {
value = org.apache.commons.lang3.StringUtils.removeFirst(value, "\\$\\{");
value = org.apache.commons.lang3.StringUtils.removeEnd(value, "}");
return value;
}
return value;
}
private Object doneInSpringContext(String value, Object rootObject) {
try {
return spelExcetor.doneInSpringContext(null, rootObject, value);
} catch (Exception e) {
}
return null;
}
public static class LengthFilter implements ValueFilter{
@Override
public Object process(Object object, String name, Object value) {
if (value != null && value instanceof String) {
String var = (String)value;
if (var.length() > 500) {
return var.substring(0, 500);
}
}
return value;
}
}
相關文章
- 最好的 Go 框架:沒有框架?Go框架
- golang有沒有好的開源遊戲框架Golang遊戲框架
- 請問大俠,DAO的開源框架哪個最好?框架
- 請教什麼是WebServices,在Java如何實現WebJava
- 在學校教學Java是有爭議的Java
- 請教關於mysql有沒有rowid?MySql
- 請教:有什麼常用的 java_selenium 的自動化測試框架Java框架
- Java界有沒有類似DotNetNuke的開源專案?Java
- 淺談 Easy-mock 最好的備胎沒有之一Mock
- 請教windows下有所有的資料檔案,控制檔案,但沒有引數檔案,如何恢復?Windows
- 誠心請教開源專案的學習
- 請教各位:專案管理的開源解決方案如何實現?專案管理
- Jmeter 對 Java 請求的測試實施JMeterJava
- 【原創】警告:實施goldengate之前源庫務必要做的--此點在gg文件裡沒有提到Go
- 在Java中,以下有關類的關聯關係描述錯誤的是()Java
- java培訓沒有錯 錯的是你沒有好好學Java
- 請教物件導向的話,持久層設計有多大區別?物件
- 教一下有P jboss 3.0 and jbuillder 7UI
- 有沒有support這樣的開源軟體
- 沒有開源,生活竟是這樣的......
- 8 個最好的 Java RESTful 框架JavaREST框架
- 請教各位高手,httpclient有沒有辦法偽裝自己的客戶端資訊?HTTPclient客戶端
- 我是剛開學JAVA,想請教一個問題。Java
- 請教老鳥!在jboss中部署程式必須以war或者ear的形式嗎?
- 請教java 的反反編譯Java編譯
- 想問一下有沒有采用 Laravel+Vue 的前後端分離的開源專案可以學習一下的啊?LaravelVue後端
- [請教] 會話Bean呼叫實體Bean時產生的Conection沒有關閉的異常會話Bean
- Java開源框架發展的遐想Java框架
- 有沒有和laravel一樣的golang框架!請推薦一下!LaravelGolang框架
- 我是剛接觸java的,請教大家一問題!Java
- golang有沒有好的AI框架?GolangAI框架
- Java中的四層框架Java框架
- 請教 github.com/antonmedv/expr 有沒有人用過Github
- Mock 框架 Moq 的使用Mock框架
- 線上編輯圖片的實現是怎麼樣的,有沒有關於這類的ajax框架?框架
- 一種在 MediaWiki 頁面中引入 Vue 專案或者其他框架的辦法Vue框架
- 請教:java安全Java
- 沒有部署ingress pod的woker節點telnet slb的80 443埠不通