<|start_filename|>binding/servlet/src/test/java/io/tracee/binding/servlet/TraceeSessionListenerTest.java<|end_filename|>
package io.tracee.binding.servlet;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.configuration.TraceeFilterConfiguration;
import io.tracee.testhelper.FieldAccessUtil;
import org.hamcrest.MatcherAssert;
import org.junit.Before;
import org.junit.Test;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;

import static io.tracee.TraceeConstants.SESSION_ID_KEY;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.internal.verification.VerificationModeFactory.atLeastOnce;

public class TraceeSessionListenerTest {

	private final TraceeBackend backend = mock(TraceeBackend.class);
	private final HttpSession session = mock(HttpSession.class);
	private final TraceeFilterConfiguration configuration = mock(TraceeFilterConfiguration.class);
	private final TraceeSessionListener unit = new TraceeSessionListener(backend);

	@Before
	public void setUpMocks() {
		when(backend.getConfiguration()).thenReturn(configuration);
		when(session.getId()).thenReturn("A_SESSION_ID");
	}

	@Test
	public void testWriteSessionIdToContextOnCreateIfConfigured() {
		when(configuration.shouldGenerateSessionId()).thenReturn(true);
		unit.sessionCreated(new HttpSessionEvent(session));
		verify(backend, atLeastOnce()).put(eq(SESSION_ID_KEY), anyString());
	}

	@Test
	public void testDontWriteSessionIdToContextOnCreateIfNotConfigured() {
		when(configuration.shouldGenerateSessionId()).thenReturn(false);
		unit.sessionCreated(new HttpSessionEvent(session));
		verify(backend, never()).put(eq(SESSION_ID_KEY), anyString());
	}

	@Test
	public void cleanupSessionOnDestroy() {
		unit.sessionDestroyed(mock(HttpSessionEvent.class));
		verify(backend).remove(SESSION_ID_KEY);
	}

	@Test
	public void defaultConstructorUsesTraceeBackend() {
		final TraceeSessionListener listener = new TraceeSessionListener();
		MatcherAssert.assertThat((TraceeBackend) FieldAccessUtil.getFieldVal(listener, "backend"), is(Tracee.getBackend()));
	}
}


<|start_filename|>backend/threadlocal-store/src/test/java/io/tracee/backend/threadlocalstore/ThreadLocalMapTest.java<|end_filename|>
package io.tracee.backend.threadlocalstore;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertThat;

public class ThreadLocalMapTest {

	@Test
	public void initialValueShouldCreateEmptyMap() {
		Map<String, String> map = new ThreadLocalMap<String, String>().initialValue();
		assertThat(map, is(instanceOf(Map.class)));
		assertThat(map.size(), is(0));
	}

	@Test
	public void shouldCreateChildWithNull() {
		assertThat(new ThreadLocalMap<String, String>().childValue(null), is(nullValue()));
	}

	@Test
	public void shouldCreateChildWithCopyOfHashMap() {
		final Map<String, String> map = new HashMap<>();
		map.put("A", "vA");
		final Map<String, String> childValueMap = new ThreadLocalMap<String, String>().childValue(map);
		assertThat(childValueMap, equalTo(map));
		assertThat(childValueMap, is(not(sameInstance(map))));
	}
}


<|start_filename|>binding/springmvc/src/test/java/io/tracee/binding/springmvc/TraceeInterceptorTest.java<|end_filename|>
package io.tracee.binding.springmvc;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.configuration.TraceeFilterConfiguration;
import io.tracee.testhelper.EmptyEnumeration;
import io.tracee.testhelper.FieldAccessUtil;
import io.tracee.testhelper.PermitAllTraceeFilterConfiguration;
import io.tracee.transport.HttpHeaderTransport;
import org.hamcrest.MatcherAssert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import static io.tracee.TraceeConstants.INVOCATION_ID_KEY;
import static java.util.Collections.singletonList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.contains;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class TraceeInterceptorTest {

	private final HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
	private final HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
	private final HttpSession httpServletSession = mock(HttpSession.class);
	private TraceeInterceptor unit;
	private TraceeBackend mockedBackend;

	@Before
	public void beforeTest() {
		mockedBackend = mockedBackend(new PermitAllTraceeFilterConfiguration());
		unit = new TraceeInterceptor(mockedBackend);
		when(httpServletRequest.getHeaders(TraceeConstants.TPIC_HEADER)).thenReturn(EmptyEnumeration.<String>emptyEnumeration());
	}

	@Test
	public void shouldSetInvocationIdToBackend() throws Exception {
		unit.preHandle(httpServletRequest, httpServletResponse, new Object());
		verify(mockedBackend).put(eq(INVOCATION_ID_KEY), anyString());
	}

	@Test
	public void shouldSetSessionIdToBackendHttpSessionExist() throws Exception {
		when(httpServletRequest.getSession(anyBoolean())).thenReturn(httpServletSession);
		when(httpServletSession.getId()).thenReturn(anyString());
		unit.preHandle(httpServletRequest, httpServletResponse, new Object());
		verify(mockedBackend).put(eq(TraceeConstants.SESSION_ID_KEY), anyString());
	}

	@Test
	public void shouldNotOverrideExistingInvocationId() throws Exception {
		when(mockedBackend.containsKey(eq(INVOCATION_ID_KEY))).thenReturn(true);
		unit.preHandle(httpServletRequest, httpServletResponse, new Object());
		verify(mockedBackend, never()).put(eq(INVOCATION_ID_KEY), anyString());
	}

	@Test
	public void shouldNotOverrideExistingSessionId() throws Exception {
		when(mockedBackend.containsKey(eq(TraceeConstants.SESSION_ID_KEY))).thenReturn(true);
		unit.preHandle(httpServletRequest, httpServletResponse, new Object());
		verify(mockedBackend, never()).put(eq(TraceeConstants.SESSION_ID_KEY), anyString());
	}

	@Test
	public void shouldWriteInitTpicToResponse() {
		final HashMap<String, String> parsedInitValues = new HashMap<>();
		parsedInitValues.put(INVOCATION_ID_KEY, "myGreatId321");
		when(mockedBackend.copyToMap()).thenReturn(parsedInitValues);

		when(httpServletResponse.isCommitted()).thenReturn(false);
		unit.preHandle(httpServletRequest, httpServletResponse, new Object());
		verify(httpServletResponse).setHeader(eq(TraceeConstants.TPIC_HEADER), contains(INVOCATION_ID_KEY + "=myGreatId321"));
	}

	@Test
	public void doNotWriteHeadersToResponseIfResponseIsCommited() {
		final HashMap<String, String> parsedInitValues = new HashMap<>();
		parsedInitValues.put(INVOCATION_ID_KEY, "myGreatId321");
		when(mockedBackend.copyToMap()).thenReturn(parsedInitValues);

		when(httpServletResponse.isCommitted()).thenReturn(true);
		unit.afterCompletion(httpServletRequest, httpServletResponse, new Object(), null);
		verify(httpServletResponse, times(0)).setHeader(eq(TraceeConstants.TPIC_HEADER), Mockito.anyString());
	}

	@Test
	public void initialTpicHeaderShouldBeReplacedAtTheEndIfResponseIsNotCommited() {
		final HashMap<String, String> parsedInitValues = new HashMap<>();
		parsedInitValues.put(INVOCATION_ID_KEY, "myGreatId321");
		when(mockedBackend.copyToMap()).thenReturn(parsedInitValues);
		when(httpServletResponse.isCommitted()).thenReturn(false);

		unit.preHandle(httpServletRequest, httpServletResponse, new Object());

		parsedInitValues.put(INVOCATION_ID_KEY, "myNewId45");
		unit.afterCompletion(httpServletRequest, httpServletResponse, new Object(), null);
		verify(httpServletResponse, times(1)).setHeader(eq(TraceeConstants.TPIC_HEADER), contains(INVOCATION_ID_KEY + "=myNewId45"));
		verify(httpServletResponse, times(2)).setHeader(eq(TraceeConstants.TPIC_HEADER), Mockito.anyString());
	}

	@Test
	public void shouldNotRenderContextInResponseIfConfigurationDeniesIt() throws Exception {
		final TraceeFilterConfiguration customFilterConfiguration = mock(TraceeFilterConfiguration.class);
		when(customFilterConfiguration.shouldProcessContext(TraceeFilterConfiguration.Channel.OutgoingResponse)).thenReturn(false);
		final TraceeBackend customBackend = mockedBackend(customFilterConfiguration);
		final TraceeInterceptor customUnit = new TraceeInterceptor(customBackend);
		mockedBackend.put(INVOCATION_ID_KEY, "123");
		customUnit.postHandle(httpServletRequest, httpServletResponse, new Object(), new ModelAndView());
		verify(httpServletResponse, never()).setHeader(eq(TraceeConstants.TPIC_HEADER), anyString());
	}

	@Test
	public void shouldRenderContextInResponseIfConfigured() throws Exception {
		mockedBackend.put(INVOCATION_ID_KEY, "123");
		unit.afterCompletion(httpServletRequest, httpServletResponse, new Object(), null);
		verify(httpServletResponse).setHeader(eq(TraceeConstants.TPIC_HEADER), anyString());
	}

	@Test
	public void shouldUseCustomHeaderInResponse() throws Exception {
		final String testHeader = "testHeader";
		unit.setOutgoingHeaderName(testHeader);
		unit.afterCompletion(httpServletRequest, httpServletResponse, new Object(), null);
		verify(httpServletResponse).setHeader(eq(testHeader), anyString());
	}

	@Test
	public void shouldUseConfiguredProfile() throws Exception {
		unit.setProfileName("FOO");
		unit.afterCompletion(httpServletRequest, httpServletResponse, new Object(), null);
		verify(mockedBackend).getConfiguration("FOO");
		assertThat(unit.getProfileName(), is("FOO"));
	}

	@Test
	public void shouldMergeIncomingContextIfConfigured() throws Exception {
		final Map<String, String> expected = new HashMap<>();
		expected.put("testkey", "testValue123");
		final Enumeration<String> header = createHeader("testkey", "testValue123");
		when(httpServletRequest.getHeaders(TraceeConstants.TPIC_HEADER)).thenReturn(header);
		unit.preHandle(httpServletRequest, httpServletResponse, new Object());
		verify(mockedBackend).putAll(eq(expected));
	}

	@Test
	public void shouldMergeIncomingContextFromCustomHeader() throws Exception {
		final String incomingHeader = "myHeader";
		unit.setIncomingHeaderName(incomingHeader);

		final Map<String, String> expected = new HashMap<>();
		expected.put("testkey", "testValue123");

		final Enumeration<String> headers = Collections.enumeration(singletonList("testkey=testValue123"));
		when(httpServletRequest.getHeaders(incomingHeader)).thenReturn(headers);
		unit.preHandle(httpServletRequest, httpServletResponse, new Object());
		verify(mockedBackend).putAll(eq(expected));
	}

	@Test
	public void shouldCleanupAfterProcessing() throws Exception {
		unit.afterCompletion(httpServletRequest, httpServletResponse, new Object(), null);
		verify(mockedBackend).clear();
	}

	@Test
	public void defaultConstructorUsesTraceeBackend() {
		final TraceeInterceptor interceptor = new TraceeInterceptor();
		MatcherAssert.assertThat((TraceeBackend) FieldAccessUtil.getFieldVal(interceptor, "backend"), is(Tracee.getBackend()));
	}

	private Enumeration<String> createHeader(String key, String value) {
		final Map<String, String> map = new HashMap<>();
		map.put(key, value);
		final String httpHeaderValue = new HttpHeaderTransport().render(map);
		return new Vector<>(Collections.singletonList(httpHeaderValue)).elements();
	}

	private TraceeBackend mockedBackend(TraceeFilterConfiguration filterConfiguration) {
		final TraceeBackend backend = mock(TraceeBackend.class);
		when(backend.getConfiguration()).thenReturn(filterConfiguration);
		when(backend.getConfiguration(anyString())).thenReturn(filterConfiguration);
		return backend;
	}
}


<|start_filename|>core/src/main/java/io/tracee/configuration/TraceePropertiesFileLoader.java<|end_filename|>
package io.tracee.configuration;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Properties;

public final class TraceePropertiesFileLoader {

	public static final String TRACEE_PROPERTIES_FILE = "META-INF/tracee.properties";
	public static final String TRACEE_DEFAULT_PROPERTIES_FILE = "META-INF/tracee.default.properties";

	public Properties loadTraceeProperties(String traceePropertiesFile) throws IOException {
		final Properties propertiesFromFile = new Properties();
		final ClassLoader loader = Thread.currentThread().getContextClassLoader();
		final Enumeration<URL> traceePropertyFiles = loader.getResources(traceePropertiesFile);

		while (traceePropertyFiles.hasMoreElements()) {
			final URL url = traceePropertyFiles.nextElement();
			try (InputStream stream = url.openStream()) {
				propertiesFromFile.load(stream);
			}
		}

		return propertiesFromFile;
	}
}


<|start_filename|>testhelper/src/main/java/io/tracee/testhelper/FieldAccessUtil.java<|end_filename|>
package io.tracee.testhelper;

import java.lang.reflect.Field;

public final class FieldAccessUtil {

	private FieldAccessUtil() {
	}

	public static <T> T getFieldVal(final Object obj, String fieldName) {
		final Class<?> objClass = obj.getClass();
		return getFieldVal(obj, objClass, fieldName);
	}

	@SuppressWarnings("unchecked")
	private static <T> T getFieldVal(Object obj, Class<?> objClass, String fieldName) {
		Field field = null;
		try {
			field = objClass.getDeclaredField(fieldName);
			field.setAccessible(true);
			return (T) (field.get(obj));
		} catch (NoSuchFieldException e) {
			if (objClass.getSuperclass() != null)
				return (T) getFieldVal(obj, objClass.getSuperclass(), fieldName);
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		} finally {
			if (field != null) {
				field.setAccessible(false);
			}
		}
	}
}


<|start_filename|>binding/cxf/src/test/java/io/tracee/binding/cxf/interceptor/IncomingRequestMessageTest.java<|end_filename|>
package io.tracee.binding.cxf.interceptor;

import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.testhelper.SimpleTraceeBackend;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageImpl;
import org.junit.Before;
import org.junit.Test;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

public class IncomingRequestMessageTest {

	private static final TraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();

	private TraceeRequestInInterceptor unit = new TraceeRequestInInterceptor(backend);

	private final MessageImpl message = spy(new MessageImpl());

	@Before
	public void onSetup() throws Exception {
		backend.clear();

		when(message.getExchange()).thenReturn(mock(Exchange.class));
		when(message.getExchange().get(eq(Message.REST_MESSAGE))).thenReturn(Boolean.TRUE);
	}

	@Test
	public void shouldHandleMessageWithoutHeader() {
		unit.handleMessage(message);
	}

	@Test
	public void shouldHandleMessageWithoutTraceeHeader() {
		final Map<String, List<String>> headers = new HashMap<>();
		final String context = "myContext";
		headers.put(TraceeConstants.TPIC_HEADER, Collections.singletonList(context));
		message.put(Message.PROTOCOL_HEADERS, headers);
		unit.handleMessage(message);
		assertThat(backend.copyToMap(), hasKey(TraceeConstants.INVOCATION_ID_KEY));
	}

	@Test
	public void generateInvocationIdUponRequest() {
		unit.handleMessage(message);
		assertThat(backend.copyToMap(), hasKey(TraceeConstants.INVOCATION_ID_KEY));
	}

	@Test
	public void onIncomingRequestMessagesIamNotTheRequestor() {
		when(message.get(eq(Message.REQUESTOR_ROLE))).thenReturn(Boolean.FALSE);
		assertThat(unit.shouldHandleMessage(message), is(true));
	}
}


<|start_filename|>binding/cxf/src/test/java/io/tracee/binding/cxf/interceptor/OutgoingRequestMessageTest.java<|end_filename|>
package io.tracee.binding.cxf.interceptor;

import io.tracee.TraceeBackend;
import io.tracee.testhelper.SimpleTraceeBackend;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageImpl;
import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

public class OutgoingRequestMessageTest {

	private static final TraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();

	private TraceeRequestOutInterceptor unit = new TraceeRequestOutInterceptor(backend);

	private final MessageImpl message = spy(new MessageImpl());

	@Before
	public void before() {
		backend.clear();
	}

	@Test
	public void onOutgoingRequestMessagesIamTheRequestor() {
		when(message.get(eq(Message.REQUESTOR_ROLE))).thenReturn(Boolean.TRUE);
		assertThat(unit.shouldHandleMessage(message), is(true));
	}


}


<|start_filename|>core/src/main/java/io/tracee/BackendBase.java<|end_filename|>
package io.tracee;

import io.tracee.configuration.PropertiesBasedTraceeFilterConfiguration;
import io.tracee.configuration.PropertyChain;
import io.tracee.configuration.TraceeFilterConfiguration;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static io.tracee.configuration.TraceeFilterConfiguration.Profile;


public abstract class BackendBase implements TraceeBackend {

	// Use #getPropertyChain to retrieve/get the chain
	private PropertyChain _lazyPropertyChain = null;

	private Map<String, TraceeFilterConfiguration> configurationCache = new ConcurrentHashMap<>();

	/**
	 * Lazily initializes the configuration for this MDCLikeTraceeBackend.
	 */
	@Override
	public final TraceeFilterConfiguration getConfiguration() {
		return getConfiguration(null);
	}

	@Override
	public final TraceeFilterConfiguration getConfiguration(String profileName) {
		final String lookupProfile = profileName == null ? Profile.DEFAULT : profileName;

		TraceeFilterConfiguration filterConfiguration = configurationCache.get(lookupProfile);
		if (filterConfiguration == null) {
			filterConfiguration = new PropertiesBasedTraceeFilterConfiguration(getPropertyChain(), lookupProfile);
			configurationCache.put(lookupProfile, filterConfiguration);
		}
		return filterConfiguration;
	}

	private PropertyChain getPropertyChain() {
		if (_lazyPropertyChain == null) {
			_lazyPropertyChain = PropertiesBasedTraceeFilterConfiguration.loadPropertyChain();
		}
		return _lazyPropertyChain;
	}

	@Override
	public String getInvocationId() {
		return get(TraceeConstants.INVOCATION_ID_KEY);
	}

	@Override
	public String getSessionId() {
		return get(TraceeConstants.SESSION_ID_KEY);
	}

}


<|start_filename|>binding/jms/src/main/java/io/tracee/binding/jms/TraceeMessageProducer.java<|end_filename|>
package io.tracee.binding.jms;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.transport.HttpHeaderTransport;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import java.util.Map;

import static io.tracee.configuration.TraceeFilterConfiguration.Channel.AsyncDispatch;

public class TraceeMessageProducer implements MessageProducer {

	private final MessageProducer delegate;
	private final TraceeBackend backend;
	private final HttpHeaderTransport httpHeaderSerialization;

	TraceeMessageProducer(MessageProducer delegate, TraceeBackend backend) {
		this.delegate = delegate;
		this.backend = backend;
		this.httpHeaderSerialization = new HttpHeaderTransport();
	}

	public TraceeMessageProducer(MessageProducer delegate) {
		this.delegate = delegate;
		this.backend = Tracee.getBackend();
		this.httpHeaderSerialization = new HttpHeaderTransport();
	}

	/**
	 * Writes the current TraceeContext to the given javaee message.
	 * This method is idempotent.
	 */
	protected void writeTraceeContextToMessage(Message message) throws JMSException {

		if (!backend.isEmpty() && backend.getConfiguration().shouldProcessContext(AsyncDispatch)) {
			final Map<String, String> filteredContext = backend.getConfiguration().filterDeniedParams(backend.copyToMap(), AsyncDispatch);
			final String contextAsString = httpHeaderSerialization.render(filteredContext);

			message.setStringProperty(TraceeConstants.TPIC_HEADER, contextAsString);
		}
	}

	@Override
	public void send(Message message) throws JMSException {
		writeTraceeContextToMessage(message);
		delegate.send(message);
	}

	@Override
	public void send(Message message, int deliveryMode, int priority, long timeToLive) throws JMSException {
		writeTraceeContextToMessage(message);
		delegate.send(message, deliveryMode, priority, timeToLive);
	}

	@Override
	public void send(Destination destination, Message message) throws JMSException {
		writeTraceeContextToMessage(message);
		delegate.send(destination, message);
	}

	@Override
	public void send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException {
		writeTraceeContextToMessage(message);
		delegate.send(destination, message, deliveryMode, priority, timeToLive);
	}

	@Override
	public void setDisableMessageID(boolean value) throws JMSException {
		delegate.setDisableMessageID(value);
	}

	@Override
	public boolean getDisableMessageID() throws JMSException {
		return delegate.getDisableMessageID();
	}

	@Override
	public void setDisableMessageTimestamp(boolean value) throws JMSException {
		delegate.setDisableMessageTimestamp(value);
	}

	@Override
	public boolean getDisableMessageTimestamp() throws JMSException {
		return delegate.getDisableMessageTimestamp();
	}

	@Override
	public void setDeliveryMode(int deliveryMode) throws JMSException {
		delegate.setDeliveryMode(deliveryMode);
	}

	@Override
	public int getDeliveryMode() throws JMSException {
		return delegate.getDeliveryMode();
	}

	@Override
	public void setPriority(int defaultPriority) throws JMSException {
		delegate.setPriority(defaultPriority);
	}

	@Override
	public int getPriority() throws JMSException {
		return delegate.getPriority();
	}

	@Override
	public void setTimeToLive(long timeToLive) throws JMSException {
		delegate.setTimeToLive(timeToLive);
	}

	@Override
	public long getTimeToLive() throws JMSException {
		return delegate.getTimeToLive();
	}

	@Override
	public Destination getDestination() throws JMSException {
		return delegate.getDestination();
	}

	@Override
	public void close() throws JMSException {
		delegate.close();
	}

}


<|start_filename|>binding/cxf/src/main/java/io/tracee/binding/cxf/TraceeCxfFeature.java<|end_filename|>
package io.tracee.binding.cxf;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.binding.cxf.interceptor.TraceeRequestInInterceptor;
import io.tracee.binding.cxf.interceptor.TraceeRequestOutInterceptor;
import io.tracee.binding.cxf.interceptor.TraceeResponseInInterceptor;
import io.tracee.binding.cxf.interceptor.TraceeResponseOutInterceptor;
import io.tracee.configuration.TraceeFilterConfiguration.Profile;
import org.apache.cxf.Bus;
import org.apache.cxf.feature.AbstractFeature;
import org.apache.cxf.interceptor.InterceptorProvider;

public class TraceeCxfFeature extends AbstractFeature {

	private String profile;
	private TraceeBackend backend;

	public TraceeCxfFeature() {
		this(Tracee.getBackend(), Profile.DEFAULT);
	}

	TraceeCxfFeature(TraceeBackend backend, String profile) {
		this.backend = backend;
		this.profile = profile;
	}

	public TraceeCxfFeature(String profile) {
		this(Tracee.getBackend(), profile);
	}

	@Override
	protected void initializeProvider(InterceptorProvider provider, Bus bus) {
		final TraceeRequestInInterceptor requestInInterceptor = new TraceeRequestInInterceptor(backend, profile);
		final TraceeResponseInInterceptor responseInInterceptor = new TraceeResponseInInterceptor(backend, profile);
		final TraceeRequestOutInterceptor requestOutInterceptor = new TraceeRequestOutInterceptor(backend, profile);
		final TraceeResponseOutInterceptor responseOutInterceptor = new TraceeResponseOutInterceptor(backend, profile);

		provider.getInInterceptors().add(requestInInterceptor);
		provider.getInInterceptors().add(responseInInterceptor);

		provider.getOutInterceptors().add(requestOutInterceptor);
		provider.getOutInterceptors().add(responseOutInterceptor);

		provider.getOutFaultInterceptors().add(responseOutInterceptor);
		provider.getInFaultInterceptors().add(requestInInterceptor);
	}
}


<|start_filename|>binding/httpcomponents5/src/test/java/io/tracee/binding/httpcomponents/TraceeHttpRequestInterceptorTest.java<|end_filename|>
package io.tracee.binding.httpcomponents;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.configuration.TraceeFilterConfiguration;
import io.tracee.testhelper.FieldAccessUtil;
import io.tracee.testhelper.SimpleTraceeBackend;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.message.BasicHttpRequest;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mock;

