/** * Handles HTTP 3xx/4xx/5xx statuses */ public static ApplicationRuntimeException handle(Application app, String url, RestClientException ex) { // HTTP 5xx if(ex instanceof HttpServerErrorException) { HttpServerErrorException serverEx = ((HttpServerErrorException)ex); return new ApplicationRuntimeException(app, String.format("A server error happened while calling %s (HTTP %s)", url, serverEx.getRawStatusCode())); } // HTTP 4xx else if(ex instanceof HttpClientErrorException) { HttpClientErrorException clientEx = ((HttpClientErrorException)ex); return new ApplicationRuntimeException(app, String.format("Bad request on endpoint %s (HTTP %s)", url, clientEx.getRawStatusCode())); } // HTTP 3xx else if(ex instanceof HttpRedirectErrorException) { HttpRedirectErrorException redirectEx = ((HttpRedirectErrorException)ex); if(redirectEx.getStatusCode().series() == Series.REDIRECTION) { return new ApplicationRuntimeException(app, String.format("Endpoint %s is available but security might be enabled (HTTP %s)", url, redirectEx.getRawStatusCode() )); } } return handle(app, ex); }
@Override public void handleError(ClientHttpResponse response) throws IOException { HttpStatus statusCode = response.getStatusCode(); if (statusCode.series() == Series.SERVER_ERROR) { handleServerErrors(statusCode); } else if (statusCode.series() == Series.CLIENT_ERROR) { handleClientErrors(response); } // if not otherwise handled, do default handling and wrap with UncategorizedApiException try { super.handleError(response); } catch (Exception e) { throw new UncategorizedApiException(TWITTER, "Error consuming Twitter REST API", e); } }
private Component getRestGrid(Collection<MetricsRest> metrics, Series httpSerie) { List<MetricsRest> metricsItems = metrics.stream() .filter(m -> m.valid() && m.getStatus().series() == httpSerie) .collect(Collectors.toList()); if(metricsItems.isEmpty()) { return new Label("No requests"); } else { Grid<MetricsRest> gridCache = new Grid<>(MetricsRest.class); gridCache.removeAllColumns(); gridCache.addColumn(MetricsRest::getName).setCaption("Path").setExpandRatio(1); gridCache.addColumn(m -> m.getStatus() + " " + m.getStatus().getReasonPhrase()).setCaption("HTTP Status"); gridCache.addColumn(MetricsRest::getValue).setCaption("Hits"); gridCache.addColumn(MetricsRest::getLastResponseTime).setCaption("Last Response Time (ms)"); gridCache.setItems(metricsItems); if(metricsItems.size() < 10) { gridCache.setHeightByRows(metricsItems.size()); } gridCache.setWidth(100, Unit.PERCENTAGE); return gridCache; } }
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; chain.doFilter(request, response); if (HttpStatus.Series.valueOf(response.getStatus()) == Series.SUCCESSFUL) { return; } logger.warn("Status {} returned from {}", response.getStatus(), GlobalExceptionMapping.buildRequestInfo(request)); }
private String getFinalStatus(HttpServletRequest request, String path, int status) { Object bestMatchingPattern = request .getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); if (bestMatchingPattern != null) { return fixSpecialCharacters(bestMatchingPattern.toString()); } Series series = getSeries(status); if (Series.CLIENT_ERROR.equals(series) || Series.SERVER_ERROR.equals(series) || Series.REDIRECTION.equals(series)) { return UNKNOWN_PATH_SUFFIX; } return path; }
private Series getSeries(int status) { try { return HttpStatus.valueOf(status).series(); } catch (Exception ex) { return null; } }
private String getFinalStatus(HttpServletRequest request, String path, int status) { Object bestMatchingPattern = request .getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); if (bestMatchingPattern != null) { return fixSpecialCharacters(bestMatchingPattern.toString()); } Series series = getSeries(status); if (Series.CLIENT_ERROR.equals(series) || Series.REDIRECTION.equals(series)) { return UNKNOWN_PATH_SUFFIX; } return path; }
public boolean hasError(ClientHttpResponse response) throws IOException { HttpStatus statusCode = response.getStatusCode(); if(statusCode == HttpStatus.NOT_FOUND) { return false; } return statusCode.series() == Series.CLIENT_ERROR || statusCode.series() == Series.SERVER_ERROR; }
@Override public void enter(ViewChangeEvent event) { pageHelper.setErrorHandler(this); this.removeAllComponents(); // Get application int appId = Integer.parseInt(event.getParameters()); Application app = pageHelper.getApp(appId); // Get metrics Health health = healthService.getHealth(app); Optional<Map<String, Number>> metrics = metricsService.getAllMetrics(app); if(!metrics.isPresent()) { throw new ApplicationRuntimeException(app, "No metrics found"); } Collection<MetricsCache> metricsCaches = metricsService.getMetricsCaches(metrics.get()).get(); List<MetricsRest> metricsRest = metricsService.getMetricsRest(metrics.get()).get(); Collection<MetricsDatasource> metricsDb = metricsService.getMetricsDatasources(metrics.get()).get(); MetricsSystem metricsSystem = metricsService.getSystemMetrics(metrics.get()).get(); // Build UI this.addComponent(new PageHeader(app, "Metrics")); this.addComponent(new Label("<h3>Health</h3>", ContentMode.HTML)); this.addComponent(getHealth(health)); this.addComponent(new Label("<h3>System metrics</h3>", ContentMode.HTML)); this.addComponent(getSystemPanel(metricsSystem)); if(!metricsRest.isEmpty()) { this.addComponent(new Label("<h3>Rest Controllers metrics : HTTP 2xx</h3>", ContentMode.HTML)); this.addComponent(getRestGrid(metricsRest, Series.SUCCESSFUL)); this.addComponent(new Label("<h3>Rest Controllers metrics : HTTP 3xx</h3>", ContentMode.HTML)); this.addComponent(getRestGrid(metricsRest, Series.REDIRECTION)); this.addComponent(new Label("<h3>Rest Controllers metrics : HTTP 4xx</h3>", ContentMode.HTML)); this.addComponent(getRestGrid(metricsRest, Series.CLIENT_ERROR)); this.addComponent(new Label("<h3>Rest Controllers metrics : HTTP 5xx</h3>", ContentMode.HTML)); this.addComponent(getRestGrid(metricsRest, Series.SERVER_ERROR)); } if(!metricsCaches.isEmpty()) { this.addComponent(new Label("<h3>Cache metrics</h3>", ContentMode.HTML)); this.addComponent(getCacheGrid(metricsCaches)); } if(!metricsDb.isEmpty()) { this.addComponent(new Label("<h3>Datasource metrics</h3>", ContentMode.HTML)); this.addComponent(getDatasourceGrid(metricsDb)); } allMetricsGrid = getAllMetricsGrid(metrics.get()); this.addComponent(new Label("<h3>All metrics</h3>", ContentMode.HTML)); this.addComponent(allMetricsGrid); }
@Test public void shouldExposeTypeOfSeries() { assertThat(series().getType(), is(TypeToken.of(Series.class))); }
/** * A {@link Navigator} that selects a binding based on the response's status code series * * @return an HTTP status code series selector * @see Series */ public static Navigator<Series> series() { return SeriesNavigator.INSTANCE; }