private FullHttpResponse handleAuthenticatedUserRequest(FullHttpRequest request) throws Exception { String authenticatedUser = httpSessionManager.getAuthenticatedUser(request); if (authenticatedUser == null) { return HttpServices.createJsonResponse("null", OK); } else { return HttpServices.createJsonResponse("\"" + authenticatedUser + "\"", OK); } }
@Override public @Nullable FullHttpResponse handleRequest(ChannelHandlerContext ctx, HttpRequest request) throws Exception { QueryStringDecoder decoder = new QueryStringDecoder(request.uri()); List<String> agentIds = decoder.parameters().get("agent-id"); if (agentIds == null) { agentIds = ImmutableList.of(""); } String agentId = agentIds.get(0); List<String> traceIds = decoder.parameters().get("trace-id"); checkNotNull(traceIds, "Missing trace id in query string: %s", request.uri()); String traceId = traceIds.get(0); // check-live-traces is an optimization so glowroot server only has to check with remote // agents when necessary List<String> checkLiveTracesParams = decoder.parameters().get("check-live-traces"); boolean checkLiveTraces = false; if (checkLiveTracesParams != null && !checkLiveTracesParams.isEmpty()) { checkLiveTraces = Boolean.parseBoolean(checkLiveTracesParams.get(0)); } logger.debug( "handleRequest(): agentId={}, traceId={}, checkLiveTraces={}", agentId, traceId, checkLiveTraces); TraceExport traceExport = traceCommonService.getExport(agentId, traceId, checkLiveTraces); if (traceExport == null) { logger.warn("no trace found for id: {}", traceId); return new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND); } ChunkedInput<HttpContent> in = getExportChunkedInput(traceExport); HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); response.headers().set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); response.headers().set(HttpHeaderNames.CONTENT_TYPE, MediaType.ZIP.toString()); response .headers() .set("Content-Disposition", "attachment; filename=" + traceExport.fileName() + ".zip"); boolean keepAlive = HttpUtil.isKeepAlive(request); if (keepAlive && !request.protocolVersion().isKeepAliveDefault()) { response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); } HttpServices.preventCaching(response); ctx.write(response); ChannelFuture future = ctx.write(in); HttpServices.addErrorListener(future); if (!keepAlive) { HttpServices.addCloseListener(future); } // return null to indicate streaming return null; }
private static FullHttpResponse newHttpResponseWithStackTrace( Exception e, HttpResponseStatus status, @Nullable String simplifiedMessage) { StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); StringBuilder sb = new StringBuilder(); try { JsonGenerator jg = jsonFactory.createGenerator(CharStreams.asWriter(sb)); jg.writeStartObject(); String message; if (simplifiedMessage == null) { Throwable cause = e; Throwable childCause = cause.getCause(); while (childCause != null) { cause = childCause; childCause = cause.getCause(); } message = cause.getMessage(); } else { message = simplifiedMessage; } jg.writeStringField("message", message); jg.writeStringField("stackTrace", sw.toString()); jg.writeEndObject(); jg.close(); return HttpServices.createJsonResponse(sb.toString(), status); } catch (IOException f) { logger.error(f.getMessage(), f); return new DefaultFullHttpResponse(HTTP_1_1, INTERNAL_SERVER_ERROR); } }
private FullHttpResponse handleNotAuthenticated(HttpRequest request) { if (httpSessionManager.getSessionId(request) != null) { return HttpServices.createJsonResponse("{\"timedOut\":true}", UNAUTHORIZED); } else { return new DefaultFullHttpResponse(HTTP_1_1, UNAUTHORIZED); } }
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { if (HttpServices.shouldLogException(cause)) { logger.warn(cause.getMessage(), cause); } ctx.close(); }
@Override public FullHttpResponse handleRequest(ChannelHandlerContext ctx, HttpRequest request) throws Exception { URL url = Resources.getResource("org/glowroot/ui/app-dist/index.html"); String indexHtml = Resources.toString(url, Charsets.UTF_8); String layout; if (httpSessionManager.hasReadAccess(request)) { layout = layoutJsonService.getLayout(); } else { layout = layoutJsonService.getNeedsAuthenticationLayout(); } String authenticatedUser = httpSessionManager.getAuthenticatedUser(request); String layoutScript = "var layout=" + layout + ";var authenticatedUser = '******'"; indexHtml = indexHtml.replaceFirst( "<base href=\"/\">", "<base href=\"" + BASE_HREF + "\"><script>" + layoutScript + "</script>"); // this is to work around an issue with IE10-11 (IE9 is OK) // (even without reverse proxy/non-root base href) // IE doesn't use the base href when loading the favicon indexHtml = indexHtml.replaceFirst( "<link rel=\"shortcut icon\" href=\"favicon\\.([0-9a-f]+)\\.ico\">", "<script>document.write('<link rel=\"shortcut icon\" href=\"'" + " + document.getElementsByTagName(\"base\")[0].href" + " + 'favicon.$1.ico\">');</script>"); if (GOOGLE_ANALYTICS_TRACKING_ID != null) { // this is for demo.glowroot.org indexHtml = indexHtml.replaceFirst( "<div class=\"navbar-brand\">(\\s*)Glowroot(\\s*)</div>", "<a href=\"https://glowroot.org\" class=\"navbar-brand\">$1Glowroot$2</a>"); indexHtml = indexHtml.replaceFirst( "</body>", "<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]" + "||function(){(i[r].q=i[r].q||[]).push(arguments)}," + "i[r].l=1*new Date();a=s.createElement(o)," + "m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;" + "m.parentNode.insertBefore(a,m)})(window,document,'script'," + "'//www.google-analytics.com/analytics.js','ga');ga('create', '" + GOOGLE_ANALYTICS_TRACKING_ID + "', 'auto');</script>\n</body>"); } ByteBuf content = Unpooled.copiedBuffer(indexHtml, Charsets.ISO_8859_1); FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, content); HttpServices.preventCaching(response); response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8"); response.headers().set(HttpHeaderNames.CONTENT_LENGTH, indexHtml.length()); // X-UA-Compatible must be set via header (as opposed to via meta tag) // see https://github.com/h5bp/html5-boilerplate/blob/master/doc/html.md#x-ua-compatible response.headers().set("X-UA-Compatible", "IE=edge"); return response; }
@Override public @Nullable FullHttpResponse handleRequest(ChannelHandlerContext ctx, HttpRequest request) throws Exception { File glowrootLogFile = new File(logDir, "glowroot.log"); CharSource glowrootLogCharSource = Files.asCharSource(glowrootLogFile, Charsets.UTF_8); HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); response.headers().set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8"); boolean keepAlive = HttpUtil.isKeepAlive(request); if (keepAlive && !request.protocolVersion().isKeepAliveDefault()) { response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); } HttpServices.preventCaching(response); ctx.write(response); ChannelFuture future = ctx.write(ChunkedInputs.from(ChunkSource.from(glowrootLogCharSource))); HttpServices.addErrorListener(future); if (!keepAlive) { HttpServices.addCloseListener(future); } // return null to indicate streaming return null; }
private static FullHttpResponse newHttpResponseWithMessage( HttpResponseStatus status, @Nullable String message) { // this is an "expected" exception, no need to send back stack trace StringBuilder sb = new StringBuilder(); try { JsonGenerator jg = jsonFactory.createGenerator(CharStreams.asWriter(sb)); jg.writeStartObject(); jg.writeStringField("message", message); jg.writeEndObject(); jg.close(); return HttpServices.createJsonResponse(sb.toString(), status); } catch (IOException f) { logger.error(f.getMessage(), f); return new DefaultFullHttpResponse(HTTP_1_1, INTERNAL_SERVER_ERROR); } }
private FullHttpResponse buildJsonResponse(@Nullable Object responseObject) { FullHttpResponse response; if (responseObject == null) { response = new DefaultFullHttpResponse(HTTP_1_1, OK); } else if (responseObject instanceof FullHttpResponse) { response = (FullHttpResponse) responseObject; } else if (responseObject instanceof String) { ByteBuf content = Unpooled.copiedBuffer(responseObject.toString(), Charsets.ISO_8859_1); response = new DefaultFullHttpResponse(HTTP_1_1, OK, content); } else { logger.warn( "unexpected type of json service response: {}", responseObject.getClass().getName()); return new DefaultFullHttpResponse(HTTP_1_1, INTERNAL_SERVER_ERROR); } response.headers().add(HttpHeaderNames.CONTENT_TYPE, MediaType.JSON_UTF_8); HttpServices.preventCaching(response); return response; }
@Override public void run() { terminate = false; logger.info("Starting echos."); EchoResourceMap echoMap = EchoResourceMap.getEchoMap(); // Get the connection details for the MQ box. String path = amqpURI.getRawPath(); String queue = path.substring(path.indexOf('/', 1) + 1); String virtualHost = uriDecode(amqpURI.getPath().substring(1, path.indexOf('/', 1))); // Prepare a simple message to send to the echo system. This message // will come back in each resource's MQ queue. StreamEcho streamEcho = new StreamEcho(); streamEcho.setHost(virtualHost); streamEcho.setQueue(queue); String guid = UUID.randomUUID().toString(); DateFormat df = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss.SSS'Z'"); df.setTimeZone(TimeZone.getTimeZone("UTC")); streamEcho.setMessage(guid + ";" + df.format(new Date())); String stringStreamEcho = JsonHelper.ToJson(streamEcho); Thread.currentThread().setName(THREAD_NAME); int sleepInterval = Integer.parseInt(SystemProperties.get("ss.echo_sender_interval")) * 1000; while (true) { try { // Send the message to the Sporting Solution's end-point. HttpServices.getHttpService() .processRequest( "http://api.sportingsolutions.com/rels/stream/batchecho", restItem, stringStreamEcho); logger.info("Batch echo sent: " + stringStreamEcho); // After the message is sent increase the number of echos sent // for all resources. // The number of missed echos is configured in: // conf/sdk.properties using "ss.echo_max_missed_echos" Set<String> defaulters = echoMap.incrAll(Integer.parseInt(SystemProperties.get("ss.echo_max_missed_echos"))); Iterator<String> keyIter = defaulters.iterator(); /* * EchoMap returns a list of resources which appear to have * unresponsive queues (the number of echo retries has been * exceeded. * * At this point we disconnect the queue consumer from the MQ * service. This triggers an action in RabbitMQ which alerts the * resource/fixture of the failure. The resource is then * responsible for communicating the problem to the client code. */ while (keyIter.hasNext()) { String resourceId = keyIter.next(); logger.warn( "Attempting to disconnect resource: " + resourceId + " due maximum number of echo retries reached"); MQListener.disconnect(resourceId); } // The interval between echos is configured in: // conf/sdk.properties using "ss.echo_sender_interval" Thread.sleep(sleepInterval); if (terminate == true) { return; } } catch (Exception ex) { logger.error("An error occured: " + ex); } } }