public class TraceeHttpRequestInterceptorTest {

	private final SimpleTraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();
	private final TraceeHttpRequestInterceptor unit = new TraceeHttpRequestInterceptor(backend, null);

	@Test
	public void testRequestInterceptorWritesTraceeContextToRequestHeader() throws Exception {
		final HttpRequest httpRequest = new BasicHttpRequest("GET", "http://localhost/pew");

		backend.put("foo", "bar");

		unit.process(httpRequest, mock(HttpContext.class));

		assertThat("HttpRequest contains TracEE Context Header", httpRequest.containsHeader(TraceeConstants.TPIC_HEADER), equalTo(true));
		assertThat(httpRequest.getFirstHeader(TraceeConstants.TPIC_HEADER).getValue(), equalTo("foo=bar"));
	}

	@Test
	public void defaultConstructorUsesDefaultProfile() {
		final TraceeHttpRequestInterceptor interceptor = new TraceeHttpRequestInterceptor();
		assertThat((String) FieldAccessUtil.getFieldVal(interceptor, "profile"), is(TraceeFilterConfiguration.Profile.DEFAULT));
	}

	@Test
	public void defaultConstructorUsesTraceeBackend() {
		final TraceeHttpRequestInterceptor interceptor = new TraceeHttpRequestInterceptor();
		assertThat((TraceeBackend) FieldAccessUtil.getFieldVal(interceptor, "backend"), is(Tracee.getBackend()));
	}

	@Test
	public void constructorStoresProfileNameInternal() {
		final TraceeHttpRequestInterceptor interceptor = new TraceeHttpRequestInterceptor("testProf");
		assertThat((String) FieldAccessUtil.getFieldVal(interceptor, "profile"), is("testProf"));
	}
}


<|start_filename|>api/src/main/java/io/tracee/Tracee.java<|end_filename|>
package io.tracee;

import io.tracee.spi.TraceeBackendProvider;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

public final class Tracee {

	private Tracee() {

	}

	/**
	 * Returns the TraceeBackend. There must be exactly one Tracee implementation on the classpath.
	 * <p/>
	 * A call to this method may initially block to lookup the implementation with a {@link java.util.ServiceLoader}.
	 * The call to this method from multiple threads with different class loader contexts may initially be slow
	 * because cache writes can overwrite each other in concurrent situations and some class loader contexts may have
	 * to be looked up multiple times. This allows the lookup mechanism to completely avoid synchronization.
	 * <p/>
	 * TODO: If you run a nested class loader environment (like a servlet container) and have the Tracee Api in a top
	 * level class loader and a Tracee Implementation in a child class loader, the child class loader may not be unloaded
	 * until a low memory situation occurs (since the SoftReference keeps the TraceeBackendProvider in memory).
	 * It could be a solution to change the SoftReference to WeakReference but let a TraceeBackend keep a strong
	 * reference to its TraceeBackendProvider.
	 */
	public static TraceeBackend getBackend() {
		return getBackend(new BackendProviderResolver());
	}

	protected static TraceeBackend getBackend(final BackendProviderResolver resolver) {
		final Set<TraceeBackendProvider> backendProviders;
		try {
			backendProviders = resolver.getBackendProviders();
		} catch (RuntimeException e) {
			throw new TraceeException("Unable to load available backend providers", e);
		}
		if (backendProviders.isEmpty()) {
			final Set<TraceeBackendProvider> defaultProvider = resolver.getDefaultTraceeBackendProvider();
			if (defaultProvider.isEmpty()) {
				throw new TraceeException("Unable to find a TracEE backend provider. Make sure that you have " +
					"tracee-core (for slf4j) or any other backend implementation on the classpath.");
			}
			return defaultProvider.iterator().next().provideBackend();
		}
		if (backendProviders.size() > 1) {
			final List<Class<?>> providerClasses = new ArrayList<>(backendProviders.size());
			for (TraceeBackendProvider backendProvider : backendProviders) {
				providerClasses.add(backendProvider.getClass());
			}
			final String providerClassNames = Arrays.toString(providerClasses.toArray());
			throw new TraceeException("Multiple TracEE backend providers found. Don't know which one of the following to use: "
				+ providerClassNames);
		}
		return backendProviders.iterator().next().provideBackend();
	}
}


<|start_filename|>core/src/main/java/io/tracee/backend/slf4j/Slf4jTraceeBackendProvider.java<|end_filename|>
package io.tracee.backend.slf4j;

import io.tracee.ThreadLocalHashSet;
import io.tracee.TraceeBackend;
import io.tracee.spi.TraceeBackendProvider;

public class Slf4jTraceeBackendProvider implements TraceeBackendProvider {

	private static final ThreadLocalHashSet<String> TRACEE_KEYS = new ThreadLocalHashSet<>();

	private final Slf4jTraceeBackend slf4jTraceeContext = new Slf4jTraceeBackend(TRACEE_KEYS);

	@Override
	public final TraceeBackend provideBackend() {
		return slf4jTraceeContext;
	}
}


<|start_filename|>core/src/test/java/io/tracee/backend/slf4j/Slf4jTraceeBackendTest.java<|end_filename|>
package io.tracee.backend.slf4j;

import io.tracee.ThreadLocalHashSet;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.MDC;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;

public class Slf4jTraceeBackendTest {

	private final ThreadLocalHashSet<String> traceeKeys = new ThreadLocalHashSet<>();

	private final Slf4jTraceeBackend OUT = new Slf4jTraceeBackend(traceeKeys);

	@Before
	public void before() {
		traceeKeys.get().clear();
	}

	@Test
	public void keyShouldExistOnlyIfInTraceeKeys() {
		MDC.put("test", "test");
		traceeKeys.get().add("test");
		assertThat(OUT.containsKey("test"), is(true));
	}

	@Test
	public void sizeShouldRespondWithTraceeKeysSize() {
		traceeKeys.get().add("a");
		traceeKeys.get().add("b");
		assertThat(OUT.size(), is(2));
	}

	@Test
	public void backendIsEmptyIfTraceeKeysIsEmpty() {
		MDC.put("test", "test");
		assertThat(OUT.isEmpty(), is(true));
	}

	@Test
	public void backendIsNotEmptryIfTraceeKeysIsNotEmpty() {
		traceeKeys.get().add("a");
		assertThat(OUT.isEmpty(), is(false));
	}

	@Test
	public void clearRemovesAllKeysInTraceeKeysFromMdc() {
		traceeKeys.get().add("a");
		MDC.put("a", "a");
		MDC.put("b", "b");
		OUT.clear();
		assertThat(MDC.get("a"), is(nullValue()));
		assertThat(MDC.get("b"), is("b"));
	}

	@Test
	public void putAddsToMdcAndTraceeKeys() {
		OUT.put("a", "ab");
		assertThat(traceeKeys.get().iterator().next(), is("a"));
		assertThat(MDC.get("a"), is("ab"));
	}

	@Test
	public void putAllAddsAllTupleToMdcAndTraceeKeys() {
		final Map<String, String> testMap = new HashMap<>();
		testMap.put("a", "ab");
		testMap.put("b", "bc");
		OUT.putAll(testMap);
		assertThat(traceeKeys.get().size(), is(2));
		assertThat(MDC.get("a"), is("ab"));
		assertThat(MDC.get("b"), is("bc"));
	}

	@Test
	public void copyToMapShouldCopyAllTraceeKeys() {
		MDC.put("a", "ab");
		MDC.put("b", "bc");
		traceeKeys.get().add("b");
		final Map<String, String> traceeCopy = OUT.copyToMap();
		assertThat(traceeCopy.size(), is(1));
		assertThat(traceeCopy.get("b"), is("bc"));
	}

	@Test
	public void returnNullIfKeyIsNull() {
		assertThat(OUT.get(null), is(nullValue()));
	}

	@Test
	public void returnNullIfKeyIsNotInTraceeValues() {
		MDC.put("a", "a");
		assertThat(OUT.get("a"), is(nullValue()));
	}

}


<|start_filename|>core/src/test/java/io/tracee/transport/jaxb/TpicMapTest.java<|end_filename|>
package io.tracee.transport.jaxb;

import nl.jqno.equalsverifier.EqualsVerifier;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;

public class TpicMapTest {

	@Test
	public void tpicMapShouldImplementEqualsCorrect() {
		EqualsVerifier.forClass(TpicMap.class).verify();
	}

	@Test
	public void tpicMapEntryShouldImplementEqualsCorrect() {
		EqualsVerifier.forClass(TpicMap.Entry.class).verify();
	}

	@Test
	public void toStringShouldContainTheKey() {
		assertThat(new TpicMap.Entry("theKey", "null").toString(), containsString("theKey"));
	}

	@Test
	public void toStringShouldContainTheValue() {
		assertThat(new TpicMap.Entry("null", "theValue").toString(), containsString("theValue"));
	}
}


<|start_filename|>binding/jaxws/src/test/java/io/tracee/binding/jaxws/TraceeJaxWsTestServiceIT.java<|end_filename|>
package io.tracee.binding.jaxws;


import io.tracee.Tracee;
import io.tracee.TraceeConstants;
import io.tracee.testhelper.SimpleTraceeBackend;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import javax.naming.NamingException;
import javax.xml.namespace.QName;
import javax.xml.ws.Endpoint;
import javax.xml.ws.Service;
import java.net.URL;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasKey;

public class TraceeJaxWsTestServiceIT {

	private static final QName ENDPOINT_QNAME = new QName(TraceeJaxWsEndpoint.Descriptor.TNS, TraceeJaxWsEndpointImpl.Descriptor.SERVICE_NAME);
	private static String ENDPOINT_URL = "http://127.0.0.1:4204/jaxws/TraceeJaxWsEndpointImpl";
	private static Endpoint endpoint;

	private SimpleTraceeBackend clientBackend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();

	@BeforeClass
	public static void setUp() throws Exception {
		endpoint = Endpoint.publish(ENDPOINT_URL, new TraceeJaxWsEndpointImpl());
	}

	@AfterClass
	public static void tearDown() throws NamingException {
		endpoint.stop();
		Tracee.getBackend().clear();
	}

	@Test
	public void transferClientTpicToServerBackend() throws Exception {
		clientBackend.put("inRequest", "yes");

		Service calculatorService = Service.create(new URL(ENDPOINT_URL + "?wsdl"), ENDPOINT_QNAME);
		calculatorService.setHandlerResolver(new TraceeClientHandlerResolver(clientBackend));

		final TraceeJaxWsEndpoint remote = calculatorService.getPort(TraceeJaxWsEndpoint.class);
		final List<String> result = remote.getCurrentTraceeContext();

		// checking server context as response.
		assertThat(result, hasItem(TraceeConstants.INVOCATION_ID_KEY));
		assertThat(result, hasItem("inRequest"));
		assertThat(result, hasItem("yes"));

		// checking client context. We should receive the pair "called"->"yes" and the invocationId from the server.
		assertThat(clientBackend.copyToMap(), hasKey(TraceeConstants.INVOCATION_ID_KEY));
		assertThat(clientBackend.copyToMap(), hasEntry("called", "yes"));
	}
}


<|start_filename|>binding/springmvc/src/test/java/io/tracee/binding/springmvc/TraceeResponseBodyAdviceTest.java<|end_filename|>
package io.tracee.binding.springmvc;

import io.tracee.Tracee;
import io.tracee.TraceeConstants;
import org.junit.Test;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static io.tracee.TraceeConstants.INVOCATION_ID_KEY;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

public class TraceeResponseBodyAdviceTest {

	private final TraceeInterceptor interceptor = new TraceeInterceptor();

	private final TraceeResponseBodyAdvice advice = new TraceeResponseBodyAdvice(interceptor);

	@Test
	public void adviceShouldHandleAllKindOfRequests() {
		assertThat(advice.supports(null, null), is(true));
	}

	@Test
	public void shouldAddTraceeHeaderToResponse() {
		Tracee.getBackend().put(INVOCATION_ID_KEY, "mySuperValue");
		final HttpServletRequest request = mock(HttpServletRequest.class);
		final HttpServletResponse response = mock(HttpServletResponse.class);

		advice.beforeBodyWrite(null, null, null, null, new ServletServerHttpRequest(request), new ServletServerHttpResponse(response));
		verify(response).setHeader(eq(TraceeConstants.TPIC_HEADER), eq(INVOCATION_ID_KEY + "=mySuperValue"));
	}

}


<|start_filename|>core/src/test/java/io/tracee/BackendBaseTest.java<|end_filename|>
package io.tracee;

import io.tracee.configuration.TraceeFilterConfiguration;
import io.tracee.configuration.TraceeFilterConfiguration.Channel;
import org.junit.Test;
import org.mockito.Mockito;

import static io.tracee.configuration.TraceeFilterConfiguration.Profile.DISABLED;
import static io.tracee.configuration.TraceeFilterConfiguration.Profile.DISABLE_INBOUND;
import static io.tracee.configuration.TraceeFilterConfiguration.Profile.DISABLE_OUTBOUND;
import static io.tracee.configuration.TraceeFilterConfiguration.Profile.HIDE_INBOUND;
import static io.tracee.configuration.TraceeFilterConfiguration.Profile.HIDE_OUTBOUND;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;

public class BackendBaseTest {

	private final BackendBase unit = Mockito.spy(BackendBase.class);

	@Test
	public void invocationIdShortcutShouldReturnTheInvocationIdIfSet() {
		when(unit.get(eq(TraceeConstants.INVOCATION_ID_KEY))).thenReturn("ourInvocationId");
		assertThat(unit.getInvocationId(), is("ourInvocationId"));
	}

	@Test
	public void invocationIdShortcutShouldReturnNullIfNoInvocationIdIsSet() {
		assertThat(unit.getInvocationId(), is(nullValue()));
	}

	@Test
	public void sessionIdShortcutShouldReturnTheSessionIdIfSet() {
		when(unit.get(eq(TraceeConstants.SESSION_ID_KEY))).thenReturn("ourSessionId");
		assertThat(unit.getSessionId(), is("ourSessionId"));
	}

	@Test
	public void sessionIdShortcutShouldReturnNullIfNoSessionIdIsSet() {
		assertThat(unit.getSessionId(), is(nullValue()));
	}

	@Test
	public void testLoadOverwrittenConfigurationValues() {
		assertThat(unit.getConfiguration().generatedInvocationIdLength(), equalTo(42));
	}

	@Test
	public void testLoadUserDefinedProfileFromProperties() {
		assertThat(unit.getConfiguration("FOO").shouldProcessParam("ANY", Channel.IncomingRequest), equalTo(true));
	}

	@Test
	public void testHideInboundProfile() {
		assertThat(unit.getConfiguration(HIDE_INBOUND).shouldProcessContext(Channel.OutgoingResponse), equalTo(false));
	}

	@Test
	public void testHideOutboundProfile() {
		assertThat(unit.getConfiguration(HIDE_OUTBOUND).shouldProcessContext(Channel.OutgoingRequest), equalTo(false));
	}

	@Test
	public void testDisableInboundProfile() {
		assertThat(unit.getConfiguration(DISABLE_INBOUND).shouldProcessContext(Channel.IncomingRequest), equalTo(false));
		assertThat(unit.getConfiguration(DISABLE_INBOUND).shouldProcessContext(Channel.OutgoingResponse), equalTo(false));
	}

	@Test
	public void testDisableOutboundProfile() {
		assertThat(unit.getConfiguration(DISABLE_OUTBOUND).shouldProcessContext(Channel.OutgoingRequest), equalTo(false));
		assertThat(unit.getConfiguration(DISABLE_OUTBOUND).shouldProcessContext(Channel.IncomingResponse), equalTo(false));
	}


	@Test
	public void testDisabledProfile() {
		assertThat(unit.getConfiguration(DISABLED).shouldProcessContext(Channel.AsyncDispatch), equalTo(false));
		assertThat(unit.getConfiguration(DISABLED).shouldProcessContext(Channel.AsyncProcess), equalTo(false));
		assertThat(unit.getConfiguration(DISABLED).shouldProcessContext(Channel.IncomingRequest), equalTo(false));
		assertThat(unit.getConfiguration(DISABLED).shouldProcessContext(Channel.IncomingResponse), equalTo(false));
		assertThat(unit.getConfiguration(DISABLED).shouldProcessContext(Channel.OutgoingRequest), equalTo(false));
		assertThat(unit.getConfiguration(DISABLED).shouldProcessContext(Channel.OutgoingResponse), equalTo(false));
	}

	@Test
	public void testNullProfile() {
		assertThat(unit.getConfiguration(null), is(not(nullValue())));
	}

	@Test
	public void testProfileCacheForEmptyOrNullProfile() {
		assertThat(unit.getConfiguration(), is(unit.getConfiguration(null)));
	}

	@Test
	public void testProfileCacheForGivenProfile() {
		final TraceeFilterConfiguration hideInboundConfiguration = unit.getConfiguration(HIDE_INBOUND);
		assertThat(unit.getConfiguration(HIDE_INBOUND), is(sameInstance(hideInboundConfiguration)));
	}

	@Test
	public void testProfileCacheForDifferenceProfiles() {
		final TraceeFilterConfiguration hideInboundConfiguration = unit.getConfiguration(HIDE_OUTBOUND);
		assertThat(unit.getConfiguration(HIDE_INBOUND), is(not(sameInstance(hideInboundConfiguration))));
	}
}


<|start_filename|>binding/springws/src/test/java/io/tracee/binding/springws/itest/testservice/JaxwsTestserviceEndpoint.java<|end_filename|>
package io.tracee.binding.springws.itest.testservice;

import io.tracee.Tracee;
import io.tracee.TraceeConstants;
import io.tracee.binding.jaxws.TraceeWsHandlerConstants;

import javax.jws.HandlerChain;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService(targetNamespace = JaxwsTestservice.TNS, name = JaxwsTestservice.CURRENT_TRACEE_CONTEXT_LOCALPART)
@HandlerChain(file = TraceeWsHandlerConstants.TRACEE_HANDLER_CHAIN_URL)
public class JaxwsTestserviceEndpoint implements JaxwsTestservice {

	@WebResult(name = "remoteInvocationId")
	public String currentTraceeContext() {
		Tracee.getBackend().put("testId", "TestValueFromRemoteEndpoint");
		return Tracee.getBackend().get(TraceeConstants.INVOCATION_ID_KEY);
	}
}


<|start_filename|>binding/jaxws/src/test/java/io/tracee/binding/jaxws/TraceeClientHandlerTest.java<|end_filename|>
package io.tracee.binding.jaxws;

import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.testhelper.SimpleTraceeBackend;
import io.tracee.transport.SoapHeaderTransport;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.bind.JAXBException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class TraceeClientHandlerTest {

	private TraceeBackend backend = spy(SimpleTraceeBackend.createNonLoggingAllPermittingBackend());

	private final TraceeClientHandler unit = new TraceeClientHandler(backend);
	private SOAPMessageContext messageContext = mock(SOAPMessageContext.class);

	private SOAPMessage message;

	@Before
	public void setup() throws SOAPException {
		message = spy(MessageFactory.newInstance().createMessage());
		when(messageContext.getMessage()).thenReturn(message);
	}

	@Test
	public void faultsShouldBeHandledWithoutMessageInteraction() throws SOAPException {
		assertThat(unit.handleFault(messageContext), is(true));
		verify(message, never()).getSOAPHeader();
	}

	@Test
	public void skipProcessingWithoutErrorIfNoTpicHeaderIsInMessage() throws SOAPException {
		unit.handleIncoming(messageContext);
		assertThat(backend.isEmpty(), is(true));
	}

	@Test
	public void skipProcessingWithoutErrorIfNoSoapHeaderIsInMessage() throws SOAPException {
		when(message.getSOAPHeader()).thenReturn(null);
		unit.handleIncoming(messageContext);
		assertThat(backend.isEmpty(), is(true));
	}

	@Test
	public void catchExceptionOnReadTpicHeader() throws SOAPException {
		when(message.getSOAPHeader()).thenThrow(new SOAPException());
		unit.handleIncoming(messageContext);
		assertThat(backend.isEmpty(), is(true));
	}

	@Test
	public void readSoapHeaderIntoToBackend() throws SOAPException, JAXBException {
		final Map<String, String> context = new HashMap<>();
		context.put("abc", "123");

		new SoapHeaderTransport().renderSoapHeader(context, message.getSOAPHeader());
		when(messageContext.getMessage()).thenReturn(message);

		unit.handleIncoming(messageContext);
		assertThat(backend.copyToMap(), hasEntry("abc", "123"));
	}

	@Test
	public void addSoapHeaderIfNooneIsOnMessage() throws SOAPException {
		backend.put("abcd", "12");
		when(message.getSOAPHeader()).thenReturn(null);
		when(message.getSOAPPart()).thenReturn(mock(SOAPPart.class));
		final SOAPEnvelope envelope = mock(SOAPEnvelope.class);
		when(message.getSOAPPart().getEnvelope()).thenReturn(envelope);
		when(message.getSOAPPart().getEnvelope().addHeader()).thenReturn(mock(SOAPHeader.class, Mockito.RETURNS_DEEP_STUBS));

		unit.handleOutgoing(messageContext);
		verify(envelope).addHeader();
	}

	@Test
	public void renderBackendToSoapHeader() throws SOAPException {
		backend.put("my header", "Wow!");
		unit.handleOutgoing(messageContext);
		final NodeList tpicElements = message.getSOAPHeader().getElementsByTagNameNS(TraceeConstants.SOAP_HEADER_NAMESPACE, TraceeConstants.TPIC_HEADER);
		assertThat(tpicElements.getLength(), is(1));
		final Node tpicEntry = tpicElements.item(0).getChildNodes().item(0);
		assertThat(tpicEntry.getLocalName(), is("entry"));
		assertThat(tpicEntry.getAttributes().getNamedItem("key").getNodeValue(), is("my header"));
		assertThat(tpicEntry.getChildNodes().item(0).getNodeValue(), is("Wow!"));
	}

	@Test
	public void skipProcessingIfBackendIsEmpty() throws SOAPException {
		unit.handleOutgoing(messageContext);
		verify(message, never()).getSOAPHeader();
	}
}


<|start_filename|>testhelper/src/test/java/io/tracee/testhelper/FieldAccessUtilTest.java<|end_filename|>
package io.tracee.testhelper;

import org.junit.Test;

import java.util.Map;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

public class FieldAccessUtilTest {

	@Test
	public void shouldAccessFields() {
		final SimpleTraceeBackend backend = new SimpleTraceeBackend(new PermitAllTraceeFilterConfiguration());
		backend.put("test", "testVal");
		@SuppressWarnings("unchecked")
		final Map<String, String> value = FieldAccessUtil.getFieldVal(backend, "backendValues");
		assertThat(value.get("test"), is("testVal"));
	}
}


<|start_filename|>core/src/main/java/io/tracee/transport/HttpHeaderTransport.java<|end_filename|>
package io.tracee.transport;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

public class HttpHeaderTransport {

	public static final String ENCODING_CHARSET = "UTF-8";
	private static final Logger LOGGER = LoggerFactory.getLogger(HttpHeaderTransport.class);

	Map<String, String> parse(String serialized) {
		final StringTokenizer pairTokenizer = new StringTokenizer(serialized.trim(), ",");
		final Map<String, String> context = new HashMap<>();
		while (pairTokenizer.hasMoreTokens()) {
			final String pairStr = pairTokenizer.nextToken();
			final String[] keyValuePair = pairStr.split("=");
			if (keyValuePair.length != 2) {
				continue;
			}
			try {
				final String key = URLDecoder.decode(keyValuePair[0], ENCODING_CHARSET);
				final String value = URLDecoder.decode(keyValuePair[1], ENCODING_CHARSET);
				context.put(key, value);
			} catch (UnsupportedEncodingException e) {
				LOGGER.error("Charset not found", e);
			}
		}

		return context;
	}

	public Map<String, String> parse(List<String> serializedElements) {
		final Map<String, String> contextMap = new HashMap<>();
		for (String serializedElement : serializedElements) {
			contextMap.putAll(parse(serializedElement));
		}

		return contextMap;
	}

	public String render(Map<String, String> context) {
		final StringBuilder sb = new StringBuilder(128);
		for (Iterator<Map.Entry<String, String>> iterator = context.entrySet().iterator(); iterator.hasNext(); ) {
			Map.Entry<String, String> entry = iterator.next();
			try {
				final String key = URLEncoder.encode(entry.getKey().trim(), ENCODING_CHARSET);
				final String value = URLEncoder.encode(entry.getValue().trim(), ENCODING_CHARSET);
				sb.append(key).append('=').append(value);
				if (iterator.hasNext()) {
					sb.append(',');
				}
			} catch (UnsupportedEncodingException e) {
				LOGGER.error("Charset not found", e);
			}
		}
		return sb.toString();
	}
}


<|start_filename|>binding/httpcomponents5/src/main/java/io/tracee/binding/httpcomponents/TraceeHttpResponseInterceptor.java<|end_filename|>
package io.tracee.binding.httpcomponents;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.configuration.TraceeFilterConfiguration;
import io.tracee.configuration.TraceeFilterConfiguration.Profile;
import io.tracee.transport.HttpHeaderTransport;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpResponseInterceptor;
import org.apache.hc.core5.http.protocol.HttpContext;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static io.tracee.configuration.TraceeFilterConfiguration.Channel.IncomingResponse;


public class TraceeHttpResponseInterceptor implements HttpResponseInterceptor {

	private final TraceeBackend backend;
	private final HttpHeaderTransport transportSerialization;
	private final String profile;

	public TraceeHttpResponseInterceptor() {
		this(Profile.DEFAULT);
	}

	public TraceeHttpResponseInterceptor(String profile) {
		this(Tracee.getBackend(), profile);
	}

	TraceeHttpResponseInterceptor(TraceeBackend backend, String profile) {
		this.backend = backend;
		this.profile = profile;
		transportSerialization = new HttpHeaderTransport();
	}

	@Override
	public final void process(HttpResponse response, HttpContext context) {
		final TraceeFilterConfiguration filterConfiguration = backend.getConfiguration(profile);
		final Iterator<Header> headerIterator = response.headerIterator(TraceeConstants.TPIC_HEADER);
		if (headerIterator != null && headerIterator.hasNext() && filterConfiguration.shouldProcessContext(IncomingResponse)) {
			final List<String> stringTraceeHeaders = new ArrayList<>();
			while (headerIterator.hasNext()) {
				stringTraceeHeaders.add(headerIterator.next().getValue());
			}
			backend.putAll(filterConfiguration.filterDeniedParams(transportSerialization.parse(stringTraceeHeaders), IncomingResponse));
		}
	}
}


<|start_filename|>binding/httpclient/src/test/java/io/tracee/binding/httpclient/TraceeHttpClientDecoratorTest.java<|end_filename|>
package io.tracee.binding.httpclient;


import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.testhelper.SimpleTraceeBackend;
import io.tracee.transport.HttpHeaderTransport;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.junit.Test;
import org.mockito.Mockito;

import java.io.IOException;
import java.util.Collections;

import static io.tracee.testhelper.DelegationTestUtil.assertDelegationToSpy;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
import static org.mockito.Matchers.anyMapOf;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class TraceeHttpClientDecoratorTest {

	private final TraceeBackend backendMock = spy(SimpleTraceeBackend.createNonLoggingAllPermittingBackend());
	private final HttpMethod httpMethodMock = mock(HttpMethod.class);
	private final HttpHeaderTransport transportSerializationMock = mock(HttpHeaderTransport.class);
	private final TraceeHttpClientDecorator unit = new TraceeHttpClientDecorator(mock(HttpClient.class), backendMock, transportSerializationMock, null);

	@Test
	public void doNotRenderTpicHeaderIfBackendIsEmpty() throws IOException {
		unit.executeMethod(null, httpMethodMock);
		verify(httpMethodMock, never()).setRequestHeader(anyString(), anyString());
	}

	@Test
	public void testContextWrittenToRequest() throws IOException {
		backendMock.put("foo", "bar");
		when(transportSerializationMock.render(anyMapOf(String.class, String.class))).thenReturn("foo=bar");
		unit.executeMethod(httpMethodMock);
		verify(httpMethodMock).setRequestHeader(eq(TraceeConstants.TPIC_HEADER), eq("foo=bar"));
	}

	@Test
	public void testContextParsedFromResponse() throws IOException {
		final Header responseHeader = new Header(TraceeConstants.TPIC_HEADER, "foo=bar");
		final Header[] responseHeaders = new Header[]{responseHeader};
		when(httpMethodMock.getResponseHeaders(eq(TraceeConstants.TPIC_HEADER))).thenReturn(responseHeaders);
		when(httpMethodMock.isRequestSent()).thenReturn(true);

		unit.executeMethod(null, httpMethodMock, null);

		verify(transportSerializationMock).parse(eq(Collections.singletonList("foo=bar")));
		verify(backendMock).putAll(Mockito.anyMapOf(String.class, String.class));
	}

	@Test
	public void shouldDelegateAllPublicMethods() {
		final HttpClient client = mock(HttpClient.class);
		final HttpClient wrappedClient = TraceeHttpClientDecorator.wrap(client);

		assertDelegationToSpy(client).by(wrappedClient).ignore("executeMethod").verify();
	}

	@Test
	public void wrapOnlyWithTraceeHttpClientDecoratorIfInstanceIsNotOfThisType() {
		final HttpClient httpClient = TraceeHttpClientDecorator.wrap(mock(HttpClient.class));
		final HttpClient wrappedAgainHttpClient = TraceeHttpClientDecorator.wrap(httpClient);
		assertThat(httpClient, is(sameInstance(wrappedAgainHttpClient)));
	}
}


<|start_filename|>binding/springws/src/test/java/io/tracee/binding/springws/itest/testservice/JaxwsTestservice.java<|end_filename|>
package io.tracee.binding.springws.itest.testservice;

public interface JaxwsTestservice {

	String TNS = "https://github.com/tracee/tracee/examples/jaxws/service/wsdl/";

	String CURRENT_TRACEE_CONTEXT_LOCALPART = "currentTraceeContext";

	String currentTraceeContext();
}


<|start_filename|>binding/jaxws/src/main/java/io/tracee/binding/jaxws/AbstractTraceeHandler.java<|end_filename|>
package io.tracee.binding.jaxws;

import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

abstract class AbstractTraceeHandler implements SOAPHandler<SOAPMessageContext> {

	private static final Set<QName> HANDLED_HEADERS = Collections.unmodifiableSet(
		new HashSet<>(Collections.singleton(TraceeConstants.SOAP_HEADER_QNAME)));

	protected final TraceeBackend traceeBackend;

	public AbstractTraceeHandler(TraceeBackend traceeBackend) {
		this.traceeBackend = traceeBackend;
	}

	@Override
	public final boolean handleMessage(final SOAPMessageContext context) {
		if (this.isOutgoing(context)) {
			this.handleOutgoing(context);
		} else {
			this.handleIncoming(context);
		}
		return true;
	}

	private boolean isOutgoing(MessageContext messageContext) {
		Object outboundBoolean = messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
		return outboundBoolean != null && (Boolean) outboundBoolean;
	}

	@Override
	public void close(MessageContext context) {
	}

	protected abstract void handleIncoming(SOAPMessageContext context);

	protected abstract void handleOutgoing(SOAPMessageContext context);

	@Override
	public Set<QName> getHeaders() {
		return HANDLED_HEADERS;
	}

	SOAPHeader getOrCreateHeader(final SOAPMessage message) throws SOAPException {
		SOAPHeader header = message.getSOAPHeader();
		if (header == null) {
			header = message.getSOAPPart().getEnvelope().addHeader();
		}
		return header;
	}
}


<|start_filename|>core/src/test/java/io/tracee/configuration/PropertiesBasedTraceeFilterConfigurationTest.java<|end_filename|>
package io.tracee.configuration;

import org.junit.Test;
import org.mockito.Mockito;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import static io.tracee.configuration.PropertiesBasedTraceeFilterConfiguration.Channel;
import static io.tracee.configuration.PropertiesBasedTraceeFilterConfiguration.GENERATE_INVOCATION_ID;
import static io.tracee.configuration.PropertiesBasedTraceeFilterConfiguration.GENERATE_SESSION_ID;
import static io.tracee.configuration.PropertiesBasedTraceeFilterConfiguration.TRACEE_DEFAULT_PROFILE_PREFIX;
import static io.tracee.configuration.TraceeFilterConfiguration.Channel.AsyncDispatch;
import static io.tracee.configuration.TraceeFilterConfiguration.Channel.IncomingRequest;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

public class PropertiesBasedTraceeFilterConfigurationTest {

	private PropertyChain propertyChain = Mockito.mock(PropertyChain.class);
	private PropertiesBasedTraceeFilterConfiguration unit = new PropertiesBasedTraceeFilterConfiguration(propertyChain);

	@Test
	public void testShouldPropagatePositive() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + AsyncDispatch.name())).thenReturn(".*");
		assertTrue(unit.shouldProcessParam("foo", AsyncDispatch));
	}

	@Test
	public void testShouldPropagateNegative() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + AsyncDispatch.name())).thenReturn("a,b,c");
		assertFalse(unit.shouldProcessParam("foo", AsyncDispatch));
	}

	@Test
	public void testShouldAllowRegexInPatterns() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + AsyncDispatch.name())).thenReturn("b[oa]+b");
		assertTrue(unit.shouldProcessParam("baab", AsyncDispatch));
		assertTrue(unit.shouldProcessParam("boob", AsyncDispatch));
	}

	@Test
	public void extractOnePattern() {
		final List<Pattern> patterns = unit.extractPatterns(".*");
		assertThat(patterns.get(0).pattern(), is(".*"));
	}

	@Test
	public void extractTwoPattern() {
		final List<Pattern> patterns = unit.extractPatterns(".*,(.*)");
		assertThat(patterns, hasSize(2));
	}

	@Test
	public void extractPatternsShouldReturnEmptyListOnNullValue() {
		assertThat(unit.extractPatterns(null), is(empty()));
	}

	@Test
	public void extractPatternsShouldReturnEmptyListOnPatternCompilation() {
		assertThat(unit.extractPatterns("foo(()"), is(empty()));
	}

	@Test
	public void testShouldNotPropagateIfNothingIsConfigured() {
		assertFalse(unit.shouldProcessParam("foo", AsyncDispatch));
	}

	@Test
	public void testShouldProcessIfDisabledByConfiguration() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + AsyncDispatch.name())).thenReturn(" \t\n");
		assertFalse(unit.shouldProcessContext(AsyncDispatch));
	}

	@Test
	public void testShouldProcessIfAnyPatternIsGiven() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + AsyncDispatch.name())).thenReturn("a");
		assertTrue(unit.shouldProcessContext(AsyncDispatch));
	}

	@Test
	public void testGeneratedInvocationIdLength() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + GENERATE_INVOCATION_ID)).thenReturn("1");
		assertThat(unit.generatedInvocationIdLength(), equalTo(1));
	}

	@Test
	public void doNotGenerateInvocationIdIfLengthIsZero() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + GENERATE_INVOCATION_ID)).thenReturn("0");
		assertThat(unit.shouldGenerateInvocationId(), is(false));
	}

	@Test
	public void doNotGenerateInvocationIdIfLengthIsNegative() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + GENERATE_INVOCATION_ID)).thenReturn("-1");
		assertThat(unit.shouldGenerateInvocationId(), is(false));
	}

	@Test
	public void generateInvocationIdIfLengthIsPositive() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + GENERATE_INVOCATION_ID)).thenReturn("1");
		assertThat(unit.shouldGenerateInvocationId(), is(true));
	}

	@Test
	public void testGeneratedInvocationIdNonNumericMeansZero() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + GENERATE_INVOCATION_ID)).thenReturn("false");
		assertThat(unit.generatedInvocationIdLength(), equalTo(0));
	}

	@Test
	public void testGeneratedSessionIdLength() {
		when(propertyChain.getProperty((TRACEE_DEFAULT_PROFILE_PREFIX + GENERATE_SESSION_ID))).thenReturn("42");
		assertThat(unit.generatedSessionIdLength(), equalTo(42));
	}

	@Test
	public void doNotSessionInvocationIdIfLengthIsZero() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + GENERATE_SESSION_ID)).thenReturn("0");
		assertThat(unit.shouldGenerateSessionId(), is(false));
	}

	@Test
	public void doNotGenerateSessionIdIfLengthIsNegative() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + GENERATE_SESSION_ID)).thenReturn("-1");
		assertThat(unit.shouldGenerateSessionId(), is(false));
	}

	@Test
	public void generateSessionIdIfLengthIsPositive() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + GENERATE_SESSION_ID)).thenReturn("1");
		assertThat(unit.shouldGenerateSessionId(), is(true));
	}

	@Test
	public void testFilterDeniedParamsFiltersEverythingWithoutConfiguration() {
		final Map<String, String> unfiltered = Collections.singletonMap("Foo", "Bar");
		assertThat(unit.filterDeniedParams(unfiltered, Channel.IncomingRequest), equalTo(Collections.<String, String>emptyMap()));
	}

	@Test
	public void testFilterDeniedParamsPassesWhitelisted() {
		when(propertyChain.getProperty(TRACEE_DEFAULT_PROFILE_PREFIX + IncomingRequest.name())).thenReturn("Foo");
		final Map<String, String> unfiltered = Collections.singletonMap("Foo", "Bar");
		assertThat(unit.filterDeniedParams(unfiltered, Channel.IncomingRequest), equalTo(unfiltered));
	}
}


<|start_filename|>binding/servlet/src/test/java/io/tracee/binding/servlet/TraceeFilterTest.java<|end_filename|>
package io.tracee.binding.servlet;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.testhelper.FieldAccessUtil;
import io.tracee.testhelper.SimpleTraceeBackend;
import io.tracee.transport.HttpHeaderTransport;
import org.hamcrest.MatcherAssert;
import org.junit.Test;
import org.mockito.Mockito;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.contains;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.internal.verification.VerificationModeFactory.atLeastOnce;

public class TraceeFilterTest {

	private final SimpleTraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();
	private final HttpHeaderTransport transport = new HttpHeaderTransport();
	private final TraceeFilter unit = new TraceeFilter(backend, transport);
	private final FilterChain filterChain = Mockito.mock(FilterChain.class);
	private final HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class);
	private final HttpServletResponse httpServletResponse = Mockito.mock(HttpServletResponse.class);


	@Test
	public void testUsesProfileIfConfigured() throws ServletException, IOException {
		final FilterConfig filterConfigWithProfile = mock(FilterConfig.class);
		when(filterConfigWithProfile.getInitParameter(TraceeFilter.PROFILE_INIT_PARAM)).thenReturn("FOO");
		final TraceeBackend spiedBackend = spy(backend);
		final TraceeFilter unitWithSpiedBackend = new TraceeFilter(spiedBackend, transport);
		unitWithSpiedBackend.init(filterConfigWithProfile);
		unitWithSpiedBackend.doFilterHttp(httpServletRequest, httpServletResponse, filterChain);
		verify(spiedBackend).getConfiguration(eq("FOO"));
	}

	@Test
	public void testWriteResponseHeaderEvenIfFilterChainThrowsAnException() throws Exception {

		backend.put("foobi", "yes sir");
		doThrow(new RuntimeException("Bad is bad")).when(filterChain).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class));

		try {
			unit.doFilter(httpServletRequest, httpServletResponse, filterChain);
			fail("Expected RuntimeException");
		} catch (RuntimeException ignored) { /*ignore*/ }

		verify(httpServletResponse, atLeastOnce()).setHeader(eq(TraceeConstants.TPIC_HEADER),
			contains("foobi=yes+sir"));
	}

	@Test
	public void testDoesNotCreateAResponseHeaderWhenBackendIsEmpty() throws Exception {

		doThrow(new RuntimeException("Bad is bad")).when(filterChain).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class));

		try {
			unit.doFilter(httpServletRequest, httpServletResponse, filterChain);
			fail("Expected RuntimeException");
		} catch (RuntimeException ignored) { /*ignore*/ }

		verify(httpServletResponse, never()).setHeader(anyString(), anyString());
	}

	@Test
	public void shouldDelegateToNextInFilterChainForNonHttpRequests() throws Exception {
		ServletRequest servletRequest = mock(ServletRequest.class);
		ServletResponse servletResponse = mock(ServletResponse.class);
		unit.doFilter(servletRequest, servletResponse, filterChain);
		verify(filterChain).doFilter(servletRequest, servletResponse);
	}

	@Test
	public void shouldDelegateToNextInFilterChainForHttpRequests() throws Exception {
		unit.doFilter(httpServletRequest, httpServletResponse, filterChain);
		verify(filterChain).doFilter(httpServletRequest, httpServletResponse);
	}

	@Test
	public void defaultConstructorUsesTraceeBackend() {
		final TraceeFilter filter = new TraceeFilter();
		MatcherAssert.assertThat((TraceeBackend) FieldAccessUtil.getFieldVal(filter, "backend"), is(Tracee.getBackend()));
	}
}


<|start_filename|>binding/cxf/src/main/java/io/tracee/binding/cxf/interceptor/TraceeResponseInInterceptor.java<|end_filename|>
package io.tracee.binding.cxf.interceptor;

import io.tracee.TraceeBackend;
import io.tracee.configuration.TraceeFilterConfiguration.Profile;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.Phase;

import static io.tracee.configuration.TraceeFilterConfiguration.Channel.IncomingResponse;

public class TraceeResponseInInterceptor extends AbstractTraceeInInterceptor {

	public TraceeResponseInInterceptor(TraceeBackend backend) {
		this(backend, Profile.DEFAULT);
	}

	public TraceeResponseInInterceptor(TraceeBackend backend, String profile) {
		super(Phase.PRE_INVOKE, IncomingResponse, backend, profile);
	}

	@Override
	protected boolean shouldHandleMessage(Message message) {
		return MessageUtils.isRequestor(message);
	}
}


<|start_filename|>binding/httpcomponents5/src/test/java/io/tracee/binding/httpcomponents/TraceeHttpResponseInterceptorTest.java<|end_filename|>
package io.tracee.binding.httpcomponents;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.configuration.TraceeFilterConfiguration;
import io.tracee.testhelper.FieldAccessUtil;
import io.tracee.testhelper.SimpleTraceeBackend;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.message.BasicHttpResponse;
import org.apache.hc.core5.http.message.BasicStatusLine;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mock;

public class TraceeHttpResponseInterceptorTest {

	private final SimpleTraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();
	private final TraceeHttpResponseInterceptor unit = new TraceeHttpResponseInterceptor(backend, null);

	@Test
	public void testResponseInterceptorParsesHttpHeaderToBackend() throws Exception {
		final HttpResponse httpResponse = new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, 404, "not found"));
		httpResponse.setHeader(TraceeConstants.TPIC_HEADER, "foobi=bar");
		unit.process(httpResponse, mock(HttpContext.class));
		assertThat(backend.get("foobi"), equalTo("bar"));
	}

	@Test
	public void defaultConstructorUsesDefaultProfile() {
		final TraceeHttpResponseInterceptor injector = new TraceeHttpResponseInterceptor();
		assertThat((String) FieldAccessUtil.getFieldVal(injector, "profile"), is(TraceeFilterConfiguration.Profile.DEFAULT));
	}

	@Test
	public void defaultConstructorUsesTraceeBackend() {
		final TraceeHttpResponseInterceptor injector = new TraceeHttpResponseInterceptor();
		assertThat((TraceeBackend) FieldAccessUtil.getFieldVal(injector, "backend"), is(Tracee.getBackend()));
	}

	@Test
	public void constructorStoresProfileNameInternal() {
		final TraceeHttpResponseInterceptor injector = new TraceeHttpResponseInterceptor("testProf");
		assertThat((String) FieldAccessUtil.getFieldVal(injector, "profile"), is("testProf"));
	}
}


<|start_filename|>binding/cxf/src/main/java/io/tracee/binding/cxf/interceptor/AbstractTraceeInInterceptor.java<|end_filename|>
package io.tracee.binding.cxf.interceptor;

import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.configuration.TraceeFilterConfiguration;
import io.tracee.transport.HttpHeaderTransport;
import io.tracee.transport.SoapHeaderTransport;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;

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

abstract class AbstractTraceeInInterceptor extends AbstractPhaseInterceptor<Message> {

	protected final TraceeBackend backend;

	private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTraceeInInterceptor.class);

	private final HttpHeaderTransport httpJsonSerializer;
	private final SoapHeaderTransport httpSoapSerializer;

	private String profile;

	private final TraceeFilterConfiguration.Channel channel;

	public AbstractTraceeInInterceptor(String phase, TraceeFilterConfiguration.Channel channel, TraceeBackend backend,
									   String profile) {
		super(phase);
		this.channel = channel;
		this.backend = backend;
		this.profile = profile;
		this.httpJsonSerializer = new HttpHeaderTransport();
		this.httpSoapSerializer = new SoapHeaderTransport();
	}

	protected abstract boolean shouldHandleMessage(Message message);

	@Override
	public void handleMessage(final Message message) {
		if (shouldHandleMessage(message)) {
			final TraceeFilterConfiguration filterConfiguration = backend.getConfiguration(profile);

			LOGGER.debug("Interceptor handles message!");
			if (filterConfiguration.shouldProcessContext(channel)) {
				if (Boolean.TRUE.equals(message.getExchange().get(Message.REST_MESSAGE))) {
					handleHttpMessage(message, filterConfiguration);
				} else {
					try {
						handleSoapMessage((SoapMessage) message, filterConfiguration);
					} catch (NoClassDefFoundError e) {
						LOGGER.error("Should handle SOAP-message but it seems that cxf soap dependency is not on the classpath. Unable to parse Tracee-Headers: {}", e.getMessage(), e);
					}
				}
			}
		}
	}

	private void handleHttpMessage(final Message message, final TraceeFilterConfiguration filterConfiguration) {
		final Map<String, List<String>> requestHeaders = CastUtils.cast((Map<?, ?>) message.get(Message.PROTOCOL_HEADERS));
		if (requestHeaders != null && !requestHeaders.isEmpty()) {
			final List<String> traceeHeader = requestHeaders.get(TraceeConstants.TPIC_HEADER);

			if (traceeHeader != null && !traceeHeader.isEmpty()) {
				final Map<String, String> parsedContext = httpJsonSerializer.parse(traceeHeader);
				backend.putAll(filterConfiguration.filterDeniedParams(parsedContext, channel));
			}
		}
	}

	private void handleSoapMessage(final SoapMessage message, final TraceeFilterConfiguration filterConfiguration) {
		final Header soapHeader = message.getHeader(TraceeConstants.SOAP_HEADER_QNAME);
		if (soapHeader != null) {
			final Map<String, String> parsedContext = httpSoapSerializer.parseTpicHeader((Element) soapHeader.getObject());
			backend.putAll(filterConfiguration.filterDeniedParams(parsedContext, channel));
		}
	}
}


<|start_filename|>binding/jaxws/src/test/java/io/tracee/binding/jaxws/TraceeJaxWsEndpointImpl.java<|end_filename|>
package io.tracee.binding.jaxws;

import io.tracee.Tracee;

import javax.jws.HandlerChain;
import javax.jws.WebService;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@WebService(serviceName = TraceeJaxWsEndpointImpl.Descriptor.SERVICE_NAME, portName = "TraceeJaxWsEndpointPort",
	targetNamespace = TraceeJaxWsEndpoint.Descriptor.TNS,
	endpointInterface = "io.tracee.binding.jaxws.TraceeJaxWsEndpoint")
@HandlerChain(file = TraceeWsHandlerConstants.TRACEE_HANDLER_CHAIN_URL)
public class TraceeJaxWsEndpointImpl implements TraceeJaxWsEndpoint {

	@Override
	public List<String> getCurrentTraceeContext() {

		final List<String> entries = new ArrayList<>();
		for (Map.Entry<String, String> entry : Tracee.getBackend().copyToMap().entrySet()) {
			entries.add(entry.getKey());
			entries.add(entry.getValue());
		}

		Tracee.getBackend().put("called", "yes");

		return entries;
	}
}


