Skip to content

Commit dcdbd79

Browse files
authored
Merge pull request #59 from androidbod/feature/improve-connectivity-configuration-error-traceability-by-retaining-ioexception-and-parseexception-stacktraces-for-api-connection-exceptions
[JENKINS-75326] Improve api logging and fix issue caused by httpclient update
2 parents 05e3e44 + 7da272b commit dcdbd79

File tree

3 files changed

+22
-19
lines changed

3 files changed

+22
-19
lines changed

src/main/java/org/quality/gates/sonar/api/ApiConnectionException.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77
public class ApiConnectionException extends RuntimeException {
88

9-
public ApiConnectionException(String message) {
10-
super(message);
9+
public ApiConnectionException(String message, Throwable cause) {
10+
super(message, cause);
1111
}
1212
}

src/main/java/org/quality/gates/sonar/api/SonarHttpRequester.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
import java.nio.charset.StandardCharsets;
88
import java.util.ArrayList;
99
import java.util.Base64;
10+
import java.util.HashMap;
1011
import java.util.List;
12+
import java.util.Map;
1113
import org.apache.commons.lang.StringUtils;
1214
import org.apache.hc.client5.http.auth.AuthScope;
1315
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
@@ -20,7 +22,6 @@
2022
import org.apache.hc.client5.http.protocol.HttpClientContext;
2123
import org.apache.hc.core5.http.HttpHeaders;
2224
import org.apache.hc.core5.http.NameValuePair;
23-
import org.apache.hc.core5.http.ParseException;
2425
import org.apache.hc.core5.http.io.entity.EntityUtils;
2526
import org.apache.hc.core5.http.message.BasicNameValuePair;
2627
import org.quality.gates.jenkins.plugin.JobConfigData;
@@ -66,7 +67,9 @@ public void setLogged(boolean logged) {
6667
private void loginApi(SonarInstance sonarInstance) {
6768
httpClientContext = HttpClientContext.create();
6869

69-
if (StringUtils.isNotEmpty(sonarInstance.getToken().getPlainText())) {
70+
// For some reason the Token Secret can be null even if empty in the Global Configuration UI
71+
if (sonarInstance.getToken() != null
72+
&& StringUtils.isNotEmpty(sonarInstance.getToken().getPlainText())) {
7073
token = sonarInstance.getToken().getPlainText();
7174
httpClient = HttpClientBuilder.create().build();
7275
} else {
@@ -121,19 +124,23 @@ private String executeGetRequest(CloseableHttpClient client, HttpGet request) th
121124
request.addHeader(HttpHeaders.AUTHORIZATION, authHeader);
122125
}
123126

124-
try (var response = client.execute(request, httpClientContext, classicHttpResponse -> classicHttpResponse)) {
125-
var statusCode = response.getCode();
126-
var entity = response.getEntity();
127-
var returnResponse = EntityUtils.toString(entity);
127+
try {
128+
var responseMap = client.execute(request, httpClientContext, classicHttpResponse -> {
129+
Map<String, Object> retVal = new HashMap<>();
130+
retVal.put("statusCode", classicHttpResponse.getCode());
131+
retVal.put("content", EntityUtils.toString(classicHttpResponse.getEntity()));
132+
return retVal;
133+
});
128134

129-
EntityUtils.consume(entity);
135+
var statusCode = (Integer) responseMap.get("statusCode");
136+
var returnResponse = responseMap.get("content").toString();
130137

131138
if (statusCode != 200) {
132139
throw new QGException("Expected status 200, got: " + statusCode + ". Response: " + returnResponse);
133140
}
134141

135142
return returnResponse;
136-
} catch (IOException | ParseException e) {
143+
} catch (IOException e) {
137144
throw new QGException("GET execution error", e);
138145
}
139146
}

src/main/java/org/quality/gates/sonar/api/SonarHttpRequesterFactory.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import java.io.IOException;
44
import org.apache.hc.client5.http.classic.methods.HttpGet;
55
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
6-
import org.apache.hc.client5.http.protocol.HttpClientContext;
7-
import org.apache.hc.core5.http.ParseException;
86
import org.apache.hc.core5.http.io.entity.EntityUtils;
97
import org.quality.gates.jenkins.plugin.SonarInstance;
108
import org.quality.gates.sonar.api80.SonarHttpRequester80;
@@ -20,11 +18,9 @@ class SonarHttpRequesterFactory {
2018

2119
static SonarHttpRequester getSonarHttpRequester(SonarInstance sonarInstance) {
2220
var request = new HttpGet(getSonarApiServerVersion(sonarInstance));
23-
var context = HttpClientContext.create();
24-
25-
try (var client = HttpClientBuilder.create().build();
26-
var response = client.execute(request, context, classicHttpResponse -> classicHttpResponse)) {
27-
var sonarVersion = EntityUtils.toString(response.getEntity());
21+
try (var client = HttpClientBuilder.create().build()) {
22+
var sonarVersion = client.execute(
23+
request, classicHttpResponse -> EntityUtils.toString(classicHttpResponse.getEntity()));
2824

2925
if (majorSonarVersion(sonarVersion) == 8 && minorSonarVersion(sonarVersion) <= 7) {
3026
return new SonarHttpRequester80();
@@ -33,8 +29,8 @@ static SonarHttpRequester getSonarHttpRequester(SonarInstance sonarInstance) {
3329
} else {
3430
throw new UnsuportedVersionException("Plugin doesn't support this version of sonar api!");
3531
}
36-
} catch (IOException | ParseException e) {
37-
throw new ApiConnectionException(e.getLocalizedMessage());
32+
} catch (IOException e) {
33+
throw new ApiConnectionException(e.getLocalizedMessage(), e);
3834
}
3935
}
4036

0 commit comments

Comments
 (0)