@@ -19,6 +19,7 @@ | |||
*/ | |||
package org.sonar.alm.client; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import java.util.OptionalLong; | |||
import org.sonar.api.config.Configuration; | |||
import org.sonar.api.utils.log.Loggers; | |||
@@ -27,8 +28,11 @@ import org.sonar.api.utils.log.Loggers; | |||
* Implementation of {@link TimeoutConfiguration} reading values from configuration properties. | |||
*/ | |||
public class TimeoutConfigurationImpl implements TimeoutConfiguration { | |||
private static final String CONNECT_TIMEOUT_PROPERTY = "sonar.alm.timeout.connect"; | |||
private static final String READ_TIMEOUT_PROPERTY = "sonar.alm.timeout.read"; | |||
@VisibleForTesting | |||
public static final String CONNECT_TIMEOUT_PROPERTY = "sonar.alm.timeout.connect"; | |||
@VisibleForTesting | |||
public static final String READ_TIMEOUT_PROPERTY = "sonar.alm.timeout.read"; | |||
private static final long DEFAULT_TIMEOUT = 30_000; | |||
private final Configuration configuration; |
@@ -61,13 +61,14 @@ public class BitbucketCloudRestClient { | |||
private final String bitbucketCloudEndpoint; | |||
private final String accessTokenEndpoint; | |||
@Inject | |||
public BitbucketCloudRestClient(OkHttpClient okHttpClient) { | |||
this(okHttpClient, ENDPOINT, ACCESS_TOKEN_ENDPOINT); | |||
public BitbucketCloudRestClient(OkHttpClient bitBucketCloudHttpClient) { | |||
this(bitBucketCloudHttpClient, ENDPOINT, ACCESS_TOKEN_ENDPOINT); | |||
} | |||
protected BitbucketCloudRestClient(OkHttpClient okHttpClient, String bitbucketCloudEndpoint, String accessTokenEndpoint) { | |||
this.client = okHttpClient; | |||
protected BitbucketCloudRestClient(OkHttpClient bitBucketCloudHttpClient, String bitbucketCloudEndpoint, String accessTokenEndpoint) { | |||
this.client = bitBucketCloudHttpClient; | |||
this.bitbucketCloudEndpoint = bitbucketCloudEndpoint; | |||
this.accessTokenEndpoint = accessTokenEndpoint; | |||
} |
@@ -0,0 +1,58 @@ | |||
/* | |||
* 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.alm.client.bitbucket.bitbucketcloud; | |||
import okhttp3.OkHttpClient; | |||
import org.sonar.alm.client.TimeoutConfiguration; | |||
import org.sonar.api.ce.ComputeEngineSide; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonarqube.ws.client.OkHttpClientBuilder; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Configuration; | |||
import org.springframework.context.annotation.Lazy; | |||
@ComputeEngineSide | |||
@ServerSide | |||
@Configuration | |||
@Lazy | |||
public class BitbucketCloudRestClientConfiguration { | |||
private final TimeoutConfiguration timeoutConfiguration; | |||
@Autowired | |||
public BitbucketCloudRestClientConfiguration(TimeoutConfiguration timeoutConfiguration) { | |||
this.timeoutConfiguration = timeoutConfiguration; | |||
} | |||
@Bean | |||
public OkHttpClient bitbucketCloudHttpClient() { | |||
OkHttpClientBuilder builder = new OkHttpClientBuilder(); | |||
builder.setConnectTimeoutMs(timeoutConfiguration.getConnectTimeout()); | |||
builder.setReadTimeoutMs(timeoutConfiguration.getReadTimeout()); | |||
builder.setFollowRedirects(false); | |||
return builder.build(); | |||
} | |||
@Bean | |||
public BitbucketCloudRestClient bitbucketCloudRestClient() { | |||
return new BitbucketCloudRestClient(bitbucketCloudHttpClient()); | |||
} | |||
} |
@@ -0,0 +1,70 @@ | |||
/* | |||
* 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.alm.client.bitbucket.bitbucketcloud; | |||
import java.io.IOException; | |||
import okhttp3.OkHttpClient; | |||
import okhttp3.Request; | |||
import okhttp3.mockwebserver.MockResponse; | |||
import okhttp3.mockwebserver.MockWebServer; | |||
import okhttp3.mockwebserver.RecordedRequest; | |||
import org.junit.Test; | |||
import org.sonar.alm.client.TimeoutConfiguration; | |||
import org.sonar.alm.client.TimeoutConfigurationImpl; | |||
import org.sonar.api.config.internal.MapSettings; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.alm.client.TimeoutConfigurationImpl.CONNECT_TIMEOUT_PROPERTY; | |||
import static org.sonar.alm.client.TimeoutConfigurationImpl.READ_TIMEOUT_PROPERTY; | |||
public class BitbucketCloudRestClientConfigurationTest { | |||
private static final long CONNECT_TIMEOUT_VALUE = 5435L; | |||
private static final long READ_TIMEOUT_VALUE = 13123L; | |||
private final MapSettings settings = new MapSettings(); | |||
private final TimeoutConfiguration timeoutConfiguration = new TimeoutConfigurationImpl(settings.asConfig()); | |||
private final BitbucketCloudRestClientConfiguration underTest = new BitbucketCloudRestClientConfiguration(timeoutConfiguration); | |||
public MockWebServer server = new MockWebServer(); | |||
@Test | |||
public void bitBucketCloudHttpClient_returnsCorrectlyConfiguredHttpClient() throws Exception { | |||
settings.setProperty(CONNECT_TIMEOUT_PROPERTY, CONNECT_TIMEOUT_VALUE); | |||
settings.setProperty(READ_TIMEOUT_PROPERTY, READ_TIMEOUT_VALUE); | |||
OkHttpClient client = underTest.bitbucketCloudHttpClient(); | |||
assertThat(client.connectTimeoutMillis()).isEqualTo(CONNECT_TIMEOUT_VALUE); | |||
assertThat(client.readTimeoutMillis()).isEqualTo(READ_TIMEOUT_VALUE); | |||
assertThat(client.proxy()).isNull(); | |||
assertThat(client.followRedirects()).isFalse(); | |||
RecordedRequest recordedRequest = call(client); | |||
assertThat(recordedRequest.getHeader("Proxy-Authorization")).isNull(); | |||
} | |||
private RecordedRequest call(OkHttpClient client) throws IOException, InterruptedException { | |||
server.enqueue(new MockResponse().setBody("pong")); | |||
client.newCall(new Request.Builder().url(server.url("/ping")).build()).execute(); | |||
return server.takeRequest(); | |||
} | |||
} |
@@ -26,6 +26,7 @@ import org.sonar.api.config.Configuration; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonarqube.ws.client.OkHttpClientBuilder; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Primary; | |||
import static java.lang.String.format; | |||
import static org.sonar.process.ProcessProperties.Property.HTTP_PROXY_PASSWORD; | |||
@@ -51,6 +52,7 @@ public class OkHttpClientProvider { | |||
/** | |||
* @return a {@link OkHttpClient} singleton | |||
*/ | |||
@Primary | |||
@Bean("OkHttpClient") | |||
public OkHttpClient provide(Configuration config, SonarRuntime runtime) { | |||
OkHttpClientBuilder builder = new OkHttpClientBuilder(); |
@@ -23,7 +23,7 @@ import java.util.List; | |||
import org.sonar.alm.client.TimeoutConfigurationImpl; | |||
import org.sonar.alm.client.azure.AzureDevOpsHttpClient; | |||
import org.sonar.alm.client.azure.AzureDevOpsValidator; | |||
import org.sonar.alm.client.bitbucket.bitbucketcloud.BitbucketCloudRestClient; | |||
import org.sonar.alm.client.bitbucket.bitbucketcloud.BitbucketCloudRestClientConfiguration; | |||
import org.sonar.alm.client.bitbucket.bitbucketcloud.BitbucketCloudValidator; | |||
import org.sonar.alm.client.bitbucketserver.BitbucketServerRestClient; | |||
import org.sonar.alm.client.bitbucketserver.BitbucketServerSettingsValidator; | |||
@@ -184,14 +184,13 @@ import org.sonar.server.projectlink.ws.ProjectLinksModule; | |||
import org.sonar.server.projecttag.ws.ProjectTagsWsModule; | |||
import org.sonar.server.property.InternalPropertiesImpl; | |||
import org.sonar.server.pushapi.ServerPushWsModule; | |||
import org.sonar.server.pushapi.qualityprofile.DistributedRuleActivatorEventsDistributor; | |||
import org.sonar.server.pushapi.qualityprofile.QualityProfileChangeEventServiceImpl; | |||
import org.sonar.server.pushapi.qualityprofile.StandaloneRuleActivatorEventsDistributor; | |||
import org.sonar.server.qualitygate.ProjectsInWarningModule; | |||
import org.sonar.server.qualitygate.QualityGateModule; | |||
import org.sonar.server.qualitygate.notification.QGChangeNotificationHandler; | |||
import org.sonar.server.qualitygate.ws.QualityGateWsModule; | |||
import org.sonar.server.qualityprofile.builtin.BuiltInQPChangeNotificationHandler; | |||
import org.sonar.server.qualityprofile.builtin.BuiltInQPChangeNotificationTemplate; | |||
import org.sonar.server.qualityprofile.builtin.BuiltInQProfileRepositoryImpl; | |||
import org.sonar.server.pushapi.qualityprofile.DistributedRuleActivatorEventsDistributor; | |||
import org.sonar.server.qualityprofile.QProfileBackuperImpl; | |||
import org.sonar.server.qualityprofile.QProfileComparison; | |||
import org.sonar.server.qualityprofile.QProfileCopier; | |||
@@ -201,9 +200,10 @@ import org.sonar.server.qualityprofile.QProfileParser; | |||
import org.sonar.server.qualityprofile.QProfileResetImpl; | |||
import org.sonar.server.qualityprofile.QProfileRulesImpl; | |||
import org.sonar.server.qualityprofile.QProfileTreeImpl; | |||
import org.sonar.server.pushapi.qualityprofile.QualityProfileChangeEventServiceImpl; | |||
import org.sonar.server.qualityprofile.builtin.BuiltInQPChangeNotificationHandler; | |||
import org.sonar.server.qualityprofile.builtin.BuiltInQPChangeNotificationTemplate; | |||
import org.sonar.server.qualityprofile.builtin.BuiltInQProfileRepositoryImpl; | |||
import org.sonar.server.qualityprofile.builtin.RuleActivator; | |||
import org.sonar.server.pushapi.qualityprofile.StandaloneRuleActivatorEventsDistributor; | |||
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; | |||
import org.sonar.server.qualityprofile.ws.QProfilesWsModule; | |||
import org.sonar.server.root.ws.RootWsModule; | |||
@@ -537,8 +537,8 @@ public class PlatformLevel4 extends PlatformLevel { | |||
GithubAppSecurityImpl.class, | |||
GithubApplicationClientImpl.class, | |||
GithubApplicationHttpClientImpl.class, | |||
BitbucketCloudRestClientConfiguration.class, | |||
BitbucketServerRestClient.class, | |||
BitbucketCloudRestClient.class, | |||
GitlabHttpClient.class, | |||
AzureDevOpsHttpClient.class, | |||
new AlmIntegrationsWSModule(), |