From: Julien Lancelot Date: Mon, 8 Sep 2014 14:18:32 +0000 (+0200) Subject: SONAR-5561 New migration task at start-up to feed ES with issue_project_permissions X-Git-Tag: 5.0-RC1~1050 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=cc5f905e907f8260b8e57379b0a5f434fa7d6238;p=sonarqube.git SONAR-5561 New migration task at start-up to feed ES with issue_project_permissions --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/db/DbClient.java b/server/sonar-server/src/main/java/org/sonar/server/db/DbClient.java index d9fc72df394..3cf1008ca30 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/db/DbClient.java +++ b/server/sonar-server/src/main/java/org/sonar/server/db/DbClient.java @@ -40,6 +40,7 @@ import org.sonar.server.measure.persistence.MeasureDao; import org.sonar.server.measure.persistence.MetricDao; import org.sonar.server.qualityprofile.db.ActiveRuleDao; import org.sonar.server.rule.db.RuleDao; +import org.sonar.server.user.db.GroupDao; import java.util.Map; @@ -63,6 +64,7 @@ public class DbClient implements ServerComponent { private final ActivityDao activityDao; private final AuthorizationDao authorizationDao; private final UserDao userDao; + private final GroupDao groupDao; private final IssueDao issueDao; private final IssueAuthorizationDao issueAuthorizationDao; @@ -87,6 +89,7 @@ public class DbClient implements ServerComponent { activityDao = getDao(map, ActivityDao.class); authorizationDao = getDao(map, AuthorizationDao.class); userDao = getDao(map, UserDao.class); + groupDao = getDao(map, GroupDao.class); issueDao = getDao(map, IssueDao.class); issueAuthorizationDao = getDao(map, IssueAuthorizationDao.class); } @@ -159,6 +162,10 @@ public class DbClient implements ServerComponent { return userDao; } + public GroupDao groupDao() { + return groupDao; + } + private K getDao(Map map, Class clazz) { return (K) map.get(clazz); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueAuthorizationDao.java b/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueAuthorizationDao.java index 64074abe00d..4548ec1beee 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueAuthorizationDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueAuthorizationDao.java @@ -63,9 +63,9 @@ public class IssueAuthorizationDao extends BaseDao> rows = session.selectList("org.sonar.core.issue.db.IssueAuthorizationMapper.selectAfterDate", params); for (Map row : rows) { - String project = row.get("PROJECT"); - String user = row.get("USER"); - String group = row.get("PERMISSION_GROUP"); + String project = row.get("project"); + String user = row.get("user"); + String group = row.get("permission_group"); IssueAuthorizationDto issueAuthorizationDto = authorizationDtoMap.get(project); if (issueAuthorizationDto == null) { issueAuthorizationDto = new IssueAuthorizationDto() diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index 153e75b83ff..2009a7e741c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -165,6 +165,7 @@ import org.sonar.server.ui.PageDecorations; import org.sonar.server.ui.Views; import org.sonar.server.updatecenter.ws.UpdateCenterWs; import org.sonar.server.user.*; +import org.sonar.server.user.db.GroupDao; import org.sonar.server.user.ws.FavoritesWs; import org.sonar.server.user.ws.UserPropertiesWs; import org.sonar.server.user.ws.UsersWs; @@ -227,6 +228,7 @@ class ServerComponents { DbClient.class, MeasureFilterDao.class, ActivityDao.class, + GroupDao.class, // Elasticsearch SearchClient.class, diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/IndexSynchronizer.java b/server/sonar-server/src/main/java/org/sonar/server/search/IndexSynchronizer.java index ee9caa8174d..20331459f3d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/search/IndexSynchronizer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/search/IndexSynchronizer.java @@ -25,6 +25,7 @@ import org.sonar.core.persistence.DbSession; import org.sonar.server.activity.index.ActivityIndex; import org.sonar.server.db.Dao; import org.sonar.server.db.DbClient; +import org.sonar.server.issue.index.IssueAuthorizationIndex; import org.sonar.server.issue.index.IssueIndex; import org.sonar.server.qualityprofile.index.ActiveRuleIndex; import org.sonar.server.rule.index.RuleIndex; @@ -51,8 +52,7 @@ public class IndexSynchronizer { long start = System.currentTimeMillis(); synchronize(session, db.ruleDao(), index.get(RuleIndex.class)); synchronize(session, db.issueDao(), index.get(IssueIndex.class)); - // TODO - //synchronize(session, db.issueAuthorizationDao(), index.get(IssueAuthorizationIndex.class)); + synchronize(session, db.issueAuthorizationDao(), index.get(IssueAuthorizationIndex.class)); synchronize(session, db.activeRuleDao(), index.get(ActiveRuleIndex.class)); synchronize(session, db.activityDao(), index.get(ActivityIndex.class)); session.commit(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/db/GroupDao.java b/server/sonar-server/src/main/java/org/sonar/server/user/db/GroupDao.java new file mode 100644 index 00000000000..9f6a5db3775 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/user/db/GroupDao.java @@ -0,0 +1,55 @@ +/* + * 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.user.db; + +import com.google.common.annotations.VisibleForTesting; +import org.sonar.api.utils.System2; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.user.GroupDto; +import org.sonar.core.user.GroupMapper; +import org.sonar.server.db.BaseDao; + +/** + * @since 3.2 + */ +public class GroupDao extends BaseDao { + + public GroupDao() { + this(System2.INSTANCE); + } + + @VisibleForTesting + public GroupDao(System2 system) { + super(GroupMapper.class, system); + } + + @Override + protected GroupDto doGetNullableByKey(DbSession session, String key) { + return mapper(session).selectByKey(key); + } + + @Override + protected GroupDto doInsert(DbSession session, GroupDto item) { + mapper(session).insert(item); + return item; + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/db/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/user/db/package-info.java new file mode 100644 index 00000000000..51f61540320 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/user/db/package-info.java @@ -0,0 +1,24 @@ +/* + * 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. + */ + +@ParametersAreNonnullByDefault +package org.sonar.server.user.db; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueAuthorizationIndexMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueAuthorizationIndexMediumTest.java new file mode 100644 index 00000000000..14eaa3fc1ac --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueAuthorizationIndexMediumTest.java @@ -0,0 +1,100 @@ +/* + * 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.issue.index; + +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.sonar.api.web.UserRole; +import org.sonar.core.component.ComponentDto; +import org.sonar.core.permission.PermissionFacade; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.user.GroupDto; +import org.sonar.core.user.UserDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.platform.Platform; +import org.sonar.server.tester.ServerTester; + +import java.util.Date; + +import static org.fest.assertions.Assertions.assertThat; + +public class IssueAuthorizationIndexMediumTest { + + @ClassRule + public static ServerTester tester = new ServerTester(); + + DbClient db; + DbSession session; + IssueAuthorizationIndex index; + + ComponentDto project; + + @Before + public void setUp() throws Exception { + tester.clearDbAndIndexes(); + db = tester.get(DbClient.class); + session = db.openSession(false); + index = tester.get(IssueAuthorizationIndex.class); + } + + @After + public void after() { + session.close(); + } + + @Test + public void synchronize() throws Exception { + project = new ComponentDto() + .setKey("Sample") + .setProjectId(1L); + db.componentDao().insert(session, project); + + GroupDto sonarUsers = new GroupDto().setName("devs"); + db.groupDao().insert(session, sonarUsers); + + UserDto john = new UserDto().setLogin("john").setName("John").setActive(true); + db.userDao().insert(session, john); + + tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), "devs", UserRole.USER, session); + tester.get(PermissionFacade.class).insertUserPermission(project.getId(), john.getId(), UserRole.USER, session); + + session.commit(); + session.clearCache(); + tester.clearIndexes(); + + assertThat(index.getByKey(project.getKey())).isNull(); + db.issueAuthorizationDao().synchronizeAfter(session, new Date(0)); + + IssueAuthorizationDoc issueAuthorizationDoc = index.getByKey(project.getKey()); + assertThat(issueAuthorizationDoc).isNotNull(); + assertThat(issueAuthorizationDoc.project()).isEqualTo("Sample"); + assertThat(issueAuthorizationDoc.permission()).isEqualTo("user"); + assertThat(issueAuthorizationDoc.groups()).containsExactly("devs"); + assertThat(issueAuthorizationDoc.users()).containsExactly("john"); + + tester.clearIndexes(); + tester.get(Platform.class).executeStartupTasks(); + assertThat(index.getByKey(project.getKey())).isNotNull(); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/db/GroupDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/db/GroupDaoTest.java new file mode 100644 index 00000000000..5a181da970f --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/user/db/GroupDaoTest.java @@ -0,0 +1,83 @@ +/* + * 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.user.db; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; +import org.sonar.core.persistence.AbstractDaoTestCase; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.user.GroupDto; + +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class GroupDaoTest extends AbstractDaoTestCase { + + GroupDao dao; + DbSession session; + System2 system2; + + @Before + public void setUp() { + this.session = getMyBatis().openSession(false); + this.system2 = mock(System2.class); + this.dao = new GroupDao(system2); + } + + @After + public void tearDown() throws Exception { + session.close(); + } + + @Test + public void select_by_key() { + setupData("select_by_key"); + + GroupDto group = dao.getByKey(session, "sonar-users"); + assertThat(group).isNotNull(); + assertThat(group.getId()).isEqualTo(1L); + assertThat(group.getName()).isEqualTo("sonar-users"); + assertThat(group.getDescription()).isEqualTo("Sonar Users"); + assertThat(group.getCreatedAt()).isEqualTo(DateUtils.parseDate("2014-09-07")); + assertThat(group.getUpdatedAt()).isEqualTo(DateUtils.parseDate("2014-09-08")); + } + + @Test + public void insert() throws Exception { + when(system2.now()).thenReturn(DateUtils.parseDate("2014-09-08").getTime()); + + setupData("empty"); + + GroupDto dto = new GroupDto() + .setId(1L) + .setName("sonar-users") + .setDescription("Sonar Users"); + + dao.insert(session, dto); + session.commit(); + + checkTables("insert", "groups"); + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/empty.xml b/server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/empty.xml new file mode 100644 index 00000000000..a1c54e4625a --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/empty.xml @@ -0,0 +1,4 @@ + + + + diff --git a/server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/insert-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/insert-result.xml new file mode 100644 index 00000000000..ebbd59a6b8d --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/insert-result.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/select_by_key.xml b/server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/select_by_key.xml new file mode 100644 index 00000000000..e3ec0111eea --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/select_by_key.xml @@ -0,0 +1,5 @@ + + + + + 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 58d40c93502..fb13bb56181 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 @@ -167,7 +167,7 @@ public class MyBatis implements BatchComponent, ServerComponent { IssueMapper.class, IssueAuthorizationMapper.class, IssueStatsMapper.class, IssueChangeMapper.class, IssueFilterMapper.class, IssueFilterFavouriteMapper.class, LoadedTemplateMapper.class, MeasureFilterMapper.class, Migration44Mapper.class, PermissionTemplateMapper.class, PropertiesMapper.class, PurgeMapper.class, ResourceKeyUpdaterMapper.class, ResourceIndexerMapper.class, ResourceSnapshotMapper.class, RoleMapper.class, RuleMapper.class, - SchemaMigrationMapper.class, SemaphoreMapper.class, UserMapper.class, WidgetMapper.class, WidgetPropertyMapper.class, + SchemaMigrationMapper.class, SemaphoreMapper.class, UserMapper.class, GroupMapper.class, WidgetMapper.class, WidgetPropertyMapper.class, org.sonar.api.database.model.MeasureMapper.class, SnapshotDataMapper.class, SnapshotSourceMapper.class, ActionPlanMapper.class, ActionPlanStatsMapper.class, NotificationQueueMapper.class, CharacteristicMapper.class, GroupMembershipMapper.class, QualityProfileMapper.class, ActiveRuleMapper.class, diff --git a/sonar-core/src/main/java/org/sonar/core/user/GroupDto.java b/sonar-core/src/main/java/org/sonar/core/user/GroupDto.java index f3afa89a920..b70d2526785 100644 --- a/sonar-core/src/main/java/org/sonar/core/user/GroupDto.java +++ b/sonar-core/src/main/java/org/sonar/core/user/GroupDto.java @@ -19,18 +19,16 @@ */ package org.sonar.core.user; +import org.sonar.core.persistence.Dto; + +import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.util.Date; -/** - * @since 3.2 - */ -public class GroupDto { +public class GroupDto extends Dto { + private Long id; private String name; private String description; - private Date createdAt; - private Date updatedAt; public Long getId() { return id; @@ -50,6 +48,7 @@ public class GroupDto { return this; } + @CheckForNull public String getDescription() { return description; } @@ -59,21 +58,9 @@ public class GroupDto { return this; } - public Date getCreatedAt() { - return createdAt; - } - - public GroupDto setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - return this; - } - - public Date getUpdatedAt() { - return updatedAt; + @Override + public String getKey() { + return name; } - public GroupDto setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; - return this; - } } diff --git a/sonar-core/src/main/java/org/sonar/core/user/GroupMapper.java b/sonar-core/src/main/java/org/sonar/core/user/GroupMapper.java new file mode 100644 index 00000000000..0edd9c3f331 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/user/GroupMapper.java @@ -0,0 +1,32 @@ +/* + * 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.user; + +import javax.annotation.CheckForNull; + +public interface GroupMapper { + + @CheckForNull + GroupDto selectByKey(String name); + + void insert(GroupDto groupDto); + +} diff --git a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueAuthorizationMapper.xml b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueAuthorizationMapper.xml index d4cf8ba718f..eb451cf51ae 100644 --- a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueAuthorizationMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueAuthorizationMapper.xml @@ -6,10 +6,10 @@ + SELECT + FROM groups g WHERE g.name=#{id} + + + + INSERT INTO groups (name, description, created_at, updated_at) + VALUES (#{name}, #{description}, #{createdAt}, #{updatedAt}) + + +