From 43eb45b1b7bddf7105d500f85934eb6f402dca3a Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Mon, 5 Sep 2016 10:56:00 +0200 Subject: [PATCH] SONAR-8039 /api/licenses/list is returning license names --- .../sonar/server/license/ws/ListAction.java | 55 +++++++++++-------- .../sonar/server/license/ws/list-example.json | 2 + .../server/license/ws/ListActionTest.java | 36 +++++++----- sonar-ws/src/main/protobuf/ws-licenses.proto | 21 +++---- 4 files changed, 68 insertions(+), 46 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/license/ws/ListAction.java b/server/sonar-server/src/main/java/org/sonar/server/license/ws/ListAction.java index 6ff20b00d23..f7f914b4f8e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/license/ws/ListAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/license/ws/ListAction.java @@ -20,6 +20,8 @@ package org.sonar.server.license.ws; +import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -33,19 +35,20 @@ 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.core.util.stream.Collectors; import org.sonar.db.DbClient; import org.sonar.db.DbSession; -import org.sonar.db.property.PropertyDto; +import org.sonar.server.setting.ws.Setting; +import org.sonar.server.setting.ws.SettingsFinder; import org.sonar.server.user.UserSession; import org.sonar.server.ws.WsAction; import org.sonarqube.ws.Licenses; import org.sonarqube.ws.Licenses.ListWsResponse; -import static com.google.common.collect.Sets.newHashSet; +import static com.google.common.base.Strings.isNullOrEmpty; import static org.sonar.api.CoreProperties.PERMANENT_SERVER_ID; import static org.sonar.api.PropertyType.LICENSE; import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; -import static org.sonar.core.util.stream.Collectors.toSet; import static org.sonar.core.util.stream.Collectors.uniqueIndex; import static org.sonar.server.ws.WsUtils.writeProtobuf; import static org.sonarqube.ws.client.license.LicensesWsParameters.ACTION_LIST; @@ -57,11 +60,13 @@ public class ListAction implements WsAction { private final UserSession userSession; private final PropertyDefinitions definitions; private final DbClient dbClient; + private final SettingsFinder settingsFinder; - public ListAction(UserSession userSession, PropertyDefinitions definitions, DbClient dbClient) { + public ListAction(UserSession userSession, PropertyDefinitions definitions, DbClient dbClient, SettingsFinder settingsFinder) { this.userSession = userSession; this.definitions = definitions; this.dbClient = dbClient; + this.settingsFinder = settingsFinder; } @Override @@ -88,35 +93,39 @@ public class ListAction implements WsAction { } private ListWsResponse doHandle(DbSession dbSession) { - Set licenseSettingsKeys = definitions.getAll().stream() + Map licenseDefinitionsByKeys = definitions.getAll().stream() .filter(definition -> LICENSE.equals(definition.type())) - .map(PropertyDefinition::key) - .collect(toSet()); - Set settingsKeys = newHashSet(licenseSettingsKeys); + .collect(Collectors.uniqueIndex(PropertyDefinition::key, Function.identity())); + Set settingsKeys = new HashSet<>(licenseDefinitionsByKeys.keySet()); settingsKeys.add(PERMANENT_SERVER_ID); - List properties = dbClient.propertiesDao().selectGlobalPropertiesByKeys(dbSession, settingsKeys); - return new ListResponseBuilder(licenseSettingsKeys, properties).build(); + List settings = settingsFinder.loadGlobalSettings(dbSession, settingsKeys); + return new ListResponseBuilder(licenseDefinitionsByKeys, settings).build(); } private static class ListResponseBuilder { private final Optional serverId; - private final Map licenseSettingsByKey; - private final Set licenseSettingsKeys; + private final Map licenseSettingsByKey; + private final Collection licenseDefinitions; - ListResponseBuilder(Set licenseSettingsKeys, List properties) { - this.serverId = getServerId(properties); - this.licenseSettingsKeys = licenseSettingsKeys; - this.licenseSettingsByKey = properties.stream().collect(uniqueIndex(PropertyDto::getKey, Function.identity())); + ListResponseBuilder(Map licenseDefinitionsByKeys, List settings) { + this.serverId = getServerId(settings); + this.licenseDefinitions = licenseDefinitionsByKeys.values(); + this.licenseSettingsByKey = settings.stream().collect(uniqueIndex(Setting::getKey, Function.identity())); } ListWsResponse build() { ListWsResponse.Builder wsResponse = ListWsResponse.newBuilder(); - licenseSettingsKeys.forEach(key -> wsResponse.addLicenses(buildLicense(key, licenseSettingsByKey.get(key)))); + licenseDefinitions.forEach(def -> wsResponse.addLicenses(buildLicense(def, licenseSettingsByKey.get(def.key())))); return wsResponse.build(); } - private Licenses.License buildLicense(String key, @Nullable PropertyDto setting) { - Licenses.License.Builder licenseBuilder = Licenses.License.newBuilder().setKey(key); + private Licenses.License buildLicense(PropertyDefinition definition, @Nullable Setting setting) { + Licenses.License.Builder licenseBuilder = Licenses.License.newBuilder() + .setKey(definition.key()); + String name = definition.name(); + if (!isNullOrEmpty(name)) { + licenseBuilder.setName(name); + } if (setting != null) { License license = License.readBase64(setting.getValue()); licenseBuilder.setValue(setting.getValue()); @@ -130,7 +139,7 @@ public class ListAction implements WsAction { return licenseBuilder.build(); } - private static void setProduct(Licenses.License.Builder licenseBuilder, License license, PropertyDto setting) { + private static void setProduct(Licenses.License.Builder licenseBuilder, License license, Setting setting) { String product = license.getProduct(); if (product != null) { licenseBuilder.setProduct(product); @@ -181,9 +190,9 @@ public class ListAction implements WsAction { } } - private static Optional getServerId(List propertyDtos) { - Optional propertyDto = propertyDtos.stream().filter(setting -> setting.getKey().equals(PERMANENT_SERVER_ID)).findFirst(); - return propertyDto.isPresent() ? Optional.of(propertyDto.get().getValue()) : Optional.empty(); + private static Optional getServerId(List settings) { + Optional setting = settings.stream().filter(s -> s.getKey().equals(PERMANENT_SERVER_ID)).findFirst(); + return setting.isPresent() ? Optional.of(setting.get().getValue()) : Optional.empty(); } } } diff --git a/server/sonar-server/src/main/resources/org/sonar/server/license/ws/list-example.json b/server/sonar-server/src/main/resources/org/sonar/server/license/ws/list-example.json index 3ec21fa9f71..62a99ef1e53 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/license/ws/list-example.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/license/ws/list-example.json @@ -2,6 +2,7 @@ "licenses": [ { "key": "sonar.devcockpit.license.secured", + "name": "Dev Cockpit", "value": "T3JnYW5pc2F0aW9uOiBVbmtub3duIApTZXJ2ZXI6IDU0MzIxIApQcm9kdWN0OiBvdGhlciAKRXhwaXJhdGlvbjogMjAxMC0wMS0wMSAKVHlwZTogRVZBTFVBVElPTiAK", "product": "other", "organization": "Unknown", @@ -14,6 +15,7 @@ }, { "key": "sonar.governance.license.secured", + "name": "Governance", "value": "T3JnYW5pc2F0aW9uOiBTb25hclNvdXJjZSAKU2VydmVyOiAxMjM0NSAKUHJvZHVjdDogZ292ZXJuYW5jZSAKRXhwaXJhdGlvbjogMjA5OS0wMS0wMSAKVHlwZTogUFJPRFVDVElPTiAKb3RoZXI6IHZhbHVlIAo\u003d", "product": "governance", "organization": "SonarSource", diff --git a/server/sonar-server/src/test/java/org/sonar/server/license/ws/ListActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/license/ws/ListActionTest.java index 15edb494b36..0ee5b0633c9 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/license/ws/ListActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/license/ws/ListActionTest.java @@ -38,6 +38,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.property.PropertyDbTester; import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.setting.ws.SettingsFinder; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; @@ -58,6 +59,7 @@ import static org.sonarqube.ws.MediaTypes.JSON; public class ListActionTest { private static final String LICENSE_KEY_SAMPLE = "sonar.governance.license.secured"; + private static final String LICENSE_NAME_SAMPLE = "Governance"; private static final String ORGANISATION_SAMPLE = "SonarSource"; private static final String SERVER_ID_SAMPLE = "12345"; private static final String PRODUCT_SAMPLE = "governance"; @@ -75,21 +77,23 @@ public class ListActionTest { DbClient dbClient = db.getDbClient(); PropertyDbTester propertyDb = new PropertyDbTester(db); PropertyDefinitions definitions = new PropertyDefinitions(); + SettingsFinder settingsFinder = new SettingsFinder(dbClient, definitions); - WsActionTester ws = new WsActionTester(new ListAction(userSession, definitions, dbClient)); + WsActionTester ws = new WsActionTester(new ListAction(userSession, definitions, dbClient, settingsFinder)); @Test public void return_licenses() throws Exception { setUserAsSystemAdmin(); addServerIdSettings("12345"); String data = createBase64License("SonarSource", "governance", "12345", "2099-01-01", "PRODUCTION", ImmutableMap.of("other", "value")); - addLicenseSetting("sonar.governance.license.secured", data); + addLicenseSetting("sonar.governance.license.secured", "Governance", data); ListWsResponse result = executeRequest(); assertThat(result.getLicensesList()).hasSize(1); Licenses.License license = result.getLicenses(0); assertThat(license.getKey()).isEqualTo("sonar.governance.license.secured"); + assertThat(license.getName()).isEqualTo("Governance"); assertThat(license.getValue()).isEqualTo(data); assertThat(license.getProduct()).isEqualTo("governance"); assertThat(license.getOrganization()).isEqualTo("SonarSource"); @@ -128,16 +132,17 @@ public class ListActionTest { } @Test - public void return_license_with_minimal_info() throws Exception { + public void return_information_when_no_licence_set() throws Exception { setUserAsSystemAdmin(); addServerIdSettings(SERVER_ID_SAMPLE); - addLicenseSetting(LICENSE_KEY_SAMPLE, toBase64("")); + addLicenseSetting(LICENSE_KEY_SAMPLE, null, toBase64("")); ListWsResponse result = executeRequest(); assertThat(result.getLicensesList()).hasSize(1); Licenses.License license = result.getLicenses(0); assertThat(license.getKey()).isEqualTo(LICENSE_KEY_SAMPLE); + assertThat(license.hasName()).isFalse(); assertThat(license.getValue()).isEmpty(); assertThat(license.hasProduct()).isFalse(); assertThat(license.hasOrganization()).isFalse(); @@ -155,7 +160,8 @@ public class ListActionTest { public void return_license_with_bad_product() throws Exception { setUserAsSystemAdmin(); addServerIdSettings(SERVER_ID_SAMPLE); - addLicenseSetting(LICENSE_KEY_SAMPLE, createBase64License(ORGANISATION_SAMPLE, "Other", SERVER_ID_SAMPLE, EXPIRATION_SAMPLE, TYPE_SAMPLE, Collections.emptyMap())); + addLicenseSetting(LICENSE_KEY_SAMPLE, LICENSE_NAME_SAMPLE, + createBase64License(ORGANISATION_SAMPLE, "Other", SERVER_ID_SAMPLE, EXPIRATION_SAMPLE, TYPE_SAMPLE, Collections.emptyMap())); ListWsResponse result = executeRequest(); @@ -171,7 +177,8 @@ public class ListActionTest { public void return_license_with_bad_server_id() throws Exception { setUserAsSystemAdmin(); addServerIdSettings(SERVER_ID_SAMPLE); - addLicenseSetting(LICENSE_KEY_SAMPLE, createBase64License(ORGANISATION_SAMPLE, PRODUCT_SAMPLE, "Other", EXPIRATION_SAMPLE, TYPE_SAMPLE, Collections.emptyMap())); + addLicenseSetting(LICENSE_KEY_SAMPLE, LICENSE_NAME_SAMPLE, + createBase64License(ORGANISATION_SAMPLE, PRODUCT_SAMPLE, "Other", EXPIRATION_SAMPLE, TYPE_SAMPLE, Collections.emptyMap())); ListWsResponse result = executeRequest(); @@ -186,7 +193,8 @@ public class ListActionTest { @Test public void does_not_return_invalid_server_id_when_all_servers_accepted_and_no_server_id_setting() throws Exception { setUserAsSystemAdmin(); - addLicenseSetting(LICENSE_KEY_SAMPLE, createBase64License(ORGANISATION_SAMPLE, PRODUCT_SAMPLE, "*", EXPIRATION_SAMPLE, TYPE_SAMPLE, Collections.emptyMap())); + addLicenseSetting(LICENSE_KEY_SAMPLE, LICENSE_NAME_SAMPLE, + createBase64License(ORGANISATION_SAMPLE, PRODUCT_SAMPLE, "*", EXPIRATION_SAMPLE, TYPE_SAMPLE, Collections.emptyMap())); ListWsResponse result = executeRequest(); @@ -200,7 +208,8 @@ public class ListActionTest { public void return_license_when_all_servers_are_accepted() throws Exception { setUserAsSystemAdmin(); addServerIdSettings(SERVER_ID_SAMPLE); - addLicenseSetting(LICENSE_KEY_SAMPLE, createBase64License(ORGANISATION_SAMPLE, PRODUCT_SAMPLE, "*", EXPIRATION_SAMPLE, TYPE_SAMPLE, Collections.emptyMap())); + addLicenseSetting(LICENSE_KEY_SAMPLE, LICENSE_NAME_SAMPLE, + createBase64License(ORGANISATION_SAMPLE, PRODUCT_SAMPLE, "*", EXPIRATION_SAMPLE, TYPE_SAMPLE, Collections.emptyMap())); ListWsResponse result = executeRequest(); @@ -214,7 +223,7 @@ public class ListActionTest { public void return_license_when_expired() throws Exception { setUserAsSystemAdmin(); addServerIdSettings(SERVER_ID_SAMPLE); - addLicenseSetting(LICENSE_KEY_SAMPLE, + addLicenseSetting(LICENSE_KEY_SAMPLE, LICENSE_NAME_SAMPLE, createBase64License(ORGANISATION_SAMPLE, PRODUCT_SAMPLE, SERVER_ID_SAMPLE, "2010-01-01", TYPE_SAMPLE, Collections.emptyMap())); ListWsResponse result = executeRequest(); @@ -252,8 +261,9 @@ public class ListActionTest { public void test_example_json_response() { setUserAsSystemAdmin(); addServerIdSettings("12345"); - addLicenseSetting("sonar.governance.license.secured", createBase64License("SonarSource", "governance", "12345", "2099-01-01", "PRODUCTION", ImmutableMap.of("other", "value"))); - addLicenseSetting("sonar.devcockpit.license.secured", createBase64License("Unknown", "other", "54321", "2010-01-01", "EVALUATION", Collections.emptyMap())); + addLicenseSetting("sonar.governance.license.secured", "Governance", + createBase64License("SonarSource", "governance", "12345", "2099-01-01", "PRODUCTION", ImmutableMap.of("other", "value"))); + addLicenseSetting("sonar.devcockpit.license.secured", "Dev Cockpit", createBase64License("Unknown", "other", "54321", "2010-01-01", "EVALUATION", Collections.emptyMap())); String result = ws.newRequest() .setMediaType(JSON) @@ -287,8 +297,8 @@ public class ListActionTest { userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN); } - private void addLicenseSetting(String key, String value) { - definitions.addComponent(PropertyDefinition.builder(key).type(LICENSE).build()); + private void addLicenseSetting(String key, @Nullable String name, String value) { + definitions.addComponent(PropertyDefinition.builder(key).name(name).type(LICENSE).build()); propertyDb.insertProperties(newGlobalPropertyDto().setKey(key).setValue(value)); } diff --git a/sonar-ws/src/main/protobuf/ws-licenses.proto b/sonar-ws/src/main/protobuf/ws-licenses.proto index 77f1002ffba..72bf937010c 100644 --- a/sonar-ws/src/main/protobuf/ws-licenses.proto +++ b/sonar-ws/src/main/protobuf/ws-licenses.proto @@ -31,16 +31,17 @@ message ListWsResponse { message License { optional string key = 1; - optional string value = 2; - optional string product = 3; - optional string organization = 4; - optional string expiration = 5; - optional string serverId = 6; - optional string type = 7; - optional AdditionalProperties additionalProperties = 8; - optional bool invalidProduct = 9; - optional bool invalidExpiration = 10; - optional bool invalidServerId = 11; + optional string name = 2; + optional string value = 3; + optional string product = 4; + optional string organization = 5; + optional string expiration = 6; + optional string serverId = 7; + optional string type = 8; + optional AdditionalProperties additionalProperties = 9; + optional bool invalidProduct = 10; + optional bool invalidExpiration = 11; + optional bool invalidServerId = 12; } message AdditionalProperties { -- 2.39.5