]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7300 Move api/properties WS to package property
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 9 Jan 2017 16:52:14 +0000 (17:52 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 10 Jan 2017 08:56:55 +0000 (09:56 +0100)
57 files changed:
server/sonar-server/src/main/java/org/sonar/server/config/ws/IndexAction.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/config/ws/PropertiesWs.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/config/ws/package-info.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/main/java/org/sonar/server/property/ws/IndexAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/property/ws/PropertiesWs.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/property/ws/package-info.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/ws/DeprecatedRestWebServiceFilter.java
server/sonar-server/src/main/java/org/sonar/server/ws/WebServiceFilter.java
server/sonar-server/src/main/resources/org/sonar/server/config/ws/index-example.json [deleted file]
server/sonar-server/src/main/resources/org/sonar/server/property/ws/index-example.json [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/config/ws/IndexActionTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/property/ws/IndexActionTest.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/does_not_fail_when_user_has_not_project_browse_permission.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/does_not_returned_secured_and_license_settings_in_property_set_when_not_authenticated.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/does_not_returned_secured_and_license_settings_when_not_authenticated.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/empty.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_all_project_settings_when_component_and_no_key.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_all_settings_when_no_component_and_no_key.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_default_values.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_global_values.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_inherited_values_on_global_setting.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_inherited_values_on_module.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_license_with_hash_settings_when_authenticated_but_not_admin.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_module_values.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_multi_value_with_coma.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_multi_values.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_only_one_setting_when_key_is_provided.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_project_values.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_property_set.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_secured_and_license_settings_in_property_set_when_system_admin.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_secured_and_license_settings_when_project_admin.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_secured_and_license_settings_when_system_admin.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_simple_value.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_values_even_if_no_property_definition.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/does_not_fail_when_user_has_not_project_browse_permission.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/does_not_returned_secured_and_license_settings_in_property_set_when_not_authenticated.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/does_not_returned_secured_and_license_settings_when_not_authenticated.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/empty.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_all_project_settings_when_component_and_no_key.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_all_settings_when_no_component_and_no_key.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_default_values.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_global_values.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_inherited_values_on_global_setting.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_inherited_values_on_module.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_license_with_hash_settings_when_authenticated_but_not_admin.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_module_values.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_multi_value_with_coma.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_multi_values.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_only_one_setting_when_key_is_provided.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_project_values.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_property_set.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_secured_and_license_settings_in_property_set_when_system_admin.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_secured_and_license_settings_when_project_admin.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_secured_and_license_settings_when_system_admin.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_simple_value.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_values_even_if_no_property_definition.json [new file with mode: 0644]

diff --git a/server/sonar-server/src/main/java/org/sonar/server/config/ws/IndexAction.java b/server/sonar-server/src/main/java/org/sonar/server/config/ws/IndexAction.java
deleted file mode 100644 (file)
index 67bce46..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * 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.config.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.core.permission.GlobalPermissions;
-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.component.ComponentFinder;
-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.server.ws.RailsHandler.PARAM_FORMAT;
-import static org.sonar.api.server.ws.RailsHandler.addJsonOnlyFormatParam;
-import static org.sonar.api.web.UserRole.ADMIN;
-import static org.sonar.server.setting.ws.SettingsPermissionPredicates.DOT_LICENSE;
-import static org.sonar.server.setting.ws.SettingsPermissionPredicates.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_KEY = "key";
-  private static final String PARAM_COMPONENT = "resource";
-
-  private final DbClient dbClient;
-  private final ComponentFinder componentFinder;
-  private final UserSession userSession;
-  private final PropertyDefinitions propertyDefinitions;
-
-  public IndexAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, PropertyDefinitions propertyDefinitions) {
-    this.dbClient = dbClient;
-    this.componentFinder = componentFinder;
-    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_KEY)
-      .setDescription("Setting key")
-      .setExampleValue("sonar.technicalDebt.hoursInDay");
-    action.createParam(PARAM_COMPONENT)
-      .setDescription("Component key or database id")
-      .setExampleValue(KEY_PROJECT_EXAMPLE_001);
-    addJsonOnlyFormatParam(action);
-  }
-
-  @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) {
-    DbSession dbSession = dbClient.openSession(true);
-    try {
-      Optional<ComponentDto> component = loadComponent(dbSession, request);
-      String key = request.param(PARAM_KEY);
-      List<PropertyDto> propertyDtos = loadProperties(dbSession, component, Optional.ofNullable(key));
-      new ResponseBuilder(propertyDtos).build(json);
-    } finally {
-      dbClient.closeSession(dbSession);
-    }
-  }
-
-  private Optional<ComponentDto> loadComponent(DbSession dbSession, Request request) {
-    String component = request.param(PARAM_COMPONENT);
-    if (component == null) {
-      return Optional.empty();
-    }
-    return Optional.of(loadComponent(dbSession, component));
-  }
-
-  private ComponentDto loadComponent(DbSession dbSession, String component) {
-    try {
-      Long componentId = Long.parseLong(component);
-      return componentFinder.getById(dbSession, componentId);
-    } catch (NumberFormatException e) {
-      return componentFinder.getByKey(dbSession, component);
-    }
-  }
-
-  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)
-      || (propertyDto.getKey().contains(DOT_LICENSE) && userSession.isLoggedIn());
-  }
-
-  private boolean hasAdminPermission(Optional<ComponentDto> component) {
-    return component.isPresent() ? userSession.hasComponentUuidPermission(ADMIN, component.get().uuid()) : userSession.hasPermission(GlobalPermissions.SYSTEM_ADMIN);
-  }
-
-  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-server/src/main/java/org/sonar/server/config/ws/PropertiesWs.java b/server/sonar-server/src/main/java/org/sonar/server/config/ws/PropertiesWs.java
deleted file mode 100644 (file)
index 3870bff..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.config.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-server/src/main/java/org/sonar/server/config/ws/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/config/ws/package-info.java
deleted file mode 100644 (file)
index c890c52..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.config.ws;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
index 6fe456ddf41f81da31f00a723b3f6b5f26381d9d..a03956b1af46d51dbc4f4192276dd09a88034498 100644 (file)
@@ -42,7 +42,6 @@ import org.sonar.server.component.DefaultComponentFinder;
 import org.sonar.server.component.DefaultRubyComponentService;
 import org.sonar.server.component.es.ProjectsEsModule;
 import org.sonar.server.component.ws.ComponentsWsModule;
