|
25 | 25 | import io.opentelemetry.sdk.resources.Resource; |
26 | 26 |
|
27 | 27 | import org.elasticsearch.client.Request; |
| 28 | +import org.elasticsearch.common.hash.BufferedMurmur3Hasher; |
28 | 29 | import org.elasticsearch.common.settings.SecureString; |
29 | 30 | import org.elasticsearch.common.settings.Settings; |
30 | 31 | import org.elasticsearch.common.util.concurrent.ThreadContext; |
@@ -236,6 +237,81 @@ public void testCounterMonotonicity() throws Exception { |
236 | 237 | assertThat(ObjectPath.evaluate(metrics, "up_down_counter_delta.time_series_metric"), equalTo("gauge")); |
237 | 238 | } |
238 | 239 |
|
| 240 | + public void testTsidForBulkIsSame() throws Exception { |
| 241 | + // This test is to ensure that the _tsid is the same when indexing via a bulk request or OTLP. |
| 242 | + long now = Clock.getDefault().now(); |
| 243 | + |
| 244 | + export( |
| 245 | + List.of( |
| 246 | + createDoubleGauge( |
| 247 | + TEST_RESOURCE, |
| 248 | + Attributes.builder() |
| 249 | + .put("string", "foo") |
| 250 | + .put("string_array", "foo", "bar", "baz") |
| 251 | + .put("boolean", true) |
| 252 | + .put("long", 42L) |
| 253 | + .put("double", 42.0) |
| 254 | + .put("host.ip", "127.0.0.1") |
| 255 | + .build(), |
| 256 | + "metric", |
| 257 | + 42, |
| 258 | + "By", |
| 259 | + now |
| 260 | + ) |
| 261 | + ) |
| 262 | + ); |
| 263 | + BufferedMurmur3Hasher hasher = new BufferedMurmur3Hasher(0); |
| 264 | + hasher.addString("metric"); |
| 265 | + String metricNamesHash = Long.toHexString(hasher.digestHash().hashCode()); |
| 266 | + // Index the same metric via a bulk request |
| 267 | + Request bulkRequest = new Request("POST", "metrics-generic.otel-default/_bulk?refresh"); |
| 268 | + bulkRequest.setJsonEntity( |
| 269 | + "{\"create\":{}}\n" |
| 270 | + + """ |
| 271 | + { |
| 272 | + "@timestamp": $time, |
| 273 | + "start_timestamp": $time, |
| 274 | + "data_stream": { |
| 275 | + "type": "metrics", |
| 276 | + "dataset": "generic.otel", |
| 277 | + "namespace": "default" |
| 278 | + }, |
| 279 | + "_metric_names_hash": "$metric_names_hash", |
| 280 | + "metrics": { |
| 281 | + "metric": 42.0 |
| 282 | + }, |
| 283 | + "attributes": { |
| 284 | + "string": "foo", |
| 285 | + "string_array": ["foo", "bar", "baz"], |
| 286 | + "boolean": true, |
| 287 | + "long": 42, |
| 288 | + "double": 42.0, |
| 289 | + "host.ip": "127.0.0.1" |
| 290 | + }, |
| 291 | + "resource": { |
| 292 | + "attributes": { |
| 293 | + "service.name": "elasticsearch" |
| 294 | + } |
| 295 | + }, |
| 296 | + "scope": { |
| 297 | + "name": "io.opentelemetry.example.metrics" |
| 298 | + }, |
| 299 | + "unit": "By" |
| 300 | + } |
| 301 | + """.replace("\n", "") |
| 302 | + .replace("$time", Long.toString(TimeUnit.NANOSECONDS.toMillis(now) + 1)) |
| 303 | + .replace("$metric_names_hash", metricNamesHash) |
| 304 | + + "\n" |
| 305 | + ); |
| 306 | + assertThat(ObjectPath.createFromResponse(client().performRequest(bulkRequest)).evaluate("errors"), equalTo(false)); |
| 307 | + |
| 308 | + ObjectPath searchResponse = ObjectPath.createFromResponse( |
| 309 | + client().performRequest(new Request("GET", "metrics-generic.otel-default/_search?docvalue_fields=_tsid")) |
| 310 | + ); |
| 311 | + assertThat(searchResponse.evaluate("hits.total.value"), equalTo(2)); |
| 312 | + assertThat(searchResponse.evaluate("hits.hits.0.fields._tsid"), equalTo(searchResponse.evaluate("hits.hits.1.fields._tsid"))); |
| 313 | + } |
| 314 | + |
239 | 315 | private static Map<String, Object> getMapping(String target) throws IOException { |
240 | 316 | Map<String, Object> mappings = ObjectPath.createFromResponse(client().performRequest(new Request("GET", target + "/_mapping"))) |
241 | 317 | .evaluate(""); |
|
0 commit comments