コード例 #1
0
 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);
   }
 }
コード例 #2
0
 @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;
 }
コード例 #3
0
 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);
   }
 }
コード例 #4
0
 private FullHttpResponse handleNotAuthenticated(HttpRequest request) {
   if (httpSessionManager.getSessionId(request) != null) {
     return HttpServices.createJsonResponse("{\"timedOut\":true}", UNAUTHORIZED);
   } else {
     return new DefaultFullHttpResponse(HTTP_1_1, UNAUTHORIZED);
   }
 }
コード例 #5
0
 @Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
   if (HttpServices.shouldLogException(cause)) {
     logger.warn(cause.getMessage(), cause);
   }
   ctx.close();
 }
コード例 #6
0
 @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;
 }
コード例 #7
0
  @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;
  }
コード例 #8
0
 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);
   }
 }
コード例 #9
0
 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);
      }
    }
  }