]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8039 Create /api/licenses/list to return licenses with metadata 1199/head
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 30 Aug 2016 13:50:56 +0000 (15:50 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 1 Sep 2016 13:05:22 +0000 (15:05 +0200)
13 files changed:
server/sonar-server/src/main/java/org/sonar/server/license/ws/LicensesWs.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/license/ws/LicensesWsModule.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/license/ws/ListAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/license/ws/package-info.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/main/resources/org/sonar/server/license/ws/list-example.json [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/license/ws/LicensesWsModuleTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/license/ws/ListActionTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/license/LicensesService.java [new file with mode: 0644]
sonar-ws/src/main/java/org/sonarqube/ws/client/license/LicensesWsParameters.java [new file with mode: 0644]
sonar-ws/src/main/protobuf/ws-licenses.proto [new file with mode: 0644]
sonar-ws/src/test/java/org/sonarqube/ws/client/license/LicensesServiceTest.java [new file with mode: 0644]

diff --git a/server/sonar-server/src/main/java/org/sonar/server/license/ws/LicensesWs.java b/server/sonar-server/src/main/java/org/sonar/server/license/ws/LicensesWs.java
new file mode 100644 (file)
index 0000000..06dc877
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.license.ws;
+
+import org.sonar.api.server.ws.WebService;
+
+import static org.sonarqube.ws.client.license.LicensesWsParameters.CONTROLLER_SETTINGS;
+
+public class LicensesWs implements WebService {
+
+  private final ListAction listAction;
+
+  public LicensesWs(ListAction listAction) {
+    this.listAction = listAction;
+  }
+
+  @Override
+  public void define(Context context) {
+    NewController controller = context.createController(CONTROLLER_SETTINGS)
+      .setDescription("Manage licenses")
+      .setSince("6.1");
+    listAction.define(controller);
+    controller.done();
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/license/ws/LicensesWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/license/ws/LicensesWsModule.java
new file mode 100644 (file)
index 0000000..656dcc1
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.license.ws;
+
+import org.sonar.core.platform.Module;
+
+public class LicensesWsModule extends Module {
+  @Override
+  protected void configureModule() {
+    add(
+      LicensesWs.class,
+      ListAction.class);
+  }
+}
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
new file mode 100644 (file)
index 0000000..6ff20b0
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.license.ws;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import javax.annotation.Nullable;
+import org.sonar.api.config.License;
+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.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.property.PropertyDto;
+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 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;
+
+public class ListAction implements WsAction {
+
+  private static final String ALL_SERVERS_VALUE = "*";
+
+  private final UserSession userSession;
+  private final PropertyDefinitions definitions;
+  private final DbClient dbClient;
+
+  public ListAction(UserSession userSession, PropertyDefinitions definitions, DbClient dbClient) {
+    this.userSession = userSession;
+    this.definitions = definitions;
+    this.dbClient = dbClient;
+  }
+
+  @Override
+  public void define(WebService.NewController context) {
+    context.createAction(ACTION_LIST)
+      .setDescription("List licenses settings.<br>" +
+        "Requires 'Administer System' permission")
+      .setResponseExample(getClass().getResource("list-example.json"))
+      .setSince("6.1")
+      .setInternal(true)
+      .setHandler(this);
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    userSession.checkPermission(SYSTEM_ADMIN);
+
+    DbSession dbSession = dbClient.openSession(true);
+    try {
+      writeProtobuf(doHandle(dbSession), request, response);
+    } finally {
+      dbClient.closeSession(dbSession);
+    }
+  }
+
+  private ListWsResponse doHandle(DbSession dbSession) {
+    Set<String> licenseSettingsKeys = definitions.getAll().stream()
+      .filter(definition -> LICENSE.equals(definition.type()))
+      .map(PropertyDefinition::key)
+      .collect(toSet());
+    Set<String> settingsKeys = newHashSet(licenseSettingsKeys);
+    settingsKeys.add(PERMANENT_SERVER_ID);
+    List<PropertyDto> properties = dbClient.propertiesDao().selectGlobalPropertiesByKeys(dbSession, settingsKeys);
+    return new ListResponseBuilder(licenseSettingsKeys, properties).build();
+  }
+
+  private static class ListResponseBuilder {
+    private final Optional<String> serverId;
+    private final Map<String, PropertyDto> licenseSettingsByKey;
+    private final Set<String> licenseSettingsKeys;
+
+    ListResponseBuilder(Set<String> licenseSettingsKeys, List<PropertyDto> properties) {
+      this.serverId = getServerId(properties);
+      this.licenseSettingsKeys = licenseSettingsKeys;
+      this.licenseSettingsByKey = properties.stream().collect(uniqueIndex(PropertyDto::getKey, Function.identity()));
+    }
+
+    ListWsResponse build() {
+      ListWsResponse.Builder wsResponse = ListWsResponse.newBuilder();
+      licenseSettingsKeys.forEach(key -> wsResponse.addLicenses(buildLicense(key, licenseSettingsByKey.get(key))));
+      return wsResponse.build();
+    }
+
+    private Licenses.License buildLicense(String key, @Nullable PropertyDto setting) {
+      Licenses.License.Builder licenseBuilder = Licenses.License.newBuilder().setKey(key);
+      if (setting != null) {
+        License license = License.readBase64(setting.getValue());
+        licenseBuilder.setValue(setting.getValue());
+        setProduct(licenseBuilder, license, setting);
+        setOrganization(licenseBuilder, license);
+        setExpiration(licenseBuilder, license);
+        setServerId(licenseBuilder, license);
+        setType(licenseBuilder, license);
+        setAdditionalProperties(licenseBuilder, license);
+      }
+      return licenseBuilder.build();
+    }
+
+    private static void setProduct(Licenses.License.Builder licenseBuilder, License license, PropertyDto setting) {
+      String product = license.getProduct();
+      if (product != null) {
+        licenseBuilder.setProduct(product);
+      }
+      if (product == null || !setting.getKey().contains(product)) {
+        licenseBuilder.setInvalidProduct(true);
+      }
+    }
+
+    private static void setOrganization(Licenses.License.Builder licenseBuilder, License license) {
+      String licenseOrganization = license.getOrganization();
+      if (licenseOrganization != null) {
+        licenseBuilder.setOrganization(licenseOrganization);
+      }
+    }
+
+    private void setServerId(Licenses.License.Builder licenseBuilder, License license) {
+      String licenseServerId = license.getServer();
+      if (licenseServerId != null) {
+        licenseBuilder.setServerId(licenseServerId);
+      }
+      if (!Objects.equals(ALL_SERVERS_VALUE, licenseServerId) && serverId.isPresent() && !serverId.get().equals(licenseServerId)) {
+        licenseBuilder.setInvalidServerId(true);
+      }
+    }
+
+    private static void setExpiration(Licenses.License.Builder licenseBuilder, License license) {
+      String expiration = license.getExpirationDateAsString();
+      if (expiration != null) {
+        licenseBuilder.setExpiration(expiration);
+      }
+      if (license.isExpired()) {
+        licenseBuilder.setInvalidExpiration(true);
+      }
+    }
+
+    private static void setType(Licenses.License.Builder licenseBuilder, License license) {
+      String type = license.getType();
+      if (type != null) {
+        licenseBuilder.setType(type);
+      }
+    }
+
+    private static void setAdditionalProperties(Licenses.License.Builder licenseBuilder, License license) {
+      Map<String, String> additionalProperties = license.additionalProperties();
+      if (!additionalProperties.isEmpty()) {
+        licenseBuilder.getAdditionalPropertiesBuilder().putAllAdditionalProperties(additionalProperties).build();
+      }
+    }
+
+    private static Optional<String> getServerId(List<PropertyDto> propertyDtos) {
+      Optional<PropertyDto> propertyDto = propertyDtos.stream().filter(setting -> setting.getKey().equals(PERMANENT_SERVER_ID)).findFirst();
+      return propertyDto.isPresent() ? Optional.of(propertyDto.get().getValue()) : Optional.empty();
+    }
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/license/ws/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/license/ws/package-info.java
new file mode 100644 (file)
index 0000000..c31656e
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.license.ws;
+
+import javax.annotation.ParametersAreNonnullByDefault;
index fa0fcc452385f8c840c54de058fb3995bb331225..b2a65af59695be2f4f7280b4f6aff16306504e9c 100644 (file)
@@ -119,6 +119,7 @@ import org.sonar.server.issue.workflow.FunctionExecutor;
 import org.sonar.server.issue.workflow.IssueWorkflow;
 import org.sonar.server.issue.ws.IssueWsModule;
 import org.sonar.server.language.ws.LanguageWs;
+import org.sonar.server.license.ws.LicensesWsModule;
 import org.sonar.server.measure.MeasureFilterEngine;
 import org.sonar.server.measure.MeasureFilterExecutor;
 import org.sonar.server.measure.MeasureFilterFactory;
@@ -584,6 +585,9 @@ public class PlatformLevel4 extends PlatformLevel {
       PropertiesWs.class,
       SettingsWsModule.class,
 
+      // Licences
+      LicensesWsModule.class,
+
       TypeValidationModule.class,
 
       // Project Links
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
new file mode 100644 (file)
index 0000000..3ec21fa
--- /dev/null
@@ -0,0 +1,28 @@
+{
+  "licenses": [
+    {
+      "key": "sonar.devcockpit.license.secured",
+      "value": "T3JnYW5pc2F0aW9uOiBVbmtub3duIApTZXJ2ZXI6IDU0MzIxIApQcm9kdWN0OiBvdGhlciAKRXhwaXJhdGlvbjogMjAxMC0wMS0wMSAKVHlwZTogRVZBTFVBVElPTiAK",
+      "product": "other",
+      "organization": "Unknown",
+      "expiration": "2010-01-01",
+      "serverId": "54321",
+      "type": "EVALUATION",
+      "invalidProduct": true,
+      "invalidExpiration": true,
+      "invalidServerId": true
+    },
+    {
+      "key": "sonar.governance.license.secured",
+      "value": "T3JnYW5pc2F0aW9uOiBTb25hclNvdXJjZSAKU2VydmVyOiAxMjM0NSAKUHJvZHVjdDogZ292ZXJuYW5jZSAKRXhwaXJhdGlvbjogMjA5OS0wMS0wMSAKVHlwZTogUFJPRFVDVElPTiAKb3RoZXI6IHZhbHVlIAo\u003d",
+      "product": "governance",
+      "organization": "SonarSource",
+      "expiration": "2099-01-01",
+      "serverId": "12345",
+      "type": "PRODUCTION",
+      "additionalProperties": {
+        "other": "value"
+      }
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/license/ws/LicensesWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/license/ws/LicensesWsModuleTest.java
new file mode 100644 (file)
index 0000000..dc1c9ff
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.license.ws;
+
+import org.junit.Test;
+import org.sonar.core.platform.ComponentContainer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class LicensesWsModuleTest {
+  @Test
+  public void verify_count_of_added_components() {
+    ComponentContainer container = new ComponentContainer();
+    new LicensesWsModule().configure(container);
+    assertThat(container.size()).isEqualTo(2 + 2);
+  }
+}
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
new file mode 100644 (file)
index 0000000..15edb49
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.license.ws;
+
+import com.google.common.collect.ImmutableMap;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.apache.commons.codec.binary.Base64;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.config.PropertyDefinition;
+import org.sonar.api.config.PropertyDefinitions;
+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.property.PropertyDbTester;
+import org.sonar.server.exceptions.ForbiddenException;
+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.Licenses;
+import org.sonarqube.ws.Licenses.ListWsResponse;
+import org.sonarqube.ws.MediaTypes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Java6Assertions.entry;
+import static org.sonar.api.CoreProperties.PERMANENT_SERVER_ID;
+import static org.sonar.api.PropertyType.LICENSE;
+import static org.sonar.core.permission.GlobalPermissions.DASHBOARD_SHARING;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+import static org.sonar.db.property.PropertyTesting.newGlobalPropertyDto;
+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 ORGANISATION_SAMPLE = "SonarSource";
+  private static final String SERVER_ID_SAMPLE = "12345";
+  private static final String PRODUCT_SAMPLE = "governance";
+  private static final String TYPE_SAMPLE = "PRODUCTION";
+  private static final String EXPIRATION_SAMPLE = "2099-01-01";
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
+
+  @Rule
+  public DbTester db = DbTester.create(System2.INSTANCE);
+
+  DbClient dbClient = db.getDbClient();
+  PropertyDbTester propertyDb = new PropertyDbTester(db);
+  PropertyDefinitions definitions = new PropertyDefinitions();
+
+  WsActionTester ws = new WsActionTester(new ListAction(userSession, definitions, dbClient));
+
+  @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);
+
+    ListWsResponse result = executeRequest();
+
+    assertThat(result.getLicensesList()).hasSize(1);
+    Licenses.License license = result.getLicenses(0);
+    assertThat(license.getKey()).isEqualTo("sonar.governance.license.secured");
+    assertThat(license.getValue()).isEqualTo(data);
+    assertThat(license.getProduct()).isEqualTo("governance");
+    assertThat(license.getOrganization()).isEqualTo("SonarSource");
+    assertThat(license.getExpiration()).isEqualTo("2099-01-01");
+    assertThat(license.getType()).isEqualTo("PRODUCTION");
+    assertThat(license.getServerId()).isEqualTo("12345");
+    assertThat(license.getAdditionalProperties().getAdditionalProperties()).containsOnly(entry("other", "value"));
+
+    assertThat(license.hasInvalidProduct()).isFalse();
+    assertThat(license.hasInvalidExpiration()).isFalse();
+    assertThat(license.hasInvalidServerId()).isFalse();
+  }
+
+  @Test
+  public void return_licenses_even_if_no_value_set_in_database() throws Exception {
+    setUserAsSystemAdmin();
+    addServerIdSettings("12345");
+    definitions.addComponent(PropertyDefinition.builder("sonar.governance.license.secured").type(LICENSE).build());
+
+    ListWsResponse result = executeRequest();
+
+    assertThat(result.getLicensesList()).hasSize(1);
+    Licenses.License license = result.getLicenses(0);
+    assertThat(license.getKey()).isEqualTo("sonar.governance.license.secured");
+    assertThat(license.hasValue()).isFalse();
+    assertThat(license.hasProduct()).isFalse();
+    assertThat(license.hasOrganization()).isFalse();
+    assertThat(license.hasExpiration()).isFalse();
+    assertThat(license.hasType()).isFalse();
+    assertThat(license.hasServerId()).isFalse();
+    assertThat(license.hasAdditionalProperties()).isFalse();
+
+    assertThat(license.hasInvalidProduct()).isFalse();
+    assertThat(license.hasInvalidExpiration()).isFalse();
+    assertThat(license.hasInvalidServerId()).isFalse();
+  }
+
+  @Test
+  public void return_license_with_minimal_info() throws Exception {
+    setUserAsSystemAdmin();
+    addServerIdSettings(SERVER_ID_SAMPLE);
+    addLicenseSetting(LICENSE_KEY_SAMPLE, toBase64(""));
+
+    ListWsResponse result = executeRequest();
+
+    assertThat(result.getLicensesList()).hasSize(1);
+    Licenses.License license = result.getLicenses(0);
+    assertThat(license.getKey()).isEqualTo(LICENSE_KEY_SAMPLE);
+    assertThat(license.getValue()).isEmpty();
+    assertThat(license.hasProduct()).isFalse();
+    assertThat(license.hasOrganization()).isFalse();
+    assertThat(license.hasExpiration()).isFalse();
+    assertThat(license.hasType()).isFalse();
+    assertThat(license.hasServerId()).isFalse();
+    assertThat(license.hasAdditionalProperties()).isFalse();
+
+    assertThat(license.hasInvalidProduct()).isTrue();
+    assertThat(license.hasInvalidExpiration()).isFalse();
+    assertThat(license.hasInvalidServerId()).isTrue();
+  }
+
+  @Test
+  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()));
+
+    ListWsResponse result = executeRequest();
+
+    assertThat(result.getLicensesList()).hasSize(1);
+    Licenses.License license = result.getLicenses(0);
+    assertThat(license.getProduct()).isEqualTo("Other");
+    assertThat(license.getInvalidProduct()).isTrue();
+    assertThat(license.hasInvalidExpiration()).isFalse();
+    assertThat(license.hasInvalidServerId()).isFalse();
+  }
+
+  @Test
+  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()));
+
+    ListWsResponse result = executeRequest();
+
+    assertThat(result.getLicensesList()).hasSize(1);
+    Licenses.License license = result.getLicenses(0);
+    assertThat(license.getServerId()).isEqualTo("Other");
+    assertThat(license.getInvalidServerId()).isTrue();
+    assertThat(license.hasInvalidProduct()).isFalse();
+    assertThat(license.hasInvalidExpiration()).isFalse();
+  }
+
+  @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()));
+
+    ListWsResponse result = executeRequest();
+
+    assertThat(result.getLicensesList()).hasSize(1);
+    Licenses.License license = result.getLicenses(0);
+    assertThat(license.getServerId()).isEqualTo("*");
+    assertThat(license.hasInvalidServerId()).isFalse();
+  }
+
+  @Test
+  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()));
+
+    ListWsResponse result = executeRequest();
+
+    assertThat(result.getLicensesList()).hasSize(1);
+    Licenses.License license = result.getLicenses(0);
+    assertThat(license.getServerId()).isEqualTo("*");
+    assertThat(license.hasInvalidServerId()).isFalse();
+  }
+
+  @Test
+  public void return_license_when_expired() throws Exception {
+    setUserAsSystemAdmin();
+    addServerIdSettings(SERVER_ID_SAMPLE);
+    addLicenseSetting(LICENSE_KEY_SAMPLE,
+      createBase64License(ORGANISATION_SAMPLE, PRODUCT_SAMPLE, SERVER_ID_SAMPLE, "2010-01-01", TYPE_SAMPLE, Collections.emptyMap()));
+
+    ListWsResponse result = executeRequest();
+
+    assertThat(result.getLicensesList()).hasSize(1);
+    Licenses.License license = result.getLicenses(0);
+    assertThat(license.getExpiration()).isEqualTo("2010-01-01");
+    assertThat(license.getInvalidExpiration()).isTrue();
+    assertThat(license.hasInvalidProduct()).isFalse();
+    assertThat(license.hasInvalidServerId()).isFalse();
+  }
+
+  @Test
+  public void none_license_type_settings_are_not_returned() throws Exception {
+    setUserAsSystemAdmin();
+    definitions.addComponent(PropertyDefinition.builder("foo").build());
+    propertyDb.insertProperties(newGlobalPropertyDto().setKey("foo").setValue("value"));
+
+    ListWsResponse result = executeRequest();
+
+    assertThat(result.getLicensesList()).isEmpty();
+  }
+
+  @Test
+  public void fail_when_not_system_admin() throws Exception {
+    userSession.login("not-admin").setGlobalPermissions(DASHBOARD_SHARING);
+    definitions.addComponent(PropertyDefinition.builder("foo").build());
+
+    expectedException.expect(ForbiddenException.class);
+
+    executeRequest();
+  }
+
+  @Test
+  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()));
+
+    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()).isTrue();
+    assertThat(action.isPost()).isFalse();
+    assertThat(action.responseExampleAsString()).isNotEmpty();
+    assertThat(action.params()).isEmpty();
+  }
+
+  private ListWsResponse executeRequest() {
+    TestRequest request = ws.newRequest()
+      .setMediaType(MediaTypes.PROTOBUF);
+    try {
+      return ListWsResponse.parseFrom(request.execute().getInputStream());
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  private void setUserAsSystemAdmin() {
+    userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
+  }
+
+  private void addLicenseSetting(String key, String value) {
+    definitions.addComponent(PropertyDefinition.builder(key).type(LICENSE).build());
+    propertyDb.insertProperties(newGlobalPropertyDto().setKey(key).setValue(value));
+  }
+
+  private void addServerIdSettings(String serverId) {
+    propertyDb.insertProperties(newGlobalPropertyDto().setKey(PERMANENT_SERVER_ID).setValue(serverId));
+  }
+
+  private static String toBase64(String data) {
+    return Base64.encodeBase64String((data.getBytes(StandardCharsets.UTF_8)));
+  }
+
+  private static String createBase64License(@Nullable String organisation, @Nullable String product, @Nullable String serverId, @Nullable String expirationDate,
+    @Nullable String type, Map<String, String> additionalProperties) {
+    StringBuilder data = new StringBuilder();
+    data.append("Organisation: ").append(organisation).append(" \n");
+    data.append("Server: ").append(serverId).append(" \n");
+    data.append("Product: ").append(product).append(" \n");
+    data.append("Expiration: ").append(expirationDate).append(" \n");
+    data.append("Type: ").append(type).append(" \n");
+    for (Map.Entry<String, String> entry : additionalProperties.entrySet()) {
+      data.append(entry.getKey()).append(": ").append(entry.getValue()).append(" \n");
+    }
+    return toBase64(data.toString());
+  }
+
+}
index 59ec14cf1d069c4bdbb5f1100c042bda0c217379..f32885cca81d8179e2b54592935c277f37a86895 100644 (file)
@@ -78,12 +78,12 @@ public class ValuesActionTest {
   DbClient dbClient = db.getDbClient();
   PropertyDbTester propertyDb = new PropertyDbTester(db);
   ComponentDbTester componentDb = new ComponentDbTester(db);
-  PropertyDefinitions propertyDefinitions = new PropertyDefinitions();
-  SettingsFinder settingsFinder = new SettingsFinder(dbClient, propertyDefinitions);
+  PropertyDefinitions definitions = new PropertyDefinitions();
+  SettingsFinder settingsFinder = new SettingsFinder(dbClient, definitions);
 
   ComponentDto project;
 
-  WsActionTester ws = new WsActionTester(new ValuesAction(dbClient, new ComponentFinder(dbClient), userSession, propertyDefinitions, settingsFinder));
+  WsActionTester ws = new WsActionTester(new ValuesAction(dbClient, new ComponentFinder(dbClient), userSession, definitions, settingsFinder));
 
   @Before
   public void setUp() throws Exception {
@@ -93,7 +93,7 @@ public class ValuesActionTest {
   @Test
   public void return_simple_value() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition
+    definitions.addComponent(PropertyDefinition
       .builder("foo")
       .build());
     propertyDb.insertProperties(newGlobalPropertyDto().setKey("foo").setValue("one"));
@@ -114,13 +114,13 @@ public class ValuesActionTest {
     setUserAsSystemAdmin();
 
     // Property never defined, default value is returned
-    propertyDefinitions.addComponent(PropertyDefinition.builder("default")
+    definitions.addComponent(PropertyDefinition.builder("default")
       .multiValues(true)
       .defaultValue("one,two")
       .build());
 
     // Property defined at global level
-    propertyDefinitions.addComponent(PropertyDefinition.builder("global")
+    definitions.addComponent(PropertyDefinition.builder("global")
       .multiValues(true)
       .build());
     propertyDb.insertProperties(newGlobalPropertyDto().setKey("global").setValue("three,four"));
@@ -144,7 +144,7 @@ public class ValuesActionTest {
   @Test
   public void return_multi_value_with_coma() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition.builder("global").multiValues(true).build());
+    definitions.addComponent(PropertyDefinition.builder("global").multiValues(true).build());
     propertyDb.insertProperties(newGlobalPropertyDto().setKey("global").setValue("three,four%2Cfive"));
 
     ValuesWsResponse result = executeRequestForGlobalProperties("global");
@@ -158,7 +158,7 @@ public class ValuesActionTest {
   @Test
   public void return_property_set() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition
+    definitions.addComponent(PropertyDefinition
       .builder("foo")
       .type(PropertyType.PROPERTY_SET)
       .fields(asList(
@@ -180,7 +180,7 @@ public class ValuesActionTest {
   @Test
   public void return_property_set_for_component() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition
+    definitions.addComponent(PropertyDefinition
       .builder("foo")
       .type(PropertyType.PROPERTY_SET)
       .fields(asList(
@@ -202,7 +202,7 @@ public class ValuesActionTest {
   @Test
   public void return_default_values() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition
+    definitions.addComponent(PropertyDefinition
       .builder("foo")
       .defaultValue("default")
       .build());
@@ -216,7 +216,7 @@ public class ValuesActionTest {
   @Test
   public void return_global_values() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build());
+    definitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build());
     propertyDb.insertProperties(
       // The property is overriding default value
       newGlobalPropertyDto().setKey("property").setValue("one"));
@@ -230,7 +230,7 @@ public class ValuesActionTest {
   @Test
   public void return_project_values() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build());
+    definitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build());
     propertyDb.insertProperties(
       newGlobalPropertyDto().setKey("property").setValue("one"),
       // The property is overriding global value
@@ -245,7 +245,7 @@ public class ValuesActionTest {
   @Test
   public void return_is_inherited_to_true_when_property_is_defined_only_at_global_level() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build());
+    definitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build());
     // The property is not defined on project
     propertyDb.insertProperties(newGlobalPropertyDto().setKey("property").setValue("one"));
 
@@ -271,7 +271,7 @@ public class ValuesActionTest {
   @Test
   public void return_empty_when_property_def_exists_but_no_value() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition
+    definitions.addComponent(PropertyDefinition
       .builder("foo")
       .build());
 
@@ -283,7 +283,7 @@ public class ValuesActionTest {
   @Test
   public void return_nothing_when_unknown_keys() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition
+    definitions.addComponent(PropertyDefinition
       .builder("foo")
       .defaultValue("default")
       .build());
@@ -298,7 +298,7 @@ public class ValuesActionTest {
   public void return_module_values() throws Exception {
     setUserAsSystemAdmin();
     ComponentDto module = componentDb.insertComponent(newModuleDto(project));
-    propertyDefinitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build());
+    definitions.addComponent(PropertyDefinition.builder("property").defaultValue("default").build());
     propertyDb.insertProperties(
       newGlobalPropertyDto().setKey("property").setValue("one"),
       // The property is overriding global value
@@ -314,7 +314,7 @@ public class ValuesActionTest {
   public void return_inherited_values_on_module() throws Exception {
     setUserAsSystemAdmin();
     ComponentDto module = componentDb.insertComponent(newModuleDto(project));
-    propertyDefinitions.addComponents(asList(
+    definitions.addComponents(asList(
       PropertyDefinition.builder("defaultProperty").defaultValue("default").build(),
       PropertyDefinition.builder("globalProperty").build(),
       PropertyDefinition.builder("projectProperty").build(),
@@ -336,7 +336,7 @@ public class ValuesActionTest {
   @Test
   public void return_inherited_values_on_global_setting() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponents(asList(
+    definitions.addComponents(asList(
       PropertyDefinition.builder("defaultProperty").defaultValue("default").build(),
       PropertyDefinition.builder("globalProperty").build()));
     propertyDb.insertProperties(
@@ -354,7 +354,7 @@ public class ValuesActionTest {
     setUserAsSystemAdmin();
     ComponentDto module = componentDb.insertComponent(newModuleDto(project));
     ComponentDto subModule = componentDb.insertComponent(newModuleDto(module));
-    propertyDefinitions.addComponents(asList(
+    definitions.addComponents(asList(
       PropertyDefinition.builder("foo").defaultValue("default").build()));
     propertyDb.insertProperties(
       newGlobalPropertyDto().setKey("foo").setValue("global"),
@@ -372,7 +372,7 @@ public class ValuesActionTest {
     setUserAsSystemAdmin();
     ComponentDto module = componentDb.insertComponent(newModuleDto(project));
     ComponentDto subModule = componentDb.insertComponent(newModuleDto(module));
-    propertyDefinitions.addComponents(asList(
+    definitions.addComponents(asList(
       PropertyDefinition.builder("foo").defaultValue("default1,default2").multiValues(true).build()));
     propertyDb.insertProperties(
       newGlobalPropertyDto().setKey("foo").setValue("global1,global2"),
@@ -390,7 +390,7 @@ public class ValuesActionTest {
     setUserAsSystemAdmin();
     ComponentDto module = componentDb.insertComponent(newModuleDto(project));
     ComponentDto subModule = componentDb.insertComponent(newModuleDto(module));
-    propertyDefinitions.addComponent(PropertyDefinition
+    definitions.addComponent(PropertyDefinition
       .builder("foo")
       .type(PropertyType.PROPERTY_SET)
       .fields(asList(
@@ -412,7 +412,7 @@ public class ValuesActionTest {
     setUserAsSystemAdmin();
     ComponentDto module = componentDb.insertComponent(newModuleDto(project));
     ComponentDto subModule = componentDb.insertComponent(newModuleDto(module));
-    propertyDefinitions.addComponents(asList(
+    definitions.addComponents(asList(
       PropertyDefinition.builder("simple").build(),
       PropertyDefinition.builder("multi").multiValues(true).build(),
       PropertyDefinition.builder("set")
@@ -447,7 +447,7 @@ public class ValuesActionTest {
   @Test
   public void return_value_of_deprecated_key() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition
+    definitions.addComponent(PropertyDefinition
       .builder("foo")
       .deprecatedKey("deprecated")
       .build());
@@ -464,16 +464,16 @@ public class ValuesActionTest {
   @Test
   public void test_example_json_response() {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition
+    definitions.addComponent(PropertyDefinition
       .builder("sonar.test.jira")
       .defaultValue("abc")
       .build());
-    propertyDefinitions.addComponent(PropertyDefinition
+    definitions.addComponent(PropertyDefinition
       .builder("sonar.autogenerated")
       .multiValues(true)
       .build());
     propertyDb.insertProperties(newGlobalPropertyDto().setKey("sonar.autogenerated").setValue("val1,val2,val3"));
-    propertyDefinitions.addComponent(PropertyDefinition
+    definitions.addComponent(PropertyDefinition
       .builder("sonar.demo")
       .type(PropertyType.PROPERTY_SET)
       .fields(PropertyFieldDefinition.build("text").name("Text").build(),
@@ -502,7 +502,7 @@ public class ValuesActionTest {
   @Test
   public void fail_when_not_system_admin() throws Exception {
     userSession.login("not-admin").setGlobalPermissions(DASHBOARD_SHARING);
-    propertyDefinitions.addComponent(PropertyDefinition.builder("foo").build());
+    definitions.addComponent(PropertyDefinition.builder("foo").build());
 
     expectedException.expect(ForbiddenException.class);
 
@@ -512,7 +512,7 @@ public class ValuesActionTest {
   @Test
   public void fail_when_not_project_admin() throws Exception {
     userSession.login("project-admin").addProjectUuidPermissions(USER, project.uuid());
-    propertyDefinitions.addComponent(PropertyDefinition.builder("foo").build());
+    definitions.addComponent(PropertyDefinition.builder("foo").build());
 
     expectedException.expect(ForbiddenException.class);
 
@@ -522,7 +522,7 @@ public class ValuesActionTest {
   @Test
   public void fail_when_deprecated_key_and_new_key_are_used() throws Exception {
     setUserAsSystemAdmin();
-    propertyDefinitions.addComponent(PropertyDefinition
+    definitions.addComponent(PropertyDefinition
       .builder("foo")
       .deprecatedKey("deprecated")
       .build());
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/license/LicensesService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/license/LicensesService.java
new file mode 100644 (file)
index 0000000..93fb452
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonarqube.ws.client.license;
+
+import org.sonarqube.ws.Licenses.ListWsResponse;
+import org.sonarqube.ws.client.BaseService;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.WsConnector;
+
+import static org.sonarqube.ws.client.license.LicensesWsParameters.ACTION_LIST;
+import static org.sonarqube.ws.client.license.LicensesWsParameters.CONTROLLER_SETTINGS;
+
+public class LicensesService extends BaseService {
+
+  public LicensesService(WsConnector wsConnector) {
+    super(wsConnector, CONTROLLER_SETTINGS);
+  }
+
+  public ListWsResponse list() {
+    GetRequest getRequest = new GetRequest(path(ACTION_LIST));
+    return call(getRequest, ListWsResponse.parser());
+  }
+
+}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/license/LicensesWsParameters.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/license/LicensesWsParameters.java
new file mode 100644 (file)
index 0000000..a035f68
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonarqube.ws.client.license;
+
+public class LicensesWsParameters {
+  public static final String CONTROLLER_SETTINGS = "api/licenses";
+
+  public static final String ACTION_LIST = "list";
+
+  private LicensesWsParameters() {
+    // Only static stuff
+  }
+
+}
diff --git a/sonar-ws/src/main/protobuf/ws-licenses.proto b/sonar-ws/src/main/protobuf/ws-licenses.proto
new file mode 100644 (file)
index 0000000..77f1002
--- /dev/null
@@ -0,0 +1,51 @@
+// SonarQube, open source software quality management tool.
+// Copyright (C) 2008-2015 SonarSource
+// mailto:contact AT sonarsource DOT com
+//
+// SonarQube 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.
+//
+// SonarQube 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.
+
+syntax = "proto2";
+
+package sonarqube.ws.licenses;
+
+option java_package = "org.sonarqube.ws";
+option java_outer_classname = "Licenses";
+option optimize_for = SPEED;
+
+// Response of GET api/licenses/list
+message ListWsResponse {
+  repeated License licenses = 1;
+}
+
+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;
+}
+
+message AdditionalProperties {
+  map<string, string> additionalProperties = 1;
+}
+
+
+
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/license/LicensesServiceTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/license/LicensesServiceTest.java
new file mode 100644 (file)
index 0000000..8b305df
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonarqube.ws.client.license;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonarqube.ws.Licenses.ListWsResponse;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.ServiceTester;
+import org.sonarqube.ws.client.WsConnector;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class LicensesServiceTest {
+
+  @Rule
+  public ServiceTester<LicensesService> serviceTester = new ServiceTester<>(new LicensesService(mock(WsConnector.class)));
+
+  private LicensesService underTest = serviceTester.getInstanceUnderTest();
+
+  @Test
+  public void list_definitions() {
+    underTest.list();
+    GetRequest getRequest = serviceTester.getGetRequest();
+
+    assertThat(serviceTester.getGetParser()).isSameAs(ListWsResponse.parser());
+    serviceTester.assertThat(getRequest).andNoOtherParam();
+  }
+
+}