diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2016-04-06 09:57:19 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2016-04-07 12:12:32 +0200 |
commit | a2be8c1b0c660f10b2e86ac046af3cfaea61214d (patch) | |
tree | a21057b61d9fb834c5c751e6f88021632d7fbcc3 /it | |
parent | f6bfd1d2f0373da2d2929d9217721a81fc3afe5d (diff) | |
download | sonarqube-a2be8c1b0c660f10b2e86ac046af3cfaea61214d.tar.gz sonarqube-a2be8c1b0c660f10b2e86ac046af3cfaea61214d.zip |
SONAR-6948 Ability for Java server extensions to call web services
Diffstat (limited to 'it')
-rw-r--r-- | it/it-plugins/pom.xml | 3 | ||||
-rw-r--r-- | it/it-plugins/ws-plugin/pom.xml | 43 | ||||
-rw-r--r-- | it/it-plugins/ws-plugin/src/main/java/LocalCallWebService.java | 85 | ||||
-rw-r--r-- | it/it-plugins/ws-plugin/src/main/java/WsPlugin.java | 30 | ||||
-rw-r--r-- | it/it-tests/src/test/java/it/Category4Suite.java | 6 | ||||
-rw-r--r-- | it/it-tests/src/test/java/it/user/LocalAuthenticationTest.java | 12 | ||||
-rw-r--r-- | it/it-tests/src/test/java/it/ws/WsLocalCallTest.java | 78 | ||||
-rw-r--r-- | it/it-tests/src/test/java/util/ItUtils.java | 6 |
8 files changed, 252 insertions, 11 deletions
diff --git a/it/it-plugins/pom.xml b/it/it-plugins/pom.xml index bee94bef359..c931e338939 100644 --- a/it/it-plugins/pom.xml +++ b/it/it-plugins/pom.xml @@ -36,6 +36,7 @@ <module>dashboard-plugin</module> <module>extension-lifecycle-plugin</module> <module>global-property-change-plugin</module> + <module>issue-filter-plugin</module> <module>l10n-fr-pack</module> <module>license-plugin</module> <module>oauth2-auth-plugin</module> @@ -50,7 +51,7 @@ <module>sonar-fake-plugin</module> <module>sonar-subcategories-plugin</module> <module>ui-extensions-plugin</module> - <module>issue-filter-plugin</module> <module>posttask-plugin</module> + <module>ws-plugin</module> </modules> </project> diff --git a/it/it-plugins/ws-plugin/pom.xml b/it/it-plugins/ws-plugin/pom.xml new file mode 100644 index 00000000000..6ac4a5d3fd8 --- /dev/null +++ b/it/it-plugins/ws-plugin/pom.xml @@ -0,0 +1,43 @@ +<?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/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.sonarsource.sonarqube</groupId> + <artifactId>it-plugins</artifactId> + <version>5.5-SNAPSHOT</version> + </parent> + + <artifactId>ws-plugin</artifactId> + <version>1.0-SNAPSHOT</version> + <packaging>sonar-plugin</packaging> + <name>SonarQube Integration Tests :: Plugins :: Ws</name> + <description>Plugin for WS tests</description> + + <dependencies> + <dependency> + <groupId>org.sonarsource.sonarqube</groupId> + <artifactId>sonar-plugin-api</artifactId> + <version>${apiVersion}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.sonarsource.sonarqube</groupId> + <artifactId>sonar-ws</artifactId> + <version>${apiVersion}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> + <artifactId>sonar-packaging-maven-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <pluginClass>WsPlugin</pluginClass> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/it/it-plugins/ws-plugin/src/main/java/LocalCallWebService.java b/it/it-plugins/ws-plugin/src/main/java/LocalCallWebService.java new file mode 100644 index 00000000000..b878ef2c47f --- /dev/null +++ b/it/it-plugins/ws-plugin/src/main/java/LocalCallWebService.java @@ -0,0 +1,85 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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. + */ + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.RequestHandler; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonarqube.ws.MediaTypes; +import org.sonarqube.ws.WsCe; +import org.sonarqube.ws.client.GetRequest; +import org.sonarqube.ws.client.LocalWsClientFactory; +import org.sonarqube.ws.client.WsClient; +import org.sonarqube.ws.client.WsResponse; + +public final class LocalCallWebService implements WebService { + + private final LocalWsClientFactory wsClientFactory; + + public LocalCallWebService(LocalWsClientFactory wsClientFactory) { + this.wsClientFactory = wsClientFactory; + } + + @Override + public void define(Context context) { + NewController controller = context.createController("local_ws_call"); + controller.createAction("protobuf_data").setHandler(new ProtobufHandler()); + controller.createAction("json_data").setHandler(new JsonHandler()); + controller.createAction("require_permission").setHandler(new RequirePermissionHandler()); + controller.done(); + } + + private class ProtobufHandler implements RequestHandler { + @Override + public void handle(Request request, Response response) throws Exception { + WsClient client = wsClientFactory.newClient(request.getLocalConnector()); + + WsCe.TaskTypesWsResponse ceTaskTypes = client.ce().taskTypes(); + response.stream().setStatus(ceTaskTypes.getTaskTypesCount() > 0 ? 200 : 500); + } + } + + private class JsonHandler implements RequestHandler { + @Override + public void handle(Request request, Response response) throws Exception { + WsClient client = wsClientFactory.newClient(request.getLocalConnector()); + + WsResponse jsonResponse = client.wsConnector().call(new GetRequest("api/issues/search")); + boolean ok = jsonResponse.contentType().equals(MediaTypes.JSON) + && jsonResponse.isSuccessful() + && jsonResponse.content().contains("\"issues\":"); + response.stream().setStatus(ok ? 200 : 500); + } + } + + private class RequirePermissionHandler implements RequestHandler { + @Override + public void handle(Request request, Response response) throws Exception { + WsClient client = wsClientFactory.newClient(request.getLocalConnector()); + + WsResponse jsonResponse = client.wsConnector().call(new GetRequest("api/system/info")); + + boolean ok = MediaTypes.JSON.equals(jsonResponse.contentType()) + && jsonResponse.isSuccessful() + && jsonResponse.content().startsWith("{"); + response.stream().setStatus(ok ? 200 : 500); + } + } +} diff --git a/it/it-plugins/ws-plugin/src/main/java/WsPlugin.java b/it/it-plugins/ws-plugin/src/main/java/WsPlugin.java new file mode 100644 index 00000000000..d907059bcee --- /dev/null +++ b/it/it-plugins/ws-plugin/src/main/java/WsPlugin.java @@ -0,0 +1,30 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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. + */ + +import java.util.Arrays; +import java.util.List; +import org.sonar.api.SonarPlugin; +import org.sonarqube.ws.client.WsClientFactories; + +public class WsPlugin extends SonarPlugin { + public List getExtensions() { + return Arrays.asList(LocalCallWebService.class, WsClientFactories.getLocal()); + } +} diff --git a/it/it-tests/src/test/java/it/Category4Suite.java b/it/it-tests/src/test/java/it/Category4Suite.java index ee4802b478d..bb75f2473f0 100644 --- a/it/it-tests/src/test/java/it/Category4Suite.java +++ b/it/it-tests/src/test/java/it/Category4Suite.java @@ -41,6 +41,7 @@ import it.user.ForceAuthenticationTest; import it.user.LocalAuthenticationTest; import it.user.MyAccountPageTest; import it.user.OAuth2IdentityProviderTest; +import it.ws.WsLocalCallTest; import org.junit.ClassRule; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -83,7 +84,8 @@ import static util.ItUtils.xooPlugin; // ui UiTest.class, // ui extensions - UiExtensionsTest.class + UiExtensionsTest.class, + WsLocalCallTest.class }) public class Category4Suite { @@ -104,5 +106,7 @@ public class Category4Suite { // Used in UiExtensionsTest .addPlugin(pluginArtifact("ui-extensions-plugin")) + // Used by WsLocalCallTest + .addPlugin(pluginArtifact("ws-plugin")) .build(); } diff --git a/it/it-tests/src/test/java/it/user/LocalAuthenticationTest.java b/it/it-tests/src/test/java/it/user/LocalAuthenticationTest.java index faf0f3bae29..61df33b9eea 100644 --- a/it/it-tests/src/test/java/it/user/LocalAuthenticationTest.java +++ b/it/it-tests/src/test/java/it/user/LocalAuthenticationTest.java @@ -37,8 +37,8 @@ import org.junit.experimental.categories.Category; import org.sonarqube.ws.WsUserTokens; import org.sonarqube.ws.client.GetRequest; import org.sonarqube.ws.client.HttpConnector; -import org.sonarqube.ws.client.HttpWsClient; import org.sonarqube.ws.client.WsClient; +import org.sonarqube.ws.client.WsClientFactories; import org.sonarqube.ws.client.WsResponse; import org.sonarqube.ws.client.permission.AddGroupWsRequest; import org.sonarqube.ws.client.permission.AddUserWsRequest; @@ -109,7 +109,7 @@ public class LocalAuthenticationTest { userRule.createUser(login, name, null, password); // authenticate - WsClient wsClient = new HttpWsClient(new HttpConnector.Builder().url(ORCHESTRATOR.getServer().getUrl()).credentials(login, password).build()); + WsClient wsClient = WsClientFactories.getDefault().newClient(HttpConnector.newBuilder().url(ORCHESTRATOR.getServer().getUrl()).credentials(login, password).build()); WsResponse response = wsClient.wsConnector().call(new GetRequest("api/authentication/validate")); assertThat(response.content()).isEqualTo("{\"valid\":true}"); } @@ -120,7 +120,7 @@ public class LocalAuthenticationTest { WsUserTokens.GenerateWsResponse generateWsResponse = userTokensWsClient.generate(new GenerateWsRequest() .setLogin(LOGIN) .setName(tokenName)); - WsClient wsClient = new HttpWsClient(new HttpConnector.Builder() + WsClient wsClient = WsClientFactories.getDefault().newClient(HttpConnector.newBuilder() .url(ORCHESTRATOR.getServer().getUrl()) .token(generateWsResponse.getToken()).build()); @@ -196,7 +196,7 @@ public class LocalAuthenticationTest { // This check is failing because signup doesn't refresh the users ES index ! // Will be fixed by SONAR-7308 -// userRule.verifyUserExists("signuplogin", "SignUpName", null); + // userRule.verifyUserExists("signuplogin", "SignUpName", null); } @Test @@ -208,14 +208,14 @@ public class LocalAuthenticationTest { "/user/LocalAuthenticationTest/redirect_to_original_url_after_direct_login.html", // SONAR-2009 "/user/LocalAuthenticationTest/redirect_to_original_url_after_indirect_login.html" - ).build()).runOn(ORCHESTRATOR); + ).build()).runOn(ORCHESTRATOR); setServerProperty(ORCHESTRATOR, "sonar.forceAuthentication", "true"); new SeleneseTest(Selenese.builder().setHtmlTestsInClasspath("force-authentication", // SONAR-3473 "/user/LocalAuthenticationTest/force-authentication.html" - ).build()).runOn(ORCHESTRATOR); + ).build()).runOn(ORCHESTRATOR); } @Test diff --git a/it/it-tests/src/test/java/it/ws/WsLocalCallTest.java b/it/it-tests/src/test/java/it/ws/WsLocalCallTest.java new file mode 100644 index 00000000000..3ec61f0ff3e --- /dev/null +++ b/it/it-tests/src/test/java/it/ws/WsLocalCallTest.java @@ -0,0 +1,78 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 it.ws; + +import com.sonar.orchestrator.Orchestrator; +import it.Category4Suite; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.sonarqube.ws.client.GetRequest; +import org.sonarqube.ws.client.HttpConnector; +import org.sonarqube.ws.client.WsClient; +import org.sonarqube.ws.client.WsClientFactories; +import org.sonarqube.ws.client.WsResponse; +import util.QaOnly; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests the ability for a web service to call another web services. + */ +@Category(QaOnly.class) +public class WsLocalCallTest { + + @ClassRule + public static final Orchestrator orchestrator = Category4Suite.ORCHESTRATOR; + + @Test + public void gets_protobuf() { + WsResponse response = newAnonymousClient().wsConnector().call(new GetRequest("local_ws_call/protobuf_data")); + assertThat(response.isSuccessful()).isTrue(); + } + + @Test + public void gets_json() { + WsResponse response = newAnonymousClient().wsConnector().call(new GetRequest("local_ws_call/json_data")); + assertThat(response.isSuccessful()).isTrue(); + } + + @Test + public void propagates_authorization_rights() { + WsClient wsClient = WsClientFactories.getDefault().newClient(HttpConnector.newBuilder() + .url(orchestrator.getServer().getUrl()) + .credentials("admin", "admin") + .build()); + WsResponse response = wsClient.wsConnector().call(new GetRequest("local_ws_call/require_permission")); + assertThat(response.isSuccessful()).isTrue(); + } + + @Test + public void fails_if_requires_permissions() { + WsResponse response = newAnonymousClient().wsConnector().call(new GetRequest("local_ws_call/require_permission")); + + // this is not the unauthorized code as plugin forces it to 500 + assertThat(response.code()).isEqualTo(500); + } + + private static WsClient newAnonymousClient() { + return WsClientFactories.getDefault().newClient(HttpConnector.newBuilder().url(orchestrator.getServer().getUrl()).build()); + } +} diff --git a/it/it-tests/src/test/java/util/ItUtils.java b/it/it-tests/src/test/java/util/ItUtils.java index b435e1244c0..21c8f9765ea 100644 --- a/it/it-tests/src/test/java/util/ItUtils.java +++ b/it/it-tests/src/test/java/util/ItUtils.java @@ -49,8 +49,8 @@ import org.sonar.wsclient.issue.IssueQuery; import org.sonar.wsclient.services.PropertyDeleteQuery; import org.sonar.wsclient.services.PropertyUpdateQuery; import org.sonarqube.ws.client.HttpConnector; -import org.sonarqube.ws.client.HttpWsClient; import org.sonarqube.ws.client.WsClient; +import org.sonarqube.ws.client.WsClientFactories; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.FluentIterable.from; @@ -77,7 +77,7 @@ public class ItUtils { public static WsClient newAdminWsClient(Orchestrator orchestrator) { Server server = orchestrator.getServer(); - return new HttpWsClient(new HttpConnector.Builder() + return WsClientFactories.getDefault().newClient(HttpConnector.newBuilder() .url(server.getUrl()) .credentials(ADMIN_LOGIN, ADMIN_PASSWORD) .build()); @@ -85,7 +85,7 @@ public class ItUtils { public static WsClient newWsClient(Orchestrator orchestrator) { Server server = orchestrator.getServer(); - return new HttpWsClient(new HttpConnector.Builder() + return WsClientFactories.getDefault().newClient(HttpConnector.newBuilder() .url(server.getUrl()) .build()); } |