]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-18856 Refactor properties and related web services
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Mon, 22 May 2023 20:21:06 +0000 (15:21 -0500)
committersonartech <sonartech@sonarsource.com>
Thu, 1 Jun 2023 20:02:59 +0000 (20:02 +0000)
35 files changed:
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/ProjectConfigurationFactory.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ConfigurationRepositoryImpl.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/analysis/ProjectConfigurationFactoryTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ConfigurationRepositoryTest.java
server/sonar-db-dao/src/it/java/org/sonar/db/component/ComponentDaoIT.java
server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectDaoIT.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentMapper.java
server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml
server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/property/PropertyTesting.java
server/sonar-server-common/src/it/java/org/sonar/server/component/index/ComponentIndexerIT.java
server/sonar-server-common/src/main/java/org/sonar/server/component/index/ComponentDoc.java
server/sonar-server-common/src/main/java/org/sonar/server/component/index/ComponentIndexDefinition.java
server/sonar-server-common/src/main/java/org/sonar/server/component/index/ComponentIndexer.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/favorite/ws/AddActionIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/favorite/ws/RemoveActionIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ListDefinitionsActionIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ResetActionIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/SetActionIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ValuesActionIT.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SuggestionsAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/favorite/FavoriteFinder.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/favorite/ws/AddAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/favorite/ws/RemoveAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ListDefinitionsAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ResetAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SetAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SettingValidations.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SettingsWsSupport.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ValuesAction.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/setting/ws/SettingsWsSupportTest.java
sonar-ws/src/main/protobuf/ws-components.proto

index cfe3b7fc4adadadfd47cb3089fe59c76dd62b634..fc8ea8930499febe3cb448213ccc509cdf1344aa 100644 (file)
@@ -38,13 +38,9 @@ public class ProjectConfigurationFactory {
     this.dbClient = dbClient;
   }
 
