public static Message<?> addSpanHeaders(TraceKeys traceKeys, Message<?> message, Span span) {
    if (span == null) {
      if (!message.getHeaders().containsKey(Span.NOT_SAMPLED_NAME)) {
        return MessageBuilder.fromMessage(message).setHeader(Span.NOT_SAMPLED_NAME, "").build();
      }
      return message;
    }

    Map<String, String> headers = new HashMap<>();
    addHeader(headers, Span.TRACE_ID_NAME, Span.toHex(span.getTraceId()));
    addHeader(headers, Span.SPAN_ID_NAME, Span.toHex(span.getSpanId()));

    if (span.isExportable()) {
      addAnnotations(traceKeys, message, span);
      Long parentId = getFirst(span.getParents());
      if (parentId != null) {
        addHeader(headers, Span.PARENT_ID_NAME, Span.toHex(parentId));
      }
      addHeader(headers, Span.SPAN_NAME_NAME, span.getName());
      addHeader(headers, Span.PROCESS_ID_NAME, span.getProcessId());
    } else {
      addHeader(headers, Span.NOT_SAMPLED_NAME, "");
    }
    return MessageBuilder.fromMessage(message).copyHeaders(headers).build();
  }
  @Test
  public void when_not_sampling_header_present_span_is_not_exportable() throws Exception {
    Long expectedTraceId = new Random().nextLong();

    MvcResult mvcResult = whenSentPingWithTraceIdAndNotSampling(expectedTraceId);

    then(tracingHeaderFrom(mvcResult)).isEqualTo(expectedTraceId);
    then(span.isExportable()).isFalse();
  }
  @Test
  public void when_always_sampler_is_used_span_is_exportable() throws Exception {
    Long expectedTraceId = new Random().nextLong();

    MvcResult mvcResult = whenSentPingWithTraceId(expectedTraceId);

    then(tracingHeaderFrom(mvcResult)).isEqualTo(expectedTraceId);
    then(span.isExportable());
  }