<|start_filename|>binding/cxf/src/main/java/io/tracee/binding/cxf/interceptor/AbstractTraceeOutInterceptor.java<|end_filename|>
package io.tracee.binding.cxf.interceptor;

import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.configuration.TraceeFilterConfiguration;
import io.tracee.transport.HttpHeaderTransport;
import io.tracee.transport.jaxb.TpicMap;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.jaxb.JAXBDataBinding;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.bind.JAXBException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

abstract class AbstractTraceeOutInterceptor extends AbstractPhaseInterceptor<Message> {

	private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTraceeOutInterceptor.class);

	protected final TraceeBackend backend;

	private final HttpHeaderTransport httpSerializer;
	private final TraceeFilterConfiguration.Channel channel;

	private String profile;

	public AbstractTraceeOutInterceptor(String phase, TraceeFilterConfiguration.Channel channel, TraceeBackend backend, String profile) {
		super(phase);
		this.channel = channel;
		this.backend = backend;
		this.profile = profile;
		this.httpSerializer = new HttpHeaderTransport();
	}

	@Override
	public void handleMessage(final Message message) {
		if (shouldHandleMessage(message)) {
			final TraceeFilterConfiguration filterConfiguration = backend.getConfiguration(profile);
			if (!backend.isEmpty() && filterConfiguration.shouldProcessContext(channel)) {
				final Map<String, String> filteredParams = filterConfiguration.filterDeniedParams(backend.copyToMap(), channel);

				LOGGER.debug("Interceptor handles message!");
				if (Boolean.TRUE.equals(message.getExchange().get(Message.REST_MESSAGE))) {
					Map<String, List<String>> responseHeaders = CastUtils.cast((Map<?, ?>) message.get(Message.PROTOCOL_HEADERS));
					if (responseHeaders == null) {
						responseHeaders = new HashMap<>();
						message.put(Message.PROTOCOL_HEADERS, responseHeaders);
					}

					final String contextAsHeader = httpSerializer.render(filteredParams);
					responseHeaders.put(TraceeConstants.TPIC_HEADER, Collections.singletonList(contextAsHeader));
				} else {
					try {
						final SoapMessage soapMessage = (SoapMessage) message;
						addSoapHeader(filteredParams, soapMessage);
					} catch (NoClassDefFoundError e) {
						LOGGER.error("Should handle SOAP-message but it seems that cxf soap dependency is not on the classpath. Unable to add Tracee-Headers: {}", e.getMessage(), e);
					}
				}
			}
		}
	}

	private void addSoapHeader(Map<String, String> filteredParams, SoapMessage soapMessage) {
		try {
			final Header tpicHeader = new Header(TraceeConstants.SOAP_HEADER_QNAME, TpicMap.wrap(filteredParams),
				new JAXBDataBinding(TpicMap.class));
			soapMessage.getHeaders().add(tpicHeader);
		} catch (JAXBException e) {
			LOGGER.warn("Error occured during TracEE soap header creation: {}", e.getMessage());
			LOGGER.debug("Detailed exception", e);
		}
	}

	protected abstract boolean shouldHandleMessage(Message message);
}


<|start_filename|>backend/threadlocal-store/src/test/java/io/tracee/backend/threadlocalstore/ThreadLocalContextProviderIT.java<|end_filename|>
package io.tracee.backend.threadlocalstore;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import org.hamcrest.Matchers;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

public class ThreadLocalContextProviderIT {

	@Test
	public void shouldDetectThreadLocalStoreBySPI() {
		final TraceeBackend context = Tracee.getBackend();
		assertThat(context, Matchers.instanceOf(ThreadLocalTraceeBackend.class));
	}

	@Test
	public void testLoadProvierThenStoreAndRetrieve() {
		final TraceeBackend context = Tracee.getBackend();
		context.put("FOO", "BAR");
		assertThat(context.get("FOO"), equalTo("BAR"));
		context.clear();
	}
}


<|start_filename|>backend/threadlocal-store/src/test/java/io/tracee/backend/threadlocalstore/ThreadLocalTraceeBackendTest.java<|end_filename|>
package io.tracee.backend.threadlocalstore;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.is;

public class ThreadLocalTraceeBackendTest {

	private ThreadLocalTraceeBackend unit = new ThreadLocalTraceeBackend();

	@Test
	public void testStoredKeys() {
		unit.clear();
		assertThat(unit.size(), equalTo(0));
		unit.put("FOO", "BAR");
		assertThat(unit.get("FOO"), equalTo("BAR"));
		assertThat(unit.size(), equalTo(1));
	}

	@Test
	public void testExtractContext() {
		unit.put("FUBI", "BARBI");
		assertThat(unit.get("FUBI"), is("BARBI"));
	}

	@Test
	public void ifTheSizeIsZeroTheBackendShouldBeEmpty() {
		assertThat(unit.size(), is(0));
		assertThat(unit.isEmpty(), is(true));
	}

	@Test
	public void ifTheSizeIsNotZeroTheBackendShouldNotBeEmpty() {
		unit.put("test", "testVal");
		assertThat(unit.size(), is(1));
		assertThat(unit.isEmpty(), is(false));
	}

	@Test
	public void copyToMapShouldCopyContentToNewMap() {
		unit.put("test1", "testVal1");
		unit.put("test2", "testVal2");
		final Map<String, String> mapCopy = unit.copyToMap();
		assertThat(mapCopy, hasEntry("test1", "testVal1"));
		assertThat(mapCopy, hasEntry("test2", "testVal2"));
		assertThat(mapCopy.size(), is(2));
	}

	@Test
	public void copiedMapsDoNotEffektEachOther() {
		unit.put("test1", "testVal1");
		final Map<String, String> mapCopy = unit.copyToMap();
		assertThat(mapCopy, hasEntry("test1", "testVal1"));
		unit.put("newKey2", "newVal2");
		assertThat(mapCopy.size(), is(1));
		assertThat(unit.size(), is(2));

		mapCopy.put("anotherKey", "anotherValue");
		assertThat(unit.containsKey("anotherKey"), is(false));
	}

	@Test
	public void putAllMethodAddsAllElementsOfGivenMap() {
		final Map<String, String> givenMap = new HashMap<>();
		givenMap.put("key1", "value1");
		givenMap.put("key2", "value2");
		unit.putAll(givenMap);
		assertThat(unit.size(), is(2));
		assertThat(unit.containsKey("key1"), is(true));
		assertThat(unit.containsKey("key2"), is(true));
	}


}


<|start_filename|>api/src/test/java/io/tracee/BackendProviderSetTest.java<|end_filename|>
package io.tracee;

import io.tracee.spi.TraceeBackendProvider;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.internal.util.collections.Sets;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;

import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.util.Set;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mock;
import static org.powermock.api.mockito.PowerMockito.whenNew;

@RunWith(PowerMockRunner.class)
@PrepareForTest(BackendProviderSet.class)
public class BackendProviderSetTest {

	@Test
	public void shouldReturnSize() {
		final Set<TraceeBackendProvider> providers = Sets.newSet(mock(TraceeBackendProvider.class), mock(TraceeBackendProvider.class));
		final BackendProviderSet out = new BackendProviderSet(providers);

		assertThat(out.size(), equalTo(2));
	}

	@Test
	public void shouldReturnMyValues() {
		final TraceeBackendProvider mockedBackend1 = mock(TraceeBackendProvider.class);
		final TraceeBackendProvider mockedBackend2 = mock(TraceeBackendProvider.class);
		final Set<TraceeBackendProvider> providers = Sets.newSet(mockedBackend1, mockedBackend2);
		final BackendProviderSet out = new BackendProviderSet(providers);

		assertThat(out, containsInAnyOrder(mockedBackend1, mockedBackend2));
	}

	@Test
	public void shouldHandleEmptySet() {
		final Set<TraceeBackendProvider> providers = Sets.newSet();
		final BackendProviderSet out = new BackendProviderSet(providers);

		assertThat(out.size(), equalTo(0));
	}

	@Test
	public void shouldReturnEmptySetIfOneElementWasDetached() throws Exception {
		final BackendProviderSet traceeBackendProviders = buildProviderSetWithOneDetachedProvider();
		assertThat(traceeBackendProviders.size(), equalTo(0));
	}

	@Test
	public void shouldReturnEmptyIteratorIfOneElementWasDetached() throws Exception {
		// Setup Set and ask for size - then we extract the 'valid' field to check that the set is marked as invalid
		final BackendProviderSet traceeBackendProviders = buildProviderSetWithOneDetachedProvider();
		assertThat(traceeBackendProviders.iterator().hasNext(), equalTo(false));
	}

	@Test
	public void backendProviderSetShouldInternallyInvalidateState() throws Exception {
		// Setup Set and ask for size - then we extract the 'valid' field to check that the set is marked as invalid
		final BackendProviderSet traceeBackendProviders = buildProviderSetWithOneDetachedProvider();
		final Field validField = Whitebox.getField(BackendProviderSet.class, "valid");
		// We've to call method that triggers validation.
		traceeBackendProviders.size();
		assertThat(validField.getBoolean(traceeBackendProviders), is(false));
		// Let's call it again to ensure that the state is not changed again (and to widen test coverage)
		traceeBackendProviders.size();
		assertThat(validField.getBoolean(traceeBackendProviders), is(false));
	}

	private BackendProviderSet buildProviderSetWithOneDetachedProvider() throws Exception {
		final TraceeBackendProvider mockedBackend1 = mock(TraceeBackendProvider.class);
		final TraceeBackendProvider mockedBackend2 = mock(TraceeBackendProvider.class);

		// Simulate a SoftReference with an empty value. (The powermock-method withArgument(..) don't work here!)
		final SoftReference backendRef1 = new SoftReference<>(mockedBackend1);
		final SoftReference backendRef2 = new SoftReference<>(null);
		whenNew(SoftReference.class).withAnyArguments().thenReturn(backendRef1, backendRef2);

		// Setup Set and ask for size - then we extract the 'valid' field to check that the set is marked as invalid
		return new BackendProviderSet(Sets.newSet(mockedBackend1, mockedBackend2));
	}
}


<|start_filename|>core/src/main/java/io/tracee/Utilities.java<|end_filename|>
package io.tracee;

import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

public final class Utilities {

	private static final char[] ALPHANUMERICS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();

	public static final Charset CHARSET_UTF8 = Charset.forName("UTF-8");

	private Utilities() {
		// hide constructor
	}

	public static boolean isNullOrEmptyString(final String value) {
		return value == null || value.trim().isEmpty();
	}

	/**
	 * Creates a random Strings consisting of alphanumeric characters with a length of 32.
	 */
	public static String createRandomAlphanumeric(final int length) {
		final Random r = ThreadLocalRandom.current();
		final char[] randomChars = new char[length];
		for (int i = 0; i < length; ++i) {
			randomChars[i] = ALPHANUMERICS[r.nextInt(ALPHANUMERICS.length)];
		}
		return new String(randomChars);
	}

	/**
	 * Creates a alphanumeric projection with a given length of the given object using its {@link Object#hashCode()}.
	 */
	public static String createAlphanumericHash(final String str, final int length) {
		try {
			final MessageDigest md = MessageDigest.getInstance("SHA-256");
			final byte[] digest = md.digest(str.getBytes(CHARSET_UTF8));
			// To human
			final StringBuilder sb = new StringBuilder();
			for (final byte b : digest) {
				if (b < 16) sb.append("0");
				sb.append(Integer.toHexString(b & 0xff));
			}
			// repeat if to small
			while (sb.length() < length) {
				sb.append(sb.toString());
			}
			// truncation and return
			return sb.delete(length, sb.length()).toString();
		} catch (NoSuchAlgorithmException | UnsupportedCharsetException e) {
			// Hashalgo. and charset is mandatory for all kinds of JDK, so this should happend. But even when, we generate a random string.
			return createRandomAlphanumeric(length);
		}
	}

	/**
	 * Generate invocation id if it doesn't exist in TraceeBackend and configuration asks for one
	 *
	 * @param backend Currently used TraceeBackend
	 */
	public static void generateInvocationIdIfNecessary(final TraceeBackend backend) {
		if (backend != null && !backend.containsKey(TraceeConstants.INVOCATION_ID_KEY) && backend.getConfiguration().shouldGenerateInvocationId()) {
			backend.put(TraceeConstants.INVOCATION_ID_KEY, Utilities.createRandomAlphanumeric(backend.getConfiguration().generatedInvocationIdLength()));
		}
	}

	/**
	 * Generate session id hash if it doesn't exist in TraceeBackend and configuration asks for one
	 *
	 * @param backend   Currently used TraceeBackend
	 * @param sessionId Current http sessionId
	 */
	public static void generateSessionIdIfNecessary(final TraceeBackend backend, final String sessionId) {
		if (backend != null && !backend.containsKey(TraceeConstants.SESSION_ID_KEY) && backend.getConfiguration().shouldGenerateSessionId()) {
			backend.put(TraceeConstants.SESSION_ID_KEY, Utilities.createAlphanumericHash(sessionId, backend.getConfiguration().generatedSessionIdLength()));
		}
	}
}


<|start_filename|>binding/springmvc/src/test/java/io/tracee/binding/springmvc/itests/TraceeInterceptorRestIT.java<|end_filename|>
package io.tracee.binding.springmvc.itests;

import io.tracee.Tracee;
import io.tracee.TraceeConstants;
import io.tracee.binding.springhttpclient.TraceeClientHttpRequestInterceptor;
import org.junit.Before;
import org.junit.Test;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collections;
import java.util.UUID;

import static io.tracee.TraceeConstants.TPIC_HEADER;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

public class TraceeInterceptorRestIT extends WebIntegrationIT {

	private RestTemplate restTemplate = new RestTemplate();

	@Before
	public void configureTestTemplate() {
		restTemplate = new RestTemplate();
		restTemplate.setInterceptors(Collections.<ClientHttpRequestInterceptor>singletonList(new TraceeClientHttpRequestInterceptor()));
	}

	@Test
	public void jsonControllerShouldReceiveTraceeHeader() throws IOException {
		Tracee.getBackend().put(TraceeConstants.INVOCATION_ID_KEY, "myValue");
		final SillyRestBody sillyBody = restTemplate.getForEntity(ENDPOINT_URL + "nameNeedTraceeId/sven", SillyRestBody.class).getBody();
		assertThat(sillyBody.getReceivedTraceeId(), is("myValue"));
	}

	@Test
	public void jsonControllerShouldSendTraceeHeader() throws IOException {
		final ResponseEntity<SillyRestBody> entity = restTemplate.getForEntity(ENDPOINT_URL + "name/sven", SillyRestBody.class);
		assertThat(entity.getHeaders().containsKey(TraceeConstants.TPIC_HEADER), is(true));
		assertThat(entity.getHeaders().get(TraceeConstants.TPIC_HEADER).get(0), containsString(TraceeConstants.INVOCATION_ID_KEY));
	}

	@Test
	public void ensureSameValueIsReceivedAndTransmittedBack() throws IOException {
		Tracee.getBackend().put(TraceeConstants.INVOCATION_ID_KEY, "myMegaValue");

		final ResponseEntity<SillyRestBody> entity = restTemplate.getForEntity(ENDPOINT_URL + "nameNeedTraceeId/daniel", SillyRestBody.class);
		final SillyRestBody sillyBody = entity.getBody();
		assertThat(sillyBody.getReceivedTraceeId(), is("myMegaValue"));
		assertThat(entity.getHeaders().get(TraceeConstants.TPIC_HEADER).get(0), containsString(TraceeConstants.INVOCATION_ID_KEY + "=myMegaValue"));
	}

	@Test
	public void withResponseBodyAdviceNewValuesShouldReceivedAsWell() {
		Tracee.getBackend().put(TraceeConstants.INVOCATION_ID_KEY, "myMegaValue");

		final ResponseEntity<SillyRestBody> entity = restTemplate.getForEntity(ENDPOINT_URL + "nameNeedTraceeId/daniel", SillyRestBody.class);
		assertThat(entity.getHeaders().get(TraceeConstants.TPIC_HEADER).get(0), containsString("laterKey=myLaterValue"));
	}

	@RestController
	public static class SillyRestController {

		@RequestMapping("/nameNeedTraceeId/{name}")
		public SillyRestBody nameNeedTraceeId(@PathVariable String name, HttpServletRequest request) {
			if (request.getHeader(TPIC_HEADER) == null) {
				throw new AssertionError("No expected Header " + TPIC_HEADER + " in request set");
			}
			return name(name);
		}

		@RequestMapping("/name/{name}")
		public SillyRestBody name(@PathVariable String name) {
			Tracee.getBackend().put("laterKey", "myLaterValue");
			return new SillyRestBody(name, Tracee.getBackend().getInvocationId());
		}
	}

	static class SillyRestBody {

		private String name;

		private String receivedTraceeId;

		private String makeItLage;

		public SillyRestBody() {
			makeItLage = createLargeBody();
		}

		private String createLargeBody() {
			final StringBuilder sb = new StringBuilder();
			for (int i = 0; i < 100; i++) {
				sb.append(UUID.randomUUID().toString());
			}
			return sb.toString();
		}

		public SillyRestBody(String name, String receivedTraceeId) {
			this();
			this.name = name;
			this.receivedTraceeId = receivedTraceeId;
		}

		public String getName() {
			return name;
		}

		public String getMakeItLage() {
			return makeItLage;
		}

		public String getReceivedTraceeId() {
			return receivedTraceeId;
		}
	}
}


<|start_filename|>binding/quartz/src/test/java/io/tracee/binding/quartz/TraceeContextInjectorTest.java<|end_filename|>
package io.tracee.binding.quartz;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.configuration.TraceeFilterConfiguration.Profile;
import io.tracee.testhelper.FieldAccessUtil;
import io.tracee.testhelper.SimpleTraceeBackend;
import org.junit.Test;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;

import java.util.Map;

import static io.tracee.TraceeConstants.TPIC_HEADER;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.is;

@SuppressWarnings("unchecked")
public class TraceeContextInjectorTest {

	private final TraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();

	private TraceeContextInjector unit = new TraceeContextInjector(backend, Profile.DEFAULT);

	@Test
	public void skipTpicProcessingIfBackendIsEmpty() {
		final JobDataMap dataMap = new JobDataMap();
		unit.injectContext(dataMap);
		assertThat(dataMap.size(), is(0));
	}

	@Test
	public void addTpicHeaderToJobDataMapIfBackendContainsValues() {
		backend.put("testKey", "testValue");
		final JobDataMap dataMap = new JobDataMap();
		unit.injectContext(dataMap);
		assertThat(dataMap, hasKey(TPIC_HEADER));
		assertThat((Map<String, String>) dataMap.get(TPIC_HEADER), hasEntry("testKey", "testValue"));
	}

	@Test
	public void addTpicHeaderToJobDataMapOfTriggerIfBackendContainsValues() {
		backend.put("testKey", "testValue");
		final Trigger trigger = TriggerBuilder.newTrigger().build();
		unit.injectContext(trigger);
		assertThat(trigger.getJobDataMap(), hasKey(TPIC_HEADER));
		assertThat((Map<String, String>) trigger.getJobDataMap().get(TPIC_HEADER), hasEntry("testKey", "testValue"));
	}

	@Test
	public void addTpicHeaderToJobDataMapOfJobDetailsIfBackendContainsValues() {
		backend.put("testKey", "testValue");
		final JobDetail jobDetail = JobBuilder.newJob(NoopJob.class).build();
		unit.injectContext(jobDetail);
		assertThat(jobDetail.getJobDataMap(), hasKey(TPIC_HEADER));
		assertThat((Map<String, String>) jobDetail.getJobDataMap().get(TPIC_HEADER), hasEntry("testKey", "testValue"));
	}

	@Test
	public void defaultConstructorUsesDefaultProfile() {
		final TraceeContextInjector injector = new TraceeContextInjector();
		assertThat((String) FieldAccessUtil.getFieldVal(injector, "profile"), is(Profile.DEFAULT));
	}

	@Test
	public void defaultConstructorUsesTraceeBackend() {
		final TraceeContextInjector injector = new TraceeContextInjector();
		assertThat((TraceeBackend) FieldAccessUtil.getFieldVal(injector, "backend"), is(Tracee.getBackend()));
	}

	@Test
	public void constructorStoresProfileNameInternal() {
		final TraceeContextInjector injector = new TraceeContextInjector("testProf");
		assertThat((String) FieldAccessUtil.getFieldVal(injector, "profile"), is("testProf"));
	}

	static class NoopJob implements Job {
		@Override
		public void execute(JobExecutionContext context) throws JobExecutionException {
			// noop
		}
	}
}


<|start_filename|>core/src/test/java/io/tracee/backend/slf4j/Slf4jTraceeBackendIT.java<|end_filename|>
package io.tracee.backend.slf4j;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;

public class Slf4jTraceeBackendIT {

	@Test
	public void traceeShouldReturnSlf4JBackendByDefault() {
		assertThat(Tracee.getBackend(), is(instanceOf(TraceeBackend.class)));
	}

	@Test
	public void shouldReturnAlwaystheSameDefaultBackend() {
		final TraceeBackend backend = Tracee.getBackend();
		assertThat(Tracee.getBackend(), is(sameInstance(backend)));
	}
}


<|start_filename|>backend/threadlocal-store/src/main/java/io/tracee/backend/threadlocalstore/ThreadLocalTraceeBackendProvider.java<|end_filename|>
package io.tracee.backend.threadlocalstore;

import io.tracee.TraceeBackend;
import io.tracee.spi.TraceeBackendProvider;

public class ThreadLocalTraceeBackendProvider implements TraceeBackendProvider {

	private final ThreadLocalTraceeBackend backend = new ThreadLocalTraceeBackend();

	@Override
	public final TraceeBackend provideBackend() {
		return backend;
	}

}


<|start_filename|>binding/jms/src/main/java/io/tracee/binding/jms/TraceeMessageListener.java<|end_filename|>
package io.tracee.binding.jms;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.Utilities;
import io.tracee.transport.HttpHeaderTransport;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
import javax.jms.JMSException;
import javax.jms.Message;
import java.lang.reflect.Method;
import java.util.Map;

import static io.tracee.configuration.TraceeFilterConfiguration.Channel.AsyncProcess;
import static java.util.Collections.singletonList;

/**
 * EJB interceptor that parses a TracEE context from message properties and cleans it after message processing.
 */
public final class TraceeMessageListener {

	private final TraceeBackend backend;

	private final HttpHeaderTransport httpHeaderSerialization;

	TraceeMessageListener(TraceeBackend backend) {
		this.backend = backend;
		this.httpHeaderSerialization = new HttpHeaderTransport();
	}

	@SuppressWarnings("unused")
	public TraceeMessageListener() {
		this(Tracee.getBackend());
	}

	@AroundInvoke
	public Object intercept(final InvocationContext ctx) throws Exception {
		final boolean isMdbInvocation = isMessageListenerOnMessageMethod(ctx.getMethod());
		try {
			if (isMdbInvocation) {
				beforeProcessing(extractMessageParameter(ctx.getParameters()));
			}
			return ctx.proceed();
		} finally {
			if (isMdbInvocation) {
				cleanUp();
			}
		}
	}

	@SuppressWarnings("unchecked")
	public void beforeProcessing(final Message message) throws JMSException {

		if (backend.getConfiguration().shouldProcessContext(AsyncProcess)) {
			final String encodedTraceeContext = message.getStringProperty(TraceeConstants.TPIC_HEADER);
			if (encodedTraceeContext != null) {
				final Map<String, String> contextFromMessage = httpHeaderSerialization.parse(singletonList(encodedTraceeContext));
				backend.putAll(backend.getConfiguration().filterDeniedParams(contextFromMessage, AsyncProcess));
			}
		}

		Utilities.generateInvocationIdIfNecessary(backend);
	}

	void cleanUp() {
		if (backend.getConfiguration().shouldProcessContext(AsyncProcess)) {
			backend.clear();
		}
	}

	Message extractMessageParameter(final Object[] parameters) {
		return (Message) parameters[0];
	}

	boolean isMessageListenerOnMessageMethod(final Method method) {
		return "onMessage".equals(method.getName())
			&& method.getParameterTypes().length == 1
			&& method.getParameterTypes()[0] == Message.class;
	}
}


