Skip to content

Commit d716538

Browse files
authored
Fix query param serialization for requests with enums (#140)
## Changes Query parameters are determined reflectively from request classes by scanning for fields with a QueryParam annotation. Serialization of query parameters is recursive in order to support complex types like the filter structures used for listing in the SQL query history service. This PR makes the following changes: 1. Terminate recursion when the request field is an enum. 2. When iterating through the request object's fields, skip any fields not annotated with QueryParam (but recursively, all fields do need to be serialized). 3. Rename the inner class from HeaderEntry to QueryParamPair (it represents query param pairs, not header entries). ## Tests Test for this change is dependent on other testing refactors that will be merged as part of #139.
1 parent 2dc895b commit d716538

File tree

2 files changed

+18
-18
lines changed

2 files changed

+18
-18
lines changed

databricks-sdk-java/src/main/java/com/databricks/sdk/core/ApiClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ private static <I> void setQuery(Request in, I entity) {
9090
if (entity == null) {
9191
return;
9292
}
93-
for (GrpcTranscodingQueryParamsSerializer.HeaderEntry e :
93+
for (GrpcTranscodingQueryParamsSerializer.QueryParamPair e :
9494
GrpcTranscodingQueryParamsSerializer.serialize(entity)) {
9595
in.withQueryParam(e.getKey(), e.getValue());
9696
}

databricks-sdk-java/src/main/java/com/databricks/sdk/core/GrpcTranscodingQueryParamsSerializer.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
* documentation for gRPC transcoding</a> for more details.
1818
*/
1919
public class GrpcTranscodingQueryParamsSerializer {
20-
public static class HeaderEntry {
20+
public static class QueryParamPair {
2121
private final String key;
2222
private final String value;
2323

24-
public HeaderEntry(String key, String value) {
24+
public QueryParamPair(String key, String value) {
2525
this.key = key;
2626
this.value = value;
2727
}
@@ -47,25 +47,19 @@ public String getValue() {
4747
* @param o The object to serialize.
4848
* @return A list of query parameter entries compatible with gRPC-transcoding.
4949
*/
50-
public static List<HeaderEntry> serialize(Object o) {
51-
Map<String, Object> flattened = flattenObject(o);
52-
for (Field f : o.getClass().getDeclaredFields()) {
53-
QueryParam queryParam = f.getAnnotation(QueryParam.class);
54-
if (queryParam == null) {
55-
flattened.remove(getFieldName(f));
56-
}
57-
}
50+
public static List<QueryParamPair> serialize(Object o) {
51+
Map<String, Object> flattened = flattenObject(o, true);
5852

59-
List<HeaderEntry> result = new ArrayList<>();
53+
List<QueryParamPair> result = new ArrayList<>();
6054
for (Map.Entry<String, Object> entry : flattened.entrySet()) {
6155
String key = entry.getKey();
6256
Object value = entry.getValue();
6357
if (value instanceof Collection) {
6458
for (Object v : (Collection<Object>) value) {
65-
result.add(new HeaderEntry(key, v.toString()));
59+
result.add(new QueryParamPair(key, v.toString()));
6660
}
6761
} else {
68-
result.add(new HeaderEntry(key, value.toString()));
62+
result.add(new QueryParamPair(key, value.toString()));
6963
}
7064
}
7165
return result;
@@ -103,24 +97,30 @@ private static String getFieldName(Field f) {
10397
}
10498
}
10599

106-
private static Map<String, Object> flattenObject(Object o) {
100+
private static Map<String, Object> flattenObject(Object o, Boolean onlyAnnotatedFields) {
107101
// LinkedHashMap ensures consistent ordering of fields.
108102
Map<String, Object> result = new LinkedHashMap<>();
109103
Field[] fields = o.getClass().getDeclaredFields();
110104
for (Field f : fields) {
105+
if (onlyAnnotatedFields && f.getAnnotation(QueryParam.class) == null) {
106+
continue;
107+
}
111108
f.setAccessible(true);
112109
try {
113110
String name = getFieldName(f);
114111
Object value = f.get(o);
115112
if (value == null) {
116113
continue;
117114
}
118-
// check if object is a primitive type or a collection of some kind
119-
if (primitiveTypes.contains(f.getType()) || Iterable.class.isAssignableFrom(f.getType())) {
115+
// check if object is a primitive type, a collection of some kind, or an enum
116+
Class<?> type = f.getType();
117+
if (primitiveTypes.contains(type)
118+
|| Iterable.class.isAssignableFrom(type)
119+
|| type.isEnum()) {
120120
result.put(name, value);
121121
} else {
122122
// recursively flatten the object
123-
Map<String, Object> flattened = flattenObject(value);
123+
Map<String, Object> flattened = flattenObject(value, false);
124124
for (Map.Entry<String, Object> entry : flattened.entrySet()) {
125125
result.put(name + "." + entry.getKey(), entry.getValue());
126126
}

0 commit comments

Comments
 (0)