From ca4ebe4ed24ce95ab556e45d25ab4933f27dfd2f Mon Sep 17 00:00:00 2001 From: Guillaume Jambet Date: Fri, 8 Dec 2017 14:41:33 +0100 Subject: [PATCH] SONAR-10181 mandatory WS Params are automatically validated on retrieval --- .../sonar/server/ws/WebServiceEngineTest.java | 17 +++++++++++++++++ .../java/org/sonar/api/server/ws/Request.java | 2 +- .../server/ws/internal/ValidatingRequest.java | 18 ++++++++++++++---- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java b/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java index 7f5682f0164..d51ffe981f7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java @@ -199,6 +199,16 @@ public class WebServiceEngineTest { assertThat(response.stream().outputAsString()).isEqualTo("{\"errors\":[{\"msg\":\"The 'message' parameter is missing\"}]}"); } + @Test + public void required_parameter_is_not_set_but_not_called_as_mandatory() { + ValidatingRequest request = new TestRequest().setPath("/api/system/test-required-parameter"); + + DumbResponse response = new DumbResponse(); + underTest.execute(request, response); + + assertThat(response.stream().outputAsString()).isEqualTo("{\"errors\":[{\"msg\":\"The 'required-parameter' parameter is missing\"}]}"); + } + @Test public void optional_parameter_is_not_set() { ValidatingRequest request = new TestRequest().setMethod("GET").setPath("/api/system/print").setParam("message", "Hello World"); @@ -382,6 +392,13 @@ public class WebServiceEngineTest { } }); + // parameter "required-parameter" is required + NewAction helloWorld = createNewDefaultAction(newController, "test-required-parameter"); + helloWorld.createParam("required-parameter").setDescription("required message").setRequired(true); + helloWorld.setHandler((request, response) -> { + String param = request.param("required-parameter"); + }); + createNewDefaultAction(newController, "fail_with_client_abort_exception") .setHandler((request, response) -> { throw new IllegalStateException("fail!", new ClientAbortException()); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java index 4ec66633e7e..d98b26a87b0 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java @@ -44,7 +44,7 @@ import static org.sonar.api.utils.DateUtils.parseDateTimeQuietly; */ public abstract class Request { - private static final String MSG_PARAMETER_MISSING = "The '%s' parameter is missing"; + protected static final String MSG_PARAMETER_MISSING = "The '%s' parameter is missing"; /** * Returns the name of the HTTP method with which this request was made. Possible diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java index e217bd4325b..d28cf8cc702 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java @@ -69,14 +69,17 @@ public abstract class ValidatingRequest extends Request { @CheckForNull public String param(String key) { WebService.Param definition = action.param(key); - String valueOrDefault = defaultString(readParam(key, definition), definition.defaultValue()); - String value = valueOrDefault == null ? null : CharMatcher.WHITESPACE.trimFrom(valueOrDefault); + + String rawValue = readParam(key, definition); + String rawValueOrDefault = defaultString(rawValue, definition.defaultValue()); + String value = rawValueOrDefault == null ? null : CharMatcher.WHITESPACE.trimFrom(rawValueOrDefault); + validateRequiredValue(key, definition, rawValue); if (value == null) { return null; } validatePossibleValues(key, value, definition); - validateMaximumLength(key, definition, valueOrDefault); - validateMinimumLength(key, definition, valueOrDefault); + validateMaximumLength(key, definition, rawValueOrDefault); + validateMinimumLength(key, definition, rawValueOrDefault); validateMaximumValue(key, definition, value); return value; } @@ -202,6 +205,13 @@ public abstract class ValidatingRequest extends Request { checkArgument(valueAsInt <= maximumValue, "'%s' value (%s) must be less than %s", key, valueAsInt, maximumValue); } + private static void validateRequiredValue(String key, WebService.Param definition, String value) { + boolean required = definition.isRequired(); + if (required) { + checkArgument(value != null, format(MSG_PARAMETER_MISSING, key)); + } + } + private static int validateAsNumeric(String key, String value) { try { return Integer.parseInt(value); -- 2.39.5