// Path: opentracing-jaxrs2/src/main/java/io/opentracing/contrib/jaxrs2/serialization/InterceptorSpanDecorator.java
// public interface InterceptorSpanDecorator {
// 
//     /**
//      * Decorate spans by outgoing object.
//      *
//      * @param context
//      * @param span
//      */
//     void decorateRead(InterceptorContext context, Span span);
// 
//     /**
//      * Decorate spans by outgoing object.
//      *
//      * @param context
//      * @param span
//      */
//     void decorateWrite(InterceptorContext context, Span span);
// 
//     /**
//      * Adds tags: \"media.type\", \"entity.type\"
//      */
//     InterceptorSpanDecorator STANDARD_TAGS = new InterceptorSpanDecorator() {
//         @Override
//         public void decorateRead(InterceptorContext context, Span span) {
//             span.setTag("media.type", context.getMediaType().toString());
//             span.setTag("entity.type", context.getType().getName());
//         }
// 
//         @Override
//         public void decorateWrite(InterceptorContext context, Span span) {
//             decorateRead(context, span);
//         }
//     };
// }


import io.opentracing.Tracer;
import io.opentracing.contrib.jaxrs2.serialization.InterceptorSpanDecorator;
import io.opentracing.util.GlobalTracer;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.Priorities;
import javax.ws.rs.client.Client;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
package io.opentracing.contrib.jaxrs2.client;


/**
 * @author Pavol Loffay
 */
public class ClientTracingFeature implements Feature {
    private static final Logger log = Logger.getLogger(ClientTracingFeature.class.getName());

    private Builder builder;

    /**
     * When using this constructor application has to call {@link GlobalTracer#registerIfAbsent(Tracer)} to register
     * tracer instance.
     *
     * For a custom configuration use {@link Builder#build()}.
     */
    public ClientTracingFeature() {
        this(new Builder(GlobalTracer.get()));
    }

    private ClientTracingFeature(Builder builder) {
        this.builder = builder;
    }

    @Override
    public boolean configure(FeatureContext context) {
        if (log.isLoggable(Level.FINE)) {
            log.fine("Registering client OpenTracing, with configuration:" + builder.toString());
        }
        context.register(new ClientTracingFilter(builder.tracer, builder.spanDecorators),
            builder.priority);

        if (builder.traceSerialization) {
            context.register(
                new ClientTracingInterceptor(builder.tracer, builder.serializationSpanDecorators),
                builder.serializationPriority);
        }
        return true;
    }

    /**
     * Builder for configuring {@link Client} to trace outgoing requests.
     *
     * By default get's operation name is HTTP method and get is decorated with
     * {@link ClientSpanDecorator#STANDARD_TAGS} which adds set of standard tags.
     */
    public static class Builder {
        private Tracer tracer;
        private List<ClientSpanDecorator> spanDecorators;
// Path: opentracing-jaxrs2/src/main/java/io/opentracing/contrib/jaxrs2/serialization/InterceptorSpanDecorator.java
// public interface InterceptorSpanDecorator {
// 
//     /**
//      * Decorate spans by outgoing object.
//      *
//      * @param context
//      * @param span
//      */
//     void decorateRead(InterceptorContext context, Span span);
// 
//     /**
//      * Decorate spans by outgoing object.
//      *
//      * @param context
//      * @param span
//      */
//     void decorateWrite(InterceptorContext context, Span span);
// 
//     /**
//      * Adds tags: \"media.type\", \"entity.type\"
//      */
//     InterceptorSpanDecorator STANDARD_TAGS = new InterceptorSpanDecorator() {
//         @Override
//         public void decorateRead(InterceptorContext context, Span span) {
//             span.setTag("media.type", context.getMediaType().toString());
//             span.setTag("entity.type", context.getType().getName());
//         }
// 
//         @Override
//         public void decorateWrite(InterceptorContext context, Span span) {
//             decorateRead(context, span);
//         }
//     };
// }


// Path: opentracing-jaxrs2/src/main/java/io/opentracing/contrib/jaxrs2/client/ClientTracingFeature.java
import io.opentracing.Tracer;
import io.opentracing.contrib.jaxrs2.serialization.InterceptorSpanDecorator;
import io.opentracing.util.GlobalTracer;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.Priorities;
import javax.ws.rs.client.Client;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;

package io.opentracing.contrib.jaxrs2.client;


/**
 * @author Pavol Loffay
 */
public class ClientTracingFeature implements Feature {
    private static final Logger log = Logger.getLogger(ClientTracingFeature.class.getName());

    private Builder builder;

    /**
     * When using this constructor application has to call {@link GlobalTracer#registerIfAbsent(Tracer)} to register
     * tracer instance.
     *
     * For a custom configuration use {@link Builder#build()}.
     */
    public ClientTracingFeature() {
        this(new Builder(GlobalTracer.get()));
    }

    private ClientTracingFeature(Builder builder) {
        this.builder = builder;
    }

    @Override
    public boolean configure(FeatureContext context) {
        if (log.isLoggable(Level.FINE)) {
            log.fine("Registering client OpenTracing, with configuration:" + builder.toString());
        }
        context.register(new ClientTracingFilter(builder.tracer, builder.spanDecorators),
            builder.priority);

        if (builder.traceSerialization) {
            context.register(
                new ClientTracingInterceptor(builder.tracer, builder.serializationSpanDecorators),
                builder.serializationPriority);
        }
        return true;
    }

    /**
     * Builder for configuring {@link Client} to trace outgoing requests.
     *
     * By default get's operation name is HTTP method and get is decorated with
     * {@link ClientSpanDecorator#STANDARD_TAGS} which adds set of standard tags.
     */
    public static class Builder {
        private Tracer tracer;
        private List<ClientSpanDecorator> spanDecorators;
        private List<InterceptorSpanDecorator> serializationSpanDecorators;