diff --git a/src/core/IncomingDataPoint.java b/src/core/IncomingDataPoint.java index ca17f01721..df25306b99 100644 --- a/src/core/IncomingDataPoint.java +++ b/src/core/IncomingDataPoint.java @@ -136,6 +136,11 @@ public final String getTSUID() { return tsuid; } + /** @param moretags the hashmap of kv pair to add */ + public final void addTags(HashMap moretags) { + this.tags.putAll(moretags); + } + /** @param metric the metric to set */ public final void setMetric(String metric) { this.metric = metric; diff --git a/src/tsd/AbstractHttpQuery.java b/src/tsd/AbstractHttpQuery.java index d7ccc54775..388127e9d6 100644 --- a/src/tsd/AbstractHttpQuery.java +++ b/src/tsd/AbstractHttpQuery.java @@ -167,6 +167,16 @@ public Map getHeaders() { return headers; } + /** + * Return the value of the given HTTP Header + * first match wins + * @return Header value as string + */ + public String getHeaderValue(final String headerName) { + if (headerName == null) { return null; } + return request.headers().get(headerName); + } + /** @param stats The stats object to mark after writing is complete */ public void setStats(final QueryStats stats) { this.stats = stats; diff --git a/src/tsd/PutDataPointRpc.java b/src/tsd/PutDataPointRpc.java index 29e77f34e6..ec2a8093cf 100644 --- a/src/tsd/PutDataPointRpc.java +++ b/src/tsd/PutDataPointRpc.java @@ -312,6 +312,7 @@ public void processDataPoint(final TSDB tsdb, throw new BadRequestException("No datapoints found in content"); } + final HashMap query_tags = new HashMap(); final boolean show_details = query.hasQueryStringParam("details"); final boolean show_summary = query.hasQueryStringParam("summary"); final boolean synchronous = query.hasQueryStringParam("sync"); @@ -326,7 +327,18 @@ public void processDataPoint(final TSDB tsdb, int queued = 0; final List> deferreds = synchronous ? new ArrayList>(dps.size()) : null; - + + if (tsdb.getConfig().enable_header_tag()) { + LOG.debug("Looking for tag header " + tsdb.getConfig().get_name_header_tag()); + final String header_tag_value = query.getHeaderValue(tsdb.getConfig().get_name_header_tag()) ; + if (header_tag_value != null) { + LOG.debug(" header found with value:" + header_tag_value); + Tags.parse(query_tags, header_tag_value); + } else { + LOG.debug(" no such header in request"); + } + } + for (final IncomingDataPoint dp : dps) { final DataPointType type; if (dp instanceof RollUpDataPoint) { @@ -387,10 +399,16 @@ public Boolean call(final Object obj) { } try { + /** Add additionnal tags from HTTP header */ + if ( (query_tags != null) && (query_tags.size() > 0) ) { + dp.addTags(query_tags); + } + if (!dp.validate(details)) { illegal_arguments.incrementAndGet(); continue; } + // TODO - refactor the add calls someday or move some of this into the // actual data point class. final Deferred deferred; diff --git a/src/utils/Config.java b/src/utils/Config.java index 0e791e8968..f92f2f5b56 100644 --- a/src/utils/Config.java +++ b/src/utils/Config.java @@ -97,6 +97,9 @@ public class Config { /** tsd.storage.fix_duplicates */ private boolean fix_duplicates = false; + /** tsd.http.header_tag */ + private String http_header_tag = null; + /** tsd.http.request.max_chunk */ private int max_chunked_requests = 4096; @@ -253,6 +256,16 @@ public int scanner_maxNumRows() { return scanner_max_num_rows; } + /** @return whether or not additional http header tag is allowed */ + public boolean enable_header_tag() { + return http_header_tag != null ; + } + + /** @return the lookup value for additional http header tag */ + public String get_name_header_tag() { + return http_header_tag ; + } + /** @return whether or not chunked requests are supported */ public boolean enable_chunked_requests() { return enable_chunked_requests; @@ -597,6 +610,7 @@ protected void setDefaults() { default_map.put("tsd.core.stats_with_port", "false"); default_map.put("tsd.http.show_stack_trace", "true"); default_map.put("tsd.http.query.allow_delete", "false"); + default_map.put("tsd.http.header_tag", ""); default_map.put("tsd.http.request.enable_chunked", "false"); default_map.put("tsd.http.request.max_chunk", "4096"); default_map.put("tsd.http.request.cors_domains", ""); @@ -717,6 +731,9 @@ public void loadStaticVariables() { if (this.hasProperty("tsd.http.request.max_chunk")) { max_chunked_requests = this.getInt("tsd.http.request.max_chunk"); } + if (this.hasProperty("tsd.http.header_tag")) { + http_header_tag = this.getString("tsd.http.header_tag"); + } enable_tree_processing = this.getBoolean("tsd.core.tree.enable_processing"); fix_duplicates = this.getBoolean("tsd.storage.fix_duplicates"); scanner_max_num_rows = this.getInt("tsd.storage.hbase.scanner.maxNumRows");