Search in sources :

Example 1 with LivyDeserializationException

use of com.thinkbiganalytics.kylo.spark.exceptions.LivyDeserializationException in project kylo by Teradata.

the class LivyRestModelTransformer method convertDataFrameDataType.

private static String convertDataFrameDataType(JsonNode dataType) {
    if (dataType.isObject()) {
        String type = dataType.get("type").asText();
        if (type.equals("udt")) {
            if (dataType.get("class").asText().equals("org.apache.spark.mllib.linalg.VectorUDT")) {
                // TODO: null check
                ArrayNode fields = (ArrayNode) dataType.get("sqlType").get("fields");
                Iterator<JsonNode> fieldsIter = fields.elements();
                while (fieldsIter.hasNext()) {
                    ObjectNode fieldDescriptors = (ObjectNode) fieldsIter.next();
                    if (fieldDescriptors.get("name").asText().equals("values")) {
                        ObjectNode fdObj = (ObjectNode) fieldDescriptors.get("type");
                        return new StringBuilder(fdObj.get("type").asText()).append("<").append(fdObj.get("elementType").asText()).append(">").toString();
                    }
                }
                return "Unknown UDT";
            } else {
                if (dataType.get("class") != null) {
                    logger.error("UDT error encountered", new LivyDeserializationException("don't know how to deserialize UDT types for class = " + dataType.get("class").asText()));
                } else {
                    logger.error("UDT error encountered", new LivyDeserializationException("don't know how to deserialize UDT type of unspecified class"));
                }
                // end if
                throw new LivyUserException("livy.unexpected_error");
            }
        // end if
        } else if (type.equals("map")) {
            return new StringBuilder(dataType.get("type").asText()).append("<").append(dataType.get("keyType").asText()).append(",").append(dataType.get("valueType").asText()).append(">").toString();
        } else if (type.equals("struct")) {
            ArrayNode fields = (ArrayNode) dataType.get("fields");
            Iterator<JsonNode> nodes = fields.elements();
            StringBuilder sb = new StringBuilder("struct<");
            // assumes min of 1 field in struct
            while (nodes.hasNext()) {
                ObjectNode node = (ObjectNode) nodes.next();
                String sfName = node.get("name").asText();
                String sfType = node.get("type").asText();
                sb.append(sfName).append(":").append(sfType).append(",");
            }
            sb.deleteCharAt(sb.length() - 1);
            return sb.toString();
        } else {
            // can there be other types?
            return "Unknown Type";
        }
    // end if
    } else {
        return dataType.asText();
    }
// end if
}
Also used : ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) JsonNode(com.fasterxml.jackson.databind.JsonNode) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) LivyUserException(com.thinkbiganalytics.kylo.spark.exceptions.LivyUserException) LivyDeserializationException(com.thinkbiganalytics.kylo.spark.exceptions.LivyDeserializationException)

Example 2 with LivyDeserializationException

use of com.thinkbiganalytics.kylo.spark.exceptions.LivyDeserializationException in project kylo by Teradata.

the class LivyRestModelTransformer method serializeStatementOutputResponse.

private static <T extends Object> T serializeStatementOutputResponse(StatementOutputResponse sor, Class<T> clazz) {
    String errMsg = String.format("Unable to deserialize JSON returned from Livy into class '%s'", clazz.getSimpleName());
    JsonNode data = sor.getData();
    if (data != null) {
        JsonNode json = data.get("application/json");
        String jsonString = json.asText();
        try {
            return mapper.readValue(jsonString, clazz);
        } catch (IOException e) {
            logger.error("Deserialization error occured", new LivyDeserializationException(errMsg));
        }
    // end try/catch
    } else {
        logger.error("Deserialization error occured", new LivyDeserializationException(errMsg));
    }
    throw new LivyUserException("livy.unexpected_error");
}
Also used : JsonNode(com.fasterxml.jackson.databind.JsonNode) IOException(java.io.IOException) LivyUserException(com.thinkbiganalytics.kylo.spark.exceptions.LivyUserException) LivyDeserializationException(com.thinkbiganalytics.kylo.spark.exceptions.LivyDeserializationException)