<|start_filename|>core/src/test/java/io/tracee/transport/SoapHeaderTransportTest.java<|end_filename|>
package io.tracee.transport;

import io.tracee.TraceeConstants;
import io.tracee.transport.jaxb.TpicMap;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

public class SoapHeaderTransportTest {

	private final SoapHeaderTransport unit = new SoapHeaderTransport();
	private SOAPMessage soapMessage;

	@Before
	public void setUp() throws SOAPException {
		this.soapMessage = MessageFactory.newInstance().createMessage();
	}

	@Test
	public void renderTpicHeaderToSoapMessage() throws SOAPException {
		final Map<String, String> context = Collections.singletonMap("FOO", "BAR");
		final SOAPHeader soapHeader = soapMessage.getSOAPHeader();

		unit.renderSoapHeader(context, soapHeader);
		final Iterator soapHeaders = soapHeader.getChildElements(TraceeConstants.SOAP_HEADER_QNAME);

		final Element tpicHeader = (Element) soapHeaders.next();
		assertThat(tpicHeader.getLocalName(), is(TraceeConstants.TPIC_HEADER));
		assertThat(tpicHeader.getNamespaceURI(), is(TraceeConstants.SOAP_HEADER_NAMESPACE));
		assertThat(tpicHeader.getFirstChild().getLocalName(), is("entry"));
		assertThat(tpicHeader.getFirstChild().getAttributes().getNamedItem("key").getNodeValue(), is("FOO"));
		assertThat(tpicHeader.getFirstChild().getFirstChild().getNodeValue(), is("BAR"));
	}

	@Test
	public void parseSoapHeaderWithOneTPICHeader() throws SOAPException, JAXBException {
		final TpicMap tpicMap = TpicMap.wrap(Collections.singletonMap("FOooo", "Bar2"));
		JAXBContext.newInstance(TpicMap.class).createMarshaller().marshal(tpicMap, soapMessage.getSOAPHeader());

		final Map<String, String> parse = unit.parseSoapHeader(soapMessage.getSOAPHeader());
		assertThat(parse, hasEntry("FOooo", "Bar2"));
	}

	@Test
	public void parseSoapHeaderWithMultipleTPICHeader() throws SOAPException, JAXBException {
		final TpicMap tpicMap = TpicMap.wrap(Collections.singletonMap("FOooo", "Bar2"));
		final TpicMap tpicMap2 = TpicMap.wrap(Collections.singletonMap("FOooo2", "Bar3"));
		JAXBContext.newInstance(TpicMap.class).createMarshaller().marshal(tpicMap, soapMessage.getSOAPHeader());
		JAXBContext.newInstance(TpicMap.class).createMarshaller().marshal(tpicMap2, soapMessage.getSOAPHeader());

		final Map<String, String> parse = unit.parseSoapHeader(soapMessage.getSOAPHeader());
		assertThat(parse, hasEntry("FOooo", "Bar2"));
		assertThat(parse, hasEntry("FOooo2", "Bar3"));
	}

	@Test
	public void parseSoapHeaderToEmptyMapIfNotParsable() throws SOAPException {
		assertThat(unit.parseSoapHeader(soapMessage.getSOAPHeader()), equalTo(Collections.<String, String>emptyMap()));
	}

	@Test
	public void parseTpicHeaderToEmptyMapIfNotParsable() throws SOAPException {
		assertThat(unit.parseTpicHeader(soapMessage.getSOAPHeader()), equalTo(Collections.<String, String>emptyMap()));
	}

	@Test
	public void parseTpicHeaderToEmptyMapIfNoTraceeHeaderIsPresent() throws SOAPException {
		final Map<String, String> context = Collections.emptyMap();
		final SOAPHeader soapHeader = soapMessage.getSOAPHeader();

		unit.renderSoapHeader(context, soapHeader);
		assertThat(unit.parseTpicHeader(soapHeader), equalTo(Collections.<String, String>emptyMap()));
	}

	@Test
	public void readRealXmlMessageAndParseHeader() throws ParserConfigurationException, IOException, SAXException {
		final InputStream xmlDoc = ClassLoader.getSystemResourceAsStream("io/tracee/transport/jaxws-output.xml");

		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		dbFactory.setNamespaceAware(true);
		Document doc = dbFactory.newDocumentBuilder().parse(xmlDoc);
		Element envelope = (Element) doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/soap/envelope/", "Envelope").item(0);
		Element header = (Element) envelope.getElementsByTagNameNS("http://schemas.xmlsoap.org/soap/envelope/", "Header").item(0);
		Map<String, String> parsedContextParams = unit.parseSoapHeader(header);
		assertThat(parsedContextParams, hasEntry(TraceeConstants.INVOCATION_ID_KEY, "<KEY>"));
	}

	@Test
	public void renderTpicContextToResult() {
		final Map<String, String> context = new HashMap<>();
		context.put("myKey", "myValue");
		context.put("myKey2", "myValue2");

		final StringWriter writer = new StringWriter();
		unit.renderSoapHeader(context, new StreamResult(writer));
		assertThat(writer.toString(), containsString("<entry key=\"myKey\">myValue</entry>"));
		assertThat(writer.toString(), containsString("<entry key=\"myKey2\">myValue2</entry>"));
	}

	@Test
	public void returnEmptyMapIfSourceIsNull() {
		final Map<String, String> stringStringMap = unit.parseTpicHeader((Source) null);
		assertThat(stringStringMap.size(), is(0));
	}

	@Test
	public void parseSourceIntoTpicMap() {
		final String header = "<tpic xmlns=\"http://tracee.io/tpic/1.0\"><entry key=\"myKey\">myValue</entry></tpic>";

		final Map<String, String> contextMap = unit.parseTpicHeader(new StreamSource(new StringReader(header)));
		assertThat(contextMap, hasEntry("myKey", "myValue"));
		assertThat(contextMap.size(), is(1));
	}

	@Test
	public void serializeDeserializerTestWithResultAndSource() {
		final Map<String, String> initContext = new HashMap<>();
		initContext.put("our key1", "our value1");
		initContext.put("our key2", "our value2");
		final StringWriter writer = new StringWriter();
		unit.renderSoapHeader(initContext, new StreamResult(writer));
		final Map<String, String> assertContext = unit.parseTpicHeader(new StreamSource(new StringReader(writer.toString())));
		assertThat(assertContext, Matchers.is(initContext));
	}
}


<|start_filename|>api/src/main/java/io/tracee/spi/TraceeBackendProvider.java<|end_filename|>
package io.tracee.spi;

import io.tracee.TraceeBackend;

public interface TraceeBackendProvider {

	TraceeBackend provideBackend();

}


<|start_filename|>api/src/test/java/io/tracee/BackendProviderResolverGetClassLoaderTest.java<|end_filename|>
package io.tracee;


import org.junit.After;
import org.junit.Test;

import java.security.Permission;

import static io.tracee.BackendProviderResolver.GetClassLoader;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

public class BackendProviderResolverGetClassLoaderTest {

	@Test
	public void shouldFetchContextClassloaderWithoutSecurityManager() {
		System.setSecurityManager(null);
		final ClassLoader cl = GetClassLoader.fromContext();
		assertThat(cl, is(this.getClass().getClassLoader()));
	}

	@Test
	public void shouldReturnClassloaderOfClassWithoutSecurityManager() {
		System.setSecurityManager(null);
		final ClassLoader cl = GetClassLoader.fromClass(this.getClass());
		assertThat(cl, is(this.getClass().getClassLoader()));
	}

	@Test
	public void shouldFetchContextClassloaderWithSecurityManager() {
		System.setSecurityManager(new TestSecurityManager());
		final ClassLoader cl = GetClassLoader.fromContext();
		assertThat(cl, is(this.getClass().getClassLoader()));
	}

	@Test
	public void shouldReturnClassloaderOfClassWithSecurityManager() {
		System.setSecurityManager(new TestSecurityManager());
		final ClassLoader cl = GetClassLoader.fromClass(this.getClass());
		assertThat(cl, is(this.getClass().getClassLoader()));
	}

	@Test(expected = IllegalArgumentException.class)
	public void shouldThrowIAEifClassNull() {
		GetClassLoader.fromClass(null);
	}

	@After
	public void after() {
		System.setSecurityManager(null);
	}

	private class TestSecurityManager extends SecurityManager {
		@Override
		public void checkPermission(Permission perm) {
		}
	}
}


<|start_filename|>binding/springrabbitmq/src/test/java/io/tracee/binding/springrabbitmq/TraceeMessagePropertiesConverterTest.java<|end_filename|>
package io.tracee.binding.springrabbitmq;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.LongString;
import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.configuration.TraceeFilterConfiguration;
import io.tracee.testhelper.FieldAccessUtil;
import io.tracee.testhelper.SimpleTraceeBackend;
import org.hamcrest.MatcherAssert;
import org.junit.Test;
import org.springframework.amqp.core.MessageProperties;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import static io.tracee.TraceeConstants.INVOCATION_ID_KEY;
import static io.tracee.TraceeConstants.TPIC_HEADER;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.collection.IsMapContaining.hasEntry;
import static org.mockito.Mockito.mock;

public class TraceeMessagePropertiesConverterTest {
	private static final String USED_PROFILE = "A_PROFILE";
	private static final String CHARSET_UTF8 = "UTF-8";
	private final TraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();

	private final TraceeMessagePropertiesConverter unit = new TraceeMessagePropertiesConverter(backend, USED_PROFILE);

	@Test
	public void shouldAddTraceeContexttoMessageHeaders() throws Exception {
		backend.put("inClientBeforeRequest", "true");

		MessageProperties messageProperties = new MessageProperties();
		final AMQP.BasicProperties basicProperties = unit.fromMessageProperties(messageProperties, CHARSET_UTF8);

		assertThat(basicProperties.getHeaders(), hasKey(TPIC_HEADER));
		assertThat((Map<String, ?>) basicProperties.getHeaders().get(TPIC_HEADER), hasKey("inClientBeforeRequest"));
	}

	@Test
	public void messageParserShouldHandleMissingTpicHeaderAndGenerateInvocationId() {
		unit.toMessageProperties(createRabbitHeaderWith("anyKey", "anyValue"), mock(Envelope.class), CHARSET_UTF8);
		assertThat(backend.copyToMap(), hasKey(TraceeConstants.INVOCATION_ID_KEY));
	}

	@Test
	public void parseMessageHeaderIntoBackend() throws Exception {
		final Map<String, LongString> rabbitTraceeHeader = new HashMap<>();
		rabbitTraceeHeader.put(INVOCATION_ID_KEY, new TestLongString("Crazy ID"));

		unit.toMessageProperties(createRabbitHeaderWith(TPIC_HEADER, rabbitTraceeHeader), mock(Envelope.class), CHARSET_UTF8);

		assertThat(backend.copyToMap(), hasEntry(INVOCATION_ID_KEY, "Crazy ID"));
	}

	@Test
	public void noTraceeHeaderShouldResultInGeneratedRequestId() throws Exception {
		unit.toMessageProperties(createRabbitHeaderWith("someHeader", "fromResponse=true"), mock(Envelope.class), CHARSET_UTF8);

		assertThat(backend.copyToMap(), hasKey(INVOCATION_ID_KEY));
		assertThat(backend.size(), is(1));
	}

	@Test
	public void roundTripShouldWorkAndGenerateRequestId() throws Exception {
		backend.put("inClientBeforeRequest", "true");

		MessageProperties messageProperties = new MessageProperties();
		final AMQP.BasicProperties basicProperties = unit.fromMessageProperties(messageProperties, CHARSET_UTF8);
		backend.clear();

		unit.toMessageProperties(basicProperties, mock(Envelope.class), CHARSET_UTF8);

		assertThat(backend.copyToMap(), hasEntry("inClientBeforeRequest", "true"));
		assertThat(backend.copyToMap(), hasKey(INVOCATION_ID_KEY));
		assertThat(backend.size(), is(2));
	}

	@Test
	public void defaultConstructorUsesDefaultProfile() {
		final TraceeMessagePropertiesConverter converter = new TraceeMessagePropertiesConverter();
		MatcherAssert.assertThat((String) FieldAccessUtil.getFieldVal(converter, "profile"), is(TraceeFilterConfiguration.Profile.DEFAULT));
	}

	@Test
	public void defaultConstructorUsesTraceeBackend() {
		final TraceeMessagePropertiesConverter converter = new TraceeMessagePropertiesConverter();
		MatcherAssert.assertThat((TraceeBackend) FieldAccessUtil.getFieldVal(converter, "backend"), is(Tracee.getBackend()));
	}

	@Test
	public void constructorStoresProfileNameInternal() {
		final TraceeMessagePropertiesConverter converter = new TraceeMessagePropertiesConverter("testProf");
		MatcherAssert.assertThat((String) FieldAccessUtil.getFieldVal(converter, "profile"), is("testProf"));
	}

	private AMQP.BasicProperties createRabbitHeaderWith(final String key, final Object value) {
		return new AMQP.BasicProperties().builder().headers(new HashMap<String, Object>() {{
			put(key, value);
		}}).build();
	}

	// Because LongStringHelper.ByteArrayLongString is private ..
	private class TestLongString implements LongString {

		private final String value;

		public TestLongString(String value) {
			this.value = value;
		}

		@Override
		public long length() {
			return value.length();
		}

		@Override
		public DataInputStream getStream() throws IOException {
			return new DataInputStream(new ByteArrayInputStream(getBytes()));
		}

		@Override
		public byte[] getBytes() {
			try {
				return value.getBytes(CHARSET_UTF8);
			} catch (UnsupportedEncodingException e) {
				throw new RuntimeException(e);
			}
		}

		@Override
		public String toString() {
			return value;
		}
	}
}


<|start_filename|>core/src/main/java/io/tracee/backend/slf4j/Slf4jTraceeBackend.java<|end_filename|>
package io.tracee.backend.slf4j;

import io.tracee.BackendBase;
import org.slf4j.MDC;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

class Slf4jTraceeBackend extends BackendBase {

	/**
	 * This set contains all MDC-Keys managed by tracee.
	 * This bookkeeping is required to ensure that operations like {@link Slf4jTraceeBackend#clear()} do not remove
	 * TracEE unrelated keys from the MDC.
	 */
	protected final ThreadLocal<Set<String>> traceeKeys;

	Slf4jTraceeBackend(ThreadLocal<Set<String>> traceeKeys) {
		this.traceeKeys = traceeKeys;
	}

	@Override
	public boolean containsKey(String key) {
		return key != null && traceeKeys.get().contains(key) && MDC.get(key) != null;
	}

	@Override
	public int size() {
		return traceeKeys.get().size();
	}

	@Override
	public boolean isEmpty() {
		return traceeKeys.get().isEmpty();
	}

	@Override
	public String get(String key) {
		if ((key != null) && traceeKeys.get().contains(key))
			return MDC.get(key);
		else
			return null;
	}

	@Override
	public void put(String key, String value) throws IllegalArgumentException {
		if (key == null) throw new IllegalArgumentException("null keys are not allowed.");
		if (value == null) throw new IllegalArgumentException("null values are not allowed.");
		final Set<String> registeredKeys = traceeKeys.get();
		if (!registeredKeys.contains(key)) {
			registeredKeys.add(key);
		}
		MDC.put(key, value);
	}

	@Override
	public void remove(String key) throws IllegalArgumentException {
		if (key == null) throw new IllegalArgumentException("null keys are not allowed.");
		if (traceeKeys.get().remove(key)) {
			MDC.remove(key);
		}
	}

	@Override
	public void clear() {
		for (String key : traceeKeys.get()) {
			MDC.remove(key);
		}
		traceeKeys.remove();
	}

	@Override
	public void putAll(Map<? extends String, ? extends String> entries) {
		for (Map.Entry<? extends String, ? extends String> entry : entries.entrySet()) {
			put(entry.getKey(), entry.getValue());
		}
	}

	@Override
	public Map<String, String> copyToMap() {
		final Map<String, String> traceeMap = new HashMap<>();
		final Set<String> keys = traceeKeys.get();
		for (String traceeKey : keys) {
			final String value = MDC.get(traceeKey);
			if (value != null) {
				traceeMap.put(traceeKey, value);
			}
		}
		return traceeMap;
	}
}


<|start_filename|>binding/jaxws/src/test/java/io/tracee/binding/jaxws/AbstractTraceeHandlerTest.java<|end_filename|>
package io.tracee.binding.jaxws;

import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import org.junit.Test;

import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

public class AbstractTraceeHandlerTest {

	private final TraceeBackend traceeBackend = mock(TraceeBackend.class);

	private TestTraceeHandler unit = spy(new TestTraceeHandler(traceeBackend));

	@Test
	public void shouldHandleOutgoingContextInOutgoingMethod() {
		final SOAPMessageContext messageContext = mock(SOAPMessageContext.class);
		when(messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)).thenReturn(Boolean.TRUE);
		unit.handleMessage(messageContext);

		verify(unit).handleOutgoing(messageContext);
	}

	@Test
	public void shouldHandleIncomingContextInIncomingMethod() {
		final SOAPMessageContext messageContext = mock(SOAPMessageContext.class);
		unit.handleMessage(messageContext);
		verify(unit).handleIncoming(messageContext);
	}

	@Test
	public void shouldHandleNoContextPropertyInIncomingMethod() {
		final SOAPMessageContext messageContext = mock(SOAPMessageContext.class);
		when(messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)).thenReturn(Boolean.FALSE);
		unit.handleMessage(messageContext);

		verify(unit).handleIncoming(messageContext);
	}

	@Test
	public void closeDoesNothing() {
		final MessageContext context = mock(MessageContext.class);
		unit.close(context);
		verifyZeroInteractions(context, traceeBackend);
	}

	@Test
	public void shouldRegisterForTraceeHeaders() {
		assertThat(unit.getHeaders(), hasItem(TraceeConstants.SOAP_HEADER_QNAME));
	}

	@Test
	public void shouldReturnTraceeBackendFromInitializiation() {
		assertThat(unit.traceeBackend, is(traceeBackend));
	}


	private static class TestTraceeHandler extends AbstractTraceeHandler {

		TestTraceeHandler(TraceeBackend traceeBackend) {
			super(traceeBackend);
		}

		@Override
		protected void handleIncoming(SOAPMessageContext context) {

		}

		@Override
		protected void handleOutgoing(SOAPMessageContext context) {

		}

		@Override
		public boolean handleFault(SOAPMessageContext context) {
			return false;
		}
	}
}


<|start_filename|>core/src/test/java/io/tracee/backend/slf4j/Slf4jMdcDelegationTest.java<|end_filename|>
package io.tracee.backend.slf4j;

import io.tracee.ThreadLocalHashSet;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.slf4j.MDC;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.powermock.api.mockito.PowerMockito.verifyStatic;
import static org.powermock.api.mockito.PowerMockito.when;

@RunWith(PowerMockRunner.class)
@PrepareForTest(MDC.class)
public class Slf4jMdcDelegationTest {

	private final ThreadLocalHashSet<String> traceeKeys = new ThreadLocalHashSet<>();

	private final Slf4jTraceeBackend unit = new Slf4jTraceeBackend(traceeKeys);

	@Before
	public void setup() {
		PowerMockito.mockStatic(MDC.class);
		traceeKeys.get().clear();
	}

	@Test
	public void shouldPutToMDC() {
		unit.put("A", "vA");
		PowerMockito.verifyStatic();
		MDC.put("A", "vA");
	}

	@Test
	public void putWritesEntryToKeysSet() {
		unit.put("Foo", "bar");
		assertThat(traceeKeys.get(), contains("Foo"));
	}

	@Test
	public void putAllWritesEntriesToMdcLike() {
		final Map<String, String> putMap = new HashMap<>();
		putMap.put("Foo", "bar");
		putMap.put("Ping", "Pong");
		unit.putAll(putMap);
		PowerMockito.verifyStatic(times(1));
		MDC.put(eq("Foo"), eq("bar"));
		PowerMockito.verifyStatic(times(1));
		MDC.put(eq("Ping"), eq("Pong"));
		PowerMockito.verifyNoMoreInteractions(MDC.class);
	}

	@Test
	public void putAllWritesEntriesToKeysSet() {
		final Map<String, String> putMap = new HashMap<>();
		putMap.put("Foo", "bar");
		putMap.put("Ping", "Pong");
		unit.putAll(putMap);
		assertThat(traceeKeys.get(), contains("Foo", "Ping"));
	}

	@Test
	public void clearAlsoRemovesTheThreadLocalTraceeKeys() {
		traceeKeys.get().add("test");
		unit.clear();
		verifyStatic(times(1));
		MDC.remove("test");
		PowerMockito.verifyNoMoreInteractions(MDC.class);
	}

	@Test
	public void containsShouldReturnTrueIfInMdcAndKeySet() {
		traceeKeys.get().add("BB");
		when(MDC.get("BB")).thenReturn("vBB");
		assertThat(unit.containsKey("BB"), is(true));
	}

	@Test
	public void containsShouldReturnFalseIfInKeysetButNotMDC() {
		traceeKeys.get().add("BB");
		assertThat(unit.containsKey("BB"), is(false));
	}

	@Test
	public void containsShouldReturnFalseIfInMdcButNotInKeyset() {
		when(MDC.get("BB")).thenReturn("vBB");
		assertThat(unit.containsKey("BB"), is(false));
	}

	@Test
	public void getValueFromMdcIfInKeySet() {
		traceeKeys.get().add("A");
		PowerMockito.when(MDC.get(eq("A"))).thenReturn("hurray");
		assertThat(unit.get("A"), equalTo("hurray"));
	}

	@Test
	public void getDoesNotReadFromMdcWhenKeyIsNotInKeySet() {
		PowerMockito.when(MDC.get(eq("A"))).thenReturn("hurray");
		assertThat(unit.get("A"), nullValue());
	}

	@Test
	public void callOnRemoveShouldRemoveValueFromMDC() {
		traceeKeys.get().add("BB");
		unit.remove("BB");
		PowerMockito.verifyStatic();
		MDC.remove("BB");
	}

	@Test
	public void callOnRemoveShouldRemoveValueFromTraceeKeys() {
		traceeKeys.get().add("BB");
		unit.remove("BB");
		assertThat(traceeKeys.get(), empty());
	}

	@Test
	public void removeDoesNotRemoveUnregisteredKeysFromMDC() {
		unit.remove("A");
		PowerMockito.verifyNoMoreInteractions(MDC.class);
	}

	@Test
	public void sizeCorrespondsToStoredKeysSize() {
		traceeKeys.get().addAll(Arrays.asList("A", "B", "C", "D"));
		assertThat(unit.size(), equalTo(4));
	}

	@Test
	public void isEmptyWhenKeySetIsEmptyRegardlessOfMDC() {
		PowerMockito.when(MDC.get(eq("A"))).thenReturn("hurray");
		assertThat(unit.isEmpty(), Matchers.is(true));
	}

	@Test
	public void isNotEmptyIfKeySetContainsValuesRegardlessOfMDC() {
		traceeKeys.get().add("A");
		Assert.assertThat(unit.isEmpty(), is(false));
	}

	@Test
	public void copyToMapShouldCreateACopy() {
		PowerMockito.when(MDC.get(eq("A"))).thenReturn("AAb");
		traceeKeys.get().add("A");

		final Map<String, String> copyOfMdc = unit.copyToMap();
		assertThat(copyOfMdc, hasEntry("A", "AAb"));
		assertThat(copyOfMdc.size(), is(1));
	}
}


<|start_filename|>core/src/main/java/io/tracee/transport/jaxb/package-info.java<|end_filename|>
@XmlSchema(
	namespace = TraceeConstants.SOAP_HEADER_NAMESPACE, elementFormDefault = XmlNsForm.QUALIFIED,
	xmlns = @XmlNs(namespaceURI = TraceeConstants.SOAP_HEADER_NAMESPACE, prefix = ""))
package io.tracee.transport.jaxb;

import io.tracee.TraceeConstants;

import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;


