aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/sonar-email-notifications-plugin/src
diff options
context:
space:
mode:
authorFabrice Bellingard <fabrice.bellingard@sonarsource.com>2013-01-24 16:07:51 +0100
committerFabrice Bellingard <fabrice.bellingard@sonarsource.com>2013-01-24 16:08:35 +0100
commit30d668f520e3972de197ab1c8f5bfd4972a481b1 (patch)
treecfe84ec7f16908313b3635182a59668eaaf20362 /plugins/sonar-email-notifications-plugin/src
parentaac947247b9e0754d4c52344fc2efc00cf40138f (diff)
downloadsonarqube-30d668f520e3972de197ab1c8f5bfd4972a481b1.tar.gz
sonarqube-30d668f520e3972de197ab1c8f5bfd4972a481b1.zip
SONAR-2746 Email new alerts on favorite projects
Diffstat (limited to 'plugins/sonar-email-notifications-plugin/src')
-rw-r--r--plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/EmailNotificationsPlugin.java14
-rw-r--r--plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/alerts/AlertsEmailTemplate.java107
-rw-r--r--plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/alerts/AlertsOnMyFavouriteProject.java53
-rw-r--r--plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/alerts/AlertsEmailTemplateTest.java131
-rw-r--r--plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/alerts/AlertsOnMyFavouriteProjectTest.java62
5 files changed, 364 insertions, 3 deletions
diff --git a/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/EmailNotificationsPlugin.java b/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/EmailNotificationsPlugin.java
index bf46289eb47..61051c38e10 100644
--- a/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/EmailNotificationsPlugin.java
+++ b/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/EmailNotificationsPlugin.java
@@ -22,6 +22,8 @@ package org.sonar.plugins.emailnotifications;
import com.google.common.collect.ImmutableList;
import org.sonar.api.ServerExtension;
import org.sonar.api.SonarPlugin;
+import org.sonar.plugins.emailnotifications.alerts.AlertsEmailTemplate;
+import org.sonar.plugins.emailnotifications.alerts.AlertsOnMyFavouriteProject;
import org.sonar.plugins.emailnotifications.newviolations.NewViolationsEmailTemplate;
import org.sonar.plugins.emailnotifications.newviolations.NewViolationsOnMyFavouriteProject;
import org.sonar.plugins.emailnotifications.reviews.ChangesInReviewAssignedToMeOrCreatedByMe;
@@ -32,10 +34,16 @@ import java.util.List;
public class EmailNotificationsPlugin extends SonarPlugin {
public List<Class<? extends ServerExtension>> getExtensions() {
return ImmutableList.of(
- ChangesInReviewAssignedToMeOrCreatedByMe.class,
EmailNotificationChannel.class,
- NewViolationsEmailTemplate.class,
+ // Notify incoming violations on my favourite projects
NewViolationsOnMyFavouriteProject.class,
- ReviewEmailTemplate.class);
+ NewViolationsEmailTemplate.class,
+ // Notify reviews changes
+ ChangesInReviewAssignedToMeOrCreatedByMe.class,
+ ReviewEmailTemplate.class,
+ // Notify alerts on my favourite projects
+ AlertsOnMyFavouriteProject.class,
+ AlertsEmailTemplate.class
+ );
}
}
diff --git a/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/alerts/AlertsEmailTemplate.java b/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/alerts/AlertsEmailTemplate.java
new file mode 100644
index 00000000000..96d96cb3ad7
--- /dev/null
+++ b/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/alerts/AlertsEmailTemplate.java
@@ -0,0 +1,107 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.emailnotifications.alerts;
+
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.config.EmailSettings;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.notifications.Notification;
+import org.sonar.plugins.emailnotifications.api.EmailMessage;
+import org.sonar.plugins.emailnotifications.api.EmailTemplate;
+
+/**
+ * Creates email message for notification "alerts".
+ *
+ * @since 3.5
+ */
+public class AlertsEmailTemplate extends EmailTemplate {
+
+ private EmailSettings configuration;
+
+ public AlertsEmailTemplate(EmailSettings configuration) {
+ this.configuration = configuration;
+ }
+
+ @Override
+ public EmailMessage format(Notification notification) {
+ if (!"alerts".equals(notification.getType())) {
+ return null;
+ }
+
+ // Retrieve useful values
+ String projectId = notification.getFieldValue("projectId");
+ String projectKey = notification.getFieldValue("projectKey");
+ String projectName = notification.getFieldValue("projectName");
+ String alertName = notification.getFieldValue("alertName");
+ String alertText = notification.getFieldValue("alertText");
+ String alertLevel = notification.getFieldValue("alertLevel");
+ boolean isNewAlert = Boolean.valueOf(notification.getFieldValue("isNewAlert"));
+
+ // Generate text
+ String subject = generateSubject(projectName, alertLevel, isNewAlert);
+ String messageBody = generateMessageBody(projectName, projectKey, alertName, alertText, isNewAlert);
+
+ // And finally return the email that will be sent
+ return new EmailMessage()
+ .setMessageId("alerts/" + projectId)
+ .setSubject(subject)
+ .setMessage(messageBody);
+ }
+
+ private String generateSubject(String projectName, String alertLevel, boolean isNewAlert) {
+ StringBuilder subjectBuilder = new StringBuilder();
+ if (Metric.Level.OK.toString().equals(alertLevel)) {
+ subjectBuilder.append("\"").append(projectName).append("\" is back to green");
+ } else if (isNewAlert) {
+ subjectBuilder.append("New alert on \"").append(projectName).append("\"");
+ } else {
+ subjectBuilder.append("Alert level changed on \"").append(projectName).append("\"");
+ }
+ return subjectBuilder.toString();
+ }
+
+ private String generateMessageBody(String projectName, String projectKey, String alertName, String alertText, boolean isNewAlert) {
+ StringBuilder messageBody = new StringBuilder();
+ messageBody.append("Project: ").append(projectName).append("\n");
+ messageBody.append("Alert level: ").append(alertName).append("\n\n");
+
+ String[] alerts = StringUtils.split(alertText, ",");
+ if (alerts.length > 0) {
+ if (isNewAlert) {
+ messageBody.append("New alert");
+ } else {
+ messageBody.append("Alert");
+ }
+ if (alerts.length == 1) {
+ messageBody.append(": ").append(alerts[0].trim()).append("\n");
+ } else {
+ messageBody.append("s:\n");
+ for (String alert : alerts) {
+ messageBody.append(" - ").append(alert.trim()).append("\n");
+ }
+ }
+ }
+
+ messageBody.append("\n").append("See it in Sonar: ").append(configuration.getServerBaseURL()).append("/dashboard/index/").append(projectKey);
+
+ return messageBody.toString();
+ }
+
+}
diff --git a/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/alerts/AlertsOnMyFavouriteProject.java b/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/alerts/AlertsOnMyFavouriteProject.java
new file mode 100644
index 00000000000..38a46a6ca49
--- /dev/null
+++ b/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/alerts/AlertsOnMyFavouriteProject.java
@@ -0,0 +1,53 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.emailnotifications.alerts;
+
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.notifications.Notification;
+import org.sonar.api.notifications.NotificationDispatcher;
+import org.sonar.core.properties.PropertiesDao;
+
+import java.util.List;
+
+/**
+ * This dispatcher means: "notify me when alerts are raised on projects that I flagged as favourite".
+ *
+ * @since 3.5
+ */
+public class AlertsOnMyFavouriteProject extends NotificationDispatcher {
+
+ private PropertiesDao propertiesDao;
+
+ public AlertsOnMyFavouriteProject(PropertiesDao propertiesDao) {
+ this.propertiesDao = propertiesDao;
+ }
+
+ @Override
+ public void dispatch(Notification notification, Context context) {
+ if (StringUtils.equals(notification.getType(), "alerts")) {
+ Long projectId = Long.parseLong(notification.getFieldValue("projectId"));
+ List<String> userLogins = propertiesDao.findUserIdsForFavouriteResource(projectId);
+ for (String userLogin : userLogins) {
+ context.addUser(userLogin);
+ }
+ }
+ }
+
+}
diff --git a/plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/alerts/AlertsEmailTemplateTest.java b/plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/alerts/AlertsEmailTemplateTest.java
new file mode 100644
index 00000000000..1a68497f1c9
--- /dev/null
+++ b/plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/alerts/AlertsEmailTemplateTest.java
@@ -0,0 +1,131 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.emailnotifications.alerts;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.EmailSettings;
+import org.sonar.api.notifications.Notification;
+import org.sonar.plugins.emailnotifications.api.EmailMessage;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class AlertsEmailTemplateTest {
+
+ private AlertsEmailTemplate template;
+
+ @Before
+ public void setUp() {
+ EmailSettings configuration = mock(EmailSettings.class);
+ when(configuration.getServerBaseURL()).thenReturn("http://nemo.sonarsource.org");
+ template = new AlertsEmailTemplate(configuration);
+ }
+
+ @Test
+ public void shouldNotFormatIfNotCorrectNotification() {
+ Notification notification = new Notification("other-notif");
+ EmailMessage message = template.format(notification);
+ assertThat(message, nullValue());
+ }
+
+ @Test
+ public void shouldFormatAlertWithSeveralMessages() {
+ Notification notification = createNotification("Orange (was Red)", "violations > 4, coverage < 75%", "WARN", "false");
+
+ EmailMessage message = template.format(notification);
+ assertThat(message.getMessageId(), is("alerts/45"));
+ assertThat(message.getSubject(), is("Alert level changed on \"Foo\""));
+ assertThat(message.getMessage(), is("" +
+ "Project: Foo\n" +
+ "Alert level: Orange (was Red)\n" +
+ "\n" +
+ "Alerts:\n" +
+ " - violations > 4\n" +
+ " - coverage < 75%\n" +
+ "\n" +
+ "See it in Sonar: http://nemo.sonarsource.org/dashboard/index/org.sonar.foo:foo"));
+ }
+
+ @Test
+ public void shouldFormatNewAlertWithSeveralMessages() {
+ Notification notification = createNotification("Orange (was Red)", "violations > 4, coverage < 75%", "WARN", "true");
+
+ EmailMessage message = template.format(notification);
+ assertThat(message.getMessageId(), is("alerts/45"));
+ assertThat(message.getSubject(), is("New alert on \"Foo\""));
+ assertThat(message.getMessage(), is("" +
+ "Project: Foo\n" +
+ "Alert level: Orange (was Red)\n" +
+ "\n" +
+ "New alerts:\n" +
+ " - violations > 4\n" +
+ " - coverage < 75%\n" +
+ "\n" +
+ "See it in Sonar: http://nemo.sonarsource.org/dashboard/index/org.sonar.foo:foo"));
+ }
+
+ @Test
+ public void shouldFormatNewAlertWithOneMessage() {
+ Notification notification = createNotification("Orange (was Red)", "violations > 4", "WARN", "true");
+
+ EmailMessage message = template.format(notification);
+ assertThat(message.getMessageId(), is("alerts/45"));
+ assertThat(message.getSubject(), is("New alert on \"Foo\""));
+ assertThat(message.getMessage(), is("" +
+ "Project: Foo\n" +
+ "Alert level: Orange (was Red)\n" +
+ "\n" +
+ "New alert: violations > 4\n" +
+ "\n" +
+ "See it in Sonar: http://nemo.sonarsource.org/dashboard/index/org.sonar.foo:foo"));
+ }
+
+ @Test
+ public void shouldFormatBackToGreenMessage() {
+ Notification notification = createNotification("Green (was Red)", "", "OK", "false");
+
+ EmailMessage message = template.format(notification);
+ assertThat(message.getMessageId(), is("alerts/45"));
+ assertThat(message.getSubject(), is("\"Foo\" is back to green"));
+ assertThat(message.getMessage(), is("" +
+ "Project: Foo\n" +
+ "Alert level: Green (was Red)\n" +
+ "\n" +
+ "\n" +
+ "See it in Sonar: http://nemo.sonarsource.org/dashboard/index/org.sonar.foo:foo"));
+ }
+
+ private Notification createNotification(String alertName, String alertText, String alertLevel, String isNewAlert) {
+ Notification notification = new Notification("alerts")
+ .setFieldValue("projectName", "Foo")
+ .setFieldValue("projectKey", "org.sonar.foo:foo")
+ .setFieldValue("projectId", "45")
+ .setFieldValue("alertName", alertName)
+ .setFieldValue("alertText", alertText)
+ .setFieldValue("alertLevel", alertLevel)
+ .setFieldValue("isNewAlert", isNewAlert);
+ return notification;
+ }
+
+}
diff --git a/plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/alerts/AlertsOnMyFavouriteProjectTest.java b/plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/alerts/AlertsOnMyFavouriteProjectTest.java
new file mode 100644
index 00000000000..fe29748d332
--- /dev/null
+++ b/plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/alerts/AlertsOnMyFavouriteProjectTest.java
@@ -0,0 +1,62 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.emailnotifications.alerts;
+
+import com.google.common.collect.Lists;
+import org.junit.Test;
+import org.sonar.api.notifications.Notification;
+import org.sonar.api.notifications.NotificationDispatcher;
+import org.sonar.core.properties.PropertiesDao;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+public class AlertsOnMyFavouriteProjectTest {
+
+ @Test
+ public void shouldNotDispatchIfNotNewViolationsNotification() throws Exception {
+ NotificationDispatcher.Context context = mock(NotificationDispatcher.Context.class);
+ AlertsOnMyFavouriteProject dispatcher = new AlertsOnMyFavouriteProject(null);
+ Notification notification = new Notification("other-notif");
+ dispatcher.dispatch(notification, context);
+
+ verify(context, never()).addUser(any(String.class));
+ }
+
+ @Test
+ public void shouldDispatchToUsersWhoHaveFlaggedProjectAsFavourite() {
+ NotificationDispatcher.Context context = mock(NotificationDispatcher.Context.class);
+ PropertiesDao propertiesDao = mock(PropertiesDao.class);
+ when(propertiesDao.findUserIdsForFavouriteResource(34L)).thenReturn(Lists.newArrayList("user1", "user2"));
+ AlertsOnMyFavouriteProject dispatcher = new AlertsOnMyFavouriteProject(propertiesDao);
+
+ Notification notification = new Notification("alerts").setFieldValue("projectId", "34");
+ dispatcher.dispatch(notification, context);
+
+ verify(context).addUser("user1");
+ verify(context).addUser("user2");
+ verifyNoMoreInteractions(context);
+ }
+
+}