From: Julien Lancelot Date: Fri, 25 Aug 2017 08:05:09 +0000 (+0200) Subject: SONAR-9616 Handle branch in api/settings/values X-Git-Tag: 6.6-RC1~380^2~43 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=0cf6dd627a9949749ce1400a82193e33632491b8;p=sonarqube.git SONAR-9616 Handle branch in api/settings/values --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java index 836e944cb1b..db6e2c21e31 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java @@ -49,9 +49,11 @@ import static java.util.stream.Stream.concat; import static org.apache.commons.lang.StringUtils.isEmpty; import static org.sonar.api.PropertyType.PROPERTY_SET; import static org.sonar.api.web.UserRole.USER; +import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; import static org.sonar.server.ws.WsUtils.writeProtobuf; import static org.sonarqube.ws.client.setting.SettingsWsParameters.ACTION_VALUES; +import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_BRANCH; import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_COMPONENT; import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_KEYS; @@ -95,12 +97,17 @@ public class ValuesAction implements SettingsWsAction { .setResponseExample(getClass().getResource("values-example.json")) .setSince("6.3") .setHandler(this); - action.createParam(PARAM_COMPONENT) - .setDescription("Component key") - .setExampleValue(KEY_PROJECT_EXAMPLE_001); action.createParam(PARAM_KEYS) .setDescription("List of setting keys") .setExampleValue("sonar.test.inclusions,sonar.dbcleaner.cleanDirectory"); + action.createParam(PARAM_COMPONENT) + .setDescription("Component key") + .setExampleValue(KEY_PROJECT_EXAMPLE_001); + action.createParam(PARAM_BRANCH) + .setDescription("Branch key") + .setExampleValue(KEY_BRANCH_EXAMPLE_001) + .setInternal(true) + .setSince("6.6"); } @Override @@ -122,7 +129,8 @@ public class ValuesAction implements SettingsWsAction { private static ValuesRequest toWsRequest(Request request) { ValuesRequest.Builder builder = ValuesRequest.builder() - .setComponent(request.param(PARAM_COMPONENT)); + .setComponent(request.param(PARAM_COMPONENT)) + .setBranch(request.param(PARAM_BRANCH)); if (request.hasParam(PARAM_KEYS)) { builder.setKeys(request.paramAsStrings(PARAM_KEYS)); } @@ -142,16 +150,20 @@ public class ValuesAction implements SettingsWsAction { if (componentKey == null) { return Optional.empty(); } - ComponentDto component = componentFinder.getByKey(dbSession, componentKey); + ComponentDto component = componentFinder.getByKeyAndOptionalBranch(dbSession, componentKey, valuesRequest.getBranch()); userSession.checkComponentPermission(USER, component); return Optional.of(component); } private List loadSettings(DbSession dbSession, Optional component, Set keys) { - // List of settings must be kept in the following orders : default -> global -> component + // List of settings must be kept in the following orders : default -> global -> component -> branch List settings = new ArrayList<>(); settings.addAll(loadDefaultSettings(keys)); settings.addAll(settingsFinder.loadGlobalSettings(dbSession, keys)); + if (component.isPresent() && component.get().getBranch() != null && component.get().getMainBranchProjectUuid() != null) { + ComponentDto project = dbClient.componentDao().selectOrFailByUuid(dbSession, component.get().getMainBranchProjectUuid()); + settings.addAll(settingsFinder.loadComponentSettings(dbSession, keys, project).values()); + } component.ifPresent(componentDto -> settings.addAll(settingsFinder.loadComponentSettings(dbSession, keys, componentDto).values())); return settings.stream() .filter(settingsWsSupport.isSettingVisible(component)) diff --git a/server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java index 1624a068e85..951d74abe7e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java @@ -727,6 +727,42 @@ public class ValuesActionTest { assertThat(result.getSettings(0).getValue()).isEqualTo("fi±∞…"); } + @Test + public void branch_values() throws Exception { + ComponentDto project = db.components().insertMainBranch(); + userSession.logIn().addProjectPermission(USER, project); + ComponentDto branch = db.components().insertProjectBranch(project); + definitions.addComponent(PropertyDefinition.builder("sonar.leak.period").onQualifiers(PROJECT).build()); + propertyDb.insertProperties(newComponentPropertyDto(branch).setKey("sonar.leak.period").setValue("two")); + + ValuesWsResponse result = ws.newRequest() + .setParam("keys", "sonar.leak.period") + .setParam("component", branch.getKey()) + .setParam("branch", branch.getBranch()) + .executeProtobuf(ValuesWsResponse.class); + + assertThat(result.getSettingsList()).hasSize(1); + assertSetting(result.getSettings(0), "sonar.leak.period", "two", false); + } + + @Test + public void branch_values_inherit_from_project() throws Exception { + ComponentDto project = db.components().insertMainBranch(); + userSession.logIn().addProjectPermission(USER, project); + ComponentDto branch = db.components().insertProjectBranch(project); + definitions.addComponent(PropertyDefinition.builder("sonar.leak.period").onQualifiers(PROJECT).build()); + propertyDb.insertProperties(newComponentPropertyDto(project).setKey("sonar.leak.period").setValue("two")); + + ValuesWsResponse result = ws.newRequest() + .setParam("keys", "sonar.leak.period") + .setParam("component", branch.getKey()) + .setParam("branch", branch.getBranch()) + .executeProtobuf(ValuesWsResponse.class); + + assertThat(result.getSettingsList()).hasSize(1); + assertSetting(result.getSettings(0), "sonar.leak.period", "two", true); + } + @Test public void fail_when_user_has_not_project_browse_permission() throws Exception { userSession.logIn("project-admin").addProjectPermission(CODEVIEWER, project); @@ -752,6 +788,34 @@ public class ValuesActionTest { executeRequestForGlobalProperties("foo", "deprecated"); } + @Test + public void fail_when_component_not_found() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Component key 'unknown' not found"); + + ws.newRequest() + .setParam("keys", "foo") + .setParam("component", "unknown") + .execute(); + } + + @Test + public void fail_when_branch_not_found() { + ComponentDto project = db.components().insertMainBranch(); + ComponentDto branch = db.components().insertProjectBranch(project); + String settingKey = "not_allowed_on_branch"; + userSession.logIn().addProjectPermission(USER, project); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage(format("Component '%s' on branch 'unknown' not found", branch.getKey())); + + ws.newRequest() + .setParam("keys", settingKey) + .setParam("component", branch.getKey()) + .setParam("branch", "unknown") + .execute(); + } + @Test public void test_example_json_response() { logIn(); @@ -804,7 +868,7 @@ public class ValuesActionTest { assertThat(action.isInternal()).isFalse(); assertThat(action.isPost()).isFalse(); assertThat(action.responseExampleAsString()).isNotEmpty(); - assertThat(action.params()).hasSize(2); + assertThat(action.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("keys", "component", "branch"); } private ValuesWsResponse executeRequestForComponentProperties(ComponentDto componentDto, String... keys) { 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 230dbd992a5..3348fdb48c5 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 @@ -53,7 +53,8 @@ public class SettingsService extends BaseService { public ValuesWsResponse values(ValuesRequest request) { GetRequest getRequest = new GetRequest(path(ACTION_VALUES)) .setParam(PARAM_KEYS, inlineMultipleParamValue(request.getKeys())) - .setParam(PARAM_COMPONENT, request.getComponent()); + .setParam(PARAM_COMPONENT, request.getComponent()) + .setParam(PARAM_BRANCH, request.getBranch()); return call(getRequest, ValuesWsResponse.parser()); } @@ -64,16 +65,14 @@ public class SettingsService extends BaseService { .setParam(PARAM_VALUES, request.getValues()) .setParam(PARAM_FIELD_VALUES, request.getFieldValues()) .setParam(PARAM_COMPONENT, request.getComponent()) - .setParam(PARAM_BRANCH, request.getBranch()) - ); + .setParam(PARAM_BRANCH, request.getBranch())); } public void reset(ResetRequest request) { call(new PostRequest(path(ACTION_RESET)) .setParam(PARAM_KEYS, inlineMultipleParamValue(request.getKeys())) .setParam(PARAM_COMPONENT, request.getComponent()) - .setParam(PARAM_BRANCH, request.getBranch()) - ); + .setParam(PARAM_BRANCH, request.getBranch())); } } diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/setting/ValuesRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/setting/ValuesRequest.java index 6352e845fe8..f45d8d015d6 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/setting/ValuesRequest.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/setting/ValuesRequest.java @@ -29,12 +29,18 @@ import static java.util.Objects.requireNonNull; public class ValuesRequest { - private final String component; private final List keys; + private final String component; + private final String branch; private ValuesRequest(Builder builder) { - this.component = builder.component; this.keys = builder.keys; + this.component = builder.component; + this.branch = builder.branch; + } + + public List getKeys() { + return keys; } @CheckForNull @@ -42,8 +48,9 @@ public class ValuesRequest { return component; } - public List getKeys() { - return keys; + @CheckForNull + public String getBranch() { + return branch; } public static Builder builder() { @@ -51,18 +58,14 @@ public class ValuesRequest { } public static class Builder { - private String component; private List keys = new ArrayList<>(); + private String component; + private String branch; private Builder() { // enforce factory method use } - public Builder setComponent(@Nullable String component) { - this.component = component; - return this; - } - public Builder setKeys(List keys) { this.keys = requireNonNull(keys); return this; @@ -72,6 +75,16 @@ public class ValuesRequest { return setKeys(asList(keys)); } + public Builder setComponent(@Nullable String component) { + this.component = component; + return this; + } + + public Builder setBranch(@Nullable String branch) { + this.branch = branch; + return this; + } + public ValuesRequest build() { return new ValuesRequest(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 c3c1f9c051e..247acd0247f 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 @@ -63,6 +63,7 @@ public class SettingsServiceTest { underTest.values(ValuesRequest.builder() .setKeys("sonar.debt,sonar.issue") .setComponent("KEY") + .setBranch("BRANCH") .build()); GetRequest getRequest = serviceTester.getGetRequest(); @@ -70,6 +71,7 @@ public class SettingsServiceTest { serviceTester.assertThat(getRequest) .hasParam(PARAM_KEYS, "sonar.debt,sonar.issue") .hasParam(PARAM_COMPONENT, "KEY") + .hasParam(PARAM_BRANCH, "BRANCH") .andNoOtherParam(); } diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/setting/ValuesRequestTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/setting/ValuesRequestTest.java index fc0537d2014..fa6bdf94074 100644 --- a/sonar-ws/src/test/java/org/sonarqube/ws/client/setting/ValuesRequestTest.java +++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/setting/ValuesRequestTest.java @@ -36,24 +36,36 @@ public class ValuesRequestTest { public void create_request_with_no_component() { ValuesRequest result = underTest.setKeys("sonar.debt").build(); - assertThat(result.getComponent()).isNull(); assertThat(result.getKeys()).containsOnly("sonar.debt"); + assertThat(result.getComponent()).isNull(); + assertThat(result.getBranch()).isNull(); } @Test public void create_request_with_no_keys() { ValuesRequest result = underTest.build(); - assertThat(result.getComponent()).isNull(); assertThat(result.getKeys()).isEmpty(); + assertThat(result.getComponent()).isNull(); + assertThat(result.getBranch()).isNull(); } @Test public void create_request_with_component() { ValuesRequest result = underTest.setKeys("sonar.debt").setComponent("projectKey").build(); + assertThat(result.getKeys()).containsOnly("sonar.debt"); assertThat(result.getComponent()).isEqualTo("projectKey"); + assertThat(result.getBranch()).isNull(); + } + + @Test + public void create_request_with_component_and_branch() { + ValuesRequest result = underTest.setKeys("sonar.debt").setComponent("projectKey").setBranch("branch").build(); + assertThat(result.getKeys()).containsOnly("sonar.debt"); + assertThat(result.getComponent()).isEqualTo("projectKey"); + assertThat(result.getBranch()).isEqualTo("branch"); } }