package com.esri.hadoop.hive.serde;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Properties;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.serde2.SerDe;
import org.apache.hadoop.hive.serde2.objectinspector.StructField;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import com.esri.core.geometry.Geometry;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.geometry.ogc.OGCGeometry;
import com.esri.hadoop.shims.HiveShims;
// Ideally tests to cover:
// - attributes and/or geometry
// - null attributes and values to not linger
// - null geometry
// - spatial reference preserved
public class TestGeoJsonSerDe extends JsonSerDeTestingBase {
@Test
public void TestIntWrite() throws Exception { // Is this valid for GeoJSON?
ArrayList<Object> stuff = new ArrayList<Object>();
Properties proptab = new Properties();
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMNS, "num");
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMN_TYPES, "int");
SerDe jserde = mkSerDe(proptab);
StructObjectInspector rowOI = (StructObjectInspector)jserde.getObjectInspector();
// {"properties":{"num":7}}
addWritable(stuff, 7);
Writable jsw = jserde.serialize(stuff, rowOI);
JsonNode jn = new ObjectMapper().readTree(((Text)jsw).toString());
jn = jn.findValue("properties");
jn = jn.findValue("num");
Assert.assertEquals(7, jn.getIntValue());
}
@Test
public void TestPointWrite() throws Exception {
ArrayList<Object> stuff = new ArrayList<Object>();
Properties proptab = new Properties();
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMNS, "shape");
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMN_TYPES, "binary");
SerDe jserde = mkSerDe(proptab);
StructObjectInspector rowOI = (StructObjectInspector)jserde.getObjectInspector();
// {"properties":{},"geometry":{"type":"Point","coordinates":[15.0,5.0]}}
addWritable(stuff, new Point(15.0, 5.0));
Writable jsw = jserde.serialize(stuff, rowOI);
String rslt = ((Text)jsw).toString();
JsonNode jn = new ObjectMapper().readTree(rslt);
jn = jn.findValue("geometry");
Assert.assertNotNull(jn.findValue("type"));
Assert.assertNotNull(jn.findValue("coordinates"));
}
@Test
public void TestIntParse() throws Exception { // Is this valid for GeoJSON?
Configuration config = new Configuration();
Text value = new Text();
SerDe jserde = new GeoJsonSerDe();
Properties proptab = new Properties();
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMNS, "num");
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMN_TYPES, "int");
jserde.initialize(config, proptab);
StructObjectInspector rowOI = (StructObjectInspector)jserde.getObjectInspector();
value.set("{\"properties\":{\"num\":7}}");
Object row = jserde.deserialize(value);
StructField f0 = rowOI.getStructFieldRef("num");
Object fieldData = rowOI.getStructFieldData(row, f0);
Assert.assertEquals(7, ((IntWritable)fieldData).get());
value.set("{\"properties\":{\"num\":9}}");
row = jserde.deserialize(value);
f0 = rowOI.getStructFieldRef("num");
fieldData = rowOI.getStructFieldData(row, f0);
Assert.assertEquals(9, ((IntWritable)fieldData).get());
}
@Test
public void TestPointParse() throws Exception {
Configuration config = new Configuration();
Text value = new Text();
SerDe jserde = new GeoJsonSerDe();
Properties proptab = new Properties();
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMNS, "shape");
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMN_TYPES, "binary");
jserde.initialize(config, proptab);
StructObjectInspector rowOI = (StructObjectInspector)jserde.getObjectInspector();
value.set("{\"properties\":{},\"geometry\":{\"type\":\"Point\",\"coordinates\":[15.0,5.0]}}");
Object row = jserde.deserialize(value);
StructField f0 = rowOI.getStructFieldRef("shape");
Object fieldData = rowOI.getStructFieldData(row, f0);
ckPoint(new Point(15.0, 5.0), (BytesWritable)fieldData);
value.set("{\"properties\":{},\"geometry\":{\"type\":\"Point\",\"type\":\"Point\",\"coordinates\":[7.0,4.0]}}");
row = jserde.deserialize(value);
f0 = rowOI.getStructFieldRef("shape");
fieldData = rowOI.getStructFieldData(row, f0);
ckPoint(new Point(7.0, 4.0), (BytesWritable)fieldData);
}
@Test
public void TestIntOnly() throws Exception { // Is this valid for GeoJSON?
ArrayList<Object> stuff = new ArrayList<Object>();
Properties proptab = new Properties();
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMNS, "num");
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMN_TYPES, "int");
SerDe jserde = mkSerDe(proptab);
StructObjectInspector rowOI = (StructObjectInspector)jserde.getObjectInspector();
//value.set("{\"properties\":{\"num\":7}}");
addWritable(stuff, 7);
Object row = runSerDe(stuff, jserde, rowOI);
Object fieldData = getField("num", row, rowOI);
Assert.assertEquals(7, ((IntWritable)fieldData).get());
stuff.clear();
addWritable(stuff, 9);
row = runSerDe(stuff, jserde, rowOI);
fieldData = getField("num", row, rowOI);
Assert.assertEquals(9, ((IntWritable)fieldData).get());
}
@Test
public void TestPointOnly() throws Exception {
ArrayList<Object> stuff = new ArrayList<Object>();
Properties proptab = new Properties();
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMNS, "shape");
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMN_TYPES, "binary");
SerDe jserde = mkSerDe(proptab);
StructObjectInspector rowOI = (StructObjectInspector)jserde.getObjectInspector();
//value.set("{\"properties\":{},\"geometry\":{\"type\":\"Point\",\"coordinates\":[15.0,5.0]}}");
addWritable(stuff, new Point(15.0, 5.0));
Object row = runSerDe(stuff, jserde, rowOI);
Object fieldData = getField("shape", row, rowOI);
ckPoint(new Point(15.0, 5.0), (BytesWritable)fieldData);
//value.set("{\"properties\":{},\"geometry\":{\"type\":\"Point\",\"type\":\"Point\",\"coordinates\":[7.0,4.0]}}");
stuff.clear();
addWritable(stuff, new Point(7.0, 4.0));
row = runSerDe(stuff, jserde, rowOI);
fieldData = getField("shape", row, rowOI);
ckPoint(new Point(7.0, 4.0), (BytesWritable)fieldData);
}
@Test
public void TestIntPoint() throws Exception {
ArrayList<Object> stuff = new ArrayList<Object>();
Properties proptab = new Properties();
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMNS, "num,shape");
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMN_TYPES, "bigint,binary");
SerDe jserde = mkSerDe(proptab);
StructObjectInspector rowOI = (StructObjectInspector)jserde.getObjectInspector();
// value.set("{\"properties\":{\"num\":7},\"geometry\":{\"type\":\"Point\",\"coordinates\":[15.0,5.0]}}");
addWritable(stuff, 7L);
addWritable(stuff, new Point(15.0, 5.0));
Object row = runSerDe(stuff, jserde, rowOI);
Object fieldData = getField("num", row, rowOI);
Assert.assertEquals(7, ((LongWritable)fieldData).get());
//value.set("{\"properties\":{\"num\":4},\"geometry\":{\"type\":\"Point\",\"coordinates\":[7.0,2.0]}}");
stuff.clear();
addWritable(stuff, 4L);
addWritable(stuff, new Point(7.0, 2.0));
row = runSerDe(stuff, jserde, rowOI);
fieldData = getField("num", row, rowOI);
Assert.assertEquals(4, ((LongWritable)fieldData).get());
fieldData = getField("shape", row, rowOI);
ckPoint(new Point(7.0, 2.0), (BytesWritable)fieldData);
}
@Test
public void TestNullAttr() throws Exception {
ArrayList<Object> stuff = new ArrayList<Object>();
Properties proptab = new Properties();
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMNS, "num");
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMN_TYPES, "int");
SerDe jserde = mkSerDe(proptab);
StructObjectInspector rowOI = (StructObjectInspector)jserde.getObjectInspector();
//value.set("{\"properties\":{\"num\":7}}");
addWritable(stuff, 7);
Object row = runSerDe(stuff, jserde, rowOI);
Object fieldData = getField("num", row, rowOI);
Assert.assertEquals(7, ((IntWritable)fieldData).get());
//value.set("{\"properties\":{}}");
stuff.set(0, null);
row = runSerDe(stuff, jserde, rowOI);
fieldData = getField("num", row, rowOI);
Assert.assertNull(fieldData);
}
@Test
public void TestNullGeom() throws Exception {
ArrayList<Object> stuff = new ArrayList<Object>();
Properties proptab = new Properties();
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMNS, "shape");
proptab.setProperty(HiveShims.serdeConstants.LIST_COLUMN_TYPES, "binary");
SerDe jserde = mkSerDe(proptab);
StructObjectInspector rowOI = (StructObjectInspector)jserde.getObjectInspector();
//value.set("{\"properties\":{},\"geometry\":{\"type\":\"Point\",\"coordinates\":[15.0,5.0]}}");
addWritable(stuff, new Point(15.0, 5.0));
Object row = runSerDe(stuff, jserde, rowOI);
Object fieldData = getField("shape", row, rowOI);
ckPoint(new Point(15.0, 5.0), (BytesWritable)fieldData);
//value.set("{\"properties\":{},\"coordinates\":null}");
stuff.set(0, null);
row = runSerDe(stuff, jserde, rowOI);
fieldData = getField("shape", row, rowOI);
Assert.assertNull(fieldData);
}
private SerDe mkSerDe(Properties proptab) throws Exception {
Configuration config = new Configuration();
SerDe jserde = new GeoJsonSerDe();
jserde.initialize(config, proptab);
return jserde;
}
}