diff options
author | Jacek <jacek.poreda@sonarsource.com> | 2019-10-28 05:27:01 -0500 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2019-11-06 10:04:33 +0100 |
commit | 15ed6d503592dff312c567b855fa446ab4515de7 (patch) | |
tree | 70e0d4899ff14ae07097cae491f8cbab1ee5a128 | |
parent | 199b78fa48b55983bdd08e76446c7393bf9ea9f7 (diff) | |
download | sonarqube-15ed6d503592dff312c567b855fa446ab4515de7.tar.gz sonarqube-15ed6d503592dff312c567b855fa446ab4515de7.zip |
SONAR-12649 Remove deprecated WSs since 6.3
- api/timemachine
- api/properties
- api/user_properties
19 files changed, 4 insertions, 1634 deletions
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/TimeMachineWs.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/TimeMachineWs.java deleted file mode 100644 index 20fa7b1fc4c..00000000000 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/TimeMachineWs.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.sonar.server.measure.ws; - -import org.sonar.api.server.ws.WebService; -import org.sonar.server.ws.RemovedWebServiceHandler; - -public class TimeMachineWs implements WebService { - - @Override - public void define(Context context) { - NewController controller = context.createController("api/timemachine") - .setDescription("Removed since 6.3, please use api/measures/search_history instead") - .setSince("2.10"); - defineIndexAction(controller); - controller.done(); - } - - private static void defineIndexAction(NewController controller) { - controller.createAction("index") - .setDescription("The web service is removed and you're invited to use api/measures/search_history instead") - .setSince("2.10") - .setDeprecatedSince("6.3") - .setHandler(RemovedWebServiceHandler.INSTANCE) - .setResponseExample(RemovedWebServiceHandler.INSTANCE.getResponseExample()); - } - -} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/property/ws/IndexAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/property/ws/IndexAction.java deleted file mode 100644 index a07b1e8c336..00000000000 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/property/ws/IndexAction.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.sonar.server.property.ws; - -import com.google.common.base.Splitter; -import com.google.common.collect.Multimap; -import com.google.common.collect.Ordering; -import com.google.common.collect.TreeMultimap; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import org.sonar.api.config.PropertyDefinition; -import org.sonar.api.config.PropertyDefinitions; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.property.PropertyDto; -import org.sonar.server.user.UserSession; -import org.sonar.server.ws.WsAction; - -import static org.apache.commons.lang.StringUtils.isEmpty; -import static org.sonar.api.PropertyType.PROPERTY_SET; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.server.setting.ws.SettingsWsSupport.DOT_SECURED; -import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; - -public class IndexAction implements WsAction { - - private static final Splitter DOT_SPLITTER = Splitter.on(".").omitEmptyStrings(); - private static final Splitter COMMA_SPLITTER = Splitter.on(","); - private static final String COMMA_ENCODED_VALUE = "%2C"; - - public static final String PARAM_ID = "id"; - public static final String PARAM_COMPONENT = "resource"; - public static final String PARAM_FORMAT = "format"; - - private final DbClient dbClient; - private final UserSession userSession; - private final PropertyDefinitions propertyDefinitions; - - public IndexAction(DbClient dbClient, UserSession userSession, PropertyDefinitions propertyDefinitions) { - this.dbClient = dbClient; - this.userSession = userSession; - this.propertyDefinitions = propertyDefinitions; - } - - @Override - public void define(WebService.NewController context) { - WebService.NewAction action = context.createAction("index") - .setDescription("This web service is deprecated, please use api/settings/values instead.") - .setDeprecatedSince("6.3") - .setResponseExample(getClass().getResource("index-example.json")) - .setSince("2.6") - .setHandler(this); - action.createParam(PARAM_ID) - .setDescription("Setting key") - .setExampleValue("sonar.test.inclusions"); - action.createParam(PARAM_COMPONENT) - .setDescription("Component key or database id") - .setExampleValue(KEY_PROJECT_EXAMPLE_001); - action.createParam(PARAM_FORMAT) - .setDescription("Only json response format is available") - .setPossibleValues("json"); - } - - @Override - public void handle(Request request, Response response) throws Exception { - request.param(PARAM_FORMAT); - JsonWriter json = response.newJsonWriter(); - json.beginArray(); - doHandle(json, request); - json.endArray(); - json.close(); - } - - private void doHandle(JsonWriter json, Request request) { - try (DbSession dbSession = dbClient.openSession(true)) { - Optional<ComponentDto> component = loadComponent(dbSession, request); - String key = request.param(PARAM_ID); - List<PropertyDto> propertyDtos = loadProperties(dbSession, component, Optional.ofNullable(key)); - new ResponseBuilder(propertyDtos).build(json); - } - } - - private Optional<ComponentDto> loadComponent(DbSession dbSession, Request request) { - String component = request.param(PARAM_COMPONENT); - if (component == null) { - return Optional.empty(); - } - return loadComponent(dbSession, component); - } - - private Optional<ComponentDto> loadComponent(DbSession dbSession, String component) { - try { - long componentId = Long.parseLong(component); - return Optional.ofNullable(dbClient.componentDao().selectById(dbSession, componentId).orElse(null)); - } catch (NumberFormatException e) { - return Optional.ofNullable(dbClient.componentDao().selectByKey(dbSession, component).orElse(null)); - } - } - - private List<PropertyDto> loadProperties(DbSession dbSession, Optional<ComponentDto> component, Optional<String> key) { - // List of settings must be kept in the following orders : default -> global -> component - List<PropertyDto> propertyDtos = new ArrayList<>(); - propertyDtos.addAll(loadDefaultSettings(key)); - propertyDtos.addAll(loadGlobalSettings(dbSession, key)); - component.ifPresent(componentDto -> propertyDtos.addAll(loadComponentSettings(dbSession, key, componentDto).values())); - return propertyDtos.stream().filter(isVisible(component)).collect(Collectors.toList()); - } - - Predicate<PropertyDto> isVisible(Optional<ComponentDto> component) { - return propertyDto -> !propertyDto.getKey().endsWith(DOT_SECURED) - || hasAdminPermission(component); - } - - private boolean hasAdminPermission(Optional<ComponentDto> component) { - return component - .map(c -> userSession.hasComponentPermission(ADMIN, c)) - .orElse(userSession.isSystemAdministrator()); - } - - private List<PropertyDto> loadGlobalSettings(DbSession dbSession, Optional<String> key) { - if (key.isPresent()) { - return dbClient.propertiesDao().selectGlobalPropertiesByKeys(dbSession, Collections.singleton(key.get())); - } - return dbClient.propertiesDao().selectGlobalProperties(dbSession); - } - - /** - * Return list of propertyDto by component uuid, sorted from project to lowest module - */ - private Multimap<String, PropertyDto> loadComponentSettings(DbSession dbSession, Optional<String> key, ComponentDto component) { - List<String> componentUuids = DOT_SPLITTER.splitToList(component.moduleUuidPath()); - List<ComponentDto> componentDtos = dbClient.componentDao().selectByUuids(dbSession, componentUuids); - Set<Long> componentIds = componentDtos.stream().map(ComponentDto::getId).collect(Collectors.toSet()); - Map<Long, String> uuidsById = componentDtos.stream().collect(Collectors.toMap(ComponentDto::getId, ComponentDto::uuid)); - List<PropertyDto> properties = key.isPresent() ? dbClient.propertiesDao().selectPropertiesByKeysAndComponentIds(dbSession, Collections.singleton(key.get()), componentIds) - : dbClient.propertiesDao().selectPropertiesByComponentIds(dbSession, componentIds); - - Multimap<String, PropertyDto> propertyDtosByUuid = TreeMultimap.create(Ordering.explicit(componentUuids), Ordering.arbitrary()); - for (PropertyDto propertyDto : properties) { - Long componentId = propertyDto.getResourceId(); - String componentUuid = uuidsById.get(componentId); - propertyDtosByUuid.put(componentUuid, propertyDto); - } - return propertyDtosByUuid; - } - - private List<PropertyDto> loadDefaultSettings(Optional<String> key) { - return propertyDefinitions.getAll().stream() - .filter(definition -> !key.isPresent() || key.get().equals(definition.key())) - .filter(defaultProperty -> !isEmpty(defaultProperty.defaultValue())) - .map(definition -> new PropertyDto().setKey(definition.key()).setValue(definition.defaultValue())) - .collect(Collectors.toList()); - } - - private class ResponseBuilder { - private final List<PropertyDto> propertyDtos; - private final Map<String, Property> propertiesByKey = new HashMap<>(); - - ResponseBuilder(List<PropertyDto> propertyDtos) { - this.propertyDtos = propertyDtos; - } - - void build(JsonWriter json) { - processSettings(); - propertiesByKey.values().forEach(property -> { - json.beginObject() - .prop("key", property.key) - .prop("value", property.value); - if (!property.values.isEmpty()) { - json.name("values").beginArray().values(property.values).endArray(); - } - json.endObject(); - }); - } - - private void processSettings() { - propertyDtos.forEach(setting -> { - Property property = createProperty(setting.getKey()); - setValue(setting, property); - }); - } - - private Property createProperty(String key) { - return propertiesByKey.computeIfAbsent(key, k -> new Property(key)); - } - - private void setValue(PropertyDto propertyDto, Property property) { - String value = propertyDto.getValue(); - property.setValue(value); - PropertyDefinition definition = propertyDefinitions.get(propertyDto.getKey()); - if (definition != null && (definition.multiValues() || definition.type().equals(PROPERTY_SET))) { - property.setValues(createValues(value)); - } - } - - private List<String> createValues(String value) { - return COMMA_SPLITTER.splitToList(value).stream().map(v -> v.replace(COMMA_ENCODED_VALUE, ",")).collect(Collectors.toList()); - } - } - - private static class Property { - private final String key; - private String value; - private List<String> values = new ArrayList<>(); - - public Property(String key) { - this.key = key; - } - - public Property setValue(String value) { - this.value = value; - return this; - } - - public Property setValues(List<String> values) { - this.values = values; - return this; - } - } - -} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/property/ws/PropertiesWs.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/property/ws/PropertiesWs.java deleted file mode 100644 index 6908cfc5ef1..00000000000 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/property/ws/PropertiesWs.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.sonar.server.property.ws; - -import org.sonar.api.server.ws.WebService; - -public class PropertiesWs implements WebService { - - public static final String CONTROLLER_PROPERTIES = "api/properties"; - - private final IndexAction indexAction; - - public PropertiesWs(IndexAction indexAction) { - this.indexAction = indexAction; - } - - @Override - public void define(Context context) { - NewController controller = context.createController(CONTROLLER_PROPERTIES) - .setDescription("This web service is deprecated, please use api/settings instead.") - .setSince("2.6"); - indexAction.define(controller); - controller.done(); - } -} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/property/ws/package-info.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/property/ws/package-info.java deleted file mode 100644 index a8ce783fbc6..00000000000 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/property/ws/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.server.property.ws; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UserPropertiesWs.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UserPropertiesWs.java deleted file mode 100644 index b8cf7228810..00000000000 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UserPropertiesWs.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.sonar.server.user.ws; - -import org.sonar.api.server.ws.WebService; -import org.sonar.server.ws.RemovedWebServiceHandler; - -public class UserPropertiesWs implements WebService { - - @Override - public void define(Context context) { - NewController controller = context.createController("api/user_properties"); - controller.setDescription("Removed since 6.3, please use api/favorites and api/notifications instead"); - controller.setSince("2.6"); - defineIndexAction(controller); - controller.done(); - } - - private static void defineIndexAction(NewController controller) { - controller.createAction("index") - .setDescription("This web service is removed") - .setSince("2.6") - .setDeprecatedSince("6.3") - .setHandler(RemovedWebServiceHandler.INSTANCE) - .setResponseExample(RemovedWebServiceHandler.INSTANCE.getResponseExample()); - } - -} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UsersWsModule.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UsersWsModule.java index 8e94362ab4b..f37c9a11a5f 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UsersWsModule.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UsersWsModule.java @@ -43,7 +43,6 @@ public class UsersWsModule extends Module { SearchAction.class, GroupsAction.class, IdentityProvidersAction.class, - UserPropertiesWs.class, UserJsonWriter.class, SetHomepageAction.class, HomepageTypesImpl.class, diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/TimeMachineWsTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/TimeMachineWsTest.java deleted file mode 100644 index 4696ff29293..00000000000 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/TimeMachineWsTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.sonar.server.measure.ws; - -import org.junit.Test; -import org.sonar.api.server.ws.WebService; - -import static org.assertj.core.api.Assertions.assertThat; - -public class TimeMachineWsTest { - - private TimeMachineWs underTest = new TimeMachineWs(); - - @Test - public void define_controller() { - WebService.Context context = new WebService.Context(); - - underTest.define(context); - - WebService.Controller controller = context.controller("api/timemachine"); - - assertThat(controller).isNotNull(); - assertThat(controller.since()).isEqualTo("2.10"); - assertThat(controller.description()).isNotEmpty(); - assertThat(controller.actions()).hasSize(1); - } - - @Test - public void define_index_action() { - WebService.Context context = new WebService.Context(); - - underTest.define(context); - - WebService.Controller controller = context.controller("api/timemachine"); - WebService.Action action = controller.action("index"); - assertThat(action).isNotNull(); - assertThat(action.responseExampleAsString()).isNotEmpty(); - } - -} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/property/ws/IndexActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/property/ws/IndexActionTest.java deleted file mode 100644 index 91fbaead015..00000000000 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/property/ws/IndexActionTest.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.sonar.server.property.ws; - -import com.google.common.collect.ImmutableMap; -import java.net.URL; -import javax.annotation.Nullable; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.PropertyType; -import org.sonar.api.config.PropertyDefinition; -import org.sonar.api.config.PropertyDefinitions; -import org.sonar.api.config.PropertyFieldDefinition; -import org.sonar.api.server.ws.WebService; -import org.sonar.api.utils.System2; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; -import org.sonar.db.property.PropertyDbTester; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.WsActionTester; -import org.sonar.test.JsonAssert; -import org.sonarqube.ws.MediaTypes; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.PropertyType.LICENSE; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; -import static org.sonar.db.component.ComponentTesting.newModuleDto; -import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto; -import static org.sonar.db.property.PropertyTesting.newGlobalPropertyDto; -import static org.sonar.test.JsonAssert.assertJson; -import static org.sonarqube.ws.MediaTypes.JSON; - -public class IndexActionTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - - private DbClient dbClient = db.getDbClient(); - private PropertyDbTester propertyDb = new PropertyDbTester(db); - private ComponentDbTester componentDb = new ComponentDbTester(db); - private PropertyDefinitions definitions = new PropertyDefinitions(); - - private ComponentDto project; - - private WsActionTester ws = new WsActionTester(new IndexAction(dbClient, userSession, definitions)); - - @Before - public void setUp() throws Exception { - project = componentDb.insertComponent(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization())); - } - - @Test - public void return_simple_value() { - logIn(); - definitions.addComponent(PropertyDefinition.builder("foo").build()); - propertyDb.insertProperties(newGlobalPropertyDto().setKey("foo").setValue("one")); - - executeAndVerify(null, null, "return_simple_value.json"); - } - - @Test - public void return_multi_values() { - logIn(); - // Property never defined, default value is returned - definitions.addComponent(PropertyDefinition.builder("default") - .multiValues(true) - .defaultValue("one,two") - .build()); - // Property defined at global level - definitions.addComponent(PropertyDefinition.builder("global") - .multiValues(true) - .build()); - propertyDb.insertProperties(newGlobalPropertyDto().setKey("global").setValue("three,four")); - - executeAndVerify(null, null, "return_multi_values.json"); - } - - @Test - public void return_multi_value_with_coma() { - logIn(); - definitions.addComponent(PropertyDefinition.builder("global").multiValues(true).build()); - propertyDb.insertProperties(newGlobalPropertyDto().setKey("global").setValue("three,four%2Cfive")); - - executeAndVerify(null, null, "return_multi_value_with_coma.json"); - } - - @Test - public void return_property_set() { - logIn(); - definitions.addComponent(PropertyDefinition - .builder("foo") - .type(PropertyType.PROPERTY_SET) - .fields(asList( - PropertyFieldDefinition.build("key").name("Key").build(), - PropertyFieldDefinition.build("size").name("Size").build())) - .build()); - propertyDb.insertPropertySet("foo", null, ImmutableMap.of("key", "key1", "size", "size1"), ImmutableMap.of("key", "key2")); - - executeAndVerify(null, null, "return_property_set.json"); - } - - @Test - public void return_default_values() { - logIn(); - definitions.addComponent(PropertyDefinition.builder("foo").defaultValue("default").build()); - - executeAndVerify(null, null, "return_default_values.json"); - } - - @Test - public void return_global_values() { - logIn(); - definitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build()); - propertyDb.insertProperties( - // The property is overriding default value - newGlobalPropertyDto().setKey("property").setValue("one")); - - executeAndVerify(null, null, "return_global_values.json"); - } - - @Test - public void return_project_values() { - logInAsProjectUser(); - definitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build()); - propertyDb.insertProperties( - newGlobalPropertyDto().setKey("property").setValue("one"), - // The property is overriding global value - newComponentPropertyDto(project).setKey("property").setValue("two")); - - executeAndVerify(project.getDbKey(), null, "return_project_values.json"); - } - - @Test - public void return_global_values_when_project_does_not_exist() { - logIn(); - definitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build()); - propertyDb.insertProperties( - newGlobalPropertyDto().setKey("property").setValue("one")); - - executeAndVerify("unknown", null, "return_global_values.json"); - } - - @Test - public void return_values_even_if_no_property_definition() { - logIn(); - propertyDb.insertProperties(newGlobalPropertyDto().setKey("globalPropertyWithoutDefinition").setValue("value")); - - executeAndVerify(null, null, "return_values_even_if_no_property_definition.json"); - } - - @Test - public void return_empty_when_property_def_exists_but_no_value() { - logIn(); - definitions.addComponent(PropertyDefinition.builder("foo").build()); - - executeAndVerify(null, null, "empty.json"); - } - - @Test - public void return_nothing_when_unknown_key() { - logIn(); - definitions.addComponent(PropertyDefinition.builder("foo").defaultValue("default").build()); - propertyDb.insertProperties(newGlobalPropertyDto().setKey("bar").setValue("")); - - executeAndVerify(null, "unknown", "empty.json"); - } - - @Test - public void return_module_values() { - logInAsProjectUser(); - ComponentDto module = componentDb.insertComponent(newModuleDto(project)); - definitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build()); - propertyDb.insertProperties( - newGlobalPropertyDto().setKey("property").setValue("one"), - // The property is overriding global value - newComponentPropertyDto(module).setKey("property").setValue("two")); - - executeAndVerify(module.getDbKey(), "property", "return_module_values.json"); - } - - @Test - public void return_inherited_values_on_module() { - logInAsProjectUser(); - ComponentDto module = componentDb.insertComponent(newModuleDto(project)); - definitions.addComponents(asList( - PropertyDefinition.builder("defaultProperty").defaultValue("default").build(), - PropertyDefinition.builder("globalProperty").build(), - PropertyDefinition.builder("projectProperty").build(), - PropertyDefinition.builder("moduleProperty").build())); - propertyDb.insertProperties( - newGlobalPropertyDto().setKey("globalProperty").setValue("global"), - newComponentPropertyDto(project).setKey("projectProperty").setValue("project"), - newComponentPropertyDto(module).setKey("moduleProperty").setValue("module")); - - executeAndVerify(module.getDbKey(), null, "return_inherited_values_on_module.json"); - } - - @Test - public void return_inherited_values_on_global_setting() { - logIn(); - definitions.addComponents(asList( - PropertyDefinition.builder("defaultProperty").defaultValue("default").build(), - PropertyDefinition.builder("globalProperty").build())); - propertyDb.insertProperties( - newGlobalPropertyDto().setKey("globalProperty").setValue("global")); - - executeAndVerify(null, null, "return_inherited_values_on_global_setting.json"); - } - - @Test - public void does_not_return_value_of_deprecated_key() { - logIn(); - definitions.addComponent(PropertyDefinition.builder("foo").deprecatedKey("deprecated").build()); - propertyDb.insertProperties(newGlobalPropertyDto().setKey("foo").setValue("one")); - - executeAndVerify(null, "deprecated", "empty.json"); - } - - @Test - public void does_not_returned_secured_settings_when_not_authenticated() { - definitions.addComponents(asList( - PropertyDefinition.builder("foo").build(), - PropertyDefinition.builder("secret.secured").build())); - propertyDb.insertProperties( - newGlobalPropertyDto().setKey("foo").setValue("one"), - newGlobalPropertyDto().setKey("secret.secured").setValue("password")); - - executeAndVerify(null, null, "does_not_returned_secured_and_license_settings_when_not_authenticated.json"); - } - - @Test - public void return_secured_settings_when_system_admin() { - logInAsSystemAdministrator(); - definitions.addComponents(asList( - PropertyDefinition.builder("foo").build(), - PropertyDefinition.builder("secret.secured").build())); - propertyDb.insertProperties( - newGlobalPropertyDto().setKey("foo").setValue("one"), - newGlobalPropertyDto().setKey("secret.secured").setValue("password")); - - executeAndVerify(null, null, "return_secured_and_license_settings_when_system_admin.json"); - } - - @Test - public void return_secured_and_license_settings_when_project_admin() { - logInAsProjectAdmin(); - definitions.addComponents(asList( - PropertyDefinition.builder("foo").build(), - PropertyDefinition.builder("secret.secured").build(), - PropertyDefinition.builder("plugin.license.secured").type(LICENSE).build())); - propertyDb.insertProperties( - newComponentPropertyDto(project).setKey("foo").setValue("one"), - newComponentPropertyDto(project).setKey("secret.secured").setValue("password"), - newComponentPropertyDto(project).setKey("plugin.license.secured").setValue("ABCD"), - newComponentPropertyDto(project).setKey("plugin.licenseHash.secured").setValue("987654321")); - - executeAndVerify(project.getDbKey(), null, "return_secured_and_license_settings_when_project_admin.json"); - } - - @Test - public void return_secured_settings_in_property_set_when_system_admin() { - logInAsSystemAdministrator(); - definitions.addComponent(PropertyDefinition - .builder("foo") - .type(PropertyType.PROPERTY_SET) - .fields(asList( - PropertyFieldDefinition.build("key").name("Key").build(), - PropertyFieldDefinition.build("secret.secured").name("Secured").build())) - .build()); - propertyDb.insertPropertySet("foo", null, - ImmutableMap.of("key", "key1", "secret.secured", "123456")); - - executeAndVerify(null, null, "return_secured_and_license_settings_in_property_set_when_system_admin.json"); - } - - @Test - public void return_all_settings_when_no_component_and_no_key() { - logInAsSystemAdministrator(); - definitions.addComponents(asList( - PropertyDefinition.builder("foo").build(), - PropertyDefinition.builder("secret.secured").build(), - PropertyDefinition.builder("plugin.license.secured").type(LICENSE).build())); - propertyDb.insertProperties( - newGlobalPropertyDto().setKey("foo").setValue("one"), - newGlobalPropertyDto().setKey("secret.secured").setValue("password"), - newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"), - newGlobalPropertyDto().setKey("not_defined").setValue("ABCD")); - - executeAndVerify(null, null, "return_all_settings_when_no_component_and_no_key.json"); - } - - @Test - public void return_all_project_settings_when_component_and_no_key() { - logInAsProjectAdmin(); - definitions.addComponents(asList( - PropertyDefinition.builder("foo").build(), - PropertyDefinition.builder("secret.secured").build(), - PropertyDefinition.builder("plugin.license.secured").type(LICENSE).build())); - propertyDb.insertProperties( - newComponentPropertyDto(project).setKey("foo").setValue("one"), - newComponentPropertyDto(project).setKey("secret.secured").setValue("password"), - newComponentPropertyDto(project).setKey("plugin.license.secured").setValue("ABCD"), - newComponentPropertyDto(project).setKey("not_defined").setValue("ABCD"), - newGlobalPropertyDto().setKey("global_not_defined").setValue("ABCD")); - - executeAndVerify(project.getDbKey(), null, "return_all_project_settings_when_component_and_no_key.json"); - } - - @Test - public void return_only_one_setting_when_key_is_provided() { - definitions.addComponents(asList( - PropertyDefinition.builder("foo").build(), - PropertyDefinition.builder("bar").build())); - propertyDb.insertProperties( - newGlobalPropertyDto().setKey("foo").setValue("one"), - newGlobalPropertyDto().setKey("bar").setValue("two")); - - executeAndVerify(project.getDbKey(), "foo", "return_only_one_setting_when_key_is_provided.json"); - executeAndVerify(project.getDbKey(), "unknown", "empty.json"); - } - - @Test - public void does_not_fail_when_user_has_not_project_browse_permission() { - userSession.logIn("project-admin").addProjectPermission(CODEVIEWER, project); - definitions.addComponent(PropertyDefinition.builder("foo").build()); - propertyDb.insertProperties(newComponentPropertyDto(project).setKey("foo").setValue("one")); - - executeAndVerify(project.getDbKey(), null, "does_not_fail_when_user_has_not_project_browse_permission.json"); - } - - @Test - public void does_not_fail_when_format_is_set_to_json() { - logIn(); - definitions.addComponent(PropertyDefinition.builder("foo").defaultValue("default").build()); - - ws.newRequest().setParam("format", "json").execute(); - } - - @Test - public void fail_when_format_is_set_to_xml() { - logIn(); - definitions.addComponent(PropertyDefinition.builder("foo").defaultValue("default").build()); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Value of parameter 'format' (xml) must be one of: [json]"); - ws.newRequest().setParam("format", "xml").execute(); - } - - @Test - public void test_example_json_response() { - logIn(); - definitions.addComponent(PropertyDefinition - .builder("sonar.test.jira") - .defaultValue("abc") - .build()); - definitions.addComponent(PropertyDefinition - .builder("sonar.autogenerated") - .multiValues(true) - .build()); - propertyDb.insertProperties(newGlobalPropertyDto().setKey("sonar.autogenerated").setValue("val1,val2,val3")); - definitions.addComponent(PropertyDefinition - .builder("sonar.demo") - .type(PropertyType.PROPERTY_SET) - .fields(PropertyFieldDefinition.build("text").name("Text").build(), - PropertyFieldDefinition.build("boolean").name("Boolean").build()) - .build()); - propertyDb.insertPropertySet("sonar.demo", null, ImmutableMap.of("text", "foo", "boolean", "true"), ImmutableMap.of("text", "bar", "boolean", "false")); - - String result = ws.newRequest().setMediaType(JSON).execute().getInput(); - - JsonAssert.assertJson(ws.getDef().responseExampleAsString()).isSimilarTo(result); - } - - @Test - public void test_ws_definition() { - WebService.Action action = ws.getDef(); - assertThat(action).isNotNull(); - assertThat(action.isInternal()).isFalse(); - assertThat(action.isPost()).isFalse(); - assertThat(action.responseExampleAsString()).isNotEmpty(); - assertThat(action.params()).hasSize(3); - } - - private void executeAndVerify(@Nullable String componentKey, @Nullable String key, String expectedFile) { - TestRequest request = ws.newRequest().setMediaType(MediaTypes.JSON); - if (key != null) { - request.setParam("id", key); - } - if (componentKey != null) { - request.setParam("resource", componentKey); - } - String result = request.execute().getInput(); - assertJson(result).isSimilarTo(resource(expectedFile)); - } - - private void logIn() { - userSession.logIn(); - } - - private void logInAsProjectUser() { - userSession.logIn().addProjectPermission(USER, project); - } - - private void logInAsSystemAdministrator() { - userSession.logIn().setSystemAdministrator(); - } - - private void logInAsProjectAdmin() { - userSession.logIn() - .addProjectPermission(ADMIN, project) - .addProjectPermission(USER, project); - } - - protected static URL resource(String s) { - Class<IndexActionTest> clazz = IndexActionTest.class; - return clazz.getResource(clazz.getSimpleName() + "/" + s); - } -} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/UserPropertiesWsTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/UserPropertiesWsTest.java deleted file mode 100644 index b836057a4b9..00000000000 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/UserPropertiesWsTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.sonar.server.user.ws; - -import org.junit.Test; -import org.sonar.api.server.ws.WebService; -import org.sonar.server.ws.RemovedWebServiceHandler; - -import static org.assertj.core.api.Assertions.assertThat; - -public class UserPropertiesWsTest { - - private UserPropertiesWs underTest = new UserPropertiesWs(); - - @Test - public void define_ws() { - WebService.Context context = new WebService.Context(); - - underTest.define(context); - - WebService.Controller controller = context.controller("api/user_properties"); - assertThat(controller).isNotNull(); - assertThat(controller.description()).isNotEmpty(); - assertThat(controller.actions()).hasSize(1); - - WebService.Action index = controller.action("index"); - assertThat(index.since()).isEqualTo("2.6"); - assertThat(index.deprecatedSince()).isEqualTo("6.3"); - assertThat(index.handler()).isSameAs(RemovedWebServiceHandler.INSTANCE); - assertThat(index.responseExample()).isEqualTo(RemovedWebServiceHandler.INSTANCE.getResponseExample()); - } - -} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java index 1fbd80a8f78..909f1163e63 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java @@ -34,7 +34,7 @@ public class UsersWsModuleTest { public void verify_count_of_added_components() { ComponentContainer container = new ComponentContainer(); new UsersWsModule(new ConfigurationBridge(settings)).configure(container); - assertThat(container.size()).isEqualTo(2 + 15); + assertThat(container.size()).isEqualTo(2 + 14); } @Test @@ -43,6 +43,6 @@ public class UsersWsModuleTest { ComponentContainer container = new ComponentContainer(); new UsersWsModule(new ConfigurationBridge(settings)).configure(container); - assertThat(container.size()).isEqualTo(2 + 16); + assertThat(container.size()).isEqualTo(2 + 15); } } diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java index 23601bc33b6..2c91bda2dd3 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java @@ -100,7 +100,6 @@ import org.sonar.server.measure.custom.ws.CustomMeasuresWsModule; import org.sonar.server.measure.index.ProjectsEsModule; import org.sonar.server.measure.live.LiveMeasureModule; import org.sonar.server.measure.ws.MeasuresWsModule; -import org.sonar.server.measure.ws.TimeMachineWs; import org.sonar.server.metric.CoreCustomMetrics; import org.sonar.server.metric.DefaultMetricFinder; import org.sonar.server.metric.ws.MetricsWsModule; @@ -123,7 +122,6 @@ import org.sonar.server.platform.ClusterVerification; import org.sonar.server.platform.PersistentSettings; import org.sonar.server.platform.SystemInfoWriterModule; import org.sonar.server.platform.WebCoreExtensionsInstaller; -import org.sonar.server.platform.web.DeprecatedPropertiesWsFilter; import org.sonar.server.platform.web.WebServiceFilter; import org.sonar.server.platform.web.WebServiceReroutingFilter; import org.sonar.server.platform.web.requestid.HttpRequestIdModule; @@ -150,7 +148,6 @@ import org.sonar.server.projectanalysis.ws.ProjectAnalysisWsModule; import org.sonar.server.projectlink.ws.ProjectLinksModule; import org.sonar.server.projecttag.ws.ProjectTagsWsModule; import org.sonar.server.property.InternalPropertiesImpl; -import org.sonar.server.property.ws.PropertiesWs; import org.sonar.server.qualitygate.ProjectsInWarningModule; import org.sonar.server.qualitygate.QualityGateModule; import org.sonar.server.qualitygate.notification.QGChangeNotificationHandler; @@ -335,7 +332,6 @@ public class PlatformLevel4 extends PlatformLevel { CustomMeasuresWsModule.class, CoreCustomMetrics.class, DefaultMetricFinder.class, - TimeMachineWs.class, QualityGateModule.class, ProjectsInWarningModule.class, @@ -345,7 +341,6 @@ public class PlatformLevel4 extends PlatformLevel { WebServiceEngine.class, WebServicesWsModule.class, WebServiceFilter.class, - DeprecatedPropertiesWsFilter.class, WebServiceReroutingFilter.class, // localization @@ -466,8 +461,6 @@ public class PlatformLevel4 extends PlatformLevel { // Settings ProjectConfigurationLoaderImpl.class, PersistentSettings.class, - PropertiesWs.class, - org.sonar.server.property.ws.IndexAction.class, SettingsWsModule.class, TypeValidationModule.class, diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/web/DeprecatedPropertiesWsFilter.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/web/DeprecatedPropertiesWsFilter.java deleted file mode 100644 index e6113889262..00000000000 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/web/DeprecatedPropertiesWsFilter.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.sonar.server.platform.web; - -import com.google.common.base.Splitter; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.io.IOUtils; -import org.sonar.api.web.ServletFilter; -import org.sonar.server.property.ws.IndexAction; -import org.sonar.server.setting.ws.SettingsWsParameters; -import org.sonar.server.ws.ServletResponse; -import org.sonar.server.ws.WebServiceEngine; - -import static com.google.common.base.Strings.isNullOrEmpty; -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.sonar.server.property.ws.PropertiesWs.CONTROLLER_PROPERTIES; - -/** - * This filter is used to execute deprecated api/properties WS, that were using REST - */ -public class DeprecatedPropertiesWsFilter extends ServletFilter { - - private static final Splitter VALUE_SPLITTER = Splitter.on(",").omitEmptyStrings(); - private static final String SEPARATOR = "/"; - - private final WebServiceEngine webServiceEngine; - - public DeprecatedPropertiesWsFilter(WebServiceEngine webServiceEngine) { - this.webServiceEngine = webServiceEngine; - } - - @Override - public UrlPattern doGetPattern() { - return UrlPattern.builder() - .includes(SEPARATOR + CONTROLLER_PROPERTIES + "/*") - .build(); - } - - @Override - public void doFilter(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse, FilterChain chain) { - HttpServletRequest request = (HttpServletRequest) servletRequest; - HttpServletResponse response = (HttpServletResponse) servletResponse; - RestServletRequest wsRequest = new RestServletRequest(request); - ServletResponse wsResponse = new ServletResponse(response); - webServiceEngine.execute(wsRequest, wsResponse); - } - - @Override - public void init(FilterConfig filterConfig) { - // Nothing to do - } - - @Override - public void destroy() { - // Nothing to do - } - - static class RestServletRequest extends org.sonar.server.ws.ServletRequest { - - private final Response restResponse; - - RestServletRequest(HttpServletRequest request) { - super(request); - this.restResponse = new Response(request); - } - - @Override - public String getPath() { - return restResponse.redirectedPath; - } - - @Override - public boolean hasParam(String key) { - return restResponse.additionalParams.containsKey(key) || restResponse.additionalMultiParams.containsKey(key); - } - - @Override - public String readParam(String key) { - return restResponse.additionalParams.get(key); - } - - @Override - public List<String> readMultiParam(String key) { - return new ArrayList<>(restResponse.additionalMultiParams.get(key)); - } - - @Override - public String method() { - return restResponse.redirectedMethod; - } - } - - private static class Response { - private final HttpServletRequest request; - private final Map<String, String> additionalParams = new HashMap<>(); - private final Multimap<String, String> additionalMultiParams = ArrayListMultimap.create(); - private final String originalPath; - private String redirectedPath; - private String redirectedMethod; - - Response(HttpServletRequest request) { - this.request = request; - this.originalPath = request.getRequestURI().replaceFirst(request.getContextPath(), ""); - init(); - } - - void init() { - String method = request.getMethod(); - Optional<String> id = getKeyOrId(); - switch (method) { - case "POST": - case "PUT": - handlePutAndPost(id, getValues(), getComponent()); - break; - case "DELETE": - handleDelete(id, getComponent()); - break; - default: - handleGet(id, getComponent()); - } - } - - private void handlePutAndPost(Optional<String> key, List<String> values, Optional<String> component) { - if (values.isEmpty()) { - redirectToReset(key, component); - } else { - redirectToSet(key, values, component); - } - } - - private void handleDelete(Optional<String> key, Optional<String> component) { - redirectToReset(key, component); - } - - private void handleGet(Optional<String> key, Optional<String> component) { - addParameterIfPresent(IndexAction.PARAM_ID, key); - addParameterIfPresent(IndexAction.PARAM_COMPONENT, component); - addParameterIfPresent(IndexAction.PARAM_FORMAT, readParam(IndexAction.PARAM_FORMAT)); - redirectedPath = CONTROLLER_PROPERTIES + "/index"; - redirectedMethod = "GET"; - } - - private Optional<String> getKeyOrId() { - Optional<String> key = getKey(); - return key.isPresent() ? key : readParam("id"); - } - - private Optional<String> getKey() { - if (originalPath.equals(SEPARATOR + CONTROLLER_PROPERTIES)) { - return Optional.empty(); - } - String key = originalPath.replace(SEPARATOR + CONTROLLER_PROPERTIES + SEPARATOR, ""); - return key.isEmpty() ? Optional.empty() : Optional.of(key); - } - - private Optional<String> getComponent() { - return readParam(IndexAction.PARAM_COMPONENT); - } - - private List<String> getValues() { - Optional<String> value = readParam("value"); - if (!value.isPresent()) { - List<String> values = new ArrayList<>(); - readBody().ifPresent(values::add); - return values; - } - return VALUE_SPLITTER.splitToList(value.get()); - } - - private Optional<String> readParam(String paramKey) { - String paramValue = request.getParameter(paramKey); - return isNullOrEmpty(paramValue) ? Optional.empty() : Optional.of(paramValue); - } - - private Optional<String> readBody() { - StringWriter writer = new StringWriter(); - try { - ServletInputStream inputStream = request.getInputStream(); - if (inputStream == null) { - return Optional.empty(); - } - IOUtils.copy(inputStream, writer, UTF_8.name()); - return Optional.of(writer.toString()); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - - private void redirectToSet(Optional<String> key, List<String> values, Optional<String> component) { - addParameterIfPresent(SettingsWsParameters.PARAM_KEY, key); - if (values.size() == 1) { - additionalParams.put(SettingsWsParameters.PARAM_VALUE, values.get(0)); - } else { - additionalMultiParams.putAll(SettingsWsParameters.PARAM_VALUES, values); - } - addParameterIfPresent(SettingsWsParameters.PARAM_COMPONENT, component); - redirectedPath = "api/settings/set"; - redirectedMethod = "POST"; - } - - private void redirectToReset(Optional<String> key, Optional<String> component) { - addParameterIfPresent(SettingsWsParameters.PARAM_KEYS, key); - addParameterIfPresent(SettingsWsParameters.PARAM_COMPONENT, component); - redirectedPath = "api/settings/reset"; - redirectedMethod = "POST"; - } - - private void addParameterIfPresent(String parameterKey, Optional<String> value) { - value.ifPresent(s -> additionalParams.put(parameterKey, s)); - } - - } - -} diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/web/WebServiceFilter.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/web/WebServiceFilter.java index 7875640a0bd..35e824ff224 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/web/WebServiceFilter.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/web/WebServiceFilter.java @@ -30,7 +30,6 @@ import org.sonar.api.SonarRuntime; import org.sonar.api.server.ws.WebService; import org.sonar.api.web.ServletFilter; import org.sonar.core.util.stream.MoreCollectors; -import org.sonar.server.property.ws.PropertiesWs; import org.sonar.server.ws.ServletFilterHandler; import org.sonar.server.ws.ServletRequest; import org.sonar.server.ws.ServletResponse; @@ -45,7 +44,6 @@ import static org.sonar.server.platform.web.WebServiceReroutingFilter.MOVED_WEB_ * Every urls beginning with '/api' and every web service urls are taken into account, except : * <ul> * <li>web services that directly implemented with servlet filter, see {@link ServletFilterHandler})</li> - * <li>deprecated '/api/properties' web service, see {@link DeprecatedPropertiesWsFilter}</li> * </ul> */ public class WebServiceFilter extends ServletFilter { @@ -63,9 +61,7 @@ public class WebServiceFilter extends ServletFilter { .flatMap(controller -> controller.actions().stream()) .map(toPath())) .collect(MoreCollectors.toSet()); - this.excludeUrls = concat(concat( - Stream.of("/" + PropertiesWs.CONTROLLER_PROPERTIES + "*"), - MOVED_WEB_SERVICES.stream()), + this.excludeUrls = concat(MOVED_WEB_SERVICES.stream(), webServiceEngine.controllers().stream() .flatMap(controller -> controller.actions().stream()) .filter(action -> action.handler() instanceof ServletFilterHandler) diff --git a/server/sonar-webserver/src/test/java/org/sonar/server/platform/web/DeprecatedPropertiesWsFilterTest.java b/server/sonar-webserver/src/test/java/org/sonar/server/platform/web/DeprecatedPropertiesWsFilterTest.java deleted file mode 100644 index c25cbbe9653..00000000000 --- a/server/sonar-webserver/src/test/java/org/sonar/server/platform/web/DeprecatedPropertiesWsFilterTest.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.sonar.server.platform.web; - -import java.io.ByteArrayInputStream; -import java.util.Arrays; -import javax.servlet.FilterChain; -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.ArgumentCaptor; -import org.sonar.server.ws.ServletRequest; -import org.sonar.server.ws.ServletResponse; -import org.sonar.server.ws.WebServiceEngine; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class DeprecatedPropertiesWsFilterTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private WebServiceEngine webServiceEngine = mock(WebServiceEngine.class); - - private HttpServletRequest request = mock(HttpServletRequest.class); - private HttpServletResponse response = mock(HttpServletResponse.class); - private FilterChain chain = mock(FilterChain.class); - private ArgumentCaptor<ServletRequest> servletRequestCaptor = ArgumentCaptor.forClass(ServletRequest.class); - - private DeprecatedPropertiesWsFilter underTest = new DeprecatedPropertiesWsFilter(webServiceEngine); - - @Before - public void setUp() { - when(request.getContextPath()).thenReturn("/sonarqube"); - } - - @Test - public void do_get_pattern() { - assertThat(underTest.doGetPattern().matches("/api/properties")).isTrue(); - assertThat(underTest.doGetPattern().matches("/api/properties/")).isTrue(); - assertThat(underTest.doGetPattern().matches("/api/properties/my.property")).isTrue(); - assertThat(underTest.doGetPattern().matches("/api/properties/my_property")).isTrue(); - - assertThat(underTest.doGetPattern().matches("/api/issues/search")).isFalse(); - assertThat(underTest.doGetPattern().matches("/batch/index")).isFalse(); - assertThat(underTest.doGetPattern().matches("/foo")).isFalse(); - } - - @Test - public void redirect_api_properties_to_api_properties_index() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties"); - when(request.getMethod()).thenReturn("GET"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/properties/index", "GET"); - assertNoParam("key", "component", "value", "values"); - } - - @Test - public void redirect_api_properties_to_api_properties_index_when_no_property() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties/"); - when(request.getMethod()).thenReturn("GET"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/properties/index", "GET"); - assertNoParam("key", "component", "value", "values"); - } - - @Test - public void redirect_api_properties_with_property_key() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties/my.property"); - when(request.getMethod()).thenReturn("GET"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/properties/index", "GET"); - assertParam("id", "my.property"); - assertNoParam("component", "value", "values"); - } - - @Test - public void redirect_api_properties_with_property_id() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties"); - when(request.getParameter("id")).thenReturn("my.property"); - when(request.getMethod()).thenReturn("GET"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/properties/index", "GET"); - assertParam("id", "my.property"); - assertNoParam("component", "value", "values"); - } - - @Test - public void redirect_api_properties_when_url_ands_with_slash() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties/"); - when(request.getParameter("id")).thenReturn("my.property"); - when(request.getMethod()).thenReturn("GET"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/properties/index", "GET"); - assertParam("id", "my.property"); - assertNoParam("component", "value", "values"); - } - - @Test - public void redirect_api_properties_when_resource() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties/my.property"); - when(request.getParameter("resource")).thenReturn("my_project"); - when(request.getMethod()).thenReturn("GET"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/properties/index", "GET"); - assertParam("id", "my.property"); - assertParam("resource", "my_project"); - assertNoParam("component", "value", "values"); - } - - @Test - public void redirect_api_properties_when_format() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties/my.property"); - when(request.getParameter("format")).thenReturn("json"); - when(request.getMethod()).thenReturn("GET"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/properties/index", "GET"); - assertParam("id", "my.property"); - assertParam("format", "json"); - assertNoParam("component", "value", "values"); - } - - @Test - public void redirect_put_api_properties_to_api_settings_set() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties/my.property"); - when(request.getParameter("value")).thenReturn("my_value"); - when(request.getParameter("resource")).thenReturn("my_project"); - when(request.getMethod()).thenReturn("PUT"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/settings/set", "POST"); - assertParam("key", "my.property"); - assertParam("value", "my_value"); - assertParam("component", "my_project"); - assertNoParam("values"); - } - - @Test - public void redirect_post_api_properties_to_api_settings_set() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties/my.property"); - when(request.getParameter("value")).thenReturn("my_value"); - when(request.getParameter("resource")).thenReturn("my_project"); - when(request.getMethod()).thenReturn("POST"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/settings/set", "POST"); - assertParam("key", "my.property"); - assertParam("value", "my_value"); - assertParam("component", "my_project"); - assertNoParam("values"); - } - - @Test - public void redirect_post_api_properties_to_api_settings_set_when_value_is_in_body() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties/my.property"); - when(request.getMethod()).thenReturn("POST"); - when(request.getInputStream()).thenReturn(new TestInputStream("my_value")); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/settings/set", "POST"); - assertParam("key", "my.property"); - assertParam("value", "my_value"); - assertNoParam("values", "component"); - } - - @Test - public void redirect_post_api_properties_to_api_settings_set_when_multi_values() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties/my.property"); - when(request.getParameter("value")).thenReturn("value1,value2,value3"); - when(request.getMethod()).thenReturn("POST"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/settings/set", "POST"); - assertParam("key", "my.property"); - assertNoParam("value"); - assertThat(servletRequestCaptor.getValue().hasParam("values")).as("Parameter '%s' hasn't been found", "values").isTrue(); - assertThat(servletRequestCaptor.getValue().readMultiParam("values")).containsOnly("value1", "value2", "value3"); - } - - @Test - public void redirect_post_api_properties_to_api_settings_reset_when_no_value() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties/my.property"); - when(request.getParameter("resource")).thenReturn("my_project"); - when(request.getMethod()).thenReturn("POST"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/settings/reset", "POST"); - assertParam("keys", "my.property"); - assertParam("component", "my_project"); - assertNoParam("value", "values"); - } - - @Test - public void redirect_post_api_properties_to_api_settings_reset_when_empty_value() throws Exception { - when(request.getRequestURI()).thenReturn("/api/properties/my.property"); - when(request.getParameter("value")).thenReturn(""); - when(request.getParameter("resource")).thenReturn("my_project"); - when(request.getMethod()).thenReturn("POST"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/settings/reset", "POST"); - assertParam("keys", "my.property"); - assertParam("component", "my_project"); - assertNoParam("value", "values"); - } - - @Test - public void redirect_delete_api_properties_to_api_settings_reset() { - when(request.getRequestURI()).thenReturn("/api/properties/my.property"); - when(request.getParameter("resource")).thenReturn("my_project"); - when(request.getMethod()).thenReturn("DELETE"); - - underTest.doFilter(request, response, chain); - - assertRedirection("api/settings/reset", "POST"); - assertParam("keys", "my.property"); - assertParam("component", "my_project"); - assertNoParam("value", "values"); - } - - private void assertRedirection(String path, String method) { - verify(webServiceEngine).execute(servletRequestCaptor.capture(), any(ServletResponse.class)); - assertThat(servletRequestCaptor.getValue().getPath()).isEqualTo(path); - assertThat(servletRequestCaptor.getValue().method()).isEqualTo(method); - } - - private void assertParam(String key, String value) { - assertThat(servletRequestCaptor.getValue().hasParam(key)).as("Parameter '%s' hasn't been found", key).isTrue(); - assertThat(servletRequestCaptor.getValue().readParam(key)).isEqualTo(value); - } - - private void assertNoParam(String... keys) { - Arrays.stream(keys).forEach(key -> { - assertThat(servletRequestCaptor.getValue().hasParam(key)).as(key).isFalse(); - assertThat(servletRequestCaptor.getValue().readParam(key)).as(key).isNull(); - }); - } - - private static class TestInputStream extends ServletInputStream { - - private final ByteArrayInputStream byteArrayInputStream; - - TestInputStream(String value) { - this.byteArrayInputStream = new ByteArrayInputStream(value.getBytes(UTF_8)); - } - - @Override - public boolean isFinished() { - return false; - } - - @Override - public boolean isReady() { - return false; - } - - @Override - public void setReadListener(ReadListener listener) { - throw new UnsupportedOperationException("Not available"); - } - - @Override - public int read() { - return byteArrayInputStream.read(); - } - } -} diff --git a/server/sonar-webserver/src/test/java/org/sonar/server/platform/web/WebServiceFilterTest.java b/server/sonar-webserver/src/test/java/org/sonar/server/platform/web/WebServiceFilterTest.java index fdee998a8dc..d1d2c06a331 100644 --- a/server/sonar-webserver/src/test/java/org/sonar/server/platform/web/WebServiceFilterTest.java +++ b/server/sonar-webserver/src/test/java/org/sonar/server/platform/web/WebServiceFilterTest.java @@ -25,11 +25,11 @@ import javax.servlet.FilterChain; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.sonar.api.SonarEdition; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.sonar.api.SonarEdition; import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarRuntime; import org.sonar.api.internal.SonarRuntimeImpl; @@ -110,14 +110,6 @@ public class WebServiceFilterTest { } @Test - public void does_not_match_api_properties_ws() { - initWebServiceEngine(newWsUrl("api/properties", "index")); - - assertThat(underTest.doGetPattern().matches("/api/properties")).isFalse(); - assertThat(underTest.doGetPattern().matches("/api/properties/index")).isFalse(); - } - - @Test public void execute_ws() { underTest = new WebServiceFilter(webServiceEngine, runtime); diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/DefaultWsClient.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/DefaultWsClient.java index 22b9c5112bc..21e7b2a7c22 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/DefaultWsClient.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/DefaultWsClient.java @@ -33,7 +33,6 @@ import org.sonarqube.ws.client.duplications.DuplicationsService; import org.sonarqube.ws.client.editions.EditionsService; import org.sonarqube.ws.client.emails.EmailsService; import org.sonarqube.ws.client.favorites.FavoritesService; -import org.sonarqube.ws.client.favourites.FavouritesService; import org.sonarqube.ws.client.governancereports.GovernanceReportsService; import org.sonarqube.ws.client.issues.IssuesService; import org.sonarqube.ws.client.l10n.L10nService; @@ -98,7 +97,6 @@ class DefaultWsClient implements WsClient { private final EditionsService editionsService; private final EmailsService emailsService; private final FavoritesService favoritesService; - private final FavouritesService favouritesService; private final GovernanceReportsService governanceReportsService; private final IssuesService issuesService; private final L10nService l10nService; @@ -156,7 +154,6 @@ class DefaultWsClient implements WsClient { this.editionsService = new EditionsService(wsConnector); this.emailsService = new EmailsService(wsConnector); this.favoritesService = new FavoritesService(wsConnector); - this.favouritesService = new FavouritesService(wsConnector); this.governanceReportsService = new GovernanceReportsService(wsConnector); this.issuesService = new IssuesService(wsConnector); this.l10nService = new L10nService(wsConnector); @@ -267,11 +264,6 @@ class DefaultWsClient implements WsClient { } @Override - public FavouritesService favourites() { - return favouritesService; - } - - @Override public GovernanceReportsService governanceReports() { return governanceReportsService; } diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java index 7023bf716fd..1f964f03c6d 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java @@ -33,7 +33,6 @@ import org.sonarqube.ws.client.duplications.DuplicationsService; import org.sonarqube.ws.client.editions.EditionsService; import org.sonarqube.ws.client.emails.EmailsService; import org.sonarqube.ws.client.favorites.FavoritesService; -import org.sonarqube.ws.client.favourites.FavouritesService; import org.sonarqube.ws.client.governancereports.GovernanceReportsService; import org.sonarqube.ws.client.issues.IssuesService; import org.sonarqube.ws.client.l10n.L10nService; @@ -122,8 +121,6 @@ public interface WsClient { FavoritesService favorites(); - FavouritesService favourites(); - GovernanceReportsService governanceReports(); IssuesService issues(); diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/favourites/FavouritesService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/favourites/FavouritesService.java deleted file mode 100644 index 83ec0384102..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/favourites/FavouritesService.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.favourites; - -import java.util.stream.Collectors; -import javax.annotation.Generated; -import org.sonarqube.ws.MediaTypes; -import org.sonarqube.ws.client.BaseService; -import org.sonarqube.ws.client.GetRequest; -import org.sonarqube.ws.client.PostRequest; -import org.sonarqube.ws.client.WsConnector; - -/** - * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/favourites">Further information about this web service online</a> - */ -@Generated("sonar-ws-generator") -public class FavouritesService extends BaseService { - - public FavouritesService(WsConnector wsConnector) { - super(wsConnector, "api/favourites"); - } - - /** - * - * This is part of the internal API. - * This is a GET request. - * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/favourites/index">Further information about this action online (including a response example)</a> - * @since 2.6 - * @deprecated since 6.3 - */ - @Deprecated - public String index() { - return call( - new GetRequest(path("index")) - .setMediaType(MediaTypes.JSON) - ).content(); - } -} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/favourites/package-info.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/favourites/package-info.java deleted file mode 100644 index 19ce8f9fc88..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/favourites/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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. - */ -@ParametersAreNonnullByDefault -@Generated("sonar-ws-generator") -package org.sonarqube.ws.client.favourites; - -import javax.annotation.ParametersAreNonnullByDefault; -import javax.annotation.Generated; - |