Example 3 with LivyDeserializationException

use of com.thinkbiganalytics.kylo.spark.exceptions.LivyDeserializationException in project kylo by Teradata.

the class LivyRestModelTransformer method toTransformQueryResultWithSchema.

private static TransformQueryResult toTransformQueryResultWithSchema(TransformResponse transformResponse, StatementOutputResponse sor) {
    logger.entry(sor);
    checkCodeWasWellFormed(sor);
    TransformQueryResult tqr = new TransformQueryResult();
    transformResponse.setResults(tqr);
    tqr.setColumns(Lists.newArrayList());
    JsonNode data = sor.getData();
    if (data != null) {
        JsonNode appJson = data.get("application/json");
        String payload = appJson.asText();
        ArrayNode json;
        try {
            json = (ArrayNode) mapper.readTree(payload);
        } catch (IOException e) {
            logger.error("An unexpected IOException occurred", new LivyDeserializationException("could not deserialize JSON returned from Livy"));
            throw logger.throwing(new LivyUserException("livy.unexpected_error"));
        }
        // end try/catch
        // array contains three objects (dfRows, actualCols, actualRows )
        transformResponse.setActualCols(json.get(1).asInt());
        transformResponse.setActualRows(json.get(2).asInt());
        json = (ArrayNode) json.get(0);
        int numRows = 0;
        Iterator<JsonNode> rowIter = json.elements();
        List<List<Object>> rowData = Lists.newArrayList();
        while (rowIter.hasNext()) {
            JsonNode row = rowIter.next();
            if (numRows++ == 0) {
                String schemaPayload = row.asText();
                ObjectNode schemaObj;
                try {
                    schemaObj = (ObjectNode) mapper.readTree(schemaPayload);
                } catch (IOException e) {
                    logger.error("Unexpected error deserializing results", new LivyDeserializationException("Unable to deserialize dataFrame schema as serialized by Livy"));
                    throw logger.throwing(new LivyUserException("livy.unexpected_error"));
                }
                // end try/catch
                // build column metadata
                logger.debug("build column metadata");
                String type = schemaObj.get("type").asText();
                if (type.equals("struct")) {
                    ArrayNode fields = (ArrayNode) schemaObj.get("fields");
                    Iterator<JsonNode> colObjsIter = fields.elements();
                    int colIdx = 0;
                    while (colObjsIter.hasNext()) {
                        ObjectNode colObj = (ObjectNode) colObjsIter.next();
                        final JsonNode dataType = colObj.get("type");
                        JsonNode metadata = colObj.get("metadata");
                        String name = colObj.get("name").asText();
                        // "true"|"false"
                        String nullable = colObj.get("nullable").asText();
                        QueryResultColumn qrc = new DefaultQueryResultColumn();
                        qrc.setDisplayName(name);
                        qrc.setField(name);
                        // not used, but still be expected to be unique
                        qrc.setHiveColumnLabel(name);
                        qrc.setIndex(colIdx++);
                        // dataType is always empty if %json of dataframe directly:: https://www.mail-archive.com/user@livy.incubator.apache.org/msg00262.html
                        qrc.setDataType(convertDataFrameDataType(dataType));
                        qrc.setComment(metadata.asText());
                        tqr.getColumns().add(qrc);
                    }
                }
                // will there be types other than "struct"?
                continue;
            }
            // end schema extraction
            // get row data
            logger.debug("build row data");
            ArrayNode valueRows = (ArrayNode) row;
            Iterator<JsonNode> valuesIter = valueRows.elements();
            while (valuesIter.hasNext()) {
                ArrayNode valueNode = (ArrayNode) valuesIter.next();
                Iterator<JsonNode> valueNodes = valueNode.elements();
                List<Object> newValues = Lists.newArrayListWithCapacity(tqr.getColumns().size());
                while (valueNodes.hasNext()) {
                    JsonNode value = valueNodes.next();
                    // extract values according to how jackson deserialized it
                    if (value.isObject()) {
                        // spark treats an array as a struct with a single field "values" ...
                        // Maps and structs can't contain arrays so
                        ArrayNode valuesArray = (ArrayNode) value.get("values");
                        if (valuesArray != null && valuesArray.isArray()) {
                            Iterator<JsonNode> arrIter = valuesArray.iterator();
                            List<Object> arrVals = Lists.newArrayListWithExpectedSize(valuesArray.size());
                            while (arrIter.hasNext()) {
                                JsonNode valNode = arrIter.next();
                                if (valNode.isNumber()) {
                                    arrVals.add(valNode.numberValue());
                                } else {
                                    arrVals.add(valNode.asText());
                                }
                            // end if
                            }
                            // end while
                            newValues.add(arrVals.toArray());
                        } else {
                            Map<String, Object> result = null;
                            try {
                                result = mapper.convertValue(value, Map.class);
                            } catch (Exception e) {
                                // column value must be a struct or other complex type that we don't handle special..
                                newValues.add(value.toString());
                            }
                            newValues.add(result);
                        }
                    // end if
                    } else if (value.isNumber()) {
                        // easy peasy.. it's just a number
                        newValues.add(value.numberValue());
                    } else if (value.isNull()) {
                        newValues.add(null);
                    } else if (value.isValueNode()) {
                        // value Nodes we just get the raw text..
                        newValues.add(value.asText());
                    } else {
                        // default = treat it as string..
                        newValues.add(value.toString());
                    }
                // end if
                }
                // end while
                rowData.add(newValues);
            }
        // end of valueRows
        }
        // end sor.data
        logger.trace("rowData={}", rowData);
        tqr.setRows(rowData);
    // tqr.setValidationResults(null);
    }
    return logger.exit(tqr);
}
Also used : ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) DefaultQueryResultColumn(com.thinkbiganalytics.discovery.model.DefaultQueryResultColumn) JsonNode(com.fasterxml.jackson.databind.JsonNode) IOException(java.io.IOException) SparkLivySaveException(com.thinkbiganalytics.kylo.spark.livy.SparkLivySaveException) IOException(java.io.IOException) LivyUserException(com.thinkbiganalytics.kylo.spark.exceptions.LivyUserException) LivyCodeException(com.thinkbiganalytics.kylo.spark.exceptions.LivyCodeException) WebApplicationException(javax.ws.rs.WebApplicationException) LivyDeserializationException(com.thinkbiganalytics.kylo.spark.exceptions.LivyDeserializationException) TransformQueryResult(com.thinkbiganalytics.spark.rest.model.TransformQueryResult) List(java.util.List) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) LivyUserException(com.thinkbiganalytics.kylo.spark.exceptions.LivyUserException) DefaultQueryResultColumn(com.thinkbiganalytics.discovery.model.DefaultQueryResultColumn) QueryResultColumn(com.thinkbiganalytics.discovery.schema.QueryResultColumn) LivyDeserializationException(com.thinkbiganalytics.kylo.spark.exceptions.LivyDeserializationException) Map(java.util.Map)

Aggregations

JsonNode (com.fasterxml.jackson.databind.JsonNode)3 LivyDeserializationException (com.thinkbiganalytics.kylo.spark.exceptions.LivyDeserializationException)3 LivyUserException (com.thinkbiganalytics.kylo.spark.exceptions.LivyUserException)3 ArrayNode (com.fasterxml.jackson.databind.node.ArrayNode)2 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)2 IOException (java.io.IOException)2 DefaultQueryResultColumn (com.thinkbiganalytics.discovery.model.DefaultQueryResultColumn)1 QueryResultColumn (com.thinkbiganalytics.discovery.schema.QueryResultColumn)1 LivyCodeException (com.thinkbiganalytics.kylo.spark.exceptions.LivyCodeException)1 SparkLivySaveException (com.thinkbiganalytics.kylo.spark.livy.SparkLivySaveException)1 TransformQueryResult (com.thinkbiganalytics.spark.rest.model.TransformQueryResult)1 List (java.util.List)1 Map (java.util.Map)1 WebApplicationException (javax.ws.rs.WebApplicationException)1