Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion jooby/src/main/java/io/jooby/internal/HeadersValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected Map<String, Value> hash() {
@Override
public Map<String, String> toMap() {
Map<String, String> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
toMultimap().forEach((k, v) -> map.put(k, v.get(0)));
toMultimap().forEach((k, v) -> map.put(k, v.getFirst()));
return map;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import static io.opentelemetry.context.Context.current;

import java.util.Iterator;

import org.jspecify.annotations.NonNull;

import io.jooby.opentelemetry.OtelContextExtractor;
Expand Down Expand Up @@ -52,8 +54,14 @@ public Iterable<String> keys(io.jooby.Context ctx) {

@Override
public String get(io.jooby.Context ctx, String key) {
var value = ctx.header(key).toList();
// Safely extract the header value, returning null if it doesn't exist
return ctx.header(key).valueOrNull();
return value.isEmpty() ? null : value.getFirst();
}

@Override
public Iterator<String> getAll(io.jooby.Context ctx, String key) {
return ctx.header(key).toList().iterator();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

import java.util.List;
import java.util.Map;
import java.util.Set;

Expand Down Expand Up @@ -108,8 +109,8 @@ void joobyRequestGetterShouldReturnHeaderKeys() {
void joobyRequestGetterShouldReturnHeaderValueOrNull() {
// Arrange
Value mockHeaderValue = mock(Value.class);
when(mockHeaderValue.valueOrNull())
.thenReturn("00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01");
when(mockHeaderValue.toList())
.thenReturn(List.of("00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"));
when(joobyCtx.header("traceparent")).thenReturn(mockHeaderValue);

// Act
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Jooby https://jooby.io
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
* Copyright 2014 Edgar Espina
*/
package io.jooby.internal.opentelemetry;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Test;

import io.jooby.Context;
import io.jooby.value.Value;
import io.jooby.value.ValueFactory;

class DefaultOtelContextHeadersExtractorTest {

@Test
void shouldExtractKeys() {
var ctx = mock(io.jooby.Context.class);
when(ctx.headerMap())
.thenReturn(
Map.of("traceparent", "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"));
var headers = DefaultOtelContextExtractor.Headers.INSTANCE;
headers.keys(ctx);
}

@Test
void shouldExtractHeaderValue() {
var ctx = mock(io.jooby.Context.class);
var headerValue = mock(io.jooby.value.Value.class);
when(headerValue.toList())
.thenReturn(java.util.List.of("00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"));
when(ctx.header("traceparent")).thenReturn(headerValue);
var headers = DefaultOtelContextExtractor.Headers.INSTANCE;
headers.get(ctx, "traceparent");
}

@Test
void shouldExtractHeaderRealSingleValue() {
var ctx = mock(io.jooby.Context.class);
var firstValue = "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01";
var headerValue = Value.value(new ValueFactory(), "traceparent", firstValue);
when(ctx.header("traceparent")).thenReturn(headerValue);
var headers = DefaultOtelContextExtractor.Headers.INSTANCE;
assertEquals(firstValue, headers.get(ctx, "traceparent"));
}

@Test
void shouldExtractHeaderRealListValue() {
var ctx = mock(io.jooby.Context.class);
var firstValue = "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01";
var secondValue = "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-02";
var headerValue =
Value.array(new ValueFactory(), "traceparent", List.of(firstValue, secondValue));
when(ctx.header("traceparent")).thenReturn(headerValue);
var headers = DefaultOtelContextExtractor.Headers.INSTANCE;
assertEquals(firstValue, headers.get(ctx, "traceparent"));
}

@Test
void shouldExtractHeaderRealEmptyValue() {
var ctx = mock(io.jooby.Context.class);
var headerValue = Value.missing(new ValueFactory(), "traceparent");
when(ctx.header("traceparent")).thenReturn(headerValue);
var headers = DefaultOtelContextExtractor.Headers.INSTANCE;
assertEquals(null, headers.get(ctx, "traceparent"));
}

@Test
void shouldExtractHeaderAllValue() {
var ctx = mock(Context.class);
var headerValue = mock(Value.class);
var values = List.of("00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01");
when(headerValue.toList()).thenReturn(values);
when(ctx.header("traceparent")).thenReturn(headerValue);
var headers = DefaultOtelContextExtractor.Headers.INSTANCE;
assertThat(headers.getAll(ctx, "traceparent")).toIterable().containsExactlyElementsOf(values);
}
}
Loading