All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.kristofa.brave.resteasy.BravePreProcessInterceptor Maven / Gradle / Ivy

package com.github.kristofa.brave.resteasy;

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

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.jboss.resteasy.annotations.interception.ServerInterceptor;
import org.jboss.resteasy.core.ResourceMethod;
import org.jboss.resteasy.core.ServerResponse;
import org.jboss.resteasy.spi.Failure;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.interception.PreProcessInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.github.kristofa.brave.BraveHttpHeaders;
import com.github.kristofa.brave.EndPointSubmitter;
import com.github.kristofa.brave.ServerTracer;

/**
 * Rest Easy {@link PreProcessInterceptor} that will:
 * 
    *
  1. Set {@link EndPoint} information for our service in case it is not set yet.
  2. *
  3. Get trace data (trace id, span id, parent span id) from http headers and initialize state for request + submit 'server * received' for request.
  4. *
  5. If no trace information is submitted we will start a new span. In that case it means client does not support tracing * and should be adapted.
  6. *
* * @author kristof */ @Component @Provider @ServerInterceptor public class BravePreProcessInterceptor implements PreProcessInterceptor { private final static Logger LOGGER = LoggerFactory.getLogger(BravePreProcessInterceptor.class); private final EndPointSubmitter endPointSubmitter; private final ServerTracer serverTracer; @Context HttpServletRequest servletRequest; /** * Creates a new instance. * * @param endPointSubmitter {@link EndPointSubmitter}. Should not be null. * @param serverTracer {@link ServerTracer}. Should not be null. * @param randomGenerator Random generator. */ @Autowired public BravePreProcessInterceptor(final EndPointSubmitter endPointSubmitter, final ServerTracer serverTracer) { Validate.notNull(endPointSubmitter); Validate.notNull(serverTracer); this.endPointSubmitter = endPointSubmitter; this.serverTracer = serverTracer; } /** * {@inheritDoc} */ @Override public ServerResponse preProcess(final HttpRequest request, final ResourceMethod method) throws Failure, WebApplicationException { submitEndpoint(); serverTracer.clearCurrentSpan(); final TraceData traceData = getTraceData(request); if (Boolean.FALSE.equals(traceData.shouldBeTraced())) { serverTracer.setStateNoTracing(); LOGGER.debug("Received indication that we should NOT trace."); } else { String spanName = getSpanName(request, traceData); if (traceData.getTraceId() != null && traceData.getSpanId() != null) { LOGGER.debug("Received span information as part of request."); serverTracer.setStateCurrentTrace(traceData.getTraceId(), traceData.getSpanId(), traceData.getParentSpanId(), spanName); } else { LOGGER.debug("Received no span state."); serverTracer.setStateUnknown(spanName); } serverTracer.setServerReceived(); } return null; } private String getSpanName(HttpRequest request, TraceData traceData) { if (StringUtils.isNotBlank(traceData.getSpanName())) { return traceData.getSpanName(); } else { return request.getPreprocessedPath(); } } private void submitEndpoint() { if (!endPointSubmitter.endPointSubmitted()) { final String localAddr = servletRequest.getLocalAddr(); final int localPort = servletRequest.getLocalPort(); final String contextPath = servletRequest.getContextPath(); LOGGER.debug("Setting endpoint: addr: {}, port: {}, contextpath: {}", localAddr, localPort, contextPath); endPointSubmitter.submit(localAddr, localPort, contextPath); } } private TraceData getTraceData(final HttpRequest request) { final HttpHeaders httpHeaders = request.getHttpHeaders(); final MultivaluedMap requestHeaders = httpHeaders.getRequestHeaders(); final TraceData traceData = new TraceData(); for (final Entry> headerEntry : requestHeaders.entrySet()) { LOGGER.debug("{}={}", headerEntry.getKey(), headerEntry.getValue()); if (BraveHttpHeaders.TraceId.getName().equalsIgnoreCase(headerEntry.getKey())) { traceData.setTraceId(getFirstLongValueFor(headerEntry)); } else if (BraveHttpHeaders.SpanId.getName().equalsIgnoreCase(headerEntry.getKey())) { traceData.setSpanId(getFirstLongValueFor(headerEntry)); } else if (BraveHttpHeaders.ParentSpanId.getName().equalsIgnoreCase(headerEntry.getKey())) { traceData.setParentSpanId(getFirstLongValueFor(headerEntry)); } else if (BraveHttpHeaders.Sampled.getName().equalsIgnoreCase(headerEntry.getKey())) { traceData.setShouldBeSampled(getFirstBooleanValueFor(headerEntry)); } else if (BraveHttpHeaders.SpanName.getName().equalsIgnoreCase(headerEntry.getKey())) { traceData.setSpanName(getFirstStringValueFor(headerEntry)); } } return traceData; } private Long getFirstLongValueFor(final Entry> headerEntry) { final String firstStringValueFor = getFirstStringValueFor(headerEntry); return firstStringValueFor == null ? null : Long.valueOf(firstStringValueFor); } private Boolean getFirstBooleanValueFor(final Entry> headerEntry) { final String firstStringValueFor = getFirstStringValueFor(headerEntry); return firstStringValueFor == null ? null : Boolean.valueOf(firstStringValueFor); } private String getFirstStringValueFor(final Entry> headerEntry) { final List values = headerEntry.getValue(); if (values != null && values.size() > 0) { return headerEntry.getValue().get(0); } return null; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy