Skip to content

Commit e8cb0d8

Browse files
authored
Let #executorService() takes precedence over #register() (#3886)
* Let ClientBuilder#executorService takes precedence over ClientBuilder#register(<@ClientAsyncExecutor>) Signed-off-by: Jan Supol <[email protected]>
1 parent 4cc873a commit e8cb0d8

File tree

3 files changed

+84
-61
lines changed

3 files changed

+84
-61
lines changed

core-client/src/main/java/org/glassfish/jersey/client/JerseyClient.java

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ public SSLContext getDefaultSslContext() {
7171
private final LinkedBlockingDeque<WeakReference<JerseyClient.ShutdownHook>> shutdownHooks =
7272
new LinkedBlockingDeque<WeakReference<JerseyClient.ShutdownHook>>();
7373
private final ReferenceQueue<JerseyClient.ShutdownHook> shReferenceQueue = new ReferenceQueue<JerseyClient.ShutdownHook>();
74-
private final ExecutorService executorService;
75-
private final ScheduledExecutorService scheduledExecutorService;
7674

7775
/**
7876
* Client instance shutdown hook.
@@ -134,39 +132,6 @@ protected JerseyClient(final Configuration config,
134132
this(config, sslContextProvider, verifier, null);
135133
}
136134

137-
/**
138-
* Create a new Jersey client instance.
139-
*
140-
* @param config jersey client configuration.
141-
* @param sslContext jersey client SSL context.
142-
* @param verifier jersey client host name verifier.
143-
* @param defaultSslContextProvider default SSL context provider.
144-
*/
145-
protected JerseyClient(final Configuration config,
146-
final SSLContext sslContext,
147-
final HostnameVerifier verifier,
148-
final DefaultSslContextProvider defaultSslContextProvider,
149-
ExecutorService executorService,
150-
ScheduledExecutorService scheduledExecutorService) {
151-
this(config, sslContext == null ? null : Values.unsafe(sslContext), verifier,
152-
defaultSslContextProvider, executorService, scheduledExecutorService);
153-
}
154-
155-
/**
156-
* Create a new Jersey client instance.
157-
*
158-
* @param config jersey client configuration.
159-
* @param sslContextProvider jersey client SSL context provider.
160-
* @param verifier jersey client host name verifier.
161-
*/
162-
protected JerseyClient(final Configuration config,
163-
final UnsafeValue<SSLContext, IllegalStateException> sslContextProvider,
164-
final HostnameVerifier verifier,
165-
ExecutorService executorService,
166-
ScheduledExecutorService scheduledExecutorService) {
167-
this(config, sslContextProvider, verifier, null, executorService, scheduledExecutorService);
168-
}
169-
170135
/**
171136
* Create a new Jersey client instance.
172137
*
@@ -180,15 +145,6 @@ protected JerseyClient(final Configuration config,
180145
final UnsafeValue<SSLContext, IllegalStateException> sslContextProvider,
181146
final HostnameVerifier verifier,
182147
final DefaultSslContextProvider defaultSslContextProvider) {
183-
this(config, sslContextProvider, verifier, defaultSslContextProvider, null, null);
184-
}
185-
186-
protected JerseyClient(final Configuration config,
187-
final UnsafeValue<SSLContext, IllegalStateException> sslContextProvider,
188-
final HostnameVerifier verifier,
189-
final DefaultSslContextProvider defaultSslContextProvider,
190-
ExecutorService executorService,
191-
ScheduledExecutorService scheduledExecutorService) {
192148
this.config = config == null ? new ClientConfig(this) : new ClientConfig(this, config);
193149

194150
if (sslContextProvider == null) {
@@ -216,8 +172,6 @@ protected JerseyClient(final Configuration config,
216172
}
217173

218174
this.hostnameVerifier = verifier;
219-
this.executorService = executorService;
220-
this.scheduledExecutorService = scheduledExecutorService;
221175
}
222176

223177
@Override
@@ -430,11 +384,11 @@ public HostnameVerifier getHostnameVerifier() {
430384
}
431385

432386
public ExecutorService getExecutorService() {
433-
return executorService;
387+
return config.getExecutorService();
434388
}
435389

436390
public ScheduledExecutorService getScheduledExecutorService() {
437-
return scheduledExecutorService;
391+
return config.getScheduledExecutorService();
438392
}
439393

440394
@Override

core-client/src/main/java/org/glassfish/jersey/client/JerseyClientBuilder.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ public class JerseyClientBuilder extends ClientBuilder {
4444
private HostnameVerifier hostnameVerifier;
4545
private SslConfigurator sslConfigurator;
4646
private SSLContext sslContext;
47-
private ExecutorService executorService;
48-
private ScheduledExecutorService scheduledExecutorService;
4947

5048
/**
5149
* Create a new custom-configured {@link JerseyClient} instance.
@@ -124,13 +122,13 @@ public JerseyClientBuilder hostnameVerifier(HostnameVerifier hostnameVerifier) {
124122

125123
@Override
126124
public ClientBuilder executorService(ExecutorService executorService) {
127-
this.executorService = executorService;
125+
config.executorService(executorService);
128126
return this;
129127
}
130128

131129
@Override
132130
public ClientBuilder scheduledExecutorService(ScheduledExecutorService scheduledExecutorService) {
133-
this.scheduledExecutorService = scheduledExecutorService;
131+
config.scheduledExecutorService(scheduledExecutorService);
134132
return this;
135133
}
136134

@@ -157,8 +155,7 @@ public ClientBuilder readTimeout(long timeout, TimeUnit unit) {
157155
@Override
158156
public JerseyClient build() {
159157
if (sslContext != null) {
160-
return new JerseyClient(config, sslContext, hostnameVerifier, null, executorService,
161-
scheduledExecutorService);
158+
return new JerseyClient(config, sslContext, hostnameVerifier, null);
162159
} else if (sslConfigurator != null) {
163160
final SslConfigurator sslConfiguratorCopy = sslConfigurator.copy();
164161
return new JerseyClient(
@@ -169,10 +166,9 @@ public SSLContext get() {
169166
return sslConfiguratorCopy.createSSLContext();
170167
}
171168
}),
172-
hostnameVerifier, executorService, scheduledExecutorService);
169+
hostnameVerifier);
173170
} else {
174-
return new JerseyClient(config, (UnsafeValue<SSLContext, IllegalStateException>) null, hostnameVerifier,
175-
executorService, scheduledExecutorService);
171+
return new JerseyClient(config, (UnsafeValue<SSLContext, IllegalStateException>) null, hostnameVerifier);
176172
}
177173
}
178174

tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/ExecutorServiceProviderTest.java

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@
1616

1717
package org.glassfish.jersey.tests.e2e;
1818

19+
import java.io.IOException;
1920
import java.util.Collection;
2021
import java.util.Collections;
2122
import java.util.IdentityHashMap;
2223
import java.util.List;
24+
import java.util.HashSet;
2325
import java.util.Set;
2426
import java.util.concurrent.Callable;
27+
import java.util.concurrent.CountDownLatch;
2528
import java.util.concurrent.ExecutionException;
2629
import java.util.concurrent.ExecutorService;
2730
import java.util.concurrent.Executors;
@@ -37,6 +40,8 @@
3740
import javax.ws.rs.Produces;
3841
import javax.ws.rs.client.Client;
3942
import javax.ws.rs.client.ClientBuilder;
43+
import javax.ws.rs.client.ClientRequestContext;
44+
import javax.ws.rs.client.ClientRequestFilter;
4045
import javax.ws.rs.container.AsyncResponse;
4146
import javax.ws.rs.container.Suspended;
4247
import javax.ws.rs.core.Application;
@@ -52,6 +57,7 @@
5257
import org.glassfish.jersey.test.JerseyTest;
5358
import org.junit.Test;
5459
import static org.junit.Assert.assertEquals;
60+
import static org.junit.Assert.assertTrue;
5561

5662
/**
5763
* {@link org.glassfish.jersey.spi.ExecutorServiceProvider} E2E tests.
@@ -137,17 +143,21 @@ public void dispose(final ExecutorService executorService) {
137143
executorService.shutdownNow();
138144
}
139145

140-
private class CustomExecutorService implements ExecutorService {
146+
/* package private */ class CustomExecutorService implements ExecutorService {
141147

142148
private final ExecutorService delegate;
143149
private final AtomicBoolean isCleanedUp;
144150

145151
public CustomExecutorService() {
146-
this.isCleanedUp = new AtomicBoolean(false);
147-
this.delegate = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
152+
this(Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
148153
.setNameFormat("async-request-%d")
149154
.setUncaughtExceptionHandler(new JerseyProcessingUncaughtExceptionHandler())
150-
.build());
155+
.build()));
156+
}
157+
158+
public CustomExecutorService(ExecutorService delegate) {
159+
this.isCleanedUp = new AtomicBoolean(false);
160+
this.delegate = delegate;
151161

152162
executorCreationCount++;
153163
executors.add(this);
@@ -231,6 +241,17 @@ public void execute(Runnable command) {
231241
}
232242
}
233243

