From c55789139071e160214508c4041acc29dfc5fc37 Mon Sep 17 00:00:00 2001 From: Hoan Xuan Le Date: Thu, 26 Jul 2018 13:22:21 +0700 Subject: [PATCH] fix issue #445 : https://github.com/influxdata/influxdb-java/issues/445 --- .../java/org/influxdb/impl/InfluxDBImpl.java | 12 ++- src/test/java/org/influxdb/InfluxDBTest.java | 94 +++++++++++++++---- 2 files changed, 85 insertions(+), 21 deletions(-) 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..606dc471f 100644 --- a/src/test/java/org/influxdb/InfluxDBTest.java +++ b/src/test/java/org/influxdb/InfluxDBTest.java @@ -1,5 +1,23 @@ package org.influxdb; +import java.io.IOException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +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; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + import org.influxdb.InfluxDB.LogLevel; import org.influxdb.InfluxDB.ResponseFormat; import org.influxdb.dto.BatchPoints; @@ -18,21 +36,7 @@ import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; -import java.io.IOException; -import java.time.Instant; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; +import okhttp3.OkHttpClient; /** * Test the InfluxDB API. @@ -891,5 +895,63 @@ 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(); + } + }); + } + System.out.println("Invoking all callableList (size()=" + callableList.size() + ")"); + executor.invokeAll(callableList); + System.out.println("Shutting down..."); + executor.shutdown(); + System.out.println("Shutdown requested and waiting for termination..."); + 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 volatile Boolean OK = true; + + InfluxDB influxClient; + + String connectAndDoNothing1() { + if (!OK) { + return null; + } + try { + influxClient = InfluxDBFactory.connect("http://127.0.0.1:8086", "admin", "admin", OKHTTP_BUILDER); + influxClient.close(); + } catch (Exception e) { + synchronized (OK) { + if (OK) { + OK = false; + } + } + + } + return null; + } + } }