View Javadoc

1   package com.atlassian.httpclient.apache.httpcomponents;
2   
3   import com.atlassian.event.api.EventPublisher;
4   import com.atlassian.httpclient.api.Response;
5   import com.atlassian.httpclient.api.ResponsePromise;
6   import com.atlassian.junit.http.jetty.JettyServer;
7   import com.atlassian.sal.api.ApplicationProperties;
8   import com.atlassian.sal.api.executor.ThreadLocalContextManager;
9   import com.google.common.base.Function;
10  import org.junit.Before;
11  import org.junit.ClassRule;
12  import org.junit.Test;
13  import org.junit.runner.RunWith;
14  import org.mockito.Mock;
15  import org.mockito.runners.MockitoJUnitRunner;
16  
17  import java.net.URL;
18  import java.net.URLClassLoader;
19  import java.util.concurrent.atomic.AtomicBoolean;
20  
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertNull;
23  import static org.junit.Assert.assertSame;
24  import static org.junit.Assert.assertTrue;
25  import static org.mockito.Mockito.when;
26  
27  @RunWith(MockitoJUnitRunner.class)
28  public final class DefaultHttpClientIntegrationTest {
29      private static final ThreadLocal<Object> TEST_THREAD_LOCAL = new ThreadLocal<Object>();
30  
31      private static final AtomicBoolean NO_OP_THREAD_LOCAL_CONTEXT_MANAGER = new AtomicBoolean(false);
32  
33      @ClassRule
34      public static final JettyServer SERVER = new JettyServer();
35  
36      private ApacheAsyncHttpClient httpClient;
37  
38      @Mock
39      private EventPublisher eventPublisher;
40  
41      @Mock
42      private ApplicationProperties applicationProperties;
43  
44      @Before
45      public void setUp() {
46          NO_OP_THREAD_LOCAL_CONTEXT_MANAGER.set(false); //By default use thread manager in all tests
47  
48          when(applicationProperties.getDisplayName()).thenReturn(DefaultHttpClientIntegrationTest.class.getSimpleName());
49          when(applicationProperties.getVersion()).thenReturn("1");
50          when(applicationProperties.getBuildNumber()).thenReturn("0001");
51  
52          httpClient = new ApacheAsyncHttpClient<Object>(eventPublisher, applicationProperties, new ThreadLocalContextManager<Object>() {
53              @Override
54              public Object getThreadLocalContext() {
55                  return NO_OP_THREAD_LOCAL_CONTEXT_MANAGER.get() ? null : TEST_THREAD_LOCAL.get();
56              }
57  
58              @Override
59              public void setThreadLocalContext(Object context) {
60                  if (!NO_OP_THREAD_LOCAL_CONTEXT_MANAGER.get()) {
61                      TEST_THREAD_LOCAL.set(context);
62                  }
63              }
64  
65              @Override
66              public void clearThreadLocalContext() {
67                  if (!NO_OP_THREAD_LOCAL_CONTEXT_MANAGER.get()) {
68                      TEST_THREAD_LOCAL.set(null);
69                  }
70              }
71          });
72      }
73  
74      @Test
75      public void threadLocalVariablesAreAvailableToFunctionsWithWorkingThreadLocalContextManager() {
76          final AtomicBoolean okFunctionCalled = new AtomicBoolean(false);
77          final long testThreadId = Thread.currentThread().getId();
78  
79          final Object objectInThreadLocal = new Object();
80          TEST_THREAD_LOCAL.set(objectInThreadLocal);
81  
82          ResponsePromise responsePromise = httpClient.newRequest(SERVER.newUri("/test")).get();
83          final Object claimedObject = httpClient.transformation().ok(new Function<Response, Object>() {
84              @Override
85              public Object apply(Response response) {
86                  okFunctionCalled.set(true);
87                  assertTrue("For this test to work the function should be executed in a separate thread!", testThreadId != Thread.currentThread().getId());
88                  assertTrue(Thread.currentThread().getName().startsWith("httpclient-callbacks"));
89                  return TEST_THREAD_LOCAL.get();
90              }
91          }).build().apply(responsePromise).claim();
92  
93          assertTrue(okFunctionCalled.get());
94          assertSame(objectInThreadLocal, claimedObject);
95      }
96  
97      @Test
98      public void threadLocalVariablesAreNotAvailableToFunctionsWithNoOpThreadLocalContextManager() {
99          NO_OP_THREAD_LOCAL_CONTEXT_MANAGER.set(true);
100 
101         final AtomicBoolean okFunctionCalled = new AtomicBoolean(false);
102         final long testThreadId = Thread.currentThread().getId();
103 
104         final Object objectInThreadLocal = new Object();
105         TEST_THREAD_LOCAL.set(objectInThreadLocal);
106 
107         ResponsePromise responsePromise = httpClient.newRequest(SERVER.newUri("/test")).get();
108         final Object claimedObject = httpClient.transformation().ok(new Function<Response, Object>() {
109             @Override
110             public Object apply(Response response) {
111                 okFunctionCalled.set(true);
112                 assertTrue("For this test to work the function should be executed in a separate thread!", testThreadId != Thread.currentThread().getId());
113                 assertTrue(Thread.currentThread().getName().startsWith("httpclient-callbacks"));
114                 return TEST_THREAD_LOCAL.get();
115             }
116         }).build().apply(responsePromise).claim();
117 
118         assertTrue(okFunctionCalled.get());
119         assertNull(claimedObject);
120     }
121 
122     @Test
123     public void contextClassLoaderSetForCallback() {
124         ClassLoader tmpClassLoader = new URLClassLoader(new URL[0]);
125         Thread.currentThread().setContextClassLoader(tmpClassLoader);
126 
127         ResponsePromise responsePromise = httpClient.newRequest(SERVER.newUri("/test")).get();
128         ClassLoader callbackClassLoader = httpClient.<ClassLoader>transformation().ok(new Function<Response, ClassLoader>() {
129             @Override
130             public ClassLoader apply(Response response) {
131                 return Thread.currentThread().getContextClassLoader();
132             }
133         }).build().apply(responsePromise).claim();
134         assertEquals(tmpClassLoader, callbackClassLoader);
135     }
136 }