Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,15 @@
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import javax.imageio.ImageIO;
import jenkins.scm.api.SCMFile;
import jenkins.scm.impl.avatars.AvatarImage;
import org.apache.commons.lang.StringUtils;
import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.http.message.BasicNameValuePair;

import static java.util.concurrent.TimeUnit.HOURS;
Expand All @@ -97,7 +93,8 @@
// Limit images to 16k
private static final int MAX_AVATAR_LENGTH = 16384;
private static final int MAX_PAGE_LENGTH = 100;
protected static final HttpClientConnectionManager connectionManager = connectionManager();

private static final HttpClientConnectionManager connectionManager = buildConnectionManager();

private final CloseableHttpClient client;
private final String owner;
Expand All @@ -110,32 +107,6 @@
private transient BitbucketRepository cachedRepository;
private transient String cachedDefaultBranch;

private static HttpClientConnectionManager connectionManager() {
try {
int connectTimeout = Integer.getInteger("http.connect.timeout", 10);
int socketTimeout = Integer.getInteger("http.socket.timeout", 60);

ConnectionConfig connCfg = ConnectionConfig.custom()
.setConnectTimeout(connectTimeout, TimeUnit.SECONDS)
.setSocketTimeout(socketTimeout, TimeUnit.SECONDS)
.build();

SocketConfig socketConfig = SocketConfig.custom()
.setSoTimeout(60, TimeUnit.SECONDS)
.build();

return PoolingHttpClientConnectionManagerBuilder.create()
.setMaxConnPerRoute(20)
.setMaxConnTotal(22)
.setDefaultConnectionConfig(connCfg)
.setSocketConfigResolver(host -> host.getTargetHost().equals(API_HOST) ? socketConfig : SocketConfig.DEFAULT)
.build();
} catch (Exception e) {
// in case of exception this avoids ClassNotFoundError which prevents the classloader from loading this class again
return null;
}
}

public static List<String> stats() {
List<String> stats = new ArrayList<>();
stats.add("Team: " + cachedTeam.stats().toString());
Expand Down Expand Up @@ -168,7 +139,7 @@
cachedTeam.setExpireDuration(teamCacheDuration, MINUTES);
cachedRepositories.setExpireDuration(repositoriesCacheDuration, MINUTES);
}
this.client = super.setupClientBuilder("bitbucket.org").build();
this.client = super.setupClientBuilder().build();
}

