aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-ws
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2016-08-31 18:07:29 +0200
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2016-09-01 16:01:12 +0200
commit3373145c7c35f67eca4d7cec04b49ae02c6587fb (patch)
tree7e1dccd2c2907742b415bad3bb851241656efe39 /sonar-ws
parenta9dcddb21deaa014255d8bff601515bbdbdf20ff (diff)
downloadsonarqube-3373145c7c35f67eca4d7cec04b49ae02c6587fb.tar.gz
sonarqube-3373145c7c35f67eca4d7cec04b49ae02c6587fb.zip
SONAR-8004 WS settings/set with a proper WS client
Diffstat (limited to 'sonar-ws')
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/BaseRequest.java81
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java7
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/LocalWsConnector.java12
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/Parameters.java37
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/WsRequest.java9
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/setting/SetRequest.java9
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/setting/SettingsService.java4
-rw-r--r--sonar-ws/src/test/java/org/sonarqube/ws/client/BaseRequestTest.java31
-rw-r--r--sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java2
-rw-r--r--sonar-ws/src/test/java/org/sonarqube/ws/client/setting/SettingsServiceTest.java8
10 files changed, 183 insertions, 17 deletions
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/BaseRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/BaseRequest.java
index 584d9505ae7..57846b6f2c2 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/BaseRequest.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/BaseRequest.java
@@ -19,13 +19,22 @@
*/
package org.sonarqube.ws.client;
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.ListMultimap;
+import java.util.Collection;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonarqube.ws.MediaTypes;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.util.Collections.singletonList;
import static java.util.Objects.requireNonNull;
abstract class BaseRequest<SELF extends BaseRequest> implements WsRequest {
@@ -34,8 +43,7 @@ abstract class BaseRequest<SELF extends BaseRequest> implements WsRequest {
private String mediaType = MediaTypes.JSON;
- // keep the same order -> do not use HashMap
- private final Map<String, String> params = new LinkedHashMap<>();
+ private final DefaultParameters parameters = new DefaultParameters();
BaseRequest(String path) {
this.path = path;
@@ -60,16 +68,79 @@ abstract class BaseRequest<SELF extends BaseRequest> implements WsRequest {
return (SELF) this;
}
+ /**
+ * To set a multi value parameters, provide a Collection with the values
+ */
public SELF setParam(String key, @Nullable Object value) {
checkArgument(!isNullOrEmpty(key), "a WS parameter key cannot be null");
- if (value != null) {
- this.params.put(key, value.toString());
+ if (value == null) {
+ return (SELF) this;
+ }
+
+ if (value instanceof Collection) {
+ Collection<Object> values = (Collection<Object>) value;
+ if (values.isEmpty()) {
+ return (SELF) this;
+ }
+ parameters.setValues(key, values.stream().map(Object::toString).collect(Collectors.toList()));
+ } else {
+ parameters.setValue(key, value.toString());
}
return (SELF) this;
}
@Override
public Map<String, String> getParams() {
- return params;
+ return parameters.keyValues.keySet().stream()
+ .collect(Collectors.toMap(
+ Function.identity(),
+ key -> parameters.keyValues.get(key).get(0),
+ (v1, v2) -> {
+ throw new IllegalStateException(String.format("Duplicate key '%s' in request", v1));
+ },
+ LinkedHashMap::new));
+ }
+
+ @Override
+ public Parameters getParameters() {
+ return parameters;
+ }
+
+ private static class DefaultParameters implements Parameters {
+ // preserve insertion order
+ private final ListMultimap<String, String> keyValues = LinkedListMultimap.create();
+
+ @Override
+ @CheckForNull
+ public String getValue(String key) {
+ return keyValues.containsKey(key) ? keyValues.get(key).get(0) : null;
+ }
+
+ @Override
+ public List<String> getValues(String key) {
+ return keyValues.get(key);
+ }
+
+ @Override
+ public Set<String> getKeys() {
+ return keyValues.keySet();
+ }
+
+ private DefaultParameters setValue(String key, String value) {
+ checkArgument(!isNullOrEmpty(key));
+ checkArgument(!isNullOrEmpty(value));
+
+ keyValues.putAll(key, singletonList(value));
+ return this;
+ }
+
+ private DefaultParameters setValues(String key, Collection<String> values) {
+ checkArgument(!isNullOrEmpty(key));
+ checkArgument(values != null && !values.isEmpty());
+
+ this.keyValues.putAll(key, values.stream().map(Object::toString).collect(Collectors.toList()));
+
+ return this;
+ }
}
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java
index 0ffe844c408..1231c6c7069 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java
@@ -162,9 +162,10 @@ public class HttpConnector implements WsConnector {
HttpUrl.Builder urlBuilder = baseUrl
.resolve(path.startsWith("/") ? path.replaceAll("^(/)+", "") : path)
.newBuilder();
- for (Map.Entry<String, String> param : wsRequest.getParams().entrySet()) {
- urlBuilder.addQueryParameter(param.getKey(), param.getValue());
- }
+ wsRequest.getParameters().getKeys()
+ .forEach(key -> wsRequest.getParameters().getValues(key)
+ .forEach(value -> urlBuilder.addQueryParameter(key, value)));
+
return urlBuilder;
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/LocalWsConnector.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/LocalWsConnector.java
index ca8947e64e7..52e6392f847 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/LocalWsConnector.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/LocalWsConnector.java
@@ -24,6 +24,7 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.util.List;
import org.sonar.api.server.ws.LocalConnector;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -55,9 +56,11 @@ class LocalWsConnector implements WsConnector {
private static class DefaultLocalRequest implements LocalConnector.LocalRequest {
private final WsRequest wsRequest;
+ private final Parameters parameters;
public DefaultLocalRequest(WsRequest wsRequest) {
this.wsRequest = wsRequest;
+ this.parameters = wsRequest.getParameters();
}
@Override
@@ -77,12 +80,17 @@ class LocalWsConnector implements WsConnector {
@Override
public boolean hasParam(String key) {
- return wsRequest.getParams().containsKey(key);
+ return !parameters.getValues(key).isEmpty();
}
@Override
public String getParam(String key) {
- return wsRequest.getParams().get(key);
+ return parameters.getValue(key);
+ }
+
+ @Override
+ public List<String> getMultiParam(String key) {
+ return parameters.getValues(key);
}
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/Parameters.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/Parameters.java
new file mode 100644
index 00000000000..f2ad75bf960
--- /dev/null
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/Parameters.java
@@ -0,0 +1,37 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonarqube.ws.client;
+
+import java.util.List;
+import java.util.Set;
+import javax.annotation.CheckForNull;
+
+public interface Parameters {
+ /**
+ * In the case of a multi value parameter, returns the first element
+ */
+ @CheckForNull
+ String getValue(String key);
+
+ List<String> getValues(String key);
+
+ Set<String> getKeys();
+}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/WsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/WsRequest.java
index 91db5b8a18e..2c52bc50840 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/WsRequest.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/WsRequest.java
@@ -32,8 +32,17 @@ public interface WsRequest {
String getMediaType();
+ /**
+ *
+ * In case of multi value parameters, returns the first value
+ *
+ * @deprecated since 6.1. Use {@link #getParameters()} instead
+ */
+ @Deprecated
Map<String, String> getParams();
+ Parameters getParameters();
+
enum Method {
GET, POST
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/setting/SetRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/setting/SetRequest.java
index 2c09dbd107a..d427fd0d9e1 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/setting/SetRequest.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/setting/SetRequest.java
@@ -21,7 +21,6 @@
package org.sonarqube.ws.client.setting;
import java.util.List;
-import java.util.Map;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
@@ -32,7 +31,7 @@ public class SetRequest {
private final String key;
private final String value;
private final List<String> values;
- private final List<Map<String, String>> fieldValues;
+ private final List<String> fieldValues;
private final String componentId;
private final String componentKey;
@@ -58,7 +57,7 @@ public class SetRequest {
return values;
}
- public List<Map<String, String>> getFieldValues() {
+ public List<String> getFieldValues() {
return fieldValues;
}
@@ -80,7 +79,7 @@ public class SetRequest {
private String key;
private String value;
private List<String> values = emptyList();
- private List<Map<String, String>> fieldValues = emptyList();
+ private List<String> fieldValues = emptyList();
private String componentId;
private String componentKey;
@@ -103,7 +102,7 @@ public class SetRequest {
return this;
}
- public Builder setFieldValues(List<Map<String, String>> fieldValues) {
+ public Builder setFieldValues(List<String> fieldValues) {
this.fieldValues = fieldValues;
return this;
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/setting/SettingsService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/setting/SettingsService.java
index f55de07baca..388bed8616d 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/setting/SettingsService.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/setting/SettingsService.java
@@ -33,9 +33,11 @@ import static org.sonarqube.ws.client.setting.SettingsWsParameters.ACTION_RESET;
import static org.sonarqube.ws.client.setting.SettingsWsParameters.ACTION_SET;
import static org.sonarqube.ws.client.setting.SettingsWsParameters.ACTION_VALUES;
import static org.sonarqube.ws.client.setting.SettingsWsParameters.CONTROLLER_SETTINGS;
+import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_FIELD_VALUES;
import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_KEY;
import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_KEYS;
import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_VALUE;
+import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_VALUES;
public class SettingsService extends BaseService {
public SettingsService(WsConnector wsConnector) {
@@ -61,6 +63,8 @@ public class SettingsService extends BaseService {
call(new PostRequest(path(ACTION_SET))
.setParam(PARAM_KEY, request.getKey())
.setParam(PARAM_VALUE, request.getValue())
+ .setParam(PARAM_VALUES, request.getValues())
+ .setParam(PARAM_FIELD_VALUES, request.getFieldValues())
.setParam(PARAM_COMPONENT_ID, request.getComponentId())
.setParam(PARAM_COMPONENT_KEY, request.getComponentKey()));
}
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/BaseRequestTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/BaseRequestTest.java
index 50c74985e92..1abb05f2db3 100644
--- a/sonar-ws/src/test/java/org/sonarqube/ws/client/BaseRequestTest.java
+++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/BaseRequestTest.java
@@ -19,11 +19,16 @@
*/
package org.sonarqube.ws.client;
+import com.google.common.collect.ImmutableList;
+import java.util.Arrays;
+import java.util.List;
+import org.assertj.core.data.MapEntry;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonarqube.ws.MediaTypes;
+import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.MapEntry.entry;
@@ -51,12 +56,24 @@ public class BaseRequestTest {
@Test
public void keep_order_of_params() {
assertThat(underTest.getParams()).isEmpty();
+ assertThat(underTest.getParameters().getKeys()).isEmpty();
underTest.setParam("keyB", "b");
assertThat(underTest.getParams()).containsExactly(entry("keyB", "b"));
+ assertParameters(entry("keyB", "b"));
+ assertMultiValueParameters(entry("keyB", singletonList("b")));
underTest.setParam("keyA", "a");
assertThat(underTest.getParams()).containsExactly(entry("keyB", "b"), entry("keyA", "a"));
+ assertParameters(entry("keyB", "b"), entry("keyA", "a"));
+ assertMultiValueParameters(entry("keyB", singletonList("b")), entry("keyA", singletonList("a")));
+
+ underTest.setParam("keyC", ImmutableList.of("c1", "c2", "c3"));
+ assertParameters(entry("keyB", "b"), entry("keyA", "a"), entry("keyC", "c1"));
+ assertMultiValueParameters(
+ entry("keyB", singletonList("b")),
+ entry("keyA", singletonList("a")),
+ entry("keyC", ImmutableList.of("c1", "c2", "c3")));
}
@Test
@@ -71,6 +88,20 @@ public class BaseRequestTest {
underTest.setParam(null, "val");
}
+ private void assertParameters(MapEntry<String, String>... values) {
+ Parameters parameters = underTest.getParameters();
+ assertThat(parameters.getKeys()).extracting(key -> MapEntry.entry(key, parameters.getValue(key))).containsExactly(values);
+ }
+
+ private void assertMultiValueParameters(MapEntry<String, List<String>>... expectedParameters) {
+ Parameters parameters = underTest.getParameters();
+ String[] expectedKeys = Arrays.stream(expectedParameters).map(MapEntry::getKey).toArray(String[]::new);
+ assertThat(parameters.getKeys()).containsExactly(expectedKeys);
+ Arrays.stream(expectedParameters).forEach(expectedParameter -> {
+ assertThat(parameters.getValues(expectedParameter.getKey())).containsExactly(expectedParameter.getValue().toArray(new String[0]));
+ });
+ }
+
private static class FakeRequest extends BaseRequest<FakeRequest> {
FakeRequest(String path) {
super(path);
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java
index 89758a70d9d..06f41cd38ac 100644
--- a/sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java
+++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java
@@ -325,7 +325,7 @@ public class ServiceTester<T extends BaseService> extends ExternalResource {
isNotNull();
MapEntry<String, String> entry = MapEntry.entry(key, values.toString());
- Assertions.assertThat(actual.getParams()).contains(entry);
+ Assertions.assertThat(actual.getParameters().getValues(key)).containsExactly(values.toArray(new String[0]));
this.assertedParams.add(entry);
return this;
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/setting/SettingsServiceTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/setting/SettingsServiceTest.java
index 9fe11418c09..82cfba4d457 100644
--- a/sonar-ws/src/test/java/org/sonarqube/ws/client/setting/SettingsServiceTest.java
+++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/setting/SettingsServiceTest.java
@@ -28,13 +28,16 @@ import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.ServiceTester;
import org.sonarqube.ws.client.WsConnector;
+import static com.google.common.collect.Lists.newArrayList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_COMPONENT_ID;
import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_COMPONENT_KEY;
+import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_FIELD_VALUES;
import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_KEY;
import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_KEYS;
import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_VALUE;
+import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_VALUES;
public class SettingsServiceTest {
@@ -76,7 +79,8 @@ public class SettingsServiceTest {
underTest.set(SetRequest.builder()
.setKey("sonar.debt")
.setValue("8h")
- // TODO WS Client must handle multi value param
+ .setValues(newArrayList("v1", "v2", "v3"))
+ .setFieldValues(newArrayList("json1","json2","json3"))
.setComponentId("UUID")
.setComponentKey("KEY")
.build());
@@ -84,6 +88,8 @@ public class SettingsServiceTest {
serviceTester.assertThat(serviceTester.getPostRequest())
.hasParam(PARAM_KEY, "sonar.debt")
.hasParam(PARAM_VALUE, "8h")
+ .hasParam(PARAM_VALUES, newArrayList("v1", "v2", "v3"))
+ .hasParam(PARAM_FIELD_VALUES, newArrayList("json1", "json2", "json3"))
.hasParam(PARAM_COMPONENT_ID, "UUID")
.hasParam(PARAM_COMPONENT_KEY, "KEY")
.andNoOtherParam();