Skip to content

Commit 8a0fbf7

Browse files
authored
Swtich to Gson from Jackson (#232)
* Use Gson that is included as part for protobuf
1 parent f17d4b8 commit 8a0fbf7

File tree

8 files changed

+168
-105
lines changed

8 files changed

+168
-105
lines changed

pom.xml

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
24
<modelVersion>4.0.0</modelVersion>
35
<groupId>com.microsoft.azure.functions</groupId>
46
<artifactId>azure-functions-java-worker</artifactId>
@@ -19,7 +21,7 @@
1921
</organization>
2022

2123
<properties>
22-
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
24+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
2325
<azure.functions.java.library.version>1.0.0-beta-7-SNAPSHOT</azure.functions.java.library.version>
2426
</properties>
2527

@@ -62,9 +64,9 @@
6264
<snapshots>
6365
<enabled>true</enabled>
6466
</snapshots>
65-
</repository>
67+
</repository>
6668
</repositories>
67-
69+
6870
<dependencies>
6971
<dependency>
7072
<groupId>com.microsoft.azure.functions</groupId>
@@ -90,7 +92,7 @@
9092
<groupId>io.grpc</groupId>
9193
<artifactId>grpc-netty</artifactId>
9294
<version>1.15.1</version>
93-
</dependency>
95+
</dependency>
9496
<dependency>
9597
<groupId>org.apache.commons</groupId>
9698
<artifactId>commons-lang3</artifactId>
@@ -100,25 +102,15 @@
100102
<groupId>commons-cli</groupId>
101103
<artifactId>commons-cli</artifactId>
102104
<version>1.4</version>
103-
</dependency>
104-
<dependency>
105-
<groupId>com.fasterxml.jackson.core</groupId>
106-
<artifactId>jackson-databind</artifactId>
107-
<version>2.9.7</version>
108-
</dependency>
109-
<dependency>
110-
<groupId>com.fasterxml.jackson.core</groupId>
111-
<artifactId>jackson-annotations</artifactId>
112-
<version>2.9.7</version>
113-
</dependency>
105+
</dependency>
114106
<dependency>
115107
<groupId>javax.annotation</groupId>
116108
<artifactId>javax.annotation-api</artifactId>
117109
<version>1.3.2</version>
118110
</dependency>
119111
<dependency>
120112
<groupId>junit</groupId>
121-
<artifactId>junit</artifactId>
113+
<artifactId>junit</artifactId>
122114
<scope>test</scope>
123115
</dependency>
124116
</dependencies>
@@ -172,7 +164,7 @@
172164
</executions>
173165
</plugin>
174166
<plugin>
175-
<artifactId>maven-compiler-plugin</artifactId>
167+
<artifactId>maven-compiler-plugin</artifactId>
176168
</plugin>
177169
<plugin>
178170
<artifactId>maven-shade-plugin</artifactId>
@@ -185,7 +177,8 @@
185177
</goals>
186178
<configuration>
187179
<transformers>
188-
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
180+
<transformer
181+
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
189182
<mainClass>com.microsoft.azure.functions.worker.Application</mainClass>
190183
<manifestEntries>
191184
<Implementation-Title>${project.name}</Implementation-Title>

src/main/java/com/microsoft/azure/functions/worker/binding/BindingDataStore.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
import org.apache.commons.lang3.exception.ExceptionUtils;
88

99
import com.microsoft.azure.functions.worker.broker.*;
10-
import com.fasterxml.jackson.core.JsonParseException;
11-
import com.fasterxml.jackson.databind.JsonMappingException;
1210
import com.microsoft.azure.functions.ExecutionContext;
1311
import com.microsoft.azure.functions.rpc.messages.*;
1412

@@ -56,7 +54,7 @@ public Optional<BindingData> getTriggerMetatDataByName(String name, Type target)
5654
return this.metadataSources.get(name).computeByName(name, target);
5755
}
5856

59-
public Optional<BindingData> getDataByType(Type target) throws JsonParseException, JsonMappingException, IOException {
57+
public Optional<BindingData> getDataByType(Type target) {
6058
return this.otherSources.get(ExecutionContext.class).computeByType(target);
6159
}
6260

src/main/java/com/microsoft/azure/functions/worker/binding/DataOperations.java

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import java.io.IOException;
44
import java.lang.reflect.Type;
5+
import java.util.ArrayList;
6+
import java.util.Arrays;
57
import java.util.Collection;
68
import java.util.HashMap;
79
import java.util.List;
@@ -12,13 +14,11 @@
1214
import org.apache.commons.lang3.exception.ExceptionUtils;
1315
import org.apache.commons.lang3.reflect.TypeUtils;
1416

15-
import com.fasterxml.jackson.annotation.JsonAutoDetect;
16-
import com.fasterxml.jackson.annotation.PropertyAccessor;
17-
import com.fasterxml.jackson.core.JsonParseException;
18-
import com.fasterxml.jackson.core.JsonParser;
19-
import com.fasterxml.jackson.databind.DeserializationFeature;
20-
import com.fasterxml.jackson.databind.JsonMappingException;
21-
import com.fasterxml.jackson.databind.ObjectMapper;
17+
import com.google.gson.Gson;
18+
import com.google.gson.JsonArray;
19+
import com.google.gson.JsonParser;
20+
import com.google.gson.JsonSyntaxException;
21+
import com.google.gson.reflect.*;
2222
import com.microsoft.azure.functions.worker.WorkerLogManager;
2323
import com.microsoft.azure.functions.worker.broker.CoreTypeResolver;
2424

@@ -79,7 +79,7 @@ public void addGenericTargetOperation(Type targetType, CheckedBiFunction<T, Type
7979
this.targetOperations.put(targetType, operation);
8080
}
8181

82-
Optional<R> apply(T sourceValue, Type targetType) throws JsonParseException, JsonMappingException, IOException {
82+
Optional<R> apply(T sourceValue, Type targetType) {
8383
Optional<R> resultValue = null;
8484

8585
if (sourceValue != null) {
@@ -88,25 +88,20 @@ Optional<R> apply(T sourceValue, Type targetType) throws JsonParseException, Jso
8888
if (matchingOperation != null) {
8989
resultValue = Optional.ofNullable(matchingOperation).map(op -> op.tryApply(sourceValue, targetType));
9090
} else {
91+
String sourceData = (String) sourceValue;
9192
// Try POJO
92-
ObjectMapper RELAXED_JSON_MAPPER = new ObjectMapper();
93-
RELAXED_JSON_MAPPER.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
94-
RELAXED_JSON_MAPPER.setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.ANY);
95-
RELAXED_JSON_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
96-
RELAXED_JSON_MAPPER.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES);
9793
if (Collection.class.isAssignableFrom(TypeUtils.getRawType(targetType, null))) {
98-
Class<?> collectionItemType = (Class<?>) CoreTypeResolver.getParameterizedActualTypeArgumentsType(targetType);
99-
String sourceData = (String) sourceValue;
94+
Class<?> collectionItemType = (Class<?>) CoreTypeResolver
95+
.getParameterizedActualTypeArgumentsType(targetType);
96+
10097
try {
101-
Object objList = RELAXED_JSON_MAPPER.readValue(sourceData, RELAXED_JSON_MAPPER.getTypeFactory()
102-
.constructCollectionType(List.class, collectionItemType));
98+
Object objList = toList(sourceData, collectionItemType);
10399
resultValue = (Optional<R>) Optional.ofNullable(objList);
104100
} catch (Exception jsonParseEx) {
105-
resultValue = convertFromJson(sourceValue, targetType, RELAXED_JSON_MAPPER);
101+
resultValue = convertFromJson(sourceData, targetType);
106102
}
107103
} else {
108-
resultValue = convertFromJson(sourceValue, TypeUtils.getRawType(targetType, null),
109-
RELAXED_JSON_MAPPER);
104+
resultValue = convertFromJson(sourceData, TypeUtils.getRawType(targetType, null));
110105
}
111106
}
112107
}
@@ -144,10 +139,36 @@ Optional<R> applyTypeAssignment(T sourceValue, Type targetType) throws Exception
144139
return resultValue;
145140
}
146141