<|start_filename|>binding/quartz/src/test/java/io/tracee/binding/quartz/TraceeJobListenerTest.java<|end_filename|>
package io.tracee.binding.quartz;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.configuration.TraceeFilterConfiguration.Profile;
import io.tracee.testhelper.FieldAccessUtil;
import io.tracee.testhelper.SimpleTraceeBackend;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class TraceeJobListenerTest {

	private TraceeBackend backend = spy(SimpleTraceeBackend.createNonLoggingAllPermittingBackend());

	private final TraceeJobListener unit = new TraceeJobListener(backend, Profile.DEFAULT);

	@Test
	public void generateRequestIdWhenJobStarts() {
		final JobExecutionContext executionContext = mock(JobExecutionContext.class);
		when(executionContext.getMergedJobDataMap()).thenReturn(new JobDataMap());
		unit.jobToBeExecuted(executionContext);
		assertThat(backend.copyToMap(), Matchers.hasKey(TraceeConstants.INVOCATION_ID_KEY));
		verify(backend).put(eq(TraceeConstants.INVOCATION_ID_KEY), anyString());
	}

	@Test
	public void addContextToTraceeBackend() {
		final Map<String, String> traceeContext = new HashMap<>();
		final JobExecutionContext executionContext = mock(JobExecutionContext.class);
		final JobDataMap jobDataMap = new JobDataMap();
		jobDataMap.put(TraceeConstants.TPIC_HEADER, traceeContext);
		when(executionContext.getMergedJobDataMap()).thenReturn(jobDataMap);
		traceeContext.put("test", "testVal");
		unit.jobToBeExecuted(executionContext);
		assertThat(backend.get("test"), is("testVal"));
	}

	@Test
	public void defaultConstructorUsesDefaultProfile() {
		final TraceeJobListener listener = new TraceeJobListener();
		assertThat((String) FieldAccessUtil.getFieldVal(listener, "profile"), is(Profile.DEFAULT));
	}

	@Test
	public void defaultConstructorUsesTraceeBackend() {
		final TraceeJobListener listener = new TraceeJobListener();
		assertThat((TraceeBackend) FieldAccessUtil.getFieldVal(listener, "backend"), is(Tracee.getBackend()));
	}

	@Test
	public void constructorStoresProfileNameInternal() {
		final TraceeJobListener listener = new TraceeJobListener("testProf");
		assertThat((String) FieldAccessUtil.getFieldVal(listener, "profile"), is("testProf"));
	}

	@Test
	public void resetBackendWhenJobHasFinished() {
		unit.jobWasExecuted(mock(JobExecutionContext.class), mock(JobExecutionException.class));
		verify(backend).clear();
	}

	@Test
	public void resetBackendWhenJobHasBeenVetoed() {
		unit.jobExecutionVetoed(mock(JobExecutionContext.class));
		verify(backend).clear();
	}

	@Test
	public void returnTheNameOfTheListener() {
		assertThat(unit.getName(), is("TracEE job listener"));
	}
}


<|start_filename|>binding/jaxws/src/test/java/io/tracee/binding/jaxws/TraceeJaxWsEndpoint.java<|end_filename|>
package io.tracee.binding.jaxws;

import javax.jws.WebService;
import java.util.List;

@WebService(targetNamespace = TraceeJaxWsEndpoint.Descriptor.TNS)
interface TraceeJaxWsEndpoint {

	List<String> getCurrentTraceeContext();

	interface Descriptor {
		String SERVICE_NAME = "TraceeJaxWsEndpoint";
		String TNS = "https://github.com/tracee/tracee/examples/jaxws/service/wsdl";
	}

}



<|start_filename|>binding/cxf/src/test/java/io/tracee/binding/cxf/interceptor/OutgoingSoapResponseMessageTest.java<|end_filename|>
package io.tracee.binding.cxf.interceptor;

import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.testhelper.SimpleTraceeBackend;
import io.tracee.transport.jaxb.TpicMap;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.MessageImpl;
import org.junit.Before;
import org.junit.Test;

import javax.xml.bind.JAXBException;
import java.util.Collections;
import java.util.Map;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class OutgoingSoapResponseMessageTest {

	private final TraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();
	private final TraceeResponseOutInterceptor outInterceptor = new TraceeResponseOutInterceptor(backend);
	private final SoapMessage soapMessage = spy(new SoapMessage(new MessageImpl()));

	@Before
	public void before() {
		when(soapMessage.getExchange()).thenReturn(mock(Exchange.class));
	}

	@Test
	public void shouldHandleSoapMessageWithoutSoapHeader() {
		outInterceptor.handleMessage(soapMessage);
		assertThat(soapMessage.getHeader(TraceeConstants.SOAP_HEADER_QNAME), is(nullValue()));
	}

	@Test
	public void shouldAddHeaderWithDataBindingToSoapMessage() throws JAXBException {
		backend.put("mySoapContext", "mySoapContextValue");
		final Map<String, String> expectedHeaderFields = backend.copyToMap();
		outInterceptor.handleMessage(soapMessage);

		final Header tpicHeader = soapMessage.getHeaders().get(0);
		assertThat(tpicHeader.getName(), is(TraceeConstants.SOAP_HEADER_QNAME));
		assertThat(tpicHeader.getObject(), instanceOf(TpicMap.class));
		assertThat(((TpicMap) tpicHeader.getObject()), is(TpicMap.wrap(expectedHeaderFields)));
	}

	@Test
	public void shouldClearTheBackendAfterHandleMessage() throws JAXBException {
		backend.put("foo", "bar");
		outInterceptor.handleMessage(soapMessage);
		assertThat(backend.copyToMap(), equalTo(Collections.<String, String>emptyMap()));
	}

	@Test
	public void failWithoutExceptionIfSoapExtentionOfCxfIsNotOnClasspath() {
		backend.put("test", "testVal");
		when(soapMessage.getHeaders()).thenThrow(new NoClassDefFoundError());
		outInterceptor.handleMessage(soapMessage);
		verify(soapMessage, times(2)).getHeaders();
	}
}


<|start_filename|>backend/threadlocal-store/src/main/java/io/tracee/backend/threadlocalstore/ThreadLocalTraceeBackend.java<|end_filename|>
package io.tracee.backend.threadlocalstore;

import io.tracee.BackendBase;

import java.util.HashMap;
import java.util.Map;

class ThreadLocalTraceeBackend extends BackendBase {

	private final ThreadLocalMap<String, String> threadLocalMap;

	public ThreadLocalTraceeBackend() {
		this.threadLocalMap = new ThreadLocalMap<>();
	}


	@Override
	public boolean containsKey(String key) {
		return threadLocalMap.get().containsKey(key);
	}

	@Override
	public int size() {
		return threadLocalMap.get().size();
	}

	@Override
	public boolean isEmpty() {
		return threadLocalMap.get().isEmpty();
	}

	@Override
	public String get(String key) {
		return threadLocalMap.get().get(key);
	}

	@Override
	public void put(String key, String value) {
		threadLocalMap.get().put(key, value);
	}

	@Override
	public void remove(String key) {
		threadLocalMap.get().remove(key);
	}

	@Override
	public void clear() {
		threadLocalMap.get().clear();
	}

	@Override
	public void putAll(Map<? extends String, ? extends String> entries) {
		threadLocalMap.get().putAll(entries);
	}

	@Override
	public Map<String, String> copyToMap() {
		return new HashMap<>(threadLocalMap.get());
	}

	ThreadLocalMap<String, String> getThreadLocalMap() {
		return threadLocalMap;
	}
}


<|start_filename|>binding/cxf/src/test/java/io/tracee/binding/cxf/interceptor/OutgoingResponseMessageTest.java<|end_filename|>
package io.tracee.binding.cxf.interceptor;

import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.testhelper.SimpleTraceeBackend;
import io.tracee.transport.HttpHeaderTransport;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageImpl;
import org.junit.Before;
import org.junit.Test;

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

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

public class OutgoingResponseMessageTest {

	private static final TraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();

	private TraceeResponseOutInterceptor outInterceptor;

	private final MessageImpl message = spy(new MessageImpl());

	private HttpHeaderTransport httpSerializer;

	@Before
	public void onSetup() throws Exception {
		backend.clear();
		outInterceptor = new TraceeResponseOutInterceptor(backend);
		httpSerializer = new HttpHeaderTransport();

		when(message.getExchange()).thenReturn(mock(Exchange.class));
		when(message.getExchange().get(eq(Message.REST_MESSAGE))).thenReturn(Boolean.TRUE);
	}

	@Test
	public void renderEmptyContextToResponse() {
		outInterceptor.handleMessage(message);
	}

	@Test
	public void renderContextToResponse() {
		backend.put("myContextKey", "contextValue2");
		outInterceptor.handleMessage(message);
		final Map<Object, List<String>> headers = CastUtils.cast((Map<?, ?>) message.get(Message.PROTOCOL_HEADERS));
		final Map<String, String> traceeContext = httpSerializer.parse(headers.get(TraceeConstants.TPIC_HEADER));
		assertThat(traceeContext.get("myContextKey"), is("contextValue2"));
	}
}


<|start_filename|>binding/cxf/src/test/java/io/tracee/binding/cxf/CxfClientToCxfServerIT.java<|end_filename|>
package io.tracee.binding.cxf;

import io.tracee.TraceeConstants;
import io.tracee.binding.cxf.testSoapService.HelloWorldTestService;
import io.tracee.configuration.TraceeFilterConfiguration.Profile;
import org.apache.cxf.bus.CXFBusFactory;
import org.apache.cxf.feature.LoggingFeature;
import org.apache.cxf.frontend.ClientProxyFactoryBean;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

public class CxfClientToCxfServerIT extends AbstractConnectionITHelper {

	private HelloWorldTestService helloWorldPort;

	@Before
	public void setup() {
		JaxWsServerFactoryBean jaxWsServer = createJaxWsServer();
		jaxWsServer.getFeatures().add(new LoggingFeature());
		jaxWsServer.getFeatures().add(new TraceeCxfFeature(serverBackend, Profile.DEFAULT));
		server = jaxWsServer.create();

		final ClientProxyFactoryBean factoryBean = new ClientProxyFactoryBean();
		factoryBean.getFeatures().add(new LoggingFeature());
		factoryBean.getFeatures().add(new TraceeCxfFeature(clientBackend, Profile.DEFAULT));
		factoryBean.setServiceClass(HelloWorldTestService.class);
		factoryBean.setBus(CXFBusFactory.getDefaultBus());
		factoryBean.setAddress(endpointAddress);
		helloWorldPort = (HelloWorldTestService) factoryBean.create();
	}

	@Test
	public void transportTraceeVariablesFromClientToBackend() {
		clientBackend.put(TraceeConstants.INVOCATION_ID_KEY, "123");
		final String answer = helloWorldPort.sayHelloWorld("Michail");
		assertThat(answer, allOf(containsString("Michail"), endsWith("invocationId was 123")));
	}

	@Test
	public void transportTraceeVariablesFromBackendToTheClient() {
		helloWorldPort.sayHelloWorld("Michail");
		assertThat(serverBackend.isEmpty(), is(true));
		assertThat(clientBackend.get(HelloWorldTestService.TEST_KEY), is("accepted"));
	}
}


<|start_filename|>binding/httpclient/src/main/java/io/tracee/binding/httpclient/TraceeHttpClientDecorator.java<|end_filename|>
package io.tracee.binding.httpclient;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.configuration.TraceeFilterConfiguration;
import io.tracee.transport.HttpHeaderTransport;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.params.HttpClientParams;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static io.tracee.configuration.TraceeFilterConfiguration.Channel.IncomingResponse;
import static io.tracee.configuration.TraceeFilterConfiguration.Channel.OutgoingRequest;
import static io.tracee.configuration.TraceeFilterConfiguration.Profile.DEFAULT;

/**
 * Wraps an HttpClient and performs TraceEE context propagation on execute methods.
 */
public class TraceeHttpClientDecorator extends HttpClient {

	private final HttpClient delegate;
	private final TraceeBackend backend;
	private final HttpHeaderTransport transportSerialization;
	private final String profile;

	public static HttpClient wrap(HttpClient httpClient) {
		return wrap(httpClient, DEFAULT);
	}

	public static HttpClient wrap(HttpClient httpClient, String profile) {
		if (httpClient instanceof TraceeHttpClientDecorator) {
			return httpClient;
		} else {
			return new TraceeHttpClientDecorator(httpClient, profile);
		}
	}

	TraceeHttpClientDecorator(HttpClient delegate, TraceeBackend backend, HttpHeaderTransport transportSerialization, String profile) {
		this.delegate = delegate;
		this.backend = backend;
		this.transportSerialization = transportSerialization;
		this.profile = profile;
	}

	TraceeHttpClientDecorator(HttpClient delegate, TraceeBackend backend, String profile) {
		this(delegate, backend, new HttpHeaderTransport(), profile);
	}

	public TraceeHttpClientDecorator(HttpClient delegate, String profile) {
		this(delegate, Tracee.getBackend(), profile);
	}


	@Override
	public int executeMethod(HttpMethod method) throws IOException, HttpException {
		return this.executeMethod(null, method, null);
	}

	@Override
	public int executeMethod(HostConfiguration hostConfiguration, HttpMethod method) throws IOException, HttpException {
		return this.executeMethod(hostConfiguration, method, null);
	}

	@Override
	public int executeMethod(HostConfiguration hostconfig, HttpMethod method, HttpState state) throws IOException, HttpException {
		preRequest(method);
		try {
			int result = delegate.executeMethod(hostconfig, method, state);
			postResponse(method);
			return result;
		} finally {
			cancel();
		}
	}

	private void cancel() {
		//TODO: do we need to cleanup anything?
	}

	private void preRequest(HttpMethod httpMethod) {
		final TraceeFilterConfiguration filterConfiguration = backend.getConfiguration(profile);
		if (!backend.isEmpty() && filterConfiguration.shouldProcessContext(OutgoingRequest)) {
			final Map<String, String> filteredParams = filterConfiguration.filterDeniedParams(backend.copyToMap(), OutgoingRequest);
			httpMethod.setRequestHeader(TraceeConstants.TPIC_HEADER, transportSerialization.render(filteredParams));
		}
	}


	private void postResponse(HttpMethod httpMethod) {
		if (!httpMethod.isRequestSent()) return;
		final Header[] responseHeaders = httpMethod.getResponseHeaders(TraceeConstants.TPIC_HEADER);
		final TraceeFilterConfiguration filterConfiguration = backend.getConfiguration(profile);
		if (responseHeaders != null && responseHeaders.length > 0 && filterConfiguration.shouldProcessContext(IncomingResponse)) {
			final List<String> stringTraceeHeaders = new ArrayList<>();
			for (Header header : responseHeaders) {
				stringTraceeHeaders.add(header.getValue());
			}

			backend.putAll(filterConfiguration.filterDeniedParams(transportSerialization.parse(stringTraceeHeaders), IncomingResponse));
		}
	}


	@Override
	public synchronized HttpState getState() {
		return delegate.getState();
	}

	@Override
	public synchronized void setState(HttpState state) {
		delegate.setState(state);
	}

	@Override
	@SuppressWarnings("deprecation")
	public synchronized void setStrictMode(boolean strictMode) {
		delegate.setStrictMode(strictMode);
	}

	@Override
	@SuppressWarnings("deprecation")
	public synchronized boolean isStrictMode() {
		return delegate.isStrictMode();
	}

	@Override
	@SuppressWarnings("deprecation")
	public synchronized void setTimeout(int newTimeoutInMilliseconds) {
		delegate.setTimeout(newTimeoutInMilliseconds);
	}

	@Override
	@SuppressWarnings("deprecation")
	public synchronized void setHttpConnectionFactoryTimeout(long timeout) {
		delegate.setHttpConnectionFactoryTimeout(timeout);
	}

	@Override
	@SuppressWarnings("deprecation")
	public synchronized void setConnectionTimeout(int newTimeoutInMilliseconds) {
		delegate.setConnectionTimeout(newTimeoutInMilliseconds);
	}

	@Override
	@SuppressWarnings("deprecation")
	public String getHost() {
		return delegate.getHost();
	}

	@Override
	@SuppressWarnings("deprecation")
	public int getPort() {
		return delegate.getPort();
	}

	@Override
	public synchronized HostConfiguration getHostConfiguration() {
		return delegate.getHostConfiguration();
	}

	@Override
	public synchronized void setHostConfiguration(HostConfiguration hostConfiguration) {
		delegate.setHostConfiguration(hostConfiguration);
	}

	@Override
	public synchronized HttpConnectionManager getHttpConnectionManager() {
		return delegate.getHttpConnectionManager();
	}

	@Override
	public synchronized void setHttpConnectionManager(HttpConnectionManager httpConnectionManager) {
		delegate.setHttpConnectionManager(httpConnectionManager);
	}

	@Override
	public HttpClientParams getParams() {
		return delegate.getParams();
	}

	@Override
	public void setParams(HttpClientParams params) {
		delegate.setParams(params);
	}
}


<|start_filename|>api/src/main/java/io/tracee/configuration/TraceeFilterConfiguration.java<|end_filename|>
package io.tracee.configuration;

import java.util.Map;

public interface TraceeFilterConfiguration {

	enum Channel {
		IncomingRequest,
		OutgoingResponse,
		OutgoingRequest,
		IncomingResponse,
		AsyncDispatch,
		AsyncProcess
	}

	/**
	 * Tracee ships with a set of builtin profiles.
	 */
	final class Profile {

		/**
		 * Default Profile.
		 * Permits Tracee headers to flow into all directions.
		 */
		public static final String DEFAULT = "default";

		/**
		 * HideInbound Profile.
		 * Prevents responding with a Tracee-Header in OutgoingResponses.
		 */
		public static final String HIDE_INBOUND = "HideInbound";
		/**
		 * HideOutbound Profile.
		 * Prevents passing of any Tracee header in OutgoingRequests.
		 */
		public static final String HIDE_OUTBOUND = "HideOutbound";
		/**
		 * DisableInbound Profile.
		 * Prevents parsing of any Tracee header from IncomingRequests and prevents responding with a Tracee-Header in OutgoingResponses.
		 */
		public static final String DISABLE_INBOUND = "DisableInbound";
		/**
		 * DisableOutbound Profile.
		 * Prevents passing of any Tracee header in OutgoingRequests and prevents parsing of any Tracee-Header in IncomingResponses.
		 */
		public static final String DISABLE_OUTBOUND = "DisableOutbound";
		/**
		 * Disabled Profile.
		 * Completely disables tracee context processing on all channels.
		 */
		public static final String DISABLED = "Disabled";

		private Profile() {
		}
	}

	/**
	 * Returns true if a given TracEE context parameter should be parsed or sent on a given channel.
	 */
	boolean shouldProcessParam(String paramName, Channel channel);

	/**
	 * Returns a map that is a filtered copy of the given {@code unfiltered} map. It contains only keys, that
	 * are allowed to be processed on this channel.
	 */
	Map<String, String> filterDeniedParams(Map<String, String> unfiltered, Channel channel);

	/**
	 * @return {@code true} if the current configuration allows context processing on the given {@code channel} at all, {@code} false otherwise.
	 */
	boolean shouldProcessContext(Channel channel);


	boolean shouldGenerateInvocationId();

	/**
	 * @return a desired non-negative length of the generated request identifiers. If it returns <code>0</code>, no request identifiers should be generated.
	 */
	int generatedInvocationIdLength();


	boolean shouldGenerateSessionId();

	/**
	 * @return a desired non-negative length of the generated session identifiers. If it returns <code>0</code>, no session identifiers should be generated.
	 */
	int generatedSessionIdLength();


}


<|start_filename|>api/src/test/java/io/tracee/TraceeTest.java<|end_filename|>
package io.tracee;

import io.tracee.spi.TraceeBackendProvider;
import org.junit.Test;
import org.mockito.Mockito;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.when;

public class TraceeTest {

	@Test
	public void constructorOfTraceeShouldBePrivate() throws Exception {
		Constructor<Tracee> constructor = Tracee.class.getDeclaredConstructor();
		assertThat(Modifier.isPrivate(constructor.getModifiers()), is(true));
		constructor.setAccessible(true);
		constructor.newInstance();
	}

	@Test(expected = TraceeException.class)
	public void backendRetrievalShouldThrowTraceeExceptionWithDefaultResolver() {
		try {
			Tracee.getBackend();
			fail();
		} catch (TraceeException e) {
			assertThat(e.getMessage(), equalTo("Unable to find a TracEE backend provider. Make sure that you have tracee-core (for slf4j) or any other backend implementation on the classpath."));
			throw e;
		}
	}

	@Test(expected = TraceeException.class)
	public void backendRetrievalShouldWrapRuntimeExceptionIfItOccurs() {
		try {
			final BackendProviderResolver testBackendProvider = Mockito.mock(BackendProviderResolver.class);
			when(testBackendProvider.getBackendProviders()).thenThrow(new RuntimeException());
			Tracee.getBackend(testBackendProvider);
			fail();
		} catch (RuntimeException e) {
			assertThat(e.getMessage(), equalTo("Unable to load available backend providers"));
			throw e;
		}
	}

	@Test(expected = TraceeException.class)
	public void backendRetrievalShouldThrowExceptionWithoutProviders() {
		final BackendProviderResolver resolver = createTestBackendResolverWith(new HashSet<TraceeBackendProvider>());
		try {
			Tracee.getBackend(resolver);
			fail();
		} catch (TraceeException e) {
			assertThat(e.getMessage(), equalTo("Unable to find a TracEE backend provider. Make sure that you have tracee-core (for slf4j) or any other backend implementation on the classpath."));
			throw e;
		}
	}

	@Test(expected = TraceeException.class)
	public void backendRetrievalShouldThrowExceptionWithMoreThenOneProvider() {
		final Set<TraceeBackendProvider> backendProvider = new HashSet<>();
		backendProvider.add(new TestBackendProvider());
		backendProvider.add(new TestBackendProvider());

		final BackendProviderResolver resolver = createTestBackendResolverWith(backendProvider);
		try {
			Tracee.getBackend(resolver);
		} catch (TraceeException e) {
			assertThat(e.getMessage(), allOf(startsWith("Multiple TracEE backend providers found. Don't know which one of the following to use:"),
				containsString(TestBackendProvider.class.getSimpleName())));
			throw e;
		}
	}

	@Test
	public void backendRetrievalShouldReturnBackendWithOneGivenProvider() {
		final Set<TraceeBackendProvider> backendProvider = new HashSet<>();
		backendProvider.add(new TestBackendProvider());

		final TraceeBackend resolvedBackend = Tracee.getBackend(createTestBackendResolverWith(backendProvider));

		assertThat(resolvedBackend, is(not(nullValue())));
	}

	private BackendProviderResolver createTestBackendResolverWith(Set<TraceeBackendProvider> backendProvider) {
		final BackendProviderResolver testBackendProvider = Mockito.mock(BackendProviderResolver.class);
		when(testBackendProvider.getBackendProviders()).thenReturn(backendProvider);
		return testBackendProvider;
	}

	private static final class TestBackendProvider implements TraceeBackendProvider {
		@Override
		public TraceeBackend provideBackend() {
			return Mockito.mock(TraceeBackend.class);
		}
	}
}


<|start_filename|>backend/threadlocal-store/src/main/java/io/tracee/backend/threadlocalstore/ThreadLocalMap.java<|end_filename|>
package io.tracee.backend.threadlocalstore;

import java.util.HashMap;
import java.util.Map;

class ThreadLocalMap<K, V> extends InheritableThreadLocal<Map<K, V>> {

	@Override
	protected final Map<K, V> initialValue() {
		return new HashMap<>();
	}

	@Override
	protected final Map<K, V> childValue(Map<K, V> parentValue) {
		if (parentValue == null) {
			return null;
		} else {
			return new HashMap<>(parentValue);
		}
	}
}


<|start_filename|>binding/servlet/src/test/java/io/tracee/binding/servlet/TraceeServletRequestListenerTest.java<|end_filename|>
package io.tracee.binding.servlet;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.configuration.TraceeFilterConfiguration;
import io.tracee.testhelper.FieldAccessUtil;
import io.tracee.transport.HttpHeaderTransport;
import org.hamcrest.MatcherAssert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;

