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);
}
}
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);
}
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;
}
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;
}
}
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;
}
}
Aggregations