Skip to content

Commit

Permalink
Switch to jackson library from org.json (#272)
Browse files Browse the repository at this point in the history
* switch to jackson for json

* added formatter

* fixed failing test cases

* fixed testcases

* ran formatter

* added jackson-core to pom

* fixed json string

* fixed string conversion

* bumped release version

* bumped up release version

* addressed Ram's review comments

* formatter changes

* refactored object mapper

* addressed Ram's review comments

* formatter changes

* changes done as per Ohad's comments

* added exception testcase for ResultSetTest

* added bigdecimal for precision in decimal values

* added comment for bigdecimal deserilaization

* made options and parameters mandatory in tojson

* fixed test case

* accept cla

* added formatter

* commit for cla

Co-authored-by: AsafMah <asafmahlev@microsoft.com>

(cherry picked from commit c3bc043)
  • Loading branch information
tanmaya-panda1 authored and AsafMah committed Dec 7, 2022
1 parent 4b906f2 commit 8b0d3e0
Show file tree
Hide file tree
Showing 25 changed files with 434 additions and 274 deletions.
21 changes: 16 additions & 5 deletions data/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,6 @@
<artifactId>httpcore</artifactId>
<version>${httpcore.version}</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
Expand Down Expand Up @@ -282,5 +277,21 @@
<groupId>com.fasterxml.jackson.core</groupId>
<version>${fasterxml.jackson.core.version}</version>
</dependency>
<!-- added this dependency since mvn dependency:tree failing with following error - Used undeclared dependencies found -->
<dependency>
<artifactId>jackson-core</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
<version>${fasterxml.jackson.core.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${fasterxml.jackson.core.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>${fasterxml.jackson.core.version}</version>
</dependency>
</dependencies>
</project>
28 changes: 11 additions & 17 deletions data/src/main/java/com/microsoft/azure/kusto/data/ClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

package com.microsoft.azure.kusto.data;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.microsoft.azure.kusto.data.auth.CloudInfo;
import com.microsoft.azure.kusto.data.auth.ConnectionStringBuilder;
import com.microsoft.azure.kusto.data.auth.TokenProviderBase;
Expand All @@ -16,8 +18,6 @@
import org.apache.http.HttpHeaders;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.InputStream;
import java.net.URI;
Expand Down Expand Up @@ -45,6 +45,8 @@ public class ClientImpl implements Client, StreamingClient {
private final CloseableHttpClient httpClient;
private boolean endpointValidated = false;

private ObjectMapper objectMapper = Utils.getObjectMapper();

public ClientImpl(ConnectionStringBuilder csb) throws URISyntaxException {
this(csb, HttpClientProperties.builder().build());
}
Expand Down Expand Up @@ -308,25 +310,17 @@ private Map<String, String> generateIngestAndCommandHeaders(ClientRequestPropert
return headers;
}

private String generateCommandPayload(String database, String command, ClientRequestProperties properties, String clusterEndpoint)
throws DataClientException {
String jsonPayload;
try {
JSONObject json = new JSONObject()
.put("db", database)
.put("csl", command);
private String generateCommandPayload(String database, String command, ClientRequestProperties properties, String clusterEndpoint) {

if (properties != null) {
json.put("properties", properties.toString());
}
ObjectNode json = objectMapper.createObjectNode()
.put("db", database)
.put("csl", command);

jsonPayload = json.toString();
} catch (JSONException e) {
throw new DataClientException(clusterEndpoint,
String.format(clusterEndpoint, "Error executing command '%s' in database '%s'. Setting up request payload failed.", command, database), e);
if (properties != null) {
json.put("properties", properties.toString());
}

return jsonPayload;
return json.toString();
}

private void addCommandHeaders(Map<String, String> headers) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

package com.microsoft.azure.kusto.data;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.microsoft.azure.kusto.data.format.CslBoolFormat;
import com.microsoft.azure.kusto.data.format.CslDateTimeFormat;
import com.microsoft.azure.kusto.data.format.CslIntFormat;
Expand All @@ -12,8 +15,6 @@
import com.microsoft.azure.kusto.data.format.CslUuidFormat;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.ParseException;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.Serializable;
import java.time.Duration;
Expand Down Expand Up @@ -190,57 +191,53 @@ public void setTimeoutInMilliSec(Long timeoutInMs) {
options.put(OPTION_SERVER_TIMEOUT, timeoutInMs);
}

JSONObject toJson() {
try {
JSONObject optionsAsJSON = new JSONObject(this.options);
Object timeoutObj = getOption(OPTION_SERVER_TIMEOUT);

if (timeoutObj != null) {
String timeoutString = "";
if (timeoutObj instanceof Long) {
Duration duration = Duration.ofMillis((Long) timeoutObj);
timeoutString = Utils.formatDurationAsTimespan(duration);
} else if (timeoutObj instanceof String) {
timeoutString = (String) timeoutObj;
} else if (timeoutObj instanceof Integer) {
Duration duration = Duration.ofMillis((Integer) timeoutObj);
timeoutString = Utils.formatDurationAsTimespan(duration);
}
optionsAsJSON.put(OPTION_SERVER_TIMEOUT, timeoutString);
JsonNode toJson() {
ObjectNode optionsAsJSON = Utils.getObjectMapper().valueToTree(this.options);
Object timeoutObj = getOption(OPTION_SERVER_TIMEOUT);

if (timeoutObj != null) {
String timeoutString = "";
if (timeoutObj instanceof Long) {
Duration duration = Duration.ofMillis((Long) timeoutObj);
timeoutString = Utils.formatDurationAsTimespan(duration);
} else if (timeoutObj instanceof String) {
timeoutString = (String) timeoutObj;
} else if (timeoutObj instanceof Integer) {
Duration duration = Duration.ofMillis((Integer) timeoutObj);
timeoutString = Utils.formatDurationAsTimespan(duration);
}
JSONObject json = new JSONObject();
json.put(OPTIONS_KEY, optionsAsJSON);
json.put(PARAMETERS_KEY, new JSONObject(this.parameters));
return json;
} catch (JSONException e) {
return null;
optionsAsJSON.put(OPTION_SERVER_TIMEOUT, timeoutString);
}
ObjectNode json = Utils.getObjectMapper().createObjectNode();
json.set(OPTIONS_KEY, optionsAsJSON);
json.set(PARAMETERS_KEY, Utils.getObjectMapper().valueToTree(this.parameters));
return json;
}

public String toString() {
return toJson().toString();
}

public static ClientRequestProperties fromString(String json) throws JSONException {
public static ClientRequestProperties fromString(String json) throws JsonProcessingException {
if (StringUtils.isNotBlank(json)) {
ClientRequestProperties crp = new ClientRequestProperties();
JSONObject jsonObj = new JSONObject(json);
Iterator<String> it = jsonObj.keys();
JsonNode jsonObj = Utils.getObjectMapper().readTree(json);
Iterator<String> it = jsonObj.fieldNames();
while (it.hasNext()) {
String propertyName = it.next();
if (propertyName.equals(OPTIONS_KEY)) {
JSONObject optionsJson = (JSONObject) jsonObj.get(propertyName);
Iterator<String> optionsIt = optionsJson.keys();
JsonNode optionsJson = jsonObj.get(propertyName);
Iterator<String> optionsIt = optionsJson.fieldNames();
while (optionsIt.hasNext()) {
String optionName = optionsIt.next();
crp.setOption(optionName, optionsJson.get(optionName));
crp.setOption(optionName, optionsJson.get(optionName).asText());
}
} else if (propertyName.equals(PARAMETERS_KEY)) {
JSONObject parameters = (JSONObject) jsonObj.get(propertyName);
Iterator<String> parametersIt = parameters.keys();
JsonNode parameters = jsonObj.get(propertyName);
Iterator<String> parametersIt = parameters.fieldNames();
while (parametersIt.hasNext()) {
String parameterName = parametersIt.next();
crp.setParameter(parameterName, parameters.get(parameterName));
crp.setParameter(parameterName, parameters.get(parameterName).asText());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@

package com.microsoft.azure.kusto.data;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.microsoft.azure.kusto.data.exceptions.JsonPropertyMissingException;
import com.microsoft.azure.kusto.data.exceptions.KustoServiceQueryError;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.invoke.MethodHandles;
import java.util.*;

public class KustoOperationResult implements Iterator<KustoResultSetTable> {

private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final Map<String, WellKnownDataSet> tablesKindsMap = new HashMap<String, WellKnownDataSet>() {
{
put("QueryResult", WellKnownDataSet.PrimaryResult);
Expand All @@ -26,6 +34,8 @@ public class KustoOperationResult implements Iterator<KustoResultSetTable> {
private final List<KustoResultSetTable> resultTables = new ArrayList<>();
private final Iterator<KustoResultSetTable> it;

private final ObjectMapper objectMapper = Utils.getObjectMapper();

public KustoOperationResult(String response, String version) throws KustoServiceQueryError {
if (version.contains("v2")) {
createFromV2Response(response);
Expand Down Expand Up @@ -58,11 +68,20 @@ public KustoResultSetTable getPrimaryResults() {
}

private void createFromV1Response(String response) throws KustoServiceQueryError {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray(TABLES_LIST_PROPERTY_NAME);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject table = jsonArray.getJSONObject(i);
resultTables.add(new KustoResultSetTable(table));
try {
JsonNode jsonObject = objectMapper.readTree(response);
if (jsonObject.has(TABLES_LIST_PROPERTY_NAME) && jsonObject.get(TABLES_LIST_PROPERTY_NAME).isArray()) {
ArrayNode jsonArray = (ArrayNode) jsonObject.get(TABLES_LIST_PROPERTY_NAME);
for (int i = 0; i < jsonArray.size(); i++) {
JsonNode table = jsonArray.get(i);
resultTables.add(new KustoResultSetTable(table));
}
} else {
throw new JsonPropertyMissingException("Tables Property missing from V1 response json");
}
} catch (JsonProcessingException | JsonPropertyMissingException e) {
log.error("Json processing error occured while parsing string to json with exception", e);
throw new KustoServiceQueryError("Json processing error occurred while parsing string to json with exception " + e.getMessage());
}

if (resultTables.size() <= 2) {
Expand All @@ -87,12 +106,26 @@ private void createFromV1Response(String response) throws KustoServiceQueryError
}

private void createFromV2Response(String response) throws KustoServiceQueryError {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject table = jsonArray.getJSONObject(i);
if (table.optString(FRAME_TYPE_PROPERTY_NAME).equals(DATA_TABLE_FRAME_TYPE_PROPERTY_NAME)) {
resultTables.add(new KustoResultSetTable(table));
ArrayNode jsonArray;
try {
JsonNode jsonNode = objectMapper.readTree(response);
if (jsonNode.isArray()) {
jsonArray = (ArrayNode) jsonNode;
for (JsonNode node : jsonArray) {
if (node.has(FRAME_TYPE_PROPERTY_NAME) && node.get(FRAME_TYPE_PROPERTY_NAME).asText().equals(DATA_TABLE_FRAME_TYPE_PROPERTY_NAME)) {
resultTables.add(new KustoResultSetTable(node));
}
}
} else {
throw new JsonPropertyMissingException("There is no array in the response which can be parsed");
}
} catch (JsonProcessingException | JsonPropertyMissingException jsonException) {
log.error("Json processing error occured while parsing string to json with exception", jsonException);
throw new KustoServiceQueryError(
"Json processing error occurred while parsing string to json with exception " + jsonException.getMessage());
} catch (NullPointerException nullPointerException) {
log.error("Null pointer exception thrown due to invalid v2 response", nullPointerException);
throw new KustoServiceQueryError("Null pointer exception thrown due to invalid v2 response " + nullPointerException.getMessage());
}
}
}

0 comments on commit 8b0d3e0

Please sign in to comment.