import static io.tracee.TraceeConstants.INVOCATION_ID_KEY;
import static io.tracee.TraceeConstants.SESSION_ID_KEY;
import static io.tracee.configuration.TraceeFilterConfiguration.Channel.IncomingRequest;
import static java.util.Collections.enumeration;
import static java.util.Collections.singletonList;
import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyMapOf;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.internal.verification.VerificationModeFactory.atLeastOnce;

public class TraceeServletRequestListenerTest {

	private final HttpHeaderTransport transportSerialization = new HttpHeaderTransport();
	private final TraceeBackend backend = Mockito.mock(TraceeBackend.class);
	private final TraceeServletRequestListener unit = new TraceeServletRequestListener(backend, transportSerialization);
	private final HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class);
	private final TraceeFilterConfiguration configuration = Mockito.mock(TraceeFilterConfiguration.class);

	@Before
	public void setupMocks() {
		when(backend.getConfiguration()).thenReturn(configuration);
	}

	@Test
	public void testGeneratesInvocationId() throws Exception {
		when(configuration.shouldGenerateInvocationId()).thenReturn(true);
		final Collection<String> emptyList = Collections.emptyList();
		when(httpServletRequest.getHeaders(TraceeConstants.TPIC_HEADER)).thenReturn(enumeration(emptyList));

		unit.requestInitialized(wrapToEvent(httpServletRequest));
		verify(backend, atLeastOnce()).put(eq(TraceeConstants.INVOCATION_ID_KEY), anyString());
	}

	@Test
	public void testDoesNotGeneratesInvocationId() throws Exception {
		when(configuration.shouldGenerateInvocationId()).thenReturn(false);
		final Collection<String> emptyList = Collections.emptyList();
		when(httpServletRequest.getHeaders(TraceeConstants.TPIC_HEADER)).thenReturn(enumeration(emptyList));

		unit.requestInitialized(wrapToEvent(httpServletRequest));
		verify(backend, never()).put(eq(TraceeConstants.INVOCATION_ID_KEY), anyString());
	}


	@Test
	public void testAcceptIncomingInvocationId() throws Exception {
		when(configuration.shouldGenerateInvocationId()).thenReturn(false);
		when(configuration.shouldProcessContext(IncomingRequest)).thenReturn(true);
		when(configuration.filterDeniedParams(anyMapOf(String.class, String.class), any(TraceeFilterConfiguration.Channel.class))).thenAnswer(new Answer<Object>() {
			@Override
			public Object answer(InvocationOnMock invocation) throws Throwable {
				return invocation.getArguments()[0];
			}
		});
		when(httpServletRequest.getHeaders(TraceeConstants.TPIC_HEADER)).thenReturn(enumeration(
			singletonList(INVOCATION_ID_KEY + "=123")));

		unit.requestInitialized(wrapToEvent(httpServletRequest));

		verify(backend, atLeastOnce()).putAll(Mockito.eq(new HashMap<String, String>() {{
			put(INVOCATION_ID_KEY, "123");
		}}));
	}

	@Test
	public void testGenerateSessionId() throws Exception {
		when(configuration.shouldGenerateSessionId()).thenReturn(true);
		final HttpSession session = Mockito.mock(HttpSession.class);
		when(httpServletRequest.getSession(any(Boolean.class))).thenReturn(session);
		when(session.getId()).thenReturn("A_RANDOM_SESSION_ID");

		unit.requestInitialized(wrapToEvent(httpServletRequest));
		verify(backend, atLeastOnce()).put(eq(SESSION_ID_KEY), anyString());
	}

	@Test
	public void testClearsBackendAfterProcessing() {
		unit.requestDestroyed(new ServletRequestEvent(mock(ServletContext.class), httpServletRequest));
		verify(backend, atLeastOnce()).clear();
	}

	@Test
	public void defaultConstructorUsesTraceeBackend() {
		final TraceeSessionListener listener = new TraceeSessionListener();
		MatcherAssert.assertThat((TraceeBackend) FieldAccessUtil.getFieldVal(listener, "backend"), is(Tracee.getBackend()));
	}

	private ServletRequestEvent wrapToEvent(ServletRequest req) {
		return new ServletRequestEvent(mock(ServletContext.class), req);
	}
}


<|start_filename|>binding/springws/src/test/java/io/tracee/binding/springws/itest/testservice/TraceeEntryResponse.java<|end_filename|>
package io.tracee.binding.springws.itest.testservice;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(namespace = JaxwsTestservice.TNS, name = "currentTraceeContextResponse")
public class TraceeEntryResponse {

	@XmlElement(name = "remoteInvocationId")
	private String remoteInvocationId;

	protected TraceeEntryResponse() {
	}

	public TraceeEntryResponse(String remoteInvocationId) {
		this.remoteInvocationId = remoteInvocationId;
	}

	public String getRemoteInvocationId() {
		return remoteInvocationId;
	}
}


<|start_filename|>binding/cxf/src/test/java/io/tracee/binding/cxf/testSoapService/HelloWorldTestService.java<|end_filename|>
package io.tracee.binding.cxf.testSoapService;

import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService(name = "HelloWorldBinding", portName = "HelloWorldBinding",
	serviceName = "HelloWorldService")
public interface HelloWorldTestService {

	String NAMESPACE = "https://github.com/tracee/tracee";

	String TEST_KEY = "serverKey";

	@WebResult(partName = "greeting")
	String sayHelloWorld(
		@WebParam(partName = "firstName") String firstName);
}


<|start_filename|>core/src/test/java/io/tracee/configuration/TraceePropertiesFileLoaderTest.java<|end_filename|>
package io.tracee.configuration;

import org.junit.Test;

import java.io.IOException;
import java.util.Properties;

import static org.hamcrest.Matchers.isEmptyOrNullString;
import static org.hamcrest.Matchers.isEmptyString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;

public class TraceePropertiesFileLoaderTest {

	private final TraceePropertiesFileLoader unit = new TraceePropertiesFileLoader();

	final Properties properties;

	{
		try {
			properties = unit.loadTraceeProperties(TraceePropertiesFileLoader.TRACEE_DEFAULT_PROPERTIES_FILE);
		} catch (IOException e) {
			throw new IllegalStateException("Could not load default properties: " + e.getMessage(), e);
		}
	}

	@Test
	public void testLoadDefaultProperties() throws IOException {

		assertThat("property tracee.default.IncomingRequest", properties.getProperty("tracee.default.IncomingRequest"), not(isEmptyOrNullString()));
		assertThat("property tracee.default.OutgoingResponse", properties.getProperty("tracee.default.OutgoingResponse"), not(isEmptyOrNullString()));
		assertThat("property tracee.default.OutgoingRequest", properties.getProperty("tracee.default.OutgoingRequest"), not(isEmptyOrNullString()));
		assertThat("property tracee.default.IncomingResponse", properties.getProperty("tracee.default.IncomingResponse"), not(isEmptyOrNullString()));
		assertThat("property tracee.default.AsyncDispatch", properties.getProperty("tracee.default.AsyncDispatch"), not(isEmptyOrNullString()));
		assertThat("property tracee.default.AsyncProcess", properties.getProperty("tracee.default.AsyncProcess"), not(isEmptyOrNullString()));
		assertThat("property tracee.default.invocationIdLength", properties.getProperty("tracee.default.invocationIdLength"), not(isEmptyOrNullString()));
		assertThat("property tracee.default.sessionIdLength", properties.getProperty("tracee.default.sessionIdLength"), not(isEmptyOrNullString()));
	}

	@Test
	public void testLoadHideInboundProfile() throws IOException {
		assertThat("property tracee.profile.HideInbound.OutgoingResponse", properties.getProperty("tracee.profile.HideInbound.OutgoingResponse"), isEmptyString());
	}

	@Test
	public void testLoadHideOutboundProfile() throws IOException {
		assertThat("property tracee.profile.HideOutbound.OutgoingRequest", properties.getProperty("tracee.profile.HideOutbound.OutgoingRequest"), isEmptyString());
	}

	@Test
	public void testLoadDisableInboundProfile() throws IOException {
		assertThat("property tracee.profile.DisableInbound.IncomingRequest", properties.getProperty("tracee.profile.DisableInbound.IncomingRequest"), isEmptyString());
		assertThat("property tracee.profile.DisableInbound.OutgoingResponse", properties.getProperty("tracee.profile.DisableInbound.OutgoingResponse"), isEmptyString());
	}

	@Test
	public void testLoadDisableOutboundProfile() throws IOException {
		assertThat("property tracee.profile.DisableOutbound.OutgoingRequest", properties.getProperty("tracee.profile.DisableOutbound.OutgoingRequest"), isEmptyString());
		assertThat("property tracee.profile.DisableOutbound.IncomingResponse", properties.getProperty("tracee.profile.DisableOutbound.IncomingResponse"), isEmptyString());
	}

	@Test
	public void testLoadDisabledProfile() throws IOException {
		assertThat("property tracee.profile.Disabled.IncomingRequest", properties.getProperty("tracee.profile.Disabled.IncomingRequest"), isEmptyString());
		assertThat("property tracee.profile.Disabled.OutgoingResponse", properties.getProperty("tracee.profile.Disabled.OutgoingResponse"), isEmptyString());
		assertThat("property tracee.profile.Disabled.OutgoingRequest", properties.getProperty("tracee.profile.Disabled.OutgoingRequest"), isEmptyString());
		assertThat("property tracee.profile.Disabled.IncomingResponse", properties.getProperty("tracee.profile.Disabled.IncomingResponse"), isEmptyString());
		assertThat("property tracee.profile.Disabled.AsyncDispatch", properties.getProperty("tracee.profile.Disabled.AsyncDispatch"), isEmptyString());
		assertThat("property tracee.profile.Disabled.AsyncProcess", properties.getProperty("tracee.profile.Disabled.AsyncProcess"), isEmptyString());
	}

}


<|start_filename|>api/src/test/java/io/tracee/configuration/TraceeFilterConfigurationTest.java<|end_filename|>
package io.tracee.configuration;

import org.junit.Test;

import static io.tracee.configuration.TraceeFilterConfiguration.Channel.AsyncDispatch;
import static io.tracee.configuration.TraceeFilterConfiguration.Channel.AsyncProcess;
import static io.tracee.configuration.TraceeFilterConfiguration.Channel.IncomingRequest;
import static io.tracee.configuration.TraceeFilterConfiguration.Channel.IncomingResponse;
import static io.tracee.configuration.TraceeFilterConfiguration.Channel.OutgoingRequest;
import static io.tracee.configuration.TraceeFilterConfiguration.Channel.OutgoingResponse;
import static io.tracee.configuration.TraceeFilterConfiguration.Channel.valueOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

public class TraceeFilterConfigurationTest {

	@Test
	public void shouldReturnIncomingRequestEnum() {
		assertThat(valueOf("IncomingRequest"), is(IncomingRequest));
	}

	@Test
	public void shouldReturnIncomingResponseEnum() {
		assertThat(valueOf("IncomingResponse"), is(IncomingResponse));
	}

	@Test
	public void shouldReturnOutgoingRequestEnum() {
		assertThat(valueOf("OutgoingRequest"), is(OutgoingRequest));
	}

	@Test
	public void shouldReturnOutgoingResponseEnum() {
		assertThat(valueOf("OutgoingResponse"), is(OutgoingResponse));
	}

	@Test
	public void shouldReturnAsyncDispatchEnum() {
		assertThat(valueOf("AsyncDispatch"), is(AsyncDispatch));
	}

	@Test
	public void shouldReturnAsyncProcessEnum() {
		assertThat(valueOf("AsyncProcess"), is(AsyncProcess));
	}
}


<|start_filename|>binding/jms/src/main/java/io/tracee/binding/jms/TraceeTopicPublisher.java<|end_filename|>
package io.tracee.binding.jms;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Topic;
import javax.jms.TopicPublisher;

public final class TraceeTopicPublisher implements TopicPublisher {


	private final TraceeMessageProducer messageProducer;
	private final TopicPublisher delegate;

	public TraceeTopicPublisher(TraceeMessageProducer messageProducer, TopicPublisher delegate) {
		this.messageProducer = messageProducer;
		this.delegate = delegate;
	}

	@Override
	public Topic getTopic() throws JMSException {
		return delegate.getTopic();
	}

	@Override
	public void publish(Message message) throws JMSException {
		messageProducer.writeTraceeContextToMessage(message);
		delegate.publish(message);
	}

	@Override
	public void publish(Message message, int deliveryMode, int priority, long timeToLive) throws JMSException {
		messageProducer.writeTraceeContextToMessage(message);
		delegate.publish(message, deliveryMode, priority, timeToLive);
	}

	@Override
	public void publish(Topic topic, Message message) throws JMSException {
		messageProducer.writeTraceeContextToMessage(message);
		delegate.publish(topic, message);
	}

	@Override
	public void publish(Topic topic, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException {
		messageProducer.writeTraceeContextToMessage(message);
		delegate.publish(topic, message, deliveryMode, priority, timeToLive);
	}

	@Override
	public void send(Message message) throws JMSException {
		messageProducer.send(message);
	}

	@Override
	public void send(Message message, int deliveryMode, int priority, long timeToLive) throws JMSException {
		messageProducer.send(message, deliveryMode, priority, timeToLive);
	}

	@Override
	public void send(Destination destination, Message message) throws JMSException {
		messageProducer.send(destination, message);
	}

	@Override
	public void send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException {
		messageProducer.send(destination, message, deliveryMode, priority, timeToLive);
	}

	@Override
	public void setDisableMessageID(boolean value) throws JMSException {
		messageProducer.setDisableMessageID(value);
	}

	@Override
	public boolean getDisableMessageID() throws JMSException {
		return messageProducer.getDisableMessageID();
	}

	@Override
	public void setDisableMessageTimestamp(boolean value) throws JMSException {
		messageProducer.setDisableMessageTimestamp(value);
	}

	@Override
	public boolean getDisableMessageTimestamp() throws JMSException {
		return messageProducer.getDisableMessageTimestamp();
	}

	@Override
	public void setDeliveryMode(int deliveryMode) throws JMSException {
		messageProducer.setDeliveryMode(deliveryMode);
	}

	@Override
	public int getDeliveryMode() throws JMSException {
		return messageProducer.getDeliveryMode();
	}

	@Override
	public void setPriority(int defaultPriority) throws JMSException {
		messageProducer.setPriority(defaultPriority);
	}

	@Override
	public int getPriority() throws JMSException {
		return messageProducer.getPriority();
	}

	@Override
	public void setTimeToLive(long timeToLive) throws JMSException {
		messageProducer.setTimeToLive(timeToLive);
	}

	@Override
	public long getTimeToLive() throws JMSException {
		return messageProducer.getTimeToLive();
	}

	@Override
	public Destination getDestination() throws JMSException {
		return messageProducer.getDestination();
	}

	@Override
	public void close() throws JMSException {
		messageProducer.close();
	}
}


<|start_filename|>binding/jaxrs2/src/test/java/io/tracee/binding/jaxrs2/TraceeClientFilterRequestTest.java<|end_filename|>
package io.tracee.binding.jaxrs2;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.testhelper.FieldAccessUtil;
import io.tracee.testhelper.SimpleTraceeBackend;
import org.hamcrest.MatcherAssert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import java.io.IOException;

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isEmptyOrNullString;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.when;

public class TraceeClientFilterRequestTest {

	private final TraceeBackend traceeBackend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();
	private final TraceeClientFilter unit = new TraceeClientFilter(traceeBackend);
	private final ClientRequestContext clientRequestContext = Mockito.mock(ClientRequestContext.class);

	@Before
	public void setUp() {
		final MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
		when(clientRequestContext.getHeaders()).thenReturn(headers);
	}

	@Test
	public void testFilterWritesBackendToRequestContextHeaders() throws IOException {
		traceeBackend.put("foo", "bar");
		unit.filter(clientRequestContext);
		assertThat((String) clientRequestContext.getHeaders().getFirst(TraceeConstants.TPIC_HEADER),
			containsString("foo=bar"));
	}

	@Test
	public void doNotCreateInvocationIdOnOutgoingRequest() throws IOException {
		unit.filter(clientRequestContext);
		assertThat(traceeBackend.get(TraceeConstants.INVOCATION_ID_KEY), isEmptyOrNullString());
		assertThat(clientRequestContext.getHeaders().getFirst(TraceeConstants.TPIC_HEADER),
			is(nullValue()));
	}

	@Test
	public void testFilterKeepsExistingInvocationId() throws IOException {
		traceeBackend.put(TraceeConstants.INVOCATION_ID_KEY, "foo");
		unit.filter(clientRequestContext);
		assertThat(traceeBackend.get(TraceeConstants.INVOCATION_ID_KEY), equalTo("foo"));
		assertThat((String) clientRequestContext.getHeaders().getFirst(TraceeConstants.TPIC_HEADER),
			containsString(TraceeConstants.INVOCATION_ID_KEY + "=foo"));
	}

	@Test
	public void defaultConstructorUsesDefaultProfile() {
		final TraceeClientFilter clientFilter = new TraceeClientFilter();
		MatcherAssert.assertThat((TraceeBackend) FieldAccessUtil.getFieldVal(clientFilter, "backend"), is(Tracee.getBackend()));
	}
}


<|start_filename|>binding/httpcomponents/src/test/java/io/tracee/binding/httpcomponents/TraceeHttpInterceptorsIT.java<|end_filename|>
package io.tracee.binding.httpcomponents;

import io.tracee.Tracee;
import io.tracee.TraceeConstants;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.InetSocketAddress;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

public class TraceeHttpInterceptorsIT {

	private Server server;

	private String serverEndpoint;

	@Test
	public void testWritesToServerAndParsesResponse() throws IOException {

		HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
		httpClientBuilder.addInterceptorLast(new TraceeHttpRequestInterceptor());
		httpClientBuilder.addInterceptorFirst(new TraceeHttpResponseInterceptor());
		CloseableHttpClient httpClient = httpClientBuilder.build();

		HttpGet getMethod = new HttpGet(serverEndpoint);
		Tracee.getBackend().put("before Request", "yip");
		final HttpResponse response = httpClient.execute(getMethod);

		assertThat(response.getStatusLine().getStatusCode(), equalTo(HttpServletResponse.SC_NO_CONTENT));
		assertThat(Tracee.getBackend().get("responseFromServer"), equalTo("yes Sir"));
	}

	@Before
	public void startJetty() throws Exception {
		server = new Server(new InetSocketAddress("127.0.0.1", 0));
		server.setHandler(requestHandler);
		server.start();
		serverEndpoint = "http://" + server.getConnectors()[0].getName();
	}

	private final Handler requestHandler = new AbstractHandler() {
		@Override
		public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, ServletException {
			final String incomingTraceeHeader = request.getHeader(TraceeConstants.TPIC_HEADER);

			assertThat(incomingTraceeHeader, equalTo("before+Request=yip"));

			httpServletResponse.setHeader(TraceeConstants.TPIC_HEADER, "responseFromServer=yes+Sir");
			httpServletResponse.setStatus(HttpServletResponse.SC_NO_CONTENT);
			request.setHandled(true);
		}
	};

	@After
	public void stopJetty() throws Exception {
		if (server != null) {
			server.stop();
			server.join();
		}
	}
}


<|start_filename|>binding/jms/src/test/java/io/tracee/binding/jms/TestMDB.java<|end_filename|>
package io.tracee.binding.jms;

import javax.annotation.Resource;
import javax.ejb.MessageDriven;
import javax.interceptor.Interceptors;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;

@MessageDriven
@Interceptors(TraceeMessageListener.class)
public class TestMDB implements MessageListener {

	@Resource
	private ConnectionFactory connectionFactory;

	@Resource(name = "Response")
	private Queue responses;

	@Override
	public void onMessage(Message message) {
		final TextMessage incomingMessage = (TextMessage) message;

		Connection connection = null;
		Session session = null;
		try {
			connection = connectionFactory.createConnection();
			connection.start();
			session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
			final MessageProducer producer = TraceeMessageWriter.wrap(session.createProducer(responses));
			producer.setDeliveryMode(DeliveryMode.PERSISTENT);
			final TextMessage responseMessage = session.createTextMessage(incomingMessage.getText());
			producer.send(responseMessage);
		} catch (JMSException e) {
			throw new IllegalStateException(e);
		} finally {
			try {
				if (session != null) session.close();
				if (connection != null) connection.close();
			} catch (JMSException ignored) {
			}
		}

	}
}


<|start_filename|>api/src/main/java/io/tracee/BackendProviderResolver.java<|end_filename|>
package io.tracee;

import io.tracee.spi.TraceeBackendProvider;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.AbstractSet;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.WeakHashMap;

class BackendProviderResolver {

	// We should use weak references for our cache. otherwise we block class unloading.
	// This map is updated by the "copyOnWrite"-pattern. Don't update this map directly!
	private static volatile Map<ClassLoader, Set<TraceeBackendProvider>> providersPerClassloader = new WeakHashMap<>();

	/**
	 * Find correct backend provider for the current context classloader. If no context classloader is available, a
	 * fallback with the classloader of this resolver class is taken
	 *
	 * @return A bunch of TraceeBackendProvider registered and available in the current classloader
	 */
	public Set<TraceeBackendProvider> getBackendProviders() {
		// Create a working copy of Cache. Reference is updated upon cache update.
		final Map<ClassLoader, Set<TraceeBackendProvider>> cacheCopy = providersPerClassloader;

		// Try to determine TraceeBackendProvider by context classloader. Fallback: use classloader of class.
		final Set<TraceeBackendProvider> providerFromContextClassLoader = getTraceeProviderFromClassloader(cacheCopy,
			GetClassLoader.fromContext());
		if (!providerFromContextClassLoader.isEmpty()) {
			return providerFromContextClassLoader;
		} else {
			return getTraceeProviderFromClassloader(cacheCopy, GetClassLoader.fromClass(BackendProviderResolver.class));
		}
	}

	/**
	 * Loads the default implementation
	 */
	Set<TraceeBackendProvider> getDefaultTraceeBackendProvider() {
		try {
			final ClassLoader classLoader = GetClassLoader.fromContext();
			final Class<?> slf4jTraceeBackendProviderClass = Class.forName("io.tracee.backend.slf4j.Slf4jTraceeBackendProvider", true, classLoader);
			final TraceeBackendProvider instance = (TraceeBackendProvider) slf4jTraceeBackendProviderClass.newInstance();
			updatedCache(classLoader, Collections.singleton(instance));
			return Collections.singleton(instance);
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | ClassCastException e) {
			return Collections.emptySet();
		}
	}

	/**
	 * Search for TraceeBackendProvider in the given classloader. The result is stored in a cache with the classloader
	 * as (weak) key. If no backendProvider could be found a special type of collection is stored in cache and is returned.
	 *
	 * @param cacheCopy   Working copy of the current cache (copy-on-write-cache)
	 * @param classLoader the classloader we've to search for TraceeBackendProvider
	 * @return A BackendProviderSet if we found at least one provider. Otherwise we return an EmptyBackendProviderSet.
	 */
	private Set<TraceeBackendProvider> getTraceeProviderFromClassloader(
		final Map<ClassLoader, Set<TraceeBackendProvider>> cacheCopy,
		final ClassLoader classLoader) {
		// use cache to get TraceeBackendProvider or empty results from old lookups
		Set<TraceeBackendProvider> classLoaderProviders = cacheCopy.get(classLoader);
		if (isLookupNeeded(classLoaderProviders)) {
			classLoaderProviders = loadProviders(classLoader);
			updatedCache(classLoader, classLoaderProviders);
		}

		return classLoaderProviders;
	}

	/*
	 * Helper method for #getTraceeProviderFromClassloader
	 * We do a lookup / return true if result is null and when the result is not an instance of EmptyBackendProviderSet and empty.
	 * In the last case the garbage collector kicked out our resolvers and we've to recreate them
	 */
	boolean isLookupNeeded(Set<TraceeBackendProvider> classLoaderProviders) {
		return classLoaderProviders == null || !(classLoaderProviders instanceof EmptyBackendProviderSet) && classLoaderProviders.isEmpty();
	}

	/*
	 * Helper method to update the static class cache
	 */
	private void updatedCache(final ClassLoader classLoader, final Set<TraceeBackendProvider> provider) {
		final Map<ClassLoader, Set<TraceeBackendProvider>> copyOnWriteMap = new WeakHashMap<>(providersPerClassloader);
		if (!provider.isEmpty()) {
			copyOnWriteMap.put(classLoader, new BackendProviderSet(provider));
		} else {
			copyOnWriteMap.put(classLoader, new EmptyBackendProviderSet());
		}
		providersPerClassloader = copyOnWriteMap;
	}