-  public Configuration newProjectConfiguration(String projectUuid, String branchUuid) {
+  public Configuration newProjectConfiguration(String projectUuid) {
     Settings projectSettings = new ChildSettings(globalSettings);
     addSettings(projectSettings, projectUuid);
-    if (!projectUuid.equals(branchUuid)) {
-      // TODO not supported?
-      addSettings(projectSettings, branchUuid);
-    }
     return new ConfigurationBridge(projectSettings);
   }
 
index 8257bb7950d757b73b2132b62a3b6de194f5232e..3181bf6f1ebe184275245f256c6bc7cc1a525f42 100644 (file)
@@ -32,11 +32,10 @@ public class ConfigurationRepositoryImpl implements ConfigurationRepository {
 
   private final Supplier<Configuration> configuration;
 
-  public ConfigurationRepositoryImpl(TreeRootHolder treeRootHolder, AnalysisMetadataHolder analysisMetadataHolder, ProjectConfigurationFactory f) {
+  public ConfigurationRepositoryImpl(AnalysisMetadataHolder analysisMetadataHolder, ProjectConfigurationFactory f) {
     this.configuration = Suppliers.memoize(() -> {
-      String branchUuid = treeRootHolder.getRoot().getUuid();
       String projectUuid = analysisMetadataHolder.getProject().getUuid();
-      return f.newProjectConfiguration(projectUuid, branchUuid);
+      return f.newProjectConfiguration(projectUuid);
     });
   }
 
index c56459bc94f64940e88584eb5bbbea32bbf37ef2..c70c6545bcb8da2a47e2d8af509b8a88b71fe7f4 100644 (file)
@@ -24,7 +24,6 @@ import org.junit.Test;
 import org.sonar.api.config.Configuration;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
 import org.sonar.db.project.ProjectDto;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -34,13 +33,13 @@ public class ProjectConfigurationFactoryTest {
   @Rule
   public DbTester db = DbTester.create();
 
-  private MapSettings settings = new MapSettings();
-  private ProjectConfigurationFactory underTest = new ProjectConfigurationFactory(settings, db.getDbClient());
+  private final MapSettings settings = new MapSettings();
+  private final ProjectConfigurationFactory underTest = new ProjectConfigurationFactory(settings, db.getDbClient());
 
   @Test
   public void return_global_settings() {
     settings.setProperty("key", "value");
-    Configuration config = underTest.newProjectConfiguration("unknown", "unknown");
+    Configuration config = underTest.newProjectConfiguration("unknown");
 
     assertThat(config.get("key")).hasValue("value");
   }
@@ -53,7 +52,7 @@ public class ProjectConfigurationFactoryTest {
       newComponentPropertyDto(project).setKey("2").setValue("val2"),
       newComponentPropertyDto(project).setKey("3").setValue("val3"));
 
-    Configuration config = underTest.newProjectConfiguration(project.getUuid(), project.getUuid());
+    Configuration config = underTest.newProjectConfiguration(project.getUuid());
 
     assertThat(config.get("1")).hasValue("val1");
     assertThat(config.get("2")).hasValue("val2");
@@ -67,7 +66,7 @@ public class ProjectConfigurationFactoryTest {
     db.properties().insertProperties(null, project.getKey(), project.getName(), project.getQualifier(),
       newComponentPropertyDto(project).setKey("key").setValue("value2"));
 
-    Configuration projectConfig = underTest.newProjectConfiguration(project.getUuid(), project.getUuid());
+    Configuration projectConfig = underTest.newProjectConfiguration(project.getUuid());
 
     assertThat(projectConfig.get("key")).hasValue("value2");
   }
index a8230f38e62b8444a7b6ca54f48a35d3668ea3ba..a13d8e656ac3f2ad5ed663288c486504cb12c61d 100644 (file)
@@ -26,15 +26,12 @@ import org.sonar.api.config.Configuration;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
-import org.sonar.ce.task.projectanalysis.analysis.Branch;
 import org.sonar.ce.task.projectanalysis.analysis.ProjectConfigurationFactory;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
 import org.sonar.db.property.PropertyDto;
 import org.sonar.server.project.Project;
 
-import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -44,8 +41,6 @@ public class ConfigurationRepositoryTest {
   @Rule
   public final DbTester db = DbTester.create(System2.INSTANCE);
   @Rule
-  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
-  @Rule
   public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
 
   private final DbClient dbClient = db.getDbClient();
@@ -54,13 +49,11 @@ public class ConfigurationRepositoryTest {
   private final Component root = mock(Component.class);
   private ConfigurationRepository underTest;
 
-
   @Before
   public void setUp() {
     analysisMetadataHolder.setProject(project);
     when(root.getUuid()).thenReturn(project.getUuid());
-    treeRootHolder.setRoot(root);
-    underTest = new ConfigurationRepositoryImpl(treeRootHolder, analysisMetadataHolder, new ProjectConfigurationFactory(globalSettings, dbClient));
+    underTest = new ConfigurationRepositoryImpl(analysisMetadataHolder, new ProjectConfigurationFactory(globalSettings, dbClient));
   }
 
   @Test
index a51ca2af3b19ea43ce081029a1431f5cf53e02a0..beb63a96a1964b154f6f5fd7d64511163ef95431 100644 (file)
@@ -22,7 +22,6 @@ package org.sonar.db.component;
 import com.tngtech.java.junit.dataprovider.DataProvider;
 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
 import com.tngtech.java.junit.dataprovider.UseDataProvider;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
@@ -36,8 +35,6 @@ import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
-import javax.annotation.Nullable;
-import org.assertj.core.api.ListAssert;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -322,7 +319,7 @@ public class ComponentDaoIT {
 
     assertThat(results)
       .extracting(ComponentDto::uuid, ComponentDto::getKey)
-        .isEmpty();
+      .isEmpty();
   }
 
   @Test
@@ -1066,50 +1063,6 @@ public class ComponentDaoIT {
         removedFile.uuid());
   }
 
-  @Test
-  public void selectForIndexing_all() {
-    assertSelectForIndexing(null)
-      .doesNotContain("DIS7")
-      .doesNotContain("COPY8") // copied projects
-      .doesNotContain("U2", "U6")// modules
-      .doesNotContain("U3")// dir
-      .doesNotContain("U4")// file
-      .containsExactlyInAnyOrder("U1", "U5", "VW1");
-  }
-
-  @Test
-  public void selectForIndexing_project() {
-    assertSelectForIndexing("U1")
-      .doesNotContain("DIS7")
-      .doesNotContain("COPY8") // copied projects
-      .doesNotContain("U6") // other projects
-      .doesNotContain("VW1") // view
-      .doesNotContain("U2", "U6")// modules
-      .doesNotContain("U3")// dir
-      .doesNotContain("U4")// file
-      .containsExactlyInAnyOrder("U1");
-  }
-
-  private ListAssert<String> assertSelectForIndexing(@Nullable String projectUuid) {
-    ComponentDto project = db.components().insertPrivateProject("U1").getMainBranchComponent();
-    ComponentDto removedProject = db.components().insertPrivateProject(p -> p.setEnabled(false)).getMainBranchComponent();
-    ComponentDto directory = db.components().insertComponent(newDirectory(project, "U3", "src"));
-    ComponentDto removedDirectory = db.components().insertComponent(newDirectory(project, "src2").setEnabled(false));
-    ComponentDto file = db.components().insertComponent(newFileDto(project, directory, "U4"));
-    ComponentDto removedFile = db.components().insertComponent(newFileDto(project, directory).setEnabled(false));
-
-    ComponentDto view = db.components().insertPublicPortfolio("VW1", p -> {
-    });
-    db.components().insertComponent(newProjectCopy("COPY8", project, view));
-
-    ComponentDto project2 = db.components().insertPrivateProject("U5").getMainBranchComponent();
-
-    List<ComponentDto> components = new ArrayList<>();
-    underTest.scrollForIndexing(dbSession, projectUuid,
-      context -> components.add(context.getResultObject()));
-    return (ListAssert<String>) assertThat(components).extracting(ComponentDto::uuid);
-  }
-
   @Test
   public void update() {
     db.components().insertPrivateProject("U1").getMainBranchComponent();
index 78dd3c197bd7d008c3b815b812eb7c7998cd5121..219c9f4c13e90386bf541d6988ed89e59122d3e7 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
@@ -31,6 +32,7 @@ import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import javax.annotation.Nullable;
+import org.apache.ibatis.session.ResultHandler;
 import org.assertj.core.api.Assertions;
 import org.assertj.core.groups.Tuple;
 import org.junit.Rule;
@@ -406,6 +408,47 @@ public class ProjectDaoIT {
     assertThat(projectDao.selectEntityByKey(db.getSession(), "unknown")).isEmpty();
   }
 
+  @Test
+  public void scrollEntitiesForIndexing_shouldReturnAllEntities() {
+    ProjectData application = db.components().insertPrivateApplication();
+    ProjectData project = db.components().insertPrivateProject();
+    PortfolioDto portfolio = db.components().insertPrivatePortfolioDto();
+
+    List<EntityDto> result = new LinkedList<>();
+    ResultHandler<EntityDto> handler = resultContext -> result.add(resultContext.getResultObject());
+    projectDao.scrollEntitiesForIndexing(db.getSession(), null, handler);
+
+    assertThat(result).extracting(EntityDto::getUuid)
+      .containsOnly(project.projectUuid(), application.projectUuid(), portfolio.getUuid());
+  }
+
+  @Test
+  public void scrollEntitiesForIndexing_whenEntityUuidSpecified_shouldReturnSpecificEntity() {
+    ProjectData application = db.components().insertPrivateApplication();
+    ProjectData project = db.components().insertPrivateProject();
+    PortfolioDto portfolio = db.components().insertPrivatePortfolioDto();
+
+    List<EntityDto> result = new LinkedList<>();
+    ResultHandler<EntityDto> handler = resultContext -> result.add(resultContext.getResultObject());
+    projectDao.scrollEntitiesForIndexing(db.getSession(), project.projectUuid(), handler);
+
+    assertThat(result).extracting(EntityDto::getUuid)
+      .containsOnly(project.projectUuid());
+  }
+
+  @Test
+  public void scrollEntitiesForIndexing_whenNonExistingUuidSpecified_shouldReturnEmpty() {
+    ProjectData application = db.components().insertPrivateApplication();
+    ProjectData project = db.components().insertPrivateProject();
+    PortfolioDto portfolio = db.components().insertPrivatePortfolioDto();
+
+    List<EntityDto> result = new LinkedList<>();
+    ResultHandler<EntityDto> handler = resultContext -> result.add(resultContext.getResultObject());
+    projectDao.scrollEntitiesForIndexing(db.getSession(), "unknown", handler);
+
+    assertThat(result).isEmpty();
+  }
+
   private void insertDefaultQualityProfile(String language) {
     QProfileDto profile = db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(true).setLanguage(language));
     db.qualityProfiles().setAsDefault(profile);
index 94c9547be06517d05fcbcb80e5e2ef1953a7c8bb..22ca24a9df23113952733b5d34f455fe48675ebb 100644 (file)
@@ -239,17 +239,6 @@ public class ComponentDao implements Dao {
     return mapper(session).selectProjectsFromView("%." + escapedViewUuid + ".%", rootViewUuid);
   }
 
-  /**
-   * Selects all components that are relevant for indexing. The result is not returned (since it is usually too big), but handed over to the <code>handler</code>
-   *
-   * @param session     the database session
-   * @param branchUuid the branch uuid, which is selected with all of its children
-   * @param handler     the action to be applied to every result
-   */
-  public void scrollForIndexing(DbSession session, @Nullable String branchUuid, ResultHandler<ComponentDto> handler) {
-    mapper(session).scrollForIndexing(branchUuid, handler);
-  }
-
   /**
    * Retrieve enabled components keys with given qualifiers
    * <p>
index bf0a8312e8a3a6df442f6a1b55ba2fa086a5c763..1e954409aa01afd671895469a622969a60106762 100644 (file)
@@ -92,8 +92,6 @@ public interface ComponentMapper {
    */
   List<String> selectProjectsFromView(@Param("viewUuidLikeQuery") String viewUuidLikeQuery, @Param("rootViewUuid") String rootViewUuid);
 
-  void scrollForIndexing(@Param("branchUuid") @Nullable String branchUuid, ResultHandler<ComponentDto> handler);
-
   void scrollAllFilesForFileMove(@Param("branchUuid") String branchUuid, ResultHandler<FileMoveRowDto> handler);
 
   void insert(ComponentDto componentDto);
index 27ab59c83d3543e2b2377af675c289beb8fbfc16..1d354a8487a7583935b7cc19bf59c27302b0fa6e 100644 (file)
 package org.sonar.db.project;
 
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import javax.annotation.Nullable;
+import org.apache.ibatis.session.ResultHandler;
 import org.sonar.api.utils.System2;
 import org.sonar.db.Dao;
 import org.sonar.db.DbSession;
@@ -155,7 +155,8 @@ public class ProjectDao implements Dao {
     if (uuids.isEmpty()) {
       return emptyList();
     }
-    return mapper(dbSession).selectEntitiesByUuids(uuids);
+
+    return executeLargeInputs(uuids, partition -> mapper(dbSession).selectEntitiesByUuids(partition));
   }
 
   public Optional<EntityDto> selectEntityByKey(DbSession dbSession, String key) {
@@ -166,8 +167,10 @@ public class ProjectDao implements Dao {
     if (keys.isEmpty()) {
       return emptyList();
     }
-    return mapper(dbSession).selectEntitiesByKeys(keys);
+    return executeLargeInputs(keys, partition -> mapper(dbSession).selectEntitiesByKeys(partition));
   }
 
-
+  public void scrollEntitiesForIndexing(DbSession session, @Nullable String entityUuid, ResultHandler<EntityDto> handler) {
+    mapper(session).scrollEntitiesForIndexing(entityUuid, handler);
+  }
 }
index 21f3953c2c7b8e76e2617ad909d12a3656ae055d..6ffcf9207335247911c93316c392e8d040c91c3a 100644 (file)
@@ -25,6 +25,7 @@ import java.util.Set;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.session.ResultHandler;
 import org.sonar.db.entity.EntityDto;
 
 public interface ProjectMapper {
@@ -82,4 +83,6 @@ public interface ProjectMapper {
   EntityDto selectEntityByKey(String key);
 
   List<EntityDto> selectEntitiesByKeys(@Param("keys") Collection<String> keys);
+
+  void scrollEntitiesForIndexing(@Param("entityUuid") @Nullable String entityUuid, ResultHandler<EntityDto> handler);
 }
index 136b85e5ba507cf836b1787f4e5a9b3cba7ec965..7f897a7090f2766acd6450f58ac594219010a3e4 100644 (file)
     </choose>
   </select>
 
-  <select id="scrollForIndexing" parameterType="map" resultType="Component" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
-    select
-      <include refid="componentColumns"/>
-    from components p
-    LEFT JOIN project_branches pb ON pb.uuid = p.branch_uuid
-    where
-      p.enabled=${_true}
-      and p.copy_component_uuid is null
-      and <include refid="mainBranchOrPortfolio"/>
-      and p.scope = 'PRJ'
-      and p.qualifier in ('TRK','VW','SVW','APP')
-      <if test="branchUuid != null">
-        and p.branch_uuid = #{branchUuid,jdbcType=VARCHAR}
-      </if>
-  </select>
-
   <select id="scrollAllFilesForFileMove" parameterType="map" resultType="org.sonar.db.component.FileMoveRowDto" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
     select
       p.uuid as uuid,
index 1ed2db7d48a41a6aa1ba334a492974ca604daf3d..11332464dcd96b8c4a8b1684dbaeed93a61daa96 100644 (file)
     where p.kee in
       <foreach collection="keys" open="(" close=")" item="kee" separator=",">
         #{kee,jdbcType=VARCHAR}
-      </foreach>)  </select>
+      </foreach>)
+  </select>
+
+  <select id="scrollEntitiesForIndexing" parameterType="map" resultType="Entity" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
+    (select <include refid="entityProjectColumns"/>
+    from projects p
+    <if test="entityUuid != null">
+      where p.uuid = #{entityUuid,jdbcType=VARCHAR}
+    </if>)
+    UNION
+    (select <include refid="entityPortfolioColumns"/>
+    from portfolios p
+    <if test="entityUuid != null">
+      where p.uuid = #{entityUuid,jdbcType=VARCHAR}
+    </if>)
+  </select>
 
 </mapper>
index 6542ac1fbeef6bf0e0b69c2dfaa401839d717d30..70c13995cac658d05ba2368c051a210900174f9f 100644 (file)
@@ -63,18 +63,6 @@ public class PropertyTesting {
     return newPropertyDto(null, user.getUuid());
   }
 
-  public static PropertyDto newPropertyDto(String key, String value, ComponentDto component, UserDto user) {
-    checkNotNull(component.uuid());
-    checkNotNull(user.getUuid());
-    return newPropertyDto(key, value, component.uuid(), user.getUuid());
-  }
-
-  public static PropertyDto newPropertyDto(ComponentDto component, UserDto user) {
-    checkNotNull(component.uuid());
-    checkNotNull(user.getUuid());
-    return newPropertyDto(component.uuid(), user.getUuid());
-  }
-
   private static PropertyDto newPropertyDto(@Nullable String componentUuid, @Nullable String userUuid) {
     String key = String.valueOf(cursor);
     cursor++;
index c8889b328e7d229882651d71039473cfabb8dec8..4835bc85c94aea204b1d757226d6abd3919ed244 100644 (file)
@@ -103,7 +103,6 @@ public class ComponentIndexerIT {
     ComponentDoc doc = es.getDocuments(TYPE_COMPONENT, ComponentDoc.class).get(0);
     assertThat(doc.getId()).isEqualTo(project.uuid());
     assertThat(doc.getKey()).isEqualTo(project.getKey());
-    assertThat(doc.getProjectUuid()).isEqualTo(project.branchUuid());
     assertThat(doc.getName()).isEqualTo(project.name());
   }
 
index 4e8a657bcb747418a88476b062c68ffbabf28576..d2fff419631a277289ab88126ada6df1f938aec0 100644 (file)
 package org.sonar.server.component.index;
 
 import java.util.HashMap;
-import java.util.Map;
 import org.sonar.server.es.BaseDoc;
-import org.sonar.server.permission.index.AuthorizationDoc;
 
 import static org.sonar.server.component.index.ComponentIndexDefinition.FIELD_KEY;
 import static org.sonar.server.component.index.ComponentIndexDefinition.FIELD_NAME;
-import static org.sonar.server.component.index.ComponentIndexDefinition.FIELD_PROJECT_UUID;
 import static org.sonar.server.component.index.ComponentIndexDefinition.FIELD_QUALIFIER;
 import static org.sonar.server.component.index.ComponentIndexDefinition.FIELD_UUID;
 import static org.sonar.server.component.index.ComponentIndexDefinition.TYPE_COMPONENT;
@@ -37,10 +34,6 @@ public class ComponentDoc extends BaseDoc {
     super(TYPE_COMPONENT, new HashMap<>(6));
   }
 
-  public ComponentDoc(Map<String, Object> fields) {
-    super(TYPE_COMPONENT, fields);
-  }
-
   @Override
   public String getId() {
     return getField(FIELD_UUID);
@@ -51,16 +44,6 @@ public class ComponentDoc extends BaseDoc {
     return this;
   }
 
-  public String getProjectUuid() {
-    return getField(FIELD_PROJECT_UUID);
-  }
-
-  public ComponentDoc setProjectUuid(String s) {
-    setField(FIELD_PROJECT_UUID, s);
-    setParent(AuthorizationDoc.idOf(s));
-    return this;
-  }
-
   public String getKey() {
     return getField(FIELD_KEY);
   }
index bdb00e26b41038945b36ba45df35de7d6b68952c..8c8d295d0a0b001e1f96be2ff9b06b2e11f8b70a 100644 (file)
@@ -43,7 +43,6 @@ public class ComponentIndexDefinition implements IndexDefinition {
   public static final Index DESCRIPTOR = Index.withRelations("components");
   public static final IndexType.IndexRelationType TYPE_COMPONENT = IndexType.relation(IndexType.main(DESCRIPTOR, TYPE_AUTHORIZATION), "component");
   public static final String FIELD_UUID = "uuid";
-  public static final String FIELD_PROJECT_UUID = "project_uuid";
   public static final String FIELD_KEY = "key";
   public static final String FIELD_NAME = "name";
   public static final String FIELD_QUALIFIER = "qualifier";
@@ -85,7 +84,6 @@ public class ComponentIndexDefinition implements IndexDefinition {
 
     TypeMapping mapping = index.createTypeMapping(TYPE_COMPONENT);
     mapping.keywordFieldBuilder(FIELD_UUID).disableNorms().build();
-    mapping.keywordFieldBuilder(FIELD_PROJECT_UUID).disableNorms().build();
     mapping.keywordFieldBuilder(FIELD_KEY).addSubFields(SORTABLE_ANALYZER).build();
     mapping.textFieldBuilder(FIELD_NAME)
       .withFieldData()
index 2890a3809ec115f14bf97f49f34a54bb0d78d349..c328728925758aedca5ac4e38d7754bb3076f953 100644 (file)
@@ -33,7 +33,7 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
 import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
+import org.sonar.db.entity.EntityDto;
 import org.sonar.db.es.EsQueueDto;
 import org.sonar.server.es.BaseDoc;
 import org.sonar.server.es.BulkIndexer;
@@ -100,7 +100,7 @@ public class ComponentIndexer implements ProjectIndexer, NeedAuthorizationIndexe
         return emptyList();
       case PROJECT_CREATION, PROJECT_DELETION, PROJECT_KEY_UPDATE:
         List<EsQueueDto> items = projectUuids.stream()
-          .map(branchUuid -> EsQueueDto.create(TYPE_COMPONENT.format(), branchUuid, null, branchUuid))
+          .map(projectUuid -> EsQueueDto.create(TYPE_COMPONENT.format(), projectUuid, null, projectUuid))
           .collect(MoreCollectors.toArrayList(projectUuids.size()));
         return dbClient.esQueueDao().insert(dbSession, items);
       default:
@@ -118,15 +118,14 @@ public class ComponentIndexer implements ProjectIndexer, NeedAuthorizationIndexe
     OneToManyResilientIndexingListener listener = new OneToManyResilientIndexingListener(dbClient, dbSession, items);
     BulkIndexer bulkIndexer = new BulkIndexer(esClient, TYPE_COMPONENT, Size.REGULAR, listener);
     bulkIndexer.start();
-    Set<String> branchUuids = items.stream().map(EsQueueDto::getDocId).collect(MoreCollectors.toHashSet(items.size()));
-    Set<String> remaining = new HashSet<>(branchUuids);
+    Set<String> entityUuids = items.stream().map(EsQueueDto::getDocId).collect(MoreCollectors.toHashSet(items.size()));
+    Set<String> remaining = new HashSet<>(entityUuids);
 
-    for (String branchUuid : branchUuids) {
-      // TODO allow scrolling multiple projects at the same time
-      dbClient.componentDao().scrollForIndexing(dbSession, branchUuid, context -> {
-        ComponentDto dto = context.getResultObject();
+    for (String entityUuid : entityUuids) {
+      dbClient.projectDao().scrollEntitiesForIndexing(dbSession, entityUuid, context -> {
+        EntityDto dto = context.getResultObject();
         bulkIndexer.add(toDocument(dto).toIndexRequest());
-        remaining.remove(dto.branchUuid());
+        remaining.remove(dto.getUuid());
       });
     }
 
@@ -139,16 +138,16 @@ public class ComponentIndexer implements ProjectIndexer, NeedAuthorizationIndexe
 
   /**
    * @param projectUuid the uuid of the project to analyze, or {@code null} if all content should be indexed.<br/>
-   * <b>Warning:</b> only use {@code null} during startup.
+   *                    <b>Warning:</b> only use {@code null} during startup.
    */
   private void doIndexByProjectUuid(@Nullable String projectUuid, Size bulkSize) {
     BulkIndexer bulk = new BulkIndexer(esClient, TYPE_COMPONENT, bulkSize);
 
     bulk.start();
     try (DbSession dbSession = dbClient.openSession(false)) {
-      dbClient.componentDao()
-        .scrollForIndexing(dbSession, projectUuid, context -> {
-          ComponentDto dto = context.getResultObject();
+      dbClient.projectDao()
+        .scrollEntitiesForIndexing(dbSession, projectUuid, context -> {
+          EntityDto dto = context.getResultObject();
           bulk.add(toDocument(dto).toIndexRequest());
         });
     }
@@ -157,7 +156,7 @@ public class ComponentIndexer implements ProjectIndexer, NeedAuthorizationIndexe
 
   private static void addProjectDeletionToBulkIndexer(BulkIndexer bulkIndexer, String projectUuid) {
     SearchRequest searchRequest = EsClient.prepareSearch(TYPE_COMPONENT.getMainType())
-      .source(new SearchSourceBuilder().query(QueryBuilders.termQuery(ComponentIndexDefinition.FIELD_PROJECT_UUID, projectUuid)))
+      .source(new SearchSourceBuilder().query(QueryBuilders.termQuery(ComponentIndexDefinition.FIELD_UUID, projectUuid)))
       .routing(AuthorizationDoc.idOf(projectUuid));
     bulkIndexer.addDeletion(searchRequest);
   }
@@ -170,7 +169,7 @@ public class ComponentIndexer implements ProjectIndexer, NeedAuthorizationIndexe
   }
 
   @VisibleForTesting
-  void index(ComponentDto... docs) {
+  void index(EntityDto... docs) {
     BulkIndexer bulk = new BulkIndexer(esClient, TYPE_COMPONENT, Size.REGULAR);
     bulk.start();
     Arrays.stream(docs)
@@ -180,12 +179,11 @@ public class ComponentIndexer implements ProjectIndexer, NeedAuthorizationIndexe
     bulk.stop();
   }
 
-  public static ComponentDoc toDocument(ComponentDto component) {
+  public static ComponentDoc toDocument(EntityDto component) {
     return new ComponentDoc()
-      .setId(component.uuid())
-      .setName(component.name())
+      .setId(component.getUuid())
+      .setName(component.getName())
       .setKey(component.getKey())
-      .setProjectUuid(component.branchUuid())
-      .setQualifier(component.qualifier());
+      .setQualifier(component.getQualifier());
   }
 }
index 9feaba8aaf45c321ecb9ce55c42ed9dbd46860c2..b51e9620c92d63ffe929976789397ee2dec818dd 100644 (file)
@@ -64,7 +64,7 @@ public class AddActionIT {
   private final DbClient dbClient = db.getDbClient();
   private final DbSession dbSession = db.getSession();
   private final FavoriteUpdater favoriteUpdater = new FavoriteUpdater(dbClient);
-  private final WsActionTester ws = new WsActionTester(new AddAction(userSession, dbClient, favoriteUpdater, TestComponentFinder.from(db)));
+  private final WsActionTester ws = new WsActionTester(new AddAction(userSession, dbClient, favoriteUpdater));
 
   @Test
   public void add_a_project() {
index f2636b299b3056a090fed0b99d75894038204a30..6aea81b54fecb061797da8441a99867cb23a3d2a 100644 (file)
@@ -55,7 +55,7 @@ public class RemoveActionIT {
 
   private final DbClient dbClient = db.getDbClient();
   private final FavoriteUpdater favoriteUpdater = new FavoriteUpdater(dbClient);
-  private final WsActionTester ws = new WsActionTester(new RemoveAction(userSession, dbClient, favoriteUpdater, TestComponentFinder.from(db)));
+  private final WsActionTester ws = new WsActionTester(new RemoveAction(userSession, dbClient, favoriteUpdater));
 
   @Before
   public void before() {
@@ -75,11 +75,11 @@ public class RemoveActionIT {
 
   @Test
   public void fail_if_not_already_a_favorite() {
-    ProjectDto componentDto = insertProjectAndPermissions();
+    ProjectDto project = insertProjectAndPermissions();
 
     assertThatThrownBy(() -> call(PROJECT_KEY))
       .isInstanceOf(IllegalArgumentException.class)
-      .hasMessage("Component '" + PROJECT_KEY + "' (uuid: " + componentDto.getUuid() + ") is not a favorite");
+      .hasMessage("Component '" + PROJECT_KEY + "' (uuid: " + project.getUuid() + ") is not a favorite");
   }
 
   @Test
index 40c4469e5a2603df4e7ab26b9b4aff1cbd924bd5..4fc97352a34aaff13f5ea5afbb831e82dfa829d3 100644 (file)
@@ -33,10 +33,8 @@ import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
 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.permission.GlobalPermission;
-import org.sonar.server.component.TestComponentFinder;
+import org.sonar.db.project.ProjectDto;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.tester.UserSessionRule;
@@ -73,16 +71,14 @@ public class ListDefinitionsActionIT {
   public DbTester db = DbTester.create(System2.INSTANCE);
 
   private final DbClient dbClient = db.getDbClient();
-  private final ComponentDbTester componentDb = new ComponentDbTester(db);
-  private ComponentDto project;
+  private ProjectDto project;
   private final PropertyDefinitions propertyDefinitions = new PropertyDefinitions(System2.INSTANCE);
   private final SettingsWsSupport support = new SettingsWsSupport(userSession);
-  private final WsActionTester ws = new WsActionTester(
-    new ListDefinitionsAction(dbClient, TestComponentFinder.from(db), userSession, propertyDefinitions, support));
+  private final WsActionTester ws = new WsActionTester(new ListDefinitionsAction(dbClient, userSession, propertyDefinitions, support));
 
   @Before
   public void setUp() {
-    project = db.components().insertPrivateProject().getMainBranchComponent();
+    project = db.components().insertPrivateProject().getProjectDto();
   }
 
   @Test
index 5d18dd2220f4f54bf92b1541db8e47ec0a13f041..a8eadfc7d1df323a406a3002abfc8eab1352daa7 100644 (file)
@@ -75,12 +75,11 @@ public class ResetActionIT {
   private final PropertyDbTester propertyDb = new PropertyDbTester(db);
   private final DbClient dbClient = db.getDbClient();
   private final DbSession dbSession = db.getSession();
-  private final ComponentFinder componentFinder = TestComponentFinder.from(db);
   private final PropertyDefinitions definitions = new PropertyDefinitions(System2.INSTANCE);
   private final SettingsUpdater settingsUpdater = new SettingsUpdater(dbClient, definitions);
   private final SettingValidations settingValidations = new SettingValidations(definitions, dbClient, i18n);
   private ProjectDto project;
-  private final ResetAction underTest = new ResetAction(dbClient, componentFinder, settingsUpdater, userSession, definitions, settingValidations);
+  private final ResetAction underTest = new ResetAction(dbClient, settingsUpdater, userSession, definitions, settingValidations);
   private final WsActionTester ws = new WsActionTester(underTest);
 
   @Before
@@ -218,7 +217,7 @@ public class ResetActionIT {
     assertThat(action.isInternal()).isFalse();
     assertThat(action.isPost()).isTrue();
     assertThat(action.responseExampleAsString()).isNull();
-    assertThat(action.params()).extracting(Param::key).containsExactlyInAnyOrder("keys", "component", "branch", "pullRequest");
+    assertThat(action.params()).extracting(Param::key).containsExactlyInAnyOrder("keys", "component");
   }
 
   @Test
index a7f16712833c80d7ab1c54b25e6e23f6ab63a7b2..44caee87e409cb61e1a3a10f29ae941b282c4f05 100644 (file)
@@ -52,8 +52,6 @@ import org.sonar.db.property.PropertyDto;
 import org.sonar.db.property.PropertyQuery;
 import org.sonar.process.ProcessProperties;
 import org.sonar.scanner.protocol.GsonHelper;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.component.TestComponentFinder;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
@@ -87,14 +85,12 @@ public class SetActionIT {
   private PropertyDbTester propertyDb = new PropertyDbTester(db);
   private DbClient dbClient = db.getDbClient();
   private DbSession dbSession = db.getSession();
-  private ComponentFinder componentFinder = TestComponentFinder.from(db);
-
   private I18nRule i18n = new I18nRule();
   private PropertyDefinitions definitions = new PropertyDefinitions(System2.INSTANCE);
   private FakeSettingsNotifier settingsChangeNotifier = new FakeSettingsNotifier(dbClient);
   private SettingsUpdater settingsUpdater = new SettingsUpdater(dbClient, definitions);
   private SettingValidations validations = new SettingValidations(definitions, dbClient, i18n);
-  private SetAction underTest = new SetAction(definitions, dbClient, componentFinder, userSession, settingsUpdater, settingsChangeNotifier, validations);
+  private SetAction underTest = new SetAction(definitions, dbClient, userSession, settingsUpdater, settingsChangeNotifier, validations);
 
   private WsActionTester ws = new WsActionTester(underTest);
 
index cea85076cc1d682a64e09c00f4be5ed096d71847..58dd418deb805a5f75dc48601fba942c860eeffc 100644 (file)
@@ -82,15 +82,13 @@ public class ValuesActionIT {
   private final DbClient dbClient = db.getDbClient();
   private final PropertyDefinitions definitions = new PropertyDefinitions(System2.INSTANCE);
   private final SettingsWsSupport support = new SettingsWsSupport(userSession);
-  private final WsActionTester wsActionTester = new WsActionTester(new ValuesAction(dbClient, TestComponentFinder.from(db), userSession, definitions, support));
+  private final WsActionTester wsActionTester = new WsActionTester(new ValuesAction(dbClient, userSession, definitions, support));
   private ProjectDto project;
-  private ComponentDto rootComponent;
 
   @Before
   public void setUp() {
     ProjectData projectData = db.components().insertPrivateProject();
     project = projectData.getProjectDto();
-    rootComponent = projectData.getMainBranchComponent();
   }
 
   @Test
index 67cadf61d4f2c58a1e16db46f9500bf0f3e17fca..d59f089cb3bc0ff7192834974f9b26d3e3663f90 100644 (file)
@@ -159,7 +159,7 @@ public class SuggestionsAction implements ComponentsWsAction {
   }
 
   /**
-   * we are generating suggestions, by using (1) favorites and (2) recently browsed components (without searchin in Elasticsearch)
+   * we are generating suggestions, by using (1) favorites and (2) recently browsed components (without searching in Elasticsearch)
    */
   private SuggestionsWsResponse loadSuggestionsWithoutSearch(int skip, int limit, Set<String> recentlyBrowsedKeys, List<String> qualifiers) {
     List<EntityDto> favorites = favoriteFinder.list();
index b31f0153500caaab2ecf0a8498dc46f0b489f1b8..5e35111dbf3a341132975527f4c2fa83c6559d66 100644 (file)
@@ -55,9 +55,9 @@ public class FavoriteFinder {
         .setKey(PROP_FAVORITE_KEY)
         .setUserUuid(userSession.getUuid())
         .build();
-      Set<String> componentUuids = dbClient.propertiesDao().selectByQuery(dbQuery, dbSession).stream().map(PropertyDto::getComponentUuid).collect(Collectors.toSet());
+      Set<String> entitiesUuids = dbClient.propertiesDao().selectByQuery(dbQuery, dbSession).stream().map(PropertyDto::getComponentUuid).collect(Collectors.toSet());
 
-      List<EntityDto> entities = dbClient.projectDao().selectEntitiesByUuids(dbSession, componentUuids);
+      List<EntityDto> entities = dbClient.projectDao().selectEntitiesByUuids(dbSession, entitiesUuids);
 
       return entities.stream()
         .sorted(Comparator.comparing(EntityDto::getName))
index a233f317cab9168fa379dc5831c1c0dd968492d7..a5618d94905adf8540b13313be95262564c52e61 100644 (file)
@@ -54,21 +54,19 @@ public class AddAction implements FavoritesWsAction {
   private final UserSession userSession;
   private final DbClient dbClient;
   private final FavoriteUpdater favoriteUpdater;
-  private final ComponentFinder componentFinder;
 
-  public AddAction(UserSession userSession, DbClient dbClient, FavoriteUpdater favoriteUpdater, ComponentFinder componentFinder) {
+  public AddAction(UserSession userSession, DbClient dbClient, FavoriteUpdater favoriteUpdater) {
     this.userSession = userSession;
     this.dbClient = dbClient;
     this.favoriteUpdater = favoriteUpdater;
-    this.componentFinder = componentFinder;
   }
 
   @Override
   public void define(WebService.NewController context) {
     WebService.NewAction action = context.createAction("add")
-      .setDescription("Add a component (project, file etc.) as favorite for the authenticated user.<br>" +
+      .setDescription("Add a component (project, portfolio, etc.) as favorite for the authenticated user.<br>" +
         "Only 100 components by qualifier can be added as favorite.<br>" +
-        "Requires authentication and the following permission: 'Browse' on the project of the specified component.")
+        "Requires authentication and the following permission: 'Browse' on the component.")
       .setSince("6.3")
       .setChangelog(
         new Change("10.1", String.format("The use of module keys in parameter '%s' is removed", PARAM_COMPONENT)),
index af6cf40038b2ae37427776399e630c57b5664968..85cc8d60a117dfeda24e0ecb5e9eee694e386479 100644 (file)
@@ -40,13 +40,11 @@ public class RemoveAction implements FavoritesWsAction {
   private final UserSession userSession;
   private final DbClient dbClient;
   private final FavoriteUpdater favoriteUpdater;
-  private final ComponentFinder componentFinder;
 
-  public RemoveAction(UserSession userSession, DbClient dbClient, FavoriteUpdater favoriteUpdater, ComponentFinder componentFinder) {
+  public RemoveAction(UserSession userSession, DbClient dbClient, FavoriteUpdater favoriteUpdater) {
     this.userSession = userSession;
     this.dbClient = dbClient;
     this.favoriteUpdater = favoriteUpdater;
-    this.componentFinder = componentFinder;
   }
 
   @Override
index c14b2b1391c91f4b9f035b9de7fc65adbadc094b..cc68222591b124436012d21461c8c371735a376b 100644 (file)
@@ -32,13 +32,14 @@ import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.server.component.ComponentFinder;
+import org.sonar.db.entity.EntityDto;
+import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Settings;
 import org.sonarqube.ws.Settings.ListDefinitionsWsResponse;
 
 import static com.google.common.base.Strings.emptyToNull;
+import static java.lang.String.format;
 import static java.util.Comparator.comparing;
 import static java.util.Optional.ofNullable;
 import static org.sonar.api.web.UserRole.USER;
@@ -49,15 +50,12 @@ import static org.sonar.server.ws.WsUtils.writeProtobuf;
 public class ListDefinitionsAction implements SettingsWsAction {
 
   private final DbClient dbClient;
-  private final ComponentFinder componentFinder;
   private final UserSession userSession;
   private final PropertyDefinitions propertyDefinitions;
   private final SettingsWsSupport settingsWsSupport;
 
-  public ListDefinitionsAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, PropertyDefinitions propertyDefinitions,
-                               SettingsWsSupport settingsWsSupport) {
+  public ListDefinitionsAction(DbClient dbClient, UserSession userSession, PropertyDefinitions propertyDefinitions, SettingsWsSupport settingsWsSupport) {
     this.dbClient = dbClient;
-    this.componentFinder = componentFinder;
     this.userSession = userSession;
     this.propertyDefinitions = propertyDefinitions;
     this.settingsWsSupport = settingsWsSupport;
@@ -93,8 +91,8 @@ public class ListDefinitionsAction implements SettingsWsAction {
 
   private ListDefinitionsWsResponse doHandle(Request request) {
     ListDefinitionsRequest wsRequest = toWsRequest(request);
-    Optional<ComponentDto> component = loadComponent(wsRequest);
-    Optional<String> qualifier = getQualifier(component);
+    Optional<EntityDto> component = loadComponent(wsRequest);
+    Optional<String> qualifier = component.map(EntityDto::getQualifier);
     ListDefinitionsWsResponse.Builder wsResponse = ListDefinitionsWsResponse.newBuilder();
     propertyDefinitions.getAll().stream()
       .filter(definition -> qualifier.map(s -> definition.qualifiers().contains(s)).orElseGet(definition::global))
@@ -111,19 +109,16 @@ public class ListDefinitionsAction implements SettingsWsAction {
       .setComponent(request.param(PARAM_COMPONENT));
   }
 
-  private static Optional<String> getQualifier(Optional<ComponentDto> component) {
-    return component.map(ComponentDto::qualifier);
-  }
-
-  private Optional<ComponentDto> loadComponent(ListDefinitionsRequest request) {
+  private Optional<EntityDto> loadComponent(ListDefinitionsRequest request) {
     try (DbSession dbSession = dbClient.openSession(false)) {
-      String componentKey = request.getComponent();
-      if (componentKey == null) {
+      String entityKey = request.getComponent();
+      if (entityKey == null) {
         return Optional.empty();
       }
-      ComponentDto component = componentFinder.getByKey(dbSession, componentKey);
-      userSession.checkComponentPermission(USER, component);
-      return Optional.of(component);
+      EntityDto entity = dbClient.projectDao().selectEntityByKey(dbSession, entityKey)
+        .orElseThrow(() -> new NotFoundException(format("Component key '%s' not found", entityKey)));
+      userSession.checkEntityPermission(USER, entity);
+      return Optional.of(entity);
     }
   }
 
index 4c2383cbc386c608acfa6021fd2bc9fdb0a599bf..e80937492646d60d7aa6a756eb20e78b0a3a2ffc 100644 (file)
@@ -34,9 +34,7 @@ import org.sonar.api.web.UserRole;
 import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
 import org.sonar.db.entity.EntityDto;
-import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.setting.ws.SettingValidations.SettingData;
 import org.sonar.server.user.UserSession;
@@ -47,24 +45,19 @@ import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_BRANCH;
 import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_COMPONENT;
 import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_KEYS;
 import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_PULL_REQUEST;
-import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
 import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
-import static org.sonar.server.ws.KeyExamples.KEY_PULL_REQUEST_EXAMPLE_001;
 
 public class ResetAction implements SettingsWsAction {
   private final DbClient dbClient;
-  private final ComponentFinder componentFinder;
   private final SettingsUpdater settingsUpdater;
   private final UserSession userSession;
   private final PropertyDefinitions definitions;
   private final SettingValidations validations;
 
-  public ResetAction(DbClient dbClient, ComponentFinder componentFinder, SettingsUpdater settingsUpdater, UserSession userSession, PropertyDefinitions definitions,
-                     SettingValidations validations) {
+  public ResetAction(DbClient dbClient, SettingsUpdater settingsUpdater, UserSession userSession, PropertyDefinitions definitions, SettingValidations validations) {
     this.dbClient = dbClient;
     this.settingsUpdater = settingsUpdater;
     this.userSession = userSession;
-    this.componentFinder = componentFinder;
     this.definitions = definitions;
     this.validations = validations;
   }
@@ -81,8 +74,9 @@ public class ResetAction implements SettingsWsAction {
         "</ul>")
       .setSince("6.1")
       .setChangelog(
+        new Change("10.1", format("Internal parameters '%s' and '%s' were removed", PARAM_BRANCH, PARAM_PULL_REQUEST)),
         new Change("8.8", "Deprecated parameter 'componentKey' has been removed"),
-        new Change("7.6", String.format("The use of module keys in parameter '%s' is deprecated", PARAM_COMPONENT)),
+        new Change("7.6", format("The use of module keys in parameter '%s' is deprecated", PARAM_COMPONENT)),
         new Change("7.1", "The settings defined in conf/sonar.properties are read-only and can't be changed"))
       .setPost(true)
       .setHandler(this);
@@ -94,16 +88,6 @@ public class ResetAction implements SettingsWsAction {
     action.createParam(PARAM_COMPONENT)
       .setDescription("Component key")
       .setExampleValue(KEY_PROJECT_EXAMPLE_001);
-    action.createParam(PARAM_BRANCH)
-      .setDescription("Branch key")
-      .setExampleValue(KEY_BRANCH_EXAMPLE_001)
-      .setInternal(true)
-      .setSince("6.6");
-    action.createParam(PARAM_PULL_REQUEST)
-      .setDescription("Pull request id")
-      .setExampleValue(KEY_PULL_REQUEST_EXAMPLE_001)
-      .setInternal(true)
-      .setSince("7.1");
   }
 
   @Override
@@ -115,8 +99,7 @@ public class ResetAction implements SettingsWsAction {
       resetRequest.getKeys().forEach(key -> {
         SettingsWsSupport.validateKey(key);
         SettingData data = new SettingData(key, emptyList(), component.orElse(null));
-        List.of(validations.scope(), validations.qualifier())
-          .forEach(validation -> validation.accept(data));
+        List.of(validations.scope(), validations.qualifier()).forEach(validation -> validation.accept(data));
       });
 
       List<String> keys = getKeys(resetRequest);
@@ -142,9 +125,7 @@ public class ResetAction implements SettingsWsAction {
   private static ResetRequest toWsRequest(Request request) {
     return new ResetRequest()
       .setKeys(request.mandatoryParamAsStrings(PARAM_KEYS))
-      .setComponent(request.param(PARAM_COMPONENT))
-      .setBranch(request.param(PARAM_BRANCH))
-      .setPullRequest(request.param(PARAM_PULL_REQUEST));
+      .setComponent(request.param(PARAM_COMPONENT));
   }
 
   private Optional<EntityDto> getComponent(DbSession dbSession, ResetRequest request) {
@@ -153,7 +134,6 @@ public class ResetAction implements SettingsWsAction {
       return Optional.empty();
     }
 
-    // TODO this WS should support branches and PRs?
     return Optional.of(dbClient.projectDao().selectEntityByKey(dbSession, componentKey)
       .orElseThrow(() -> new NotFoundException(format("Component key '%s' not found", componentKey))));
   }
@@ -167,32 +147,9 @@ public class ResetAction implements SettingsWsAction {
   }
 
   private static class ResetRequest {
-
-    private String branch;
-    private String pullRequest;
     private String component;
     private List<String> keys;
 
-    public ResetRequest setBranch(@Nullable String branch) {
-      this.branch = branch;
-      return this;
-    }
-
-    @CheckForNull
-    public String getBranch() {
-      return branch;
-    }
-
-    public ResetRequest setPullRequest(@Nullable String pullRequest) {
-      this.pullRequest = pullRequest;
-      return this;
-    }
-
-    @CheckForNull
-    public String getPullRequest() {
-      return pullRequest;
-    }
-
     public ResetRequest setComponent(@Nullable String component) {
       this.component = component;
       return this;
index 3257522f33d705353503015489ee1fb4d89df61e..c7d50a66de0c0e7a8f4a9ed1ea3e526cb86badb8 100644 (file)
@@ -47,11 +47,9 @@ import org.sonar.api.server.ws.WebService;
 import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
 import org.sonar.db.entity.EntityDto;
 import org.sonar.db.property.PropertyDto;
 import org.sonar.scanner.protocol.GsonHelper;
-import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.setting.SettingsChangeNotifier;
@@ -75,17 +73,15 @@ public class SetAction implements SettingsWsAction {
 
   private final PropertyDefinitions propertyDefinitions;
   private final DbClient dbClient;
-  private final ComponentFinder componentFinder;
   private final UserSession userSession;
   private final SettingsUpdater settingsUpdater;
   private final SettingsChangeNotifier settingsChangeNotifier;
   private final SettingValidations validations;
 
-  public SetAction(PropertyDefinitions propertyDefinitions, DbClient dbClient, ComponentFinder componentFinder, UserSession userSession,
+  public SetAction(PropertyDefinitions propertyDefinitions, DbClient dbClient, UserSession userSession,
     SettingsUpdater settingsUpdater, SettingsChangeNotifier settingsChangeNotifier, SettingValidations validations) {
     this.propertyDefinitions = propertyDefinitions;
     this.dbClient = dbClient;
-    this.componentFinder = componentFinder;
     this.userSession = userSession;
     this.settingsUpdater = settingsUpdater;
     this.settingsChangeNotifier = settingsChangeNotifier;
index dbe09a534274807db2992404bb4a4f6d4055c904..c978d12d3cf5a6852a03a29aa71b258a280ace39 100644 (file)
@@ -54,7 +54,7 @@ import static java.util.Objects.requireNonNull;
 import static org.sonar.server.exceptions.BadRequestException.checkRequest;
 
 public class SettingValidations {
-  private static final Collection<String> SECURITY_JSON_PROPERTIES = List.of(
+  private static final Set<String> SECURITY_JSON_PROPERTIES = Set.of(
     "sonar.security.config.javasecurity",
     "sonar.security.config.phpsecurity",
     "sonar.security.config.pythonsecurity",
index 551025aa3cec62adcfcac092d72cf115aeeb2802..e95241f75a2ad97d477f88ffd9702ca734432b00 100644 (file)
@@ -25,6 +25,7 @@ import java.util.Set;
 import org.sonar.api.server.ServerSide;
 import org.sonar.api.web.UserRole;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.entity.EntityDto;
 import org.sonar.db.permission.GlobalPermission;
 import org.sonar.process.ProcessProperties;
 import org.sonar.server.user.UserSession;
@@ -54,14 +55,14 @@ public class SettingsWsSupport {
       });
   }
 
-  boolean isVisible(String key, Optional<ComponentDto> component) {
+  boolean isVisible(String key, Optional<EntityDto> component) {
     if (isAdmin(component)) {
       return true;
     }
     return hasPermission(GlobalPermission.SCAN, UserRole.SCAN, component) || !isProtected(key);
   }
 
-  private boolean isAdmin(Optional<ComponentDto> component) {
+  private boolean isAdmin(Optional<EntityDto> component) {
     return userSession.isSystemAdministrator() || hasPermission(GlobalPermission.ADMINISTER, ADMIN, component);
   }
 
@@ -77,12 +78,12 @@ public class SettingsWsSupport {
     return ADMIN_ONLY_SETTINGS.contains(key);
   }
 
-  private boolean hasPermission(GlobalPermission orgPermission, String projectPermission, Optional<ComponentDto> component) {
+  private boolean hasPermission(GlobalPermission orgPermission, String projectPermission, Optional<EntityDto> component) {
     if (userSession.hasPermission(orgPermission)) {
       return true;
     }
     return component
-      .map(c -> userSession.hasComponentPermission(projectPermission, c))
+      .map(c -> userSession.hasEntityPermission(projectPermission, c))
       .orElse(false);
   }
 
index 7157264adedb5c9b15a59d67df33b986ed77b71c..6c996322b287fdde55737ed90b9a2705d1ba23cf 100644 (file)
@@ -21,9 +21,6 @@ package org.sonar.server.setting.ws;
 
 import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableSet;
-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.Collection;
 import java.util.HashMap;
@@ -46,12 +43,11 @@ import org.sonar.api.server.ws.WebService;
 import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
-import org.sonar.db.component.BranchDto;
-import org.sonar.db.component.ComponentDto;
+import org.sonar.db.entity.EntityDto;
 import org.sonar.db.permission.GlobalPermission;
 import org.sonar.db.property.PropertyDto;
 import org.sonar.markdown.Markdown;
-import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Settings;
 import org.sonarqube.ws.Settings.ValuesWsResponse;
@@ -78,15 +74,12 @@ public class ValuesAction implements SettingsWsAction {
   private static final Set<String> SERVER_SETTING_KEYS = Set.of(SERVER_STARTTIME, SERVER_ID);
 
   private final DbClient dbClient;
-  private final ComponentFinder componentFinder;
   private final UserSession userSession;
   private final PropertyDefinitions propertyDefinitions;
   private final SettingsWsSupport settingsWsSupport;
 
-  public ValuesAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, PropertyDefinitions propertyDefinitions,
-    SettingsWsSupport settingsWsSupport) {
+  public ValuesAction(DbClient dbClient, UserSession userSession, PropertyDefinitions propertyDefinitions, SettingsWsSupport settingsWsSupport) {
     this.dbClient = dbClient;
-    this.componentFinder = componentFinder;
     this.userSession = userSession;
     this.propertyDefinitions = propertyDefinitions;
     this.settingsWsSupport = settingsWsSupport;
@@ -125,7 +118,7 @@ public class ValuesAction implements SettingsWsAction {
   private ValuesWsResponse doHandle(Request request) {
     try (DbSession dbSession = dbClient.openSession(true)) {
       ValuesRequest valuesRequest = ValuesRequest.from(request);
-      Optional<ComponentDto> component = loadComponent(dbSession, valuesRequest);
+      Optional<EntityDto> component = loadComponent(dbSession, valuesRequest);
       Set<String> keys = loadKeys(valuesRequest);
       Map<String, String> keysToDisplayMap = getKeysToDisplayMap(keys);
       List<Setting> settings = loadSettings(dbSession, component, keysToDisplayMap.keySet());
@@ -145,23 +138,25 @@ public class ValuesAction implements SettingsWsAction {
     return result;
   }
 
-  private Optional<ComponentDto> loadComponent(DbSession dbSession, ValuesRequest valuesRequest) {
+  private Optional<EntityDto> loadComponent(DbSession dbSession, ValuesRequest valuesRequest) {
     String componentKey = valuesRequest.getComponent();
     if (componentKey == null) {
       return Optional.empty();
     }
-    ComponentDto component = componentFinder.getByKey(dbSession, componentKey);
 
-    if (!userSession.hasComponentPermission(USER, component) &&
-      !userSession.hasComponentPermission(UserRole.SCAN, component) &&
+    EntityDto component = dbClient.projectDao().selectEntityByKey(dbSession, componentKey)
+      .orElseThrow(() -> new NotFoundException(format("Component key '%s' not found", componentKey)));
+
+    if (!userSession.hasEntityPermission(USER, component) &&
+      !userSession.hasEntityPermission(UserRole.SCAN, component) &&
       !userSession.hasPermission(GlobalPermission.SCAN)) {
       throw insufficientPrivilegesException();
     }
     return Optional.of(component);
   }
 
-  private List<Setting> loadSettings(DbSession dbSession, Optional<ComponentDto> component, Set<String> keys) {
-    // List of settings must be kept in the following orders : default -> global -> component -> branch
+  private List<Setting> loadSettings(DbSession dbSession, Optional<EntityDto> component, Set<String> keys) {
+    // List of settings must be kept in the following orders : default -> global -> component
     List<Setting> settings = new ArrayList<>();
     settings.addAll(loadDefaultValues(keys));
     settings.addAll(loadGlobalSettings(dbSession, keys));
@@ -171,22 +166,8 @@ public class ValuesAction implements SettingsWsAction {
       .toList();
   }
 
-  private Collection<Setting> loadComponentSettings(DbSession dbSession, ComponentDto componentDto, Set<String> keys) {
-    BranchDto branchDto = componentFinder.getBranchByUuid(dbSession, componentDto.branchUuid());
-
-    List<String> componentUuids = new LinkedList<>();
-    if (!branchDto.isMain()) {
-      ComponentDto mainBranchComponent = componentFinder.getByKey(dbSession, componentDto.getKey());
-      if (!mainBranchComponent.isRoot()) {
-        componentUuids.add(mainBranchComponent.branchUuid());
-      }
-      componentUuids.add(mainBranchComponent.uuid());
-    }
-    if (!componentDto.isRoot()) {
-      componentUuids.add(componentDto.branchUuid());
-    }
-    componentUuids.add(componentDto.uuid());
-    return loadComponentsSettings(dbSession, keys, componentUuids);
+  private Collection<Setting> loadComponentSettings(DbSession dbSession, EntityDto entity, Set<String> keys) {
+    return loadComponentSettings(dbSession, keys, entity.getUuid());
   }
 
   private List<Setting> loadDefaultValues(Set<String> keys) {
@@ -209,25 +190,24 @@ public class ValuesAction implements SettingsWsAction {
     List<PropertyDto> properties = dbClient.propertiesDao().selectGlobalPropertiesByKeys(dbSession, keys);
     List<PropertyDto> propertySets = dbClient.propertiesDao().selectGlobalPropertiesByKeys(dbSession, getPropertySetKeys(properties));
     return properties.stream()
-      .map(property -> Setting.createFromDto(property, getPropertySets(property.getKey(), propertySets, null), propertyDefinitions.get(property.getKey())))
+      .map(property -> Setting.createFromDto(property, filterPropertySets(property.getKey(), propertySets, null), propertyDefinitions.get(property.getKey())))
       .toList();
   }
 
   /**
    * Return list of settings by component uuids
    */
-  private Collection<Setting> loadComponentsSettings(DbSession dbSession, Set<String> keys, List<String> componentUuids) {
-    List<PropertyDto> properties = dbClient.propertiesDao().selectPropertiesByKeysAndComponentUuids(dbSession, keys, componentUuids);
-    List<PropertyDto> propertySets = dbClient.propertiesDao().selectPropertiesByKeysAndComponentUuids(dbSession, getPropertySetKeys(properties), componentUuids);
+  private Collection<Setting> loadComponentSettings(DbSession dbSession, Set<String> keys, String entityUuid) {
+    List<PropertyDto> properties = dbClient.propertiesDao().selectPropertiesByKeysAndComponentUuids(dbSession, keys, Set.of(entityUuid));
+    List<PropertyDto> propertySets = dbClient.propertiesDao().selectPropertiesByKeysAndComponentUuids(dbSession, getPropertySetKeys(properties), Set.of(entityUuid));
 
-    Multimap<String, Setting> settingsByUuid = TreeMultimap.create(Ordering.explicit(componentUuids), Ordering.arbitrary());
+    List<Setting> settings = new LinkedList<>();
     for (PropertyDto propertyDto : properties) {
       String componentUuid = propertyDto.getComponentUuid();
       String propertyKey = propertyDto.getKey();
-      settingsByUuid.put(componentUuid,
-        Setting.createFromDto(propertyDto, getPropertySets(propertyKey, propertySets, componentUuid), propertyDefinitions.get(propertyKey)));
+      settings.add(Setting.createFromDto(propertyDto, filterPropertySets(propertyKey, propertySets, componentUuid), propertyDefinitions.get(propertyKey)));
     }
-    return settingsByUuid.values();
+    return settings;
   }
 
   private Set<String> getPropertySetKeys(List<PropertyDto> properties) {
@@ -238,7 +218,7 @@ public class ValuesAction implements SettingsWsAction {
       .collect(Collectors.toSet());
   }
 
-  private static List<PropertyDto> getPropertySets(String propertyKey, List<PropertyDto> propertySets, @Nullable String componentUuid) {
+  private static List<PropertyDto> filterPropertySets(String propertyKey, List<PropertyDto> propertySets, @Nullable String componentUuid) {
     return propertySets.stream()
       .filter(propertyDto -> Objects.equals(propertyDto.getComponentUuid(), componentUuid))
       .filter(propertyDto -> propertyDto.getKey().startsWith(propertyKey + "."))
@@ -247,14 +227,14 @@ public class ValuesAction implements SettingsWsAction {
 
   private class ValuesResponseBuilder {
     private final List<Setting> settings;
-    private final Optional<ComponentDto> requestedComponent;
+    private final Optional<EntityDto> requestedComponent;
 
     private final ValuesWsResponse.Builder valuesWsBuilder = ValuesWsResponse.newBuilder();
     private final Map<String, Settings.Setting.Builder> settingsBuilderByKey = new HashMap<>();
     private final Map<String, Setting> settingsByParentKey = new HashMap<>();
     private final Map<String, String> keysToDisplayMap;
 
-    ValuesResponseBuilder(List<Setting> settings, Optional<ComponentDto> requestedComponent, Map<String, String> keysToDisplayMap) {
+    ValuesResponseBuilder(List<Setting> settings, Optional<EntityDto> requestedComponent, Map<String, String> keysToDisplayMap) {
       this.settings = settings;
       this.requestedComponent = requestedComponent;
       this.keysToDisplayMap = keysToDisplayMap;
@@ -288,7 +268,7 @@ public class ValuesAction implements SettingsWsAction {
     private void setInherited(Setting setting, Settings.Setting.Builder valueBuilder) {
       boolean isDefault = setting.isDefault();
       boolean isGlobal = !requestedComponent.isPresent();
-      boolean isOnComponent = requestedComponent.isPresent() && Objects.equals(setting.getComponentUuid(), requestedComponent.get().uuid());
+      boolean isOnComponent = requestedComponent.isPresent() && Objects.equals(setting.getComponentUuid(), requestedComponent.get().getUuid());
       boolean isSet = isGlobal || isOnComponent;
       valueBuilder.setInherited(isDefault || !isSet);
     }
index f7b162812b3b95c8d7ee95f08cf0fc16ff00434d..23d80dd0edf509301c9187773db4d014a0f36fdb 100644 (file)
@@ -31,9 +31,11 @@ import org.mockito.Mock;
 import org.sonar.api.web.UserRole;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.permission.GlobalPermission;
+import org.sonar.db.project.ProjectDto;
 import org.sonar.server.user.UserSession;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.openMocks;
 
@@ -74,10 +76,8 @@ public class SettingsWsSupportTest {
   private final boolean hasComponentPermission;
   private final boolean expectedIsVisible;
 
-  @Mock
-  private ComponentDto componentDto;
-  @Mock
-  private UserSession userSession;
+  private final ProjectDto componentDto = mock(ProjectDto.class);
+  private final UserSession userSession = mock(UserSession.class);
   @InjectMocks
   private SettingsWsSupport settingsWsSupport;
 
@@ -94,7 +94,7 @@ public class SettingsWsSupportTest {
     openMocks(this);
     when(userSession.isSystemAdministrator()).thenReturn(isAdmin);
     when(userSession.hasPermission(GlobalPermission.SCAN)).thenReturn(hasGlobalPermission);
-    when(userSession.hasComponentPermission(UserRole.SCAN, componentDto)).thenReturn(hasComponentPermission);
+    when(userSession.hasEntityPermission(UserRole.SCAN, componentDto)).thenReturn(hasComponentPermission);
 
     boolean isVisible = settingsWsSupport.isVisible(property, Optional.of(componentDto));
     assertThat(isVisible).isEqualTo(expectedIsVisible);
index f4b1cac6b6abae429f14afdcb6c7167bb1b295ca..d51a8a2805bec0eeed82b9b85b45d273ba9541c7 100644 (file)
@@ -48,10 +48,10 @@ message ShowWsResponse {
 
 // WS api/components/suggestions
 message SuggestionsWsResponse {
-  reserved 3; //drop organization
   repeated Category results = 1;
   optional string warning = 2;
-  repeated Project projects = 4;
+  reserved 3; //drop organization
+  reserved 4; //drop projects
 
   message Category {
     optional string q = 1;
@@ -68,11 +68,6 @@ message SuggestionsWsResponse {
     optional bool isRecentlyBrowsed = 6;
     optional bool isFavorite = 7;
   }
-
-  message Project {
-    optional string key = 1;
-    optional string name = 2;
-  }
 }
 
 // WS api/components/search_projects