/**
Expand Down Expand Up @@ -679,7 +650,7 @@
@Deprecated(since = "935.0.0", forRemoval = true)
@Override
@CheckForNull
public AvatarImage getTeamAvatar() throws IOException {

Check warning on line 653 in src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClient.java

View check run for this annotation

ci.jenkins.io / Java Compiler

compiler:compile

NORMAL: getTeamAvatar() in com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi has been deprecated and marked for removal
final BitbucketTeam team = getTeam();
return getAvatar(team == null ? null : team.getAvatar());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import java.io.IOException;
import java.io.InputStream;
import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.io.entity.EntityUtils;

Expand All @@ -36,16 +35,12 @@ public class ClosingConnectionInputStream extends InputStream {

private final HttpUriRequest method;

private final HttpClientConnectionManager connectionManager;

private final InputStream delegate;

public ClosingConnectionInputStream(final ClassicHttpResponse response,
final HttpUriRequest method,
final HttpClientConnectionManager connectionmanager) throws IOException {
final HttpUriRequest method) throws IOException {
this.response = response;
this.method = method;
this.connectionManager = connectionmanager;
this.delegate = response.getEntity().getContent();
}

Expand All @@ -58,8 +53,7 @@ public int available() throws IOException {
public void close() throws IOException {
EntityUtils.consume(response.getEntity());
delegate.close();
//FIXME method.releaseConnection();
//FIXME connectionManager.closeExpiredConnections();
// method.releaseConnection();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import com.cloudbees.jenkins.plugins.bitbucket.client.ClosingConnectionInputStream;
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import hudson.ProxyConfiguration;
import hudson.util.Secret;
import java.io.FileNotFoundException;
Expand All @@ -54,13 +53,15 @@
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.classic.methods.HttpPut;
import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.auth.BasicScheme;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.http.ClassicHttpResponse;
Expand Down Expand Up @@ -133,20 +134,35 @@ private long getLenghtFromHeader(ClassicHttpResponse response) {
return len;
}

protected HttpClientBuilder setupClientBuilder(@Nullable String host) {
protected static HttpClientConnectionManager buildConnectionManager() {
int connectTimeout = Integer.getInteger("http.connect.timeout", 10);
int socketTimeout = Integer.getInteger("http.socket.timeout", 60);
ConnectionConfig connectionConfig = ConnectionConfig.custom()
.setConnectTimeout(connectTimeout, TimeUnit.SECONDS)
.setSocketTimeout(socketTimeout, TimeUnit.SECONDS)
.build();

HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
.setMaxConnPerRoute(20)
.setMaxConnTotal(22)
.setDefaultConnectionConfig(connectionConfig)
.build();
return connectionManager;
}

protected HttpClientBuilder setupClientBuilder() {
int connectionRequestTimeout = Integer.getInteger("http.connect.request.timeout", 60);

RequestConfig config = RequestConfig.custom()
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(connectionRequestTimeout, TimeUnit.SECONDS)
.build();

HttpClientConnectionManager connectionManager = getConnectionManager();
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
.useSystemProperties()
.setConnectionManager(connectionManager)
.setConnectionManagerShared(connectionManager != null)
.setConnectionManager(getConnectionManager())
.setConnectionManagerShared(true)
.setRetryStrategy(new ExponentialBackoffRetryStrategy(2, TimeUnit.SECONDS.toMillis(5), TimeUnit.HOURS.toMillis(1)))
.setDefaultRequestConfig(config)
.setDefaultRequestConfig(requestConfig)
.evictExpiredConnections()
.evictIdleConnections(TimeValue.ofSeconds(2))
.disableCookieManagement();
Expand Down Expand Up @@ -269,7 +285,7 @@ protected InputStream getRequestAsInputStream(String path) throws IOException {
String content = getResponseContent(response);
throw buildResponseException(response, content);
}
return new ClosingConnectionInputStream(response, httpget, getConnectionManager());
return new ClosingConnectionInputStream(response, httpget);
}

protected int headRequestStatus(String path) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,17 @@
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator;
import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
import hudson.util.Secret;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.hc.client5.http.auth.AuthCache;
import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.CredentialsStore;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.auth.BasicScheme;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.http.HttpHost;
import java.nio.charset.StandardCharsets;
import org.apache.hc.client5.http.utils.Base64;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpRequest;

/**
* Authenticator that uses a username and password (probably the default)
*/
public class BitbucketUsernamePasswordAuthenticator implements BitbucketAuthenticator {

private static final Logger LOGGER = Logger.getLogger(BitbucketUsernamePasswordAuthenticator.class.getName());

private final UsernamePasswordCredentials httpCredentials;
private final String encodedAuth;
private final String credentialsId;

/**
Expand All @@ -57,24 +48,14 @@
public BitbucketUsernamePasswordAuthenticator(StandardUsernamePasswordCredentials credentials) {
credentialsId = credentials.getId();
String password = Secret.toString(credentials.getPassword());
httpCredentials = new UsernamePasswordCredentials(credentials.getUsername(), password.toCharArray());
String auth = credentials.getUsername() + ":" + password;
encodedAuth = Base64.encodeBase64String(auth.getBytes(StandardCharsets.ISO_8859_1));
}

/**
* Sets up HTTP Basic Auth with the provided username/password
*
* @param context The connection context
* @param host host being connected to
*/
@Override
public void configureContext(HttpClientContext context, HttpHost host) {
CredentialsStore credentialsStore = new BasicCredentialsProvider();
credentialsStore.setCredentials(new AuthScope(host), httpCredentials);
AuthCache authCache = new BasicAuthCache();
LOGGER.log(Level.FINE,"Add host={0} to authCache.", host);
authCache.put(host, new BasicScheme());
context.setCredentialsProvider(credentialsStore);
context.setAuthCache(authCache);
public void configureRequest(HttpRequest request) {
final String authHeader = "Basic " + encodedAuth;
request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);

Check warning on line 58 in src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/credentials/BitbucketUsernamePasswordAuthenticator.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 57-58 are not covered by tests
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@
import org.apache.commons.lang.StringUtils;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpStatus;
Expand Down Expand Up @@ -139,19 +138,7 @@
private static final String API_MIRRORS_PATH = "/rest/mirroring/1.0/mirrorServers";
private static final Integer DEFAULT_PAGE_LIMIT = 200;

protected static final HttpClientConnectionManager connectionManager = connectionManager();

private static HttpClientConnectionManager connectionManager() {
try {
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); // NOSONAR
connManager.setDefaultMaxPerRoute(20);
connManager.setMaxTotal(22);
return connManager;
} catch (Exception e) {
// in case of exception this avoids ClassNotFoundError which prevents the classloader from loading this class again
return null;
}
}
private static final HttpClientConnectionManager connectionManager = buildConnectionManager();

/**
* Repository owner.
Expand Down Expand Up @@ -190,7 +177,7 @@
this.repositoryName = repositoryName;
this.baseURL = Util.removeTrailingSlash(baseURL);
this.webhookImplementation = requireNonNull(webhookImplementation);
this.client = setupClientBuilder(baseURL).build();
this.client = setupClientBuilder().build();
}

/**
Expand Down Expand Up @@ -798,7 +785,7 @@
*/
@Deprecated(since = "935.0.0", forRemoval = true)
@Override
public AvatarImage getTeamAvatar() throws IOException {

Check warning on line 788 in src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java

View check run for this annotation

ci.jenkins.io / Java Compiler

compiler:compile

NORMAL: getTeamAvatar() in com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi has been deprecated and marked for removal
if (userCentric) {
return AvatarImage.EMPTY;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ void test_retry(ClientAndServer mockServer) throws Exception {
false,
mock(BitbucketServerWebhookImplementation.class)) {
@Override
protected HttpClientBuilder setupClientBuilder(String host) {
return super.setupClientBuilder(host)
protected HttpClientBuilder setupClientBuilder() {
return super.setupClientBuilder()
.setRetryStrategy(new ExponentialBackoffRetryStrategy(2, 5, 100))
.addResponseInterceptorFirst(counterInterceptor);
}
Expand Down
Loading