Search in sources :

Example 66 with HttpResponseStatus

use of io.netty.handler.codec.http.HttpResponseStatus in project java by wavefrontHQ.

the class WriteHttpJsonPortUnificationHandler method handleHttpMessage.

@Override
protected void handleHttpMessage(final ChannelHandlerContext ctx, final FullHttpRequest request) {
    HttpResponseStatus status = HttpResponseStatus.OK;
    String requestBody = request.content().toString(CharsetUtil.UTF_8);
    try {
        JsonNode metrics = jsonParser.readTree(requestBody);
        if (!metrics.isArray()) {
            logger.warning("metrics is not an array!");
            pointHandler.reject((ReportPoint) null, "[metrics] is not an array!");
            status = HttpResponseStatus.BAD_REQUEST;
            writeHttpResponse(ctx, status, "", request);
            return;
        }
        reportMetrics(metrics);
        writeHttpResponse(ctx, status, "", request);
    } catch (Exception e) {
        status = HttpResponseStatus.BAD_REQUEST;
        logWarning("WF-300: Failed to handle incoming write_http request", e, ctx);
        writeHttpResponse(ctx, status, errorMessageWithRootCause(e), request);
    }
}
Also used : HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) JsonNode(com.fasterxml.jackson.databind.JsonNode)

Example 67 with HttpResponseStatus

use of io.netty.handler.codec.http.HttpResponseStatus in project java by wavefrontHQ.

the class AbstractLineDelimitedHandler method handleHttpMessage.

/**
 * Handles an incoming HTTP message. Accepts HTTP POST on all paths
 */
@Override
protected void handleHttpMessage(final ChannelHandlerContext ctx, final FullHttpRequest request) {
    StringBuilder output = new StringBuilder();
    HttpResponseStatus status;
    try {
        DataFormat format = getFormat(request);
        Splitter.on('\n').trimResults().omitEmptyStrings().split(request.content().toString(CharsetUtil.UTF_8)).forEach(line -> processLine(ctx, line, format));
        status = HttpResponseStatus.ACCEPTED;
    } catch (Exception e) {
        status = HttpResponseStatus.BAD_REQUEST;
        output.append(errorMessageWithRootCause(e));
        logWarning("WF-300: Failed to handle HTTP POST", e, ctx);
    }
    writeHttpResponse(ctx, status, output, request);
}
Also used : HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) DataFormat(com.wavefront.agent.formatter.DataFormat)

Example 68 with HttpResponseStatus

use of io.netty.handler.codec.http.HttpResponseStatus in project java by wavefrontHQ.

the class DataDogPortUnificationHandler method reportMetrics.

/**
 * Parse the metrics JSON and report the metrics found.
 * There are 2 formats supported: array of points and single point
 *
 * @param metrics a DataDog-format payload
 * @param pointCounter counter to track the number of points processed in one request
 *
 * @return final HTTP status code to return to the client
 * @see #reportMetric(JsonNode, AtomicInteger, Consumer)
 */
private HttpResponseStatus reportMetrics(final JsonNode metrics, @Nullable final AtomicInteger pointCounter, Consumer<String> outputConsumer) {
    if (metrics == null || !metrics.isObject()) {
        error("Empty or malformed /api/v1/series payload - ignoring", outputConsumer);
        return HttpResponseStatus.BAD_REQUEST;
    }
    if (!metrics.has("series")) {
        error("/api/v1/series payload missing 'series' field", outputConsumer);
        return HttpResponseStatus.BAD_REQUEST;
    }
    JsonNode series = metrics.get("series");
    if (!series.isArray()) {
        error("'series' field must be an array", outputConsumer);
        return HttpResponseStatus.BAD_REQUEST;
    }
    HttpResponseStatus worstStatus = HttpResponseStatus.ACCEPTED;
    for (final JsonNode metric : series) {
        HttpResponseStatus latestStatus = reportMetric(metric, pointCounter, outputConsumer);
        if (latestStatus.compareTo(worstStatus) > 0) {
            worstStatus = latestStatus;
        }
    }
    return worstStatus;
}
Also used : HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) JsonNode(com.fasterxml.jackson.databind.JsonNode)

Example 69 with HttpResponseStatus

use of io.netty.handler.codec.http.HttpResponseStatus in project java by wavefrontHQ.

the class DataDogPortUnificationHandler method handleHttpMessage.

