aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2016-10-18 17:44:48 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2016-10-20 13:12:07 +0200
commitac8031ea04ac687ebde118919d7a079ed9ebc609 (patch)
treeb7ae9b983bc05994d326ceb61b3d19f877421a70 /server/sonar-server
parent980460baadab04da9a1092fe15c22a716af3d1bc (diff)
downloadsonarqube-ac8031ea04ac687ebde118919d7a079ed9ebc609.tar.gz
sonarqube-ac8031ea04ac687ebde118919d7a079ed9ebc609.zip
SONAR-8227 Index project measures authorization
Diffstat (limited to 'server/sonar-server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/es/IndexerStartupTask.java8
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/permission/index/AuthorizationDao.java13
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/permission/index/AuthorizationIndexer.java165
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java10
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ApplyPermissionsStepTest.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java13
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java9
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationDaoTest.java11
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationIndexerTest.java58
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationIndexerTester.java44
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java3
11 files changed, 233 insertions, 104 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/IndexerStartupTask.java b/server/sonar-server/src/main/java/org/sonar/server/es/IndexerStartupTask.java
index aba3ca3c003..f73bfeaac9d 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/es/IndexerStartupTask.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/es/IndexerStartupTask.java
@@ -22,9 +22,9 @@ package org.sonar.server.es;
import org.sonar.api.config.Settings;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
+import org.sonar.server.component.es.ProjectMeasuresIndexer;
import org.sonar.server.issue.index.IssueIndexer;
import org.sonar.server.permission.index.AuthorizationIndexer;
-import org.sonar.server.component.es.ProjectMeasuresIndexer;
import org.sonar.server.test.index.TestIndexer;
import org.sonar.server.user.index.UserIndexer;
import org.sonar.server.view.index.ViewIndexer;
@@ -47,8 +47,8 @@ public class IndexerStartupTask {
* {@link org.sonar.server.issue.index.IssueIndexer}
*/
public IndexerStartupTask(TestIndexer testIndexer, AuthorizationIndexer authorizationIndexer, IssueIndexer issueIndexer,
- UserIndexer userIndexer, ViewIndexer viewIndexer, ProjectMeasuresIndexer projectMeasuresIndexer,
- Settings settings) {
+ UserIndexer userIndexer, ViewIndexer viewIndexer, ProjectMeasuresIndexer projectMeasuresIndexer,
+ Settings settings) {
this.testIndexer = testIndexer;
this.authorizationIndexer = authorizationIndexer;
this.issueIndexer = issueIndexer;
@@ -62,7 +62,7 @@ public class IndexerStartupTask {
if (!settings.getBoolean("sonar.internal.es.disableIndexes")) {
LOG.info("Index authorization");
- authorizationIndexer.index();
+ authorizationIndexer.indexAllIfEmpty();
LOG.info("Index issues");
issueIndexer.index();
diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/index/AuthorizationDao.java b/server/sonar-server/src/main/java/org/sonar/server/permission/index/AuthorizationDao.java
index b585a05e35f..a3b848471db 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/permission/index/AuthorizationDao.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/permission/index/AuthorizationDao.java
@@ -148,14 +148,15 @@ public class AuthorizationDao {
" AND group_roles.group_id IS NULL " +
" ) project_authorization";
- List<Dto> selectAfterDate(DbClient dbClient, DbSession session, List<String> projectUuids) {
- if (projectUuids.isEmpty()) {
- return doSelectAfterDate(dbClient, session, Collections.emptyList());
- }
- return executeLargeInputs(projectUuids, subProjectUuids -> doSelectAfterDate(dbClient, session, subProjectUuids));
+ List<Dto> selectAll(DbClient dbClient, DbSession session) {
+ return doSelectByProjects(dbClient, session, Collections.emptyList());
+ }
+
+ List<Dto> selectByProjects(DbClient dbClient, DbSession session, List<String> projectUuids) {
+ return executeLargeInputs(projectUuids, subProjectUuids -> doSelectByProjects(dbClient, session, subProjectUuids));
}
- private List<Dto> doSelectAfterDate(DbClient dbClient, DbSession session, List<String> projectUuids) {
+ private static List<Dto> doSelectByProjects(DbClient dbClient, DbSession session, List<String> projectUuids) {
try {
Map<String, Dto> dtosByProjectUuid = new HashMap<>();
PreparedStatement stmt = null;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/index/AuthorizationIndexer.java b/server/sonar-server/src/main/java/org/sonar/server/permission/index/AuthorizationIndexer.java
index 614a689bbf5..7ed91cbc758 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/permission/index/AuthorizationIndexer.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/permission/index/AuthorizationIndexer.java
@@ -20,28 +20,33 @@
package org.sonar.server.permission.index;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.Uninterruptibles;
import java.util.Collection;
-import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.index.IndexRequest;
+import org.elasticsearch.action.search.SearchResponse;
+import org.picocontainer.Startable;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.server.es.BaseIndexer;
+import org.sonar.server.component.es.ProjectMeasuresIndexDefinition;
import org.sonar.server.es.BulkIndexer;
import org.sonar.server.es.EsClient;
+import org.sonar.server.es.EsUtils;
+import org.sonar.server.issue.index.IssueIndexDefinition;
import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Arrays.asList;
-import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_AUTHORIZATION_GROUPS;
-import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID;
-import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT;
-import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_AUTHORIZATION_USERS;
-import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_TECHNICAL_UPDATED_AT;
-import static org.sonar.server.issue.index.IssueIndexDefinition.INDEX;
-import static org.sonar.server.issue.index.IssueIndexDefinition.TYPE_AUTHORIZATION;
+import static java.util.Collections.singletonList;
+import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
/**
* Manages the synchronization of index issues/authorization with authorization settings defined in database :
@@ -50,76 +55,148 @@ import static org.sonar.server.issue.index.IssueIndexDefinition.TYPE_AUTHORIZATI
* <li>delete project orphans from index</li>
* </ul>
*/
-public class AuthorizationIndexer extends BaseIndexer {
+public class AuthorizationIndexer implements Startable {
+ private static final int MAX_BATCH_SIZE = 1000;
+
+ private static final String BULK_ERROR_MESSAGE = "Fail to index authorization";
+
+ private final ThreadPoolExecutor executor;
private final DbClient dbClient;
+ private final EsClient esClient;
public AuthorizationIndexer(DbClient dbClient, EsClient esClient) {
- super(esClient, 0L, INDEX, TYPE_AUTHORIZATION, FIELD_ISSUE_TECHNICAL_UPDATED_AT);
+ this.executor = new ThreadPoolExecutor(0, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
this.dbClient = dbClient;
+ this.esClient = esClient;
}
- @Override
- protected long doIndex(long lastUpdatedAt) {
- return doIndex(createBulkIndexer(), Collections.<String>emptyList());
+ /**
+ * Index issues authorization and project measures authorization indexes only when they are empty
+ */
+ public void indexAllIfEmpty() {
+ Future submit = executor.submit(() -> {
+ if (isIndexEmpty(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION) ||
+ isIndexEmpty(ProjectMeasuresIndexDefinition.TYPE_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION)) {
+ truncate(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION);
+ truncate(ProjectMeasuresIndexDefinition.TYPE_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION);
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ index(new AuthorizationDao().selectAll(dbClient, dbSession));
+ }
+ }
+ });
+ try {
+ Uninterruptibles.getUninterruptibly(submit);
+ } catch (ExecutionException e) {
+ Throwables.propagate(e);
+ }
}
- public void index(String projectUuid) {
- index(asList(projectUuid));
+ private boolean isIndexEmpty(String index, String type) {
+ SearchResponse issuesAuthorizationResponse = esClient.prepareSearch(index).setTypes(type).setSize(0).get();
+ return issuesAuthorizationResponse.getHits().getTotalHits() == 0;
+ }
+
+ private void truncate(String index, String type) {
+ BulkIndexer.delete(esClient, index, esClient.prepareSearch(index).setTypes(type).setQuery(matchAllQuery()));
}
public void index(List<String> projectUuids) {
checkArgument(!projectUuids.isEmpty(), "ProjectUuids cannot be empty");
- super.index(lastUpdatedAt -> doIndex(createBulkIndexer(), projectUuids));
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ AuthorizationDao dao = new AuthorizationDao();
+ index(dao.selectByProjects(dbClient, dbSession, projectUuids));
+ }
}
- private long doIndex(BulkIndexer bulk, List<String> projectUuids) {
+ private void index(Collection<AuthorizationDao.Dto> authorizations) {
+ if (authorizations.isEmpty()) {
+ return;
+ }
+ int count = 0;
+ BulkRequestBuilder bulkRequest = esClient.prepareBulk().setRefresh(false);
+ for (AuthorizationDao.Dto dto : authorizations) {
+ bulkRequest.add(newIssuesAuthorizationIndexRequest(dto));
+ bulkRequest.add(newProjectMeasuresAuthorizationIndexRequest(dto));
+ count++;
+ if (count >= MAX_BATCH_SIZE) {
+ EsUtils.executeBulkRequest(bulkRequest, BULK_ERROR_MESSAGE);
+ bulkRequest = esClient.prepareBulk().setRefresh(false);
+ count = 0;
+ }
+ }
+ EsUtils.executeBulkRequest(bulkRequest, BULK_ERROR_MESSAGE);
+ esClient.prepareRefresh(IssueIndexDefinition.INDEX).get();
+ esClient.prepareRefresh(ProjectMeasuresIndexDefinition.TYPE_PROJECT_MEASURES).get();
+ }
+
+ public void index(String projectUuid) {
try (DbSession dbSession = dbClient.openSession(false)) {
AuthorizationDao dao = new AuthorizationDao();
- Collection<AuthorizationDao.Dto> authorizations = dao.selectAfterDate(dbClient, dbSession, projectUuids);
- return doIndex(bulk, authorizations);
+ List<AuthorizationDao.Dto> dtos = dao.selectByProjects(dbClient, dbSession, singletonList(projectUuid));
+ if (dtos.size() == 1) {
+ index(dtos.get(0));
+ }
}
}
@VisibleForTesting
- public void index(Collection<AuthorizationDao.Dto> authorizations) {
- final BulkIndexer bulk = new BulkIndexer(esClient, INDEX);
- doIndex(bulk, authorizations);
+ void index(AuthorizationDao.Dto dto) {
+ index(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, newIssuesAuthorizationIndexRequest(dto));
+ index(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, newProjectMeasuresAuthorizationIndexRequest(dto));
}
- private static long doIndex(BulkIndexer bulk, Collection<AuthorizationDao.Dto> authorizations) {
- long maxDate = 0L;
- bulk.start();
- for (AuthorizationDao.Dto authorization : authorizations) {
- bulk.add(newIndexRequest(authorization));
- maxDate = Math.max(maxDate, authorization.getUpdatedAt());
- }
- bulk.stop();
- return maxDate;
+ private void index(String index, String type, IndexRequest indexRequest) {
+ esClient.prepareIndex(index, type)
+ .setId(indexRequest.id())
+ .setRouting(indexRequest.routing())
+ .setSource(indexRequest.source())
+ .setRefresh(true)
+ .get();
}
public void deleteProject(String uuid, boolean refresh) {
esClient
- .prepareDelete(INDEX, TYPE_AUTHORIZATION, uuid)
+ .prepareDelete(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, uuid)
+ .setRefresh(refresh)
+ .setRouting(uuid)
+ .get();
+ esClient
+ .prepareDelete(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, uuid)
.setRefresh(refresh)
.setRouting(uuid)
.get();
}
- private BulkIndexer createBulkIndexer() {
- // warning - do not enable large mode, else disabling of replicas
- // will impact the type "issue" which is much bigger than issueAuthorization
- return new BulkIndexer(esClient, INDEX);
+ private static IndexRequest newIssuesAuthorizationIndexRequest(AuthorizationDao.Dto dto) {
+ Map<String, Object> doc = ImmutableMap.of(
+ IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, dto.getProjectUuid(),
+ IssueIndexDefinition.FIELD_AUTHORIZATION_GROUPS, dto.getGroups(),
+ IssueIndexDefinition.FIELD_AUTHORIZATION_USERS, dto.getUsers(),
+ IssueIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT, new Date(dto.getUpdatedAt()));
+ return new IndexRequest(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid())
+ .routing(dto.getProjectUuid())
+ .source(doc);
}
- private static IndexRequest newIndexRequest(AuthorizationDao.Dto dto) {
+ private static IndexRequest newProjectMeasuresAuthorizationIndexRequest(AuthorizationDao.Dto dto) {
Map<String, Object> doc = ImmutableMap.of(
- FIELD_AUTHORIZATION_PROJECT_UUID, dto.getProjectUuid(),
- FIELD_AUTHORIZATION_GROUPS, dto.getGroups(),
- FIELD_AUTHORIZATION_USERS, dto.getUsers(),
- FIELD_AUTHORIZATION_UPDATED_AT, new Date(dto.getUpdatedAt()));
- return new IndexRequest(INDEX, TYPE_AUTHORIZATION, dto.getProjectUuid())
+ ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, dto.getProjectUuid(),
+ ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_GROUPS, dto.getGroups(),
+ ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_USERS, dto.getUsers(),
+ ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT, new Date(dto.getUpdatedAt()));
+ return new IndexRequest(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid())
.routing(dto.getProjectUuid())
.source(doc);
}
+
+ @Override
+ public void start() {
+ // nothing to do at startup
+ }
+
+ @Override
+ public void stop() {
+ executor.shutdown();
+ }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java
index 62190745f3a..3260a53eee9 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java
@@ -43,13 +43,12 @@ import org.sonar.server.issue.index.IssueDoc;
import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.issue.index.IssueIndexDefinition;
import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.permission.index.AuthorizationDao;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.AuthorizationIndexerTester;
import org.sonar.server.platform.ServerFileSystem;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsTester;
-import static com.google.common.collect.Lists.newArrayList;
+import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -78,7 +77,7 @@ public class IssuesActionTest {
private IssueIndex issueIndex;
private IssueIndexer issueIndexer;
- private AuthorizationIndexer issueAuthorizationIndexer;
+ private AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(es);
private ServerFileSystem fs = mock(ServerFileSystem.class);
WsTester tester;
@@ -89,7 +88,6 @@ public class IssuesActionTest {
public void before() {
issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSessionRule);
issueIndexer = new IssueIndexer(null, es.client());
- issueAuthorizationIndexer = new AuthorizationIndexer(null, es.client());
issuesAction = new IssuesAction(db.getDbClient(), issueIndex, userSessionRule, new ComponentFinder(db.getDbClient()));
tester = new WsTester(new BatchWs(new BatchIndex(fs), issuesAction));
@@ -329,7 +327,7 @@ public class IssuesActionTest {
}
private void addIssueAuthorization(String projectUuid, @Nullable String group, @Nullable String user) {
- issueAuthorizationIndexer.index(newArrayList(new AuthorizationDao.Dto(projectUuid, 1).addGroup(group).addUser(user)));
+ authorizationIndexerTester.insertProjectAuthorization(projectUuid, singletonList(group), singletonList(user));
}
private void addBrowsePermissionOnComponent(String componentKey) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ApplyPermissionsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ApplyPermissionsStepTest.java
index d04968bacc1..e78f57338dd 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ApplyPermissionsStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ApplyPermissionsStepTest.java
@@ -35,6 +35,7 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.permission.PermissionRepository;
import org.sonar.db.permission.template.PermissionTemplateDto;
+import org.sonar.server.component.es.ProjectMeasuresIndexDefinition;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.MutableDbIdsRepositoryRule;
import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
@@ -61,7 +62,7 @@ public class ApplyPermissionsStepTest extends BaseStepTest {
private static final long SOME_DATE = 1000L;
@Rule
- public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()));
+ public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()), new ProjectMeasuresIndexDefinition(new MapSettings()));
@Rule
public DbTester dbTester = DbTester.create(System2.INSTANCE);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java
index 65117b830de..023db7a3177 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java
@@ -19,7 +19,6 @@
*/
package org.sonar.server.issue.index;
-import java.util.Arrays;
import java.util.Map;
import java.util.TimeZone;
import javax.annotation.Nullable;
@@ -41,13 +40,14 @@ import org.sonar.server.es.SearchResult;
import org.sonar.server.issue.IssueQuery;
import org.sonar.server.issue.IssueQuery.Builder;
import org.sonar.server.issue.IssueTesting;
-import org.sonar.server.permission.index.AuthorizationDao;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.AuthorizationIndexerTester;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.view.index.ViewIndexDefinition;
import org.sonar.server.view.index.ViewIndexer;
import static com.google.common.collect.Lists.newArrayList;
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.mockito.Mockito.mock;
@@ -66,13 +66,12 @@ public class IssueIndexDebtTest {
IssueIndex index;
IssueIndexer issueIndexer;
- AuthorizationIndexer issueAuthorizationIndexer;
+ AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(tester);
ViewIndexer viewIndexer;
@Before
public void setUp() {
issueIndexer = new IssueIndexer(null, tester.client());
- issueAuthorizationIndexer = new AuthorizationIndexer(null, tester.client());
viewIndexer = new ViewIndexer(null, tester.client());
System2 system = mock(System2.class);
when(system.getDefaultTimeZone()).thenReturn(TimeZone.getTimeZone("+01:00"));
@@ -280,14 +279,14 @@ public class IssueIndexDebtTest {
}
private void indexIssues(IssueDoc... issues) {
- issueIndexer.index(Arrays.asList(issues).iterator());
+ issueIndexer.index(asList(issues).iterator());
for (IssueDoc issue : issues) {
addIssueAuthorization(issue.projectUuid(), DefaultGroups.ANYONE, null);
}
}
private void addIssueAuthorization(String projectUuid, @Nullable String group, @Nullable String user) {
- issueAuthorizationIndexer.index(newArrayList(new AuthorizationDao.Dto(projectUuid, 1).addGroup(group).addUser(user)));
+ authorizationIndexerTester.insertProjectAuthorization(projectUuid, singletonList(group), singletonList(user));
}
private Builder newQueryBuilder() {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java
index e60c23c85d8..34aa4a444db 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java
@@ -50,14 +50,14 @@ import org.sonar.server.es.SearchResult;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.issue.IssueQuery;
import org.sonar.server.issue.IssueTesting;
-import org.sonar.server.permission.index.AuthorizationDao;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.AuthorizationIndexerTester;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.view.index.ViewDoc;
import org.sonar.server.view.index.ViewIndexDefinition;
import org.sonar.server.view.index.ViewIndexer;
import static com.google.common.collect.Lists.newArrayList;
+import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
@@ -79,13 +79,12 @@ public class IssueIndexTest {
IssueIndex underTest;
IssueIndexer issueIndexer;
- AuthorizationIndexer issueAuthorizationIndexer;
+ AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(tester);
ViewIndexer viewIndexer;
@Before
public void setUp() {
issueIndexer = new IssueIndexer(null, tester.client());
- issueAuthorizationIndexer = new AuthorizationIndexer(null, tester.client());
viewIndexer = new ViewIndexer(null, tester.client());
System2 system = mock(System2.class);
when(system.getDefaultTimeZone()).thenReturn(TimeZone.getTimeZone("GMT-1:00"));
@@ -1290,7 +1289,7 @@ public class IssueIndexTest {
}
private void addIssueAuthorization(String projectUuid, @Nullable String group, @Nullable String user) {
- issueAuthorizationIndexer.index(newArrayList(new AuthorizationDao.Dto(projectUuid, 1).addGroup(group).addUser(user)));
+ authorizationIndexerTester.insertProjectAuthorization(projectUuid, singletonList(group), singletonList(user));
}
private void indexView(String viewUuid, List<String> projects) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationDaoTest.java
index 9428f6070ed..942dd696dcf 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationDaoTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationDaoTest.java
@@ -21,7 +21,6 @@ package org.sonar.server.permission.index;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@@ -80,7 +79,7 @@ public class AuthorizationDaoTest {
public void select_all() {
insertTestDataForProject1And2();
- Collection<AuthorizationDao.Dto> dtos = underTest.selectAfterDate(dbClient, dbSession, Collections.emptyList());
+ Collection<AuthorizationDao.Dto> dtos = underTest.selectAll(dbClient, dbSession);
assertThat(dtos).hasSize(2);
AuthorizationDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos);
@@ -98,7 +97,7 @@ public class AuthorizationDaoTest {
public void select_by_project() throws Exception {
insertTestDataForProject1And2();
- Collection<AuthorizationDao.Dto> dtos = underTest.selectAfterDate(dbClient, dbSession, singletonList(project1.uuid()));
+ Collection<AuthorizationDao.Dto> dtos = underTest.selectByProjects(dbClient, dbSession, singletonList(project1.uuid()));
assertThat(dtos).hasSize(1);
AuthorizationDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos);
assertThat(project1Authorization.getGroups()).containsOnly(ANYONE, group.getName());
@@ -110,7 +109,7 @@ public class AuthorizationDaoTest {
public void select_by_projects() throws Exception {
insertTestDataForProject1And2();
- Map<String, AuthorizationDao.Dto> dtos = underTest.selectAfterDate(dbClient, dbSession, asList(project1.uuid(), project2.uuid()))
+ Map<String, AuthorizationDao.Dto> dtos = underTest.selectByProjects(dbClient, dbSession, asList(project1.uuid(), project2.uuid()))
.stream()
.collect(Collectors.uniqueIndex(AuthorizationDao.Dto::getProjectUuid, Function.identity()));
assertThat(dtos).hasSize(2);
@@ -142,7 +141,7 @@ public class AuthorizationDaoTest {
}
dbSession.commit();
- Map<String, AuthorizationDao.Dto> dtos = underTest.selectAfterDate(dbClient, dbSession, projects)
+ Map<String, AuthorizationDao.Dto> dtos = underTest.selectByProjects(dbClient, dbSession, projects)
.stream()
.collect(Collectors.uniqueIndex(AuthorizationDao.Dto::getProjectUuid, Function.identity()));
assertThat(dtos).hasSize(350);
@@ -153,7 +152,7 @@ public class AuthorizationDaoTest {
userDbTester.insertProjectPermissionOnUser(user1, USER, project2);
userDbTester.insertProjectPermissionOnGroup(group, USER, project2);
- Collection<AuthorizationDao.Dto> dtos = underTest.selectAfterDate(dbClient, dbSession, Collections.emptyList());
+ Collection<AuthorizationDao.Dto> dtos = underTest.selectAll(dbClient, dbSession);
assertThat(dtos).hasSize(2);
AuthorizationDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationIndexerTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationIndexerTest.java
index dc67e68442f..8fa2c0400d1 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationIndexerTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationIndexerTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.permission.index;
+import com.google.common.collect.ImmutableMap;
import java.util.Collections;
import org.junit.Rule;
import org.junit.Test;
@@ -28,9 +29,12 @@ import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.permission.GroupPermissionDto;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDbTester;
import org.sonar.db.user.UserDto;
+import org.sonar.server.component.es.ProjectMeasuresIndexDefinition;
import org.sonar.server.es.EsTester;
import org.sonar.server.issue.index.IssueIndexDefinition;
@@ -51,7 +55,7 @@ public class AuthorizationIndexerTest {
public DbTester dbTester = DbTester.create(System2.INSTANCE);
@Rule
- public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()));
+ public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()), new ProjectMeasuresIndexDefinition(new MapSettings()));
ComponentDbTester componentDbTester = new ComponentDbTester(dbTester);
UserDbTester userDbTester = new UserDbTester(dbTester);
@@ -60,14 +64,14 @@ public class AuthorizationIndexerTest {
AuthorizationIndexer underTest = new AuthorizationIndexer(dbTester.getDbClient(), esTester.client());
@Test
- public void index_nothing() {
- underTest.index();
+ public void index_all_does_nothing_when_no_data() {
+ underTest.indexAllIfEmpty();
assertThat(esTester.countDocuments("issues", "authorization")).isZero();
}
@Test
- public void index() {
+ public void index_all() {
ComponentDto project = componentDbTester.insertProject();
UserDto user = userDbTester.insertUser();
userDbTester.insertProjectPermissionOnUser(user, USER, project);
@@ -76,12 +80,52 @@ public class AuthorizationIndexerTest {
userDbTester.insertProjectPermissionOnGroup(group, USER, project);
userDbTester.insertProjectPermissionOnAnyone(USER, project);
- underTest.index();
+ underTest.indexAllIfEmpty();
authorizationIndexerTester.verifyProjectExistsWithAuthorization(project.uuid(), asList(group.getName(), ANYONE), singletonList(user.getLogin()));
}
@Test
+ public void index_all_with_huge_number_of_projects() throws Exception {
+ GroupDto group = userDbTester.insertGroup();
+ for (int i = 0; i < 1100; i++) {
+ ComponentDto project = ComponentTesting.newProjectDto();
+ dbTester.getDbClient().componentDao().insert(dbTester.getSession(), project);
+ GroupPermissionDto dto = new GroupPermissionDto()
+ .setOrganizationUuid(group.getOrganizationUuid())
+ .setGroupId(group.getId())
+ .setRole(USER)
+ .setResourceId(project.getId());
+ dbTester.getDbClient().groupPermissionDao().insert(dbTester.getSession(), dto);
+ }
+ dbTester.getSession().commit();
+
+ underTest.indexAllIfEmpty();
+
+ assertThat(esTester.countDocuments(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION)).isEqualTo(1100);
+ assertThat(esTester.countDocuments(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION)).isEqualTo(1100);
+ }
+
+ @Test
+ public void index_all_is_first_truncating_indexes() throws Exception {
+ // Insert only one document in issues authorization => only one index is empty
+ esTester.client().prepareIndex(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION)
+ .setId("ABC")
+ .setRouting("ABC")
+ .setSource(ImmutableMap.of(IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, "ABC"))
+ .setRefresh(true)
+ .get();
+ GroupDto group = userDbTester.insertGroup();
+ ComponentDto project = componentDbTester.insertProject();
+ userDbTester.insertProjectPermissionOnGroup(group, USER, project);
+
+ underTest.indexAllIfEmpty();
+
+ authorizationIndexerTester.verifyProjectExistsWithAuthorization(project.uuid(), asList(group.getName(), ANYONE), emptyList());
+ authorizationIndexerTester.verifyProjectDoesNotExist("ABC");
+ }
+
+ @Test
public void index_one_project() throws Exception {
GroupDto group = userDbTester.insertGroup();
ComponentDto project1 = componentDbTester.insertProject();
@@ -123,7 +167,7 @@ public class AuthorizationIndexerTest {
}
@Test
- public void do_not_fail_when_deleting_unindexed_project() {
+ public void do_not_fail_when_deleting_unknown_project() {
underTest.deleteProject("UNKNOWN", true);
authorizationIndexerTester.verifyEmptyProjectAuthorization();
@@ -134,7 +178,7 @@ public class AuthorizationIndexerTest {
authorizationIndexerTester.insertProjectAuthorization("ABC", singletonList("guy"), singletonList("dev"));
// remove permissions -> dto has no users nor groups
- underTest.index(singletonList(new AuthorizationDao.Dto("ABC", System.currentTimeMillis())));
+ underTest.index(new AuthorizationDao.Dto("ABC", System.currentTimeMillis()));
authorizationIndexerTester.verifyProjectExistsWithoutAuthorization("ABC");
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationIndexerTester.java b/server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationIndexerTester.java
index 9096bd17b4e..90c756a2d70 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationIndexerTester.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationIndexerTester.java
@@ -23,19 +23,17 @@ package org.sonar.server.permission.index;
import java.util.List;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.index.query.BoolQueryBuilder;
+import org.sonar.server.component.es.ProjectMeasuresIndexDefinition;
import org.sonar.server.es.EsTester;
+import org.sonar.server.issue.index.IssueIndexDefinition;
import static java.util.Collections.emptyList;
-import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.existsQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
-import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_AUTHORIZATION_GROUPS;
-import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID;
-import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_AUTHORIZATION_USERS;
public class AuthorizationIndexerTester {
@@ -50,17 +48,19 @@ public class AuthorizationIndexerTester {
public void insertProjectAuthorization(String projectUuid, List<String> groupNames, List<String> userLogins) {
AuthorizationDao.Dto authorization = new AuthorizationDao.Dto(projectUuid, System.currentTimeMillis());
- groupNames.forEach(authorization::addUser);
- userLogins.forEach(authorization::addGroup);
- authorizationIndexer.index(singletonList(authorization));
+ groupNames.forEach(authorization::addGroup);
+ userLogins.forEach(authorization::addUser);
+ authorizationIndexer.index(authorization);
}
public void verifyEmptyProjectAuthorization() {
- assertThat(esTester.countDocuments("issues", "authorization")).isZero();
+ assertThat(esTester.countDocuments(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION)).isZero();
+ assertThat(esTester.countDocuments(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION)).isZero();
}
public void verifyProjectDoesNotExist(String projectUuid) {
- assertThat(esTester.getIds("issues", "authorization")).doesNotContain(projectUuid);
+ assertThat(esTester.getIds(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION)).doesNotContain(projectUuid);
+ assertThat(esTester.getIds(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION)).doesNotContain(projectUuid);
}
public void verifyProjectExistsWithoutAuthorization(String projectUuid) {
@@ -68,21 +68,31 @@ public class AuthorizationIndexerTester {
}
public void verifyProjectExistsWithAuthorization(String projectUuid, List<String> groupNames, List<String> userLogins) {
- assertThat(esTester.getIds("issues", "authorization")).contains(projectUuid);
- BoolQueryBuilder queryBuilder = boolQuery().must(termQuery(FIELD_AUTHORIZATION_PROJECT_UUID, projectUuid));
+ verifyProjectExistsWithAuthorizationInIndex(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION,
+ IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, IssueIndexDefinition.FIELD_AUTHORIZATION_GROUPS, IssueIndexDefinition.FIELD_AUTHORIZATION_USERS,
+ projectUuid, groupNames, userLogins);
+ verifyProjectExistsWithAuthorizationInIndex(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION,
+ ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_GROUPS,
+ ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_USERS, projectUuid, groupNames, userLogins);
+ }
+
+ private void verifyProjectExistsWithAuthorizationInIndex(String index, String type, String projectField, String groupField, String userField, String projectUuid,
+ List<String> groupNames, List<String> userLogins) {
+ assertThat(esTester.getIds(index, type)).contains(projectUuid);
+ BoolQueryBuilder queryBuilder = boolQuery().must(termQuery(projectField, projectUuid));
if (groupNames.isEmpty()) {
- queryBuilder.mustNot(existsQuery(FIELD_AUTHORIZATION_GROUPS));
+ queryBuilder.mustNot(existsQuery(groupField));
} else {
- queryBuilder.must(termsQuery(FIELD_AUTHORIZATION_GROUPS, groupNames));
+ queryBuilder.must(termsQuery(groupField, groupNames));
}
if (userLogins.isEmpty()) {
- queryBuilder.mustNot(existsQuery(FIELD_AUTHORIZATION_USERS));
+ queryBuilder.mustNot(existsQuery(userField));
} else {
- queryBuilder.must(termsQuery(FIELD_AUTHORIZATION_USERS, userLogins));
+ queryBuilder.must(termsQuery(userField, userLogins));
}
SearchRequestBuilder request = esTester.client()
- .prepareSearch("issues")
- .setTypes("authorization")
+ .prepareSearch(index)
+ .setTypes(type)
.setQuery(boolQuery().must(matchAllQuery()).filter(queryBuilder));
assertThat(request.get().getHits()).hasSize(1);
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java
index e90a36aebc5..5c3957ea7de 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java
@@ -36,6 +36,7 @@ import org.sonar.db.permission.template.PermissionTemplateDto;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.component.es.ProjectMeasuresIndexDefinition;
import org.sonar.server.es.EsTester;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
@@ -60,7 +61,7 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_T
public class ApplyTemplateActionTest extends BasePermissionWsTest<ApplyTemplateAction> {
@Rule
- public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()));
+ public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()), new ProjectMeasuresIndexDefinition(new MapSettings()));
private static final String ACTION = "apply_template";