-import org.sonar.server.config.ws.PropertiesWs;
 import org.sonar.server.debt.DebtModelBackup;
 import org.sonar.server.debt.DebtModelPluginRepository;
 import org.sonar.server.debt.DebtModelService;
@@ -134,6 +133,7 @@ import org.sonar.server.project.ws.ProjectsWsModule;
 import org.sonar.server.projectanalysis.ProjectAnalysisModule;
 import org.sonar.server.projectlink.ws.ProjectLinksModule;
 import org.sonar.server.property.InternalPropertiesImpl;
+import org.sonar.server.property.ws.PropertiesWs;
 import org.sonar.server.qualitygate.QualityGateModule;
 import org.sonar.server.qualityprofile.QProfileBackuper;
 import org.sonar.server.qualityprofile.QProfileComparison;
@@ -445,7 +445,7 @@ public class PlatformLevel4 extends PlatformLevel {
       // Settings
       PersistentSettings.class,
       PropertiesWs.class,
-      org.sonar.server.config.ws.IndexAction.class,
+      org.sonar.server.property.ws.IndexAction.class,
       SettingsWsModule.class,
 
       // Licences
diff --git a/server/sonar-server/src/main/java/org/sonar/server/property/ws/IndexAction.java b/server/sonar-server/src/main/java/org/sonar/server/property/ws/IndexAction.java
new file mode 100644 (file)
index 0000000..4d171d7
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * 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.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.core.permission.GlobalPermissions;
+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.component.ComponentFinder;
+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.server.ws.RailsHandler.PARAM_FORMAT;
+import static org.sonar.api.server.ws.RailsHandler.addJsonOnlyFormatParam;
+import static org.sonar.api.web.UserRole.ADMIN;
+import static org.sonar.server.setting.ws.SettingsPermissionPredicates.DOT_LICENSE;
+import static org.sonar.server.setting.ws.SettingsPermissionPredicates.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_KEY = "key";
+  private static final String PARAM_COMPONENT = "resource";
+
+  private final DbClient dbClient;
+  private final ComponentFinder componentFinder;
+  private final UserSession userSession;
+  private final PropertyDefinitions propertyDefinitions;
+
+  public IndexAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, PropertyDefinitions propertyDefinitions) {
+    this.dbClient = dbClient;
+    this.componentFinder = componentFinder;
+    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_KEY)
+      .setDescription("Setting key")
+      .setExampleValue("sonar.technicalDebt.hoursInDay");
+    action.createParam(PARAM_COMPONENT)
+      .setDescription("Component key or database id")
+      .setExampleValue(KEY_PROJECT_EXAMPLE_001);
+    addJsonOnlyFormatParam(action);
+  }
+
+  @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) {
+    DbSession dbSession = dbClient.openSession(true);
+    try {
+      Optional<ComponentDto> component = loadComponent(dbSession, request);
+      String key = request.param(PARAM_KEY);
+      List<PropertyDto> propertyDtos = loadProperties(dbSession, component, Optional.ofNullable(key));
+      new ResponseBuilder(propertyDtos).build(json);
+    } finally {
+      dbClient.closeSession(dbSession);
+    }
+  }
+
+  private Optional<ComponentDto> loadComponent(DbSession dbSession, Request request) {
+    String component = request.param(PARAM_COMPONENT);
+    if (component == null) {
+      return Optional.empty();
+    }
+    return Optional.of(loadComponent(dbSession, component));
+  }
+
+  private ComponentDto loadComponent(DbSession dbSession, String component) {
+    try {
+      Long componentId = Long.parseLong(component);
+      return componentFinder.getById(dbSession, componentId);
+    } catch (NumberFormatException e) {
+      return componentFinder.getByKey(dbSession, component);
+    }
+  }
+
+  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)
+      || (propertyDto.getKey().contains(DOT_LICENSE) && userSession.isLoggedIn());
+  }
+
+  private boolean hasAdminPermission(Optional<ComponentDto> component) {
+    return component.isPresent() ? userSession.hasComponentUuidPermission(ADMIN, component.get().uuid()) : userSession.hasPermission(GlobalPermissions.SYSTEM_ADMIN);
+  }
+
+  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-server/src/main/java/org/sonar/server/property/ws/PropertiesWs.java b/server/sonar-server/src/main/java/org/sonar/server/property/ws/PropertiesWs.java
new file mode 100644 (file)
index 0000000..7db24ea
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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.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-server/src/main/java/org/sonar/server/property/ws/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/property/ws/package-info.java
new file mode 100644 (file)
index 0000000..843eeaa
--- /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.property.ws;
+
+import javax.annotation.ParametersAreNonnullByDefault;
index 2ffd0e5fd73e800f165cd7eeec492908b1413748..dd774f623a9922b75224813d74d0d6656f61e48c 100644 (file)
@@ -30,9 +30,9 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.web.ServletFilter;
-import org.sonar.server.config.ws.IndexAction;
+import org.sonar.server.property.ws.IndexAction;
 
