]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8954 return every license hashes in api/settings/values 1831/head
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 21 Mar 2017 16:54:21 +0000 (17:54 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 23 Mar 2017 11:13:27 +0000 (12:13 +0100)
server/sonar-server/src/main/java/org/sonar/server/setting/ws/ScannerSettings.java
server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java
server/sonar-server/src/test/java/org/sonar/server/setting/ws/ScannerSettingsTest.java
server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java
sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java
sonar-db/src/main/java/org/sonar/db/property/PropertiesMapper.java
sonar-db/src/main/resources/org/sonar/db/property/PropertiesMapper.xml
sonar-db/src/test/java/org/sonar/db/property/PropertiesDaoTest.java

index f0ffeb902d089f5ed38fdc067ffec970ed3d6889..6fadbf2ad9338f88edd3c2232bbee88ff6c728ee 100644 (file)
@@ -22,11 +22,11 @@ package org.sonar.server.setting.ws;
 import com.google.common.collect.ImmutableSet;
 import java.util.Set;
 import java.util.stream.Stream;
-import org.sonar.api.Startable;
 import org.sonar.api.config.PropertyDefinition;
 import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.core.platform.PluginInfo;
-import org.sonar.core.platform.PluginRepository;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.property.PropertyDto;
 
 import static java.util.stream.Collectors.toSet;
 import static java.util.stream.Stream.concat;
@@ -39,31 +39,25 @@ import static org.sonar.server.setting.ws.SettingsWsSupport.LICENSE_HASH_SUFFIX;
 /**
  * This class returns the list of settings required on scanner side (licenses, license hashes, server ids, etc.)
  */
-public class ScannerSettings implements Startable {
+public class ScannerSettings {
 
-  private static final String SONAR_PREFIX = "sonar.";
   private static final Set<String> SERVER_SETTING_KEYS = ImmutableSet.of(PERMANENT_SERVER_ID, SERVER_STARTTIME, SERVER_ID);
 
+  private final DbClient dbClient;
   private final PropertyDefinitions propertyDefinitions;
-  private final PluginRepository pluginRepository;
 
-  private Set<String> scannerSettingKeys;
-
-  public ScannerSettings(PropertyDefinitions propertyDefinitions, PluginRepository pluginRepository) {
+  public ScannerSettings(DbClient dbClient, PropertyDefinitions propertyDefinitions) {
+    this.dbClient = dbClient;
     this.propertyDefinitions = propertyDefinitions;
-    this.pluginRepository = pluginRepository;
   }
 
-  @Override
-  public void start() {
-    this.scannerSettingKeys = concat(concat(loadLicenseKeys(), loadLicenseHashKeys()),
+  Set<String> getScannerSettingKeys(DbSession dbSession) {
+    return concat(concat(loadLicenseKeys(), loadLicenseHashKeys(dbSession)),
       SERVER_SETTING_KEYS.stream()).collect(toSet());
   }
 
-  private Stream<String> loadLicenseHashKeys() {
-    return pluginRepository.getPluginInfos().stream()
-      .map(PluginInfo::getKey)
-      .map(key -> SONAR_PREFIX + key + LICENSE_HASH_SUFFIX);
+  private Stream<String> loadLicenseHashKeys(DbSession dbSession) {
+    return dbClient.propertiesDao().selectGlobalPropertiesByKeyQuery(dbSession, LICENSE_HASH_SUFFIX).stream().map(PropertyDto::getKey);
   }
 
   private Stream<String> loadLicenseKeys() {
@@ -73,12 +67,4 @@ public class ScannerSettings implements Startable {
       .map(PropertyDefinition::key);
   }
 
-  Set<String> getScannerSettingKeys() {
-    return scannerSettingKeys;
-  }
-
-  @Override
-  public void stop() {
-    // nothing to do
-  }
 }
index bbf39457feaae51653d1f57d3d5e24741850aea2..836e944cb1bf2f988888ba0949d33b45da9a5543 100644 (file)
@@ -69,7 +69,7 @@ public class ValuesAction implements SettingsWsAction {
   private final ScannerSettings scannerSettings;
 
   public ValuesAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, PropertyDefinitions propertyDefinitions, SettingsFinder settingsFinder,
-                      SettingsWsSupport settingsWsSupport, ScannerSettings scannerSettings) {
+    SettingsWsSupport settingsWsSupport, ScannerSettings scannerSettings) {
     this.dbClient = dbClient;
     this.componentFinder = componentFinder;
     this.userSession = userSession;
@@ -113,7 +113,7 @@ public class ValuesAction implements SettingsWsAction {
       ValuesRequest valuesRequest = toWsRequest(request);
       Optional<ComponentDto> component = loadComponent(dbSession, valuesRequest);
 
-      Set<String> keys = loadKeys(valuesRequest);
+      Set<String> keys = loadKeys(dbSession, valuesRequest);
       Map<String, String> keysToDisplayMap = getKeysToDisplayMap(keys);
       List<Setting> settings = loadSettings(dbSession, component, keysToDisplayMap.keySet());
       return new ValuesResponseBuilder(settings, component, keysToDisplayMap).build();
@@ -129,12 +129,12 @@ public class ValuesAction implements SettingsWsAction {
     return builder.build();
   }
 
-  private Set<String> loadKeys(ValuesRequest valuesRequest) {
+  private Set<String> loadKeys(DbSession dbSession, ValuesRequest valuesRequest) {
     List<String> keys = valuesRequest.getKeys();
-    if (!keys.isEmpty()) {
-      return new HashSet<>(keys);
+    if (keys.isEmpty()) {
+      return concat(propertyDefinitions.getAll().stream().map(PropertyDefinition::key), scannerSettings.getScannerSettingKeys(dbSession).stream()).collect(Collectors.toSet());
     }
-    return concat(propertyDefinitions.getAll().stream().map(PropertyDefinition::key), scannerSettings.getScannerSettingKeys().stream()).collect(Collectors.toSet());
+    return new HashSet<>(keys);
   }
 
   private Optional<ComponentDto> loadComponent(DbSession dbSession, ValuesRequest valuesRequest) {
index 8b8dcfd99576b8e69d359dc51ceaf40f8d1dfe98..034d81e613c958d3cc19921b8e3d190fd0c11011 100644 (file)
  */
 package org.sonar.server.setting.ws;
 
+import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.PropertyDefinition;
 import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.core.platform.PluginInfo;
-import org.sonar.core.platform.PluginRepository;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
 
 import static java.util.Arrays.asList;
-import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 import static org.sonar.api.PropertyType.LICENSE;
+import static org.sonar.db.property.PropertyTesting.newGlobalPropertyDto;
 
 public class ScannerSettingsTest {
 
+  @Rule
+  public DbTester db = DbTester.create(System2.INSTANCE);
+
   private PropertyDefinitions definitions = new PropertyDefinitions();
-  private PluginRepository repository = mock(PluginRepository.class);
 
-  private ScannerSettings underTest = new ScannerSettings(definitions, repository);
+  private ScannerSettings underTest = new ScannerSettings(db.getDbClient(), definitions);
 
   @Test
   public void return_license_keys() throws Exception {
     definitions.addComponents(asList(
       PropertyDefinition.builder("foo").build(),
       PropertyDefinition.builder("myplugin.license.secured").type(LICENSE).build()));
-    underTest.start();
 
-    assertThat(underTest.getScannerSettingKeys()).contains("myplugin.license.secured");
+    assertThat(underTest.getScannerSettingKeys(db.getSession())).contains("myplugin.license.secured");
   }
 
   @Test
   public void return_license_hash_keys() throws Exception {
-    PluginInfo pluginInfo = mock(PluginInfo.class);
-    when(pluginInfo.getKey()).thenReturn("myplugin");
-    when(repository.getPluginInfos()).thenReturn(singletonList(pluginInfo));
-    underTest.start();
+    db.properties().insertProperty(newGlobalPropertyDto("sonar.myplugin.licenseHash.secured", "hash"));
 
-    assertThat(underTest.getScannerSettingKeys()).contains("sonar.myplugin.licenseHash.secured");
+    assertThat(underTest.getScannerSettingKeys(db.getSession())).contains("sonar.myplugin.licenseHash.secured");
   }
 
   @Test
@@ -64,8 +61,7 @@ public class ScannerSettingsTest {
     definitions.addComponents(asList(
       PropertyDefinition.builder("foo").build(),
       PropertyDefinition.builder("myplugin.license.secured").type(LICENSE).build()));
-    underTest.start();
 
-    assertThat(underTest.getScannerSettingKeys()).contains("sonar.server_id", "sonar.core.id", "sonar.core.startTime");
+    assertThat(underTest.getScannerSettingKeys(db.getSession())).contains("sonar.server_id", "sonar.core.id", "sonar.core.startTime");
   }
 }
index 02c71e58833333beda7b63da51048a4f48c40d31..cffd4f4c897008ecca7d5041ac075be812737086 100644 (file)
@@ -34,8 +34,6 @@ 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.core.platform.PluginInfo;
-import org.sonar.core.platform.PluginRepository;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDbTester;
@@ -55,11 +53,8 @@ import org.sonarqube.ws.Settings;
 import org.sonarqube.ws.Settings.ValuesWsResponse;
 
 import static java.util.Arrays.asList;
-import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Java6Assertions.assertThat;
 import static org.assertj.core.groups.Tuple.tuple;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 import static org.sonar.api.PropertyType.LICENSE;
 import static org.sonar.api.resources.Qualifiers.MODULE;
 import static org.sonar.api.resources.Qualifiers.PROJECT;
@@ -93,8 +88,7 @@ public class ValuesActionTest {
   private ComponentDbTester componentDb = new ComponentDbTester(db);
   private PropertyDefinitions definitions = new PropertyDefinitions();
   private SettingsFinder settingsFinder = new SettingsFinder(dbClient, definitions);
-  private PluginRepository repository = mock(PluginRepository.class);
-  private ScannerSettings scannerSettings = new ScannerSettings(definitions, repository);
+  private ScannerSettings scannerSettings = new ScannerSettings(db.getDbClient(), definitions);
   private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
   private SettingsWsSupport support = new SettingsWsSupport(defaultOrganizationProvider, userSession);
   private ComponentDto project;
@@ -104,10 +98,6 @@ public class ValuesActionTest {
 
   @Before
   public void setUp() throws Exception {
-    PluginInfo pluginInfo = mock(PluginInfo.class);
-    when(pluginInfo.getKey()).thenReturn("plugin");
-    when(repository.getPluginInfos()).thenReturn(singletonList(pluginInfo));
-    scannerSettings.start();
     OrganizationDto organizationDto = db.organizations().insert();
     project = componentDb.insertComponent(newProjectDto(organizationDto));
   }
index 0f6bfe392af38765ec1c97191f7dc5b721fa3b48..80aaa2219a8ef50b783fd0bd1024b681c8c4e0fe 100644 (file)
@@ -36,8 +36,10 @@ import org.sonar.db.Dao;
 import org.sonar.db.DatabaseUtils;
 import org.sonar.db.DbSession;
 import org.sonar.db.MyBatis;
+import org.sonar.db.WildcardPosition;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static org.sonar.db.DatabaseUtils.buildLikeValue;
 import static org.sonar.db.DatabaseUtils.executeLargeInputs;
 
 public class PropertiesDao implements Dao {
@@ -170,6 +172,10 @@ public class PropertiesDao implements Dao {
     return executeLargeInputs(keys, partitionKeys -> getMapper(session).selectByKeys(partitionKeys, componentId));
   }
 
+  public List<PropertyDto> selectGlobalPropertiesByKeyQuery(DbSession session, String keyQuery) {
+    return getMapper(session).selectGlobalPropertiesByKeyQuery(buildLikeValue(keyQuery, WildcardPosition.BEFORE_AND_AFTER));
+  }
+
   /**
    * Saves the specified property and its value.
    * <p>
index e7a5b25d5b03e2ffbc9876682076dd0eeb6c25bb..5cd2d6cf5cec66a95a3591d338e6a77f0e1dd083 100644 (file)
@@ -46,6 +46,8 @@ public interface PropertiesMapper {
   List<PropertyDto> selectDescendantModuleProperties(@Param("moduleUuid") String moduleUuid, @Param(value = "scope") String scope,
     @Param(value = "excludeDisabled") boolean excludeDisabled);
 
+  List<PropertyDto> selectGlobalPropertiesByKeyQuery(@Param("textQuery") String textQuery);
+
   void insertAsEmpty(@Param("key") String key, @Nullable @Param("userId") Long userId, @Nullable @Param("componentId") Long componentId,
     @Param("now") long now);
 
index 8feebbb8c7c39d2156c4e30ba687b90acc4685d1..64c4b41201e45888e3523913d129ba5334a30ef8 100644 (file)
     </where>
   </select>
 
+  <select id="selectGlobalPropertiesByKeyQuery" resultType="ScrapProperty">
+    select
+    <include refid="columnsToScrapPropertyDto"/>
+    from
+    properties p
+    where
+    p.resource_id is null
+    and p.user_id is null
+    and p.prop_key like #{textQuery,jdbcType=VARCHAR}
+  </select>
+
   <insert id="insertAsEmpty" parameterType="Map" useGeneratedKeys="false">
     insert into properties
     (
index 570c7d9636411239aed1d089bbd0df389123a540..f568dd8a63a981c0e8bc9309219daea72956b969 100644 (file)
@@ -444,8 +444,7 @@ public class PropertiesDaoTest {
       .extracting("key", "resourceId").containsOnly(
         tuple(key, project.getId()),
         tuple(key, project2.getId()),
-        tuple(anotherKey, project2.getId())
-      );
+        tuple(anotherKey, project2.getId()));
 
     assertThat(underTest.selectPropertiesByComponentIds(session, newHashSet(123456789L))).isEmpty();
   }
@@ -484,6 +483,24 @@ public class PropertiesDaoTest {
     assertThat(underTest.selectPropertiesByKeysAndComponentIds(session, newHashSet("unknown"), newHashSet(123456789L))).isEmpty();
   }
 
+  @Test
+  public void select_global_properties_by_key_query() throws SQLException {
+    // global
+    insertProperty("sonar.plugin1.licenseHash.secured", "one", null, null);
+    insertProperty("sonar.plugin2.licenseHash.secured", "two", null, null);
+    // on component and user
+    insertProperty("sonar.plugin1.licenseHash.secure", "one", 10L, null);
+    insertProperty("sonar.plugin1.licenseHash.secure", "two", 10L, 100L);
+
+    assertThat(underTest.selectGlobalPropertiesByKeyQuery(dbTester.getSession(), ".licenseHash.secured")).extracting(PropertyDto::getKey, PropertyDto::getValue)
+      .containsOnly(tuple("sonar.plugin1.licenseHash.secured", "one"), tuple("sonar.plugin2.licenseHash.secured", "two"));
+    assertThat(underTest.selectGlobalPropertiesByKeyQuery(dbTester.getSession(), "plugin1.licenseHash.secured")).extracting(PropertyDto::getKey, PropertyDto::getValue)
+      .containsOnly(tuple("sonar.plugin1.licenseHash.secured", "one"));
+    assertThat(underTest.selectGlobalPropertiesByKeyQuery(dbTester.getSession(), "plugin1")).extracting(PropertyDto::getKey, PropertyDto::getValue)
+      .containsOnly(tuple("sonar.plugin1.licenseHash.secured", "one"));
+    assertThat(underTest.selectGlobalPropertiesByKeyQuery(dbTester.getSession(), "unknown")).isEmpty();
+  }
+
   @Test
   public void saveProperty_inserts_global_properties_when_they_do_not_exist_in_db() {
     when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5);