diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2015-01-28 12:24:33 +0100 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2015-01-29 15:08:49 +0100 |
commit | 18ff30bdf1a602b1eff8344af998ece8002af29e (patch) | |
tree | 90a78fdf40c002842cf0f4ef3bd79dadd3950865 | |
parent | 410a553075d6047fa3ec8721f84ad753e2545c5f (diff) | |
download | sonarqube-18ff30bdf1a602b1eff8344af998ece8002af29e.tar.gz sonarqube-18ff30bdf1a602b1eff8344af998ece8002af29e.zip |
SONAR-6087 Purge removed Views and Sub-Views Index on each Views analysis
18 files changed, 456 insertions, 23 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java b/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java index 84091b1343e..858917deb05 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java @@ -27,6 +27,7 @@ import org.sonar.api.resources.Scopes; import org.sonar.api.utils.System2; import org.sonar.core.component.ComponentDto; import org.sonar.core.component.FilePathWithHashDto; +import org.sonar.core.component.UuidWithProjectUuidDto; import org.sonar.core.component.db.ComponentMapper; import org.sonar.core.persistence.DaoComponent; import org.sonar.core.persistence.DbSession; @@ -38,7 +39,6 @@ import javax.annotation.CheckForNull; import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Map; import static com.google.common.collect.Lists.newArrayList; @@ -143,7 +143,7 @@ public class ComponentDao extends BaseDao<ComponentMapper, ComponentDto, String> return mapper(session).findProjectUuids(); } - public List<Map<String, String>> selectAllViewsAndSubViews(DbSession session) { + public List<UuidWithProjectUuidDto> selectAllViewsAndSubViews(DbSession session) { return mapper(session).selectAllViewsAndSubViews(Qualifiers.VIEW, Qualifiers.SUBVIEW); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationComponents.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationComponents.java index 51f73608783..7a202030b18 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ComputationComponents.java @@ -22,6 +22,7 @@ package org.sonar.server.computation; import org.sonar.core.issue.db.UpdateConflictResolver; import org.sonar.server.computation.issue.*; import org.sonar.server.computation.step.ComputationSteps; +import org.sonar.server.view.index.ViewIndex; import java.util.Arrays; import java.util.List; @@ -50,6 +51,9 @@ public class ComputationComponents { RuleCache.class, RuleCacheLoader.class, IssueCache.class, - UpdateConflictResolver.class); + UpdateConflictResolver.class, + + // views + ViewIndex.class); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java index a2d1f605334..e19da64b18f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java @@ -46,6 +46,9 @@ public class ComputationSteps { IndexSourceLinesStep.class, IndexViewsStep.class, + // Purge of removed views has to be done after Views has been indexed + PurgeRemovedViewsStep.class, + // notifications are sent at the end, so that webapp displays up-to-date information SendIssueNotificationsStep.class); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PurgeRemovedViewsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PurgeRemovedViewsStep.java new file mode 100644 index 00000000000..de8c824018e --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PurgeRemovedViewsStep.java @@ -0,0 +1,85 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.computation.step; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; +import org.sonar.api.resources.Qualifiers; +import org.sonar.core.component.UuidWithProjectUuidDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.server.computation.ComputationContext; +import org.sonar.server.db.DbClient; +import org.sonar.server.view.index.ViewIndex; + +import javax.annotation.Nullable; + +import java.util.List; +import java.util.Set; + +import static com.google.common.collect.Sets.newHashSet; + +/** + * This step will remove every Views and Sub Views from the index that do not exists in the db. + * As it's executed on each analysis, it means that when the Views task is executed on every views, this step will be executed on each views ! + * + * A more optimized approach would be to execute this step only once at this end of the Views task. + */ +public class PurgeRemovedViewsStep implements ComputationStep { + + private final DbClient dbClient; + private final ViewIndex index; + + public PurgeRemovedViewsStep(ViewIndex index, DbClient dbClient) { + this.index = index; + this.dbClient = dbClient; + } + + @Override + public void execute(ComputationContext context) { + if (context.getProject().qualifier().equals(Qualifiers.VIEW)) { + purgeRemovedViews(); + } + } + + private void purgeRemovedViews() { + DbSession session = dbClient.openSession(false); + try { + List<UuidWithProjectUuidDto> uuidWithProjectUuidDtos = dbClient.componentDao().selectAllViewsAndSubViews(session); + Set<String> viewUuidsInDb = newHashSet(Iterables.transform(uuidWithProjectUuidDtos, new Function<UuidWithProjectUuidDto, String>() { + @Override + public String apply(@Nullable UuidWithProjectUuidDto input) { + return input != null ? input.getUuid() : null; + } + })); + Set<String> viewUuidsInIndex = newHashSet(index.findAllViewUuids()); + Set<String> viewsToRemove = Sets.difference(viewUuidsInIndex, viewUuidsInDb); + index.delete(viewsToRemove); + } finally { + session.close(); + } + } + + @Override + public String getDescription() { + return "Purge removed views"; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewDoc.java b/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewDoc.java index 55ba66a1867..9b92dd8f72e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewDoc.java +++ b/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewDoc.java @@ -20,6 +20,7 @@ package org.sonar.server.view.index; +import com.google.common.collect.Maps; import org.sonar.server.search.BaseDoc; import java.util.List; @@ -31,6 +32,10 @@ public class ViewDoc extends BaseDoc { super(fields); } + public ViewDoc() { + super(Maps.<String, Object>newHashMap()); + } + public String uuid() { return getField(ViewIndexDefinition.FIELD_UUID); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndex.java b/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndex.java new file mode 100644 index 00000000000..67341fb7e36 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndex.java @@ -0,0 +1,84 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.view.index; + +import org.elasticsearch.action.search.SearchRequestBuilder; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchType; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.index.query.FilterBuilders; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.sonar.api.ServerComponent; +import org.sonar.server.es.EsClient; + +import java.util.Collection; +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; + +public class ViewIndex implements ServerComponent { + + private final int SCROLL_TIME_IN_MINUTES = 3; + + private final EsClient esClient; + + public ViewIndex(EsClient esClient) { + this.esClient = esClient; + } + + public List<String> findAllViewUuids() { + SearchRequestBuilder esSearch = esClient.prepareSearch(ViewIndexDefinition.INDEX) + .setTypes(ViewIndexDefinition.TYPE_VIEW) + .setSearchType(SearchType.SCAN) + .setScroll(TimeValue.timeValueMinutes(SCROLL_TIME_IN_MINUTES)) + .setFetchSource(ViewIndexDefinition.FIELD_UUID, null) + .setSize(100) + .setQuery(QueryBuilders.matchAllQuery()); + + SearchResponse response = esSearch.get(); + List<String> result = newArrayList(); + while (true) { + List<SearchHit> hits = newArrayList(response.getHits()); + for (SearchHit hit : hits) { + result.add((String) hit.getSource().get(ViewIndexDefinition.FIELD_UUID)); + } + response = esClient.prepareSearchScroll(response.getScrollId()) + .setScroll(TimeValue.timeValueMinutes(SCROLL_TIME_IN_MINUTES)) + .get(); + // Break condition: No hits are returned + if (response.getHits().getHits().length == 0) { + break; + } + } + return result; + } + + public void delete(Collection<String> viewUuids) { + esClient + .prepareDeleteByQuery(ViewIndexDefinition.INDEX) + .setTypes(ViewIndexDefinition.TYPE_VIEW) + .setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), + FilterBuilders.termsFilter(ViewIndexDefinition.FIELD_UUID, viewUuids) + )) + .get(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexer.java b/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexer.java index 78bc4f7d2c6..cb6ed32d19f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexer.java @@ -20,9 +20,9 @@ package org.sonar.server.view.index; -import com.google.common.collect.Maps; import org.elasticsearch.action.update.UpdateRequest; import org.sonar.core.component.ComponentDto; +import org.sonar.core.component.UuidWithProjectUuidDto; import org.sonar.core.persistence.DbSession; import org.sonar.server.db.DbClient; import org.sonar.server.es.BaseIndexer; @@ -53,8 +53,8 @@ public class ViewIndexer extends BaseIndexer { DbSession dbSession = dbClient.openSession(false); try { Map<String, String> viewAndProjectViewUuidMap = newHashMap(); - for (Map<String, String> viewsMap : dbClient.componentDao().selectAllViewsAndSubViews(dbSession)) { - viewAndProjectViewUuidMap.put(viewsMap.get("uuid"), viewsMap.get("projectUuid")); + for (UuidWithProjectUuidDto uuidWithProjectUuidDto : dbClient.componentDao().selectAllViewsAndSubViews(dbSession)) { + viewAndProjectViewUuidMap.put(uuidWithProjectUuidDto.getUuid(), uuidWithProjectUuidDto.getProjectUuid()); } index(dbSession, viewAndProjectViewUuidMap); } finally { @@ -88,7 +88,7 @@ public class ViewIndexer extends BaseIndexer { private void doIndex(DbSession dbSession, BulkIndexer bulk, String uuid, String projectUuid) { List<String> projects = dbClient.componentDao().selectProjectsFromView(dbSession, uuid, projectUuid); - bulk.add(newUpsertRequest(new ViewDoc(Maps.<String, Object>newHashMap()) + bulk.add(newUpsertRequest(new ViewDoc() .setUuid(uuid) .setProjects(projects))); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java index ccbba1a36e4..a5f007bee05 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java @@ -56,7 +56,10 @@ public class ComponentTesting { } public static ComponentDto newModuleDto(ComponentDto subProjectOrProject) { - String uuid = Uuids.create(); + return newModuleDto(subProjectOrProject, Uuids.create()); + } + + public static ComponentDto newModuleDto(ComponentDto subProjectOrProject, String uuid) { return newComponent(subProjectOrProject, uuid) .setKey("KEY_" + uuid) .setName("NAME_" + uuid) diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java index 80ba999ed90..2cccb49f4c8 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java @@ -20,7 +20,6 @@ package org.sonar.server.component.db; -import com.google.common.collect.ImmutableMap; import org.apache.ibatis.exceptions.PersistenceException; import org.junit.After; import org.junit.Before; @@ -440,12 +439,8 @@ public class ComponentDaoTest extends AbstractDaoTestCase { public void select_views_and_sub_views() { setupData("shared_views"); - assertThat(dao.selectAllViewsAndSubViews(session)).contains( - ImmutableMap.of("uuid", "ABCD", "projectUuid", "ABCD"), - ImmutableMap.of("uuid", "EFGH", "projectUuid", "EFGH"), - ImmutableMap.of("uuid", "FGHI", "projectUuid", "EFGH"), - ImmutableMap.of("uuid", "IJKL", "projectUuid", "IJKL") - ); + assertThat(dao.selectAllViewsAndSubViews(session)).extracting("uuid").containsOnly("ABCD", "EFGH", "FGHI", "IJKL"); + assertThat(dao.selectAllViewsAndSubViews(session)).extracting("projectUuid").containsOnly("ABCD", "EFGH", "IJKL"); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeRemovedViewsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeRemovedViewsStepTest.java new file mode 100644 index 00000000000..e14386b9705 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeRemovedViewsStepTest.java @@ -0,0 +1,126 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.computation.step; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; +import org.elasticsearch.search.SearchHit; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Qualifiers; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.server.component.ComponentTesting; +import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.computation.ComputationContext; +import org.sonar.server.db.DbClient; +import org.sonar.server.es.EsTester; +import org.sonar.server.issue.db.IssueDao; +import org.sonar.server.view.index.ViewDoc; +import org.sonar.server.view.index.ViewIndex; +import org.sonar.server.view.index.ViewIndexDefinition; + +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class PurgeRemovedViewsStepTest { + + @Rule + public EsTester esTester = new EsTester().addDefinitions(new ViewIndexDefinition(new Settings())); + + @Rule + public DbTester db = new DbTester(); + + ComputationContext context; + + DbSession session; + + DbClient dbClient; + + PurgeRemovedViewsStep step; + + @Before + public void setUp() { + context = mock(ComputationContext.class); + session = db.myBatis().openSession(false); + dbClient = new DbClient(db.database(), db.myBatis(), new IssueDao(db.myBatis()), new ComponentDao()); + step = new PurgeRemovedViewsStep(new ViewIndex(esTester.client()), dbClient); + } + + @After + public void after() { + this.session.close(); + } + + @Test + public void purge_removed_views() throws Exception { + when(context.getProject()).thenReturn(ComponentTesting.newProjectDto("DBCA").setQualifier(Qualifiers.VIEW)); + + esTester.putDocuments(ViewIndexDefinition.INDEX, ViewIndexDefinition.TYPE_VIEW, + new ViewDoc().setUuid("ABCD").getFields(), + new ViewDoc().setUuid("BCDE").getFields(), + // Should be removed as it no more exists in db + new ViewDoc().setUuid("CDEF").getFields()); + + ComponentDto view = ComponentTesting.newProjectDto("ABCD").setQualifier(Qualifiers.VIEW); + ComponentDto subView = ComponentTesting.newModuleDto(view, "BCDE").setQualifier(Qualifiers.SUBVIEW); + dbClient.componentDao().insert(session, view, subView); + session.commit(); + + step.execute(context); + + List<SearchHit> results = esTester.getDocuments(ViewIndexDefinition.INDEX, ViewIndexDefinition.TYPE_VIEW); + List<String> viewUuids = newArrayList(Iterables.transform(results, new Function<SearchHit, String>() { + @Override + public String apply(SearchHit input) { + return new ViewDoc(input.getSource()).uuid(); + } + })); + assertThat(viewUuids).containsOnly("ABCD", "BCDE"); + } + + @Test + public void nothing_to_do_when_not_analysing_view() throws Exception { + when(context.getProject()).thenReturn(ComponentTesting.newProjectDto("DBCA")); + + esTester.putDocuments(ViewIndexDefinition.INDEX, ViewIndexDefinition.TYPE_VIEW, + new ViewDoc().setUuid("ABCD").getFields(), + // This vies does not exists in db... + new ViewDoc().setUuid("BCDE").getFields()); + + dbClient.componentDao().insert(session, ComponentTesting.newProjectDto("ABCD").setQualifier(Qualifiers.VIEW)); + session.commit(); + + step.execute(context); + + // ... But it should not be removed as the project of the context is not a view + assertThat(esTester.countDocuments(ViewIndexDefinition.INDEX, ViewIndexDefinition.TYPE_VIEW)).isEqualTo(2); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexTest.java new file mode 100644 index 00000000000..44f72a67151 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexTest.java @@ -0,0 +1,71 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.view.index; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.config.Settings; +import org.sonar.server.es.EsTester; + +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; +import static org.assertj.core.api.Assertions.assertThat; + +public class ViewIndexTest { + + @Rule + public EsTester esTester = new EsTester().addDefinitions(new ViewIndexDefinition(new Settings())); + + private ViewIndex index; + + @Before + public void setUp() { + index = new ViewIndex(esTester.client()); + } + + @Test + public void find_all_view_uuids() throws Exception { + esTester.putDocuments(ViewIndexDefinition.INDEX, ViewIndexDefinition.TYPE_VIEW, this.getClass(), "view1.json", "view2.json"); + + List<String> result = newArrayList(index.findAllViewUuids()); + + assertThat(result).containsOnly("fed0a543-9d9c-4af5-a4ec-450a8fe78ce7", "8d0bc2a5-bfba-464b-92de-bb170e9d978e"); + } + + @Test + public void not_find_all_view_uuids() throws Exception { + List<String> result = newArrayList(index.findAllViewUuids()); + + assertThat(result).isEmpty(); + } + + @Test + public void delete_views() throws Exception { + esTester.putDocuments(ViewIndexDefinition.INDEX, ViewIndexDefinition.TYPE_VIEW, this.getClass(), "view1.json", "view2.json"); + + index.delete(newArrayList("fed0a543-9d9c-4af5-a4ec-450a8fe78ce7", "8d0bc2a5-bfba-464b-92de-bb170e9d978e")); + + assertThat(esTester.countDocuments(ViewIndexDefinition.INDEX, ViewIndexDefinition.TYPE_VIEW)).isEqualTo(0L); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java b/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java index 966b66d9401..4e8485a5027 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java @@ -21,7 +21,6 @@ package org.sonar.server.view.index; import com.google.common.base.Function; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import org.junit.Before; import org.junit.Rule; @@ -89,10 +88,7 @@ public class ViewIndexerTest { // Some views are not in the db dbTester.prepareDbUnit(getClass(), "index.xml"); esTester.putDocuments(ViewIndexDefinition.INDEX, ViewIndexDefinition.TYPE_VIEW, - ImmutableMap.<String, Object>of( - ViewIndexDefinition.FIELD_UUID, "ABCD", - ViewIndexDefinition.FIELD_PROJECTS, newArrayList("BCDE") - )); + new ViewDoc().setUuid("ABCD").setProjects(newArrayList("BCDE")).getFields()); indexer.index(); diff --git a/server/sonar-server/src/test/resources/org/sonar/server/view/index/ViewIndexTest/view1.json b/server/sonar-server/src/test/resources/org/sonar/server/view/index/ViewIndexTest/view1.json new file mode 100644 index 00000000000..246e7ad41a6 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/view/index/ViewIndexTest/view1.json @@ -0,0 +1,6 @@ +{ + "uuid": "fed0a543-9d9c-4af5-a4ec-450a8fe78ce7", + "projects": [ + "548415bc-6626-45b1-a99a-ca77aedec45f" + ] +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/view/index/ViewIndexTest/view2.json b/server/sonar-server/src/test/resources/org/sonar/server/view/index/ViewIndexTest/view2.json new file mode 100644 index 00000000000..b88462641d2 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/view/index/ViewIndexTest/view2.json @@ -0,0 +1,8 @@ +{ + "uuid": "8d0bc2a5-bfba-464b-92de-bb170e9d978e", + "projects": [ + "e5dccc4f-431a-46ba-ab55-47318c332af7", + "6432a311-4d1f-41fd-b90a-826130f6f890", + "bf93ca9b-18f6-4f5d-848b-722ca7bd67d1" + ] +} diff --git a/sonar-core/src/main/java/org/sonar/core/component/UuidWithProjectUuidDto.java b/sonar-core/src/main/java/org/sonar/core/component/UuidWithProjectUuidDto.java new file mode 100644 index 00000000000..82fe44a82dd --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/component/UuidWithProjectUuidDto.java @@ -0,0 +1,45 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.core.component; + +public class UuidWithProjectUuidDto { + + private String uuid; + private String projectUuid; + + public String getProjectUuid() { + return projectUuid; + } + + public UuidWithProjectUuidDto setProjectUuid(String projectUuid) { + this.projectUuid = projectUuid; + return this; + } + + public String getUuid() { + return uuid; + } + + public UuidWithProjectUuidDto setUuid(String uuid) { + this.uuid = uuid; + return this; + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java b/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java index 81215f8d557..344bedd75fa 100644 --- a/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java @@ -23,12 +23,12 @@ package org.sonar.core.component.db; import org.apache.ibatis.annotations.Param; import org.sonar.core.component.ComponentDto; import org.sonar.core.component.FilePathWithHashDto; +import org.sonar.core.component.UuidWithProjectUuidDto; import javax.annotation.CheckForNull; import java.util.Collection; import java.util.List; -import java.util.Map; /** * @since 4.3 @@ -88,7 +88,7 @@ public interface ComponentMapper { /** * Return all views and sub views */ - List<Map<String, String>> selectAllViewsAndSubViews(@Param("viewQualifier") String viewQualifier, @Param("subViewQualifier") String subViewQualifier); + List<UuidWithProjectUuidDto> selectAllViewsAndSubViews(@Param("viewQualifier") String viewQualifier, @Param("subViewQualifier") String subViewQualifier); /** * Return technical projects from a view or a sub-view diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java index 75f75cf9089..a3c29f4e0c0 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java @@ -38,6 +38,7 @@ import org.sonar.core.cluster.WorkQueue; import org.sonar.core.component.ComponentDto; import org.sonar.core.component.FilePathWithHashDto; import org.sonar.core.component.SnapshotDto; +import org.sonar.core.component.UuidWithProjectUuidDto; import org.sonar.core.component.db.ComponentMapper; import org.sonar.core.component.db.SnapshotMapper; import org.sonar.core.computation.db.AnalysisReportDto; @@ -181,6 +182,7 @@ public class MyBatis implements BatchComponent, ServerComponent { loadAlias(conf, "AnalysisReport", AnalysisReportDto.class); loadAlias(conf, "IdUuidPair", IdUuidPair.class); loadAlias(conf, "FilePathWithHash", FilePathWithHashDto.class); + loadAlias(conf, "UuidWithProjectUuid", UuidWithProjectUuidDto.class); // AuthorizationMapper has to be loaded before IssueMapper because this last one used it loadMapper(conf, "org.sonar.core.user.AuthorizationMapper"); diff --git a/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml b/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml index c9a2d7ca514..3b496246050 100644 --- a/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml @@ -156,7 +156,7 @@ </where> </select> - <select id="selectAllViewsAndSubViews" resultType="hashmap"> + <select id="selectAllViewsAndSubViews" resultType="UuidWithProjectUuid"> SELECT v.uuid as "uuid", v.project_uuid as "projectUuid" FROM projects v <where> v.enabled=${_true} AND v.qualifier=#{viewQualifier} OR v.qualifier=#{subViewQualifier} |