001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.http.tracing;
018
019/**
020 * Neutral, tracer-agnostic carrier of W3C trace-context fields ({@code traceparent} /
021 * {@code tracestate} / {@code baggage}) from a source that need not be an HTTP request.
022 *
023 * <p>
024 * {@code juneau-rest-server} has exactly one built-in carrier source &mdash; HTTP request headers,
025 * read directly by the OpenTelemetry bridge's {@code RestRequestTextMapGetter}. This interface exists
026 * so a <i>second</i> carrier source &mdash; for example a JSON-RPC/MCP request's nested
027 * {@code params._meta} object &mdash; can be read/written through the exact same shape a
028 * {@code TracerHook} bridge already knows how to consume, without that bridge (or this module)
029 * depending on the concept of MCP, JSON-RPC, or any specific wire format.
030 *
031 * <p>
032 * A single carrier instance may also be a <i>composite</i> that consults more than one underlying
033 * source with a defined precedence (for example: an explicit metadata key wins, an absent key falls
034 * back to the equivalent HTTP header). This interface makes no assumption about how many underlying
035 * sources a given implementation consults &mdash; only that {@link #get(String)} return the
036 * effective value for a key after any such precedence is applied.
037 *
038 * <p>
039 * Implementations are read/write: {@link #get(String)} and {@link #keys()} support inbound context
040 * extraction (a {@code TracerHook} bridge reading a remote parent out of the carrier);
041 * {@link #set(String, String)} supports outbound context injection (a bridge or
042 * {@code TraceContexts#inject(TracerHook, TraceContextCarrier)} writing the current trace context
043 * into the carrier for a caller to read back).
044 *
045 * <h5 class='section'>See Also:</h5><ul>
046 *    <li class='jc'>{@code org.apache.juneau.rest.server.tracing.TraceContextExtractor}
047 *    <li class='jc'>{@code org.apache.juneau.rest.server.tracing.TraceContexts}
048 *    <li class='jc'>{@code org.apache.juneau.rest.server.tracing.TracerHook}
049 *    <li class='link'><a class="doclink" href="https://www.w3.org/TR/trace-context/">W3C Trace Context</a>
050 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerObservability">Observability — Micrometer + OpenTelemetry</a>
051 * </ul>
052 *
053 * @since 10.0.0
054 */
055public interface TraceContextCarrier {
056
057   /**
058    * Returns the effective value for the given key.
059    *
060    * @param key The carrier key (e.g. {@code "traceparent"}, {@code "tracestate"}, {@code "baggage"}).
061    *    Never <jk>null</jk>.
062    * @return The value for <c>key</c>, or <jk>null</jk> if the key is absent from every underlying
063    *    source the carrier consults.
064    */
065   String get(String key);
066
067   /**
068    * Returns every key this carrier can resolve through {@link #get(String)}.
069    *
070    * <p>
071    * For a composite carrier, this is the union of the keys available across every underlying
072    * source &mdash; not just the source that happens to win precedence for any single key.
073    *
074    * @return The carrier's keys. Never <jk>null</jk>; empty if the carrier currently has no keys.
075    */
076   Iterable<String> keys();
077
078   /**
079    * Writes a value for the given key.
080    *
081    * <p>
082    * Used for outbound context injection &mdash; a {@code TracerHook} bridge rendering the current
083    * trace context into the carrier so a caller can read it back (for example, an MCP adapter
084    * copying the rendered {@code traceparent} into a JSON-RPC result's {@code _meta}).
085    *
086    * @param key The carrier key (e.g. {@code "traceparent"}, {@code "tracestate"}, {@code "baggage"}).
087    *    Never <jk>null</jk>.
088    * @param value The value to write. Never <jk>null</jk>.
089    */
090   void set(String key, String value);
091}