@Override
protected void handleHttpMessage(final ChannelHandlerContext ctx, final FullHttpRequest request) throws URISyntaxException {
    StringBuilder output = new StringBuilder();
    AtomicInteger pointsPerRequest = new AtomicInteger();
    URI uri = new URI(request.uri());
    HttpResponseStatus status = HttpResponseStatus.ACCEPTED;
    String requestBody = request.content().toString(CharsetUtil.UTF_8);
    if (requestRelayClient != null && requestRelayTarget != null && request.method() == POST) {
        Histogram requestRelayDuration = Metrics.newHistogram(new TaggedMetricName("listeners", "http-relay.duration-nanos", "port", handle));
        long startNanos = System.nanoTime();
        try {
            String outgoingUrl = requestRelayTarget.replaceFirst("/*$", "") + request.uri();
            HttpPost outgoingRequest = new HttpPost(outgoingUrl);
            if (request.headers().contains("Content-Type")) {
                outgoingRequest.addHeader("Content-Type", request.headers().get("Content-Type"));
            }
            outgoingRequest.setEntity(new StringEntity(requestBody));
            if (synchronousMode) {
                if (logger.isLoggable(Level.FINE)) {
                    logger.fine("Relaying incoming HTTP request to " + outgoingUrl);
                }
                HttpResponse response = requestRelayClient.execute(outgoingRequest);
                int httpStatusCode = response.getStatusLine().getStatusCode();
                httpStatusCounterCache.get(httpStatusCode).inc();
                if (httpStatusCode < 200 || httpStatusCode >= 300) {
                    // anything that is not 2xx is relayed as is to the client, don't process the payload
                    writeHttpResponse(ctx, HttpResponseStatus.valueOf(httpStatusCode), EntityUtils.toString(response.getEntity(), "UTF-8"), request);
                    return;
                }
            } else {
                threadpool.submit(() -> {
                    try {
                        if (logger.isLoggable(Level.FINE)) {
                            logger.fine("Relaying incoming HTTP request (async) to " + outgoingUrl);
                        }
                        HttpResponse response = requestRelayClient.execute(outgoingRequest);
                        int httpStatusCode = response.getStatusLine().getStatusCode();
                        httpStatusCounterCache.get(httpStatusCode).inc();
                        EntityUtils.consumeQuietly(response.getEntity());
                    } catch (IOException e) {
                        logger.warning("Unable to relay request to " + requestRelayTarget + ": " + e.getMessage());
                        Metrics.newCounter(new TaggedMetricName("listeners", "http-relay.failed", "port", handle)).inc();
                    }
                });
            }
        } catch (IOException e) {
            logger.warning("Unable to relay request to " + requestRelayTarget + ": " + e.getMessage());
            Metrics.newCounter(new TaggedMetricName("listeners", "http-relay.failed", "port", handle)).inc();
            writeHttpResponse(ctx, HttpResponseStatus.BAD_GATEWAY, "Unable to relay request: " + e.getMessage(), request);
            return;
        } finally {
            requestRelayDuration.update(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos));
        }
    }
    String path = uri.getPath().endsWith("/") ? uri.getPath() : uri.getPath() + "/";
    switch(path) {
        case "/api/v1/series/":
            try {
                status = reportMetrics(jsonParser.readTree(requestBody), pointsPerRequest, output::append);
            } catch (Exception e) {
                status = HttpResponseStatus.BAD_REQUEST;
                output.append(errorMessageWithRootCause(e));
                logWarning("WF-300: Failed to handle /api/v1/series request", e, ctx);
            }
            httpRequestSize.update(pointsPerRequest.intValue());
            writeHttpResponse(ctx, status, output, request);
            break;
        case "/api/v1/check_run/":
            if (!processServiceChecks) {
                Metrics.newCounter(new TaggedMetricName("listeners", "http-requests.ignored", "port", handle)).inc();
                writeHttpResponse(ctx, HttpResponseStatus.ACCEPTED, output, request);
                return;
            }
            try {
                reportChecks(jsonParser.readTree(requestBody), pointsPerRequest, output::append);
            } catch (Exception e) {
                status = HttpResponseStatus.BAD_REQUEST;
                output.append(errorMessageWithRootCause(e));
                logWarning("WF-300: Failed to handle /api/v1/check_run request", e, ctx);
            }
            writeHttpResponse(ctx, status, output, request);
            break;
        case "/api/v1/validate/":
            writeHttpResponse(ctx, HttpResponseStatus.OK, output, request);
            break;
        case "/intake/":
            try {
                status = processMetadataAndSystemMetrics(jsonParser.readTree(requestBody), processSystemMetrics, pointsPerRequest, output::append);
            } catch (Exception e) {
                status = HttpResponseStatus.BAD_REQUEST;
                output.append(errorMessageWithRootCause(e));
                logWarning("WF-300: Failed to handle /intake request", e, ctx);
            }
            httpRequestSize.update(pointsPerRequest.intValue());
            writeHttpResponse(ctx, status, output, request);
            break;
        default:
            writeHttpResponse(ctx, HttpResponseStatus.NO_CONTENT, output, request);
            logWarning("WF-300: Unexpected path '" + request.uri() + "', returning HTTP 204", null, ctx);
            break;
    }
}
Also used : HttpPost(org.apache.http.client.methods.HttpPost) Histogram(com.yammer.metrics.core.Histogram) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) ChannelUtils.writeHttpResponse(com.wavefront.agent.channel.ChannelUtils.writeHttpResponse) HttpResponse(org.apache.http.HttpResponse) IOException(java.io.IOException) URI(java.net.URI) TaggedMetricName(com.wavefront.common.TaggedMetricName) ReportPoint(wavefront.report.ReportPoint) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) StringEntity(org.apache.http.entity.StringEntity) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 70 with HttpResponseStatus

