diff --git a/fizz-core/src/main/java/we/fizz/Pipeline.java b/fizz-core/src/main/java/we/fizz/Pipeline.java index 279731a..b09b758 100644 --- a/fizz-core/src/main/java/we/fizz/Pipeline.java +++ b/fizz-core/src/main/java/we/fizz/Pipeline.java @@ -26,6 +26,7 @@ import java.util.Map; import javax.script.ScriptException; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.data.util.Pair; import we.schema.util.I18nUtils; import org.noear.snack.ONode; import org.slf4j.Logger; @@ -91,14 +92,13 @@ public class Pipeline { long t1 = System.currentTimeMillis(); @SuppressWarnings("unchecked") - List validateErrorList = inputValidate(input, + String validateMsg = this.inputValidate(input, (Map)((Map)this.stepContext.get("input")).get("request")); this.stepContext.addElapsedTime("入参校验", System.currentTimeMillis()-t1); - if (!CollectionUtils.isEmpty(validateErrorList)) { + if (StringUtils.hasText(validateMsg)) { long t2 = System.currentTimeMillis(); - String validateMsg = StringUtils.collectionToCommaDelimitedString(validateErrorList); // 将验证错误信息放入上下文 stepContext.put("validateMsg", validateMsg); Map validateResponse = config.getValidateResponse(); @@ -337,62 +337,59 @@ public class Pipeline { return aggResult; } - @SuppressWarnings("unchecked") - private List inputValidate(Input input, Map clientInput) { + private static final String LANGUAGE_CHINESE = "zh"; + private static final String LANGUAGE_ENGLISH = "en"; + enum ValidateType { + /** + * Header + */ + HEADER("请求头", "Header"), + /** + * Query param + */ + QUERY_PARAM("Query参数", "Query param"), + /** + * Body + */ + BODY("请求体", "Body"), + /** + * Script + */ + SCRIPT("脚本校验", "Script"); + + ValidateType(String tipZh, String tipEn) { + this.tipZh = tipZh; + this.tipEn = tipEn; + } + + String tipZh; + String tipEn; + + public String getTip() { + String language = I18nUtils.getContextLocale().getLanguage(); + if (LANGUAGE_CHINESE.equals(language)) { + return tipZh; + } else if (LANGUAGE_ENGLISH.equals(language)) { + return tipEn; + } + return tipZh; + } + } + + String inputValidate(Input input, Map clientInput) { try { InputConfig config = input.getConfig(); if (config instanceof ClientInputConfig) { Map langDef = ((ClientInputConfig) config).getLangDef(); this.handleLangDef(langDef); - Map headersDef = ((ClientInputConfig) config).getHeadersDef(); - if (!CollectionUtils.isEmpty(headersDef)) { - // 验证headers入参是否符合要求 - List errorList; - PropertiesSupportUtils.setContextSupportPropertyUpperCase(); - try { - errorList = JsonSchemaUtils.validateAllowValueStr(JSON.toJSONString(headersDef), JSON.toJSONString(clientInput.get("headers"))); - } finally { - PropertiesSupportUtils.removeContextSupportPropertyUpperCase(); - } - - if (!CollectionUtils.isEmpty(errorList)) { - return errorList; - } - } - - Map paramsDef = ((ClientInputConfig) config).getParamsDef(); - if (!CollectionUtils.isEmpty(paramsDef)) { - // 验证params入参是否符合要求 - List errorList = JsonSchemaUtils.validateAllowValueStr(JSON.toJSONString(paramsDef), JSON.toJSONString(clientInput.get("params"))); - if (!CollectionUtils.isEmpty(errorList)) { - return errorList; - } - } - - Map bodyDef = ((ClientInputConfig) config).getBodyDef(); - if (!CollectionUtils.isEmpty(bodyDef)) { - // 验证body入参是否符合要求 - List errorList = JsonSchemaUtils.validate(JSON.toJSONString(bodyDef), JSON.toJSONString(clientInput.get("body"))); - if (!CollectionUtils.isEmpty(errorList)) { - return errorList; - } - } - - Map scriptValidate = ((ClientInputConfig) config).getScriptValidate(); - if (!CollectionUtils.isEmpty(scriptValidate)) { - ONode ctxNode = PathMapping.toONode(stepContext); - // 验证入参是否符合脚本要求 - try { - List errorList = (List) ScriptHelper.execute(scriptValidate, ctxNode, stepContext, List.class); - if (!CollectionUtils.isEmpty(errorList)) { - return errorList; - } - } catch (ScriptException e) { - LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(scriptValidate), e); - throw new ExecuteScriptException(e, stepContext, scriptValidate); - } + Pair> validateTypeAndValidateErrorListPair = + this.doInputValidate((ClientInputConfig) config, clientInput); + if (validateTypeAndValidateErrorListPair == null) { + return null; } + return String.format("%s: %s", validateTypeAndValidateErrorListPair.getFirst().getTip(), + StringUtils.collectionToCommaDelimitedString(validateTypeAndValidateErrorListPair.getSecond())); } return null; } finally { @@ -400,6 +397,63 @@ public class Pipeline { } } + private Pair> doInputValidate(ClientInputConfig config, Map clientInput) { + Map headersDef = config.getHeadersDef(); + if (!CollectionUtils.isEmpty(headersDef)) { + // 验证headers入参是否符合要求 + List errorList; + PropertiesSupportUtils.setContextSupportPropertyUpperCase(); + try { + errorList = JsonSchemaUtils.validateAllowValueStr(JSON.toJSONString(headersDef), + JSON.toJSONString(clientInput.get("headers"))); + } finally { + PropertiesSupportUtils.removeContextSupportPropertyUpperCase(); + } + + if (!CollectionUtils.isEmpty(errorList)) { + return Pair.of(ValidateType.HEADER, errorList); + } + } + + Map paramsDef = config.getParamsDef(); + if (!CollectionUtils.isEmpty(paramsDef)) { + // 验证params入参是否符合要求 + List errorList = JsonSchemaUtils.validateAllowValueStr(JSON.toJSONString(paramsDef), + JSON.toJSONString(clientInput.get("params"))); + if (!CollectionUtils.isEmpty(errorList)) { + return Pair.of(ValidateType.QUERY_PARAM, errorList); + } + } + + Map bodyDef = config.getBodyDef(); + if (!CollectionUtils.isEmpty(bodyDef)) { + // 验证body入参是否符合要求 + List errorList = JsonSchemaUtils.validate(JSON.toJSONString(bodyDef), + JSON.toJSONString(clientInput.get("body"))); + if (!CollectionUtils.isEmpty(errorList)) { + return Pair.of(ValidateType.BODY, errorList); + } + } + + Map scriptValidate = config.getScriptValidate(); + if (!CollectionUtils.isEmpty(scriptValidate)) { + ONode ctxNode = PathMapping.toONode(stepContext); + // 验证入参是否符合脚本要求 + try { + @SuppressWarnings("unchecked") + List errorList = (List) ScriptHelper.execute(scriptValidate, ctxNode, stepContext, List.class); + if (!CollectionUtils.isEmpty(errorList)) { + return Pair.of(ValidateType.SCRIPT, errorList); + } + } catch (ScriptException e) { + LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(scriptValidate), e); + throw new ExecuteScriptException(e, stepContext, scriptValidate); + } + } + + return null; + } + @SuppressWarnings("unchecked") private void handleLangDef(Map langDef) { if (!CollectionUtils.isEmpty(langDef)) { diff --git a/fizz-core/src/test/java/we/fizz/InputValidateTests.java b/fizz-core/src/test/java/we/fizz/InputValidateTests.java new file mode 100644 index 0000000..283440f --- /dev/null +++ b/fizz-core/src/test/java/we/fizz/InputValidateTests.java @@ -0,0 +1,134 @@ +package we.fizz; + +import org.junit.jupiter.api.Test; +import org.noear.snack.ONode; +import we.fizz.input.ClientInputConfig; +import we.fizz.input.Input; +import we.schema.util.I18nUtils; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * aggregate input validate tests + * + * @author zhongjie + */ +class InputValidateTests { + private Map jsonSchemaDef = ONode.load("{\n" + + " \"properties\": {\n" + + " \"library\": {\n" + + " \"type\": \"string\"\n" + + " }\n" + + " },\n" + + " \"required\": [\n" + + " \"library\"\n" + + " ],\n" + + " \"type\": [\n" + + " \"object\",\n" + + " \"null\"\n" + + " ]\n" + + "}").toObject(Map.class); + + @Test + void inputValidateHeaderTipTest() { + Pipeline pipeline = new Pipeline(); + + ClientInputConfig clientInputConfig = new ClientInputConfig(); + clientInputConfig.setHeadersDef(jsonSchemaDef); + Input input = new Input(); + input.setConfig(clientInputConfig); + Map clientInput = new HashMap<>(16); + clientInput.put("headers", new HashMap<>(0)); + String validateMsg = pipeline.inputValidate(input, clientInput); + assertNotNull(validateMsg); + assertTrue(validateMsg.startsWith(Pipeline.ValidateType.HEADER.tipZh)); + + I18nUtils.setContextLocale(new Locale("en")); + try { + validateMsg = pipeline.inputValidate(input, clientInput); + assertNotNull(validateMsg); + assertTrue(validateMsg.startsWith(Pipeline.ValidateType.HEADER.tipEn)); + } finally { + I18nUtils.removeContextLocale(); + } + } + + @Test + void inputValidateQueryParamTipTest() { + Pipeline pipeline = new Pipeline(); + + ClientInputConfig clientInputConfig = new ClientInputConfig(); + clientInputConfig.setParamsDef(jsonSchemaDef); + Input input = new Input(); + input.setConfig(clientInputConfig); + Map clientInput = new HashMap<>(16); + clientInput.put("params", new HashMap<>(0)); + String validateMsg = pipeline.inputValidate(input, clientInput); + assertNotNull(validateMsg); + assertTrue(validateMsg.startsWith(Pipeline.ValidateType.QUERY_PARAM.tipZh)); + + I18nUtils.setContextLocale(new Locale("en")); + try { + validateMsg = pipeline.inputValidate(input, clientInput); + assertNotNull(validateMsg); + assertTrue(validateMsg.startsWith(Pipeline.ValidateType.QUERY_PARAM.tipEn)); + } finally { + I18nUtils.removeContextLocale(); + } + } + + @Test + void inputValidateBodyTipTest() { + Pipeline pipeline = new Pipeline(); + + ClientInputConfig clientInputConfig = new ClientInputConfig(); + clientInputConfig.setBodyDef(jsonSchemaDef); + Input input = new Input(); + input.setConfig(clientInputConfig); + Map clientInput = new HashMap<>(16); + clientInput.put("body", new HashMap<>(0)); + String validateMsg = pipeline.inputValidate(input, clientInput); + assertNotNull(validateMsg); + assertTrue(validateMsg.startsWith(Pipeline.ValidateType.BODY.tipZh)); + + I18nUtils.setContextLocale(new Locale("en")); + try { + validateMsg = pipeline.inputValidate(input, clientInput); + assertNotNull(validateMsg); + assertTrue(validateMsg.startsWith(Pipeline.ValidateType.BODY.tipEn)); + } finally { + I18nUtils.removeContextLocale(); + } + } + + @Test + void inputValidateScriptTipTest() { + Pipeline pipeline = new Pipeline(); + + ClientInputConfig clientInputConfig = new ClientInputConfig(); + Map scriptValidate = new HashMap<>(4); + scriptValidate.put("type", "groovy"); + scriptValidate.put("source", "import java.util.List; import java.util.ArrayList; " + + "List errorList = new ArrayList<>(1); errorList.add(\"same thing error\"); return errorList;"); + clientInputConfig.setScriptValidate(scriptValidate); + Input input = new Input(); + input.setConfig(clientInputConfig); + Map clientInput = new HashMap<>(16); + String validateMsg = pipeline.inputValidate(input, clientInput); + assertNotNull(validateMsg); + assertTrue(validateMsg.startsWith(Pipeline.ValidateType.SCRIPT.tipZh)); + + I18nUtils.setContextLocale(new Locale("en")); + try { + validateMsg = pipeline.inputValidate(input, clientInput); + assertNotNull(validateMsg); + assertTrue(validateMsg.startsWith(Pipeline.ValidateType.SCRIPT.tipEn)); + } finally { + I18nUtils.removeContextLocale(); + } + } +} \ No newline at end of file