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.rest.server.tracing.otel;
018
019import static org.apache.juneau.commons.utils.Shorts.*;
020
021import org.apache.juneau.http.tracing.TraceContextCarrier;
022import org.apache.juneau.rest.server.tracing.*;
023
024import io.opentelemetry.context.propagation.*;
025
026/**
027 * {@link TextMapSetter} implementation that writes W3C trace-context fields into a neutral
028 * {@link TraceContextCarrier} instead of an HTTP response.
029 *
030 * <p>
031 * The adapter substrate for {@link OtelTracerHook#inject(TraceContextCarrier)}: the configured
032 * {@link TextMapPropagator} renders the caller's currently-active trace context (and baggage, when a
033 * baggage propagator is configured) by calling {@link #set(TraceContextCarrier, String, String)} once
034 * per key, which this class forwards to {@link TraceContextCarrier#set(String, String)}. A propagator
035 * with nothing valid to render (no active span context, empty baggage, etc.) simply never calls
036 * {@link #set(TraceContextCarrier, String, String)}, so the carrier is left untouched &mdash; the
037 * substrate for {@link TracerHook}'s documented default no-op {@code inject(...)} contract.
038 *
039 * @since 10.0.0
040 */
041@SuppressWarnings({
042   "java:S6548" // Singleton pattern is intentional; INSTANCE is a stateless, thread-safe TextMapSetter implementation.
043})
044public final class TraceContextCarrierTextMapSetter implements TextMapSetter<TraceContextCarrier> {
045
046   /** Process-wide singleton instance. */
047   public static final TraceContextCarrierTextMapSetter INSTANCE = new TraceContextCarrierTextMapSetter();
048
049   private TraceContextCarrierTextMapSetter() {}
050
051   @Override /* TextMapSetter */
052   public void set(TraceContextCarrier carrier, String key, String value) {
053      if (nn(carrier) && nn(key) && nn(value))
054         carrier.set(key, value);
055   }
056}