diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6c68c121c3b..9094260fd11 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,12 @@
## 6.7.0 [unreleased]
### Features
-1. [#439](https://github.com/influxdata/influxdb-client-java/pull/439): Added `FluxRecord.getRow()` which stores response data in a list
+1. [#439](https://github.com/influxdata/influxdb-client-java/pull/439): Add `FluxRecord.getRow()` which stores response data in a list
### Dependencies
+
+1. [#446](https://github.com/influxdata/influxdb-client-java/pull/446): Remove `gson-fire`
+
Update dependencies:
#### Build:
diff --git a/client/pom.xml b/client/pom.xml
index d004b94864b..65b1e8b3803 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -132,11 +132,6 @@
adapter-rxjava3
-
- io.gsonfire
- gson-fire
-
-
com.squareup.retrofit2
converter-scalars
diff --git a/client/src/generated/java/com/influxdb/client/JSON.java b/client/src/generated/java/com/influxdb/client/JSON.java
index a102d5a6857..389bab0887d 100644
--- a/client/src/generated/java/com/influxdb/client/JSON.java
+++ b/client/src/generated/java/com/influxdb/client/JSON.java
@@ -13,24 +13,7 @@
package com.influxdb.client;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonIOException;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonSerializer;
-import com.google.gson.TypeAdapter;
-import com.google.gson.internal.bind.util.ISO8601Utils;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import com.google.gson.JsonElement;
-import io.gsonfire.GsonFireBuilder;
-import io.gsonfire.TypeSelector;
-
-import com.influxdb.client.domain.*;
-
import java.io.IOException;
-import java.io.StringReader;
-import java.lang.reflect.Type;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
@@ -40,138 +23,97 @@
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;
-import java.util.Locale;
+import java.util.LinkedHashMap;
import java.util.Map;
-import java.util.HashMap;
+
+import javax.annotation.Nonnull;
+
+import com.influxdb.client.domain.*;
+import com.influxdb.utils.Arguments;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonIOException;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.internal.bind.util.ISO8601Utils;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
public class JSON {
private Gson gson;
- private DateTypeAdapter dateTypeAdapter = new DateTypeAdapter();
- private SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter();
- private OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
- private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
public static GsonBuilder createGson() {
- GsonFireBuilder fireBuilder = new GsonFireBuilder()
- .registerTypeSelector(Check.class, new TypeSelector() {
- @Override
- public Class getClassForElement(JsonElement readElement) {
- Map classByDiscriminatorValue = new HashMap();
- classByDiscriminatorValue.put("deadman".toUpperCase(Locale.ROOT), DeadmanCheck.class);
- classByDiscriminatorValue.put("threshold".toUpperCase(Locale.ROOT), ThresholdCheck.class);
- classByDiscriminatorValue.put("custom".toUpperCase(Locale.ROOT), CustomCheck.class);
- classByDiscriminatorValue.put("Check".toUpperCase(Locale.ROOT), Check.class);
- return getClassByDiscriminator(
- classByDiscriminatorValue,
- getDiscriminatorValue(readElement, "type"));
- }
- })
- .registerTypeSelector(CheckDiscriminator.class, new TypeSelector() {
- @Override
- public Class getClassForElement(JsonElement readElement) {
- Map classByDiscriminatorValue = new HashMap();
- classByDiscriminatorValue.put("deadman".toUpperCase(Locale.ROOT), DeadmanCheck.class);
- classByDiscriminatorValue.put("threshold".toUpperCase(Locale.ROOT), ThresholdCheck.class);
- classByDiscriminatorValue.put("custom".toUpperCase(Locale.ROOT), CustomCheck.class);
- classByDiscriminatorValue.put("CheckDiscriminator".toUpperCase(Locale.ROOT), CheckDiscriminator.class);
- return getClassByDiscriminator(
- classByDiscriminatorValue,
- getDiscriminatorValue(readElement, "type"));
- }
- })
- .registerTypeSelector(NotificationEndpoint.class, new TypeSelector() {
- @Override
- public Class getClassForElement(JsonElement readElement) {
- Map classByDiscriminatorValue = new HashMap();
- classByDiscriminatorValue.put("slack".toUpperCase(Locale.ROOT), SlackNotificationEndpoint.class);
- classByDiscriminatorValue.put("pagerduty".toUpperCase(Locale.ROOT), PagerDutyNotificationEndpoint.class);
- classByDiscriminatorValue.put("http".toUpperCase(Locale.ROOT), HTTPNotificationEndpoint.class);
- classByDiscriminatorValue.put("telegram".toUpperCase(Locale.ROOT), TelegramNotificationEndpoint.class);
- classByDiscriminatorValue.put("NotificationEndpoint".toUpperCase(Locale.ROOT), NotificationEndpoint.class);
- return getClassByDiscriminator(
- classByDiscriminatorValue,
- getDiscriminatorValue(readElement, "type"));
- }
- })
- .registerTypeSelector(NotificationEndpointDiscriminator.class, new TypeSelector() {
- @Override
- public Class getClassForElement(JsonElement readElement) {
- Map classByDiscriminatorValue = new HashMap();
- classByDiscriminatorValue.put("slack".toUpperCase(Locale.ROOT), SlackNotificationEndpoint.class);
- classByDiscriminatorValue.put("pagerduty".toUpperCase(Locale.ROOT), PagerDutyNotificationEndpoint.class);
- classByDiscriminatorValue.put("http".toUpperCase(Locale.ROOT), HTTPNotificationEndpoint.class);
- classByDiscriminatorValue.put("telegram".toUpperCase(Locale.ROOT), TelegramNotificationEndpoint.class);
- classByDiscriminatorValue.put("NotificationEndpointDiscriminator".toUpperCase(Locale.ROOT), NotificationEndpointDiscriminator.class);
- return getClassByDiscriminator(
- classByDiscriminatorValue,
- getDiscriminatorValue(readElement, "type"));
- }
- })
- .registerTypeSelector(NotificationRule.class, new TypeSelector() {
- @Override
- public Class getClassForElement(JsonElement readElement) {
- Map classByDiscriminatorValue = new HashMap();
- classByDiscriminatorValue.put("slack".toUpperCase(Locale.ROOT), SlackNotificationRule.class);
- classByDiscriminatorValue.put("smtp".toUpperCase(Locale.ROOT), SMTPNotificationRule.class);
- classByDiscriminatorValue.put("pagerduty".toUpperCase(Locale.ROOT), PagerDutyNotificationRule.class);
- classByDiscriminatorValue.put("http".toUpperCase(Locale.ROOT), HTTPNotificationRule.class);
- classByDiscriminatorValue.put("telegram".toUpperCase(Locale.ROOT), TelegramNotificationRule.class);
- classByDiscriminatorValue.put("NotificationRule".toUpperCase(Locale.ROOT), NotificationRule.class);
- return getClassByDiscriminator(
- classByDiscriminatorValue,
- getDiscriminatorValue(readElement, "type"));
- }
- })
- .registerTypeSelector(NotificationRuleDiscriminator.class, new TypeSelector() {
- @Override
- public Class getClassForElement(JsonElement readElement) {
- Map classByDiscriminatorValue = new HashMap();
- classByDiscriminatorValue.put("slack".toUpperCase(Locale.ROOT), SlackNotificationRule.class);
- classByDiscriminatorValue.put("smtp".toUpperCase(Locale.ROOT), SMTPNotificationRule.class);
- classByDiscriminatorValue.put("pagerduty".toUpperCase(Locale.ROOT), PagerDutyNotificationRule.class);
- classByDiscriminatorValue.put("http".toUpperCase(Locale.ROOT), HTTPNotificationRule.class);
- classByDiscriminatorValue.put("telegram".toUpperCase(Locale.ROOT), TelegramNotificationRule.class);
- classByDiscriminatorValue.put("NotificationRuleDiscriminator".toUpperCase(Locale.ROOT), NotificationRuleDiscriminator.class);
- return getClassByDiscriminator(
- classByDiscriminatorValue,
- getDiscriminatorValue(readElement, "type"));
- }
- })
- .registerTypeSelector(Threshold.class, new TypeSelector() {
- @Override
- public Class getClassForElement(JsonElement readElement) {
- Map classByDiscriminatorValue = new HashMap();
- classByDiscriminatorValue.put("greater".toUpperCase(Locale.ROOT), GreaterThreshold.class);
- classByDiscriminatorValue.put("lesser".toUpperCase(Locale.ROOT), LesserThreshold.class);
- classByDiscriminatorValue.put("range".toUpperCase(Locale.ROOT), RangeThreshold.class);
- classByDiscriminatorValue.put("Threshold".toUpperCase(Locale.ROOT), Threshold.class);
- return getClassByDiscriminator(
- classByDiscriminatorValue,
- getDiscriminatorValue(readElement, "type"));
- }
- })
+ GsonBuilder builder = new GsonBuilder();
- ;
- return fireBuilder.createGsonBuilder();
- }
-
- private static String getDiscriminatorValue(JsonElement readElement, String discriminatorField) {
- JsonElement element = readElement.getAsJsonObject().get(discriminatorField);
- if(null == element) {
- throw new IllegalArgumentException("missing discriminator field: <" + discriminatorField + ">");
- }
- return element.getAsString();
- }
-
- private static Class getClassByDiscriminator(Map classByDiscriminatorValue, String discriminatorValue) {
- Class clazz = (Class) classByDiscriminatorValue.get(discriminatorValue.toUpperCase(Locale.ROOT));
- if(null == clazz) {
- throw new IllegalArgumentException("cannot determine model class of name: <" + discriminatorValue + ">");
- }
- return clazz;
+ builder.registerTypeAdapterFactory(new DiscriminatorAdapter<>(Check.class,
+ new LinkedHashMap>() {{
+ put("deadman", DeadmanCheck.class);
+ put("threshold", ThresholdCheck.class);
+ put("custom", CustomCheck.class);
+ }}));
+
+ builder.registerTypeAdapterFactory(new DiscriminatorAdapter<>(CheckDiscriminator.class,
+ new LinkedHashMap>() {{
+ put("deadman", DeadmanCheck.class);
+ put("threshold", ThresholdCheck.class);
+ put("custom", CustomCheck.class);
+ }}));
+
+ builder.registerTypeAdapterFactory(new DiscriminatorAdapter<>(NotificationEndpoint.class,
+ new LinkedHashMap>() {{
+ put("slack", SlackNotificationEndpoint.class);
+ put("pagerduty", PagerDutyNotificationEndpoint.class);
+ put("http", HTTPNotificationEndpoint.class);
+ put("telegram", TelegramNotificationEndpoint.class);
+ }}));
+
+ builder.registerTypeAdapterFactory(new DiscriminatorAdapter<>(NotificationEndpointDiscriminator.class,
+ new LinkedHashMap>() {{
+ put("slack", SlackNotificationEndpoint.class);
+ put("pagerduty", PagerDutyNotificationEndpoint.class);
+ put("http", HTTPNotificationEndpoint.class);
+ put("telegram", TelegramNotificationEndpoint.class);
+ }}));
+
+ builder.registerTypeAdapterFactory(new DiscriminatorAdapter<>(NotificationRule.class,
+ new LinkedHashMap>() {{
+ put("slack", SlackNotificationRule.class);
+ put("smtp", SMTPNotificationRule.class);
+ put("pagerduty", PagerDutyNotificationRule.class);
+ put("http", HTTPNotificationRule.class);
+ put("telegram", TelegramNotificationRule.class);
+ }}));
+
+ builder.registerTypeAdapterFactory(new DiscriminatorAdapter<>(NotificationRuleDiscriminator.class,
+ new LinkedHashMap>() {{
+ put("slack", SlackNotificationRule.class);
+ put("smtp", SMTPNotificationRule.class);
+ put("pagerduty", PagerDutyNotificationRule.class);
+ put("http", HTTPNotificationRule.class);
+ put("telegram", TelegramNotificationRule.class);
+ }}));
+
+ builder.registerTypeAdapterFactory(new DiscriminatorAdapter<>(Threshold.class,
+ new LinkedHashMap>() {{
+ put("greater", GreaterThreshold.class);
+ put("lesser", LesserThreshold.class);
+ put("range", RangeThreshold.class);
+ }}));
+
+ return builder;
}
public JSON() {
+ DateTypeAdapter dateTypeAdapter = new DateTypeAdapter();
+ SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter();
+ OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
+ LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
+
gson = createGson()
.registerTypeAdapter(Date.class, dateTypeAdapter)
.registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter)
@@ -246,7 +188,7 @@ public OffsetDateTime read(JsonReader in) throws IOException {
default:
String date = in.nextString();
if (date.endsWith("+0000")) {
- date = date.substring(0, date.length()-5) + "Z";
+ date = date.substring(0, date.length() - 5) + "Z";
}
return OffsetDateTime.parse(date, formatter);
}
@@ -294,16 +236,6 @@ public LocalDate read(JsonReader in) throws IOException {
}
}
- public JSON setOffsetDateTimeFormat(DateTimeFormatter dateFormat) {
- offsetDateTimeTypeAdapter.setFormat(dateFormat);
- return this;
- }
-
- public JSON setLocalDateFormat(DateTimeFormatter dateFormat) {
- localDateTypeAdapter.setFormat(dateFormat);
- return this;
- }
-
/**
* Gson TypeAdapter for java.sql.Date type
* If the dateFormat is null, a simple "yyyy-MM-dd" format will be used
@@ -316,10 +248,6 @@ public static class SqlDateTypeAdapter extends TypeAdapter {
public SqlDateTypeAdapter() {
}
- public SqlDateTypeAdapter(DateFormat dateFormat) {
- this.dateFormat = dateFormat;
- }
-
public void setFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
}
@@ -370,10 +298,6 @@ public static class DateTypeAdapter extends TypeAdapter {
public DateTypeAdapter() {
}
- public DateTypeAdapter(DateFormat dateFormat) {
- this.dateFormat = dateFormat;
- }
-
public void setFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
}
@@ -417,14 +341,93 @@ public Date read(JsonReader in) throws IOException {
}
}
- public JSON setDateFormat(DateFormat dateFormat) {
- dateTypeAdapter.setFormat(dateFormat);
- return this;
- }
+ @SuppressWarnings("unchecked")
+ static final class DiscriminatorAdapter implements TypeAdapterFactory {
+ private final Class> type;
+ private final Map> subTypes;
+ private TypeAdapter> cachedAdapter;
+
+ DiscriminatorAdapter(@Nonnull final Class type,
+ @Nonnull final Map> subTypes) {
+ Arguments.checkNotNull(type, "type");
+ Arguments.checkNotNull(subTypes, "subTypes");
+ this.type = type;
+ this.subTypes = subTypes;
+ }
- public JSON setSqlDateFormat(DateFormat dateFormat) {
- sqlDateTypeAdapter.setFormat(dateFormat);
- return this;
- }
+ @Override
+ public TypeAdapter create(Gson gson, TypeToken type) {
+ if (type == null) {
+ return null;
+ }
+
+ if (!this.type.isAssignableFrom(type.getRawType())) {
+ return null;
+ }
+
+ if (cachedAdapter == null) {
+ cachedAdapter = new InnerDiscriminatorAdapter(gson).nullSafe();
+ }
+ return (TypeAdapter) cachedAdapter;
+ }
+
+ private class InnerDiscriminatorAdapter extends TypeAdapter {
+ private final Gson gson;
+ private final TypeAdapter jsonAdapter;
+ private final Map> cachedSubtypesReadAdapters;
+ private final Map, TypeAdapter>> cachedSubtypesWriteAdapters;
+
+ InnerDiscriminatorAdapter(@Nonnull final Gson gson) {
+ Arguments.checkNotNull(gson, "gson");
+
+ this.gson = gson;
+ this.jsonAdapter = gson.getAdapter(JsonElement.class);
+ this.cachedSubtypesReadAdapters = new LinkedHashMap<>();
+ this.cachedSubtypesWriteAdapters = new LinkedHashMap<>();
+
+ for (Map.Entry> entry : subTypes.entrySet()) {
+ TypeAdapter> adapter = gson.getDelegateAdapter(DiscriminatorAdapter.this,
+ TypeToken.get(entry.getValue()));
+ cachedSubtypesReadAdapters.put(entry.getKey(), adapter);
+ cachedSubtypesWriteAdapters.put(entry.getValue(), adapter);
+ }
+ }
+
+ @Override
+ public R read(JsonReader in) throws IOException {
+ JsonObject json = jsonAdapter.read(in).getAsJsonObject();
+ JsonElement discriminatorJson = json.get("type");
+
+ if (discriminatorJson == null) {
+ String msg = String.format("Cannot find JSON field 'type' for %s adapter. JSON value: '%s'",
+ DiscriminatorAdapter.this.type, json);
+ throw new JsonParseException(msg);
+ }
+
+ String discriminator = discriminatorJson.getAsString();
+ TypeAdapter adapter = (TypeAdapter) cachedSubtypesReadAdapters.get(discriminator);
+ if (adapter == null) {
+ String msg = String.format("Cannot find model: '%s' for discriminator: '%s'. "
+ + "The discriminator wasn't registered.", discriminator, DiscriminatorAdapter.this.type);
+ throw new JsonParseException(msg);
+ }
+ return adapter.fromJsonTree(json);
+ }
+
+ @Override
+ public void write(JsonWriter out, R value) throws IOException {
+ Class> outputType = value.getClass();
+ TypeAdapter adapter = (TypeAdapter) cachedSubtypesWriteAdapters.get(outputType);
+
+ if (adapter == null) {
+ adapter = (TypeAdapter) gson.getDelegateAdapter(DiscriminatorAdapter.this,
+ TypeToken.get(outputType));
+ cachedSubtypesWriteAdapters.put(type, adapter);
+ }
+
+ jsonAdapter.write(out, adapter.toJsonTree(value).getAsJsonObject());
+ }
+ }
+ }
}
diff --git a/client/src/test/java/com/influxdb/client/JSONTest.java b/client/src/test/java/com/influxdb/client/JSONTest.java
new file mode 100644
index 00000000000..34d9f6e8137
--- /dev/null
+++ b/client/src/test/java/com/influxdb/client/JSONTest.java
@@ -0,0 +1,63 @@
+/*
+ * The MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.influxdb.client;
+
+import com.influxdb.client.domain.CheckStatusLevel;
+import com.influxdb.client.domain.Threshold;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonParseException;
+import com.google.gson.annotations.SerializedName;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class JSONTest {
+ @Test
+ public void serializeUnknownDiscriminator() {
+ DummyThreshold dummyThreshold = new DummyThreshold();
+ dummyThreshold.setLevel(CheckStatusLevel.OK);
+
+ Gson gson = JSON.createGson().create();
+ String json = gson.toJson(dummyThreshold);
+ Assertions.assertThat(json).isEqualTo("{\"type\":\"dummy\",\"value\":15,\"level\":\"OK\"}");
+ }
+
+ @Test
+ public void deSerializeUnknownDiscriminator() {
+ Gson gson = JSON.createGson().create();
+ Assertions.assertThatThrownBy(() -> {
+ gson.fromJson("{\"type\":\"not_registered\",\"value\":16,\"level\":\"OK\"}", Threshold.class);
+ })
+ .isInstanceOf(JsonParseException.class)
+ .hasMessage("Cannot find model: 'not_registered' for discriminator: "
+ + "'class com.influxdb.client.domain.Threshold'. The discriminator wasn't registered.");
+ }
+
+ @SuppressWarnings("unused")
+ public static class DummyThreshold extends Threshold {
+ @SerializedName("type")
+ private String type = "dummy";
+
+ @SerializedName("value")
+ private Integer value = 15;
+ }
+}
diff --git a/pom.xml b/pom.xml
index 406db9e92e5..bcb4871ff7b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -601,18 +601,6 @@
${dependency.gson.version}
-
- io.gsonfire
- gson-fire
- 1.8.5
-
-
- com.google.code.gson
- gson
-
-
-
-
io.reactivex.rxjava3
rxjava