]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-14527 Use 30s write timeout when submitting scanner report
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Fri, 26 Feb 2021 18:06:31 +0000 (12:06 -0600)
committersonartech <sonartech@sonarsource.com>
Wed, 3 Mar 2021 20:12:50 +0000 (20:12 +0000)
13 files changed:
.github/workflows/dogfood.yml [deleted file]
.github/workflows/nightly-qa.yml [deleted file]
.github/workflows/release.yml [deleted file]
.github/workflows/suggest-dependency-upgrades.yml [deleted file]
.github/workflows/sync-lts-branch.yml [deleted file]
.github/workflows/sync-master-branch.yml [deleted file]
sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ReportPublisherTest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/BaseRequest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java
sonar-ws/src/main/java/org/sonarqube/ws/client/WsRequest.java
sonar-ws/src/test/java/org/sonarqube/ws/client/BaseRequestTest.java
sonar-ws/src/test/java/org/sonarqube/ws/client/HttpConnectorTest.java

diff --git a/.github/workflows/dogfood.yml b/.github/workflows/dogfood.yml
deleted file mode 100644 (file)
index 34c8382..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-name: Dogfood merge
-on:
-  push:
-    branches:
-      - master
-      - "dogfood/**"
-jobs:
-  dogfood_merge:
-    # prevent job to run on public repository sonarsource/sonarqube
-    if: github.repository == 'sonarsource/sonar-enterprise'
-    runs-on: ubuntu-latest
-    name: Update dogfood-on-next branch
-    steps:
-      - name: Merge dogfood and master branches
-        uses: SonarSource/gh-action_dogfood_merge@v1
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_ORG_TOKEN }}
-        with:
-          dogfood-branch: "dogfood-on-next"
-      - name: Notify failures on Slack
-        if: failure()
-        uses: Ilshidur/action-slack@2.0.0
-        env:
-          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
-        with:
-          args: "Failed to merge dogfood and master branches, see the logs at https://github.com/SonarSource/sonar-enterprise/actions"
diff --git a/.github/workflows/nightly-qa.yml b/.github/workflows/nightly-qa.yml
deleted file mode 100644 (file)
index d9ac507..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-name: Nightly QA
-on:
-  schedule:
-    # at 1:30 daily
-    - cron: "30 1 * * *"
-jobs:
-  nightly:
-    # prevent job to run on public repository sonarsource/sonarqube
-    if: github.repository == 'sonarsource/sonar-enterprise'
-    runs-on: ubuntu-latest
-    name: Trigger the nightly QA build
-    steps:
-      - name: Fetch code
-        uses: actions/checkout@v2
-        with:
-          token: ${{ secrets.GITHUB_ORG_TOKEN }}
-          ref: branch-nightly-build
-          path: repo
-      - name: Trigger nightly build
-        run: |
-          cd repo/
-          ./private/trigger-nightly-build.sh
-      - name: Notify failures on Slack
-        if: failure()
-        uses: Ilshidur/action-slack@2.0.0
-        env:
-          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
-        with:
-          args: "Nightly QA failed, see the logs at https://github.com/SonarSource/sonar-enterprise/actions"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644 (file)
index 26746cc..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-name: Release
-# This workflow is triggered when publishing a GitHub release
-on:
-  release:
-    types:
-      - published
-
-env:
-  PYTHONUNBUFFERED: 1
-
-jobs:
-  release:
-    if: github.repository == 'sonarsource/sonar-enterprise'
-    runs-on: ubuntu-latest
-    name: Start release process
-    timeout-minutes: 60
-    steps:
-      - name: Run release action
-        id: run_release
-        uses: SonarSource/gh-action_LT_release@v2
-        with:
-          distribute: true
-          publish_to_binaries: true
-          attach_artifacts_to_github_release: false
-          run_rules_cov: false
-          slack_channel: sonarqube-build
-        env:
-          ARTIFACTORY_API_KEY: ${{ secrets.ARTIFACTORY_API_KEY }}
-          BINTRAY_USER: ${{ secrets.BINTRAY_USER }}
-          BINTRAY_TOKEN: ${{ secrets.BINTRAY_TOKEN }}
-          BURGRX_USER: ${{ secrets.BURGRX_USER }}
-          BURGRX_PASSWORD: ${{ secrets.BURGRX_PASSWORD }}
-          CENTRAL_USER: ${{ secrets.CENTRAL_USER }}
-          CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
-          CIRRUS_TOKEN: ${{ secrets.CIRRUS_TOKEN }}
-          GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
-          PATH_PREFIX: ${{ secrets.BINARIES_PATH_PREFIX }}
-          GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
-          RELEASE_SSH_USER: ${{ secrets.RELEASE_SSH_USER }}
-          RELEASE_SSH_KEY: ${{ secrets.RELEASE_SSH_KEY }}
-          SLACK_API_TOKEN: ${{secrets.SLACK_API_TOKEN }}
-      - name: Log outputs
-        if: always()
-        run: |
-          echo "${{ steps.run_release.outputs.releasability }}"
-          echo "${{ steps.run_release.outputs.release }}"
-          echo "${{ steps.run_release.outputs.distribute_release }}"
-      - name: Notify success on Slack
-        uses: Ilshidur/action-slack@2.0.0
-        env:
-          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
-        with:
-          args: "Release successful for {{ GITHUB_REPOSITORY }} by {{ GITHUB_ACTOR }}"
-      - name: Notify failures on Slack
-        uses: Ilshidur/action-slack@2.0.0
-        if: failure()
-        env:
-          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
-        with:
-          args: "Release failed, see the logs at https://github.com/{{ GITHUB_REPOSITORY }}/actions by {{ GITHUB_ACTOR }}"
diff --git a/.github/workflows/suggest-dependency-upgrades.yml b/.github/workflows/suggest-dependency-upgrades.yml
deleted file mode 100644 (file)
index 99937a6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-name: Suggest dependency upgrades
-on:
-# use push to test the bot
-#  push:
-#    branches-ignore:
-#      - 'bot/upgrade_plugins**'
-  schedule:
-    # at 5:00 every Monday
-    - cron:  '0 5 * * MON'
-
-jobs:
-  suggest-upgrades-job:
-    # prevent job to run on public repository sonarsource/sonarqube (on which GitHub Actions are disabled)
-    if: github.repository == 'sonarsource/sonar-enterprise'
-    runs-on: ubuntu-latest
-    name: List available upgrades
-    steps:
-      - uses: actions/checkout@v2
-        with:
-          fetch-depth: 1
-          ref: master
-      - name: Set up JDK
-        uses: actions/setup-java@v1
-        with:
-          java-version: 11
-      - name: Cache Gradle Wrapper
-        uses: actions/cache@v1
-        with:
-          path: ~/.gradle/wrapper
-          key: ${{ runner.os }}-gradlew-${{ hashFiles('**/*.zip') }}
-          restore-keys: ${{ runner.os }}-gradlew
-      - name: Find upgrades
-        env:
-          ARTIFACTORY_PRIVATE_USERNAME: ${{ secrets.REPOX_LOGIN }}
-          ARTIFACTORY_PRIVATE_PASSWORD: ${{ secrets.REPOX_API_KEY }}
-        run: |
-          ./gradlew dependencyUpdates yarn_audit -Drevision=release
diff --git a/.github/workflows/sync-lts-branch.yml b/.github/workflows/sync-lts-branch.yml
deleted file mode 100644 (file)
index 4cfaea7..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-name: Sync LTS branch
-on:
-  schedule:
-    # at 20:00 daily
-    - cron: "0 20 * * *"
-jobs:
-  sync_lts:
-    # prevent job to run on public repository sonarsource/sonarqube
-    if: github.repository == 'sonarsource/sonar-enterprise'
-    runs-on: ubuntu-latest
-    name: Sync LTS branch of sonarsource/sonar-enterprise with sonarsource/sonarqube
-    steps:
-      - name: Fetch code
-        uses: actions/checkout@v2
-        with:
-          token: ${{ secrets.GITHUB_ORG_TOKEN }}
-          ref: master
-          path: repo
-      - name: Sync LTS branch
-        run: ./repo/private/sync-public-git-branches.sh
-        env:
-          GITHUB_ORG_TOKEN: ${{ secrets.GITHUB_ORG_TOKEN }}
-          BRANCH_NAME: branch-7.9
-      - name: Notify failures on Slack
-        if: failure()
-        uses: Ilshidur/action-slack@2.0.0
-        env:
-          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
-        with:
-          args: "Nightly public sync failed, see the logs at https://github.com/SonarSource/sonar-enterprise/actions"
diff --git a/.github/workflows/sync-master-branch.yml b/.github/workflows/sync-master-branch.yml
deleted file mode 100644 (file)
index 0542b06..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-name: Sync master branch
-on:
-  schedule:
-    # at 20:00 daily
-    - cron: "0 20 * * *"
-jobs:
-  sync_master:
-    # prevent job to run on public repository sonarsource/sonarqube
-    if: github.repository == 'sonarsource/sonar-enterprise'
-    runs-on: ubuntu-latest
-    name: Sync master branch of sonarsource/sonar-enterprise with sonarsource/sonarqube
-    steps:
-      - name: Fetch code
-        uses: actions/checkout@v2
-        with:
-          token: ${{ secrets.GITHUB_ORG_TOKEN }}
-          ref: master
-          path: repo
-      - name: Sync master branch
-        run: ./repo/private/sync-public-git-branches.sh
-        env:
-          GITHUB_ORG_TOKEN: ${{ secrets.GITHUB_ORG_TOKEN }}
-          BRANCH_NAME: master
-      - name: Notify failures on Slack
-        if: failure()
-        uses: Ilshidur/action-slack@2.0.0
-        env:
-          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
-        with:
-          args: "Nightly public sync failed, see the logs at https://github.com/SonarSource/sonar-enterprise/actions"
index 9011a8eacd76512855ea1003bca12798814c61e8..f15f4d03f08522e65d0dbd71fb4b098d9544792f 100644 (file)
@@ -61,7 +61,7 @@ import static org.sonar.core.util.FileUtils.deleteQuietly;
 import static org.sonar.scanner.scan.branch.BranchType.PULL_REQUEST;
 
 public class ReportPublisher implements Startable {
-
+  private static final int DEFAULT_WRITE_TIMEOUT = 30_000;
   private static final Logger LOG = Loggers.get(ReportPublisher.class);
   private static final String CHARACTERISTIC = "characteristic";
   private static final String DASHBOARD = "dashboard";
@@ -200,6 +200,7 @@ public class ReportPublisher implements Startable {
 
     WsResponse response;
     try {
+      post.setWriteTimeOutInMs(DEFAULT_WRITE_TIMEOUT);
       response = wsClient.call(post).failIfNotSuccessful();
     } catch (HttpException e) {
       throw MessageException.of(String.format("Failed to upload report - %s", DefaultScannerWsClient.createErrorMessage(e)));
index a98a1a28012d4a1c66e1e56cef51c1152e078707..f28488eb69a1c31a871f2c4afd7c0e649bfb027a 100644 (file)
@@ -53,6 +53,7 @@ import org.sonarqube.ws.client.WsResponse;
 import static org.apache.commons.io.FileUtils.readFileToString;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -94,6 +95,18 @@ public class ReportPublisherTest {
       .resolve("report-task.txt"));
   }
 
+  @Test
+  public void use_30s_write_timeout() {
+    MockWsResponse submitMockResponse = new MockWsResponse();
+    submitMockResponse.setContent(Ce.SubmitResponse.newBuilder().setTaskId("task-1234").build().toByteArray());
+    when(wsClient.call(any())).thenReturn(submitMockResponse);
+
+    underTest.start();
+    underTest.execute();
+    
+    verify(wsClient).call(argThat(req -> req.getWriteTimeOutInMs().orElse(0) == 30_000));
+  }
+
   @Test
   public void dump_information_about_report_uploading() throws IOException {
     underTest.prepareAndDumpMetadata("TASK-123");
index a048ddccac52b04b4dd0746d54b409551a39b926..c81c0604eaddaa2c11b05003b43b0631413af8be 100644 (file)
@@ -50,7 +50,8 @@ abstract class BaseRequest<SELF extends BaseRequest> implements WsRequest {
   private final DefaultParameters parameters = new DefaultParameters();
   private final DefaultHeaders headers = new DefaultHeaders();
   private OptionalInt timeOutInMs = OptionalInt.empty();
-
+  private OptionalInt writeTimeOutInMs = OptionalInt.empty();
+  
   BaseRequest(String path) {
     this.path = path;
   }
@@ -75,6 +76,16 @@ abstract class BaseRequest<SELF extends BaseRequest> implements WsRequest {
     return (SELF) this;
   }
 
+  @Override
+  public OptionalInt getWriteTimeOutInMs() {
+    return writeTimeOutInMs;
+  }
+
+  public SELF setWriteTimeOutInMs(int writeTimeOutInMs) {
+    this.writeTimeOutInMs = OptionalInt.of(writeTimeOutInMs);
+    return (SELF) this;
+  }
+
   /**
    * Expected media type of response. Default is {@link MediaTypes#JSON}.
    */
index db02624c0d1c077c30000b63a60920f24618f494..d2ef094719df30852f1e0ad8cef886bfe7131811 100644 (file)
@@ -164,14 +164,19 @@ public class HttpConnector implements WsConnector {
       .newBuilder();
   }
 
-  private static OkHttpClient prepareOkHttpClient(OkHttpClient okHttpClient, WsRequest wsRequest) {
-    if (!wsRequest.getTimeOutInMs().isPresent()) {
+  static OkHttpClient prepareOkHttpClient(OkHttpClient okHttpClient, WsRequest wsRequest) {
+    if (!wsRequest.getTimeOutInMs().isPresent() && !wsRequest.getWriteTimeOutInMs().isPresent()) {
       return okHttpClient;
     }
+    OkHttpClient.Builder builder = okHttpClient.newBuilder();
+    if (wsRequest.getTimeOutInMs().isPresent()) {
+      builder.readTimeout(wsRequest.getTimeOutInMs().getAsInt(), TimeUnit.MILLISECONDS);
+    }
+    if (wsRequest.getWriteTimeOutInMs().isPresent()) {
+      builder.writeTimeout(wsRequest.getWriteTimeOutInMs().getAsInt(), TimeUnit.MILLISECONDS);
+    }
 
-    return okHttpClient.newBuilder()
-      .readTimeout(wsRequest.getTimeOutInMs().getAsInt(), TimeUnit.MILLISECONDS)
-      .build();
+    return builder.build();
   }
 
   private static void completeUrlQueryParameters(BaseRequest<?> request, HttpUrl.Builder urlBuilder) {
@@ -197,7 +202,7 @@ public class HttpConnector implements WsConnector {
     try {
       return call.execute();
     } catch (IOException e) {
-      throw new IllegalStateException("Fail to request " + okRequest.url(), e);
+      throw new IllegalStateException("Fail to request url: " + okRequest.url(), e);
     }
   }
 
index b7094817086a97e838c0d5c5c6ea975d2daf51c1..474f876a0208a250dcadff5e418535af38daf48f 100644 (file)
@@ -35,6 +35,8 @@ public interface WsRequest {
 
   OptionalInt getTimeOutInMs();
 
+  OptionalInt getWriteTimeOutInMs();
+
   /**
    *
    * In case of multi value parameters, returns the first value
index 5e1a0f99d6ab59ac0baafd5ec7e37e740c6a42e2..01cf250ef944d9616ad5d7ba93e0fc7e61f9d013 100644 (file)
@@ -45,6 +45,13 @@ public class BaseRequestTest {
     assertThat(underTest.getParams()).isEmpty();
     assertThat(underTest.getMediaType()).isEqualTo(MediaTypes.JSON);
     assertThat(underTest.getPath()).isEqualTo("api/foo");
+    assertThat(underTest.getWriteTimeOutInMs()).isEmpty();
+  }
+
+  @Test
+  public void set_write_timeout() {
+    underTest.setWriteTimeOutInMs(30_000);
+    assertThat(underTest.getWriteTimeOutInMs()).hasValue(30_000);
   }
 
   @Test
index 97f6f9b2ad134f6ad90b60f73782fcb8f8adefe4..b95f9a8afb56b30349405f3a4ad5d0a25636c1f7 100644 (file)
@@ -30,6 +30,7 @@ import java.util.Random;
 import java.util.concurrent.TimeUnit;
 import javax.net.ssl.SSLSocketFactory;
 import okhttp3.ConnectionSpec;
+import okhttp3.OkHttpClient;
 import okhttp3.mockwebserver.MockResponse;
 import okhttp3.mockwebserver.MockWebServer;
 import okhttp3.mockwebserver.RecordedRequest;
@@ -289,6 +290,15 @@ public class HttpConnectorTest {
     assertThat(underTest.okHttpClient().connectTimeoutMillis()).isEqualTo(74);
   }
 
+  @Test
+  public void override_timeouts_with_request() {
+    OkHttpClient client = new OkHttpClient.Builder().build();
+    WsRequest request = new PostRequest("abc").setWriteTimeOutInMs(123).setTimeOutInMs(234);
+    client = underTest.prepareOkHttpClient(client, request);
+    assertThat(client.writeTimeoutMillis()).isEqualTo(123);
+    assertThat(client.readTimeoutMillis()).isEqualTo(234);
+  }
+
   @Test
   public void send_user_agent() throws Exception {
     answerHelloWorld();