aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2017-06-20 08:35:37 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2017-06-29 17:23:19 +0200
commit44eaa37244f20ca311a1a797c961c80706b35251 (patch)
treebd7994fe9a9f2010b4e2e3737be167af27ba8d1c
parent6f754683a488d38ae95e3f6143f81a1b8f24b0fb (diff)
downloadsonarqube-44eaa37244f20ca311a1a797c961c80706b35251.tar.gz
sonarqube-44eaa37244f20ca311a1a797c961c80706b35251.zip
SONAR-9442 Send email to profile admin on each qprofile update
-rw-r--r--it/it-plugins/foo-plugin-v1/pom.xml75
-rw-r--r--it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java43
-rw-r--r--it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java39
-rw-r--r--it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/package-info.java23
-rw-r--r--it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooBasicProfile.java41
-rw-r--r--it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java46
-rw-r--r--it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/package-info.java23
-rw-r--r--it/it-plugins/foo-plugin-v2/pom.xml75
-rw-r--r--it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java43
-rw-r--r--it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java39
-rw-r--r--it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/package-info.java23
-rw-r--r--it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooBasicProfile.java42
-rw-r--r--it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java46
-rw-r--r--it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/package-info.java23
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java6
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationMapper.java2
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/permission/AuthorizationMapper.xml18
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java47
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/notification/NotificationModule.java13
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/notification/ws/NotificationWsModule.java34
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java9
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotification.java41
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcher.java59
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplate.java42
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java7
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/notification/NotificationModuleTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/notification/ws/NotificationWsModuleTest.java34
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcherTest.java61
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java35
-rw-r--r--tests/plugins/foo-plugin-v1/pom.xml75
-rw-r--r--tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java43
-rw-r--r--tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java39
-rw-r--r--tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/package-info.java23
-rw-r--r--tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooBasicProfile.java41
-rw-r--r--tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java46
-rw-r--r--tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/package-info.java23
-rw-r--r--tests/plugins/foo-plugin-v2/pom.xml75
-rw-r--r--tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java43
-rw-r--r--tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java39
-rw-r--r--tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/package-info.java23
-rw-r--r--tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooBasicProfile.java42
-rw-r--r--tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java46
-rw-r--r--tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/package-info.java23
-rw-r--r--tests/plugins/pom.xml2
-rw-r--r--tests/src/test/java/org/sonarqube/tests/Category5Suite.java8
-rw-r--r--tests/src/test/java/org/sonarqube/tests/qualityProfile/BuiltInQualityProfilesNotificationTest.java176
-rw-r--r--tests/src/test/java/util/ItUtils.java2
48 files changed, 1739 insertions, 23 deletions
diff --git a/it/it-plugins/foo-plugin-v1/pom.xml b/it/it-plugins/foo-plugin-v1/pom.xml
new file mode 100644
index 00000000000..e34322baece
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v1/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.sonarsource.sonarqube</groupId>
+ <artifactId>sonarqube</artifactId>
+ <version>6.5-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+ <artifactId>foo-plugin-v1</artifactId>
+ <name>SonarQube :: Plugins :: Foo (V1)</name>
+ <packaging>sonar-plugin</packaging>
+ <description>Sample of plugin to document and test available APIs</description>
+
+ <properties>
+ <sonar.skip>true</sonar.skip>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonarsource.sonarqube</groupId>
+ <artifactId>sonar-plugin-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- unit testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
+ <artifactId>sonar-packaging-maven-plugin</artifactId>
+ <configuration>
+ <pluginKey>foo</pluginKey>
+ <pluginName>Foo</pluginName>
+ <pluginClass>org.sonar.foo.FooPlugin</pluginClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java
new file mode 100644
index 00000000000..522bc81483d
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java
@@ -0,0 +1,43 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo;
+
+import org.sonar.api.resources.Language;
+
+public class Foo implements Language {
+
+ public static final String KEY = "foo";
+ public static final String NAME = "foo";
+
+ @Override
+ public String getKey() {
+ return KEY;
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public String[] getFileSuffixes() {
+ return new String[0];
+ }
+}
diff --git a/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java
new file mode 100644
index 00000000000..17677e0acb2
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java
@@ -0,0 +1,39 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo;
+
+import org.sonar.api.Plugin;
+import org.sonar.foo.rule.FooBasicProfile;
+import org.sonar.foo.rule.FooRulesDefinition;
+
+/**
+ * Plugin entry-point, as declared in pom.xml.
+ */
+public class FooPlugin implements Plugin {
+
+ @Override
+ public void define(Context context) {
+ context.addExtensions(
+ Foo.class,
+ FooRulesDefinition.class,
+ FooBasicProfile.class);
+ }
+
+}
diff --git a/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/package-info.java b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/package-info.java
new file mode 100644
index 00000000000..24613bbdaf7
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooBasicProfile.java b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooBasicProfile.java
new file mode 100644
index 00000000000..3a53e9293ff
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooBasicProfile.java
@@ -0,0 +1,41 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo.rule;
+
+import org.sonar.api.profiles.ProfileDefinition;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.utils.ValidationMessages;
+
+import static org.sonar.api.rules.RulePriority.MAJOR;
+import static org.sonar.foo.Foo.KEY;
+import static org.sonar.foo.rule.FooRulesDefinition.FOO_REPOSITORY;
+
+public class FooBasicProfile extends ProfileDefinition {
+
+ @Override
+ public RulesProfile createProfile(ValidationMessages validation) {
+ final RulesProfile profile = RulesProfile.create("Basic", KEY);
+ profile.activateRule(Rule.create(FOO_REPOSITORY, "UnchangedRule"), MAJOR);
+ profile.activateRule(Rule.create(FOO_REPOSITORY, "ChangedRule"), MAJOR);
+ profile.activateRule(Rule.create(FOO_REPOSITORY, "RemovedRule"), MAJOR);
+ return profile;
+ }
+}
diff --git a/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java
new file mode 100644
index 00000000000..7257dd72681
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java
@@ -0,0 +1,46 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo.rule;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.foo.Foo;
+
+public class FooRulesDefinition implements RulesDefinition {
+
+ public static final String FOO_REPOSITORY = "foo";
+
+ @Override
+ public void define(Context context) {
+ defineRulesXoo(context);
+ }
+
+ private static void defineRulesXoo(Context context) {
+ NewRepository repo = context.createRepository(FOO_REPOSITORY, Foo.KEY).setName("Foo");
+ createRule(repo, "UnchangedRule");
+ createRule(repo, "ChangedRule");
+ createRule(repo, "RemovedRule");
+ repo.done();
+ }
+
+ private static NewRule createRule(NewRepository repo, String key) {
+ return repo.createRule(key).setName(key).setHtmlDescription(key);
+ }
+
+}
diff --git a/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/package-info.java b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/package-info.java
new file mode 100644
index 00000000000..b3209c8ac96
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo.rule;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/it/it-plugins/foo-plugin-v2/pom.xml b/it/it-plugins/foo-plugin-v2/pom.xml
new file mode 100644
index 00000000000..db2fc2c5916
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v2/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.sonarsource.sonarqube</groupId>
+ <artifactId>sonarqube</artifactId>
+ <version>6.5-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+ <artifactId>foo-plugin-v2</artifactId>
+ <name>SonarQube :: Plugins :: Foo (V2)</name>
+ <packaging>sonar-plugin</packaging>
+ <description>Sample of plugin to document and test available APIs</description>
+
+ <properties>
+ <sonar.skip>true</sonar.skip>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonarsource.sonarqube</groupId>
+ <artifactId>sonar-plugin-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- unit testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
+ <artifactId>sonar-packaging-maven-plugin</artifactId>
+ <configuration>
+ <pluginKey>foo</pluginKey>
+ <pluginName>Foo</pluginName>
+ <pluginClass>org.sonar.foo.FooPlugin</pluginClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java
new file mode 100644
index 00000000000..522bc81483d
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java
@@ -0,0 +1,43 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo;
+
+import org.sonar.api.resources.Language;
+
+public class Foo implements Language {
+
+ public static final String KEY = "foo";
+ public static final String NAME = "foo";
+
+ @Override
+ public String getKey() {
+ return KEY;
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public String[] getFileSuffixes() {
+ return new String[0];
+ }
+}
diff --git a/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java
new file mode 100644
index 00000000000..17677e0acb2
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java
@@ -0,0 +1,39 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo;
+
+import org.sonar.api.Plugin;
+import org.sonar.foo.rule.FooBasicProfile;
+import org.sonar.foo.rule.FooRulesDefinition;
+
+/**
+ * Plugin entry-point, as declared in pom.xml.
+ */
+public class FooPlugin implements Plugin {
+
+ @Override
+ public void define(Context context) {
+ context.addExtensions(
+ Foo.class,
+ FooRulesDefinition.class,
+ FooBasicProfile.class);
+ }
+
+}
diff --git a/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/package-info.java b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/package-info.java
new file mode 100644
index 00000000000..24613bbdaf7
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooBasicProfile.java b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooBasicProfile.java
new file mode 100644
index 00000000000..1c2d051f7cf
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooBasicProfile.java
@@ -0,0 +1,42 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo.rule;
+
+import org.sonar.api.profiles.ProfileDefinition;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.utils.ValidationMessages;
+
+import static org.sonar.api.rules.RulePriority.MAJOR;
+import static org.sonar.api.rules.RulePriority.MINOR;
+import static org.sonar.foo.Foo.KEY;
+import static org.sonar.foo.rule.FooRulesDefinition.FOO_REPOSITORY;
+
+public class FooBasicProfile extends ProfileDefinition {
+
+ @Override
+ public RulesProfile createProfile(ValidationMessages validation) {
+ final RulesProfile profile = RulesProfile.create("Basic", KEY);
+ profile.activateRule(Rule.create(FOO_REPOSITORY, "UnchangedRule"), MAJOR);
+ profile.activateRule(Rule.create(FOO_REPOSITORY, "ChangedRule"), MINOR);
+ profile.activateRule(Rule.create(FOO_REPOSITORY, "NewRule"), MAJOR);
+ return profile;
+ }
+}
diff --git a/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java
new file mode 100644
index 00000000000..aacc2335262
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java
@@ -0,0 +1,46 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo.rule;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.foo.Foo;
+
+public class FooRulesDefinition implements RulesDefinition {
+
+ public static final String FOO_REPOSITORY = "foo";
+
+ @Override
+ public void define(Context context) {
+ defineRulesXoo(context);
+ }
+
+ private static void defineRulesXoo(Context context) {
+ NewRepository repo = context.createRepository(FOO_REPOSITORY, Foo.KEY).setName("Foo");
+ createRule(repo, "UnchangedRule");
+ createRule(repo, "ChangedRule");
+ createRule(repo, "NewRule");
+ repo.done();
+ }
+
+ private static NewRule createRule(NewRepository repo, String key) {
+ return repo.createRule(key).setName(key).setHtmlDescription(key);
+ }
+
+}
diff --git a/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/package-info.java b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/package-info.java
new file mode 100644
index 00000000000..b3209c8ac96
--- /dev/null
+++ b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo.rule;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java
index 2e0c94c29af..44afc088c09 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java
@@ -20,6 +20,7 @@
package org.sonar.db.permission;
import java.util.Collection;
+import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import org.sonar.db.Dao;
@@ -27,6 +28,7 @@ import org.sonar.db.DbSession;
import static org.sonar.db.DatabaseUtils.executeLargeInputs;
import static org.sonar.db.DatabaseUtils.executeLargeInputsIntoSet;
+import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
/**
* The SQL requests used to verify authorization (the permissions
@@ -163,6 +165,10 @@ public class AuthorizationDao implements Dao {
partitionSize -> partitionSize / 3);
}
+ public List<String> selectQualityProfileAdministratorLogins(DbSession dbSession) {
+ return mapper(dbSession).selectQualityProfileAdministratorLogins(ADMINISTER_QUALITY_PROFILES.getKey());
+ }
+
private static AuthorizationMapper mapper(DbSession dbSession) {
return dbSession.getMapper(AuthorizationMapper.class);
}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationMapper.java
index e60588cf1bd..5c76c4ea5d4 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationMapper.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationMapper.java
@@ -60,4 +60,6 @@ public interface AuthorizationMapper {
Set<String> selectProjectPermissions(@Param("projectUuid") String projectUuid, @Param("userId") long userId);
Set<String> selectProjectPermissionsOfAnonymous(@Param("projectUuid") String projectUuid);
+
+ List<String> selectQualityProfileAdministratorLogins(@Param("permission") String permission);
}
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/permission/AuthorizationMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/permission/AuthorizationMapper.xml
index 181292874bb..76dd716a1f5 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/permission/AuthorizationMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/permission/AuthorizationMapper.xml
@@ -378,4 +378,22 @@
and p.organization_uuid = gr.organization_uuid
and gr.group_id is null
</sql>
+
+ <select id="selectQualityProfileAdministratorLogins" parameterType="map" resultType="String">
+ select u.login
+ from user_roles ur
+ inner join users u on u.id=ur.user_id
+ where
+ ur.role=#{permission,jdbcType=VARCHAR}
+
+ union
+
+ select u.login
+ from group_roles gr
+ inner join groups_users gu on gr.group_id = gu.group_id
+ inner join users u on u.id=gu.user_id
+ where
+ gr.role = #{permission,jdbcType=VARCHAR} and
+ gr.group_id is not null
+ </select>
</mapper>
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java
index 9ffad60746c..c3a099c4f8a 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java
@@ -46,7 +46,9 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES;
+import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
import static org.sonar.db.permission.OrganizationPermission.SCAN;
public class AuthorizationDaoTest {
@@ -691,7 +693,6 @@ public class AuthorizationDaoTest {
users.stream().map(UserDto::getId).collect(Collectors.toSet()), "user", PROJECT_ID)).isEmpty();
}
-
@Test
public void countUsersWithGlobalPermissionExcludingGroupMember() {
// u1 has the direct permission, u2 and u3 have the permission through their group
@@ -958,6 +959,50 @@ public class AuthorizationDaoTest {
.containsOnly(publicProject.uuid());
assertThat(underTest.keepAuthorizedProjectUuids(dbSession, newHashSet(publicProject.uuid()), null, UserRole.ADMIN))
.isEmpty();
+ }
+
+ @Test
+ public void selectQualityProfileAdministratorLogins_return_users_with_quality_profile_administrator_permission() {
+ OrganizationDto organization1 = db.organizations().insert();
+ UserDto user1 = db.users().insertUser();
+ db.users().insertPermissionOnUser(organization1, user1, ADMINISTER_QUALITY_PROFILES);
+ OrganizationDto organization2 = db.organizations().insert();
+ UserDto user2 = db.users().insertUser();
+ db.users().insertPermissionOnUser(organization2, user2, ADMINISTER_QUALITY_PROFILES);
+ List<String> logins = underTest.selectQualityProfileAdministratorLogins(dbSession);
+
+ assertThat(logins).containsExactlyInAnyOrder(user1.getLogin(), user2.getLogin());
}
+
+ @Test
+ public void selectQualityProfileAdministratorLogins_return_users_within_quality_profile_administrator_group() {
+ OrganizationDto organization1 = db.organizations().insert();
+ GroupDto qualityProfileAdministratorGroup1 = db.users().insertGroup(organization1);
+ db.users().insertPermissionOnGroup(qualityProfileAdministratorGroup1, ADMINISTER_QUALITY_PROFILES);
+ UserDto user1 = db.users().insertUser();
+ db.users().insertMember(qualityProfileAdministratorGroup1, user1);
+ OrganizationDto organization2 = db.organizations().insert();
+ GroupDto qualityProfileAdministratorGroup2 = db.users().insertGroup(organization2);
+ db.users().insertPermissionOnGroup(qualityProfileAdministratorGroup2, ADMINISTER_QUALITY_PROFILES);
+ UserDto user2 = db.users().insertUser();
+ db.users().insertMember(qualityProfileAdministratorGroup2, user2);
+
+ List<String> logins = underTest.selectQualityProfileAdministratorLogins(dbSession);
+
+ assertThat(logins).containsExactlyInAnyOrder(user1.getLogin(), user2.getLogin());
+ }
+
+ @Test
+ public void selectQualityProfileAdministratorLogins_does_not_return_non_quality_profile_administrator_logins() {
+ OrganizationDto organization1 = db.organizations().insert();
+ UserDto user1 = db.users().insertUser();
+ db.users().insertPermissionOnUser(organization1, user1, ADMINISTER);
+ db.users().insertUser();
+
+ List<String> logins = underTest.selectQualityProfileAdministratorLogins(dbSession);
+
+ assertThat(logins).isEmpty();
+ }
+
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/notification/NotificationModule.java b/server/sonar-server/src/main/java/org/sonar/server/notification/NotificationModule.java
index a7e88a63c9a..555da5d7249 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/notification/NotificationModule.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/notification/NotificationModule.java
@@ -21,12 +21,7 @@ package org.sonar.server.notification;
import org.sonar.api.config.EmailSettings;
import org.sonar.core.platform.Module;
-import org.sonar.server.notification.email.AlertsEmailTemplate;
import org.sonar.server.notification.email.EmailNotificationChannel;
-import org.sonar.server.notification.ws.AddAction;
-import org.sonar.server.notification.ws.ListAction;
-import org.sonar.server.notification.ws.NotificationsWs;
-import org.sonar.server.notification.ws.RemoveAction;
public class NotificationModule extends Module {
@Override
@@ -38,12 +33,6 @@ public class NotificationModule extends Module {
NotificationUpdater.class,
DefaultNotificationManager.class,
NotificationDaemon.class,
- AlertsEmailTemplate.class,
- EmailNotificationChannel.class,
- // WS
- NotificationsWs.class,
- AddAction.class,
- RemoveAction.class,
- ListAction.class);
+ EmailNotificationChannel.class);
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/notification/ws/NotificationWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/notification/ws/NotificationWsModule.java
new file mode 100644
index 00000000000..968af6912a5
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/notification/ws/NotificationWsModule.java
@@ -0,0 +1,34 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.notification.ws;
+
+import org.sonar.core.platform.Module;
+
+public class NotificationWsModule extends Module {
+ @Override
+ protected void configureModule() {
+ add(
+ // WS
+ NotificationsWs.class,
+ AddAction.class,
+ RemoveAction.class,
+ ListAction.class);
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
index 8321a4ba0ff..3056d5bdde8 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
@@ -84,6 +84,7 @@ import org.sonar.server.metric.CoreCustomMetrics;
import org.sonar.server.metric.DefaultMetricFinder;
import org.sonar.server.metric.ws.MetricsWsModule;
import org.sonar.server.notification.NotificationModule;
+import org.sonar.server.notification.ws.NotificationWsModule;
import org.sonar.server.organization.BillingValidationsProxyImpl;
import org.sonar.server.organization.OrganizationCreationImpl;
import org.sonar.server.organization.OrganizationValidationImpl;
@@ -434,6 +435,7 @@ public class PlatformLevel4 extends PlatformLevel {
// Notifications
NotificationModule.class,
+ NotificationWsModule.class,
EmailsWsModule.class,
// Tests
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java
index d627e3c40ab..39c20db53c7 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java
@@ -21,6 +21,7 @@ package org.sonar.server.platform.platformlevel;
import org.sonar.server.app.ProcessCommandWrapper;
import org.sonar.server.es.IndexerStartupTask;
+import org.sonar.server.notification.NotificationModule;
import org.sonar.server.organization.DefaultOrganizationEnforcer;
import org.sonar.server.platform.ServerLifecycleNotifier;
import org.sonar.server.platform.web.RegisterServletFilters;
@@ -28,6 +29,9 @@ import org.sonar.server.qualitygate.RegisterQualityGates;
import org.sonar.server.qualityprofile.BuiltInQProfileInsertImpl;
import org.sonar.server.qualityprofile.BuiltInQProfileLoader;
import org.sonar.server.qualityprofile.BuiltInQProfileUpdateImpl;
+import org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification;
+import org.sonar.server.qualityprofile.BuiltInQualityProfilesNotificationDispatcher;
+import org.sonar.server.qualityprofile.BuiltInQualityProfilesNotificationTemplate;
import org.sonar.server.qualityprofile.RegisterQualityProfiles;
import org.sonar.server.rule.RegisterRules;
import org.sonar.server.rule.WebServerRuleFinder;
@@ -58,6 +62,11 @@ public class PlatformLevelStartup extends PlatformLevel {
RegisterRules.class);
add(BuiltInQProfileLoader.class);
addIfStartupLeader(
+ // TODO Should we put it in level 2 ?
+ NotificationModule.class,
+ BuiltInQualityProfilesNotificationDispatcher.class,
+ BuiltInQualityProfilesNotificationTemplate.class,
+ BuiltInQualityProfilesNotification.class,
BuiltInQProfileInsertImpl.class,
BuiltInQProfileUpdateImpl.class,
RegisterQualityProfiles.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotification.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotification.java
new file mode 100644
index 00000000000..cdc2b657748
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotification.java
@@ -0,0 +1,41 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.qualityprofile;
+
+import org.sonar.api.notifications.Notification;
+import org.sonar.server.notification.NotificationManager;
+
+public class BuiltInQualityProfilesNotification {
+
+ static final String BUILT_IN_QUALITY_PROFILES = "built-in-quality-profiles";
+
+ private final NotificationManager notificationManager;
+
+ public BuiltInQualityProfilesNotification(NotificationManager notificationManager) {
+ this.notificationManager = notificationManager;
+ }
+
+ void send() {
+ notificationManager.scheduleForSending(
+ new Notification(BUILT_IN_QUALITY_PROFILES)
+ .setDefaultMessage("This is a test message from SonarQube"));
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcher.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcher.java
new file mode 100644
index 00000000000..5fab56c976d
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcher.java
@@ -0,0 +1,59 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.qualityprofile;
+
+import java.util.List;
+import org.sonar.api.notifications.Notification;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.server.notification.NotificationDispatcher;
+import org.sonar.server.notification.email.EmailNotificationChannel;
+
+import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification.BUILT_IN_QUALITY_PROFILES;
+
+public class BuiltInQualityProfilesNotificationDispatcher extends NotificationDispatcher {
+
+ public static final String KEY = "BuiltInQP";
+
+ private final EmailNotificationChannel emailNotificationChannel;
+ private final DbClient dbClient;
+
+ public BuiltInQualityProfilesNotificationDispatcher(EmailNotificationChannel emailNotificationChannel, DbClient dbClient) {
+ super(BUILT_IN_QUALITY_PROFILES);
+ this.emailNotificationChannel = emailNotificationChannel;
+ this.dbClient = dbClient;
+ }
+
+ @Override
+ public String getKey() {
+ return KEY;
+ }
+
+ @Override
+ public void dispatch(Notification notification, Context context) {
+ getRecipients().forEach(login -> context.addUser(login, emailNotificationChannel));
+ }
+
+ private List<String> getRecipients() {
+ try (DbSession session = dbClient.openSession(false)) {
+ return dbClient.authorizationDao().selectQualityProfileAdministratorLogins(session);
+ }
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplate.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplate.java
new file mode 100644
index 00000000000..b15c4f7046f
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplate.java
@@ -0,0 +1,42 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.qualityprofile;
+
+import org.sonar.api.notifications.Notification;
+import org.sonar.plugins.emailnotifications.api.EmailMessage;
+import org.sonar.plugins.emailnotifications.api.EmailTemplate;
+
+import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification.BUILT_IN_QUALITY_PROFILES;
+
+public class BuiltInQualityProfilesNotificationTemplate extends EmailTemplate {
+
+ @Override
+ public EmailMessage format(Notification notification) {
+ if (!BUILT_IN_QUALITY_PROFILES.equals(notification.getType())) {
+ return null;
+ }
+ // And finally return the email that will be sent
+ return new EmailMessage()
+ .setMessageId(BUILT_IN_QUALITY_PROFILES)
+ .setSubject("empty")
+ .setMessage("This is a test message from SonarQube");
+ }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java
index c6b9593f13b..89c900f9a10 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java
@@ -45,13 +45,16 @@ public class RegisterQualityProfiles {
private final DbClient dbClient;
private final BuiltInQProfileInsert builtInQProfileInsert;
private final BuiltInQProfileUpdate builtInQProfileUpdate;
+ private final BuiltInQualityProfilesNotification builtInQualityProfilesNotification;
public RegisterQualityProfiles(BuiltInQProfileRepository builtInQProfileRepository,
- DbClient dbClient, BuiltInQProfileInsert builtInQProfileInsert, BuiltInQProfileUpdate builtInQProfileUpdate) {
+ DbClient dbClient, BuiltInQProfileInsert builtInQProfileInsert, BuiltInQProfileUpdate builtInQProfileUpdate,
+ BuiltInQualityProfilesNotification builtInQualityProfilesNotification) {
this.builtInQProfileRepository = builtInQProfileRepository;
this.dbClient = dbClient;
this.builtInQProfileInsert = builtInQProfileInsert;
this.builtInQProfileUpdate = builtInQProfileUpdate;
+ this.builtInQualityProfilesNotification = builtInQualityProfilesNotification;
}
public void start() {
@@ -95,6 +98,8 @@ public class RegisterQualityProfiles {
LOGGER.info("Update profile {}", builtIn.getQProfileName());
builtInQProfileUpdate.update(dbSession, builtIn, ruleProfile);
+
+ builtInQualityProfilesNotification.send();
}
/**
diff --git a/server/sonar-server/src/test/java/org/sonar/server/notification/NotificationModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/notification/NotificationModuleTest.java
index 187df6f7b7b..3c29ccf4822 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/notification/NotificationModuleTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/notification/NotificationModuleTest.java
@@ -29,6 +29,6 @@ public class NotificationModuleTest {
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new NotificationModule().configure(container);
- assertThat(container.size()).isEqualTo(12 + 2);
+ assertThat(container.size()).isEqualTo(7 + 2);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/notification/ws/NotificationWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/notification/ws/NotificationWsModuleTest.java
new file mode 100644
index 00000000000..fe37e926afd
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/notification/ws/NotificationWsModuleTest.java
@@ -0,0 +1,34 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.notification.ws;
+
+import org.junit.Test;
+import org.sonar.core.platform.ComponentContainer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class NotificationWsModuleTest {
+ @Test
+ public void verify_count_of_added_components() {
+ ComponentContainer container = new ComponentContainer();
+ new NotificationWsModule().configure(container);
+ assertThat(container.size()).isEqualTo(4 + 2);
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcherTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcherTest.java
new file mode 100644
index 00000000000..9290e130489
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcherTest.java
@@ -0,0 +1,61 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.qualityprofile;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.notifications.Notification;
+import org.sonar.db.DbTester;
+import org.sonar.db.permission.OrganizationPermission;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.notification.NotificationDispatcher.Context;
+import org.sonar.server.notification.email.EmailNotificationChannel;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+public class BuiltInQualityProfilesNotificationDispatcherTest {
+
+ @Rule
+ public DbTester dbTester = DbTester.create();
+ private Context context = mock(Context.class);
+ private EmailNotificationChannel channel = mock(EmailNotificationChannel.class);
+ private BuiltInQualityProfilesNotificationDispatcher underTest = new BuiltInQualityProfilesNotificationDispatcher(channel, dbTester.getDbClient());
+
+ @Test
+ public void send_email_to_quality_profile_administrator() {
+ UserDto profileAdmin = dbTester.users().insertUser();
+ dbTester.users().insertPermissionOnUser(profileAdmin, OrganizationPermission.ADMINISTER_QUALITY_PROFILES);
+
+ underTest.dispatch(mock(Notification.class), context);
+
+ verify(context).addUser(profileAdmin.getLogin(), channel);
+ }
+
+ @Test
+ public void does_not_send_email_to_user_that_is_not_quality_profile_administrator() {
+ dbTester.users().insertUser();
+
+ underTest.dispatch(mock(Notification.class), context);
+
+ verifyZeroInteractions(context);
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java
index b8aa907ad31..205b2939863 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java
@@ -38,6 +38,9 @@ import org.sonar.server.language.LanguageTesting;
import org.sonar.server.tester.UserSessionRule;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.sonar.db.qualityprofile.QualityProfileTesting.newRuleProfileDto;
public class RegisterQualityProfilesTest {
@@ -58,10 +61,11 @@ public class RegisterQualityProfilesTest {
private DbClient dbClient = db.getDbClient();
private DummyBuiltInQProfileInsert insert = new DummyBuiltInQProfileInsert();
private DummyBuiltInQProfileUpdate update = new DummyBuiltInQProfileUpdate();
+ private BuiltInQualityProfilesNotification builtInQualityProfilesNotification = mock(BuiltInQualityProfilesNotification.class);
private RegisterQualityProfiles underTest = new RegisterQualityProfiles(
builtInQProfileRepositoryRule,
dbClient,
- insert, update);
+ insert, update, builtInQualityProfilesNotification);
@Test
public void start_fails_if_BuiltInQProfileRepository_has_not_been_initialized() {
@@ -133,15 +137,38 @@ public class RegisterQualityProfilesTest {
assertThat(logTester.logs(LoggerLevel.INFO)).contains("Update profile foo/Sonar way");
}
+ @Test
+ public void does_not_send_notification_on_new_profile() {
+ builtInQProfileRepositoryRule.add(FOO_LANGUAGE, "Sonar way");
+ builtInQProfileRepositoryRule.initialize();
+
+ underTest.start();
+
+ verifyZeroInteractions(builtInQualityProfilesNotification);
+ }
+
+ @Test
+ public void send_notification_when_built_in_profile_is_updated() {
+ RulesProfileDto ruleProfile = newRuleProfileDto(rp -> rp.setIsBuiltIn(true).setName("Sonar way").setLanguage(FOO_LANGUAGE.getKey()));
+ db.getDbClient().qualityProfileDao().insert(db.getSession(), ruleProfile);
+ db.commit();
+ builtInQProfileRepositoryRule.add(FOO_LANGUAGE, ruleProfile.getName(), false);
+ builtInQProfileRepositoryRule.initialize();
+
+ underTest.start();
+
+ verify(builtInQualityProfilesNotification).send();
+ }
+
private String selectPersistedName(QProfileDto profile) {
return db.qualityProfiles().selectByUuid(profile.getKee()).get().getName();
}
private void insertRulesProfile(BuiltInQProfile builtIn) {
RulesProfileDto dto = newRuleProfileDto(rp -> rp
- .setIsBuiltIn(true)
- .setLanguage(builtIn.getLanguage())
- .setName(builtIn.getName()));
+ .setIsBuiltIn(true)
+ .setLanguage(builtIn.getLanguage())
+ .setName(builtIn.getName()));
dbClient.qualityProfileDao().insert(db.getSession(), dto);
db.commit();
}
diff --git a/tests/plugins/foo-plugin-v1/pom.xml b/tests/plugins/foo-plugin-v1/pom.xml
new file mode 100644
index 00000000000..e34322baece
--- /dev/null
+++ b/tests/plugins/foo-plugin-v1/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.sonarsource.sonarqube</groupId>
+ <artifactId>sonarqube</artifactId>
+ <version>6.5-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+ <artifactId>foo-plugin-v1</artifactId>
+ <name>SonarQube :: Plugins :: Foo (V1)</name>
+ <packaging>sonar-plugin</packaging>
+ <description>Sample of plugin to document and test available APIs</description>
+
+ <properties>
+ <sonar.skip>true</sonar.skip>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonarsource.sonarqube</groupId>
+ <artifactId>sonar-plugin-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- unit testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
+ <artifactId>sonar-packaging-maven-plugin</artifactId>
+ <configuration>
+ <pluginKey>foo</pluginKey>
+ <pluginName>Foo</pluginName>
+ <pluginClass>org.sonar.foo.FooPlugin</pluginClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java
new file mode 100644
index 00000000000..522bc81483d
--- /dev/null
+++ b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java
@@ -0,0 +1,43 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo;
+
+import org.sonar.api.resources.Language;
+
+public class Foo implements Language {
+
+ public static final String KEY = "foo";
+ public static final String NAME = "foo";
+
+ @Override
+ public String getKey() {
+ return KEY;
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public String[] getFileSuffixes() {
+ return new String[0];
+ }
+}
diff --git a/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java
new file mode 100644
index 00000000000..17677e0acb2
--- /dev/null
+++ b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/FooPlugin.java
@@ -0,0 +1,39 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo;
+
+import org.sonar.api.Plugin;
+import org.sonar.foo.rule.FooBasicProfile;
+import org.sonar.foo.rule.FooRulesDefinition;
+
+/**
+ * Plugin entry-point, as declared in pom.xml.
+ */
+public class FooPlugin implements Plugin {
+
+ @Override
+ public void define(Context context) {
+ context.addExtensions(
+ Foo.class,
+ FooRulesDefinition.class,
+ FooBasicProfile.class);
+ }
+
+}
diff --git a/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/package-info.java b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/package-info.java
new file mode 100644
index 00000000000..24613bbdaf7
--- /dev/null
+++ b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooBasicProfile.java b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooBasicProfile.java
new file mode 100644
index 00000000000..3a53e9293ff
--- /dev/null
+++ b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooBasicProfile.java
@@ -0,0 +1,41 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo.rule;
+
+import org.sonar.api.profiles.ProfileDefinition;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.utils.ValidationMessages;
+
+import static org.sonar.api.rules.RulePriority.MAJOR;
+import static org.sonar.foo.Foo.KEY;
+import static org.sonar.foo.rule.FooRulesDefinition.FOO_REPOSITORY;
+
+public class FooBasicProfile extends ProfileDefinition {
+
+ @Override
+ public RulesProfile createProfile(ValidationMessages validation) {
+ final RulesProfile profile = RulesProfile.create("Basic", KEY);
+ profile.activateRule(Rule.create(FOO_REPOSITORY, "UnchangedRule"), MAJOR);
+ profile.activateRule(Rule.create(FOO_REPOSITORY, "ChangedRule"), MAJOR);
+ profile.activateRule(Rule.create(FOO_REPOSITORY, "RemovedRule"), MAJOR);
+ return profile;
+ }
+}
diff --git a/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java
new file mode 100644
index 00000000000..7257dd72681
--- /dev/null
+++ b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java
@@ -0,0 +1,46 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo.rule;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.foo.Foo;
+
+public class FooRulesDefinition implements RulesDefinition {
+
+ public static final String FOO_REPOSITORY = "foo";
+
+ @Override
+ public void define(Context context) {
+ defineRulesXoo(context);
+ }
+
+ private static void defineRulesXoo(Context context) {
+ NewRepository repo = context.createRepository(FOO_REPOSITORY, Foo.KEY).setName("Foo");
+ createRule(repo, "UnchangedRule");
+ createRule(repo, "ChangedRule");
+ createRule(repo, "RemovedRule");
+ repo.done();
+ }
+
+ private static NewRule createRule(NewRepository repo, String key) {
+ return repo.createRule(key).setName(key).setHtmlDescription(key);
+ }
+
+}
diff --git a/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/package-info.java b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/package-info.java
new file mode 100644
index 00000000000..b3209c8ac96
--- /dev/null
+++ b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/rule/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo.rule;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/tests/plugins/foo-plugin-v2/pom.xml b/tests/plugins/foo-plugin-v2/pom.xml
new file mode 100644
index 00000000000..db2fc2c5916
--- /dev/null
+++ b/tests/plugins/foo-plugin-v2/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.sonarsource.sonarqube</groupId>
+ <artifactId>sonarqube</artifactId>
+ <version>6.5-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+ <artifactId>foo-plugin-v2</artifactId>
+ <name>SonarQube :: Plugins :: Foo (V2)</name>
+ <packaging>sonar-plugin</packaging>
+ <description>Sample of plugin to document and test available APIs</description>
+
+ <properties>
+ <sonar.skip>true</sonar.skip>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonarsource.sonarqube</groupId>
+ <artifactId>sonar-plugin-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- unit testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
+ <artifactId>sonar-packaging-maven-plugin</artifactId>
+ <configuration>
+ <pluginKey>foo</pluginKey>
+ <pluginName>Foo</pluginName>
+ <pluginClass>org.sonar.foo.FooPlugin</pluginClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java
new file mode 100644
index 00000000000..522bc81483d
--- /dev/null
+++ b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java
@@ -0,0 +1,43 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo;
+
+import org.sonar.api.resources.Language;
+
+public class Foo implements Language {
+
+ public static final String KEY = "foo";
+ public static final String NAME = "foo";
+
+ @Override
+ public String getKey() {
+ return KEY;
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public String[] getFileSuffixes() {
+ return new String[0];
+ }
+}
diff --git a/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java
new file mode 100644
index 00000000000..17677e0acb2
--- /dev/null
+++ b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/FooPlugin.java
@@ -0,0 +1,39 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo;
+
+import org.sonar.api.Plugin;
+import org.sonar.foo.rule.FooBasicProfile;
+import org.sonar.foo.rule.FooRulesDefinition;
+
+/**
+ * Plugin entry-point, as declared in pom.xml.
+ */
+public class FooPlugin implements Plugin {
+
+ @Override
+ public void define(Context context) {
+ context.addExtensions(
+ Foo.class,
+ FooRulesDefinition.class,
+ FooBasicProfile.class);
+ }
+
+}
diff --git a/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/package-info.java b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/package-info.java
new file mode 100644
index 00000000000..24613bbdaf7
--- /dev/null
+++ b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooBasicProfile.java b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooBasicProfile.java
new file mode 100644
index 00000000000..1c2d051f7cf
--- /dev/null
+++ b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooBasicProfile.java
@@ -0,0 +1,42 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo.rule;
+
+import org.sonar.api.profiles.ProfileDefinition;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.utils.ValidationMessages;
+
+import static org.sonar.api.rules.RulePriority.MAJOR;
+import static org.sonar.api.rules.RulePriority.MINOR;
+import static org.sonar.foo.Foo.KEY;
+import static org.sonar.foo.rule.FooRulesDefinition.FOO_REPOSITORY;
+
+public class FooBasicProfile extends ProfileDefinition {
+
+ @Override
+ public RulesProfile createProfile(ValidationMessages validation) {
+ final RulesProfile profile = RulesProfile.create("Basic", KEY);
+ profile.activateRule(Rule.create(FOO_REPOSITORY, "UnchangedRule"), MAJOR);
+ profile.activateRule(Rule.create(FOO_REPOSITORY, "ChangedRule"), MINOR);
+ profile.activateRule(Rule.create(FOO_REPOSITORY, "NewRule"), MAJOR);
+ return profile;
+ }
+}
diff --git a/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java
new file mode 100644
index 00000000000..aacc2335262
--- /dev/null
+++ b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/FooRulesDefinition.java
@@ -0,0 +1,46 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo.rule;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.foo.Foo;
+
+public class FooRulesDefinition implements RulesDefinition {
+
+ public static final String FOO_REPOSITORY = "foo";
+
+ @Override
+ public void define(Context context) {
+ defineRulesXoo(context);
+ }
+
+ private static void defineRulesXoo(Context context) {
+ NewRepository repo = context.createRepository(FOO_REPOSITORY, Foo.KEY).setName("Foo");
+ createRule(repo, "UnchangedRule");
+ createRule(repo, "ChangedRule");
+ createRule(repo, "NewRule");
+ repo.done();
+ }
+
+ private static NewRule createRule(NewRepository repo, String key) {
+ return repo.createRule(key).setName(key).setHtmlDescription(key);
+ }
+
+}
diff --git a/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/package-info.java b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/package-info.java
new file mode 100644
index 00000000000..b3209c8ac96
--- /dev/null
+++ b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/rule/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.foo.rule;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/tests/plugins/pom.xml b/tests/plugins/pom.xml
index 2f41319fe52..e66f838108f 100644
--- a/tests/plugins/pom.xml
+++ b/tests/plugins/pom.xml
@@ -41,6 +41,8 @@
<module>batch-plugin</module>
<module>extension-lifecycle-plugin</module>
<module>fake-billing-plugin</module>
+ <module>foo-plugin-v1</module>
+ <module>foo-plugin-v2</module>
<module>global-property-change-plugin</module>
<module>issue-filter-plugin</module>
<module>l10n-fr-pack</module>
diff --git a/tests/src/test/java/org/sonarqube/tests/Category5Suite.java b/tests/src/test/java/org/sonarqube/tests/Category5Suite.java
index 283aea49471..5335ef37b3b 100644
--- a/tests/src/test/java/org/sonarqube/tests/Category5Suite.java
+++ b/tests/src/test/java/org/sonarqube/tests/Category5Suite.java
@@ -19,6 +19,9 @@
*/
package org.sonarqube.tests;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.sonarqube.tests.qualityProfile.BuiltInQualityProfilesNotificationTest;
import org.sonarqube.tests.serverSystem.ClusterTest;
import org.sonarqube.tests.serverSystem.RestartTest;
import org.sonarqube.tests.serverSystem.ServerSystemRestartingOrchestrator;
@@ -28,8 +31,6 @@ import org.sonarqube.tests.updateCenter.UpdateCenterTest;
import org.sonarqube.tests.user.OnboardingTest;
import org.sonarqube.tests.user.RealmAuthenticationTest;
import org.sonarqube.tests.user.SsoAuthenticationTest;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
/**
* This suite is reserved to the tests that start their own instance of Orchestrator.
@@ -47,7 +48,8 @@ import org.junit.runners.Suite;
UpdateCenterTest.class,
RealmAuthenticationTest.class,
SsoAuthenticationTest.class,
- OnboardingTest.class
+ OnboardingTest.class,
+ BuiltInQualityProfilesNotificationTest.class
})
public class Category5Suite {
diff --git a/tests/src/test/java/org/sonarqube/tests/qualityProfile/BuiltInQualityProfilesNotificationTest.java b/tests/src/test/java/org/sonarqube/tests/qualityProfile/BuiltInQualityProfilesNotificationTest.java
new file mode 100644
index 00000000000..9960e8b7c42
--- /dev/null
+++ b/tests/src/test/java/org/sonarqube/tests/qualityProfile/BuiltInQualityProfilesNotificationTest.java
@@ -0,0 +1,176 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.sonarqube.tests.qualityProfile;
+
+import com.sonar.orchestrator.Orchestrator;
+import java.io.File;
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonarqube.ws.WsUsers;
+import org.sonarqube.ws.client.PostRequest;
+import org.sonarqube.ws.client.WsClient;
+import org.sonarqube.ws.client.permission.AddGroupWsRequest;
+import org.sonarqube.ws.client.permission.AddUserWsRequest;
+import org.subethamail.wiser.Wiser;
+import org.subethamail.wiser.WiserMessage;
+import util.ItUtils;
+import util.user.UserRule;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.assertj.core.api.Assertions.assertThat;
+import static util.ItUtils.pluginArtifact;
+
+public class BuiltInQualityProfilesNotificationTest {
+
+ private static Orchestrator orchestrator;
+ private static Wiser smtpServer;
+ private static UserRule userRule;
+
+ @Before
+ public void init() throws Exception {
+ smtpServer = new Wiser(0);
+ smtpServer.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (orchestrator != null) {
+ orchestrator.stop();
+ }
+ if (smtpServer != null) {
+ smtpServer.stop();
+ }
+ }
+
+ @Test
+ public void does_not_send_mail_if_no_quality_profile_is_updated() throws Exception {
+ orchestrator = Orchestrator.builderEnv()
+ .addPlugin(pluginArtifact("foo-plugin-v1"))
+ .setServerProperty("email.smtp_host.secured", "localhost")
+ .setServerProperty("email.smtp_port.secured", Integer.toString(smtpServer.getServer().getPort()))
+ // .setServerProperty("sonar.web.javaAdditionalOpts", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005")// FIXME
+ // remove web debugging
+ .build();
+ orchestrator.start();
+
+ userRule = UserRule.from(orchestrator);
+
+ WsUsers.CreateWsResponse.User profileAdmin1 = userRule.generate();
+ WsClient wsClient = ItUtils.newAdminWsClient(orchestrator);
+ wsClient.permissions().addUser(new AddUserWsRequest().setLogin(profileAdmin1.getLogin()).setPermission("profileadmin"));
+
+ WsUsers.CreateWsResponse.User profileAdmin2 = userRule.generate();
+ String groupName = randomAlphanumeric(20);
+ wsClient.wsConnector().call(new PostRequest("api/user_groups/create").setParam("name", groupName)).failIfNotSuccessful();
+ wsClient.permissions().addGroup(new AddGroupWsRequest().setPermission("profileadmin").setGroupName(groupName));
+ wsClient.wsConnector().call(new PostRequest("api/user_groups/add_user").setParam("name", groupName).setParam("login", profileAdmin2.getLogin())).failIfNotSuccessful();
+
+ WsUsers.CreateWsResponse.User noProfileAdmin = userRule.generate();
+
+ orchestrator.restartServer();
+
+ waitUntilAllNotificationsAreDelivered(1, 10, 100);
+ assertThat(smtpServer.getMessages()).isEmpty();
+ }
+
+ @Test
+ public void send_mail_if_quality_profile_is_updated() throws Exception {
+ orchestrator = Orchestrator.builderEnv()
+ .addPlugin(pluginArtifact("foo-plugin-v1"))
+ .setServerProperty("email.smtp_host.secured", "localhost")
+ .setServerProperty("email.smtp_port.secured", Integer.toString(smtpServer.getServer().getPort()))
+ // .setServerProperty("sonar.web.javaAdditionalOpts", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005")// FIXME
+ // remove web debugging
+ .build();
+ orchestrator.start();
+
+ userRule = UserRule.from(orchestrator);
+
+ WsUsers.CreateWsResponse.User profileAdmin1 = userRule.generate();
+ WsClient wsClient = ItUtils.newAdminWsClient(orchestrator);
+ wsClient.permissions().addUser(new AddUserWsRequest().setLogin(profileAdmin1.getLogin()).setPermission("profileadmin"));
+
+ WsUsers.CreateWsResponse.User profileAdmin2 = userRule.generate();
+ String groupName = randomAlphanumeric(20);
+ wsClient.wsConnector().call(new PostRequest("api/user_groups/create").setParam("name", groupName)).failIfNotSuccessful();
+ wsClient.permissions().addGroup(new AddGroupWsRequest().setPermission("profileadmin").setGroupName(groupName));
+ wsClient.wsConnector().call(new PostRequest("api/user_groups/add_user").setParam("name", groupName).setParam("login", profileAdmin2.getLogin())).failIfNotSuccessful();
+
+ WsUsers.CreateWsResponse.User noProfileAdmin = userRule.generate();
+
+ // uninstall plugin V1
+ wsClient.wsConnector().call(new PostRequest("api/plugins/uninstall").setParam("key", "foo")).failIfNotSuccessful();
+
+ // install plugin V2
+ File pluginsDir = new File(orchestrator.getServer().getHome() + "/extensions/plugins");
+ orchestrator.getConfiguration().fileSystem().copyToDirectory(pluginArtifact("foo-plugin-v2"), pluginsDir);
+
+ orchestrator.restartServer();
+
+ waitUntilAllNotificationsAreDelivered(2, 10, 1_000);
+ assertThat(smtpServer.getMessages())
+ .extracting(this::getMimeMessage)
+ .extracting(this::getAllRecipients)
+ .containsOnly("<" + profileAdmin1.getEmail() + ">", "<" + profileAdmin2.getEmail() + ">");
+ assertThat(smtpServer.getMessages())
+ .extracting(this::getMimeMessage)
+ .extracting(this::getContent)
+ .extracting(m -> m.contains("This is a test message from SonarQube"))
+ .containsOnly(true);
+ }
+
+ private MimeMessage getMimeMessage(WiserMessage msg) {
+ try {
+ return msg.getMimeMessage();
+ } catch (MessagingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private String getContent(MimeMessage mimeMessage1) {
+ try {
+ return mimeMessage1.getContent().toString();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private String getAllRecipients(MimeMessage mimeMessage) {
+ try {
+ return mimeMessage.getHeader("To", null);
+ } catch (MessagingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static void waitUntilAllNotificationsAreDelivered(int expectedNumberOfEmails, int pollNumber, int pollMillis) throws InterruptedException {
+ for (int i = 0; i < pollNumber; i++) {
+ if (smtpServer.getMessages().size() == expectedNumberOfEmails) {
+ break;
+ }
+ Thread.sleep(pollMillis);
+ }
+ }
+
+}
diff --git a/tests/src/test/java/util/ItUtils.java b/tests/src/test/java/util/ItUtils.java
index 3ef0d275549..7c41cb2ab34 100644
--- a/tests/src/test/java/util/ItUtils.java
+++ b/tests/src/test/java/util/ItUtils.java
@@ -146,7 +146,6 @@ public class ItUtils {
* Locate the artifact of a fake plugin stored in it/plugins.
*
* @param dirName the directory of it/plugins, for example "sonar-fake-plugin".
- * It assumes that version is 1.0-SNAPSHOT
*/
public static FileLocation pluginArtifact(String dirName) {
return FileLocation.byWildcardMavenFilename(new File("plugins/" + dirName + "/target"), dirName + "-*.jar");
@@ -495,6 +494,7 @@ public class ItUtils {
public static void expectMissingError(Runnable runnable) {
expectHttpError(404, runnable);
}
+
/**
* Missing permissions
*/