Progamatically inter-convert Avro Schema to Class
How to inter-convert avro schema to class programatically.
The only way possible to convert a Avro Class from a definition is at compile time using avro maven plugin.
Convert from json Schema to schema Object:
Schema employeeSchema = new org.apache.avro.Schema.Parser().parse(jsonAvroSchema);
Convert from Json Schema to generic Record:
GenericRecord employeeRecord = new GenericData.Record(employeeSchema);
Select Class from classPath based on schema.
Class clazz = SpecificData.get().getClass(Employee.getClassSchema());
DO remember:
- The JsonSchema and schema present in AvroClass.getClassSchema() are not the same.
- Extra key,Value pairs have been added to AvroClass.getClassSchema().
- Using the normal JsonSchema one can only form GenricRecord.
- With the extra Key,Value pair available in AvroClass.getClassSchema() one can form Specific Record
import com.big.data.avro.schema.Employee;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.specific.SpecificData;
import java.util.HashMap;
import java.util.Map;
public class AvroSchemaToObjectConverter {
private static String employeeSchemaString = "{\n" +
" \"name\": \"com.big.data.avro.schema.Employee\",\n" +
" \"type\": \"record\",\n" +
" \"fields\": [{\n" +
" \"name\": \"emp_id\",\n" +
" \"type\": \"int\",\n" +
" \"doc\": \"employee Id of the employee\"\n" +
" },\n" +
" {\n" +
" \"name\": \"emp_name\",\n" +
" \"type\": \"string\",\n" +
" \"doc\": \"employee name of the employee\"\n" +
" },\n" +
" {\n" +
" \"name\": \"emp_country\",\n" +
" \"type\": \"string\",\n" +
" \"doc\": \"country of residence\"\n" +
" },\n" +
" { \"name\": \"bonus\",\n" +
" \"type\": [\"null\", \"long\"],\n" +
" \"default\": null,\n" +
" \"doc\": \"bonus received on a yearly basis\"\n" +
" },\n" +
" {\n" +
" \"name\": \"subordinates\",\n" +
" \"type\": [\"null\", {\"type\": \"map\", \"values\": \"string\"}],\n" +
" \"default\": null,\n" +
" \"doc\": \"map of subordinates Name and Designation\"\n" +
" },\n" +
" {\n" +
" \"name\": \"departments\",\n" +
" \"type\":[\"null\", {\"type\":\"array\", \"items\":\"string\" }],\n" +
" \"default\":null,\n" +
" \"doc\": \"Departments under the employee\"\n" +
" }\n" +
" ]\n" +
" }";
[addToAppearHere]
public void convertSchemaToClass() {
Map<String, String> subordinateMap;
subordinateMap = new HashMap<>();
subordinateMap.put("maverick", "Junior SE");
Schema employeeSchema = new org.apache.avro.Schema.Parser().parse(employeeSchemaString);
// Form Generic Record.
GenericRecord employeeRecord = new GenericData.Record(employeeSchema);
//Insert Data into Generic Record
employeeRecord.put("emp_id", 1L);
employeeRecord.put("emp_name", "Mavrick");
employeeRecord.put("emp_country", "NETHERLAND");
employeeRecord.put("subordinates", subordinateMap);
System.out.println("Generic Employee Record is : " + employeeRecord);
}
public void convertClassToSchema() {
Class clazz = SpecificData.get().getClass(Employee.getClassSchema());
System.out.println("Class extracted from the schema is " + clazz);
}
public static void main(String[] args) {
AvroSchemaToObjectConverter converter = new AvroSchemaToObjectConverter();
converter.convertClassToSchema();
converter.convertSchemaToClass();
}
}