aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server-common
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-server-common
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-server-common')
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/ChangesOnMyIssueNotificationHandler.java6
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/MyNewIssuesNotificationHandler.java6
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/notification/DefaultNotificationManager.java35
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java14
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssueNotificationHandlerTest.java35
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/MyNewIssuesNotificationHandlerTest.java49
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/notification/DefaultNotificationManagerTest.java138
7 files changed, 224 insertions, 59 deletions
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/ChangesOnMyIssueNotificationHandler.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/ChangesOnMyIssueNotificationHandler.java
index f6e69d39f9b..7d5e5243d74 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/ChangesOnMyIssueNotificationHandler.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/ChangesOnMyIssueNotificationHandler.java
@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.CheckForNull;
import org.sonar.server.notification.EmailNotificationHandler;
@@ -89,8 +90,11 @@ public class ChangesOnMyIssueNotificationHandler extends EmailNotificationHandle
}
private Stream<? extends EmailDeliveryRequest> toEmailDeliveryRequests(String projectKey, Collection<IssueChangeNotification> notifications) {
+ Set<String> assignees = notifications.stream()
+ .map(IssueChangeNotification::getAssignee)
+ .collect(Collectors.toSet());
Map<String, EmailRecipient> recipientsByLogin = notificationManager
- .findSubscribedEmailRecipients(KEY, projectKey, ALL_MUST_HAVE_ROLE_USER)
+ .findSubscribedEmailRecipients(KEY, projectKey, assignees, ALL_MUST_HAVE_ROLE_USER)
.stream()
.collect(uniqueIndex(EmailRecipient::getLogin));
return notifications.stream()
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/MyNewIssuesNotificationHandler.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/MyNewIssuesNotificationHandler.java
index 84382720b83..9e4a19cc044 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/MyNewIssuesNotificationHandler.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/MyNewIssuesNotificationHandler.java
@@ -25,6 +25,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.CheckForNull;
import org.sonar.core.util.stream.MoreCollectors;
@@ -84,8 +85,11 @@ public class MyNewIssuesNotificationHandler extends EmailNotificationHandler<MyN
}
private Stream<? extends EmailDeliveryRequest> toEmailDeliveryRequests(String projectKey, Collection<MyNewIssuesNotification> notifications) {
+ Set<String> assignees = notifications.stream()
+ .map(MyNewIssuesNotification::getAssignee)
+ .collect(Collectors.toSet());
Map<String, NotificationManager.EmailRecipient> recipientsByLogin = notificationManager
- .findSubscribedEmailRecipients(KEY, projectKey, ALL_MUST_HAVE_ROLE_USER)
+ .findSubscribedEmailRecipients(KEY, projectKey, assignees, ALL_MUST_HAVE_ROLE_USER)
.stream()
.collect(MoreCollectors.uniqueIndex(NotificationManager.EmailRecipient::getLogin));
return notifications.stream()
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/notification/DefaultNotificationManager.java b/server/sonar-server-common/src/main/java/org/sonar/server/notification/DefaultNotificationManager.java
index e1a2eae5b7b..1106e19e0fb 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/notification/DefaultNotificationManager.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/notification/DefaultNotificationManager.java
@@ -188,16 +188,39 @@ public class DefaultNotificationManager implements NotificationManager {
try (DbSession dbSession = dbClient.openSession(false)) {
Set<EmailSubscriberDto> emailSubscribers = dbClient.propertiesDao().findEmailSubscribersForNotification(
dbSession, dispatcherKey, EmailNotificationChannel.class.getSimpleName(), projectKey);
- if (emailSubscribers.isEmpty()) {
- return emptySet();
- }
- return keepAuthorizedEmailSubscribers(dbSession, projectKey, emailSubscribers, subscriberPermissionsOnProject)
- .map(emailSubscriber -> new EmailRecipient(emailSubscriber.getLogin(), emailSubscriber.getEmail()))
- .collect(MoreCollectors.toSet());
+ return keepAuthorizedEmailSubscribers(dbSession, projectKey, subscriberPermissionsOnProject, emailSubscribers);
+ }
+ }
+
+ @Override
+ public Set<EmailRecipient> findSubscribedEmailRecipients(String dispatcherKey, String projectKey, Set<String> logins,
+ SubscriberPermissionsOnProject subscriberPermissionsOnProject) {
+ verifyProjectKey(projectKey);
+ requireNonNull(logins, "logins can't be null");
+ if (logins.isEmpty()) {
+ return emptySet();
+ }
+
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ Set<EmailSubscriberDto> emailSubscribers = dbClient.propertiesDao().findEmailSubscribersForNotification(
+ dbSession, dispatcherKey, EmailNotificationChannel.class.getSimpleName(), projectKey, logins);
+
+ return keepAuthorizedEmailSubscribers(dbSession, projectKey, subscriberPermissionsOnProject, emailSubscribers);
}
}
+ private Set<EmailRecipient> keepAuthorizedEmailSubscribers(DbSession dbSession, String projectKey,
+ SubscriberPermissionsOnProject subscriberPermissionsOnProject, Set<EmailSubscriberDto> emailSubscribers) {
+ if (emailSubscribers.isEmpty()) {
+ return emptySet();
+ }
+
+ return keepAuthorizedEmailSubscribers(dbSession, projectKey, emailSubscribers, subscriberPermissionsOnProject)
+ .map(emailSubscriber -> new EmailRecipient(emailSubscriber.getLogin(), emailSubscriber.getEmail()))
+ .collect(MoreCollectors.toSet());
+ }
+
private Stream<EmailSubscriberDto> keepAuthorizedEmailSubscribers(DbSession dbSession, String projectKey, Set<EmailSubscriberDto> emailSubscribers,
SubscriberPermissionsOnProject requiredPermissions) {
if (requiredPermissions.getGlobalSubscribers().equals(requiredPermissions.getProjectSubscribers())) {
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java b/server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java
index 6135dd4eb0c..13181fb4f2a 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java
@@ -63,6 +63,7 @@ public interface NotificationManager {
Multimap<String, NotificationChannel> findSubscribedRecipientsForDispatcher(NotificationDispatcher dispatcher, String projectKey,
SubscriberPermissionsOnProject subscriberPermissionsOnProject);
+
@Immutable
final class EmailRecipient {
private final String login;
@@ -104,8 +105,21 @@ public interface NotificationManager {
}
}
+ /**
+ * Find login and email of users which have subscribed to the email notification of the specified {@code dispatcherKey}.
+ * <p>
+ * Obviously, only subscribers which have an email are returned.
+ */
Set<EmailRecipient> findSubscribedEmailRecipients(String dispatcherKey, String projectKey, SubscriberPermissionsOnProject subscriberPermissionsOnProject);
+ /**
+ * Find email of users with the specified {@code logins} which have subscribed to the email notification of the
+ * specified {@code dispatcherKey}.
+ * <p>
+ * Obviously, only subscribers which have an email are returned.
+ */
+ Set<EmailRecipient> findSubscribedEmailRecipients(String dispatcherKey, String projectKey, Set<String> logins, SubscriberPermissionsOnProject subscriberPermissionsOnProject);
+
final class SubscriberPermissionsOnProject {
public static final SubscriberPermissionsOnProject ALL_MUST_HAVE_ROLE_USER = new SubscriberPermissionsOnProject(UserRole.USER);
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssueNotificationHandlerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssueNotificationHandlerTest.java
index 6857262e9d8..60e859a8f5f 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssueNotificationHandlerTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssueNotificationHandlerTest.java
@@ -36,7 +36,9 @@ import org.mockito.Mockito;
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.notification.NotificationManager;
import org.sonar.server.notification.email.EmailNotificationChannel;
+import org.sonar.server.notification.email.EmailNotificationChannel.EmailDeliveryRequest;
+import static java.util.Collections.singleton;
import static java.util.stream.Collectors.toSet;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
@@ -192,8 +194,8 @@ public class ChangesOnMyIssueNotificationHandlerTest {
int deliver = underTest.deliver(Stream.concat(notifications1.stream(), notifications2.stream()).collect(toSet()));
assertThat(deliver).isZero();
- verify(notificationManager).findSubscribedEmailRecipients(CHANGE_ON_MY_ISSUES_DISPATCHER_KEY, projectKey1, ALL_MUST_HAVE_ROLE_USER);
- verify(notificationManager).findSubscribedEmailRecipients(CHANGE_ON_MY_ISSUES_DISPATCHER_KEY, projectKey2, ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(CHANGE_ON_MY_ISSUES_DISPATCHER_KEY, projectKey1, singleton(assignee1), ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(CHANGE_ON_MY_ISSUES_DISPATCHER_KEY, projectKey2, singleton(assignee2), ALL_MUST_HAVE_ROLE_USER);
verifyNoMoreInteractions(notificationManager);
verify(emailNotificationChannel).isActivated();
verifyNoMoreInteractions(emailNotificationChannel);
@@ -205,17 +207,15 @@ public class ChangesOnMyIssueNotificationHandlerTest {
String projectKey = randomAlphabetic(5);
String assignee1 = randomAlphabetic(6);
String assignee2 = randomAlphabetic(7);
- String assignee3 = randomAlphabetic(8);
// assignee1 is not authorized
Set<IssueChangeNotification> assignee1Notifications = randomSetOfNotifications(projectKey, assignee1, noOrDifferentChangeAuthor);
// assignee2 is authorized
Set<IssueChangeNotification> assignee2Notifications = randomSetOfNotifications(projectKey, assignee2, noOrDifferentChangeAuthor);
- // assignee3 is authorized but has no notification
when(emailNotificationChannel.isActivated()).thenReturn(true);
- when(notificationManager.findSubscribedEmailRecipients(CHANGE_ON_MY_ISSUES_DISPATCHER_KEY, projectKey, ALL_MUST_HAVE_ROLE_USER))
- .thenReturn(ImmutableSet.of(emailRecipientOf(assignee2), emailRecipientOf(assignee3)));
- Set<EmailNotificationChannel.EmailDeliveryRequest> expectedRequests = assignee2Notifications.stream()
- .map(t -> new EmailNotificationChannel.EmailDeliveryRequest(emailOf(t.getAssignee()), t))
+ when(notificationManager.findSubscribedEmailRecipients(CHANGE_ON_MY_ISSUES_DISPATCHER_KEY, projectKey, ImmutableSet.of(assignee1, assignee2), ALL_MUST_HAVE_ROLE_USER))
+ .thenReturn(ImmutableSet.of(emailRecipientOf(assignee2)));
+ Set<EmailDeliveryRequest> expectedRequests = assignee2Notifications.stream()
+ .map(t -> new EmailDeliveryRequest(emailOf(t.getAssignee()), t))
.collect(toSet());
int deliveredCount = new Random().nextInt(expectedRequests.size());
when(emailNotificationChannel.deliver(expectedRequests)).thenReturn(deliveredCount);
@@ -223,7 +223,7 @@ public class ChangesOnMyIssueNotificationHandlerTest {
int deliver = underTest.deliver(Stream.concat(assignee1Notifications.stream(), assignee2Notifications.stream()).collect(toSet()));
assertThat(deliver).isEqualTo(deliveredCount);
- verify(notificationManager).findSubscribedEmailRecipients(CHANGE_ON_MY_ISSUES_DISPATCHER_KEY, projectKey, ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(CHANGE_ON_MY_ISSUES_DISPATCHER_KEY, projectKey, ImmutableSet.of(assignee1, assignee2), ALL_MUST_HAVE_ROLE_USER);
verifyNoMoreInteractions(notificationManager);
verify(emailNotificationChannel).isActivated();
verify(emailNotificationChannel).deliver(expectedRequests);
@@ -238,22 +238,23 @@ public class ChangesOnMyIssueNotificationHandlerTest {
String assignee3 = randomAlphabetic(8);
// assignee1 is the changeAuthor of every notification he's the assignee of
Set<IssueChangeNotification> assignee1ChangeAuthor = randomSetOfNotifications(projectKey, assignee1, assignee1);
- // assignee1 is the changeAuthor of some notification he's the assignee of
+ // assignee2 is the changeAuthor of some notification he's the assignee of
Set<IssueChangeNotification> assignee2ChangeAuthor = randomSetOfNotifications(projectKey, assignee2, assignee2);
Set<IssueChangeNotification> assignee2NotChangeAuthor = randomSetOfNotifications(projectKey, assignee2, randomAlphabetic(10));
Set<IssueChangeNotification> assignee2NoChangeAuthor = randomSetOfNotifications(projectKey, assignee2, NO_CHANGE_AUTHOR);
- // assignee2 is never the changeAuthor of the notification he's the assignee of
+ // assignee3 is never the changeAuthor of the notification he's the assignee of
Set<IssueChangeNotification> assignee3NotChangeAuthor = randomSetOfNotifications(projectKey, assignee3, randomAlphabetic(11));
Set<IssueChangeNotification> assignee3NoChangeAuthor = randomSetOfNotifications(projectKey, assignee3, NO_CHANGE_AUTHOR);
when(emailNotificationChannel.isActivated()).thenReturn(true);
- // all assignees have subscribed
- when(notificationManager.findSubscribedEmailRecipients(CHANGE_ON_MY_ISSUES_DISPATCHER_KEY, projectKey, ALL_MUST_HAVE_ROLE_USER))
- .thenReturn(ImmutableSet.of(emailRecipientOf(assignee1), emailRecipientOf(assignee2), emailRecipientOf(assignee3)));
- Set<EmailNotificationChannel.EmailDeliveryRequest> expectedRequests = Stream.of(
+ // assignees which are not changeAuthor have subscribed
+ Set<String> assigneesChangeAuthor = ImmutableSet.of(assignee2, assignee3);
+ when(notificationManager.findSubscribedEmailRecipients(CHANGE_ON_MY_ISSUES_DISPATCHER_KEY, projectKey, assigneesChangeAuthor, ALL_MUST_HAVE_ROLE_USER))
+ .thenReturn(ImmutableSet.of(emailRecipientOf(assignee2), emailRecipientOf(assignee3)));
+ Set<EmailDeliveryRequest> expectedRequests = Stream.of(
assignee2NotChangeAuthor.stream(), assignee2NoChangeAuthor.stream(),
assignee3NotChangeAuthor.stream(), assignee3NoChangeAuthor.stream())
.flatMap(t -> t)
- .map(t -> new EmailNotificationChannel.EmailDeliveryRequest(emailOf(t.getAssignee()), t))
+ .map(t -> new EmailDeliveryRequest(emailOf(t.getAssignee()), t))
.collect(toSet());
int deliveredCount = new Random().nextInt(expectedRequests.size());
when(emailNotificationChannel.deliver(expectedRequests)).thenReturn(deliveredCount);
@@ -266,7 +267,7 @@ public class ChangesOnMyIssueNotificationHandlerTest {
int deliver = underTest.deliver(notifications);
assertThat(deliver).isEqualTo(deliveredCount);
- verify(notificationManager).findSubscribedEmailRecipients(CHANGE_ON_MY_ISSUES_DISPATCHER_KEY, projectKey, ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(CHANGE_ON_MY_ISSUES_DISPATCHER_KEY, projectKey, assigneesChangeAuthor, ALL_MUST_HAVE_ROLE_USER);
verifyNoMoreInteractions(notificationManager);
verify(emailNotificationChannel).isActivated();
verify(emailNotificationChannel).deliver(expectedRequests);
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/MyNewIssuesNotificationHandlerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/MyNewIssuesNotificationHandlerTest.java
index 6a85a4ddc9f..365d3e867f9 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/MyNewIssuesNotificationHandlerTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/MyNewIssuesNotificationHandlerTest.java
@@ -19,7 +19,6 @@
*/
package org.sonar.server.issue.notification;
-import com.google.common.collect.ImmutableSet;
import java.util.Collections;
import java.util.Random;
import java.util.Set;
@@ -35,6 +34,7 @@ import org.sonar.server.notification.NotificationManager.EmailRecipient;
import org.sonar.server.notification.email.EmailNotificationChannel;
import org.sonar.server.notification.email.EmailNotificationChannel.EmailDeliveryRequest;
+import static com.google.common.collect.ImmutableSet.of;
import static java.util.Collections.emptySet;
import static java.util.stream.Collectors.toSet;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
@@ -156,13 +156,13 @@ public class MyNewIssuesNotificationHandlerTest {
String assignee = randomAlphabetic(10);
MyNewIssuesNotification notification = newNotification(projectKey, assignee);
when(emailNotificationChannel.isActivated()).thenReturn(true);
- when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, ALL_MUST_HAVE_ROLE_USER))
+ when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, of(assignee), ALL_MUST_HAVE_ROLE_USER))
.thenReturn(emptySet());
int deliver = underTest.deliver(Collections.singleton(notification));
assertThat(deliver).isZero();
- verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, of(assignee), ALL_MUST_HAVE_ROLE_USER);
verifyNoMoreInteractions(notificationManager);
verify(emailNotificationChannel).isActivated();
verifyNoMoreInteractions(emailNotificationChannel);
@@ -185,7 +185,8 @@ public class MyNewIssuesNotificationHandlerTest {
.map(n -> new EmailDeliveryRequest(n.getAssignee() + "@foo", n))
.collect(toSet());
when(emailNotificationChannel.isActivated()).thenReturn(true);
- when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, ALL_MUST_HAVE_ROLE_USER))
+ Set<String> assignees = withProjectKey.stream().map(MyNewIssuesNotification::getAssignee).collect(toSet());
+ when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, assignees, ALL_MUST_HAVE_ROLE_USER))
.thenReturn(authorizedRecipients);
Set<MyNewIssuesNotification> notifications = Stream.of(withProjectKey.stream(), noProjectKey.stream(), noProjectKeyNoAssignee.stream())
@@ -194,7 +195,7 @@ public class MyNewIssuesNotificationHandlerTest {
int deliver = underTest.deliver(notifications);
assertThat(deliver).isZero();
- verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, assignees, ALL_MUST_HAVE_ROLE_USER);
verifyNoMoreInteractions(notificationManager);
verify(emailNotificationChannel).isActivated();
verify(emailNotificationChannel).deliver(expectedRequests);
@@ -216,7 +217,8 @@ public class MyNewIssuesNotificationHandlerTest {
.map(n -> new EmailDeliveryRequest(n.getAssignee() + "@foo", n))
.collect(toSet());
when(emailNotificationChannel.isActivated()).thenReturn(true);
- when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, ALL_MUST_HAVE_ROLE_USER))
+ Set<String> assignees = withAssignee.stream().map(MyNewIssuesNotification::getAssignee).collect(toSet());
+ when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, assignees, ALL_MUST_HAVE_ROLE_USER))
.thenReturn(authorizedRecipients);
Set<MyNewIssuesNotification> notifications = Stream.of(withAssignee.stream(), noAssignee.stream(), noProjectKeyNoAssignee.stream())
@@ -225,7 +227,7 @@ public class MyNewIssuesNotificationHandlerTest {
int deliver = underTest.deliver(notifications);
assertThat(deliver).isZero();
- verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, assignees, ALL_MUST_HAVE_ROLE_USER);
verifyNoMoreInteractions(notificationManager);
verify(emailNotificationChannel).isActivated();
verify(emailNotificationChannel).deliver(expectedRequests);
@@ -241,16 +243,16 @@ public class MyNewIssuesNotificationHandlerTest {
Set<MyNewIssuesNotification> notifications1 = randomSetOfNotifications(projectKey1, assignee1);
Set<MyNewIssuesNotification> notifications2 = randomSetOfNotifications(projectKey2, assignee2);
when(emailNotificationChannel.isActivated()).thenReturn(true);
- when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey1, ALL_MUST_HAVE_ROLE_USER))
+ when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey1, of(assignee1), ALL_MUST_HAVE_ROLE_USER))
.thenReturn(emptySet());
- when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey2, ALL_MUST_HAVE_ROLE_USER))
+ when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey2, of(assignee2),ALL_MUST_HAVE_ROLE_USER))
.thenReturn(emptySet());
int deliver = underTest.deliver(Stream.concat(notifications1.stream(), notifications2.stream()).collect(toSet()));
assertThat(deliver).isZero();
- verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey1, ALL_MUST_HAVE_ROLE_USER);
- verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey2, ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey1, of(assignee1), ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey2, of(assignee2), ALL_MUST_HAVE_ROLE_USER);
verifyNoMoreInteractions(notificationManager);
verify(emailNotificationChannel).isActivated();
verifyNoMoreInteractions(emailNotificationChannel);
@@ -261,15 +263,14 @@ public class MyNewIssuesNotificationHandlerTest {
String projectKey = randomAlphabetic(5);
String assignee1 = randomAlphabetic(6);
String assignee2 = randomAlphabetic(7);
- String assignee3 = randomAlphabetic(8);
+ Set<String> assignees = of(assignee1, assignee2);
// assignee1 is not authorized
Set<MyNewIssuesNotification> assignee1Notifications = randomSetOfNotifications(projectKey, assignee1);
// assignee2 is authorized
Set<MyNewIssuesNotification> assignee2Notifications = randomSetOfNotifications(projectKey, assignee2);
- // assignee 3 is authorized but has no notification
when(emailNotificationChannel.isActivated()).thenReturn(true);
- when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, ALL_MUST_HAVE_ROLE_USER))
- .thenReturn(ImmutableSet.of(emailRecipientOf(assignee2), emailRecipientOf(assignee3)));
+ when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, assignees, ALL_MUST_HAVE_ROLE_USER))
+ .thenReturn(of(emailRecipientOf(assignee2)));
Set<EmailDeliveryRequest> expectedRequests = assignee2Notifications.stream()
.map(t -> new EmailDeliveryRequest(emailOf(t.getAssignee()), t))
.collect(toSet());
@@ -279,7 +280,7 @@ public class MyNewIssuesNotificationHandlerTest {
int deliver = underTest.deliver(Stream.concat(assignee1Notifications.stream(), assignee2Notifications.stream()).collect(toSet()));
assertThat(deliver).isEqualTo(deliveredCount);
- verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey, assignees, ALL_MUST_HAVE_ROLE_USER);
verifyNoMoreInteractions(notificationManager);
verify(emailNotificationChannel).isActivated();
verify(emailNotificationChannel).deliver(expectedRequests);
@@ -305,11 +306,11 @@ public class MyNewIssuesNotificationHandlerTest {
Set<MyNewIssuesNotification> assignee3Project2 = randomSetOfNotifications(projectKey2, assignee3);
Set<MyNewIssuesNotification> assignee3Project3 = randomSetOfNotifications(projectKey3, assignee3);
when(emailNotificationChannel.isActivated()).thenReturn(true);
- when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey1, ALL_MUST_HAVE_ROLE_USER))
- .thenReturn(ImmutableSet.of(emailRecipientOf(assignee1), emailRecipientOf(assignee2)));
- when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey2, ALL_MUST_HAVE_ROLE_USER))
- .thenReturn(ImmutableSet.of(emailRecipientOf(assignee2), emailRecipientOf(assignee3)));
- when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey3, ALL_MUST_HAVE_ROLE_USER))
+ when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey1, of(assignee1, assignee2), ALL_MUST_HAVE_ROLE_USER))
+ .thenReturn(of(emailRecipientOf(assignee1), emailRecipientOf(assignee2)));
+ when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey2, of(assignee1, assignee2, assignee3), ALL_MUST_HAVE_ROLE_USER))
+ .thenReturn(of(emailRecipientOf(assignee2), emailRecipientOf(assignee3)));
+ when(notificationManager.findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey3, of(assignee2, assignee3), ALL_MUST_HAVE_ROLE_USER))
.thenReturn(emptySet());
Set<EmailDeliveryRequest> expectedRequests = Stream.of(
assignee1Project1.stream(), assignee2Project1.stream(), assignee2Project2.stream(), assignee3Project2.stream())
@@ -328,9 +329,9 @@ public class MyNewIssuesNotificationHandlerTest {
int deliver = underTest.deliver(notifications);
assertThat(deliver).isEqualTo(deliveredCount);
- verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey1, ALL_MUST_HAVE_ROLE_USER);
- verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey2, ALL_MUST_HAVE_ROLE_USER);
- verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey3, ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey1, of(assignee1, assignee2), ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey2, of(assignee1, assignee2, assignee3), ALL_MUST_HAVE_ROLE_USER);
+ verify(notificationManager).findSubscribedEmailRecipients(MY_NEW_ISSUES_DISPATCHER_KEY, projectKey3, of(assignee2, assignee3), ALL_MUST_HAVE_ROLE_USER);
verifyNoMoreInteractions(notificationManager);
verify(emailNotificationChannel).isActivated();
verify(emailNotificationChannel).deliver(expectedRequests);
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/notification/DefaultNotificationManagerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/notification/DefaultNotificationManagerTest.java
index a78a8c5e985..d1520314553 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/notification/DefaultNotificationManagerTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/notification/DefaultNotificationManagerTest.java
@@ -272,6 +272,37 @@ public class DefaultNotificationManagerTest {
}
@Test
+ public void findSubscribedEmailRecipients_with_logins_fails_with_NPE_if_projectKey_is_null() {
+ String dispatcherKey = randomAlphabetic(12);
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("projectKey is mandatory");
+
+ underTest.findSubscribedEmailRecipients(dispatcherKey, null, ImmutableSet.of(), ALL_MUST_HAVE_ROLE_USER);
+ }
+
+ @Test
+ public void findSubscribedEmailRecipients_with_logins_fails_with_NPE_if_logins_is_null() {
+ String dispatcherKey = randomAlphabetic(12);
+ String projectKey = randomAlphabetic(6);
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("logins can't be null");
+
+ underTest.findSubscribedEmailRecipients(dispatcherKey, projectKey, null, ALL_MUST_HAVE_ROLE_USER);
+ }
+
+ @Test
+ public void findSubscribedEmailRecipients_with_logins_returns_empty_if_login_set_is_empty() {
+ String dispatcherKey = randomAlphabetic(12);
+ String projectKey = randomAlphabetic(6);
+
+ Set<EmailRecipient> recipients = underTest.findSubscribedEmailRecipients(dispatcherKey, projectKey, ImmutableSet.of(), ALL_MUST_HAVE_ROLE_USER);
+
+ assertThat(recipients).isEmpty();
+ }
+
+ @Test
public void findSubscribedEmailRecipients_returns_empty_if_no_email_recipients_in_project_for_dispatcher_key() {
String dispatcherKey = randomAlphabetic(12);
String globalPermission = randomAlphanumeric(4);
@@ -288,21 +319,33 @@ public class DefaultNotificationManagerTest {
}
@Test
+ public void findSubscribedEmailRecipients_with_logins_returns_empty_if_no_email_recipients_in_project_for_dispatcher_key() {
+ String dispatcherKey = randomAlphabetic(12);
+ String globalPermission = randomAlphanumeric(4);
+ String projectPermission = randomAlphanumeric(5);
+ String projectKey = randomAlphabetic(6);
+ Set<String> logins = IntStream.range(0, 1 + new Random().nextInt(10))
+ .mapToObj(i -> "login_" + i)
+ .collect(Collectors.toSet());
+ when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey, logins))
+ .thenReturn(Collections.emptySet());
+
+ Set<EmailRecipient> emailRecipients = underTest.findSubscribedEmailRecipients(dispatcherKey, projectKey, logins,
+ new SubscriberPermissionsOnProject(globalPermission, projectPermission));
+ assertThat(emailRecipients).isEmpty();
+
+ verify(authorizationDao, times(0)).keepAuthorizedLoginsOnProject(any(DbSession.class), anySet(), anyString(), anyString());
+ }
+
+ @Test
public void findSubscribedEmailRecipients_applies_distinct_permission_filtering_global_or_project_subscribers() {
String dispatcherKey = randomAlphabetic(12);
- String otherDispatcherKey = randomAlphabetic(13);
String globalPermission = randomAlphanumeric(4);
String projectPermission = randomAlphanumeric(5);
String projectKey = randomAlphabetic(6);
- String otherProjectKey = randomAlphabetic(7);
when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey))
.thenReturn(
newHashSet(new EmailSubscriberDto("user1", false, "user1@foo"), new EmailSubscriberDto("user3", false, "user3@foo"), new EmailSubscriberDto("user3", true, "user3@foo")));
- when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", otherProjectKey))
- .thenReturn(newHashSet(new EmailSubscriberDto("user2", false, "user2@foo")));
- when(propertiesDao.findEmailSubscribersForNotification(dbSession, otherDispatcherKey, "EmailNotificationChannel", projectKey))
- .thenReturn(newHashSet(new EmailSubscriberDto("user4", true, "user4@foo")));
-
when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user3", "user4"), projectKey, globalPermission))
.thenReturn(newHashSet("user3"));
when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user1", "user3"), projectKey, projectPermission))
@@ -319,7 +362,32 @@ public class DefaultNotificationManagerTest {
}
@Test
- public void findSubscribedEmailRecipients_do_not_call_db_for_project_permission_filtering_if_there_is_no_project_subscriber() {
+ public void findSubscribedEmailRecipients_with_logins_applies_distinct_permission_filtering_global_or_project_subscribers() {
+ String dispatcherKey = randomAlphabetic(12);
+ String globalPermission = randomAlphanumeric(4);
+ String projectPermission = randomAlphanumeric(5);
+ String projectKey = randomAlphabetic(6);
+ Set<String> logins = ImmutableSet.of("user1", "user2", "user3");
+ when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey, logins))
+ .thenReturn(
+ newHashSet(new EmailSubscriberDto("user1", false, "user1@foo"), new EmailSubscriberDto("user3", false, "user3@foo"), new EmailSubscriberDto("user3", true, "user3@foo")));
+ when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user3", "user4"), projectKey, globalPermission))
+ .thenReturn(newHashSet("user3"));
+ when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, newHashSet("user1", "user3"), projectKey, projectPermission))
+ .thenReturn(newHashSet("user1", "user3"));
+
+ Set<EmailRecipient> emailRecipients = underTest.findSubscribedEmailRecipients(dispatcherKey, projectKey, logins,
+ new SubscriberPermissionsOnProject(globalPermission, projectPermission));
+ assertThat(emailRecipients)
+ .isEqualTo(ImmutableSet.of(new EmailRecipient("user1", "user1@foo"), new EmailRecipient("user3", "user3@foo")));
+
+ // code is optimized to perform only 2 SQL requests for all channels
+ verify(authorizationDao, times(1)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(globalPermission));
+ verify(authorizationDao, times(1)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(projectPermission));
+ }
+
+ @Test
+ public void findSubscribedEmailRecipients_does_not_call_db_for_project_permission_filtering_if_there_is_no_project_subscriber() {
String dispatcherKey = randomAlphabetic(12);
String globalPermission = randomAlphanumeric(4);
String projectPermission = randomAlphanumeric(5);
@@ -327,9 +395,9 @@ public class DefaultNotificationManagerTest {
Set<EmailSubscriberDto> subscribers = IntStream.range(0, 1 + new Random().nextInt(10))
.mapToObj(i -> new EmailSubscriberDto("user" + i, true, "user" + i + "@sonarsource.com"))
.collect(Collectors.toSet());
+ Set<String> logins = subscribers.stream().map(EmailSubscriberDto::getLogin).collect(Collectors.toSet());
when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey))
.thenReturn(subscribers);
- Set<String> logins = subscribers.stream().map(EmailSubscriberDto::getLogin).collect(Collectors.toSet());
when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, logins, projectKey, globalPermission))
.thenReturn(logins);
@@ -344,6 +412,31 @@ public class DefaultNotificationManagerTest {
}
@Test
+ public void findSubscribedEmailRecipients_with_logins_does_not_call_db_for_project_permission_filtering_if_there_is_no_project_subscriber() {
+ String dispatcherKey = randomAlphabetic(12);
+ String globalPermission = randomAlphanumeric(4);
+ String projectPermission = randomAlphanumeric(5);
+ String projectKey = randomAlphabetic(6);
+ Set<EmailSubscriberDto> subscribers = IntStream.range(0, 1 + new Random().nextInt(10))
+ .mapToObj(i -> new EmailSubscriberDto("user" + i, true, "user" + i + "@sonarsource.com"))
+ .collect(Collectors.toSet());
+ Set<String> logins = subscribers.stream().map(EmailSubscriberDto::getLogin).collect(Collectors.toSet());
+ when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey, logins))
+ .thenReturn(subscribers);
+ when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, logins, projectKey, globalPermission))
+ .thenReturn(logins);
+
+ Set<EmailRecipient> emailRecipients = underTest.findSubscribedEmailRecipients(dispatcherKey, projectKey, logins,
+ new SubscriberPermissionsOnProject(globalPermission, projectPermission));
+ Set<EmailRecipient> expected = subscribers.stream().map(i -> new EmailRecipient(i.getLogin(), i.getEmail())).collect(Collectors.toSet());
+ assertThat(emailRecipients)
+ .isEqualTo(expected);
+
+ verify(authorizationDao, times(1)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(globalPermission));
+ verify(authorizationDao, times(0)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(projectPermission));
+ }
+
+ @Test
public void findSubscribedEmailRecipients_does_not_call_DB_for_project_permission_filtering_if_there_is_no_global_subscriber() {
String dispatcherKey = randomAlphabetic(12);
String globalPermission = randomAlphanumeric(4);
@@ -352,9 +445,9 @@ public class DefaultNotificationManagerTest {
Set<EmailSubscriberDto> subscribers = IntStream.range(0, 1 + new Random().nextInt(10))
.mapToObj(i -> new EmailSubscriberDto("user" + i, false, "user" + i + "@sonarsource.com"))
.collect(Collectors.toSet());
+ Set<String> logins = subscribers.stream().map(EmailSubscriberDto::getLogin).collect(Collectors.toSet());
when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey))
.thenReturn(subscribers);
- Set<String> logins = subscribers.stream().map(EmailSubscriberDto::getLogin).collect(Collectors.toSet());
when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, logins, projectKey, projectPermission))
.thenReturn(logins);
@@ -367,4 +460,29 @@ public class DefaultNotificationManagerTest {
verify(authorizationDao, times(0)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(globalPermission));
verify(authorizationDao, times(1)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(projectPermission));
}
+
+ @Test
+ public void findSubscribedEmailRecipients_with_logins_does_not_call_DB_for_project_permission_filtering_if_there_is_no_global_subscriber() {
+ String dispatcherKey = randomAlphabetic(12);
+ String globalPermission = randomAlphanumeric(4);
+ String projectPermission = randomAlphanumeric(5);
+ String projectKey = randomAlphabetic(6);
+ Set<EmailSubscriberDto> subscribers = IntStream.range(0, 1 + new Random().nextInt(10))
+ .mapToObj(i -> new EmailSubscriberDto("user" + i, false, "user" + i + "@sonarsource.com"))
+ .collect(Collectors.toSet());
+ Set<String> logins = subscribers.stream().map(EmailSubscriberDto::getLogin).collect(Collectors.toSet());
+ when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey, logins))
+ .thenReturn(subscribers);
+ when(authorizationDao.keepAuthorizedLoginsOnProject(dbSession, logins, projectKey, projectPermission))
+ .thenReturn(logins);
+
+ Set<EmailRecipient> emailRecipients = underTest.findSubscribedEmailRecipients(dispatcherKey, projectKey, logins,
+ new SubscriberPermissionsOnProject(globalPermission, projectPermission));
+ Set<EmailRecipient> expected = subscribers.stream().map(i -> new EmailRecipient(i.getLogin(), i.getEmail())).collect(Collectors.toSet());
+ assertThat(emailRecipients)
+ .isEqualTo(expected);
+
+ verify(authorizationDao, times(0)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(globalPermission));
+ verify(authorizationDao, times(1)).keepAuthorizedLoginsOnProject(eq(dbSession), anySet(), anyString(), eq(projectPermission));
+ }
}