use of io.netty.handler.codec.http.HttpResponseStatus in project java by wavefrontHQ.

the class OpenTSDBPortUnificationHandler method handleHttpMessage.

@Override
protected void handleHttpMessage(final ChannelHandlerContext ctx, final FullHttpRequest request) throws URISyntaxException {
    StringBuilder output = new StringBuilder();
    URI uri = new URI(request.uri());
    switch(uri.getPath()) {
        case "/api/put":
            final ObjectMapper jsonTree = new ObjectMapper();
            HttpResponseStatus status;
            // had an error, the API will return a 400.
            try {
                JsonNode metrics = jsonTree.readTree(request.content().toString(CharsetUtil.UTF_8));
                if (reportMetrics(metrics, ctx)) {
                    status = HttpResponseStatus.NO_CONTENT;
                } else {
                    // TODO: improve error message
                    // http://opentsdb.net/docs/build/html/api_http/put.html#response
                    // User should understand that successful points are processed and the reason
                    // for BAD_REQUEST is due to at least one failure point.
                    status = HttpResponseStatus.BAD_REQUEST;
                    output.append("At least one data point had error.");
                }
            } catch (Exception e) {
                status = HttpResponseStatus.BAD_REQUEST;
                output.append(errorMessageWithRootCause(e));
                logWarning("WF-300: Failed to handle /api/put request", e, ctx);
            }
            writeHttpResponse(ctx, status, output, request);
            break;
        case "/api/version":
            // http://opentsdb.net/docs/build/html/api_http/version.html
            ObjectNode node = JsonNodeFactory.instance.objectNode();
            node.put("version", ResourceBundle.getBundle("build").getString("build.version"));
            writeHttpResponse(ctx, HttpResponseStatus.OK, node, request);
            break;
        default:
            writeHttpResponse(ctx, HttpResponseStatus.BAD_REQUEST, "Unsupported path", request);
            logWarning("WF-300: Unexpected path '" + request.uri() + "'", null, ctx);
            break;
    }
}
Also used : ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) JsonNode(com.fasterxml.jackson.databind.JsonNode) URI(java.net.URI) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) URISyntaxException(java.net.URISyntaxException)

Aggregations

HttpResponseStatus (io.netty.handler.codec.http.HttpResponseStatus)73 DefaultFullHttpResponse (io.netty.handler.codec.http.DefaultFullHttpResponse)17 FullHttpResponse (io.netty.handler.codec.http.FullHttpResponse)16 ByteBuf (io.netty.buffer.ByteBuf)15 HttpMethod (io.netty.handler.codec.http.HttpMethod)11 IOException (java.io.IOException)11 HttpHeaders (io.netty.handler.codec.http.HttpHeaders)10 HttpResponse (io.netty.handler.codec.http.HttpResponse)10 HttpVersion (io.netty.handler.codec.http.HttpVersion)9 URI (java.net.URI)7 Test (org.junit.Test)7 HttpHeaderNames (io.netty.handler.codec.http.HttpHeaderNames)6 URISyntaxException (java.net.URISyntaxException)6 Map (java.util.Map)6 Test (org.junit.jupiter.api.Test)6 Channel (io.netty.channel.Channel)5 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)5 HttpHeaderValues (io.netty.handler.codec.http.HttpHeaderValues)4 Duration (java.time.Duration)4 ArrayList (java.util.ArrayList)4