]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10344 add service api/webhooks/search interface.
authorGuillaume Jambet <guillaume.jambet@sonarsource.com>
Tue, 30 Jan 2018 15:02:22 +0000 (16:02 +0100)
committerGuillaume Jambet <guillaume.jambet@gmail.com>
Thu, 1 Mar 2018 14:21:05 +0000 (15:21 +0100)
server/sonar-server/src/main/java/org/sonar/server/webhook/ws/SearchAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhookSearchDTO.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhooksWs.java
server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhooksWsModule.java
server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhooksWsParameters.java [new file with mode: 0644]
server/sonar-server/src/main/resources/org/sonar/server/webhook/ws/example-webhooks-search.json [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/webhook/ws/SearchActionTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/webhook/ws/WebhooksWsModuleTest.java
sonar-ws/src/main/protobuf/ws-webhooks.proto

diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/ws/SearchAction.java
new file mode 100644 (file)
index 0000000..c31b49b
--- /dev/null
@@ -0,0 +1,75 @@
+package org.sonar.server.webhook.ws;
+
+import com.google.common.io.Resources;
+import java.util.ArrayList;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.server.user.UserSession;
+import org.sonarqube.ws.Webhooks;
+
+import static org.sonar.server.webhook.ws.WebhooksWsParameters.ORGANIZATION_KEY_PARAM;
+import static org.sonar.server.webhook.ws.WebhooksWsParameters.PROJECT_KEY_PARAM;
+import static org.sonar.server.webhook.ws.WebhooksWsParameters.SEARCH_ACTION;
+import static org.sonar.server.ws.KeyExamples.KEY_ORG_EXAMPLE_001;
+import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
+
+public class SearchAction implements WebhooksWsAction {
+
+  private final DbClient dbClient;
+  private final UserSession userSession;
+
+  public SearchAction(DbClient dbClient, UserSession userSession) {
+    this.dbClient = dbClient;
+    this.userSession = userSession;
+  }
+
+  @Override
+  public void define(WebService.NewController controller) {
+
+    WebService.NewAction action = controller.createAction(SEARCH_ACTION)
+      .setDescription("Search for webhooks associated to an organization or a project.<br/>")
+      .setSince("7.1")
+      .setResponseExample(Resources.getResource(this.getClass(), "example-webhooks-search.json"))
+      .setHandler(this);
+
+    action.createParam(ORGANIZATION_KEY_PARAM)
+      .setDescription("Organization key. If no organization is provided, the default organization is used.")
+      .setInternal(true)
+      .setRequired(false)
+      .setExampleValue(KEY_ORG_EXAMPLE_001);
+
+    action.createParam(PROJECT_KEY_PARAM)
+      .setDescription("Project key")
+      .setRequired(false)
+      .setExampleValue(KEY_PROJECT_EXAMPLE_001);
+
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+
+    Webhooks.SearchWsResponse.Builder searchResponse = Webhooks.SearchWsResponse.newBuilder();
+
+    // FIXME : hard coded to test plumbing
+    ArrayList<WebhookSearchDTO> webhookSearchDTOS = new ArrayList<>();
+    webhookSearchDTOS.add(new WebhookSearchDTO("UUID-1", "my first webhook", "http://www.my-webhook-listener.com/sonarqube"));
+    webhookSearchDTOS.add(new WebhookSearchDTO("UUID-2", "my 2nd webhook", "https://www.my-other-webhook-listener.com/fancy-listner"));
+
+    for (WebhookSearchDTO dto : webhookSearchDTOS) {
+      searchResponse.addWebhooksBuilder()
+        .setKey(dto.getKey())
+        .setName(dto.getName())
+        .setUrl(dto.getUrl());
+    }
+
+    writeProtobuf(searchResponse.build(), request, response);
+  }
+
+}
+
+// {"key":"UUID-1","name":,"url":,"latestDelivery":{"id":"d1","at":"2017-07-14T04:40:00+0200","success":true,"httpStatus":200,"durationMs":10}},
+// {"key":"UUID-2","name":"my 2nd
+// webhook","url":"https://www.my-other-webhook-listener.com/fancy-listner","latestDelivery":{"id":"d2","at":"2017-07-14T04:40:00+0200","success":true,"httpStatus":200,"durationMs":10}}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhookSearchDTO.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhookSearchDTO.java
new file mode 100644 (file)
index 0000000..617ef66
--- /dev/null
@@ -0,0 +1,26 @@
+package org.sonar.server.webhook.ws;
+
+public class WebhookSearchDTO {
+
+  private final String key;
+  private final String name;
+  private final String url;
+
+  public WebhookSearchDTO(String key, String name, String url) {
+    this.key = key;
+    this.name = name;
+    this.url = url;
+  }
+
+  public String getKey() {
+    return key;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public String getUrl() {
+    return url;
+  }
+}
index d41a0ae3b074a0831bf680c2a1b341b5c245fec4..a61fc3b6d75e71b1e743f7ca5863611e4df3204e 100644 (file)
@@ -21,9 +21,9 @@ package org.sonar.server.webhook.ws;
 
 import org.sonar.api.server.ws.WebService;
 
-public class WebhooksWs implements WebService {
+import static org.sonar.server.webhook.ws.WebhooksWsParameters.WEBHOOKS_CONTROLLER;
 
-  public static final String API_ENDPOINT = "api/webhooks";
+public class WebhooksWs implements WebService {
 
   private final WebhooksWsAction[] actions;
 
@@ -33,7 +33,7 @@ public class WebhooksWs implements WebService {
 
   @Override
   public void define(Context context) {
-    NewController controller = context.createController(API_ENDPOINT);
+    NewController controller = context.createController(WEBHOOKS_CONTROLLER);
     controller.setDescription("Webhooks allow to notify external services when a project analysis is done");
     controller.setSince("6.2");
     for (WebhooksWsAction action : actions) {
index dd7092f823423ec4cbf80095412d21972f822cd7..3f589d19b6058a1a428da02489ff771bff214d6c 100644 (file)
@@ -26,6 +26,7 @@ public class WebhooksWsModule extends Module {
   protected void configureModule() {
     add(
       WebhooksWs.class,
+      SearchAction.class,
       WebhookDeliveryAction.class,
       WebhookDeliveriesAction.class);
   }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhooksWsParameters.java b/server/sonar-server/src/main/java/org/sonar/server/webhook/ws/WebhooksWsParameters.java
new file mode 100644 (file)
index 0000000..3a8d18a
--- /dev/null
@@ -0,0 +1,14 @@
+package org.sonar.server.webhook.ws;
+
+class WebhooksWsParameters {
+
+  static final String WEBHOOKS_CONTROLLER = "api/webhooks";
+
+
+  static final String SEARCH_ACTION = "search";
+
+
+  static final String ORGANIZATION_KEY_PARAM = "organization";
+  static final String PROJECT_KEY_PARAM = "project";
+
+}
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/webhook/ws/example-webhooks-search.json b/server/sonar-server/src/main/resources/org/sonar/server/webhook/ws/example-webhooks-search.json
new file mode 100644 (file)
index 0000000..0f5d3be
--- /dev/null
@@ -0,0 +1,28 @@
+{
+  "webhooks": [
+    {
+      "key": "UUID-1",
+      "name": "my first webhook",
+      "url": "http://www.my-webhook-listener.com/sonarqube",
+      "latestDelivery": {
+        "id": "d1",
+        "at": "2017-07-14T04:40:00+0200",
+        "success": true,
+        "httpStatus": 200,
+        "durationMs": 10
+      }
+    },
+    {
+      "key": "UUID-2",
+      "name": "my 2nd webhook",
+      "url": "https://www.my-other-webhook-listener.com/fancy-listner",
+      "latestDelivery": {
+        "id": "d2",
+        "at": "2017-07-14T04:40:00+0200",
+        "success": true,
+        "httpStatus": 200,
+        "durationMs": 10
+      }
+    }
+  ]
+}
\ No newline at end of file
diff --git a/server/sonar-server/src/test/java/org/sonar/server/webhook/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/webhook/ws/SearchActionTest.java
new file mode 100644 (file)
index 0000000..6826439
--- /dev/null
@@ -0,0 +1,49 @@
+package org.sonar.server.webhook.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.WsActionTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.tuple;
+
+public class SearchActionTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
+
+  @Rule
+  public DbTester db = DbTester.create();
+
+  private DbClient dbClient = db.getDbClient();
+  private DbSession dbSession = db.getSession();
+
+  private org.sonar.server.webhook.ws.SearchAction underTest = new SearchAction(dbClient, userSession);
+  private WsActionTester wsActionTester = new WsActionTester(underTest);
+
+  @Test
+  public void definition() {
+
+    WebService.Action action = wsActionTester.getDef();
+
+    assertThat(action).isNotNull();
+    assertThat(action.isInternal()).isFalse();
+    assertThat(action.isPost()).isFalse();
+    assertThat(action.responseExampleAsString()).isNotEmpty();
+    assertThat(action.params())
+      .extracting(WebService.Param::key, WebService.Param::isRequired)
+      .containsExactlyInAnyOrder(
+        tuple("organization", false),
+        tuple("project", false));
+  }
+
+}
\ No newline at end of file
index 96dc9eb65779f1d98b04451348fd79011fb485bc..a361235f99ca1204f15bbdf8ac57384cf726f99b 100644 (file)
@@ -32,7 +32,7 @@ public class WebhooksWsModuleTest {
   public void verify_count_of_added_components() {
     ComponentContainer container = new ComponentContainer();
     underTest.configure(container);
-    assertThat(container.size()).isEqualTo(2 + 3);
+    assertThat(container.size()).isEqualTo(3 + 3);
   }
 
 }
index a7ef3a9ab2ba7f11de458d383470780295bc426a..30ae14d8a4d974278c31da52e40f4b57c11e6ffb 100644 (file)
@@ -24,6 +24,27 @@ option java_package = "org.sonarqube.ws";
 option java_outer_classname = "Webhooks";
 option optimize_for = SPEED;
 
+// WS api/webhooks/search
+message SearchWsResponse {
+  repeated Search webhooks = 1;
+}
+
+message Search {
+  optional string key = 1;
+  optional string name = 2;
+  optional string url = 3;
+  optional LatestDelivery latestDelivery = 4;
+}
+
+message LatestDelivery {
+  optional string id = 1;
+  optional string at = 2;
+  optional string success = 3;
+  optional string httpStatus = 4;
+  optional string durationMs = 5;
+}
+
+
 // WS api/webhooks/deliveries
 message DeliveriesWsResponse {
   repeated Delivery deliveries = 1;