import java.util.List;
import java.util.Map;
import java.util.function.BinaryOperator;
+import java.util.function.Supplier;
import javax.annotation.Nullable;
import org.sonar.api.utils.MessageException;
import org.sonar.scanner.bootstrap.ScannerWsClient;
import org.sonarqube.ws.Qualityprofiles.SearchWsResponse;
import org.sonarqube.ws.Qualityprofiles.SearchWsResponse.QualityProfile;
import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.HttpException;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
@Override
public List<QualityProfile> loadDefault(@Nullable String profileName) {
StringBuilder url = new StringBuilder(WS_URL + "?defaults=true");
- return loadAndOverrideIfNeeded(profileName, url);
+ return handleErrors(profileName, url, () -> "Failed to load the default quality profiles");
}
@Override
public List<QualityProfile> load(String projectKey, @Nullable String profileName) {
StringBuilder url = new StringBuilder(WS_URL + "?projectKey=").append(encodeForUrl(projectKey));
- return loadAndOverrideIfNeeded(profileName, url);
+ return handleErrors(profileName, url, () -> String.format("Failed to load the quality profiles of project '%s'", projectKey));
}
- private List<QualityProfile> loadAndOverrideIfNeeded(@Nullable String profileName, StringBuilder url) {
+ private List<QualityProfile> handleErrors(@Nullable String profileName, StringBuilder url, Supplier<String> errorMsg) {
+ try {
+ return loadAndOverrideIfNeeded(profileName, url);
+ } catch (HttpException e) {
+ if (e.code() == 404) {
+ throw MessageException.of(errorMsg.get() + ": " + ScannerWsClient.tryParseAsJsonError(e.content()));
+ }
+ throw new IllegalStateException(errorMsg.get(), e);
+ } catch (MessageException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new IllegalStateException(errorMsg.get(), e);
+ }
+ }
+
+ private List<QualityProfile> loadAndOverrideIfNeeded(@Nullable String profileName, StringBuilder url) throws IOException {
properties.organizationKey().ifPresent(k -> url.append("&organization=").append(encodeForUrl(k)));
Map<String, QualityProfile> result = call(url.toString());
return new ArrayList<>(result.values());
}
- private Map<String, QualityProfile> call(String url) {
+ private Map<String, QualityProfile> call(String url) throws IOException {
GetRequest getRequest = new GetRequest(url);
try (InputStream is = wsClient.call(getRequest).contentStream()) {
SearchWsResponse profiles = SearchWsResponse.parseFrom(is);
List<QualityProfile> profilesList = profiles.getProfilesList();
return profilesList.stream().collect(toMap(QualityProfile::getLanguage, identity(), throwingMerger(), LinkedHashMap::new));
- } catch (IOException e) {
- throw new IllegalStateException("Failed to load quality profiles", e);
}
-
}
private static <T> BinaryOperator<T> throwingMerger() {
import org.sonar.scanner.scan.ScanProperties;
import org.sonarqube.ws.Qualityprofiles;
import org.sonarqube.ws.Qualityprofiles.SearchWsResponse.QualityProfile;
+import org.sonarqube.ws.client.HttpException;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoMoreInteractions;
verifyNoMoreInteractions(wsClient);
}
+ @Test
+ public void load_throws_MessageException_if_organization_is_not_found() throws IOException {
+ HttpException e = new HttpException("", 404, "{\"errors\":[{\"msg\":\"No organization with key 'myorg'\"}]}");
+ WsTestUtil.mockException(wsClient, e);
+
+ exception.expect(MessageException.class);
+ exception.expectMessage("Failed to load the quality profiles of project 'project': No organization with key 'myorg'");
+
+ underTest.load("project", null);
+ verifyNoMoreInteractions(wsClient);
+ }
+
private void verifyCalledPath(String expectedPath) {
WsTestUtil.verifyCall(wsClient, expectedPath);
}
import java.io.IOException;
import java.util.Map;
import org.apache.commons.io.FileUtils;
+import org.apache.http.MessageConstraintException;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonarqube.qa.util.Tester;
import org.sonarqube.tests.Category3Suite;
@Rule
public Tester tester = new Tester(orchestrator).disableOrganizations();
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
@Before
public void setUp() {
ItUtils.restoreProfile(orchestrator, getClass().getResource("/analysis/BatchTest/one-issue-per-line.xml"));
File cache = new File(userHome, "cache");
assertThat(cache).exists().isDirectory();
- int cachedFiles = FileUtils.listFiles(cache, new String[]{"jar"}, true).size();
+ int cachedFiles = FileUtils.listFiles(cache, new String[] {"jar"}, true).size();
assertThat(cachedFiles).isGreaterThan(5);
assertThat(result.getLogs()).contains("User cache: " + cache.getAbsolutePath());
result = scan("shared/xoo-sample",
"sonar.userHome", userHome.getAbsolutePath());
- int cachedFiles2 = FileUtils.listFiles(cache, new String[]{"jar"}, true).size();
+ int cachedFiles2 = FileUtils.listFiles(cache, new String[] {"jar"}, true).size();
assertThat(cachedFiles).isEqualTo(cachedFiles2);
assertThat(result.getLogs()).contains("User cache: " + cache.getAbsolutePath());
}
assertThat(getComponent(orchestrator, "com.sonarsource.it.samples:moduleB")).isNotNull();
}
+ @Test
+ public void use_invalid_organization_key() {
+ BuildResult result = scanQuietly("shared/xoo-sample",
+ "sonar.organization", "non-existing-org");
+
+ assertThat(result.isSuccess()).isFalse();
+ assertThat(result.getLogs()).contains("Failed to load the default quality profiles: No organization with key 'non-existing-org'");
+ }
+
private BuildResult scan(String projectPath, String... props) {
SonarScanner scanner = configureScanner(projectPath, props);
return orchestrator.executeBuild(scanner);