244+
public static class SecondCustomExecutorProvider extends CustomExecutorProvider {
245+
public static final String NAME_FORMAT = "second-async-request";
246+
247+
public ExecutorService getExecutorService() {
248+
return new CustomExecutorService(Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
249+
.setNameFormat(NAME_FORMAT + "-%d")
250+
.setUncaughtExceptionHandler(new JerseyProcessingUncaughtExceptionHandler())
251+
.build()));
252+
}
253+
}
254+
234255
private static final CustomExecutorProvider serverExecutorProvider = new CustomExecutorProvider();
235256

236257
@Override
@@ -355,4 +376,56 @@ public void testCustomNamedServerExecutorsInjectionAndReleasing() throws Excepti
355376

356377
setUp(); // re-starting test container to ensure proper post-test tearDown.
357378
}
379+
380+
@Test
381+
public void testClientBuilderExecutorServiceTakesPrecedenceOverRegistered() throws Exception {
382+
serverExecutorProvider.reset();
383+
CountDownLatch nameLatch = new CountDownLatch(1);
384+
Set<String> threadName = new HashSet<>(1);
385+
386+
final CustomExecutorProvider executorProvider = new CustomExecutorProvider();
387+
Client client = ClientBuilder.newBuilder().register(new ClientRequestFilter() {
388+
@Override
389+
public void filter(ClientRequestContext requestContext) throws IOException {
390+
threadName.add(Thread.currentThread().getName());
391+
nameLatch.countDown();
392+
}
393+
}).executorService(new SecondCustomExecutorProvider().getExecutorService()).register(executorProvider).build();
394+
395+
client.target(getBaseUri()).path("resource").request().async().get(String.class).get();
396+
assertTrue(nameLatch.await(10, TimeUnit.SECONDS));
397+
assertEquals(threadName.size(), 1);
398+
assertTrue(threadName.iterator().next().startsWith(SecondCustomExecutorProvider.NAME_FORMAT));
399+
400+
tearDown(); // stopping test container
401+
client.close();
402+
403+
setUp(); // re-starting test container to ensure proper post-test tearDown.
404+
}
405+
406+
@Test
407+
public void testRegisteredExecutorServiceDoesNotTakesPrecedenceOverClientBuilder() throws Exception {
408+
serverExecutorProvider.reset();
409+
CountDownLatch nameLatch = new CountDownLatch(1);
410+
Set<String> threadName = new HashSet<>(1);
411+
412+
final CustomExecutorProvider executorProvider = new CustomExecutorProvider();
413+
Client client = ClientBuilder.newBuilder().register(executorProvider).register(new ClientRequestFilter() {
414+
@Override
415+
public void filter(ClientRequestContext requestContext) throws IOException {
416+
threadName.add(Thread.currentThread().getName());
417+
nameLatch.countDown();
418+
}
419+
}).executorService(new SecondCustomExecutorProvider().getExecutorService()).build();
420+
421+
client.target(getBaseUri()).path("resource").request().async().get(String.class).get();
422+
assertTrue(nameLatch.await(10, TimeUnit.SECONDS));
423+
assertEquals(threadName.size(), 1);
424+
assertTrue(threadName.iterator().next().startsWith(SecondCustomExecutorProvider.NAME_FORMAT));
425+
426+
tearDown(); // stopping test container
427+
client.close();
428+
429+
setUp(); // re-starting test container to ensure proper post-test tearDown.
430+
}
358431
}

0 commit comments

Comments
 (0)