aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java8
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml8
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml2
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ComponentCleanerService.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java16
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/es/ProjectIndexers.java13
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/es/ProjectIndexersImpl.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/permission/PermissionUpdater.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkUpdateKeyAction.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/projecttag/ws/SetAction.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java10
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexerTest.java1
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/es/ProjectIndexersImplTest.java67
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/es/ProjectIndexersTest.java92
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/es/TestProjectIndexers.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkUpdateKeyActionTest.java4
-rw-r--r--tests/src/test/java/org/sonarqube/tests/Category6Suite.java4
-rw-r--r--tests/src/test/java/org/sonarqube/tests/Elasticsearch.java19
-rw-r--r--tests/src/test/java/org/sonarqube/tests/projectAdministration/ProjectKeyUpdatePageTest.java (renamed from tests/src/test/java/org/sonarqube/tests/projectAdministration/ProjectKeyPageTest.java)2
-rw-r--r--tests/src/test/java/org/sonarqube/tests/projectAdministration/ProjectKeyUpdateTest.java254
26 files changed, 443 insertions, 85 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java
index 357732fa08c..b954a67e27f 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java
@@ -48,22 +48,20 @@ public class ComponentKeyUpdaterDao implements Dao {
private static final Set<String> PROJECT_OR_MODULE_QUALIFIERS = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.MODULE);
- public void updateKey(DbSession dbSession, String projectUuid, String newKey) {
+ public void updateKey(DbSession dbSession, String projectOrModuleUuid, String newKey) {
ComponentKeyUpdaterMapper mapper = dbSession.getMapper(ComponentKeyUpdaterMapper.class);
if (mapper.countResourceByKey(newKey) > 0) {
throw new IllegalArgumentException("Impossible to update key: a component with key \"" + newKey + "\" already exists.");
}
// must SELECT first everything
- ResourceDto project = mapper.selectProject(projectUuid);
+ ResourceDto project = mapper.selectProject(projectOrModuleUuid);
String projectOldKey = project.getKey();
- List<ResourceDto> resources = mapper.selectProjectResources(projectUuid);
+ List<ResourceDto> resources = mapper.selectProjectResources(projectOrModuleUuid);
resources.add(project);
// and then proceed with the batch UPDATE at once
runBatchUpdateForAllResources(resources, projectOldKey, newKey, mapper);
-
- dbSession.commit();
}
public static void checkIsProjectOrModule(ComponentDto component) {
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml
index b47e6f46b44..d7189fdb1ec 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml
@@ -21,15 +21,15 @@
<select id="selectProject" parameterType="String" resultMap="resourceResultMap">
select * from projects
- where uuid=#{uuid,jdbcType=VARCHAR}
+ where uuid = #{uuid,jdbcType=VARCHAR}
</select>
<select id="selectProjectResources" parameterType="String" resultMap="resourceResultMap">
select * from projects
where
- root_uuid=#{rootUuid,jdbcType=VARCHAR}
- and scope!='PRJ'
- and enabled=${_true}
+ root_uuid = #{rootUuid,jdbcType=VARCHAR}
+ and scope != 'PRJ'
+ and enabled = ${_true}
</select>
<select id="selectDescendantProjects" parameterType="String" resultMap="resourceResultMap">
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml
index f9a99818714..fecf8cf8715 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml
@@ -425,7 +425,7 @@
p.enabled=${_true}
and p.copy_component_uuid is null
<if test="projectUuid != null">
- and p.project_uuid=#{projectUuid,jdbcType=VARCHAR}
+ and p.project_uuid = #{projectUuid,jdbcType=VARCHAR}
</if>
</select>
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java
index 8dd4bbcadce..f8305553ee9 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java
@@ -56,6 +56,7 @@ public class ComponentKeyUpdaterDaoTest {
db.prepareDbUnit(getClass(), "shared.xml");
underTest.updateKey(dbSession, "B", "struts:core");
+ dbSession.commit();
db.assertDbUnit(getClass(), "shouldUpdateKey-result.xml", "projects");
}
@@ -70,7 +71,7 @@ public class ComponentKeyUpdaterDaoTest {
db.components().insertComponent(newFileDto(project, inactiveDirectory).setKey("my_project:inactive_directory/file").setEnabled(false));
underTest.updateKey(dbSession, "A", "your_project");
- db.commit();
+ dbSession.commit();
List<ComponentDto> result = dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, "your_project");
assertThat(result).hasSize(5).extracting(ComponentDto::getKey)
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentCleanerService.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentCleanerService.java
index 33d357e3a75..8c840c4749d 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentCleanerService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentCleanerService.java
@@ -56,7 +56,7 @@ public class ComponentCleanerService {
throw new IllegalArgumentException("Only projects can be deleted");
}
dbClient.purgeDao().deleteRootComponent(dbSession, project.uuid());
- projectIndexers.commitAndIndex(dbSession, singletonList(project.uuid()), ProjectIndexer.Cause.PROJECT_DELETION);
+ projectIndexers.commitAndIndex(dbSession, singletonList(project), ProjectIndexer.Cause.PROJECT_DELETION);
}
private static boolean hasNotProjectScope(ComponentDto project) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java
index 1cf8b58feff..6c015fb1259 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java
@@ -46,18 +46,18 @@ public class ComponentService {
}
// TODO should be moved to UpdateKeyAction
- public void updateKey(DbSession dbSession, ComponentDto component, String newKey) {
- userSession.checkComponentPermission(UserRole.ADMIN, component);
- checkIsProjectOrModule(component);
+ public void updateKey(DbSession dbSession, ComponentDto projectOrModule, String newKey) {
+ userSession.checkComponentPermission(UserRole.ADMIN, projectOrModule);
+ checkIsProjectOrModule(projectOrModule);
checkProjectOrModuleKeyFormat(newKey);
- dbClient.componentKeyUpdaterDao().updateKey(dbSession, component.uuid(), newKey);
- projectIndexers.commitAndIndex(dbSession, singletonList(component.uuid()), ProjectIndexer.Cause.PROJECT_KEY_UPDATE);
+ dbClient.componentKeyUpdaterDao().updateKey(dbSession, projectOrModule.uuid(), newKey);
+ projectIndexers.commitAndIndex(dbSession, singletonList(projectOrModule), ProjectIndexer.Cause.PROJECT_KEY_UPDATE);
}
// TODO should be moved to BulkUpdateKeyAction
- public void bulkUpdateKey(DbSession dbSession, String projectUuid, String stringToReplace, String replacementString) {
- dbClient.componentKeyUpdaterDao().bulkUpdateKey(dbSession, projectUuid, stringToReplace, replacementString);
- projectIndexers.commitAndIndex(dbSession, singletonList(projectUuid), ProjectIndexer.Cause.PROJECT_KEY_UPDATE);
+ public void bulkUpdateKey(DbSession dbSession, ComponentDto projectOrModule, String stringToReplace, String replacementString) {
+ dbClient.componentKeyUpdaterDao().bulkUpdateKey(dbSession, projectOrModule.uuid(), stringToReplace, replacementString);
+ projectIndexers.commitAndIndex(dbSession, singletonList(projectOrModule), ProjectIndexer.Cause.PROJECT_KEY_UPDATE);
}
private static void checkProjectOrModuleKeyFormat(String key) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java
index 115a7e28f4a..fdb5dddf2e3 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java
@@ -72,7 +72,7 @@ public class ComponentUpdater {
ComponentDto componentDto = createRootComponent(dbSession, newComponent);
removeDuplicatedProjects(dbSession, componentDto.getKey());
handlePermissionTemplate(dbSession, componentDto, newComponent.getOrganizationUuid(), userId);
- projectIndexers.commitAndIndex(dbSession, singletonList(componentDto.uuid()), Cause.PROJECT_CREATION);
+ projectIndexers.commitAndIndex(dbSession, singletonList(componentDto), Cause.PROJECT_CREATION);
return componentDto;
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/ProjectIndexers.java b/server/sonar-server/src/main/java/org/sonar/server/es/ProjectIndexers.java
index 51a9b34bd76..c582dfb73b3 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/es/ProjectIndexers.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/es/ProjectIndexers.java
@@ -20,13 +20,24 @@
package org.sonar.server.es;
import java.util.Collection;
+import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbSession;
+import org.sonar.db.component.ComponentDto;
public interface ProjectIndexers {
/**
* Commits the DB transaction and indexes the specified projects, if needed (according to
* "cause" parameter).
+ * IMPORTANT - UUIDs must relate to projects only. Modules, directories and files are forbidden
+ * and will lead to lack of indexing.
*/
- void commitAndIndex(DbSession dbSession, Collection<String> projectUuid, ProjectIndexer.Cause cause);
+ void commitAndIndexByProjectUuids(DbSession dbSession, Collection<String> projectUuids, ProjectIndexer.Cause cause);
+
+ default void commitAndIndex(DbSession dbSession, Collection<ComponentDto> projectOrModules, ProjectIndexer.Cause cause) {
+ Collection<String> projectUuids = projectOrModules.stream()
+ .map(ComponentDto::projectUuid)
+ .collect(MoreCollectors.toSet(projectOrModules.size()));
+ commitAndIndexByProjectUuids(dbSession, projectUuids, cause);
+ }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/ProjectIndexersImpl.java b/server/sonar-server/src/main/java/org/sonar/server/es/ProjectIndexersImpl.java
index d26ba078d9c..553622ead1b 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/es/ProjectIndexersImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/es/ProjectIndexersImpl.java
@@ -38,7 +38,7 @@ public class ProjectIndexersImpl implements ProjectIndexers {
}
@Override
- public void commitAndIndex(DbSession dbSession, Collection<String> projectUuids, ProjectIndexer.Cause cause) {
+ public void commitAndIndexByProjectUuids(DbSession dbSession, Collection<String> projectUuids, ProjectIndexer.Cause cause) {
Map<ProjectIndexer, Collection<EsQueueDto>> itemsByIndexer = new IdentityHashMap<>();
indexers.forEach(i -> itemsByIndexer.put(i, i.prepareForRecovery(dbSession, projectUuids, cause)));
dbSession.commit();
diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java
index 82735ce115f..ddfcaabc81b 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java
@@ -32,7 +32,6 @@ import org.sonar.api.resources.Qualifiers;
import org.sonar.api.server.ServerSide;
import org.sonar.core.component.ComponentKeys;
import org.sonar.core.permission.ProjectPermissions;
-import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
@@ -104,7 +103,7 @@ public class PermissionTemplateService {
for (ComponentDto project : projects) {
copyPermissions(dbSession, template, project, null);
}
- projectIndexers.commitAndIndex(dbSession, projects.stream().map(ComponentDto::uuid).collect(MoreCollectors.toList()), ProjectIndexer.Cause.PERMISSION_CHANGE);
+ projectIndexers.commitAndIndex(dbSession, projects, ProjectIndexer.Cause.PERMISSION_CHANGE);
}
/**
diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionUpdater.java
index 9238fd5e36e..126ba94a36c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionUpdater.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionUpdater.java
@@ -43,7 +43,7 @@ public class PermissionUpdater {
private final GroupPermissionChanger groupPermissionChanger;
public PermissionUpdater(DbClient dbClient, ProjectIndexers projectIndexers,
- UserPermissionChanger userPermissionChanger, GroupPermissionChanger groupPermissionChanger) {
+ UserPermissionChanger userPermissionChanger, GroupPermissionChanger groupPermissionChanger) {
this.dbClient = dbClient;
this.projectIndexers = projectIndexers;
this.userPermissionChanger = userPermissionChanger;
@@ -65,7 +65,7 @@ public class PermissionUpdater {
dbClient.resourceDao().updateAuthorizationDate(projectId, dbSession);
}
- projectIndexers.commitAndIndex(dbSession, projectOrViewUuids, ProjectIndexer.Cause.PERMISSION_CHANGE);
+ projectIndexers.commitAndIndexByProjectUuids(dbSession, projectOrViewUuids, ProjectIndexer.Cause.PERMISSION_CHANGE);
}
private boolean doApply(DbSession dbSession, PermissionChange change) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkUpdateKeyAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkUpdateKeyAction.java
index 890571e70ba..106a9db3a6c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkUpdateKeyAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkUpdateKeyAction.java
@@ -154,8 +154,7 @@ public class BulkUpdateKeyAction implements ProjectsWsAction {
}
private void bulkUpdateKey(DbSession dbSession, BulkUpdateKeyWsRequest request, ComponentDto projectOrModule) {
- componentService.bulkUpdateKey(dbSession, projectOrModule.uuid(), request.getFrom(), request.getTo());
- dbSession.commit();
+ componentService.bulkUpdateKey(dbSession, projectOrModule, request.getFrom(), request.getTo());
}
private static BulkUpdateKeyWsResponse buildResponse(Map<String, String> newKeysByOldKeys, Map<String, Boolean> newKeysWithDuplicateMap) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java
index d845d695d89..4364f3c1cac 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java
@@ -101,7 +101,6 @@ public class UpdateKeyAction implements ProjectsWsAction {
try (DbSession dbSession = dbClient.openSession(false)) {
ComponentDto projectOrModule = componentFinder.getByUuidOrKey(dbSession, request.getId(), request.getKey(), ParamNames.PROJECT_ID_AND_FROM);
componentService.updateKey(dbSession, projectOrModule, request.getNewKey());
- dbSession.commit();
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java
index 990839e226c..95fb26c20e3 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java
@@ -109,7 +109,7 @@ public class UpdateVisibilityAction implements ProjectsWsAction {
} else {
updatePermissionsToPublic(dbSession, component);
}
- projectIndexers.commitAndIndex(dbSession, singletonList(component.uuid()), ProjectIndexer.Cause.PERMISSION_CHANGE);
+ projectIndexers.commitAndIndex(dbSession, singletonList(component), ProjectIndexer.Cause.PERMISSION_CHANGE);
}
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/projecttag/ws/SetAction.java b/server/sonar-server/src/main/java/org/sonar/server/projecttag/ws/SetAction.java
index 71fab7c6114..b46278cde7c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/projecttag/ws/SetAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/projecttag/ws/SetAction.java
@@ -99,7 +99,7 @@ public class SetAction implements ProjectTagsWsAction {
project.setTags(tags);
dbClient.componentDao().updateTags(dbSession, project);
- projectIndexers.commitAndIndex(dbSession, singletonList(project.uuid()), PROJECT_TAGS_UPDATE);
+ projectIndexers.commitAndIndex(dbSession, singletonList(project), PROJECT_TAGS_UPDATE);
}
response.noContent();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceTest.java
index b8928a8419f..7e63c6ec873 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceTest.java
@@ -60,7 +60,7 @@ public class ComponentServiceTest {
ComponentDto file = componentDb.insertComponent(newFileDto(module, null).setKey("my_project:root:module:src/File.xoo"));
ComponentDto inactiveFile = componentDb.insertComponent(newFileDto(module, null).setKey("my_project:root:module:src/InactiveFile.xoo").setEnabled(false));
- underTest.bulkUpdateKey(dbSession, project.uuid(), "my_", "your_");
+ underTest.bulkUpdateKey(dbSession, project, "my_", "your_");
assertComponentKeyUpdated(project.key(), "your_project");
assertComponentKeyUpdated(module.key(), "your_project:root:module");
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java
index b4208705488..22334b55a58 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java
@@ -86,10 +86,9 @@ public class ComponentServiceUpdateKeyTest {
public void update_module_key() {
ComponentDto project = insertSampleRootProject();
ComponentDto module = ComponentTesting.newModuleDto(project).setKey("sample:root:module");
- dbClient.componentDao().insert(dbSession, module);
+ db.components().insertComponent(module);
ComponentDto file = ComponentTesting.newFileDto(module, null).setKey("sample:root:module:src/File.xoo");
- dbClient.componentDao().insert(dbSession, file);
- dbSession.commit();
+ db.components().insertComponent(file);
logInAsProjectAdministrator(project);
underTest.updateKey(dbSession, module, "sample:root2:module");
@@ -99,7 +98,8 @@ public class ComponentServiceUpdateKeyTest {
assertComponentKeyHasBeenUpdated(module.key(), "sample:root2:module");
assertComponentKeyHasBeenUpdated(file.key(), "sample:root2:module:src/File.xoo");
- org.assertj.core.api.Assertions.assertThat(projectIndexers.hasBeenCalled(module.uuid(), ProjectIndexer.Cause.PROJECT_KEY_UPDATE)).isTrue();
+ // do not index the module but the project
+ org.assertj.core.api.Assertions.assertThat(projectIndexers.hasBeenCalled(project.uuid(), ProjectIndexer.Cause.PROJECT_KEY_UPDATE)).isTrue();
}
@Test
@@ -180,7 +180,7 @@ public class ComponentServiceUpdateKeyTest {
ComponentDto file = componentDb.insertComponent(newFileDto(module, null).setKey("my_project:root:module:src/File.xoo"));
ComponentDto inactiveFile = componentDb.insertComponent(newFileDto(module, null).setKey("my_project:root:module:src/InactiveFile.xoo").setEnabled(false));
- underTest.bulkUpdateKey(dbSession, project.uuid(), "my_", "your_");
+ underTest.bulkUpdateKey(dbSession, project, "my_", "your_");
assertComponentKeyUpdated(project.key(), "your_project");
assertComponentKeyUpdated(module.key(), "your_project:root:module");
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexerTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexerTest.java
index 959ec117e9e..86874bb8fcc 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexerTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexerTest.java
@@ -184,6 +184,7 @@ public class ComponentIndexerTest {
ComponentDto project = db.components().insertPrivateProject();
ComponentDto file = db.components().insertComponent(newFileDto(project));
indexProject(project, PROJECT_CREATION);
+ assertThatIndexHasSize(2);
db.getDbClient().componentDao().delete(db.getSession(), project.getId());
db.getDbClient().componentDao().delete(db.getSession(), file.getId());
diff --git a/server/sonar-server/src/test/java/org/sonar/server/es/ProjectIndexersImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/es/ProjectIndexersImplTest.java
index 2d956778031..8ba6ddd9e81 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/es/ProjectIndexersImplTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/es/ProjectIndexersImplTest.java
@@ -19,14 +19,17 @@
*/
package org.sonar.server.es;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import java.util.Set;
import org.junit.Test;
import org.sonar.db.DbSession;
-import org.sonar.db.es.EsQueueDto;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.organization.OrganizationTesting;
+import org.sonar.server.es.ProjectIndexer.Cause;
-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;
@@ -34,54 +37,34 @@ import static org.mockito.Mockito.mock;
public class ProjectIndexersImplTest {
@Test
- public void commitAndIndex_calls_indexer_with_only_its_supported_items() {
- EsQueueDto item1a = EsQueueDto.create("fake/fake1", "P1");
- EsQueueDto item1b = EsQueueDto.create("fake/fake1", "P1");
- EsQueueDto item2 = EsQueueDto.create("fake/fake2", "P1");
- FakeIndexer indexer1 = new FakeIndexer(asList(item1a, item1b));
- FakeIndexer indexer2 = new FakeIndexer(singletonList(item2));
- DbSession dbSession = mock(DbSession.class);
+ public void commitAndIndex_indexes_project() {
+ OrganizationDto organization = OrganizationTesting.newOrganizationDto();
+ ComponentDto project = ComponentTesting.newPublicProjectDto(organization);
- ProjectIndexersImpl underTest = new ProjectIndexersImpl(indexer1, indexer2);
- underTest.commitAndIndex(dbSession, singletonList("P1"), ProjectIndexer.Cause.PROJECT_CREATION);
+ FakeIndexers underTest = new FakeIndexers();
+ underTest.commitAndIndex(mock(DbSession.class), singletonList(project), Cause.PROJECT_CREATION);
- assertThat(indexer1.calledItems).containsExactlyInAnyOrder(item1a, item1b);
- assertThat(indexer2.calledItems).containsExactlyInAnyOrder(item2);
+ assertThat(underTest.calls).containsExactly(project.uuid());
}
- private static class FakeIndexer implements ProjectIndexer {
-
- private final List<EsQueueDto> items;
- private Collection<EsQueueDto> calledItems;
-
- private FakeIndexer(List<EsQueueDto> items) {
- this.items = items;
- }
-
- @Override
- public void indexOnStartup(Set<IndexType> uninitializedIndexTypes) {
- throw new UnsupportedOperationException();
- }
+ @Test
+ public void commitAndIndex_of_module_indexes_the_project() {
+ OrganizationDto organization = OrganizationTesting.newOrganizationDto();
+ ComponentDto project = ComponentTesting.newPublicProjectDto(organization);
+ ComponentDto module = ComponentTesting.newModuleDto(project);
- @Override
- public Set<IndexType> getIndexTypes() {
- throw new UnsupportedOperationException();
- }
+ FakeIndexers underTest = new FakeIndexers();
+ underTest.commitAndIndex(mock(DbSession.class), singletonList(module), Cause.PROJECT_CREATION);
- @Override
- public Collection<EsQueueDto> prepareForRecovery(DbSession dbSession, Collection<String> projectUuids, Cause cause) {
- return items;
- }
+ assertThat(underTest.calls).containsExactly(project.uuid());
+ }
- @Override
- public IndexingResult index(DbSession dbSession, Collection<EsQueueDto> items) {
- this.calledItems = items;
- return new IndexingResult();
- }
+ private static class FakeIndexers implements ProjectIndexers {
+ private final List<String> calls = new ArrayList<>();
@Override
- public void indexOnAnalysis(String projectUuid) {
- throw new UnsupportedOperationException();
+ public void commitAndIndexByProjectUuids(DbSession dbSession, Collection<String> projectUuids, Cause cause) {
+ calls.addAll(projectUuids);
}
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/es/ProjectIndexersTest.java b/server/sonar-server/src/test/java/org/sonar/server/es/ProjectIndexersTest.java
new file mode 100644
index 00000000000..9ec69689c1b
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/es/ProjectIndexersTest.java
@@ -0,0 +1,92 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.es;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import org.junit.Test;
+import org.sonar.db.DbSession;
+import org.sonar.db.es.EsQueueDto;
+
+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;
+
+public class ProjectIndexersTest {
+
+ @Test
+ public void commitAndIndexByProjectUuids_calls_indexer_with_only_its_supported_items() {
+ EsQueueDto item1a = EsQueueDto.create("fake/fake1", "P1");
+ EsQueueDto item1b = EsQueueDto.create("fake/fake1", "P1");
+ EsQueueDto item2 = EsQueueDto.create("fake/fake2", "P1");
+ FakeIndexer indexer1 = new FakeIndexer(asList(item1a, item1b));
+ FakeIndexer indexer2 = new FakeIndexer(singletonList(item2));
+ DbSession dbSession = mock(DbSession.class);
+
+ ProjectIndexersImpl underTest = new ProjectIndexersImpl(indexer1, indexer2);
+ underTest.commitAndIndexByProjectUuids(dbSession, singletonList("P1"), ProjectIndexer.Cause.PROJECT_CREATION);
+
+ assertThat(indexer1.calledItems).containsExactlyInAnyOrder(item1a, item1b);
+ assertThat(indexer2.calledItems).containsExactlyInAnyOrder(item2);
+ }
+
+ @Test
+ public void commitAndIndex_restricts_indexing_to_projects() {
+ // TODO
+ }
+
+ private static class FakeIndexer implements ProjectIndexer {
+
+ private final List<EsQueueDto> items;
+ private Collection<EsQueueDto> calledItems;
+
+ private FakeIndexer(List<EsQueueDto> items) {
+ this.items = items;
+ }
+
+ @Override
+ public void indexOnStartup(Set<IndexType> uninitializedIndexTypes) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<IndexType> getIndexTypes() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Collection<EsQueueDto> prepareForRecovery(DbSession dbSession, Collection<String> projectUuids, Cause cause) {
+ return items;
+ }
+
+ @Override
+ public IndexingResult index(DbSession dbSession, Collection<EsQueueDto> items) {
+ this.calledItems = items;
+ return new IndexingResult();
+ }
+
+ @Override
+ public void indexOnAnalysis(String projectUuid) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/es/TestProjectIndexers.java b/server/sonar-server/src/test/java/org/sonar/server/es/TestProjectIndexers.java
index 957612a0588..173ced760da 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/es/TestProjectIndexers.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/es/TestProjectIndexers.java
@@ -29,7 +29,7 @@ public class TestProjectIndexers implements ProjectIndexers {
private final ListMultimap<String, ProjectIndexer.Cause> calls = ArrayListMultimap.create();
@Override
- public void commitAndIndex(DbSession dbSession, Collection<String> projectUuids, ProjectIndexer.Cause cause) {
+ public void commitAndIndexByProjectUuids(DbSession dbSession, Collection<String> projectUuids, ProjectIndexer.Cause cause) {
dbSession.commit();
projectUuids.forEach(projectUuid -> calls.put(projectUuid, cause));
diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkUpdateKeyActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkUpdateKeyActionTest.java
index ddf60c51689..632813f071f 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkUpdateKeyActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkUpdateKeyActionTest.java
@@ -140,7 +140,7 @@ public class BulkUpdateKeyActionTest {
tuple(project.key(), "your_project", false),
tuple(module.key(), "your_project:root:module", false));
- verify(componentService).bulkUpdateKey(any(DbSession.class), eq(project.uuid()), eq(FROM), eq(TO));
+ verify(componentService).bulkUpdateKey(any(DbSession.class), eq(project), eq(FROM), eq(TO));
}
@Test
@@ -150,7 +150,7 @@ public class BulkUpdateKeyActionTest {
callByKey(provisionedProject.key(), provisionedProject.getKey(), newKey);
- verify(componentService).bulkUpdateKey(any(DbSession.class), eq(provisionedProject.uuid()), eq(provisionedProject.getKey()), eq(newKey));
+ verify(componentService).bulkUpdateKey(any(DbSession.class), eq(provisionedProject), eq(provisionedProject.getKey()), eq(newKey));
}
@Test
diff --git a/tests/src/test/java/org/sonarqube/tests/Category6Suite.java b/tests/src/test/java/org/sonarqube/tests/Category6Suite.java
index cf02b593415..ab947ec17e7 100644
--- a/tests/src/test/java/org/sonarqube/tests/Category6Suite.java
+++ b/tests/src/test/java/org/sonarqube/tests/Category6Suite.java
@@ -34,6 +34,7 @@ import org.sonarqube.tests.organization.OrganizationTest;
import org.sonarqube.tests.organization.PersonalOrganizationTest;
import org.sonarqube.tests.organization.RootUserOnOrganizationTest;
import org.sonarqube.tests.projectAdministration.ProjectDeletionTest;
+import org.sonarqube.tests.projectAdministration.ProjectKeyUpdateTest;
import org.sonarqube.tests.projectAdministration.ProjectProvisioningTest;
import org.sonarqube.tests.projectSearch.LeakProjectsPageTest;
import org.sonarqube.tests.projectSearch.SearchProjectsTest;
@@ -71,7 +72,8 @@ import static util.ItUtils.xooPlugin;
SearchProjectsTest.class,
RulesWsTest.class,
ProjectDeletionTest.class,
- ProjectProvisioningTest.class
+ ProjectProvisioningTest.class,
+ ProjectKeyUpdateTest.class
})
public class Category6Suite {
diff --git a/tests/src/test/java/org/sonarqube/tests/Elasticsearch.java b/tests/src/test/java/org/sonarqube/tests/Elasticsearch.java
index 60df943b9b1..a19d9708a92 100644
--- a/tests/src/test/java/org/sonarqube/tests/Elasticsearch.java
+++ b/tests/src/test/java/org/sonarqube/tests/Elasticsearch.java
@@ -1,3 +1,22 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
package org.sonarqube.tests;
import java.net.InetAddress;
diff --git a/tests/src/test/java/org/sonarqube/tests/projectAdministration/ProjectKeyPageTest.java b/tests/src/test/java/org/sonarqube/tests/projectAdministration/ProjectKeyUpdatePageTest.java
index a1d7f61aba1..fb9572d3748 100644
--- a/tests/src/test/java/org/sonarqube/tests/projectAdministration/ProjectKeyPageTest.java
+++ b/tests/src/test/java/org/sonarqube/tests/projectAdministration/ProjectKeyUpdatePageTest.java
@@ -38,7 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static util.ItUtils.newAdminWsClient;
import static util.ItUtils.projectDir;
-public class ProjectKeyPageTest {
+public class ProjectKeyUpdatePageTest {
@ClassRule
public static Orchestrator ORCHESTRATOR = Category1Suite.ORCHESTRATOR;
diff --git a/tests/src/test/java/org/sonarqube/tests/projectAdministration/ProjectKeyUpdateTest.java b/tests/src/test/java/org/sonarqube/tests/projectAdministration/ProjectKeyUpdateTest.java
new file mode 100644
index 00000000000..275552cf3ec
--- /dev/null
+++ b/tests/src/test/java/org/sonarqube/tests/projectAdministration/ProjectKeyUpdateTest.java
@@ -0,0 +1,254 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonarqube.tests.projectAdministration;
+
+import com.sonar.orchestrator.Orchestrator;
+import com.sonar.orchestrator.build.SonarScanner;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import javax.annotation.CheckForNull;
+import org.junit.After;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.DisableOnDebug;
+import org.junit.rules.TestRule;
+import org.junit.rules.Timeout;
+import org.sonarqube.tests.Category6Suite;
+import org.sonarqube.tests.Tester;
+import org.sonarqube.ws.Organizations;
+import org.sonarqube.ws.WsComponents;
+import org.sonarqube.ws.WsProjects;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.WsResponse;
+import org.sonarqube.ws.client.component.SearchProjectsRequest;
+import org.sonarqube.ws.client.project.CreateRequest;
+import org.sonarqube.ws.client.project.SearchWsRequest;
+import org.sonarqube.ws.client.project.UpdateKeyWsRequest;
+import util.ItUtils;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static util.ItUtils.projectDir;
+
+public class ProjectKeyUpdateTest {
+
+ @ClassRule
+ public static final Orchestrator orchestrator = Category6Suite.ORCHESTRATOR;
+
+ @Rule
+ public TestRule safeguard = new DisableOnDebug(Timeout.seconds(300));
+ @Rule
+ public Tester tester = new Tester(orchestrator)
+ .setElasticsearchHttpPort(Category6Suite.SEARCH_HTTP_PORT);
+
+ @After
+ public void tearDown() throws Exception {
+ unlockWritesOnProjectIndices();
+ }
+
+ @Test
+ public void update_key_of_provisioned_project() {
+ Organizations.Organization organization = tester.organizations().generate();
+ WsProjects.CreateWsResponse.Project project = createProject(organization, "one", "Foo");
+
+ updateKey(project, "two");
+
+ assertThat(isInProjectsSearch(organization, "one")).isFalse();
+ assertThat(isInProjectsSearch(organization, "two")).isTrue();
+ assertThat(isInComponentSearch(organization, "one")).isFalse();
+ assertThat(isInComponentSearch(organization, "two")).isTrue();
+ assertThat(keyInComponentSearchProjects("Foo")).isEqualTo("two");
+ assertThat(keysInComponentSuggestions("Foo")).containsExactly("two");
+ }
+
+ @Test
+ public void recover_indexing_errors_when_updating_key_of_provisioned_project() throws Exception {
+ Organizations.Organization organization = tester.organizations().generate();
+ WsProjects.CreateWsResponse.Project project = createProject(organization, "one", "Foo");
+
+ lockWritesOnProjectIndices();
+
+ updateKey(project, "two");
+
+ assertThat(isInProjectsSearch(organization, "one")).isFalse();
+
+ // WS gets the list of projects from ES then reloads projects from db.
+ // That's why keys in WS responses are correct.
+ assertThat(isInProjectsSearch(organization, "one")).isFalse();
+ assertThat(isInProjectsSearch(organization, "two")).isTrue();
+ assertThat(keyInComponentSearchProjects("Foo")).isEqualTo("two");
+ assertThat(keysInComponentSuggestions("Foo")).containsExactly("two");
+
+ // however searching by key is inconsistent
+ assertThat(keyInComponentSearchProjects("one")).isEqualTo("two");
+ assertThat(keysInComponentSuggestions("one")).containsExactly("two");
+ assertThat(keyInComponentSearchProjects("two")).isNull();
+ assertThat(keysInComponentSuggestions("two")).isEmpty();
+
+ unlockWritesOnProjectIndices();
+
+ boolean recovered = false;
+ while (!recovered) {
+ // recovery daemon runs every second, see Category6Suite
+ Thread.sleep(1_000L);
+ recovered = keyInComponentSearchProjects("one") == null &&
+ keysInComponentSuggestions("one").isEmpty() &&
+ "two".equals(keyInComponentSearchProjects("two")) &&
+ keysInComponentSuggestions("two").contains("two");
+ }
+ }
+
+ @Test
+ public void update_key_of_module() {
+ Organizations.Organization organization = tester.organizations().generate();
+ orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-multi-modules-sample"),
+ "sonar.organization", organization.getKey(),
+ "sonar.login", "admin", "sonar.password", "admin"));
+
+ String initialKey = "com.sonarsource.it.samples:multi-modules-sample:module_a";
+ String newKey = "com.sonarsource.it.samples:multi-modules-sample:module_c";
+
+ updateKey(initialKey, newKey);
+
+ assertThat(isInComponentSearch(organization, initialKey)).isFalse();
+ assertThat(isInComponentSearch(organization, newKey)).isTrue();
+ // suggestions engine ignores one-character words, so we can't search for "Module A"
+ assertThat(keysInComponentSuggestions("Module"))
+ .contains(newKey)
+ .doesNotContain(initialKey);
+ assertThat(keysInComponentSuggestions(newKey))
+ .contains(newKey)
+ .doesNotContain(initialKey);
+ assertThat(keysInComponentSuggestions(initialKey)).isEmpty();
+
+ }
+
+ @Test
+ public void recover_indexing_errors_when_updating_key_of_module() throws Exception {
+ Organizations.Organization organization = tester.organizations().generate();
+ orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-multi-modules-sample"),
+ "sonar.organization", organization.getKey(),
+ "sonar.login", "admin", "sonar.password", "admin"));
+
+ String initialKey = "com.sonarsource.it.samples:multi-modules-sample:module_a";
+ String newKey = "com.sonarsource.it.samples:multi-modules-sample:module_c";
+
+ lockWritesOnProjectIndices();
+ updateKey(initialKey, newKey);
+
+ // api/components/search loads keys from db, so results are consistent
+ assertThat(isInComponentSearch(organization, initialKey)).isFalse();
+ assertThat(isInComponentSearch(organization, newKey)).isTrue();
+
+ // key in result of suggestion engine is loaded from db, so results are ok when searching for unchanged name
+ assertThat(keysInComponentSuggestions("Module"))
+ .contains(newKey)
+ .doesNotContain(initialKey);
+
+ // but searching for new key does not work
+ assertThat(keysInComponentSuggestions(newKey)).isEmpty();
+ assertThat(keysInComponentSuggestions(initialKey))
+ .isNotEmpty()
+ .contains(newKey /* the returned key is loaded from db, so it's correct */);
+
+ unlockWritesOnProjectIndices();
+
+ boolean recovered = false;
+ while (!recovered) {
+ // recovery daemon runs every second, see Category6Suite
+ Thread.sleep(1_000L);
+ recovered = keysInComponentSuggestions(newKey).contains(newKey) && keysInComponentSuggestions(initialKey).isEmpty();
+ }
+
+ }
+
+ private void lockWritesOnProjectIndices() throws Exception {
+ tester.elasticsearch().lockWrites("components");
+ tester.elasticsearch().lockWrites("projectmeasures");
+ }
+
+
+ private void unlockWritesOnProjectIndices() throws Exception {
+ tester.elasticsearch().unlockWrites("components");
+ tester.elasticsearch().unlockWrites("projectmeasures");
+ }
+
+ private void updateKey(WsProjects.CreateWsResponse.Project project, String newKey) {
+ tester.wsClient().projects().updateKey(UpdateKeyWsRequest.builder().setKey(project.getKey()).setNewKey(newKey).build());
+ }
+
+ private void updateKey(String initialKey, String newKey) {
+ tester.wsClient().projects().updateKey(UpdateKeyWsRequest.builder().setKey(initialKey).setNewKey(newKey).build());
+ }
+
+ private WsProjects.CreateWsResponse.Project createProject(Organizations.Organization organization, String key, String name) {
+ CreateRequest createRequest = CreateRequest.builder().setKey(key).setName(name).setOrganization(organization.getKey()).build();
+ return tester.wsClient().projects().create(createRequest).getProject();
+ }
+
+ /**
+ * Projects administration page - uses database
+ */
+ private boolean isInProjectsSearch(Organizations.Organization organization, String key) {
+ WsProjects.SearchWsResponse response = tester.wsClient().projects().search(
+ SearchWsRequest.builder().setOrganization(organization.getKey()).setQuery(key).setQualifiers(singletonList("TRK")).build());
+ return response.getComponentsCount() > 0;
+ }
+
+ private boolean isInComponentSearch(Organizations.Organization organization, String key) {
+ org.sonarqube.ws.client.component.SearchWsRequest request = new org.sonarqube.ws.client.component.SearchWsRequest()
+ .setQualifiers(asList("TRK", "BRC"))
+ .setQuery(key)
+ .setOrganization(organization.getKey());
+ return tester.wsClient().components().search(request).getComponentsCount() == 1L;
+ }
+
+ /**
+ * Projects page - api/components/search_projects - uses ES + DB
+ */
+ @CheckForNull
+ private String keyInComponentSearchProjects(String name) {
+ WsComponents.SearchProjectsWsResponse response = tester.wsClient().components().searchProjects(
+ SearchProjectsRequest.builder().setFilter("query=\"" + name + "\"").build());
+ if (response.getComponentsCount() > 0) {
+ return response.getComponents(0).getKey();
+ }
+ return null;
+ }
+
+ /**
+ * Top-right search engine - api/components/suggestions - uses ES + DB
+ */
+ private List<String> keysInComponentSuggestions(String name) {
+ GetRequest request = new GetRequest("api/components/suggestions").setParam("s", name);
+ WsResponse response = tester.wsClient().wsConnector().call(request);
+ Map<String, Object> json = ItUtils.jsonToMap(response.content());
+ Collection<Map<String, Object>> results = (Collection<Map<String, Object>>) json.get("results");
+ return results.stream()
+ .filter(map -> "TRK".equals(map.get("q")) || "BRC".equals(map.get("q")))
+ .flatMap(map -> ((Collection<Map<String, Object>>) map.get("items")).stream())
+ .map(map -> (String) map.get("key"))
+ .collect(Collectors.toList());
+ }
+}