From 54df07c9f9c1e586c2931d2ca10e7759fc1ec61b Mon Sep 17 00:00:00 2001 From: Lukasz Jarocki Date: Fri, 15 Jul 2022 15:47:35 +0200 Subject: [PATCH] SONAR-14349 added new internal endpoints api/features/list --- .../server/feature/SonarQubeFeature.java | 27 ++++++ .../sonar/server/feature/ws/FeatureWs.java | 42 +++++++++ .../server/feature/ws/FeatureWsModule.java | 30 ++++++ .../sonar/server/feature/ws/ListAction.java | 59 ++++++++++++ .../sonar/server/language/ws/ListAction.java | 1 + .../sonar/server/feature/ws/example-list.json | 1 + .../feature/ws/FeatureWsModuleTest.java | 37 ++++++++ .../server/feature/ws/FeatureWsTest.java | 47 ++++++++++ .../server/feature/ws/ListActionTest.java | 94 +++++++++++++++++++ .../valid-json-with-2-features.json | 1 + .../platformlevel/PlatformLevel4.java | 4 + 11 files changed, 343 insertions(+) create mode 100644 server/sonar-server-common/src/main/java/org/sonar/server/feature/SonarQubeFeature.java create mode 100644 server/sonar-webserver-webapi/src/main/java/org/sonar/server/feature/ws/FeatureWs.java create mode 100644 server/sonar-webserver-webapi/src/main/java/org/sonar/server/feature/ws/FeatureWsModule.java create mode 100644 server/sonar-webserver-webapi/src/main/java/org/sonar/server/feature/ws/ListAction.java create mode 100644 server/sonar-webserver-webapi/src/main/resources/org/sonar/server/feature/ws/example-list.json create mode 100644 server/sonar-webserver-webapi/src/test/java/org/sonar/server/feature/ws/FeatureWsModuleTest.java create mode 100644 server/sonar-webserver-webapi/src/test/java/org/sonar/server/feature/ws/FeatureWsTest.java create mode 100644 server/sonar-webserver-webapi/src/test/java/org/sonar/server/feature/ws/ListActionTest.java create mode 100644 server/sonar-webserver-webapi/src/test/resources/org/sonar/server/feature/ws/ListActionTest/valid-json-with-2-features.json diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/feature/SonarQubeFeature.java b/server/sonar-server-common/src/main/java/org/sonar/server/feature/SonarQubeFeature.java new file mode 100644 index 00000000000..a3f844d1364 --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/feature/SonarQubeFeature.java @@ -0,0 +1,27 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 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.feature; + +public interface SonarQubeFeature { + + String getName(); + + boolean isEnabled(); +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/feature/ws/FeatureWs.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/feature/ws/FeatureWs.java new file mode 100644 index 00000000000..167bc7c26eb --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/feature/ws/FeatureWs.java @@ -0,0 +1,42 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 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.feature.ws; + +import org.sonar.api.server.ws.WebService; + +public class FeatureWs implements WebService { + + private final ListAction list; + + public FeatureWs(ListAction list) { + this.list = list; + } + + @Override + public void define(Context context) { + NewController features = context.createController("api/features") + .setDescription("Provides information about features available in SonarQube") + .setSince("9.6"); + + list.define(features); + + features.done(); + } +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/feature/ws/FeatureWsModule.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/feature/ws/FeatureWsModule.java new file mode 100644 index 00000000000..063642f0752 --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/feature/ws/FeatureWsModule.java @@ -0,0 +1,30 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 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.feature.ws; + +import org.sonar.core.platform.Module; + +public class FeatureWsModule extends Module { + + @Override + protected void configureModule() { + add(ListAction.class, FeatureWs.class); + } +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/feature/ws/ListAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/feature/ws/ListAction.java new file mode 100644 index 00000000000..2f97d36472a --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/feature/ws/ListAction.java @@ -0,0 +1,59 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 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.feature.ws; + +import com.google.common.io.Resources; +import java.util.List; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.server.feature.SonarQubeFeature; +import org.sonar.server.ws.WsAction; + +public class ListAction implements WsAction { + + private final List sonarQubeFeatures; + + public ListAction(List sonarQubeFeatures) { + this.sonarQubeFeatures = sonarQubeFeatures; + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("list") + .setDescription("List supported features") + .setSince("9.6") + .setInternal(true) + .setHandler(this) + .setResponseExample(Resources.getResource(getClass(), "example-list.json")); + } + + @Override + public void handle(Request request, Response response) throws Exception { + try (JsonWriter json = response.newJsonWriter()) { + json.beginArray(); + sonarQubeFeatures.stream() + .filter(SonarQubeFeature::isEnabled) + .forEach(f -> json.value(f.getName())); + json.endArray(); + } + } +} \ No newline at end of file diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/language/ws/ListAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/language/ws/ListAction.java index 270ab8de623..5552ed21c73 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/language/ws/ListAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/language/ws/ListAction.java @@ -63,6 +63,7 @@ public class ListAction implements WsAction { } } + @Override public void define(WebService.NewController controller) { NewAction action = controller.createAction("list") .setDescription("List supported programming languages") diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/feature/ws/example-list.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/feature/ws/example-list.json new file mode 100644 index 00000000000..7415b789abf --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/feature/ws/example-list.json @@ -0,0 +1 @@ +[ "monorepo" ] \ No newline at end of file diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/feature/ws/FeatureWsModuleTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/feature/ws/FeatureWsModuleTest.java new file mode 100644 index 00000000000..3f53b34658b --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/feature/ws/FeatureWsModuleTest.java @@ -0,0 +1,37 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 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.feature.ws; + +import org.junit.Test; +import org.sonar.core.platform.ListContainer; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FeatureWsModuleTest { + + @Test + public void verify_count_of_added_components() { + ListContainer container = new ListContainer(); + + new FeatureWsModule().configure(container); + + assertThat(container.getAddedObjects()).hasSizeGreaterThanOrEqualTo(2); + } +} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/feature/ws/FeatureWsTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/feature/ws/FeatureWsTest.java new file mode 100644 index 00000000000..ecf4592a804 --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/feature/ws/FeatureWsTest.java @@ -0,0 +1,47 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 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.feature.ws; + +import java.util.List; +import org.junit.Test; +import org.sonar.api.server.ws.WebService; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FeatureWsTest { + + private static final String CONTROLLER_FEATURES = "api/features"; + + private final FeatureWs underTest = new FeatureWs(new ListAction(List.of())); + + @Test + public void define_shouldHasAtLeastOneAction() { + WebService.Context context = new WebService.Context(); + + underTest.define(context); + + WebService.Controller controller = context.controller(CONTROLLER_FEATURES); + assertThat(controller).isNotNull(); + assertThat(controller.description()).isNotEmpty(); + assertThat(controller.path()).isEqualTo(CONTROLLER_FEATURES); + assertThat(controller.since()).isEqualTo("9.6"); + assertThat(controller.actions()).hasSizeGreaterThanOrEqualTo(1); + } +} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/feature/ws/ListActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/feature/ws/ListActionTest.java new file mode 100644 index 00000000000..7433bffbfa2 --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/feature/ws/ListActionTest.java @@ -0,0 +1,94 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 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.feature.ws; + +import java.util.List; +import org.junit.Test; +import org.sonar.api.server.ws.WebService; +import org.sonar.server.feature.SonarQubeFeature; +import org.sonar.server.ws.TestResponse; +import org.sonar.server.ws.WsActionTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; + +public class ListActionTest { + + private static final List EXAMPLE_FEATURES = getExampleFeatures(); + + private final ListAction underTest = new ListAction(EXAMPLE_FEATURES); + private final WsActionTester tester = new WsActionTester(underTest); + + @Test + public void define_hasNecessaryInformation() { + WebService.Action def = tester.getDef(); + + assertThat(def.since()).isEqualTo("9.6"); + assertTrue(def.isInternal()); + assertThat(def.description()).isNotEmpty(); + assertThat(def.responseExampleAsString()).isNotEmpty(); + } + + @Test + public void handle_returnsValidJsonWithInfoAboutExampleFeatures() { + TestResponse execute = tester.newRequest().execute(); + + execute.assertJson(this.getClass(), "valid-json-with-2-features.json"); + } + + @Test + public void handle_returnsEmptyJsonWhenNoFeaturesDefined() { + ListAction actionWithNoFeatures = new ListAction(List.of()); + WsActionTester tester = new WsActionTester(actionWithNoFeatures); + TestResponse execute = tester.newRequest().execute(); + + execute.assertJson("[]"); + } + + private static List getExampleFeatures() { + ExampleSonarQubeFeature feature1 = new ExampleSonarQubeFeature("feature1", true); + ExampleSonarQubeFeature feature2 = new ExampleSonarQubeFeature("feature2", true); + ExampleSonarQubeFeature feature3 = new ExampleSonarQubeFeature("feature3", false); + + return List.of(feature1, feature2, feature3); + } + + static class ExampleSonarQubeFeature implements SonarQubeFeature { + + private final String name; + private final boolean enabled; + + public ExampleSonarQubeFeature(String name, boolean enabled) { + this.name = name; + this.enabled = enabled; + } + + @Override + public String getName() { + return name; + } + + @Override + public boolean isEnabled() { + return enabled; + } + } +} + diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/feature/ws/ListActionTest/valid-json-with-2-features.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/feature/ws/ListActionTest/valid-json-with-2-features.json new file mode 100644 index 00000000000..171ba483104 --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/feature/ws/ListActionTest/valid-json-with-2-features.json @@ -0,0 +1 @@ +[ "feature1", "feature2" ] diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java index 3c79441837f..98562996585 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java @@ -98,6 +98,7 @@ import org.sonar.server.extension.CoreExtensionBootstraper; import org.sonar.server.extension.CoreExtensionStopper; import org.sonar.server.favorite.FavoriteModule; import org.sonar.server.favorite.ws.FavoriteWsModule; +import org.sonar.server.feature.ws.FeatureWsModule; import org.sonar.server.health.NodeHealthModule; import org.sonar.server.hotspot.ws.HotspotsWsModule; import org.sonar.server.issue.AddTagsAction; @@ -594,6 +595,9 @@ public class PlatformLevel4 extends PlatformLevel { // UI new NavigationWsModule(), + // SonarQube features + new FeatureWsModule(), + // webhooks WebhookQGChangeEventListener.class, new WebhookModule(), -- 2.39.5