	/**
	 * Loads the list of providers with the java ServiceLoader.<br />
	 * <p>Test information:<br />
	 * I tried to implement a test for such method. But it's really complicated:
	 * * We have to implement an own "mocked" classloader that simulates ClassLoader#getResources() calls. The returned list of URLs
	 * is opened by the ServiceLoader.<br />
	 * * Because we couldn't simulate N different loader scenarios we should return URLs with an own URLStreamHandler.
	 * Every StreamHandler returns a text InputStream on the getInputStream-Method and return a text that points to a classname.<br />
	 * * Our mocked classloader could/should simulate such loader classes<br />
	 * <br />
	 * Due such cases I reviewed the code and keep it untested :-(
	 * <p/>
	 * </p>
	 *
	 * @param classloader the classloader that is searched for TraceeBackendProvider services
	 * @return A list of available TraceeBackendProvider
	 */
	private Set<TraceeBackendProvider> loadProviders(ClassLoader classloader) {
		final ServiceLoader<TraceeBackendProvider> loader = ServiceLoader.load(TraceeBackendProvider.class, classloader);
		final Iterator<TraceeBackendProvider> providerIterator = loader.iterator();
		final Set<TraceeBackendProvider> traceeProvider = new HashSet<>();
		while (providerIterator.hasNext()) {
			try {
				traceeProvider.add(providerIterator.next());
			} catch (ServiceConfigurationError ignored) {
				// ignore, because it can happen when multiple providers are present and some of
				// them are not class loader compatible with our API.
			}
		}
		return traceeProvider;
	}

	static final class GetClassLoader implements PrivilegedAction<ClassLoader> {
		private final Class<?> clazz;

		private GetClassLoader(final Class<?> clazz) {
			this.clazz = clazz;
		}

		public ClassLoader run() {
			if (clazz != null) {
				return clazz.getClassLoader();
			} else {
				return Thread.currentThread().getContextClassLoader();
			}
		}

		public static ClassLoader fromContext() {
			return doPrivileged(new GetClassLoader(null));
		}

		public static ClassLoader fromClass(Class<?> clazz) {
			if (clazz == null) {
				throw new IllegalArgumentException("Class is null");
			}
			return doPrivileged(new GetClassLoader(clazz));
		}

		private static ClassLoader doPrivileged(GetClassLoader action) {
			if (System.getSecurityManager() != null) {
				return AccessController.doPrivileged(action);
			} else {
				return action.run();
			}
		}
	}

	static final class EmptyBackendProviderSet extends AbstractSet<TraceeBackendProvider> {

		@Override
		public Iterator<TraceeBackendProvider> iterator() {
			return Collections.<TraceeBackendProvider>emptyList().iterator();
		}

		@Override
		public int size() {
			return 0;
		}
	}
}


<|start_filename|>binding/jaxrs2/src/main/java/io/tracee/binding/jaxrs2/TraceeClientFilter.java<|end_filename|>
package io.tracee.binding.jaxrs2;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.transport.HttpHeaderTransport;

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.ext.Provider;
import java.util.List;
import java.util.Map;

import static io.tracee.configuration.TraceeFilterConfiguration.Channel.IncomingResponse;
import static io.tracee.configuration.TraceeFilterConfiguration.Channel.OutgoingRequest;

@Provider
public class TraceeClientFilter implements ClientRequestFilter, ClientResponseFilter {

	private final TraceeBackend backend;
	private final HttpHeaderTransport transportSerialization;

	@SuppressWarnings("unused")
	public TraceeClientFilter() {
		this(Tracee.getBackend());
	}

	TraceeClientFilter(TraceeBackend backend) {
		this.backend = backend;
		this.transportSerialization = new HttpHeaderTransport();
	}

	/**
	 * This method handles the outgoing request
	 */
	@Override
	public void filter(final ClientRequestContext requestContext) {
		if (!backend.isEmpty() && backend.getConfiguration().shouldProcessContext(OutgoingRequest)) {
			final Map<String, String> filtered = backend.getConfiguration().filterDeniedParams(backend.copyToMap(), OutgoingRequest);
			requestContext.getHeaders().putSingle(TraceeConstants.TPIC_HEADER, transportSerialization.render(filtered));
		}
	}

	/**
	 * This method handles the incoming response
	 */
	@Override
	public void filter(final ClientRequestContext requestContext, final ClientResponseContext responseContext) {
		final List<String> serializedHeaders = responseContext.getHeaders().get(TraceeConstants.TPIC_HEADER);
		if (serializedHeaders != null && backend.getConfiguration().shouldProcessContext(IncomingResponse)) {
			final Map<String, String> parsed = transportSerialization.parse(serializedHeaders);
			backend.putAll(backend.getConfiguration().filterDeniedParams(parsed, IncomingResponse));
		}
	}
}


<|start_filename|>backend/threadlocal-store/src/test/java/io/tracee/backend/threadlocalstore/MdcLikeThreadLocalMapAdapterTest.java<|end_filename|>
package io.tracee.backend.threadlocalstore;

import io.tracee.ThreadLocalHashSet;
import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.is;

public class MdcLikeThreadLocalMapAdapterTest {
	private final ThreadLocalHashSet<String> traceeKeys = new ThreadLocalHashSet<>();

	private final ThreadLocalTraceeBackend unit = new ThreadLocalTraceeBackend();

	@Before
	public void setup() {
		traceeKeys.get().add("BB");
	}

	@Test
	public void shouldPutToMDC() {
		unit.put("A", "vA");
		assertThat(unit.getThreadLocalMap().get(), hasEntry("A", "vA"));
	}

	@Test
	public void shouldReturnTrueIfKeyIsInMDC() {
		unit.getThreadLocalMap().get().put("BB", "vBB");
		assertThat(unit.containsKey("BB"), is(true));
	}

	@Test
	public void shouldReturnValueFromMDC() {
		unit.getThreadLocalMap().get().put("BB", "vBB");
		assertThat(unit.get("BB"), is("vBB"));
	}

	@Test
	public void shouldCallRemoveOnMDC() {
		unit.getThreadLocalMap().get().put("BB", "vBB");
		unit.remove("BB");
		assertThat(unit.getThreadLocalMap().get().containsKey("BB"), is(false));
	}
}


<|start_filename|>binding/jms/src/test/java/io/tracee/binding/jms/TraceeMessageListenerTest.java<|end_filename|>
package io.tracee.binding.jms;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.testhelper.FieldAccessUtil;
import io.tracee.testhelper.SimpleTraceeBackend;
import io.tracee.transport.HttpHeaderTransport;
import org.hamcrest.MatcherAssert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import javax.ejb.EJB;
import javax.interceptor.InvocationContext;
import javax.jms.Message;
import java.util.HashMap;
import java.util.Map;

import static io.tracee.TraceeConstants.INVOCATION_ID_KEY;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class TraceeMessageListenerTest {

	private final HttpHeaderTransport httpHeaderTransport = new HttpHeaderTransport();
	private final SimpleTraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();
	private final TraceeMessageListener unit = new TraceeMessageListener(backend);
	private final InvocationContext invocationContext = mock(InvocationContext.class);
	private final Message message = mock(Message.class);
	private final Map<String, String> encodedContext = new HashMap<>();
	private final MdbLike mdbLike = spy(new MdbLike());

	@Before
	public void setupMocks() throws Exception {
		when(invocationContext.getMethod()).thenReturn(MdbLike.class.getMethod("onMessage", Message.class));
		when(invocationContext.getParameters()).thenReturn(new Message[]{message});
		when(invocationContext.proceed()).then(new Answer<Object>() {
			@Override
			public Object answer(InvocationOnMock invocation) throws Throwable {
				mdbLike.onMessage(message);
				return null;
			}
		});
		when(message.getStringProperty(TraceeConstants.TPIC_HEADER)).thenAnswer(new Answer<String>() {
			@Override
			public String answer(InvocationOnMock invocation) throws Throwable {
				return httpHeaderTransport.render(encodedContext);
			}
		});
	}

	@Test
	public void testDecodesFromMessage() throws Exception {
		encodedContext.put("contextFromMessage", "yes");
		encodedContext.put(INVOCATION_ID_KEY, "an invocationId");
		unit.intercept(invocationContext);
		assertThat(backend.getValuesBeforeLastClear(), hasEntry(INVOCATION_ID_KEY, "an invocationId"));
		assertThat(backend.getValuesBeforeLastClear(), hasEntry("contextFromMessage", "yes"));
		verify(mdbLike).onMessage(message);
	}

	@Test
	public void testCleansUpContextAfterProcessing() throws Exception {
		encodedContext.put("contextFromMessage", "yes");
		unit.intercept(invocationContext);
		assertThat(backend.isEmpty(), is(true));
		verify(mdbLike).onMessage(message);
	}

	@Test
	public void testInvocationIdGeneratedIfAbsent() throws Exception {
		encodedContext.put("contextFromMessage", "yes");
		unit.intercept(invocationContext);
		assertThat(backend.getValuesBeforeLastClear(), hasEntry(is(INVOCATION_ID_KEY), notNullValue()));
		verify(mdbLike).onMessage(message);
	}

	/**
	 *
	 * @see <a href="https://github.com/tracee/tracee/issues/168">TracEE Issue 168</a>
	 */
	@Test
	public void readContextWithoutUsingObjectMethods_issue168() throws Exception {
		encodedContext.put("contextFromMessage", "yes");
		unit.intercept(invocationContext);
		verify(message, never()).getObjectProperty(anyString());
	}

	@EJB
	private class MdbLike {
		public void onMessage(Message message) {
			assertThat(backend.get("contextFromMessage"), is("yes"));
		}
	}

	@Test
	public void defaultConstructorUsesTraceeBackend() {
		final TraceeMessageListener listener = new TraceeMessageListener();
		MatcherAssert.assertThat((TraceeBackend) FieldAccessUtil.getFieldVal(listener, "backend"), is(Tracee.getBackend()));
	}
}


<|start_filename|>binding/quartz/src/main/java/io/tracee/binding/quartz/TraceeJobListener.java<|end_filename|>
package io.tracee.binding.quartz;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import io.tracee.Utilities;
import io.tracee.configuration.TraceeFilterConfiguration;
import io.tracee.configuration.TraceeFilterConfiguration.Profile;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.listeners.JobListenerSupport;

import java.util.Map;

import static io.tracee.configuration.TraceeFilterConfiguration.Channel.AsyncProcess;

/**
 * Generates a invocation Id and clears the backend after the job has finished or aborted in an ungraceful way.
 * <p/>
 * This class is thread-safe.
 */
public class TraceeJobListener extends JobListenerSupport {

	private final TraceeBackend backend;

	private final String profile;

	public TraceeJobListener() {
		this(Tracee.getBackend(), Profile.DEFAULT);
	}

	public TraceeJobListener(final String profile) {
		this(Tracee.getBackend(), profile);
	}

	TraceeJobListener(final TraceeBackend backend, final String profile) {
		this.backend = backend;
		this.profile = profile;
	}

	@Override
	public String getName() {
		return "TracEE job listener";
	}

	@Override
	public void jobToBeExecuted(JobExecutionContext context) {
		final TraceeFilterConfiguration configuration = backend.getConfiguration(profile);

		if (configuration.shouldProcessContext(AsyncProcess)) {
			@SuppressWarnings("unchecked")
			final Map<String, String> traceeContext = (Map<String, String>) context.getMergedJobDataMap().get(TraceeConstants.TPIC_HEADER);

			if (traceeContext != null && !traceeContext.isEmpty()) {
				final Map<String, String> filteredContext = configuration.filterDeniedParams(traceeContext, AsyncProcess);
				backend.putAll(filteredContext);
			}
		}

		Utilities.generateInvocationIdIfNecessary(backend);
	}

	@Override
	public void jobExecutionVetoed(JobExecutionContext context) {
		backend.clear();
	}

	@Override
	public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
		backend.clear();
	}
}


<|start_filename|>binding/cxf/src/test/java/io/tracee/binding/cxf/testSoapService/HelloWorldTestServiceImpl.java<|end_filename|>
package io.tracee.binding.cxf.testSoapService;

import io.tracee.TraceeBackend;
import io.tracee.TraceeConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorldTestServiceImpl implements HelloWorldTestService {

	private final TraceeBackend backend;

	private static final Logger LOGGER = LoggerFactory.getLogger(HelloWorldTestServiceImpl.class);

	public HelloWorldTestServiceImpl(TraceeBackend backend) {
		this.backend = backend;
	}

	public String sayHelloWorld(String firstName) {
		backend.put(TEST_KEY, "accepted");
		LOGGER.info("sayHelloWorld called with firstname '{}'", firstName);
		return "Hello " + firstName + " || invocationId was " + backend.get(TraceeConstants.INVOCATION_ID_KEY);
	}
}


<|start_filename|>binding/springws/src/test/java/io/tracee/binding/springws/itest/testservice/TraceeEntryMethod.java<|end_filename|>
package io.tracee.binding.springws.itest.testservice;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(namespace = JaxwsTestservice.TNS,
	name = JaxwsTestservice.CURRENT_TRACEE_CONTEXT_LOCALPART)
public class TraceeEntryMethod {
}


<|start_filename|>api/src/test/java/io/tracee/BackendProviderResolverTest.java<|end_filename|>
package io.tracee;

import io.tracee.spi.TraceeBackendProvider;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import static io.tracee.BackendProviderResolver.EmptyBackendProviderSet;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.support.membermodification.MemberMatcher.method;

@RunWith(PowerMockRunner.class)
@PrepareForTest(BackendProviderResolver.class)
public class BackendProviderResolverTest {

	private BackendProviderResolver out;

	@Before
	public void before() {
		out = new BackendProviderResolver();
	}

	@Test
	public void shouldReturnTrueIfSetIsNull() {
		assertThat(out.isLookupNeeded(null), is(true));
	}

	@Test
	public void shouldReturnTrueIfSetIsEmpty() {
		assertThat(out.isLookupNeeded(Collections.<TraceeBackendProvider>emptySet()), is(true));
	}

	@Test
	public void shouldReturnFalseIfEmptySetObjectIsPresent() {
		assertThat(out.isLookupNeeded(new EmptyBackendProviderSet()), is(false));
	}

	@Test
	public void emptyProviderSetShouldReturnEmptyIterator() {
		final Iterator<TraceeBackendProvider> emptySetIter = new EmptyBackendProviderSet().iterator();
		assertThat(emptySetIter.hasNext(), is(false));
	}

	@Test
	public void emptyProviderSetShouldBeEmpty() {
		assertThat(new EmptyBackendProviderSet(), empty());
	}

	@Test(expected = UnsupportedOperationException.class)
	public void emptyProviderSetShouldBeImmutable() {
		new EmptyBackendProviderSet().add(mock(TraceeBackendProvider.class));
	}

	@Test
	public void shouldReturnClassloaderFromContext() throws Exception {
		final Set<TraceeBackendProvider> contextClassloader = new HashSet<>();
		contextClassloader.add(mock(TraceeBackendProvider.class));

		BackendProviderResolver resolver = PowerMockito.spy(new BackendProviderResolver());

		when(resolver, method(BackendProviderResolver.class, "loadProviders", ClassLoader.class))
			.withArguments(BackendProviderResolver.GetClassLoader.fromContext())
			.thenReturn(contextClassloader);
		assertThat(resolver.getBackendProviders(), is(equalTo(contextClassloader)));
	}
}


<|start_filename|>testhelper/src/main/java/io/tracee/testhelper/PermitAllTraceeFilterConfiguration.java<|end_filename|>
package io.tracee.testhelper;

import io.tracee.configuration.TraceeFilterConfiguration;

import java.util.Map;

public class PermitAllTraceeFilterConfiguration implements TraceeFilterConfiguration {

	public static final int ARBITRARY_NUMBER = 32;

	@Override
	public final boolean shouldProcessParam(String paramName, Channel channel) {
		return true;
	}

	@Override
	public final Map<String, String> filterDeniedParams(Map<String, String> unfiltered, Channel channel) {
		return unfiltered;
	}

	@Override
	public final boolean shouldProcessContext(Channel channel) {
		return true;
	}

	@Override
	public final boolean shouldGenerateInvocationId() {
		return true;
	}

	@Override
	public final int generatedInvocationIdLength() {
		return ARBITRARY_NUMBER;
	}

	@Override
	public final boolean shouldGenerateSessionId() {
		return true;
	}

	@Override
	public final int generatedSessionIdLength() {
		return ARBITRARY_NUMBER;
	}
}


<|start_filename|>core/src/test/java/io/tracee/UtilitiesTest.java<|end_filename|>
package io.tracee;

import io.tracee.testhelper.PermitAllTraceeFilterConfiguration;
import io.tracee.testhelper.SimpleTraceeBackend;
import org.junit.Test;

import java.util.regex.Pattern;

import static io.tracee.TraceeConstants.INVOCATION_ID_KEY;
import static io.tracee.TraceeConstants.SESSION_ID_KEY;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.comparesEqualTo;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isEmptyOrNullString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertTrue;

public class UtilitiesTest {

	@Test
	public void testCreateRandomAlphanumeric() {
		final String randomAlphanumeric = Utilities.createRandomAlphanumeric(32);
		assertTrue("32 alphanumeric character sequence",
			Pattern.compile("[0-9a-zA-Z]{32}").matcher(randomAlphanumeric).matches());
	}

	@Test
	public void testIsNullOrEmptyString() {
		assertThat(Utilities.isNullOrEmptyString(null), is(true));
		assertThat(Utilities.isNullOrEmptyString(""), is(true));
		assertThat(Utilities.isNullOrEmptyString(" "), is(true));
		assertThat(Utilities.isNullOrEmptyString(" \n\t"), is(true));
		assertThat(Utilities.isNullOrEmptyString("a"), is(false));
	}

	@Test
	public void shouldCreateStringWithSpecificLength() {
		final String randomAlphanumeric = Utilities.createRandomAlphanumeric(32);
		assertThat("length", randomAlphanumeric.length(), equalTo(32));
	}

	@Test
	public void shouldCreateRandomString() {
		final String randA = Utilities.createRandomAlphanumeric(10);
		final String randB = Utilities.createRandomAlphanumeric(10);
		assertThat(randA, not(containsString(randB)));
	}

	@Test
	public void shouldCreateSameHashForSameString() {
		final String hashA = Utilities.createAlphanumericHash("ABC", 20);
		final String hashB = Utilities.createAlphanumericHash("ABC", 20);
		assertThat(hashA, equalTo(hashB));
	}

	@Test
	public void shouldCreateDifferentHashForDifferentString() {
		final String hashA = Utilities.createAlphanumericHash("ABCE", 20);
		final String hashB = Utilities.createAlphanumericHash("ABCD", 20);
		assertThat(hashA, not(equalTo(hashB)));
	}

	@Test
	public void shouldCreateHashInCorrectLength() {
		final String hash = Utilities.createAlphanumericHash("ABCE", 25);
		assertThat(hash.length(), comparesEqualTo(25));
	}

	@Test
	public void shouldRepeatHashesIfLengthIsToLong() {
		final String hash = Utilities.createAlphanumericHash("ABCD", 500);
		assertThat(hash.length(), comparesEqualTo(500));
	}

	@Test
	public void shouldHandleNormalSha256Length() {
		final String hash = Utilities.createAlphanumericHash("ABCD", 77);
		assertThat(hash.length(), comparesEqualTo(77));
	}

	@Test
	public void ignoreInvocationIdGenerationIfBackendIsNull() {
		Utilities.generateInvocationIdIfNecessary(null);
		assertTrue("No exception occurred", true);
	}

	@Test
	public void dontGenerateInvocationIdIfPresentInBackend() {
		final TraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();
		backend.put(INVOCATION_ID_KEY, "ourTestId");
		Utilities.generateInvocationIdIfNecessary(backend);
		assertThat(backend.get(INVOCATION_ID_KEY), is("ourTestId"));
	}

	@Test
	public void generateInvocationIdIfNotPresentInBackend() {
		final TraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();
		Utilities.generateInvocationIdIfNecessary(backend);
		assertThat(backend.get(INVOCATION_ID_KEY), not(isEmptyOrNullString()));
	}

	@Test
	public void ignoreSessionIdGenerationIfBackendIsNull() {
		Utilities.generateSessionIdIfNecessary(null, "abc");
		assertTrue("No exception occurred", true);
	}

	@Test
	public void dontGenerateSessionIdIfPresentInBackend() {
		final TraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();
		backend.put(SESSION_ID_KEY, "ourTestId");
		Utilities.generateSessionIdIfNecessary(backend, "123");
		assertThat(backend.get(SESSION_ID_KEY), is("ourTestId"));
	}

	@Test
	public void generateSessionIdIfNotPresentInBackend() {
		final TraceeBackend backend = SimpleTraceeBackend.createNonLoggingAllPermittingBackend();
		Utilities.generateSessionIdIfNecessary(backend, "123");
		assertThat(backend.get(SESSION_ID_KEY), equalTo(Utilities.createAlphanumericHash("123",
			PermitAllTraceeFilterConfiguration.ARBITRARY_NUMBER)));
	}
}


<|start_filename|>testhelper/src/main/java/io/tracee/testhelper/PortUtil.java<|end_filename|>
package io.tracee.testhelper;

import java.util.Random;

public final class PortUtil {

	public static int randomTestPort() {
		int port;
		//noinspection StatementWithEmptyBody
		while ((port = new Random().nextInt(65536)) < 10000) {
		}
		return port;
	}

	private PortUtil() {
	}
}


<|start_filename|>binding/jaxws/src/main/java/io/tracee/binding/jaxws/TraceeClientHandler.java<|end_filename|>
package io.tracee.binding.jaxws;

import io.tracee.Tracee;
import io.tracee.TraceeBackend;
import io.tracee.transport.SoapHeaderTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.util.Map;

import static io.tracee.configuration.TraceeFilterConfiguration.Channel.IncomingResponse;
import static io.tracee.configuration.TraceeFilterConfiguration.Channel.OutgoingRequest;

public class TraceeClientHandler extends AbstractTraceeHandler {

	private static final Logger logger = LoggerFactory.getLogger(TraceeClientHandler.class);

	private final SoapHeaderTransport transportSerialization = new SoapHeaderTransport();

	public TraceeClientHandler() {
		this(Tracee.getBackend());
	}

	public TraceeClientHandler(TraceeBackend traceeBackend) {
		super(traceeBackend);
	}

	@Override
	public final boolean handleFault(final SOAPMessageContext context) {
		return true;
	}

	protected final void handleIncoming(final SOAPMessageContext context) {

		final SOAPMessage msg = context.getMessage();
		if (msg != null && traceeBackend.getConfiguration().shouldProcessContext(OutgoingRequest)) {

			try {
				final SOAPHeader header = msg.getSOAPHeader();

				if (header != null) {
					final Map<String, String> parsedContext = transportSerialization.parseSoapHeader(header);
					traceeBackend.putAll(traceeBackend.getConfiguration().filterDeniedParams(parsedContext, OutgoingRequest));
				}
			} catch (final SOAPException e) {
				logger.warn("Error during precessing of inbound soap header: " + e.getMessage());
				logger.debug("Detailed: Error during precessing of inbound soap header: {}", e.getMessage(), e);
			}
		}
	}

	protected final void handleOutgoing(final SOAPMessageContext context) {

		final SOAPMessage msg = context.getMessage();
		if (msg != null && !traceeBackend.isEmpty() && traceeBackend.getConfiguration().shouldProcessContext(IncomingResponse)) {

			try {
				final SOAPHeader header = getOrCreateHeader(msg);

				final Map<String, String> filteredContext = traceeBackend.getConfiguration().filterDeniedParams(traceeBackend.copyToMap(), IncomingResponse);
				transportSerialization.renderSoapHeader(filteredContext, header);

				msg.saveChanges();
			} catch (final SOAPException e) {
				logger.warn("TraceeClientHandler : Exception occurred during processing of outbound message.", e);
			}
		}
	}
}