147-
private Optional<R> convertFromJson(T sourceValue, Type targetType, ObjectMapper RELAXED_JSON_MAPPER)
148-
throws IOException, JsonParseException, JsonMappingException {
149-
Object obj = RELAXED_JSON_MAPPER.readValue((String) sourceValue, TypeUtils.getRawType(targetType, null));
150-
return (Optional<R>) Optional.ofNullable(obj);
142+
private Optional<R> convertFromJson(String sourceValue, Type targetType) {
143+
if (null == sourceValue) {
144+
return null;
145+
}
146+
Object result = null;
147+
try {
148+
result = RpcJsonDataSource.gson.fromJson(sourceValue, targetType);
149+
} catch (JsonSyntaxException ex) {
150+
if (Collection.class.isAssignableFrom(TypeUtils.getRawType(targetType, null)) || targetType.getClass().isArray()) {
151+
result = RpcJsonDataSource.convertToStringArrayOrList(sourceValue, targetType);
152+
}
153+
else {
154+
throw ex;
155+
}
156+
}
157+
return (Optional<R>) Optional.ofNullable(result);
158+
}
159+
160+
public static <T> List<T> toList(String json, Class<T> elementType) {
161+
if (null == json) {
162+
return null;
163+
}
164+
List<T> pojoList = new ArrayList<T>();
165+
JsonParser parser = new JsonParser();
166+
JsonArray array = parser.parse(json).getAsJsonArray();
167+
for (int i = 0; i < array.size(); i++) {
168+
pojoList.add((T) RpcJsonDataSource.gson.fromJson(array.get(i), elementType));
169+
}
170+
171+
return pojoList;
151172
}
152173

153174
static Object generalAssignment(Object value, Type target) {

src/main/java/com/microsoft/azure/functions/worker/binding/DataSource.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
package com.microsoft.azure.functions.worker.binding;
22

3-
import java.io.IOException;
43
import java.lang.reflect.Type;
54
import java.lang.reflect.TypeVariable;
65
import java.util.Map;
76
import java.util.Optional;
87

9-
import org.apache.commons.lang3.ArrayUtils;
108
import org.apache.commons.lang3.ObjectUtils;
119
import org.apache.commons.lang3.exception.ExceptionUtils;
1210
import org.apache.commons.lang3.reflect.TypeUtils;
1311

14-
import com.fasterxml.jackson.core.JsonParseException;
15-
import com.fasterxml.jackson.databind.JsonMappingException;
16-
1712
/**
1813
* Base class of all data sources. Provides basic information and logic for type
1914
* conversion. Data operation template: T (source) -> Object (value).
@@ -46,13 +41,13 @@ public Optional<BindingData> computeByName(String name, Type target) {
4641
try {
4742
data = source.get().computeByType(target);
4843
return data;
49-
} catch (IOException ex) {
44+
} catch (Exception ex) {
5045
ExceptionUtils.rethrow(ex);
5146
}
5247
return Optional.empty();
5348
}
5449

55-
public Optional<BindingData> computeByType(Type target) throws JsonParseException, JsonMappingException, IOException {
50+
public Optional<BindingData> computeByType(Type target) {
5651
boolean isTargetOptional = Optional.class.equals(TypeUtils.getRawType(target, null));
5752
if (isTargetOptional) {
5853
Map<TypeVariable<?>, Type> typeArgs = TypeUtils.getTypeArguments(target, Optional.class);
Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,46 @@
11
package com.microsoft.azure.functions.worker.binding;
22

3-
import com.fasterxml.jackson.annotation.JsonAutoDetect;
4-
import com.fasterxml.jackson.annotation.PropertyAccessor;
5-
import com.fasterxml.jackson.core.JsonParser;
6-
import com.fasterxml.jackson.databind.DeserializationFeature;
7-
import com.fasterxml.jackson.databind.ObjectMapper;
3+
import java.lang.reflect.Type;
4+
import java.util.ArrayList;
5+
import java.util.Collection;
6+
import java.util.List;
7+
8+
import org.apache.commons.lang3.reflect.TypeUtils;
9+
10+
import com.google.gson.Gson;
11+
import com.google.gson.JsonArray;
12+
import com.google.gson.JsonParser;
13+
import com.google.gson.JsonSyntaxException;
814

915
public final class RpcJsonDataSource extends DataSource<String> {
10-
public RpcJsonDataSource(String name, String value) { super(name, value, JSON_DATA_OPERATIONS); }
16+
public RpcJsonDataSource(String name, String value) {
17+
super(name, value, JSON_DATA_OPERATIONS);
18+
}
1119

12-
private static final ObjectMapper RELAXED_JSON_MAPPER = new ObjectMapper();
13-
private static final DataOperations<String, Object> JSON_DATA_OPERATIONS = new DataOperations<>();
20+
public static final Gson gson = new Gson();
21+
public static final JsonParser gsonParser = new JsonParser();
22+
private static final DataOperations<String, Object> JSON_DATA_OPERATIONS = new DataOperations<>();
1423

15-
static {
16-
RELAXED_JSON_MAPPER.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
17-
RELAXED_JSON_MAPPER.setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.ANY);
18-
RELAXED_JSON_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
19-
RELAXED_JSON_MAPPER.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES);
24+
public static Object convertToStringArrayOrList(String sourceValue, Type targetType) {
25+
try {
26+
return gson.fromJson(sourceValue, targetType);
27+
} catch (JsonSyntaxException ex) {
28+
List<String> jsonStringArrayList = new ArrayList<String>();
29+
JsonArray array = gsonParser.parse(sourceValue).getAsJsonArray();
30+
for (int i = 0; i < array.size(); i++) {
31+
jsonStringArrayList.add(array.get(i).toString());
32+
}
33+
if (Collection.class.isAssignableFrom(TypeUtils.getRawType(targetType, null))) {
34+
return jsonStringArrayList;
35+
}
36+
String[] jsonStringListAsArray = new String[jsonStringArrayList.size()];
37+
jsonStringListAsArray = jsonStringArrayList.toArray(jsonStringListAsArray);
38+
return jsonStringListAsArray;
39+
}
40+
}
2041

21-
JSON_DATA_OPERATIONS.addOperation(String.class, s -> s);
22-
JSON_DATA_OPERATIONS.addOperation(String[].class, s -> RELAXED_JSON_MAPPER.readValue(s, String[].class));
23-
}
42+
static {
43+
JSON_DATA_OPERATIONS.addOperation(String.class, s -> s);
44+
JSON_DATA_OPERATIONS.addGenericOperation(String[].class, (v, t) -> convertToStringArrayOrList(v, t));
45+
}
2446
}

src/main/java/com/microsoft/azure/functions/worker/binding/RpcStringDataSource.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
package com.microsoft.azure.functions.worker.binding;
22

3-
import java.io.IOException;
43
import java.lang.reflect.Type;
54

6-
import com.fasterxml.jackson.core.JsonParseException;
7-
import com.fasterxml.jackson.databind.JsonMappingException;
8-
95
public final class RpcStringDataSource extends DataSource<String> {
106
public RpcStringDataSource(String name, String value) { super(name, value, STRING_DATA_OPERATIONS); }
117

12-
private static Object convertToJson(boolean isStrict, String s, Type target) throws JsonParseException, JsonMappingException, ClassCastException, IOException {
8+
private static Object convertToJson(boolean isStrict, String s, Type target) throws ClassCastException {
139
DataSource<?> jsonSource = new RpcJsonDataSource(null, s);
1410
if (isStrict) {
1511
return jsonSource.computeByType(target).orElseThrow(ClassCastException::new).getNullSafeValue();

src/main/java/com/microsoft/azure/functions/worker/binding/RpcUnspecifiedDataTarget.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package com.microsoft.azure.functions.worker.binding;
22

3-
import com.fasterxml.jackson.annotation.JsonAutoDetect;
4-
import com.fasterxml.jackson.annotation.PropertyAccessor;
5-
import com.fasterxml.jackson.core.JsonParser;
6-
import com.fasterxml.jackson.databind.DeserializationFeature;
7-
import com.fasterxml.jackson.databind.ObjectMapper;
83
import com.google.protobuf.ByteString;
94
import com.microsoft.azure.functions.rpc.messages.TypedData;
105

@@ -70,21 +65,15 @@ private static TypedData.Builder toByteArrayData(Object value) {
7065
public static TypedData.Builder toJsonData(Object value) throws Exception {
7166
TypedData.Builder dataBuilder = TypedData.newBuilder();
7267
if (value != null) {
73-
dataBuilder.setJson(RELAXED_JSON_MAPPER.writeValueAsString(value));
68+
dataBuilder.setJson(RpcJsonDataSource.gson.toJson(value));
7469
} else {
7570
throw new IllegalArgumentException();
7671
}
7772
return dataBuilder;
7873
}
7974

80-
private static final ObjectMapper RELAXED_JSON_MAPPER = new ObjectMapper();
8175
private static final DataOperations<Object, TypedData.Builder> UNSPECIFIED_TARGET_OPERATIONS = new DataOperations<>();
8276
static {
83-
RELAXED_JSON_MAPPER.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
84-
RELAXED_JSON_MAPPER.setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.ANY);
85-
RELAXED_JSON_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
86-
RELAXED_JSON_MAPPER.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES);
87-
8877
UNSPECIFIED_TARGET_OPERATIONS.addTargetOperation(long.class, RpcUnspecifiedDataTarget::toIntData);
8978
UNSPECIFIED_TARGET_OPERATIONS.addTargetOperation(Long.class, RpcUnspecifiedDataTarget::toIntData);
9079
UNSPECIFIED_TARGET_OPERATIONS.addTargetOperation(int.class, RpcUnspecifiedDataTarget::toIntData);

0 commit comments

Comments
 (0)