import org.sonar.api.utils.log.Loggers;
import org.sonarqube.ws.client.OkHttpClientBuilder;
+import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static java.util.Locale.ENGLISH;
import static org.sonar.api.internal.apachecommons.lang.StringUtils.removeEnd;
return doGet(token, url, r -> buildGson().fromJson(r.body().charStream(), ProjectList.class));
}
- public BranchesList getBranches(String serverUrl, String token, String projectSlug, String repositorySlug){
+ public BranchesList getBranches(String serverUrl, String token, String projectSlug, String repositorySlug) {
HttpUrl url = buildUrl(serverUrl, format("/rest/api/1.0/projects/%s/repos/%s/branches", projectSlug, repositorySlug));
return doGet(token, url, r -> buildGson().fromJson(r.body().charStream(), BranchesList.class));
}
return doCall(request, handler);
}
- protected static Request prepareRequestWithBearerToken(String token, String method, HttpUrl url, @Nullable RequestBody body) {
- return new Request.Builder()
+ protected static Request prepareRequestWithBearerToken(@Nullable String token, String method, HttpUrl url, @Nullable RequestBody body) {
+ Request.Builder builder = new Request.Builder()
.method(method, body)
.url(url)
- .addHeader("Authorization", "Bearer " + token)
- .addHeader("x-atlassian-token", "no-check")
- .build();
+ .addHeader("x-atlassian-token", "no-check");
+
+ if (!isNullOrEmpty(token)) {
+ builder.addHeader("Authorization", "Bearer " + token);
+ }
+
+ return builder.build();
}
protected <G> G doCall(Request request, Function<Response, G> handler) {
handleError(response);
return handler.apply(response);
} catch (JsonSyntaxException e) {
+ LOG.info(UNABLE_TO_CONTACT_BITBUCKET_SERVER + ": " + e.getMessage(), e);
throw new IllegalArgumentException(UNABLE_TO_CONTACT_BITBUCKET_SERVER + ", got an unexpected response", e);
} catch (IOException e) {
+ LOG.info(UNABLE_TO_CONTACT_BITBUCKET_SERVER + ": " + e.getMessage(), e);
throw new IllegalArgumentException(UNABLE_TO_CONTACT_BITBUCKET_SERVER, e);
}
}
}
protected static String getErrorMessage(ResponseBody body) throws IOException {
+ String bodyString = body.string();
if (equals(MediaType.parse("application/json;charset=utf-8"), body.contentType())) {
try {
- return Stream.of(buildGson().fromJson(body.charStream(), Errors.class).errorData)
+ return Stream.of(buildGson().fromJson(bodyString, Errors.class).errorData)
.map(e -> e.exceptionName + " " + e.message)
.collect(Collectors.joining("\n"));
} catch (JsonParseException e) {
- return body.string();
+ return bodyString;
}
}
- return body.string();
+ return bodyString;
}
protected static Gson buildGson() {
import okhttp3.mockwebserver.MockWebServer;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.sonar.alm.client.ConstantTimeoutConfiguration;
+import org.sonar.api.utils.log.LogTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
public class BitbucketServerRestClientTest {
private final MockWebServer server = new MockWebServer();
+
+ @Rule
+ public LogTester logTester = new LogTester();
+
private BitbucketServerRestClient underTest;
@Before
.hasMessage("Invalid personal access token");
}
+ @Test
+ public void fail_validate_on_io_exception() throws IOException {
+ server.shutdown();
+
+ String serverUrl = server.url("/").toString();
+ assertThatThrownBy(() -> underTest.validateUrl(serverUrl))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Unable to contact Bitbucket server");
+
+ assertThat(String.join(", ", logTester.logs())).contains("Unable to contact Bitbucket server: Failed to connect");
+ }
+
+ @Test
+ public void fail_validate_url_on_non_json_result_log_correctly_the_response(){
+ server.enqueue(new MockResponse()
+ .setHeader("Content-Type", "application/json;charset=UTF-8")
+ .setResponseCode(500)
+ .setBody("not json"));
+
+ String serverUrl = server.url("/").toString();
+ assertThatThrownBy(() -> underTest.validateReadPermission(serverUrl, "token"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Unable to contact Bitbucket server");
+
+ assertThat(String.join(", ", logTester.logs())).contains("Unable to contact Bitbucket server: 500 not json");
+ }
+
+ @Test
+ public void fail_validate_url_on_text_result_log_the_returned_payload(){
+ server.enqueue(new MockResponse()
+ .setResponseCode(500)
+ .setBody("this is a text payload"));
+
+ String serverUrl = server.url("/").toString();
+ assertThatThrownBy(() -> underTest.validateReadPermission(serverUrl, "token"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Unable to contact Bitbucket server");
+
+ assertThat(String.join(", ", logTester.logs())).contains("Unable to contact Bitbucket server: 500 this is a text payload");
+ }
+
}