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)); } }
@Override public String getURL() { return StringUtils.removeEnd(client.baseUrl(), "/"); }
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.createErrorMessage(e)); } throw new IllegalStateException(errorMsg.get() + ": " + ScannerWsClient.createErrorMessage(e)); } catch (MessageException e) { throw e; } catch (Exception e) { throw new IllegalStateException(errorMsg.get(), e); } }
/** * Tries to form a short and relevant error message from the exception, to be displayed in the console. */ public static String createErrorMessage(HttpException exception) { String json = tryParseAsJsonError(exception.content()); if (json != null) { return json; } String msg = "HTTP code " + exception.code(); if (isHtml(exception.content())) { return msg; } return msg + ": " + StringUtils.left(exception.content(), MAX_ERROR_MSG_LEN); }
@Test public void log_and_profile_request_if_debug_level() { WsRequest request = newRequest(); WsResponse response = newResponse().setRequestUrl("https://local/api/issues/search"); when(wsClient.wsConnector().call(request)).thenReturn(response); logTester.setLevel(LoggerLevel.DEBUG); ScannerWsClient underTest = new ScannerWsClient(wsClient, false, new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap()))); WsResponse result = underTest.call(request); // do not fail the execution -> interceptor returns the response assertThat(result).isSameAs(response); // check logs List<String> debugLogs = logTester.logs(LoggerLevel.DEBUG); assertThat(debugLogs).hasSize(1); assertThat(debugLogs.get(0)).contains("GET 200 https://local/api/issues/search | time="); }
response = wsClient.call(post).failIfNotSuccessful(); } catch (HttpException e) { throw MessageException.of(String.format("Failed to upload report - %s", ScannerWsClient.createErrorMessage(e)));
/** * If an exception is not thrown, the response needs to be closed by either calling close() directly, or closing the * body content's stream/reader. * * @throws IllegalStateException if the request could not be executed due to a connectivity problem or timeout. Because networks can * fail during an exchange, it is possible that the remote server accepted the request before the failure * @throws MessageException if there was a problem with authentication or if a error message was parsed from the response. * @throws HttpException if the response code is not in range [200..300). Consider using {@link #createErrorMessage(HttpException)} to create more relevant messages for the users. */ public WsResponse call(WsRequest request) { Preconditions.checkState(!globalMode.isMediumTest(), "No WS call should be made in medium test mode"); Profiler profiler = Profiler.createIfDebug(LOG).start(); WsResponse response = target.wsConnector().call(request); profiler.stopDebug(format("%s %d %s", request.getMethod(), response.code(), response.requestUrl())); failIfUnauthorized(response); return response; }
private void failIfUnauthorized(WsResponse response) { int code = response.code(); if (code == HTTP_UNAUTHORIZED) { response.close(); if (hasCredentials) { // credentials are not valid throw MessageException.of(format("Not authorized. Please check the properties %s and %s.", CoreProperties.LOGIN, CoreProperties.PASSWORD)); } // not authenticated - see https://jira.sonarsource.com/browse/SONAR-4048 throw MessageException.of(format("Not authorized. Analyzing this project requires to be authenticated. " + "Please provide the values of the properties %s and %s.", CoreProperties.LOGIN, CoreProperties.PASSWORD)); } if (code == HTTP_FORBIDDEN) { throw MessageException.of("You're not authorized to run analysis. Please contact the project administrator."); } if (code == HTTP_BAD_REQUEST) { String jsonMsg = tryParseAsJsonError(response.content()); if (jsonMsg != null) { throw MessageException.of(jsonMsg); } } // if failed, throws an HttpException response.failIfNotSuccessful(); }
@Before public void setUp() throws Exception { HttpConnector connector = HttpConnector.newBuilder().url(server.url("/").toString()).build(); GlobalAnalysisMode analysisMode = new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap())); ScannerWsClient wsClient = new ScannerWsClient(WsClientFactories.getDefault().newClient(connector), false, analysisMode); userHome = temp.newFolder(); MapSettings settings = new MapSettings(); settings.setProperty("sonar.userHome", userHome.getAbsolutePath()); underTest = new PluginFiles(wsClient, settings.asConfig()); }
@Test public void fail_if_requires_credentials() { expectedException.expect(MessageException.class); expectedException .expectMessage("Not authorized. Analyzing this project requires to be authenticated. Please provide the values of the properties sonar.login and sonar.password."); WsRequest request = newRequest(); WsResponse response = newResponse().setCode(401); when(wsClient.wsConnector().call(request)).thenReturn(response); new ScannerWsClient(wsClient, false, new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap()))).call(request); }
response = wsClient.call(post).failIfNotSuccessful(); } catch (HttpException e) { throw MessageException.of(String.format("Failed to upload report - %s", ScannerWsClient.createErrorMessage(e)));
/** * Tries to form a short and relevant error message from the exception, to be displayed in the console. */ public static String createErrorMessage(HttpException exception) { String json = tryParseAsJsonError(exception.content()); if (json != null) { return json; } String msg = "HTTP code " + exception.code(); if (isHtml(exception.content())) { return msg; } return msg + ": " + StringUtils.left(exception.content(), MAX_ERROR_MSG_LEN); }
/** * If an exception is not thrown, the response needs to be closed by either calling close() directly, or closing the * body content's stream/reader. * * @throws IllegalStateException if the request could not be executed due to a connectivity problem or timeout. Because networks can * fail during an exchange, it is possible that the remote server accepted the request before the failure * @throws MessageException if there was a problem with authentication or if a error message was parsed from the response. * @throws HttpException if the response code is not in range [200..300). Consider using {@link #createErrorMessage(HttpException)} to create more relevant messages for the users. */ public WsResponse call(WsRequest request) { Preconditions.checkState(!globalMode.isMediumTest(), "No WS call should be made in medium test mode"); Profiler profiler = Profiler.createIfDebug(LOG).start(); WsResponse response = target.wsConnector().call(request); profiler.stopDebug(format("%s %d %s", request.getMethod(), response.code(), response.requestUrl())); failIfUnauthorized(response); return response; }
private void failIfUnauthorized(WsResponse response) { int code = response.code(); if (code == HTTP_UNAUTHORIZED) { response.close(); if (hasCredentials) { // credentials are not valid throw MessageException.of(format("Not authorized. Please check the properties %s and %s.", CoreProperties.LOGIN, CoreProperties.PASSWORD)); } // not authenticated - see https://jira.sonarsource.com/browse/SONAR-4048 throw MessageException.of(format("Not authorized. Analyzing this project requires to be authenticated. " + "Please provide the values of the properties %s and %s.", CoreProperties.LOGIN, CoreProperties.PASSWORD)); } if (code == HTTP_FORBIDDEN) { throw MessageException.of("You're not authorized to run analysis. Please contact the project administrator."); } if (code == HTTP_BAD_REQUEST) { String jsonMsg = tryParseAsJsonError(response.content()); if (jsonMsg != null) { throw MessageException.of(jsonMsg); } } // if failed, throws an HttpException response.failIfNotSuccessful(); }
public static void mockException(ScannerWsClient mock, Exception e) { when(mock.call(any(WsRequest.class))).thenThrow(e); }
@Test public void fail_if_credentials_are_not_valid() { expectedException.expect(MessageException.class); expectedException.expectMessage("Not authorized. Please check the properties sonar.login and sonar.password."); WsRequest request = newRequest(); WsResponse response = newResponse().setCode(401); when(wsClient.wsConnector().call(request)).thenReturn(response); new ScannerWsClient(wsClient, /* credentials are configured */true, new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap()))).call(request); }
@Override public String getPublicRootUrl() { String baseUrl = trimToEmpty(settings.get(CoreProperties.SERVER_BASE_URL).orElse("")); if (baseUrl.isEmpty()) { // If server base URL was not configured in Sonar server then is is better to take URL configured on batch side baseUrl = client.baseUrl(); } return StringUtils.removeEnd(baseUrl, "/"); }
@Test public void create_error_msg_from_json() { String content = "{\"errors\":[{\"msg\":\"missing scan permission\"}, {\"msg\":\"missing another permission\"}]}"; assertThat(ScannerWsClient.createErrorMessage(new HttpException("url", 400, content))).isEqualTo("missing scan permission, missing another permission"); }
public static void mockStream(ScannerWsClient mock, InputStream is) { WsResponse response = mock(WsResponse.class); when(response.contentStream()).thenReturn(is); when(mock.call(any(WsRequest.class))).thenReturn(response); }
@Test public void fail_if_requires_permission() { expectedException.expect(MessageException.class); expectedException.expectMessage("You're not authorized to run analysis. Please contact the project administrator."); WsRequest request = newRequest(); WsResponse response = newResponse() .setCode(403); when(wsClient.wsConnector().call(request)).thenReturn(response); new ScannerWsClient(wsClient, true, new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap()))).call(request); }