diff --git a/src/main/java/org/influxdb/impl/InfluxDBImpl.java b/src/main/java/org/influxdb/impl/InfluxDBImpl.java index 366b0e729..096230c36 100644 --- a/src/main/java/org/influxdb/impl/InfluxDBImpl.java +++ b/src/main/java/org/influxdb/impl/InfluxDBImpl.java @@ -123,12 +123,13 @@ public InfluxDBImpl(final String url, final String username, final String passwo setLogLevel(LOG_LEVEL); this.gzipRequestInterceptor = new GzipRequestInterceptor(); - client.addInterceptor(loggingInterceptor).addInterceptor(gzipRequestInterceptor); + OkHttpClient.Builder clonedBuilder = client.build().newBuilder(); + clonedBuilder.addInterceptor(loggingInterceptor).addInterceptor(gzipRequestInterceptor); Factory converterFactory = null; switch (responseFormat) { case MSGPACK: - client.addInterceptor(chain -> { + clonedBuilder.addInterceptor(chain -> { Request request = chain.request().newBuilder().addHeader("Accept", APPLICATION_MSGPACK) .addHeader("Accept-Encoding", "identity").build(); return chain.proceed(request); @@ -147,8 +148,8 @@ public InfluxDBImpl(final String url, final String username, final String passwo break; } - this.retrofit = new Retrofit.Builder().baseUrl(url).client(client.build()).addConverterFactory(converterFactory) - .build(); + this.retrofit = new Retrofit.Builder().baseUrl(url).client( + clonedBuilder.build()).addConverterFactory(converterFactory).build(); this.influxDBService = this.retrofit.create(InfluxDBService.class); } @@ -171,8 +172,9 @@ public InfluxDBImpl(final String url, final String username, final String passwo setLogLevel(LOG_LEVEL); this.gzipRequestInterceptor = new GzipRequestInterceptor(); + OkHttpClient.Builder clonedBuilder = client.build().newBuilder(); this.retrofit = new Retrofit.Builder().baseUrl(url) - .client(client.addInterceptor(loggingInterceptor).addInterceptor(gzipRequestInterceptor).build()) + .client(clonedBuilder.addInterceptor(loggingInterceptor).addInterceptor(gzipRequestInterceptor).build()) .addConverterFactory(MoshiConverterFactory.create()).build(); this.influxDBService = influxDBService; diff --git a/src/test/java/org/influxdb/InfluxDBTest.java b/src/test/java/org/influxdb/InfluxDBTest.java index df7835b97..d5af2bf2c 100644 --- a/src/test/java/org/influxdb/InfluxDBTest.java +++ b/src/test/java/org/influxdb/InfluxDBTest.java @@ -18,6 +18,8 @@ import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; +import okhttp3.OkHttpClient; + import java.io.IOException; import java.time.Instant; import java.time.ZoneId; @@ -27,7 +29,9 @@ import java.util.List; import java.util.Set; import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadFactory; @@ -891,5 +895,62 @@ public void testMessagePackOnOldDbVersion() { influxDB.describeDatabases(); }); } - + + /** + * test for issue #445 + * make sure reusing of OkHttpClient.Builder causes no error + * @throws InterruptedException + */ + @Test + public void testIssue445() throws InterruptedException { + ExecutorService executor = Executors.newFixedThreadPool(100); + + final int maxCallables = 10_000; + List> callableList = new ArrayList<>(maxCallables); + for (int i = 0; i < maxCallables; i++) { + callableList.add(new Callable() { + @Override + public String call() throws Exception { + MyInfluxDBBean myBean = new MyInfluxDBBean(); + return myBean.connectAndDoNothing1(); + } + }); + } + executor.invokeAll(callableList); + executor.shutdown(); + if (!executor.awaitTermination(20, TimeUnit.SECONDS)) { + executor.shutdownNow(); + } + Assertions.assertTrue(MyInfluxDBBean.OK); + //assert that MyInfluxDBBean.OKHTTP_BUILDER stays untouched (no interceptor added) + Assertions.assertTrue(MyInfluxDBBean.OKHTTP_BUILDER.interceptors().isEmpty()); + } + + private static final class MyInfluxDBBean { + + static final OkHttpClient.Builder OKHTTP_BUILDER = new OkHttpClient.Builder(); + static Boolean OK = true; + static final String URL = "http://" + TestUtils.getInfluxIP() + ":" + TestUtils.getInfluxPORT(true); + + InfluxDB influxClient; + + String connectAndDoNothing1() { + synchronized (OK) { + if (!OK) { + return null; + } + } + try { + influxClient = InfluxDBFactory.connect(URL, "admin", "admin", OKHTTP_BUILDER); + influxClient.close(); + } catch (Exception e) { + synchronized (OK) { + if (OK) { + OK = false; + } + } + } + return null; + } + } }