summaryrefslogtreecommitdiffstats
path: root/server/sonar-db-dao
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2019-04-02 10:53:34 +0200
committersonartech <sonartech@sonarsource.com>2019-04-23 10:37:54 +0200
commit8420e1087f18f08d54d94e4f1a46770ca684ff9b (patch)
tree1c7c6fad4bd7389aad009f28f35fdb28974ab3f5 /server/sonar-db-dao
parentdfae66e01938fda55760991e65397f0d318c38c8 (diff)
downloadsonarqube-8420e1087f18f08d54d94e4f1a46770ca684ff9b.tar.gz
sonarqube-8420e1087f18f08d54d94e4f1a46770ca684ff9b.zip
SONAR-11753 dont retrieve all subscribers if only interested in subset
Diffstat (limited to 'server/sonar-db-dao')
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java19
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java5
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml6
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java135
4 files changed, 162 insertions, 3 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java
index 465c8e4d9e2..bad536ddf3e 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java
@@ -25,6 +25,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -40,6 +41,7 @@ import org.sonar.db.MyBatis;
import static com.google.common.base.Preconditions.checkArgument;
import static org.apache.commons.lang.StringUtils.repeat;
import static org.sonar.db.DatabaseUtils.executeLargeInputs;
+import static org.sonar.db.DatabaseUtils.executeLargeInputsIntoSet;
import static org.sonar.db.DatabaseUtils.executeLargeInputsWithoutOutput;
public class PropertiesDao implements Dao {
@@ -72,7 +74,22 @@ public class PropertiesDao implements Dao {
public Set<EmailSubscriberDto> findEmailSubscribersForNotification(DbSession dbSession, String notificationDispatcherKey, String notificationChannelKey,
@Nullable String projectKey) {
- return getMapper(dbSession).findEmailRecipientsForNotification(NOTIFICATION_PREFIX + notificationDispatcherKey + "." + notificationChannelKey, projectKey);
+ return getMapper(dbSession).findEmailRecipientsForNotification(NOTIFICATION_PREFIX + notificationDispatcherKey + "." + notificationChannelKey, projectKey, null);
+ }
+
+ public Set<EmailSubscriberDto> findEmailSubscribersForNotification(DbSession dbSession, String notificationDispatcherKey, String notificationChannelKey,
+ @Nullable String projectKey, Set<String> logins) {
+ if (logins.isEmpty()) {
+ return Collections.emptySet();
+ }
+
+ return executeLargeInputsIntoSet(
+ logins,
+ loginsPartition -> {
+ String notificationKey = NOTIFICATION_PREFIX + notificationDispatcherKey + "." + notificationChannelKey;
+ return getMapper(dbSession).findEmailRecipientsForNotification(notificationKey, projectKey, loginsPartition);
+ },
+ partitionSize -> projectKey == null ? partitionSize : (partitionSize / 2));
}
public boolean hasProjectNotificationSubscribersForDispatchers(String projectUuid, Collection<String> dispatcherKeys) {
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java
index 5009b2e25ee..ccd2bb5f2e0 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java
@@ -29,7 +29,8 @@ public interface PropertiesMapper {
Set<Subscriber> findUsersForNotification(@Param("notifKey") String notificationKey, @Nullable @Param("projectKey") String projectKey);
- Set<EmailSubscriberDto> findEmailRecipientsForNotification(@Param("notifKey") String notificationKey, @Nullable @Param("projectKey") String projectKey);
+ Set<EmailSubscriberDto> findEmailRecipientsForNotification(@Param("notifKey") String notificationKey, @Nullable @Param("projectKey") String projectKey,
+ @Nullable @Param("logins") List<String> logins);
List<PropertyDto> selectGlobalProperties();
@@ -52,7 +53,7 @@ public interface PropertiesMapper {
List<Long> selectIdsByOrganizationAndUser(@Param("organizationUuid") String organizationUuid, @Param("userId") int userId);
List<Long> selectIdsByOrganizationAndMatchingLogin(@Param("organizationUuid") String organizationUuid, @Param("login") String login,
- @Param("propertyKeys") List<String> propertyKeys);
+ @Param("propertyKeys") List<String> propertyKeys);
void insertAsEmpty(@Param("key") String key, @Nullable @Param("userId") Integer userId, @Nullable @Param("componentId") Long componentId,
@Param("now") long now);
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml
index bd1f93556d3..4360431ea57 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml
@@ -46,6 +46,9 @@
and p.resource_id IS NULL
WHERE
u.email is not null
+ <if test="logins != null">
+ and u.login in <foreach collection="logins" open="(" close=")" item="login" separator=",">#{login,jdbcType=VARCHAR}</foreach>
+ </if>
<if test="projectKey != null">
UNION
@@ -65,6 +68,9 @@
and p.resource_id = c.id
WHERE
u.email is not null
+ <if test="logins != null">
+ and u.login in <foreach collection="logins" open="(" close=")" item="login" separator=",">#{login,jdbcType=VARCHAR}</foreach>
+ </if>
</if>
</select>
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java
index 4c7d01ac062..b93f129625d 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java
@@ -47,6 +47,7 @@ import org.sonar.db.component.ComponentTesting;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.UserDto;
+import static com.google.common.collect.ImmutableSet.of;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.Collections.singletonList;
@@ -172,6 +173,19 @@ public class PropertiesDaoTest {
}
@Test
+ public void findEmailRecipientsForNotification_with_logins_returns_empty_on_empty_properties_table() {
+ db.users().insertUser();
+ String dispatcherKey = randomAlphabetic(5);
+ String channelKey = randomAlphabetic(6);
+ String projectKey = randomAlphabetic(7);
+ Set<String> logins = of("user1", "user2");
+
+ Set<EmailSubscriberDto> subscribers = underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, logins);
+
+ assertThat(subscribers).isEmpty();
+ }
+
+ @Test
public void findEmailRecipientsForNotification_finds_only_globally_subscribed_users_if_projectKey_is_null() {
int userId1 = db.users().insertUser(withEmail("user1")).getId();
int userId2 = db.users().insertUser(withEmail("user2")).getId();
@@ -204,6 +218,47 @@ public class PropertiesDaoTest {
}
@Test
+ public void findEmailRecipientsForNotification_with_logins_finds_only_globally_subscribed_specified_users_if_projectKey_is_null() {
+ int userId1 = db.users().insertUser(withEmail("user1")).getId();
+ int userId2 = db.users().insertUser(withEmail("user2")).getId();
+ int userId3 = db.users().insertUser(withEmail("user3")).getId();
+ int userId4 = db.users().insertUser(withEmail("user4")).getId();
+ long projectId = insertPrivateProject("PROJECT_A").getId();
+ String dispatcherKey = randomAlphabetic(5);
+ String otherDispatcherKey = randomAlphabetic(6);
+ String channelKey = randomAlphabetic(7);
+ String otherChannelKey = randomAlphabetic(8);
+ // user1 subscribed only globally
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, userId1);
+ // user2 subscribed on project and globally
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, userId2);
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", projectId, userId2);
+ // user3 subscribed on project only
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", projectId, userId3);
+ // user4 did not subscribe
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "false", projectId, userId4);
+ Set<String> allLogins = of("user1", "user2", "user3", "user4");
+
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, allLogins))
+ .containsOnly(new EmailSubscriberDto("user1", true, emailOf("user1")), new EmailSubscriberDto("user2", true, emailOf("user2")));
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, of("user1", "user2")))
+ .containsOnly(new EmailSubscriberDto("user1", true, emailOf("user1")), new EmailSubscriberDto("user2", true, emailOf("user2")));
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, of("user2")))
+ .containsOnly(new EmailSubscriberDto("user2", true, emailOf("user2")));
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, of("user1")))
+ .containsOnly(new EmailSubscriberDto("user1", true, emailOf("user1")));
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, of()))
+ .isEmpty();
+
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, otherChannelKey, null, allLogins))
+ .isEmpty();
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), otherDispatcherKey, channelKey, null, allLogins))
+ .isEmpty();
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), channelKey, dispatcherKey, null, allLogins))
+ .isEmpty();
+ }
+
+ @Test
public void findEmailRecipientsForNotification_finds_global_and_project_subscribed_users_when_projectKey_is_non_null() {
int userId1 = db.users().insertUser(withEmail("user1")).getId();
int userId2 = db.users().insertUser(withEmail("user2")).getId();
@@ -243,6 +298,56 @@ public class PropertiesDaoTest {
}
@Test
+ public void findEmailRecipientsForNotification_with_logins_finds_global_and_project_subscribed_specified_users_when_projectKey_is_non_null() {
+ int userId1 = db.users().insertUser(withEmail("user1")).getId();
+ int userId2 = db.users().insertUser(withEmail("user2")).getId();
+ int userId3 = db.users().insertUser(withEmail("user3")).getId();
+ int userId4 = db.users().insertUser(withEmail("user4")).getId();
+ String projectKey = randomAlphabetic(3);
+ String otherProjectKey = randomAlphabetic(4);
+ long projectId = insertPrivateProject(projectKey).getId();
+ String dispatcherKey = randomAlphabetic(5);
+ String otherDispatcherKey = randomAlphabetic(6);
+ String channelKey = randomAlphabetic(7);
+ String otherChannelKey = randomAlphabetic(8);
+ // user1 subscribed only globally
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, userId1);
+ // user2 subscribed on project and globally
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, userId2);
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", projectId, userId2);
+ // user3 subscribed on project only
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", projectId, userId3);
+ // user4 did not subscribe
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "false", projectId, userId4);
+ Set<String> allLogins = of("user1", "user2", "user3", "user4");
+
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, allLogins))
+ .containsOnly(
+ new EmailSubscriberDto("user1", true, emailOf("user1")),
+ new EmailSubscriberDto("user2", true, emailOf("user2")), new EmailSubscriberDto("user2", false, "user2@foo"),
+ new EmailSubscriberDto("user3", false, emailOf("user3")));
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of("user1")))
+ .containsOnly(
+ new EmailSubscriberDto("user1", true, emailOf("user1")));
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of("user2")))
+ .containsOnly(
+ new EmailSubscriberDto("user2", true, emailOf("user2")), new EmailSubscriberDto("user2", false, "user2@foo"));
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of("user3")))
+ .containsOnly(new EmailSubscriberDto("user3", false, emailOf("user3")));
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of()))
+ .isEmpty();
+
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, otherProjectKey, allLogins))
+ .containsOnly(
+ new EmailSubscriberDto("user1", true, emailOf("user1")),
+ new EmailSubscriberDto("user2", true, emailOf("user2")));
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, otherChannelKey, otherProjectKey, allLogins))
+ .isEmpty();
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), otherDispatcherKey, channelKey, otherProjectKey, allLogins))
+ .isEmpty();
+ }
+
+ @Test
public void findEmailRecipientsForNotification_ignores_subscribed_users_without_email() {
int userId1 = db.users().insertUser(withEmail("user1")).getId();
int userId2 = db.users().insertUser(noEmail("user2")).getId();
@@ -272,6 +377,36 @@ public class PropertiesDaoTest {
}
@Test
+ public void findEmailRecipientsForNotification_with_logins_ignores_subscribed_users_without_email() {
+ int userId1 = db.users().insertUser(withEmail("user1")).getId();
+ int userId2 = db.users().insertUser(noEmail("user2")).getId();
+ int userId3 = db.users().insertUser(withEmail("user3")).getId();
+ int userId4 = db.users().insertUser(noEmail("user4")).getId();
+ Set<String> allLogins = of("user1", "user2", "user3");
+ String projectKey = randomAlphabetic(3);
+ long projectId = insertPrivateProject(projectKey).getId();
+ String dispatcherKey = randomAlphabetic(4);
+ String channelKey = randomAlphabetic(5);
+ // user1 and user2 subscribed on project and globally
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, userId1);
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", projectId, userId1);
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, userId2);
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", projectId, userId2);
+ // user3 and user4 subscribed only globally
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, userId3);
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, userId4);
+
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, allLogins))
+ .containsOnly(
+ new EmailSubscriberDto("user1", true, emailOf("user1")), new EmailSubscriberDto("user1", false, emailOf("user1")),
+ new EmailSubscriberDto("user3", true, emailOf("user3")));
+ assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, allLogins))
+ .containsOnly(
+ new EmailSubscriberDto("user1", true, emailOf("user1")),
+ new EmailSubscriberDto("user3", true, emailOf("user3")));
+ }
+
+ @Test
public void selectGlobalProperties() {
// global
long id1 = insertProperty("global.one", "one", null, null);