-import static org.sonar.server.config.ws.PropertiesWs.CONTROLLER_PROPERTIES;
+import static org.sonar.server.property.ws.PropertiesWs.CONTROLLER_PROPERTIES;
 
 /**
  * This filter is used to execute some deprecated Java WS, that were using REST
index 028c5c1760f1d519b06284a2249213e9f570561f..7d1f78da0283ec46166618ada417ee46fb85d49c 100644 (file)
@@ -32,7 +32,7 @@ import org.sonar.api.server.ws.RailsHandler;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.web.ServletFilter;
 
-import static org.sonar.server.config.ws.PropertiesWs.CONTROLLER_PROPERTIES;
+import static org.sonar.server.property.ws.PropertiesWs.CONTROLLER_PROPERTIES;
 
 /**
  * This filter is used to execute Java WS.
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/config/ws/index-example.json b/server/sonar-server/src/main/resources/org/sonar/server/config/ws/index-example.json
deleted file mode 100644 (file)
index 9574238..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-[
-  {
-    "key": "sonar.test.jira",
-    "value": "abc"
-  },
-  {
-    "key": "sonar.autogenerated",
-    "value": "val1,val2,val3",
-    "values": [
-      "val1",
-      "val2",
-      "val3"
-    ]
-  },
-  {
-    "key": "sonar.demo",
-    "value": "1,2",
-    "values": [
-      "1",
-      "2"
-    ]
-  },
-  {
-    "key": "sonar.demo.1.text",
-    "value": "foo"
-  },
-  {
-    "key": "sonar.demo.1.boolean",
-    "value": "true"
-  },
-  {
-    "key": "sonar.demo.2.text",
-    "value": "bar"
-  },
-  {
-    "key": "sonar.demo.2.boolean",
-    "value": "false"
-  }
-]
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/property/ws/index-example.json b/server/sonar-server/src/main/resources/org/sonar/server/property/ws/index-example.json
new file mode 100644 (file)
index 0000000..9574238
--- /dev/null
@@ -0,0 +1,39 @@
+[
+  {
+    "key": "sonar.test.jira",
+    "value": "abc"
+  },
+  {
+    "key": "sonar.autogenerated",
+    "value": "val1,val2,val3",
+    "values": [
+      "val1",
+      "val2",
+      "val3"
+    ]
+  },
+  {
+    "key": "sonar.demo",
+    "value": "1,2",
+    "values": [
+      "1",
+      "2"
+    ]
+  },
+  {
+    "key": "sonar.demo.1.text",
+    "value": "foo"
+  },
+  {
+    "key": "sonar.demo.1.boolean",
+    "value": "true"
+  },
+  {
+    "key": "sonar.demo.2.text",
+    "value": "bar"
+  },
+  {
+    "key": "sonar.demo.2.boolean",
+    "value": "false"
+  }
+]
diff --git a/server/sonar-server/src/test/java/org/sonar/server/config/ws/IndexActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/config/ws/IndexActionTest.java
deleted file mode 100644 (file)
index 1aba735..0000000
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * 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.config.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.property.PropertyDbTester;
-import org.sonar.server.component.ComponentFinder;
-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.core.permission.GlobalPermissions.SYSTEM_ADMIN;
-import static org.sonar.db.component.ComponentTesting.newModuleDto;
-import static org.sonar.db.component.ComponentTesting.newProjectDto;
-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);
-
-  DbClient dbClient = db.getDbClient();
-  PropertyDbTester propertyDb = new PropertyDbTester(db);
-  ComponentDbTester componentDb = new ComponentDbTester(db);
-  PropertyDefinitions definitions = new PropertyDefinitions();
-
-  ComponentDto project;
-
-  WsActionTester ws = new WsActionTester(new IndexAction(dbClient, new ComponentFinder(dbClient), userSession, definitions));
-
-  @Before
-  public void setUp() throws Exception {
-    project = componentDb.insertComponent(newProjectDto());
-  }
-
-  @Test
-  public void return_simple_value() throws Exception {
-    setAuthenticatedUser();
-    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() throws Exception {
-    setAuthenticatedUser();
-    // 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() throws Exception {
-    setAuthenticatedUser();
-    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() throws Exception {
-    setAuthenticatedUser();
-    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() throws Exception {
-    setAuthenticatedUser();
-    definitions.addComponent(PropertyDefinition.builder("foo").defaultValue("default").build());
-
-    executeAndVerify(null, null, "return_default_values.json");
-  }
-
-  @Test
-  public void return_global_values() throws Exception {
-    setAuthenticatedUser();
-    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() throws Exception {
-    setUserWithBrowsePermissionOnProject();
-    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.key(), null, "return_project_values.json");
-  }
-
-  @Test
-  public void return_values_even_if_no_property_definition() throws Exception {
-    setAuthenticatedUser();
-    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() throws Exception {
-    setAuthenticatedUser();
-    definitions.addComponent(PropertyDefinition.builder("foo").build());
-
-    executeAndVerify(null, null, "empty.json");
-  }
-
-  @Test
-  public void return_nothing_when_unknown_key() throws Exception {
-    setAuthenticatedUser();
-    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() throws Exception {
-    setUserWithBrowsePermissionOnProject();
-    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.key(), "property", "return_module_values.json");
-  }
-
-  @Test
-  public void return_inherited_values_on_module() throws Exception {
-    setUserWithBrowsePermissionOnProject();
-    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.key(), null, "return_inherited_values_on_module.json");
-  }
-
-  @Test
-  public void return_inherited_values_on_global_setting() throws Exception {
-    setAuthenticatedUser();
-    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() throws Exception {
-    setAuthenticatedUser();
-    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_and_license_settings_when_not_authenticated() throws Exception {
-    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"));
-
-    executeAndVerify(null, null, "does_not_returned_secured_and_license_settings_when_not_authenticated.json");
-  }
-
-  @Test
-  public void does_not_returned_secured_and_license_settings_in_property_set_when_not_authenticated() throws Exception {
-    definitions.addComponent(PropertyDefinition
-      .builder("foo")
-      .type(PropertyType.PROPERTY_SET)
-      .fields(asList(
-        PropertyFieldDefinition.build("key").name("Key").build(),
-        PropertyFieldDefinition.build("plugin.license.secured").name("License").type(LICENSE).build(),
-        PropertyFieldDefinition.build("secret.secured").name("Secured").build()))
-      .build());
-    propertyDb.insertPropertySet("foo", null,
-      ImmutableMap.of("key", "key1", "plugin.license.secured", "ABCD", "secret.secured", "123456"));
-
-    executeAndVerify(null, null, "does_not_returned_secured_and_license_settings_in_property_set_when_not_authenticated.json");
-  }
-
-  @Test
-  public void return_license_with_hash_settings_when_authenticated_but_not_admin() throws Exception {
-    setUserWithBrowsePermissionOnProject();
-    definitions.addComponents(asList(
-      PropertyDefinition.builder("foo").build(),
-      PropertyDefinition.builder("secret.secured").build(),
-      PropertyDefinition.builder("commercial.plugin").type(LICENSE).build(),
-      PropertyDefinition.builder("plugin.license.secured").type(LICENSE).build()));
-    propertyDb.insertProperties(
-      newGlobalPropertyDto().setKey("foo").setValue("one"),
-      newGlobalPropertyDto().setKey("secret.secured").setValue("password"),
-      newGlobalPropertyDto().setKey("commercial.plugin").setValue("ABCD"),
-      newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"),
-      newGlobalPropertyDto().setKey("plugin.licenseHash.secured").setValue("987654321"));
-
-    executeAndVerify(null, null, "return_license_with_hash_settings_when_authenticated_but_not_admin.json");
-  }
-
-  @Test
-  public void return_secured_and_license_settings_when_system_admin() throws Exception {
-    setUserAsSystemAdmin();
-    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("plugin.licenseHash.secured").setValue("987654321"));
-
-    executeAndVerify(null, null, "return_secured_and_license_settings_when_system_admin.json");
-  }
-
-  @Test
-  public void return_secured_and_license_settings_when_project_admin() throws Exception {
-    setUserAsProjectAdmin();
-    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.key(), null, "return_secured_and_license_settings_when_project_admin.json");
-  }
-
-  @Test
-  public void return_secured_and_license_settings_in_property_set_when_system_admin() throws Exception {
-    setUserAsSystemAdmin();
-    definitions.addComponent(PropertyDefinition
-      .builder("foo")
-      .type(PropertyType.PROPERTY_SET)
-      .fields(asList(
-        PropertyFieldDefinition.build("key").name("Key").build(),
-        PropertyFieldDefinition.build("plugin.license.secured").name("License").type(LICENSE).build(),
-        PropertyFieldDefinition.build("secret.secured").name("Secured").build()))
-      .build());
-    propertyDb.insertPropertySet("foo", null,
-      ImmutableMap.of("key", "key1", "plugin.license.secured", "ABCD", "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() throws Exception {
-    setUserAsSystemAdmin();
-    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() throws Exception {
-    setUserAsProjectAdmin();
-    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.key(), null, "return_all_project_settings_when_component_and_no_key.json");
-  }
-
-  @Test
-  public void return_only_one_setting_when_key_is_provided() throws Exception {
-    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.key(), "foo", "return_only_one_setting_when_key_is_provided.json");
-    executeAndVerify(project.key(), "unknown", "empty.json");
-  }
-
-  @Test
-  public void does_not_fail_when_user_has_not_project_browse_permission() throws Exception {
-    userSession.login("project-admin").addProjectUuidPermissions(CODEVIEWER, project.uuid());
-    definitions.addComponent(PropertyDefinition.builder("foo").build());
-    propertyDb.insertProperties(newComponentPropertyDto(project).setKey("foo").setValue("one"));
-
-    executeAndVerify(project.key(), null, "does_not_fail_when_user_has_not_project_browse_permission.json");
-  }
-
-  @Test
-  public void does_not_fail_when_format_is_set_to_json() throws Exception {
-    setAuthenticatedUser();
-    definitions.addComponent(PropertyDefinition.builder("foo").defaultValue("default").build());
-
-    ws.newRequest().setParam("format", "json").execute();
-  }
-
-  @Test
-  public void fail_when_format_is_set_to_xml() throws Exception {
-    setAuthenticatedUser();
-    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() {
-    setAuthenticatedUser();
-    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("key", key);
-    }
-    if (componentKey != null) {
-      request.setParam("resource", componentKey);
-    }
-    String result = request.execute().getInput();
-    assertJson(result).isSimilarTo(resource(expectedFile));
-  }
-
-  private void setAuthenticatedUser() {
-    userSession.login("user");
-  }
-
-  private void setUserWithBrowsePermissionOnProject() {
-    userSession.login("user").addProjectUuidPermissions(USER, project.uuid());
-  }
-
-  private void setUserAsSystemAdmin() {
-    userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
-  }
-
-  private void setUserAsProjectAdmin() {
-    userSession.login("project-admin")
-      .addProjectUuidPermissions(ADMIN, project.uuid())
-      .addProjectUuidPermissions(USER, project.uuid());
-  }
-
-  protected static URL resource(String s) {
-    Class<IndexActionTest> clazz = IndexActionTest.class;
-    return clazz.getResource(clazz.getSimpleName() + "/" + s);
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/property/ws/IndexActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/property/ws/IndexActionTest.java
new file mode 100644 (file)
index 0000000..e5a6530
--- /dev/null
@@ -0,0 +1,483 @@
+/*
+ * 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.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.property.PropertyDbTester;
+import org.sonar.server.component.ComponentFinder;
+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.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+import static org.sonar.db.component.ComponentTesting.newModuleDto;
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
+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);
+
+  DbClient dbClient = db.getDbClient();
+  PropertyDbTester propertyDb = new PropertyDbTester(db);
+  ComponentDbTester componentDb = new ComponentDbTester(db);
+  PropertyDefinitions definitions = new PropertyDefinitions();
+
+  ComponentDto project;
+
+  WsActionTester ws = new WsActionTester(new IndexAction(dbClient, new ComponentFinder(dbClient), userSession, definitions));
+
+  @Before
+  public void setUp() throws Exception {
+    project = componentDb.insertComponent(newProjectDto());
+  }
+
+  @Test
+  public void return_simple_value() throws Exception {
+    setAuthenticatedUser();
+    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() throws Exception {
+    setAuthenticatedUser();
+    // 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() throws Exception {
+    setAuthenticatedUser();
+    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() throws Exception {
+    setAuthenticatedUser();
+    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() throws Exception {
+    setAuthenticatedUser();
+    definitions.addComponent(PropertyDefinition.builder("foo").defaultValue("default").build());
+
+    executeAndVerify(null, null, "return_default_values.json");
+  }
+
+  @Test
+  public void return_global_values() throws Exception {
+    setAuthenticatedUser();
+    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() throws Exception {
+    setUserWithBrowsePermissionOnProject();
+    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.key(), null, "return_project_values.json");
+  }
+
+  @Test
+  public void return_values_even_if_no_property_definition() throws Exception {
+    setAuthenticatedUser();
+    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() throws Exception {
+    setAuthenticatedUser();
+    definitions.addComponent(PropertyDefinition.builder("foo").build());
+
+    executeAndVerify(null, null, "empty.json");
+  }
+
+  @Test
+  public void return_nothing_when_unknown_key() throws Exception {
+    setAuthenticatedUser();
+    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() throws Exception {
+    setUserWithBrowsePermissionOnProject();
+    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.key(), "property", "return_module_values.json");
+  }
+
+  @Test
+  public void return_inherited_values_on_module() throws Exception {
+    setUserWithBrowsePermissionOnProject();
+    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.key(), null, "return_inherited_values_on_module.json");
+  }
+
+  @Test
+  public void return_inherited_values_on_global_setting() throws Exception {
+    setAuthenticatedUser();
+    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() throws Exception {
+    setAuthenticatedUser();
+    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_and_license_settings_when_not_authenticated() throws Exception {
+    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"));
+
+    executeAndVerify(null, null, "does_not_returned_secured_and_license_settings_when_not_authenticated.json");
+  }
+
+  @Test
+  public void does_not_returned_secured_and_license_settings_in_property_set_when_not_authenticated() throws Exception {
+    definitions.addComponent(PropertyDefinition
+      .builder("foo")
+      .type(PropertyType.PROPERTY_SET)
+      .fields(asList(
+        PropertyFieldDefinition.build("key").name("Key").build(),
+        PropertyFieldDefinition.build("plugin.license.secured").name("License").type(LICENSE).build(),
+        PropertyFieldDefinition.build("secret.secured").name("Secured").build()))
+      .build());
+    propertyDb.insertPropertySet("foo", null,
+      ImmutableMap.of("key", "key1", "plugin.license.secured", "ABCD", "secret.secured", "123456"));
+
+    executeAndVerify(null, null, "does_not_returned_secured_and_license_settings_in_property_set_when_not_authenticated.json");
+  }
+
+  @Test
+  public void return_license_with_hash_settings_when_authenticated_but_not_admin() throws Exception {
+    setUserWithBrowsePermissionOnProject();
+    definitions.addComponents(asList(
+      PropertyDefinition.builder("foo").build(),
+      PropertyDefinition.builder("secret.secured").build(),
+      PropertyDefinition.builder("commercial.plugin").type(LICENSE).build(),
+      PropertyDefinition.builder("plugin.license.secured").type(LICENSE).build()));
+    propertyDb.insertProperties(
+      newGlobalPropertyDto().setKey("foo").setValue("one"),
+      newGlobalPropertyDto().setKey("secret.secured").setValue("password"),
+      newGlobalPropertyDto().setKey("commercial.plugin").setValue("ABCD"),
+      newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"),
+      newGlobalPropertyDto().setKey("plugin.licenseHash.secured").setValue("987654321"));
+
+    executeAndVerify(null, null, "return_license_with_hash_settings_when_authenticated_but_not_admin.json");
+  }
+
+  @Test
+  public void return_secured_and_license_settings_when_system_admin() throws Exception {
+    setUserAsSystemAdmin();
+    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("plugin.licenseHash.secured").setValue("987654321"));
+
+    executeAndVerify(null, null, "return_secured_and_license_settings_when_system_admin.json");
+  }
+
+  @Test
+  public void return_secured_and_license_settings_when_project_admin() throws Exception {
+    setUserAsProjectAdmin();
+    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.key(), null, "return_secured_and_license_settings_when_project_admin.json");
+  }
+
+  @Test
+  public void return_secured_and_license_settings_in_property_set_when_system_admin() throws Exception {
+    setUserAsSystemAdmin();
+    definitions.addComponent(PropertyDefinition
+      .builder("foo")
+      .type(PropertyType.PROPERTY_SET)
+      .fields(asList(
+        PropertyFieldDefinition.build("key").name("Key").build(),
+        PropertyFieldDefinition.build("plugin.license.secured").name("License").type(LICENSE).build(),
+        PropertyFieldDefinition.build("secret.secured").name("Secured").build()))
+      .build());
+    propertyDb.insertPropertySet("foo", null,
+      ImmutableMap.of("key", "key1", "plugin.license.secured", "ABCD", "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() throws Exception {
+    setUserAsSystemAdmin();
+    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() throws Exception {
+    setUserAsProjectAdmin();
+    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.key(), null, "return_all_project_settings_when_component_and_no_key.json");
+  }
+
+  @Test
+  public void return_only_one_setting_when_key_is_provided() throws Exception {
+    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.key(), "foo", "return_only_one_setting_when_key_is_provided.json");
+    executeAndVerify(project.key(), "unknown", "empty.json");
+  }
+
+  @Test
+  public void does_not_fail_when_user_has_not_project_browse_permission() throws Exception {
+    userSession.login("project-admin").addProjectUuidPermissions(CODEVIEWER, project.uuid());
+    definitions.addComponent(PropertyDefinition.builder("foo").build());
+    propertyDb.insertProperties(newComponentPropertyDto(project).setKey("foo").setValue("one"));
+
+    executeAndVerify(project.key(), null, "does_not_fail_when_user_has_not_project_browse_permission.json");
+  }
+
+  @Test
+  public void does_not_fail_when_format_is_set_to_json() throws Exception {
+    setAuthenticatedUser();
+    definitions.addComponent(PropertyDefinition.builder("foo").defaultValue("default").build());
+
+    ws.newRequest().setParam("format", "json").execute();
+  }
+
+  @Test
+  public void fail_when_format_is_set_to_xml() throws Exception {
+    setAuthenticatedUser();
+    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() {
+    setAuthenticatedUser();
+    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("key", key);
+    }
+    if (componentKey != null) {
+      request.setParam("resource", componentKey);
+    }
+    String result = request.execute().getInput();
+    assertJson(result).isSimilarTo(resource(expectedFile));
+  }
+
+  private void setAuthenticatedUser() {
+    userSession.login("user");
+  }
+
+  private void setUserWithBrowsePermissionOnProject() {
+    userSession.login("user").addProjectUuidPermissions(USER, project.uuid());
+  }
+
+  private void setUserAsSystemAdmin() {
+    userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
+  }
+
+  private void setUserAsProjectAdmin() {
+    userSession.login("project-admin")
+      .addProjectUuidPermissions(ADMIN, project.uuid())
+      .addProjectUuidPermissions(USER, project.uuid());
+  }
+
+  protected static URL resource(String s) {
+    Class<IndexActionTest> clazz = IndexActionTest.class;
+    return clazz.getResource(clazz.getSimpleName() + "/" + s);
+  }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/does_not_fail_when_user_has_not_project_browse_permission.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/does_not_fail_when_user_has_not_project_browse_permission.json
deleted file mode 100644 (file)
index d98b4c4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[
-  {
-    "key": "foo",
-    "value": "one"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/does_not_returned_secured_and_license_settings_in_property_set_when_not_authenticated.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/does_not_returned_secured_and_license_settings_in_property_set_when_not_authenticated.json
deleted file mode 100644 (file)
index 1475b5a..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-[
-  {
-    "key": "foo",
-    "value": "1",
-    "values": [
-      "1"
-    ]
-  },
-  {
-    "key": "foo.1.key",
-    "value": "key1"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/does_not_returned_secured_and_license_settings_when_not_authenticated.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/does_not_returned_secured_and_license_settings_when_not_authenticated.json
deleted file mode 100644 (file)
index d98b4c4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[
-  {
-    "key": "foo",
-    "value": "one"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/empty.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/empty.json
deleted file mode 100644 (file)
index 0d4f101..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_all_project_settings_when_component_and_no_key.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_all_project_settings_when_component_and_no_key.json
deleted file mode 100644 (file)
index 12d2fd7..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-[
-  {
-    "key": "secret.secured",
-    "value": "password"
-  },
-  {
-    "key": "foo",
-    "value": "one"
-  },
-  {
-    "key": "not_defined",
-    "value": "ABCD"
-  },
-  {
-    "key": "plugin.license.secured",
-    "value": "ABCD"
-  },
-  {
-    "key": "global_not_defined",
-    "value": "ABCD"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_all_settings_when_no_component_and_no_key.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_all_settings_when_no_component_and_no_key.json
deleted file mode 100644 (file)
index 96409e9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-[
-  {
-    "key": "secret.secured",
-    "value": "password"
-  },
-  {
-    "key": "foo",
-    "value": "one"
-  },
-  {
-    "key": "not_defined",
-    "value": "ABCD"
-  },
-  {
-    "key": "plugin.license.secured",
-    "value": "ABCD"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_default_values.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_default_values.json
deleted file mode 100644 (file)
index 4647a4e..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[
-  {
-    "key": "foo",
-    "value": "default"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_global_values.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_global_values.json
deleted file mode 100644 (file)
index 0869d17..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[
-  {
-    "key": "property",
-    "value": "one"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_inherited_values_on_global_setting.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_inherited_values_on_global_setting.json
deleted file mode 100644 (file)
index 815c459..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-[
-  {
-    "key": "defaultProperty",
-    "value": "default"
-  },
-  {
-    "key": "globalProperty",
-    "value": "global"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_inherited_values_on_module.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_inherited_values_on_module.json
deleted file mode 100644 (file)
index 15a3ae5..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-[
-  {
-    "key": "defaultProperty",
-    "value": "default"
-  },
-  {
-    "key": "projectProperty",
-    "value": "project"
-  },
-  {
-    "key": "globalProperty",
-    "value": "global"
-  },
-  {
-    "key": "moduleProperty",
-    "value": "module"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_license_with_hash_settings_when_authenticated_but_not_admin.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_license_with_hash_settings_when_authenticated_but_not_admin.json
deleted file mode 100644 (file)
index e40076c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-[
-  {
-    "key": "plugin.licenseHash.secured",
-    "value": "987654321"
-  },
-  {
-    "key": "foo",
-    "value": "one"
-  },
-  {
-    "key": "plugin.license.secured",
-    "value": "ABCD"
-  },
-  {
-    "key": "commercial.plugin",
-    "value": "ABCD"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_module_values.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_module_values.json
deleted file mode 100644 (file)
index 5486106..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[
-  {
-    "key": "property",
-    "value": "two"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_multi_value_with_coma.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_multi_value_with_coma.json
deleted file mode 100644 (file)
index 8411a36..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-[
-  {
-    "key": "global",
-    "value": "three,four%2Cfive",
-    "values": [
-      "three",
-      "four,five"
-    ]
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_multi_values.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_multi_values.json
deleted file mode 100644 (file)
index ce4fcb9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-[
-  {
-    "key": "default",
-    "value": "one,two",
-    "values": [
-      "one",
-      "two"
-    ]
-  },
-  {
-    "key": "global",
-    "value": "three,four",
-    "values": [
-      "three",
-      "four"
-    ]
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_only_one_setting_when_key_is_provided.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_only_one_setting_when_key_is_provided.json
deleted file mode 100644 (file)
index d98b4c4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[
-  {
-    "key": "foo",
-    "value": "one"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_project_values.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_project_values.json
deleted file mode 100644 (file)
index 5486106..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[
-  {
-    "key": "property",
-    "value": "two"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_property_set.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_property_set.json
deleted file mode 100644 (file)
index 327d187..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-[
-  {
-    "key": "foo",
-    "value": "1,2",
-    "values": [
-      "1",
-      "2"
-    ]
-  },
-  {
-    "key": "foo.1.key",
-    "value": "key1"
-  },
-  {
-    "key": "foo.2.key",
-    "value": "key2"
-  },
-  {
-    "key": "foo.1.size",
-    "value": "size1"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_secured_and_license_settings_in_property_set_when_system_admin.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_secured_and_license_settings_in_property_set_when_system_admin.json
deleted file mode 100644 (file)
index 3da8aab..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-[
-  {
-    "key": "foo",
-    "value": "1",
-    "values": [
-      "1"
-    ]
-  },
-  {
-    "key": "foo.1.key",
-    "value": "key1"
-  },
-  {
-    "key": "foo.1.plugin.license.secured",
-    "value": "ABCD"
-  },
-  {
-    "key": "foo.1.secret.secured",
-    "value": "123456"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_secured_and_license_settings_when_project_admin.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_secured_and_license_settings_when_project_admin.json
deleted file mode 100644 (file)
index 29261a0..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-[
-  {
-    "key": "secret.secured",
-    "value": "password"
-  },
-  {
-    "key": "plugin.licenseHash.secured",
-    "value": "987654321"
-  },
-  {
-    "key": "foo",
-    "value": "one"
-  },
-  {
-    "key": "plugin.license.secured",
-    "value": "ABCD"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_secured_and_license_settings_when_system_admin.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_secured_and_license_settings_when_system_admin.json
deleted file mode 100644 (file)
index 29261a0..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-[
-  {
-    "key": "secret.secured",
-    "value": "password"
-  },
-  {
-    "key": "plugin.licenseHash.secured",
-    "value": "987654321"
-  },
-  {
-    "key": "foo",
-    "value": "one"
-  },
-  {
-    "key": "plugin.license.secured",
-    "value": "ABCD"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_simple_value.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_simple_value.json
deleted file mode 100644 (file)
index d98b4c4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[
-  {
-    "key": "foo",
-    "value": "one"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_values_even_if_no_property_definition.json b/server/sonar-server/src/test/resources/org/sonar/server/config/ws/IndexActionTest/return_values_even_if_no_property_definition.json
deleted file mode 100644 (file)
index c3d4ba1..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[
-  {
-    "key": "globalPropertyWithoutDefinition",
-    "value": "value"
-  }
-]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/does_not_fail_when_user_has_not_project_browse_permission.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/does_not_fail_when_user_has_not_project_browse_permission.json
new file mode 100644 (file)
index 0000000..d98b4c4
--- /dev/null
@@ -0,0 +1,6 @@
+[
+  {
+    "key": "foo",
+    "value": "one"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/does_not_returned_secured_and_license_settings_in_property_set_when_not_authenticated.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/does_not_returned_secured_and_license_settings_in_property_set_when_not_authenticated.json
new file mode 100644 (file)
index 0000000..1475b5a
--- /dev/null
@@ -0,0 +1,13 @@
+[
+  {
+    "key": "foo",
+    "value": "1",
+    "values": [
+      "1"
+    ]
+  },
+  {
+    "key": "foo.1.key",
+    "value": "key1"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/does_not_returned_secured_and_license_settings_when_not_authenticated.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/does_not_returned_secured_and_license_settings_when_not_authenticated.json
new file mode 100644 (file)
index 0000000..d98b4c4
--- /dev/null
@@ -0,0 +1,6 @@
+[
+  {
+    "key": "foo",
+    "value": "one"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/empty.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/empty.json
new file mode 100644 (file)
index 0000000..0d4f101
--- /dev/null
@@ -0,0 +1,2 @@
+[
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_all_project_settings_when_component_and_no_key.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_all_project_settings_when_component_and_no_key.json
new file mode 100644 (file)
index 0000000..12d2fd7
--- /dev/null
@@ -0,0 +1,22 @@
+[
+  {
+    "key": "secret.secured",
+    "value": "password"
+  },
+  {
+    "key": "foo",
+    "value": "one"
+  },
+  {
+    "key": "not_defined",
+    "value": "ABCD"
+  },
+  {
+    "key": "plugin.license.secured",
+    "value": "ABCD"
+  },
+  {
+    "key": "global_not_defined",
+    "value": "ABCD"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_all_settings_when_no_component_and_no_key.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_all_settings_when_no_component_and_no_key.json
new file mode 100644 (file)
index 0000000..96409e9
--- /dev/null
@@ -0,0 +1,18 @@
+[
+  {
+    "key": "secret.secured",
+    "value": "password"
+  },
+  {
+    "key": "foo",
+    "value": "one"
+  },
+  {
+    "key": "not_defined",
+    "value": "ABCD"
+  },
+  {
+    "key": "plugin.license.secured",
+    "value": "ABCD"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_default_values.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_default_values.json
new file mode 100644 (file)
index 0000000..4647a4e
--- /dev/null
@@ -0,0 +1,6 @@
+[
+  {
+    "key": "foo",
+    "value": "default"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_global_values.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_global_values.json
new file mode 100644 (file)
index 0000000..0869d17
--- /dev/null
@@ -0,0 +1,6 @@
+[
+  {
+    "key": "property",
+    "value": "one"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_inherited_values_on_global_setting.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_inherited_values_on_global_setting.json
new file mode 100644 (file)
index 0000000..815c459
--- /dev/null
@@ -0,0 +1,10 @@
+[
+  {
+    "key": "defaultProperty",
+    "value": "default"
+  },
+  {
+    "key": "globalProperty",
+    "value": "global"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_inherited_values_on_module.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_inherited_values_on_module.json
new file mode 100644 (file)
index 0000000..15a3ae5
--- /dev/null
@@ -0,0 +1,18 @@
+[
+  {
+    "key": "defaultProperty",
+    "value": "default"
+  },
+  {
+    "key": "projectProperty",
+    "value": "project"
+  },
+  {
+    "key": "globalProperty",
+    "value": "global"
+  },
+  {
+    "key": "moduleProperty",
+    "value": "module"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_license_with_hash_settings_when_authenticated_but_not_admin.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_license_with_hash_settings_when_authenticated_but_not_admin.json
new file mode 100644 (file)
index 0000000..e40076c
--- /dev/null
@@ -0,0 +1,18 @@
+[
+  {
+    "key": "plugin.licenseHash.secured",
+    "value": "987654321"
+  },
+  {
+    "key": "foo",
+    "value": "one"
+  },
+  {
+    "key": "plugin.license.secured",
+    "value": "ABCD"
+  },
+  {
+    "key": "commercial.plugin",
+    "value": "ABCD"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_module_values.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_module_values.json
new file mode 100644 (file)
index 0000000..5486106
--- /dev/null
@@ -0,0 +1,6 @@
+[
+  {
+    "key": "property",
+    "value": "two"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_multi_value_with_coma.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_multi_value_with_coma.json
new file mode 100644 (file)
index 0000000..8411a36
--- /dev/null
@@ -0,0 +1,10 @@
+[
+  {
+    "key": "global",
+    "value": "three,four%2Cfive",
+    "values": [
+      "three",
+      "four,five"
+    ]
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_multi_values.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_multi_values.json
new file mode 100644 (file)
index 0000000..ce4fcb9
--- /dev/null
@@ -0,0 +1,18 @@
+[
+  {
+    "key": "default",
+    "value": "one,two",
+    "values": [
+      "one",
+      "two"
+    ]
+  },
+  {
+    "key": "global",
+    "value": "three,four",
+    "values": [
+      "three",
+      "four"
+    ]
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_only_one_setting_when_key_is_provided.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_only_one_setting_when_key_is_provided.json
new file mode 100644 (file)
index 0000000..d98b4c4
--- /dev/null
@@ -0,0 +1,6 @@
+[
+  {
+    "key": "foo",
+    "value": "one"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_project_values.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_project_values.json
new file mode 100644 (file)
index 0000000..5486106
--- /dev/null
@@ -0,0 +1,6 @@
+[
+  {
+    "key": "property",
+    "value": "two"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_property_set.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_property_set.json
new file mode 100644 (file)
index 0000000..327d187
--- /dev/null
@@ -0,0 +1,22 @@
+[
+  {
+    "key": "foo",
+    "value": "1,2",
+    "values": [
+      "1",
+      "2"
+    ]
+  },
+  {
+    "key": "foo.1.key",
+    "value": "key1"
+  },
+  {
+    "key": "foo.2.key",
+    "value": "key2"
+  },
+  {
+    "key": "foo.1.size",
+    "value": "size1"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_secured_and_license_settings_in_property_set_when_system_admin.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_secured_and_license_settings_in_property_set_when_system_admin.json
new file mode 100644 (file)
index 0000000..3da8aab
--- /dev/null
@@ -0,0 +1,21 @@
+[
+  {
+    "key": "foo",
+    "value": "1",
+    "values": [
+      "1"
+    ]
+  },
+  {
+    "key": "foo.1.key",
+    "value": "key1"
+  },
+  {
+    "key": "foo.1.plugin.license.secured",
+    "value": "ABCD"
+  },
+  {
+    "key": "foo.1.secret.secured",
+    "value": "123456"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_secured_and_license_settings_when_project_admin.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_secured_and_license_settings_when_project_admin.json
new file mode 100644 (file)
index 0000000..29261a0
--- /dev/null
@@ -0,0 +1,18 @@
+[
+  {
+    "key": "secret.secured",
+    "value": "password"
+  },
+  {
+    "key": "plugin.licenseHash.secured",
+    "value": "987654321"
+  },
+  {
+    "key": "foo",
+    "value": "one"
+  },
+  {
+    "key": "plugin.license.secured",
+    "value": "ABCD"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_secured_and_license_settings_when_system_admin.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_secured_and_license_settings_when_system_admin.json
new file mode 100644 (file)
index 0000000..29261a0
--- /dev/null
@@ -0,0 +1,18 @@
+[
+  {
+    "key": "secret.secured",
+    "value": "password"
+  },
+  {
+    "key": "plugin.licenseHash.secured",
+    "value": "987654321"
+  },
+  {
+    "key": "foo",
+    "value": "one"
+  },
+  {
+    "key": "plugin.license.secured",
+    "value": "ABCD"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_simple_value.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_simple_value.json
new file mode 100644 (file)
index 0000000..d98b4c4
--- /dev/null
@@ -0,0 +1,6 @@
+[
+  {
+    "key": "foo",
+    "value": "one"
+  }
+]
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_values_even_if_no_property_definition.json b/server/sonar-server/src/test/resources/org/sonar/server/property/ws/IndexActionTest/return_values_even_if_no_property_definition.json
new file mode 100644 (file)
index 0000000..c3d4ba1
--- /dev/null
@@ -0,0 +1,6 @@
+[
+  {
+    "key": "globalPropertyWithoutDefinition",
+    "value": "value"
+  }
+]