Merge branch 'bug/json-body-non-object-types' into 'release'

Handle 500 when JSON body doesn't make up an object data type.

See merge request theappsmith/internal-tools-server!316
This commit is contained in:
Shrikant Kandula 2020-04-30 13:32:24 +00:00
commit f4b4c630fe

View File

@ -11,6 +11,7 @@ import com.appsmith.external.plugins.BasePlugin;
import com.appsmith.external.plugins.PluginExecutor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.bson.internal.Base64;
@ -191,15 +192,23 @@ public class RestApiPlugin extends BasePlugin {
if (iteration == MAX_REDIRECTS) {
return Mono.error(new AppsmithPluginException(
AppsmithPluginError.PLUGIN_ERROR,
"Exceeded the HTTO redirect limits of " + MAX_REDIRECTS
"Exceeded the HTTP redirect limits of " + MAX_REDIRECTS
));
}
Object requestBodyAsObject;
Object requestBodyAsObject = null;
if (isJsonContentType) {
GsonBuilder gson = new GsonBuilder();
requestBodyAsObject = gson.create().fromJson(requestBodyAsString, Map.class);
} else {
try {
requestBodyAsObject = objectFromJson(requestBodyAsString);
} catch (JsonSyntaxException e) {
return Mono.error(new AppsmithPluginException(
AppsmithPluginError.PLUGIN_ERROR,
"Malformed JSON: " + e.getMessage()
));
}
}
if (requestBodyAsObject == null) {
requestBodyAsObject = requestBodyAsString;
}
@ -232,6 +241,31 @@ public class RestApiPlugin extends BasePlugin {
});
}
/**
* Given a JSON string, we infer the top-level type of the object it represents and then parse it into that
* type. However, only `Map` and `List` top-levels are supported. Note that the map or list may contain
* anything, like booleans or number or even more maps or lists. It's only that the top-level type should be a
* map / list.
* @param jsonString A string that confirms to JSON syntax. Shouldn't be null.
* @return An object of type `Map`, `List`, if applicable, or `null`.
*/
private static Object objectFromJson(String jsonString) {
Class<?> type;
String trimmed = jsonString.trim();
if (trimmed.startsWith("{")) {
type = Map.class;
} else if (trimmed.startsWith("[")) {
type = List.class;
} else {
// The JSON body is likely a literal boolean or number or string. For our purposes here, we don't have
// to parse this JSON.
return null;
}
return new GsonBuilder().create().fromJson(jsonString, type);
}
@Override
public Mono<Object> datasourceCreate(DatasourceConfiguration datasourceConfiguration) {
return Mono.empty();